From f6fc5824e6447235fd7d9d557f274def75ebbfd9 Mon Sep 17 00:00:00 2001 From: harryob Date: Wed, 13 Nov 2024 00:05:07 +0000 Subject: [PATCH 001/222] fix clicking other ghosts' screen alerts (#87830) closes #87572 ## About The Pull Request usr does not necessarily mean owner for screen alerts, thanks Observe ## Why It's Good For The Game shouldn't be teleporting other ghosts around --- code/_onclick/hud/alert.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 46e9d4898c8ed..5eaff57b6096d 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -858,6 +858,8 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." /atom/movable/screen/alert/notify_action/Click() . = ..() + if(!.) + return var/atom/target = target_ref?.resolve() if(isnull(target) || !isobserver(owner) || target == owner) From 430de5b72d71f0118524e8853b05d1bc8d32cf41 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 00:05:29 +0000 Subject: [PATCH 002/222] Automatic changelog for PR #87830 [ci skip] --- html/changelogs/AutoChangeLog-pr-87830.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87830.yml diff --git a/html/changelogs/AutoChangeLog-pr-87830.yml b/html/changelogs/AutoChangeLog-pr-87830.yml new file mode 100644 index 0000000000000..b55d409d98d37 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87830.yml @@ -0,0 +1,4 @@ +author: "harryob" +delete-after: True +changes: + - bugfix: "ghosts observing ghosts can no longer click on their screen alerts" \ No newline at end of file From eb67a99d00260ba3a3a08e6c7fd9869ee185b1b3 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 00:25:39 +0000 Subject: [PATCH 003/222] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-87773.yml | 4 -- html/changelogs/AutoChangeLog-pr-87818.yml | 4 -- html/changelogs/AutoChangeLog-pr-87819.yml | 5 -- html/changelogs/AutoChangeLog-pr-87825.yml | 4 -- html/changelogs/AutoChangeLog-pr-87827.yml | 4 -- html/changelogs/AutoChangeLog-pr-87830.yml | 4 -- html/changelogs/AutoChangeLog-pr-87832.yml | 4 -- html/changelogs/AutoChangeLog-pr-87834.yml | 4 -- html/changelogs/AutoChangeLog-pr-87835.yml | 4 -- html/changelogs/AutoChangeLog-pr-87836.yml | 4 -- html/changelogs/AutoChangeLog-pr-87837.yml | 4 -- html/changelogs/AutoChangeLog-pr-87838.yml | 5 -- html/changelogs/AutoChangeLog-pr-87839.yml | 4 -- html/changelogs/AutoChangeLog-pr-87840.yml | 4 -- html/changelogs/AutoChangeLog-pr-87841.yml | 4 -- html/changelogs/AutoChangeLog-pr-87843.yml | 4 -- html/changelogs/AutoChangeLog-pr-87845.yml | 4 -- html/changelogs/AutoChangeLog-pr-87846.yml | 4 -- html/changelogs/AutoChangeLog-pr-87847.yml | 5 -- html/changelogs/AutoChangeLog-pr-87849.yml | 4 -- html/changelogs/AutoChangeLog-pr-87850.yml | 4 -- html/changelogs/AutoChangeLog-pr-87851.yml | 4 -- html/changelogs/AutoChangeLog-pr-87852.yml | 4 -- html/changelogs/AutoChangeLog-pr-87855.yml | 4 -- html/changelogs/AutoChangeLog-pr-87856.yml | 7 --- html/changelogs/archive/2024-11.yml | 57 ++++++++++++++++++++++ 26 files changed, 57 insertions(+), 106 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-87773.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87818.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87819.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87825.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87827.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87830.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87832.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87834.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87835.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87836.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87837.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87838.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87839.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87840.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87841.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87843.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87845.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87846.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87847.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87849.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87850.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87851.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87852.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87855.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87856.yml diff --git a/html/changelogs/AutoChangeLog-pr-87773.yml b/html/changelogs/AutoChangeLog-pr-87773.yml deleted file mode 100644 index beb2605ec2748..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87773.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Holoo-1" -delete-after: True -changes: - - bugfix: "fixed roundstart borgs not being synced to ai" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87818.yml b/html/changelogs/AutoChangeLog-pr-87818.yml deleted file mode 100644 index 84037f8dcd987..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87818.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "Fixed special DNA infusions from squids and pufferfish." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87819.yml b/html/changelogs/AutoChangeLog-pr-87819.yml deleted file mode 100644 index 5e7cfe01c003d..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87819.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "Fixed bombing non-turfs fishing spots not spawning loot correctly." - - balance: "Explosive bombing no longer spawns bottled messages/photos." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87825.yml b/html/changelogs/AutoChangeLog-pr-87825.yml deleted file mode 100644 index 15258c679ad04..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87825.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "Fixed fish not being able to reproduce with other fish of the same type without the crossbreeding trait." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87827.yml b/html/changelogs/AutoChangeLog-pr-87827.yml deleted file mode 100644 index 153c3581b473c..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87827.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "Fixed fish still being hungry when fed if in aquarium with the 'growth and reproduction' option disabled." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87830.yml b/html/changelogs/AutoChangeLog-pr-87830.yml deleted file mode 100644 index b55d409d98d37..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87830.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "harryob" -delete-after: True -changes: - - bugfix: "ghosts observing ghosts can no longer click on their screen alerts" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87832.yml b/html/changelogs/AutoChangeLog-pr-87832.yml deleted file mode 100644 index 4ebb0e20d35a8..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87832.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Xenobio console puts sucked up slimes into stasis so they no longer split up inside" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87834.yml b/html/changelogs/AutoChangeLog-pr-87834.yml deleted file mode 100644 index 8a0ada8f2cd2d..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87834.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "harryob" -delete-after: True -changes: - - bugfix: "certain tgui inputs no longer require 2 clicks to open" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87835.yml b/html/changelogs/AutoChangeLog-pr-87835.yml deleted file mode 100644 index ab2ded648b722..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87835.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "sqnztb" -delete-after: True -changes: - - map: "tramstation tool storage trash no longer routes to the barber shop" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87836.yml b/html/changelogs/AutoChangeLog-pr-87836.yml deleted file mode 100644 index dcac7fdd74dd8..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87836.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Goat" -delete-after: True -changes: - - qol: "You can now examine labelers to tell how many more labels it has." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87837.yml b/html/changelogs/AutoChangeLog-pr-87837.yml deleted file mode 100644 index 96a44be2edb83..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87837.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "tmyqlfpir" -delete-after: True -changes: - - bugfix: "Airlock shells are properly assigned circuit cameras modules" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87838.yml b/html/changelogs/AutoChangeLog-pr-87838.yml deleted file mode 100644 index 6e8027cf19a73..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87838.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Neocloudy" -delete-after: True -changes: - - bugfix: "examine tags now use regex for checking if a tag has \"and\" in it" - - spellcheck: "the tooltip for the morbid examine tag doesn't try to use html anymore" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87839.yml b/html/changelogs/AutoChangeLog-pr-87839.yml deleted file mode 100644 index 43aafa3b23640..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87839.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Rhials" -delete-after: True -changes: - - qol: "Makes some minor updates to Runtimestation, including event spawn points and a cargo bounty pad." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87840.yml b/html/changelogs/AutoChangeLog-pr-87840.yml deleted file mode 100644 index 2ce6d8d10d9c9..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87840.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "EmptyLullaby" -delete-after: True -changes: - - bugfix: "Goliath cloaks are no longer so hard on the calves that they force digitigrade legs to disable." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87841.yml b/html/changelogs/AutoChangeLog-pr-87841.yml deleted file mode 100644 index 83704f38ee57b..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87841.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Goat" -delete-after: True -changes: - - qol: "Curator console's inventory screen will now update when you change pages or remove items." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87843.yml b/html/changelogs/AutoChangeLog-pr-87843.yml deleted file mode 100644 index 168494cd29b45..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87843.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Goat" -delete-after: True -changes: - - map: "The library's scanner on Birdshot is now close enough to connect to the computer and was also given a book binder." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87845.yml b/html/changelogs/AutoChangeLog-pr-87845.yml deleted file mode 100644 index 9a9672e710500..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87845.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothymtorres" -delete-after: True -changes: - - bugfix: "Fix missing screentips plasmaman helmets and MOD suit hat stabilizer helmets." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87846.yml b/html/changelogs/AutoChangeLog-pr-87846.yml deleted file mode 100644 index 3423cb647db77..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87846.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothymtorres" -delete-after: True -changes: - - bugfix: "Fix broken link to issue manager guide in Github contributor guide" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87847.yml b/html/changelogs/AutoChangeLog-pr-87847.yml deleted file mode 100644 index b1290b19944e4..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87847.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Absolucy" -delete-after: True -changes: - - bugfix: "You can no longer crush random unsuspecting people with vendors by ventcrawling while cursed." - - qol: "AFK players don't count as \"watchers\" for cursed stuff." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87849.yml b/html/changelogs/AutoChangeLog-pr-87849.yml deleted file mode 100644 index 394c7b39a0d9d..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87849.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothymtorres" -delete-after: True -changes: - - bugfix: "Fix holymelon armor not inheriting magic resistance" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87850.yml b/html/changelogs/AutoChangeLog-pr-87850.yml deleted file mode 100644 index b84618840865c..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87850.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "OrionTheFox" -delete-after: True -changes: - - bugfix: "(DeltaStation) Fixed unwired APCs in the Electronic Marketing Den, Abandoned Garden, Security Maintenance, and Private Investigator's Office" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87851.yml b/html/changelogs/AutoChangeLog-pr-87851.yml deleted file mode 100644 index e2c0c757c4ee3..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87851.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Fixed hat stabilizer ignoring clothing worn_y_offset" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87852.yml b/html/changelogs/AutoChangeLog-pr-87852.yml deleted file mode 100644 index 50ad199495d90..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87852.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Fixed basic mob performance impact created by the factorio PR" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87855.yml b/html/changelogs/AutoChangeLog-pr-87855.yml deleted file mode 100644 index e31cdb3c8d3a2..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87855.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "00-Steven" -delete-after: True -changes: - - bugfix: "Fixed auto-reel fishing line item catching logic." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87856.yml b/html/changelogs/AutoChangeLog-pr-87856.yml deleted file mode 100644 index df597780aa209..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87856.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: "SyncIt21" -delete-after: True -changes: - - bugfix: "flatpacker accepts circuitboards with left click" - - bugfix: "rcd can deconstruct tables" - - bugfix: "you can open panels of destructive analyzers with screwdriver right click. Use right click or combat mode with items for default interactions" - - bugfix: "flatpacker & machines with local storage can be RPED'd again" \ No newline at end of file diff --git a/html/changelogs/archive/2024-11.yml b/html/changelogs/archive/2024-11.yml index dc1ca68e5f858..994af6753b8e6 100644 --- a/html/changelogs/archive/2024-11.yml +++ b/html/changelogs/archive/2024-11.yml @@ -401,3 +401,60 @@ grungussuss: - qol: you can now mitigate motion sickness from screen shake by enabling "darken screen shake" in preferences +2024-11-13: + 00-Steven: + - bugfix: Fixed auto-reel fishing line item catching logic. + Absolucy: + - bugfix: You can no longer crush random unsuspecting people with vendors by ventcrawling + while cursed. + - qol: AFK players don't count as "watchers" for cursed stuff. + EmptyLullaby: + - bugfix: Goliath cloaks are no longer so hard on the calves that they force digitigrade + legs to disable. + Ghommie: + - bugfix: Fixed special DNA infusions from squids and pufferfish. + - bugfix: Fixed fish still being hungry when fed if in aquarium with the 'growth + and reproduction' option disabled. + - bugfix: Fixed bombing non-turfs fishing spots not spawning loot correctly. + - balance: Explosive bombing no longer spawns bottled messages/photos. + - bugfix: Fixed fish not being able to reproduce with other fish of the same type + without the crossbreeding trait. + Goat: + - map: The library's scanner on Birdshot is now close enough to connect to the computer + and was also given a book binder. + - qol: Curator console's inventory screen will now update when you change pages + or remove items. + - qol: You can now examine labelers to tell how many more labels it has. + Holoo-1: + - bugfix: fixed roundstart borgs not being synced to ai + Neocloudy: + - bugfix: examine tags now use regex for checking if a tag has "and" in it + - spellcheck: the tooltip for the morbid examine tag doesn't try to use html anymore + OrionTheFox: + - bugfix: (DeltaStation) Fixed unwired APCs in the Electronic Marketing Den, Abandoned + Garden, Security Maintenance, and Private Investigator's Office + Rhials: + - qol: Makes some minor updates to Runtimestation, including event spawn points + and a cargo bounty pad. + SmArtKar: + - bugfix: Xenobio console puts sucked up slimes into stasis so they no longer split + up inside + - bugfix: Fixed basic mob performance impact created by the factorio PR + - bugfix: Fixed hat stabilizer ignoring clothing worn_y_offset + SyncIt21: + - bugfix: flatpacker accepts circuitboards with left click + - bugfix: rcd can deconstruct tables + - bugfix: you can open panels of destructive analyzers with screwdriver right click. + Use right click or combat mode with items for default interactions + - bugfix: flatpacker & machines with local storage can be RPED'd again + harryob: + - bugfix: ghosts observing ghosts can no longer click on their screen alerts + - bugfix: certain tgui inputs no longer require 2 clicks to open + sqnztb: + - map: tramstation tool storage trash no longer routes to the barber shop + timothymtorres: + - bugfix: Fix holymelon armor not inheriting magic resistance + - bugfix: Fix broken link to issue manager guide in Github contributor guide + - bugfix: Fix missing screentips plasmaman helmets and MOD suit hat stabilizer helmets. + tmyqlfpir: + - bugfix: Airlock shells are properly assigned circuit cameras modules From 6f98b9efe7072c5b84f1583b5ddc4cf5bf28ae45 Mon Sep 17 00:00:00 2001 From: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Date: Wed, 13 Nov 2024 07:05:15 +0530 Subject: [PATCH 004/222] Holosign creators interact with storage correctly (#87824) ## About The Pull Request - Fixes #87539 Racks, bags & basically anything that stores stuff will interact with all holosign creator's correctly ## Changelog :cl: fix: holosign creators interact with storage items correctly /:cl: --- code/game/objects/items/holosign_creator.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/game/objects/items/holosign_creator.dm b/code/game/objects/items/holosign_creator.dm index 049ea8928feff..efe1d9e31f1ba 100644 --- a/code/game/objects/items/holosign_creator.dm +++ b/code/game/objects/items/holosign_creator.dm @@ -35,6 +35,11 @@ return . += span_notice("It is currently maintaining [signs.len]/[max_signs] projections.") +/obj/item/holosign_creator/check_allowed_items(atom/target, not_inside, target_self) + if(HAS_TRAIT(target, TRAIT_COMBAT_MODE_SKIP_INTERACTION)) + return FALSE + return ..() + /obj/item/holosign_creator/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) if(!check_allowed_items(interacting_with, not_inside = TRUE)) return NONE From cc98b68c2c9537865d2882b5c9a35ce60aab4ef6 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 01:35:37 +0000 Subject: [PATCH 005/222] Automatic changelog for PR #87824 [ci skip] --- html/changelogs/AutoChangeLog-pr-87824.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87824.yml diff --git a/html/changelogs/AutoChangeLog-pr-87824.yml b/html/changelogs/AutoChangeLog-pr-87824.yml new file mode 100644 index 0000000000000..6e323bb9556e9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87824.yml @@ -0,0 +1,4 @@ +author: "SyncIt21" +delete-after: True +changes: + - bugfix: "holosign creators interact with storage items correctly" \ No newline at end of file From 13ac419b9b82b505589a47db01ce7610b2788e78 Mon Sep 17 00:00:00 2001 From: Jeremiah <42397676+jlsnow301@users.noreply.github.com> Date: Tue, 12 Nov 2024 19:08:26 -0800 Subject: [PATCH 006/222] [tgui] Fixes sassy warnings (#87776) ## About The Pull Request Sass was warning about deprecated APIs in our codebase. Went through and fixed them Used sass-migrator tool as much as I could, some were by hand ### Updated: Sass would no longer let you run functions on hex color codes so I went through and HSL'd them all, how cool! If you have a simpler way to approach this, let me know Adds a tool to convert hex to HSL ## Why It's Good For The Game None of this ![image](https://github.com/user-attachments/assets/35d3dbeb-f62f-4485-bb2e-889c5d4453e2) ## Changelog N/A --- tgui/package.json | 2 +- .../tgui-panel/styles/components/Chat.scss | 16 +- .../styles/components/Notifications.scss | 4 +- .../tgui-panel/styles/components/Ping.scss | 2 +- tgui/packages/tgui-panel/styles/main.scss | 4 +- .../tgui-panel/styles/tgchat/chat-dark.scss | 348 ++++++++--------- .../tgui-panel/styles/tgchat/chat-light.scss | 352 +++++++++--------- .../tgui-panel/styles/themes/light.scss | 26 +- tgui/packages/tgui-say/styles/colors.scss | 48 +-- .../tgui/styles/atomic/candystripe.scss | 2 +- .../tgui/styles/atomic/debug-layout.scss | 6 +- tgui/packages/tgui/styles/base.scss | 4 +- tgui/packages/tgui/styles/colors.scss | 44 +-- .../tgui/styles/components/Button.scss | 2 +- .../tgui/styles/components/Input.scss | 4 +- .../packages/tgui/styles/components/Knob.scss | 8 +- .../tgui/styles/components/MenuBar.scss | 3 +- .../tgui/styles/components/NoticeBox.scss | 4 +- .../tgui/styles/components/RoundGauge.scss | 2 +- .../tgui/styles/components/SearchItem.scss | 2 +- .../tgui/styles/components/Slider.scss | 4 +- .../tgui/styles/components/Tooltip.scss | 4 +- tgui/packages/tgui/styles/functions.scss | 14 +- .../styles/interfaces/DetectiveBoard.scss | 20 +- .../interfaces/ExperimentConfigure.scss | 8 +- .../tgui/styles/interfaces/Fabricator.scss | 3 +- .../tgui/styles/interfaces/Fishing.scss | 6 +- .../styles/interfaces/IntegratedCircuit.scss | 2 +- .../tgui/styles/interfaces/Mecha.scss | 14 +- .../tgui/styles/interfaces/NtosMessenger.scss | 6 +- .../tgui/styles/interfaces/NuclearBomb.scss | 12 +- .../styles/interfaces/PersonalCrafting.scss | 12 +- .../styles/interfaces/PreferencesMenu.scss | 24 +- .../packages/tgui/styles/interfaces/Safe.scss | 30 +- .../tgui/styles/interfaces/Techweb.scss | 6 +- .../tgui/styles/interfaces/Uplink.scss | 42 ++- tgui/packages/tgui/styles/layouts/Layout.scss | 2 +- .../tgui/styles/layouts/NtosWindow.scss | 4 +- .../tgui/styles/layouts/TitleBar.scss | 18 +- tgui/packages/tgui/styles/layouts/Window.scss | 4 +- tgui/packages/tgui/styles/main.scss | 2 +- tgui/packages/tgui/styles/reset.scss | 2 +- .../packages/tgui/styles/themes/abductor.scss | 28 +- tgui/packages/tgui/styles/themes/admin.scss | 5 +- .../tgui/styles/themes/cardtable.scss | 20 +- .../tgui/styles/themes/hackerman.scss | 16 +- .../tgui/styles/themes/malfunction.scss | 24 +- tgui/packages/tgui/styles/themes/neutral.scss | 2 +- tgui/packages/tgui/styles/themes/ntOS95.scss | 64 ++-- tgui/packages/tgui/styles/themes/ntos.scss | 2 +- .../packages/tgui/styles/themes/ntos_cat.scss | 75 ++-- .../tgui/styles/themes/ntos_darkmode.scss | 2 +- .../tgui/styles/themes/ntos_lightmode.scss | 28 +- .../tgui/styles/themes/ntos_spooky.scss | 30 +- .../tgui/styles/themes/ntos_synth.scss | 32 +- .../tgui/styles/themes/ntos_terminal.scss | 52 +-- tgui/packages/tgui/styles/themes/paper.scss | 50 +-- tgui/packages/tgui/styles/themes/retro.scss | 30 +- .../tgui/styles/themes/spookyconsole.scss | 26 +- .../tgui/styles/themes/syndicate.scss | 24 +- tgui/packages/tgui/styles/themes/wizard.scss | 24 +- tgui/yarn.lock | 10 +- tools/hslify/README.md | 21 ++ tools/hslify/hslify.py | 27 ++ 64 files changed, 900 insertions(+), 814 deletions(-) create mode 100644 tools/hslify/README.md create mode 100644 tools/hslify/hslify.py diff --git a/tgui/package.json b/tgui/package.json index 57d02a389d267..f89241c5a3f2e 100644 --- a/tgui/package.json +++ b/tgui/package.json @@ -45,7 +45,7 @@ "mini-css-extract-plugin": "^2.9.2", "prettier": "^3.2.5", "sass": "^1.80.6", - "sass-loader": "^14.2.1", + "sass-loader": "^16.0.3", "style-loader": "^4.0.0", "swc-loader": "^0.2.6", "typescript": "^5.6.3", diff --git a/tgui/packages/tgui-panel/styles/components/Chat.scss b/tgui/packages/tgui-panel/styles/components/Chat.scss index b439ace8c58f1..882f86a7aaacb 100644 --- a/tgui/packages/tgui-panel/styles/components/Chat.scss +++ b/tgui/packages/tgui-panel/styles/components/Chat.scss @@ -8,7 +8,7 @@ @use '~tgui/styles/base.scss'; @use '~tgui/styles/colors.scss'; -$text-color: #abc6ec !default; +$text-color: hsl(210, 50%, 80%) !default; $color-bg-section: base.$color-bg-section !default; .Chat { @@ -21,11 +21,11 @@ $color-bg-section: base.$color-bg-section !default; font-size: 0.7em; padding: 0.2em 0.3em; line-height: 1; - color: white; + color: hsl(0, 0%, 100%); text-align: center; white-space: nowrap; vertical-align: middle; - background-color: crimson; + background-color: hsl(348, 83%, 47%); border-radius: 10px; transition: font-size 200ms ease-out; @@ -68,12 +68,12 @@ $color-bg-section: base.$color-bg-section !default; } .Chat__highlight { - color: #000; + color: hsl(0, 0%, 0%); } .Chat__highlight--restricted { - color: #fff; - background-color: #a00; + color: hsl(0, 0%, 100%); + background-color: hsl(0, 100%, 33.3%); font-weight: bold; } @@ -83,7 +83,7 @@ $color-bg-section: base.$color-bg-section !default; .ChatMessage--highlighted { position: relative; - border-left: math.div(1em, 6) solid rgba(255, 221, 68); + border-left: math.div(1em, 6) solid hsl(50, 100%, 63.5%); padding-left: 0.5em; &:after { @@ -93,7 +93,7 @@ $color-bg-section: base.$color-bg-section !default; bottom: 0; left: 0; right: 0; - background-color: rgba(255, 221, 68, 0.1); + background-color: hsla(50, 100%, 63.5%, 0.1); // Make this click-through since this is an overlay pointer-events: none; } diff --git a/tgui/packages/tgui-panel/styles/components/Notifications.scss b/tgui/packages/tgui-panel/styles/components/Notifications.scss index f3669967fd70c..2e99e59a20aa0 100644 --- a/tgui/packages/tgui-panel/styles/components/Notifications.scss +++ b/tgui/packages/tgui-panel/styles/components/Notifications.scss @@ -11,8 +11,8 @@ } .Notification { - color: #fff; - background-color: crimson; + color: hsl(0, 0%, 100%); + background-color: hsl(348, 83%, 47%); padding: 0.5em; margin: 1em 0; diff --git a/tgui/packages/tgui-panel/styles/components/Ping.scss b/tgui/packages/tgui-panel/styles/components/Ping.scss index 251b0fd953912..292caf11105e0 100644 --- a/tgui/packages/tgui-panel/styles/components/Ping.scss +++ b/tgui/packages/tgui-panel/styles/components/Ping.scss @@ -23,6 +23,6 @@ $border-color: rgba(140, 140, 140, 0.5) !default; left: 0.5em; width: 0.5em; height: 0.5em; - background-color: #888; + background-color: hsl(0, 0%, 53.3%); border-radius: 0.25em; } diff --git a/tgui/packages/tgui-panel/styles/main.scss b/tgui/packages/tgui-panel/styles/main.scss index 08e60d18ee6a3..9b1aad07fb5ae 100644 --- a/tgui/packages/tgui-panel/styles/main.scss +++ b/tgui/packages/tgui-panel/styles/main.scss @@ -8,8 +8,8 @@ @use '~tgui/styles/colors.scss'; @use '~tgui/styles/base.scss' with ( - $color-bg: #202020, - $color-bg-section: color.adjust(#202020, $lightness: -5%), + $color-bg: hsl(0, 0%, 12.5%), + $color-bg-section: color.adjust(hsl(0, 0%, 12.5%), $lightness: -5%), $color-bg-grad-spread: 0% ); diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss index f7316b5e6733e..2308d720436c8 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss @@ -27,15 +27,15 @@ img.icon { } a { - color: #397ea5; + color: hsl(201.7, 48.6%, 43.5%); } a.visited { - color: #7c00e6; + color: hsl(272.3, 100%, 45.1%); } a:visited { - color: #7c00e6; + color: hsl(272.3, 100%, 45.1%); } a.popt { @@ -139,7 +139,7 @@ a.popt { } .highlightPopup input.highlightColor { - background-color: #ffff00; + background-color: hsl(60, 100%, 50%); } .highlightPopup input.highlightTermSubmit { @@ -199,7 +199,7 @@ a.popt { /* MOTD */ .motd { - color: #a4bad6; + color: hsl(213.6, 37.9%, 74.1%); font-family: Verdana, sans-serif; white-space: normal; } @@ -210,7 +210,7 @@ a.popt { .motd h4, .motd h5, .motd h6 { - color: #a4bad6; + color: hsl(213.6, 37.9%, 74.1%); text-decoration: underline; } @@ -219,7 +219,7 @@ a.popt { .motd a:visited, .motd a:active, .motd a:hover { - color: #a4bad6; + color: hsl(213.6, 37.9%, 74.1%); } /* ADD HERE FOR BOLD */ @@ -255,13 +255,13 @@ h3, h4, h5, h6 { - color: #a4bad6; + color: hsl(213.6, 37.9%, 74.1%); font-family: Georgia, Verdana, sans-serif; } h1.alert, h2.alert { - color: #a4bad6; + color: hsl(213.6, 37.9%, 74.1%); } em { @@ -270,27 +270,27 @@ em { } .ooc { - color: #cca300; + color: hsl(47.9, 100%, 40%); font-weight: bold; } .adminobserverooc { - color: #0099cc; + color: hsl(195, 100%, 40%); font-weight: bold; } .adminooc { - color: #3d5bc3; + color: hsl(226.6, 52.8%, 50.2%); font-weight: bold; } .adminsay { - color: #ff4500; + color: hsl(16.2, 100%, 50%); font-weight: bold; } .admin { - color: #5975da; + color: hsl(227, 63.5%, 60.2%); font-weight: bold; } @@ -306,91 +306,91 @@ em { } .deadsay { - color: #e2c1ff; + color: hsl(271.9, 100%, 87.8%); } .binarysay { - color: #1e90ff; + color: hsl(209.6, 100%, 55.9%); } .binarysay a { - color: #00ff00; + color: hsl(120, 100%, 50%); } .binarysay a:active, .binarysay a:visited { - color: #88ff88; + color: hsl(120, 100%, 76.7%); } /* RADIO COLORS */ /* IF YOU CHANGE THIS KEEP IT IN SYNC WITH TGUI CONSTANTS */ .radio { - color: #1ecc43; + color: hsl(132.8, 74.4%, 45.9%); } .sciradio { - color: #c68cfa; + color: hsl(271.6, 91.7%, 76.5%); } .comradio { - color: #fcdf03; + color: hsl(53, 97.6%, 50%); } .secradio { - color: #dd3535; + color: hsl(0, 71.2%, 53.7%); } .medradio { - color: #57b8f0; + color: hsl(202, 83.6%, 64.1%); } .engradio { - color: #f37746; + color: hsl(17, 87.8%, 61.4%); } .suppradio { - color: #b88646; + color: hsl(33.7, 44.9%, 49.8%); } .servradio { - color: #6ca729; + color: hsl(88.1, 60.6%, 40.8%); } .syndradio { - color: #8f4a4b; + color: hsl(359.1, 31.8%, 42.5%); } .gangradio { - color: #ac2ea1; + color: hsl(305.2, 57.8%, 42.7%); } .centcomradio { - color: #2681a5; + color: hsl(197, 62.6%, 39.8%); } .aiprivradio { - color: #d65d95; + color: hsl(332.2, 59.6%, 60.2%); } .enteradio { - color: #79c5a8; + color: hsl(157.1, 39.6%, 62.4%); } .redteamradio { - color: #ff4444 !important; + color: hsl(0, 100%, 63.3%) !important; } .blueteamradio { - color: #3434fd !important; + color: hsl(240, 98%, 59.8%) !important; } .greenteamradio { - color: #34fd34 !important; + color: hsl(120, 98%, 59.8%) !important; } .yellowteamradio { - color: #fdfd34 !important; + color: hsl(60, 98%, 59.8%) !important; } .yell { @@ -398,122 +398,122 @@ em { } .alert { - color: #d82020; + color: hsl(0, 74.2%, 48.6%); } .userdanger { - color: #c51e1e; + color: hsl(0, 73.6%, 44.5%); font-weight: bold; font-size: 185%; } .bolddanger { - color: #c51e1e; + color: hsl(0, 73.6%, 44.5%); font-weight: bold; } .danger { - color: #c51e1e; + color: hsl(0, 73.6%, 44.5%); } .tinydanger { - color: #c51e1e; + color: hsl(0, 73.6%, 44.5%); font-size: 85%; } .smalldanger { - color: #c51e1e; + color: hsl(0, 73.6%, 44.5%); font-size: 90%; } .warning { - color: #c51e1e; + color: hsl(0, 73.6%, 44.5%); font-style: italic; } .alertwarning { - color: #ff0000; + color: hsl(0, 100%, 50%); font-weight: bold; } .boldwarning { - color: #c51e1e; + color: hsl(0, 73.6%, 44.5%); font-style: italic; font-weight: bold; } .announce { - color: #c51e1e; + color: hsl(0, 73.6%, 44.5%); font-weight: bold; } .boldannounce { - color: #c51e1e; + color: hsl(0, 73.6%, 44.5%); font-weight: bold; } .minorannounce { - color: #c51e1e; + color: hsl(0, 73.6%, 44.5%); font-weight: bold; font-size: 185%; } .minoralert { - color: #a4bad6; + color: hsl(213.6, 37.9%, 74.1%); font-size: 125%; } .priorityannounce { - color: #a4bad6; + color: hsl(213.6, 37.9%, 74.1%); font-weight: bold; font-size: 225%; } .prioritytitle { - color: #6685f5; + color: hsl(227, 87.7%, 68%); font-weight: bold; font-size: 185%; } .priorityalert { - color: #c51e1e; + color: hsl(0, 73.6%, 44.5%); font-size: 140%; } .greenannounce { - color: #059223; + color: hsl(132.8, 93.4%, 29.6%); font-weight: bold; } .rose { - color: #ff5050; + color: hsl(0, 100%, 65.7%); } .info { - color: #9ab0ff; + color: hsl(226.9, 100%, 80.2%); } .notice { - color: #6685f5; + color: hsl(227, 87.7%, 68%); } .tinynotice { - color: #6685f5; + color: hsl(227, 87.7%, 68%); font-size: 85%; } .tinynoticeital { - color: #6685f5; + color: hsl(227, 87.7%, 68%); font-style: italic; font-size: 85%; } .smallnotice { - color: #6685f5; + color: hsl(227, 87.7%, 68%); font-size: 90%; } .smallnoticeital { - color: #6685f5; + color: hsl(227, 87.7%, 68%); font-style: italic; font-size: 90%; } @@ -524,218 +524,218 @@ em { } .boldnotice { - color: #6685f5; + color: hsl(227, 87.7%, 68%); font-weight: bold; } .hear { - color: #6685f5; + color: hsl(227, 87.7%, 68%); font-style: italic; } .adminnotice { - color: #6685f5; + color: hsl(227, 87.7%, 68%); } .adminhelp { - color: #ff0000; + color: hsl(0, 100%, 50%); font-weight: bold; } .unconscious { - color: #a4bad6; + color: hsl(213.6, 37.9%, 74.1%); font-weight: bold; } .suicide { - color: #ff5050; + color: hsl(0, 100%, 65.7%); font-style: italic; } .green { - color: #059223; + color: hsl(132.8, 93.4%, 29.6%); } .grey { - color: #838383; + color: hsl(0, 0%, 51.4%); } .red { - color: #ff0000; + color: hsl(0, 100%, 50%); } .blue { - color: #215cff; + color: hsl(224.1, 100%, 56.5%); } .nicegreen { - color: #059223; + color: hsl(132.8, 93.4%, 29.6%); } .boldnicegreen { - color: #059223; + color: hsl(132.8, 93.4%, 29.6%); font-weight: bold; } .blob { - color: #ee4000; + color: hsl(16.1, 100%, 46.7%); } .blobannounce { - color: #556b2f; + color: hsl(82, 39%, 30.2%); font-weight: bold; font-size: 185%; } .cult { - color: #973e3b; + color: hsl(2, 43.8%, 41.2%); } .cult_italic { - color: #973e3b; + color: hsl(2, 43.8%, 41.2%); font-style: italic; } .cult_bold { - color: #973e3b; + color: hsl(2, 43.8%, 41.2%); font-style: italic; font-weight: bold; } .cult_bold_italic { - color: #973e3b; + color: hsl(2, 43.8%, 41.2%); font-weight: bold; font-size: 185%; } .cult_large { - color: #973e3b; + color: hsl(2, 43.8%, 41.2%); font-weight: bold; font-size: 185%; } .narsie { - color: #973e3b; + color: hsl(2, 43.8%, 41.2%); font-weight: bold; font-size: 925%; } .narsiesmall { - color: #973e3b; + color: hsl(2, 43.8%, 41.2%); font-weight: bold; font-size: 370%; } .colossus { - color: #7f282a; + color: hsl(358.6, 52.1%, 32.7%); font-size: 310%; } .hierophant { - color: #b441ee; + color: hsl(279.9, 83.6%, 59.4%); font-weight: bold; font-style: italic; } .hierophant_warning { - color: #c56bf1; + color: hsl(280.3, 82.7%, 68.2%); font-style: italic; } .purple { - color: #9956d3; + color: hsl(272.2, 58.7%, 58.2%); } .holoparasite { - color: #88809c; + color: hsl(257.1, 12.4%, 55.7%); } .revennotice { - color: #c099e2; + color: hsl(272.1, 55.7%, 74.3%); } .revenboldnotice { - color: #c099e2; + color: hsl(272.1, 55.7%, 74.3%); font-weight: bold; } .revenbignotice { - color: #c099e2; + color: hsl(272.1, 55.7%, 74.3%); font-weight: bold; font-size: 185%; } .revenminor { - color: #823abb; + color: hsl(273.5, 52.7%, 48%); } .revenwarning { - color: #760fbb; + color: hsl(275.9, 85.1%, 39.6%); font-style: italic; } .revendanger { - color: #760fbb; + color: hsl(275.9, 85.1%, 39.6%); font-weight: bold; font-size: 185%; } .deconversion_message { - color: #a947ff; + color: hsl(272, 100%, 63.9%); font-size: 185%; font-style: italic; } .ghostalert { - color: #6600ff; + color: hsl(264, 100%, 50%); font-style: italic; font-weight: bold; } .alien { - color: #855d85; + color: hsl(300, 17.7%, 44.3%); } .noticealien { - color: #059223; + color: hsl(132.8, 93.4%, 29.6%); } .alertalien { - color: #059223; + color: hsl(132.8, 93.4%, 29.6%); font-weight: bold; } .changeling { - color: #059223; + color: hsl(132.8, 93.4%, 29.6%); font-style: italic; } .alertsyndie { - color: #ff0000; + color: hsl(0, 100%, 50%); font-size: 185%; font-weight: bold; } .spiderbroodmother { - color: #8800ff; + color: hsl(272, 100%, 50%); font-weight: bold; font-size: 185%; } .spiderbreacher { - color: #e8b670; + color: hsl(35, 72.3%, 67.5%); font-weight: bold; font-size: 140%; } .spiderscout { - color: #231d98; + color: hsl(242.9, 68%, 35.5%); font-weight: bold; font-size: 120%; } .interface { - color: #750e75; + color: hsl(300, 78.6%, 25.7%); } .sans { @@ -751,7 +751,7 @@ em { } .tape_recorder { - color: #ff0000; + color: hsl(0, 100%, 50%); font-family: 'Courier New', cursive, sans-serif; } @@ -786,17 +786,17 @@ em { } .greentext { - color: #059223; + color: hsl(132.8, 93.4%, 29.6%); font-size: 185%; } .redtext { - color: #c51e1e; + color: hsl(0, 73.6%, 44.5%); font-size: 185%; } .clown { - color: #ff70c1; + color: hsl(326, 100%, 72%); font-size: 160%; font-family: 'Comic Sans MS', cursive, sans-serif; font-weight: bold; @@ -808,13 +808,13 @@ em { } .his_grace { - color: #15d512; + color: hsl(119.1, 84.4%, 45.3%); font-family: 'Courier New', cursive, sans-serif; font-style: italic; } .hypnophrase { - color: #202020; + color: hsl(0, 0%, 12.5%); font-weight: bold; animation: hypnocolor 1500ms infinite; animation-direction: alternate; @@ -822,43 +822,43 @@ em { @keyframes hypnocolor { 0% { - color: #202020; + color: hsl(0, 0%, 12.5%); } 25% { - color: #4b02ac; + color: hsl(265.8, 97.7%, 34.1%); } 50% { - color: #9f41f1; + color: hsl(272, 86.3%, 60%); } 75% { - color: #541c9c; + color: hsl(266.2, 69.6%, 36.1%); } 100% { - color: #7adbf3; + color: hsl(191.9, 83.4%, 71.6%); } } .phobia { - color: #dd0000; + color: hsl(0, 100%, 43.3%); font-weight: bold; animation: phobia 750ms infinite; } @keyframes phobia { 0% { - color: #f75a5a; + color: hsl(0, 90.8%, 66.1%); } 50% { - color: #dd0000; + color: hsl(0, 100%, 43.3%); } 100% { - color: #f75a5a; + color: hsl(0, 90.8%, 66.1%); } } @@ -876,7 +876,7 @@ em { } .memo { - color: #638500; + color: hsl(75.3, 100%, 26.1%); text-align: center; } @@ -886,35 +886,35 @@ em { } .abductor { - color: #c204c2; + color: hsl(300, 96%, 38.8%); font-style: italic; } .mind_control { - color: #df3da9; + color: hsl(320, 71.7%, 55.7%); font-size: 100%; font-weight: bold; font-style: italic; } .slime { - color: #00ced1; + color: hsl(180.9, 100%, 41%); } .drone { - color: #848482; + color: hsl(60, 0.8%, 51.4%); } .monkey { - color: #975032; + color: hsl(17.8, 50.2%, 39.4%); } .swarmer { - color: #2c75ff; + color: hsl(219.2, 100%, 58.6%); } .resonate { - color: #298f85; + color: hsl(174.1, 55.4%, 36.1%); } .upside_down { @@ -938,7 +938,7 @@ em { } .internal.boldnshit { - color: #3d5bc3; + color: hsl(226.6, 52.8%, 50.2%); font-weight: bold; } @@ -967,8 +967,8 @@ em { } .examine_block { - background: #1b1c1e; - border: 1px solid #a4bad6; + background: hsl(220, 5.3%, 11.2%); + border: 1px solid hsl(213.6, 37.9%, 74.1%); margin: 0.5em; padding: 0.5em 0.75em; } @@ -990,7 +990,7 @@ em { .separator::after { content: ''; flex: 1; - border-bottom: 1px solid #a4bad6; + border-bottom: 1px solid hsl(213.6, 37.9%, 74.1%); } .separator:not(:empty)::before { @@ -1020,51 +1020,51 @@ em { } $alert-stripe-colors: ( - 'default': #00283a, - 'green': #003d00, - 'blue': #00283a, - 'pink': #30001b, - 'yellow': #574a00, - 'orange': #593400, - 'red': #420000, - 'purple': #2c0030, - 'grey': #252525, + 'default': hsl(198.6, 100%, 11.4%), + 'green': hsl(120, 100%, 12%), + 'blue': hsl(198.6, 100%, 11.4%), + 'pink': hsl(326.2, 100%, 9.4%), + 'yellow': hsl(51, 100%, 17.1%), + 'orange': hsl(35.1, 100%, 17.5%), + 'red': hsl(0, 100%, 12.9%), + 'purple': hsl(295, 100%, 9.4%), + 'grey': hsl(0, 0%, 14.5%), ); $alert-stripe-alternate-colors: ( - 'default': #003045, - 'green': #004700, - 'blue': #003045, - 'pink': #400025, - 'yellow': #4d4100, - 'orange': #6b4200, - 'red': #520000, - 'purple': #38003d, - 'grey': #292929, + 'default': hsl(198.3, 100%, 13.5%), + 'green': hsl(120, 100%, 13.9%), + 'blue': hsl(198.3, 100%, 13.5%), + 'pink': hsl(325.3, 100%, 12.5%), + 'yellow': hsl(50.6, 100%, 15.1%), + 'orange': hsl(37, 100%, 21%), + 'red': hsl(0, 100%, 16.1%), + 'purple': hsl(295.1, 100%, 12%), + 'grey': hsl(0, 0%, 16.1%), ); $alert-major-header-colors: ( - 'default': #33d5ff, - 'green': #00ff80, - 'blue': #33d5ff, - 'pink': #ff5297, - 'yellow': #fff4e0, - 'orange': #feefe7, - 'red': #ff5297, - 'purple': #c7a1f7, - 'grey': #ff5297, + 'default': hsl(192.4, 100%, 60%), + 'green': hsl(150.1, 100%, 50%), + 'blue': hsl(192.4, 100%, 60%), + 'pink': hsl(336.1, 100%, 66.1%), + 'yellow': hsl(38.7, 100%, 93.9%), + 'orange': hsl(20.9, 92%, 95.1%), + 'red': hsl(336.1, 100%, 66.1%), + 'purple': hsl(266.5, 84.3%, 80%), + 'grey': hsl(336.1, 100%, 66.1%), ); $alert-subheader-header-colors: ( - 'default': #ff5297, - 'green': #ff85b5, - 'blue': #ff5297, - 'pink': #33d5ff, - 'yellow': #33d5ff, - 'orange': #33d5ff, - 'red': #33d5ff, - 'purple': #33d5ff, - 'grey': #33d5ff, + 'default': hsl(336.1, 100%, 66.1%), + 'green': hsl(336.4, 100%, 76.1%), + 'blue': hsl(336.1, 100%, 66.1%), + 'pink': hsl(192.4, 100%, 60%), + 'yellow': hsl(192.4, 100%, 60%), + 'orange': hsl(192.4, 100%, 60%), + 'red': hsl(192.4, 100%, 60%), + 'purple': hsl(192.4, 100%, 60%), + 'grey': hsl(192.4, 100%, 60%), ); $border-width: 4; @@ -1091,8 +1091,8 @@ $border-width-px: $border-width * 1px; } .major_announcement_text { - color: #eaeaea; - background-color: #131313; + color: hsl(0, 0%, 91.8%); + background-color: hsl(0, 0%, 7.5%); font-weight: bold; font-size: 100%; text-align: left; @@ -1113,8 +1113,8 @@ $border-width-px: $border-width * 1px; } .minor_announcement_text { - background-color: #202020; - color: #eaeaea; + background-color: hsl(0, 0%, 12.5%); + color: hsl(0, 0%, 91.8%); padding: 0.5rem 0.5rem; text-align: left; font-size: 100%; @@ -1127,18 +1127,18 @@ $border-width-px: $border-width * 1px; } .ooc_alert { - background: #4d4100; - border: 1px solid #cca300; + background: hsl(50.6, 100%, 15.1%); + border: 1px solid hsl(47.9, 100%, 40%); margin: 0.5em; padding: 0.5em 0.5em 0.5em 0.2em; - color: #ffffff; + color: hsl(0, 0%, 100%); font-weight: bold; display: flex; flex-direction: column; } .ooc_announcement_text { - color: #cca300; + color: hsl(47.9, 100%, 40%); padding: 0.5em 0 0 0.35em; display: flex; flex-direction: column; @@ -1146,7 +1146,7 @@ $border-width-px: $border-width * 1px; @each $color-name, $color-value in $alert-stripe-colors { .chat_alert_#{$color-name} { - color: #ffffff; + color: hsl(0, 0%, 100%); padding: 0.5rem 0.5rem; box-shadow: none; font-weight: bold; diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss index d6ecb23b400e1..a3d0688ce362c 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss @@ -11,7 +11,7 @@ body { padding: 0; margin: 0; height: 100%; - color: #000000; + color: hsl(0, 0%, 0%); } body { @@ -45,15 +45,15 @@ img.icon { } a { - color: #0000ff; + color: hsl(240, 100%, 50%); } a.visited { - color: #ff00ff; + color: hsl(300, 100%, 50%); } a:visited { - color: #ff00ff; + color: hsl(300, 100%, 50%); } a.popt { @@ -157,7 +157,7 @@ a.popt { } .highlightPopup input.highlightColor { - background-color: #ffff00; + background-color: hsl(60, 100%, 50%); } .highlightPopup input.highlightTermSubmit { @@ -217,7 +217,7 @@ a.popt { /* MOTD */ .motd { - color: #638500; + color: hsl(75.3, 100%, 26.1%); font-family: Verdana, sans-serif; white-space: normal; } @@ -228,7 +228,7 @@ a.popt { .motd h4, .motd h5, .motd h6 { - color: #638500; + color: hsl(75.3, 100%, 26.1%); text-decoration: underline; } @@ -237,7 +237,7 @@ a.popt { .motd a:visited, .motd a:active, .motd a:hover { - color: #638500; + color: hsl(75.3, 100%, 26.1%); } /* ADD HERE FOR BOLD */ @@ -273,13 +273,13 @@ h3, h4, h5, h6 { - color: #0000ff; + color: hsl(240, 100%, 50%); font-family: Georgia, Verdana, sans-serif; } h1.alert, h2.alert { - color: #000000; + color: hsl(0, 0%, 0%); } em { @@ -288,27 +288,27 @@ em { } .ooc { - color: #002eb8; + color: hsl(225, 100%, 36.1%); font-weight: bold; } .adminobserverooc { - color: #0099cc; + color: hsl(195, 100%, 40%); font-weight: bold; } .adminooc { - color: #700038; + color: hsl(330, 100%, 22%); font-weight: bold; } .adminsay { - color: #ff4500; + color: hsl(16.2, 100%, 50%); font-weight: bold; } .admin { - color: #4473ff; + color: hsl(224.9, 100%, 63.3%); font-weight: bold; } @@ -324,90 +324,90 @@ em { } .deadsay { - color: #5c00e6; + color: hsl(264, 100%, 45.1%); } .binarysay { - color: #20c20e; - background-color: #000000; + color: hsl(114, 86.5%, 40.8%); + background-color: hsl(0, 0%, 0%); display: block; } .binarysay a { - color: #00ff00; + color: hsl(120, 100%, 50%); } .binarysay a:active, .binarysay a:visited { - color: #88ff88; + color: hsl(120, 100%, 76.7%); } .radio { - color: #008000; + color: hsl(120, 100%, 25.1%); } .sciradio { - color: #993399; + color: hsl(300, 50%, 40%); } .comradio { - color: #948f02; + color: hsl(57.9, 97.3%, 29.4%); } .secradio { - color: #a30000; + color: hsl(0, 100%, 32%); } .medradio { - color: #337296; + color: hsl(201.8, 49.3%, 39.4%); } .engradio { - color: #fb5613; + color: hsl(17.3, 96.7%, 52.9%); } .suppradio { - color: #a8732b; + color: hsl(34.6, 59.2%, 41.4%); } .servradio { - color: #6eaa2c; + color: hsl(88.6, 58.9%, 42%); } .syndradio { - color: #6d3f40; + color: hsl(358.7, 26.7%, 33.7%); } .gangradio { - color: #ac2ea1; + color: hsl(305.2, 57.8%, 42.7%); } .centcomradio { - color: #686868; + color: hsl(0, 0%, 40.8%); } .aiprivradio { - color: #ff00ff; + color: hsl(300, 100%, 50%); } .enteradio { - color: #5c8a87; + color: hsl(176.1, 20%, 45.1%); } .redteamradio { - color: #ff0000 !important; + color: hsl(0, 100%, 50%) !important; } .blueteamradio { - color: #0000ff !important; + color: hsl(240, 100%, 50%) !important; } .greenteamradio { - color: #00ff00 !important; + color: hsl(120, 100%, 50%) !important; } .yellowteamradio { - color: #d1ba22 !important; + color: hsl(52.1, 72%, 47.6%) !important; } .yell { @@ -415,345 +415,345 @@ em { } .alert { - color: #ff0000; + color: hsl(0, 100%, 50%); } h1.alert, h2.alert { - color: #000000; + color: hsl(0, 0%, 0%); } .userdanger { - color: #ff0000; + color: hsl(0, 100%, 50%); font-weight: bold; font-size: 185%; } .bolddanger { - color: #ff0000; + color: hsl(0, 100%, 50%); font-weight: bold; } .danger { - color: #ff0000; + color: hsl(0, 100%, 50%); } .tinydanger { - color: #ff0000; + color: hsl(0, 100%, 50%); font-size: 85%; } .smalldanger { - color: #ff0000; + color: hsl(0, 100%, 50%); font-size: 90%; } .warning { - color: #ff0000; + color: hsl(0, 100%, 50%); font-style: italic; } .alertwarning { - color: #ff0000; + color: hsl(0, 100%, 50%); font-weight: bold; } .boldwarning { - color: #ff0000; + color: hsl(0, 100%, 50%); font-style: italic; font-weight: bold; } .announce { - color: #228b22; + color: hsl(120, 60.7%, 33.9%); font-weight: bold; } .boldannounce { - color: #ff0000; + color: hsl(0, 100%, 50%); font-weight: bold; } .minorannounce { - color: #ff0000; + color: hsl(0, 100%, 50%); font-weight: bold; font-size: 185%; } .minoralert { - color: #000000; + color: hsl(0, 0%, 0%); font-size: 125%; } .priorityannounce { - color: #000000; + color: hsl(0, 0%, 0%); font-weight: bold; font-size: 225%; } .prioritytitle { - color: #0000ff; + color: hsl(240, 100%, 50%); font-weight: bold; font-size: 185%; } .priorityalert { - color: #ff0000; + color: hsl(0, 100%, 50%); font-size: 140%; } .greenannounce { - color: #00ff00; + color: hsl(120, 100%, 50%); font-weight: bold; } .rose { - color: #ff5050; + color: hsl(0, 100%, 65.7%); } .info { - color: #0000cc; + color: hsl(240, 100%, 40%); } .notice { - color: #000099; + color: hsl(240, 100%, 30%); } .tinynotice { - color: #000099; + color: hsl(240, 100%, 30%); font-size: 85%; } .tinynoticeital { - color: #000099; + color: hsl(240, 100%, 30%); font-style: italic; font-size: 85%; } .smallnotice { - color: #000099; + color: hsl(240, 100%, 30%); font-size: 90%; } .smallnoticeital { - color: #000099; + color: hsl(240, 100%, 30%); font-style: italic; font-size: 90%; } .boldnotice { - color: #000099; + color: hsl(240, 100%, 30%); font-weight: bold; } .hear { - color: #000099; + color: hsl(240, 100%, 30%); font-style: italic; } .adminnotice { - color: #0000ff; + color: hsl(240, 100%, 50%); } .adminhelp { - color: #ff0000; + color: hsl(0, 100%, 50%); font-weight: bold; } .unconscious { - color: #0000ff; + color: hsl(240, 100%, 50%); font-weight: bold; } .suicide { - color: #ff5050; + color: hsl(0, 100%, 65.7%); font-style: italic; } .green { - color: #03ff39; + color: hsl(132.9, 100%, 50.6%); } .grey { - color: #838383; + color: hsl(0, 0%, 51.4%); } .red { - color: #ff0000; + color: hsl(0, 100%, 50%); } .blue { - color: #0000ff; + color: hsl(240, 100%, 50%); } .nicegreen { - color: #14a833; + color: hsl(132.6, 78.7%, 36.9%); } .boldnicegreen { - color: #14a833; + color: hsl(132.6, 78.7%, 36.9%); font-weight: bold; } .cult { - color: #973e3b; + color: hsl(2, 43.8%, 41.2%); } .cultitalic { - color: #973e3b; + color: hsl(2, 43.8%, 41.2%); font-style: italic; } .cult_bold { - color: #973e3b; + color: hsl(2, 43.8%, 41.2%); font-style: italic; font-weight: bold; } .cult_bold_italic { - color: #973e3b; + color: hsl(2, 43.8%, 41.2%); font-weight: bold; font-size: 185%; } .cult_large { - color: #973e3b; + color: hsl(2, 43.8%, 41.2%); font-weight: bold; font-size: 185%; } .blob { - color: #ee4000; + color: hsl(16.1, 100%, 46.7%); } .blobannounce { - color: #323f1c; + color: hsl(82.3, 38.5%, 17.8%); font-weight: bold; font-size: 185%; } .narsie { - color: #973e3b; + color: hsl(2, 43.8%, 41.2%); font-weight: bold; font-size: 925%; } .narsiesmall { - color: #973e3b; + color: hsl(2, 43.8%, 41.2%); font-weight: bold; font-size: 370%; } .colossus { - color: #7f282a; + color: hsl(358.6, 52.1%, 32.7%); font-size: 310%; } .hierophant { - color: #660099; + color: hsl(280, 100%, 30%); font-weight: bold; font-style: italic; } .hierophant_warning { - color: #660099; + color: hsl(280, 100%, 30%); font-style: italic; } .purple { - color: #5e2d79; + color: hsl(278.7, 45.8%, 32.5%); } .holoparasite { - color: #35333a; + color: hsl(257.1, 6.4%, 21.4%); } .revennotice { - color: #1d2953; + color: hsl(226.7, 48.2%, 22%); } .revenboldnotice { - color: #1d2953; + color: hsl(226.7, 48.2%, 22%); font-weight: bold; } .revenbignotice { - color: #1d2953; + color: hsl(226.7, 48.2%, 22%); font-weight: bold; font-size: 185%; } .revenminor { - color: #823abb; + color: hsl(273.5, 52.7%, 48%); } .revenwarning { - color: #760fbb; + color: hsl(275.9, 85.1%, 39.6%); font-style: italic; } .revendanger { - color: #760fbb; + color: hsl(275.9, 85.1%, 39.6%); font-weight: bold; font-size: 185%; } .deconversion_message { - color: #5000a0; + color: hsl(270, 100%, 31.4%); font-size: 185%; font-style: italic; } .ghostalert { - color: #5c00e6; + color: hsl(264, 100%, 45.1%); font-style: italic; font-weight: bold; } .alien { - color: #543354; + color: hsl(300, 24.4%, 26.5%); } .noticealien { - color: #00c000; + color: hsl(120, 100%, 37.6%); } .alertalien { - color: #00c000; + color: hsl(120, 100%, 37.6%); font-weight: bold; } .changeling { - color: #800080; + color: hsl(300, 100%, 25.1%); font-style: italic; } .alertsyndie { - color: #ff0000; + color: hsl(0, 100%, 50%); font-size: 185%; font-weight: bold; } .spiderbroodmother { - color: #4d004d; + color: hsl(300, 100%, 15.1%); font-weight: bold; font-size: 185%; } .spiderbreacher { - color: #804b02; + color: hsl(34.8, 96.9%, 25.5%); font-weight: bold; font-size: 140%; } .spiderscout { - color: #0c0674; + color: hsl(243.3, 90.2%, 23.9%); font-weight: bold; font-size: 120%; } .interface { - color: #330033; + color: hsl(300, 100%, 10%); } .sans { @@ -769,7 +769,7 @@ h2.alert { } .tape_recorder { - color: #800000; + color: hsl(0, 100%, 25.1%); font-family: 'Courier New', cursive, sans-serif; } @@ -804,17 +804,17 @@ h2.alert { } .greentext { - color: #00ff00; + color: hsl(120, 100%, 50%); font-size: 185%; } .redtext { - color: #ff0000; + color: hsl(0, 100%, 50%); font-size: 185%; } .clown { - color: #ff69bf; + color: hsl(325.6, 100%, 70.6%); font-size: 160%; font-family: 'Comic Sans MS', cursive, sans-serif; font-weight: bold; @@ -826,13 +826,13 @@ h2.alert { } .his_grace { - color: #15d512; + color: hsl(119.1, 84.4%, 45.3%); font-family: 'Courier New', cursive, sans-serif; font-style: italic; } .hypnophrase { - color: #0d0d0d; + color: hsl(0, 0%, 5.1%); font-weight: bold; animation: hypnocolor 1500ms infinite; animation-direction: alternate; @@ -840,43 +840,43 @@ h2.alert { @keyframes hypnocolor { 0% { - color: #0d0d0d; + color: hsl(0, 0%, 5.1%); } 25% { - color: #410194; + color: hsl(266.1, 98.7%, 29.2%); } 50% { - color: #7f17d8; + color: hsl(272.3, 80.8%, 46.9%); } 75% { - color: #410194; + color: hsl(266.1, 98.7%, 29.2%); } 100% { - color: #3bb5d3; + color: hsl(191.8, 63.3%, 52.9%); } } .phobia { - color: #dd0000; + color: hsl(0, 100%, 43.3%); font-weight: bold; animation: phobia 750ms infinite; } @keyframes phobia { 0% { - color: #0d0d0d; + color: hsl(0, 0%, 5.1%); } 50% { - color: #dd0000; + color: hsl(0, 100%, 43.3%); } 100% { - color: #0d0d0d; + color: hsl(0, 0%, 5.1%); } } @@ -894,7 +894,7 @@ h2.alert { } .memo { - color: #638500; + color: hsl(75.3, 100%, 26.1%); text-align: center; } @@ -904,35 +904,35 @@ h2.alert { } .abductor { - color: #800080; + color: hsl(300, 100%, 25.1%); font-style: italic; } .mind_control { - color: #a00d6f; + color: hsl(320, 85%, 33.9%); font-size: 100%; font-weight: bold; font-style: italic; } .slime { - color: #00ced1; + color: hsl(180.9, 100%, 41%); } .drone { - color: #848482; + color: hsl(60, 0.8%, 51.4%); } .monkey { - color: #975032; + color: hsl(17.8, 50.2%, 39.4%); } .swarmer { - color: #2c75ff; + color: hsl(219.2, 100%, 58.6%); } .resonate { - color: #298f85; + color: hsl(174.1, 55.4%, 36.1%); } .upside_down { @@ -985,8 +985,8 @@ h2.alert { } .examine_block { - background: #f2f7fa; - border: 1px solid #111a27; + background: hsl(202.5, 44.4%, 96.5%); + border: 1px solid hsl(215.5, 39.3%, 11%); margin: 0.5em; padding: 0.5em 0.75em; } @@ -1008,7 +1008,7 @@ h2.alert { .separator::after { content: ''; flex: 1; - border-bottom: 1px solid #111a27; + border-bottom: 1px solid hsl(215.5, 39.3%, 11%); } .separator:not(:empty)::before { @@ -1038,51 +1038,51 @@ h2.alert { } $alert-stripe-colors: ( - 'default': #b3bfff, - 'green': #adffad, - 'blue': #b3bfff, - 'pink': #ffb3df, - 'yellow': #fff3b3, - 'orange': #ffe2b3, - 'red': #ffb3b3, - 'purple': #fac2ff, - 'grey': #e3e3e3, + 'default': hsl(230.5, 100%, 85.1%), + 'green': hsl(120, 100%, 83.9%), + 'blue': hsl(230.5, 100%, 85.1%), + 'pink': hsl(325.3, 100%, 85.1%), + 'yellow': hsl(50.5, 100%, 85.1%), + 'orange': hsl(37.1, 100%, 85.1%), + 'red': hsl(0, 100%, 85.1%), + 'purple': hsl(295.1, 100%, 88%), + 'grey': hsl(0, 0%, 89%), ); $alert-stripe-alternate-colors: ( - 'default': #bdc8ff, - 'green': #bdffbd, - 'blue': #bdc8ff, - 'pink': #ffc2e5, - 'yellow': #fff5c2, - 'orange': #ffe8c2, - 'red': #ffc2c2, - 'purple': #fbd1ff, - 'grey': #ebebeb, + 'default': hsl(230, 100%, 87.1%), + 'green': hsl(120, 100%, 87.1%), + 'blue': hsl(230, 100%, 87.1%), + 'pink': hsl(325.6, 100%, 88%), + 'yellow': hsl(50.2, 100%, 88%), + 'orange': hsl(37.4, 100%, 88%), + 'red': hsl(0, 100%, 88%), + 'purple': hsl(294.8, 100%, 91%), + 'grey': hsl(0, 0%, 92.2%), ); $alert-major-header-colors: ( - 'default': #003061, - 'green': #005229, - 'blue': #003061, - 'pink': #800033, - 'yellow': #754900, - 'orange': #823208, - 'red': #800029, - 'purple': #450d8c, - 'grey': #800033, + 'default': hsl(210.3, 100%, 19%), + 'green': hsl(150, 100%, 16.1%), + 'blue': hsl(210.3, 100%, 19%), + 'pink': hsl(336.1, 100%, 25.1%), + 'yellow': hsl(37.4, 100%, 22.9%), + 'orange': hsl(20.7, 88.4%, 27.1%), + 'red': hsl(340.8, 100%, 25.1%), + 'purple': hsl(266.5, 83%, 30%), + 'grey': hsl(336.1, 100%, 25.1%), ); $alert-subheader-header-colors: ( - 'default': #6b0020, - 'green': #6b0020, - 'blue': #6b0020, - 'pink': #002c85, - 'yellow': #002c85, - 'orange': #002c85, - 'red': #002c85, - 'purple': #002c85, - 'grey': #002c85, + 'default': hsl(342.1, 100%, 21%), + 'green': hsl(342.1, 100%, 21%), + 'blue': hsl(342.1, 100%, 21%), + 'pink': hsl(220.2, 100%, 26.1%), + 'yellow': hsl(220.2, 100%, 26.1%), + 'orange': hsl(220.2, 100%, 26.1%), + 'red': hsl(220.2, 100%, 26.1%), + 'purple': hsl(220.2, 100%, 26.1%), + 'grey': hsl(220.2, 100%, 26.1%), ); $border-width: 4; @@ -1109,8 +1109,8 @@ $border-width-px: $border-width * 1px; } .major_announcement_text { - color: #131313; - background-color: #eaeaea; + color: hsl(0, 0%, 7.5%); + background-color: hsl(0, 0%, 91.8%); font-weight: bold; font-size: 100%; text-align: left; @@ -1131,8 +1131,8 @@ $border-width-px: $border-width * 1px; } .minor_announcement_text { - background-color: #eaeaea; - color: #202020; + background-color: hsl(0, 0%, 91.8%); + color: hsl(0, 0%, 12.5%); padding: 0.5rem 0.5rem; text-align: left; font-size: 100%; @@ -1145,18 +1145,18 @@ $border-width-px: $border-width * 1px; } .ooc_alert { - background: #bdc8ff; - border: 1px solid #002eb8; + background: hsl(230, 100%, 87.1%); + border: 1px solid hsl(225, 100%, 36.1%); margin: 0.5em; padding: 0.5em 0.5em 0.5em 0.2em; - color: #00283a; + color: hsl(198.6, 100%, 11.4%); font-weight: bold; display: flex; flex-direction: column; } .ooc_announcement_text { - color: #002eb8; + color: hsl(225, 100%, 36.1%); padding: 0.5em 0 0 0.35em; display: flex; flex-direction: column; @@ -1164,7 +1164,7 @@ $border-width-px: $border-width * 1px; @each $color-name, $color-value in $alert-stripe-colors { .chat_alert_#{$color-name} { - color: #ffffff; + color: hsl(0, 0%, 100%); padding: 0.5rem 0.5rem; box-shadow: none; font-weight: bold; diff --git a/tgui/packages/tgui-panel/styles/themes/light.scss b/tgui/packages/tgui-panel/styles/themes/light.scss index f8bfd67ee934f..659bb7130962d 100644 --- a/tgui/packages/tgui-panel/styles/themes/light.scss +++ b/tgui/packages/tgui-panel/styles/themes/light.scss @@ -7,21 +7,21 @@ @use 'sass:meta'; @use '~tgui/styles/colors.scss' with ( - $primary: #ffffff, + $primary: hsl(0, 0%, 100%), $bg-lightness: -25%, $fg-lightness: -10%, - $label: #3b3b3b, + $label: hsl(0, 0%, 23.1%), // Makes button look actually grey due to weird maths. - $grey: #ffffff, + $grey: hsl(0, 0%, 100%), // Commenting out color maps will adjust all colors based on the lightness // settings above, but will add extra 10KB to the theme. // $fg-map-keys: (), // $bg-map-keys: (), ); @use '~tgui/styles/base.scss' with ( - $color-fg: #000000, - $color-bg: #eeeeee, - $color-bg-section: #ffffff, + $color-fg: hsl(0, 0%, 0%), + $color-bg: hsl(0, 0%, 93.3%), + $color-bg-section: hsl(0, 0%, 100%), $color-bg-grad-spread: 0% ); @@ -45,11 +45,11 @@ @include meta.load-css( '~tgui/styles/components/Button.scss', $with: ( - 'color-default': #bbbbbb, - 'color-disabled': #363636, - 'color-selected': #0668b8, - 'color-caution': #be6209, - 'color-danger': #9a9d00, + 'color-default': hsl(0, 0%, 73.3%), + 'color-disabled': hsl(0, 0%, 21.2%), + 'color-selected': hsl(204, 94%, 35.3%), + 'color-caution': hsl(28, 91%, 38.2%), + 'color-danger': hsl(62, 100%, 30.2%), 'color-transparent-text': rgba(0, 0, 0, 0.5) ) ); @@ -57,7 +57,7 @@ '~tgui/styles/components/Input.scss', $with: ( 'border-color': colors.fg(colors.$label), - 'background-color': #e6e6e6 + 'background-color': hsl(0, 0%, 90.2%) ) ); @include meta.load-css('~tgui/styles/components/NumberInput.scss'); @@ -69,7 +69,7 @@ // Components specific to tgui-panel @include meta.load-css( '../components/Chat.scss', - $with: ('text-color': #000000) + $with: ('text-color': hsl(0, 0%, 0%)) ); // Layouts diff --git a/tgui/packages/tgui-say/styles/colors.scss b/tgui/packages/tgui-say/styles/colors.scss index c7a7de452d54f..5113af953e740 100644 --- a/tgui/packages/tgui-say/styles/colors.scss +++ b/tgui/packages/tgui-say/styles/colors.scss @@ -1,31 +1,31 @@ @use 'sass:map'; -$background: #131313; -$button: #1f1f1f; -$lightMode: #ffffff; -$lightBorder: #bbbbbb; -$lightHover: #eaeaea; +$background: hsl(0, 0%, 7.5%); +$button: hsl(0, 0%, 12.2%); +$lightMode: hsl(0, 0%, 100%); +$lightBorder: hsl(0, 0%, 73.3%); +$lightHover: hsl(0, 0%, 91.8%); $_channel_map: ( - 'Admin': #ffbbff, - 'AI': #d65d95, - 'CCom': #2681a5, - 'Cling': #4c701f, - 'Cmd': #fcdf03, - 'Engi': #f37746, - 'Hive': #855d85, - 'io': #1e90ff, - 'Me': #5975da, - 'Med': #57b8f0, - 'OOC': #cca300, - 'Ent': #5c8a87, - 'Radio': #1ecc43, - 'Say': #a4bad6, - 'Sci': #c68cfa, - 'Sec': #dd3535, - 'Supp': #b88646, - 'Svc': #6ca729, - 'Synd': #8f4a4b, + 'Admin': hsl(300, 100%, 86.7%), + 'AI': hsl(332.2, 59.6%, 60.2%), + 'CCom': hsl(197, 62.6%, 39.8%), + 'Cling': hsl(86.7, 56.6%, 28%), + 'Cmd': hsl(53, 97.6%, 50%), + 'Engi': hsl(17, 87.8%, 61.4%), + 'Hive': hsl(300, 17.7%, 44.3%), + 'io': hsl(209.6, 100%, 55.9%), + 'Me': hsl(227, 63.5%, 60.2%), + 'Med': hsl(202, 83.6%, 64.1%), + 'OOC': hsl(47.9, 100%, 40%), + 'Ent': hsl(176.1, 20%, 45.1%), + 'Radio': hsl(132.8, 74.4%, 45.9%), + 'Say': hsl(213.6, 37.9%, 74.1%), + 'Sci': hsl(271.6, 91.7%, 76.5%), + 'Sec': hsl(0, 71.2%, 53.7%), + 'Supp': hsl(33.7, 44.9%, 49.8%), + 'Svc': hsl(88.1, 60.6%, 40.8%), + 'Synd': hsl(359.1, 31.8%, 42.5%), ); $channel_keys: map.keys($_channel_map) !default; diff --git a/tgui/packages/tgui/styles/atomic/candystripe.scss b/tgui/packages/tgui/styles/atomic/candystripe.scss index 30159bf99c306..ff46280ea51e4 100644 --- a/tgui/packages/tgui/styles/atomic/candystripe.scss +++ b/tgui/packages/tgui/styles/atomic/candystripe.scss @@ -4,5 +4,5 @@ */ .candystripe:nth-child(odd) { - background-color: rgba(0, 0, 0, 0.25); + background-color: hsla(0, 0%, 0%, 0.25); } diff --git a/tgui/packages/tgui/styles/atomic/debug-layout.scss b/tgui/packages/tgui/styles/atomic/debug-layout.scss index d015185927adb..0b0a2b7f4b2b2 100644 --- a/tgui/packages/tgui/styles/atomic/debug-layout.scss +++ b/tgui/packages/tgui/styles/atomic/debug-layout.scss @@ -5,13 +5,13 @@ .debug-layout, .debug-layout *:not(g):not(path) { - color: rgba(255, 255, 255, 0.9) !important; + color: hsla(0, 0%, 100%, 0.9) !important; background: transparent !important; - outline: 1px solid rgba(255, 255, 255, 0.5) !important; + outline: 1px solid hsla(0, 0%, 100%, 0.5) !important; box-shadow: none !important; filter: none !important; &:hover { - outline-color: rgba(255, 255, 255, 0.8) !important; + outline-color: hsla(0, 0%, 100%, 0.8) !important; } } diff --git a/tgui/packages/tgui/styles/base.scss b/tgui/packages/tgui/styles/base.scss index 3a99d5d28d755..a54e20c4c452f 100644 --- a/tgui/packages/tgui/styles/base.scss +++ b/tgui/packages/tgui/styles/base.scss @@ -6,8 +6,8 @@ @use 'sass:color'; @use 'sass:math'; -$color-fg: #ffffff !default; -$color-bg: #252525 !default; +$color-fg: hsl(0, 0%, 100%) !default; +$color-bg: hsl(0, 0%, 14%) !default; $color-bg-section: rgba(0, 0, 0, 0.33) !default; $color-bg-grad-spread: 2% !default; $color-bg-start: color.adjust( diff --git a/tgui/packages/tgui/styles/colors.scss b/tgui/packages/tgui/styles/colors.scss index 1488d09aa43c2..04493e92f2e85 100644 --- a/tgui/packages/tgui/styles/colors.scss +++ b/tgui/packages/tgui/styles/colors.scss @@ -8,27 +8,27 @@ @use 'sass:meta'; // Base colors -$black: #000000 !default; -$white: #ffffff !default; -$red: #db2828 !default; -$orange: #f2711c !default; -$yellow: #fbd608 !default; -$olive: #b5cc18 !default; -$green: #20b142 !default; -$teal: #00b5ad !default; -$blue: #2185d0 !default; -$violet: #6435c9 !default; -$purple: #a333c8 !default; -$pink: #e03997 !default; -$brown: #a5673f !default; -$grey: #767676 !default; -$light-grey: #aaa !default; +$black: hsl(0, 0%, 0%) !default; +$white: hsl(0, 0%, 100%) !default; +$red: hsl(0, 72%, 50%) !default; +$orange: hsl(24, 89%, 54%) !default; +$yellow: hsl(52, 97%, 52%) !default; +$olive: hsl(68, 76%, 45%) !default; +$green: hsl(136, 70%, 41%) !default; +$teal: hsl(178, 100%, 35%) !default; +$blue: hsl(208, 65%, 47%) !default; +$violet: hsl(259, 60%, 50%) !default; +$purple: hsl(288, 60%, 49%) !default; +$pink: hsl(326, 71%, 56%) !default; +$brown: hsl(24, 47%, 45%) !default; +$grey: hsl(0, 0%, 47%) !default; +$light-grey: hsl(0, 0%, 67%) !default; -$primary: #4972a1 !default; -$good: #5baa27 !default; -$average: #f08f11 !default; -$bad: #db2828 !default; -$label: #7e90a7 !default; +$primary: hsl(210, 37%, 46%) !default; +$good: hsl(94, 63%, 41%) !default; +$average: hsl(33, 89%, 50%) !default; +$bad: hsl(0, 72%, 50%) !default; +$label: hsl(210, 18%, 58%) !default; // Background and foreground color lightness ratios $bg-lightness: -15% !default; @@ -74,7 +74,7 @@ $bg-map-keys: map.keys($_gen_map) !default; $fg-map: (); @each $color-name in $fg-map-keys { // prettier-ignore - $fg-map: map-merge($fg-map, ( + $fg-map: map.merge($fg-map, ( $color-name: fg(map.get($_gen_map, $color-name)), )); } @@ -82,7 +82,7 @@ $fg-map: (); $bg-map: (); @each $color-name in $bg-map-keys { // prettier-ignore - $bg-map: map-merge($bg-map, ( + $bg-map: map.merge($bg-map, ( $color-name: bg(map.get($_gen_map, $color-name)), )); } diff --git a/tgui/packages/tgui/styles/components/Button.scss b/tgui/packages/tgui/styles/components/Button.scss index fe777e9d3ef52..525bc42a3bfc5 100644 --- a/tgui/packages/tgui/styles/components/Button.scss +++ b/tgui/packages/tgui/styles/components/Button.scss @@ -8,7 +8,7 @@ @use '../functions.scss' as *; $color-default: colors.bg(colors.$primary) !default; -$color-disabled: #999999 !default; +$color-disabled: hsl(0, 0%, 60%) !default; $color-selected: colors.bg(colors.$green) !default; $color-caution: colors.bg(colors.$yellow) !default; $color-danger: colors.bg(colors.$red) !default; diff --git a/tgui/packages/tgui/styles/components/Input.scss b/tgui/packages/tgui/styles/components/Input.scss index c2e779529f97a..6f15d89bb4107 100644 --- a/tgui/packages/tgui/styles/components/Input.scss +++ b/tgui/packages/tgui/styles/components/Input.scss @@ -7,8 +7,8 @@ @use '../functions.scss' as *; $text-color: base.$color-fg !default; -$background-color: #0a0a0a !default; -$border-color: #88bfff !default; +$background-color: hsl(0, 0%, 3.9%) !default; +$border-color: hsl(212.3, 100%, 76.7%) !default; $border-radius: base.$border-radius !default; .Input { diff --git a/tgui/packages/tgui/styles/components/Knob.scss b/tgui/packages/tgui/styles/components/Knob.scss index 1a5f0d10a998a..032d3c0de0c35 100644 --- a/tgui/packages/tgui/styles/components/Knob.scss +++ b/tgui/packages/tgui/styles/components/Knob.scss @@ -9,10 +9,10 @@ $bg-map: colors.$bg-map !default; $fg-map: colors.$fg-map !default; -$ring-color: #6a96c9 !default; -$knob-color: #333333 !default; -$popup-background-color: #000000 !default; -$popup-text-color: #ffffff !default; +$ring-color: hsl(212.2, 46.8%, 60.2%) !default; +$knob-color: hsl(0, 0%, 20%) !default; +$popup-background-color: hsl(0, 0%, 0%) !default; +$popup-text-color: hsl(0, 0%, 100%) !default; $inner-padding: 0.1em; diff --git a/tgui/packages/tgui/styles/components/MenuBar.scss b/tgui/packages/tgui/styles/components/MenuBar.scss index 0f5eb47380cdb..3c0ea66b0616e 100644 --- a/tgui/packages/tgui/styles/components/MenuBar.scss +++ b/tgui/packages/tgui/styles/components/MenuBar.scss @@ -1,3 +1,4 @@ +@use 'sass:color'; /** * Copyright (c) 2020 Aleksej Komarov * SPDX-License-Identifier: MIT @@ -21,7 +22,7 @@ $dropdown-z-index: 5; .MenuBar__hover { &:hover { - background-color: lighten($background-color, 30%); + background-color: color.adjust($background-color, $lightness: 30%); transition: background-color 0ms; } } diff --git a/tgui/packages/tgui/styles/components/NoticeBox.scss b/tgui/packages/tgui/styles/components/NoticeBox.scss index 0394ffaa660bb..75b3ac11a8e1c 100644 --- a/tgui/packages/tgui/styles/components/NoticeBox.scss +++ b/tgui/packages/tgui/styles/components/NoticeBox.scss @@ -9,9 +9,9 @@ @use '../functions.scss' as *; // NoticeBox -$background-color: #bb9b68 !default; +$background-color: hsl(36.9, 37.9%, 57.1%) !default; $color-stripes: rgba(0, 0, 0, 0.1) !default; -$color-border: #272727 !default; +$color-border: hsl(0, 0%, 15.3%) !default; $bg-map: colors.$bg-map !default; .NoticeBox { diff --git a/tgui/packages/tgui/styles/components/RoundGauge.scss b/tgui/packages/tgui/styles/components/RoundGauge.scss index be95519d64613..1975127e745a5 100644 --- a/tgui/packages/tgui/styles/components/RoundGauge.scss +++ b/tgui/packages/tgui/styles/components/RoundGauge.scss @@ -8,7 +8,7 @@ @use '../functions.scss' as *; $fg-map: colors.$fg-map !default; -$ring-color: #6a96c9 !default; +$ring-color: hsl(212.2, 46.8%, 60.2%) !default; .RoundGauge { font-size: 1rem; diff --git a/tgui/packages/tgui/styles/components/SearchItem.scss b/tgui/packages/tgui/styles/components/SearchItem.scss index 5dadcdf8d6aea..bd6af021e2d27 100644 --- a/tgui/packages/tgui/styles/components/SearchItem.scss +++ b/tgui/packages/tgui/styles/components/SearchItem.scss @@ -9,7 +9,7 @@ .SearchItem--box { background: black; - border: thin solid #212121; + border: thin solid hsl(0, 0%, 12.9%); display: flex; align-items: center; justify-content: center; diff --git a/tgui/packages/tgui/styles/components/Slider.scss b/tgui/packages/tgui/styles/components/Slider.scss index 83baf71dc0991..000c814d314fb 100644 --- a/tgui/packages/tgui/styles/components/Slider.scss +++ b/tgui/packages/tgui/styles/components/Slider.scss @@ -6,8 +6,8 @@ @use '../base.scss'; $cursor-color: base.$color-fg !default; -$popup-background-color: #000000 !default; -$popup-text-color: #ffffff !default; +$popup-background-color: hsl(0, 0%, 0%) !default; +$popup-text-color: hsl(0, 0%, 100%) !default; .Slider { cursor: e-resize; diff --git a/tgui/packages/tgui/styles/components/Tooltip.scss b/tgui/packages/tgui/styles/components/Tooltip.scss index 497813a206d0c..e6db806fa01d6 100644 --- a/tgui/packages/tgui/styles/components/Tooltip.scss +++ b/tgui/packages/tgui/styles/components/Tooltip.scss @@ -6,8 +6,8 @@ @use '../base.scss'; @use '../functions.scss' as *; -$color: #ffffff !default; -$background-color: #000000 !default; +$color: hsl(0, 0%, 100%) !default; +$background-color: hsl(0, 0%, 0%) !default; $border-radius: base.$border-radius !default; .Tooltip { diff --git a/tgui/packages/tgui/styles/functions.scss b/tgui/packages/tgui/styles/functions.scss index 1c8d65e3a1756..403d43c7b4bcb 100644 --- a/tgui/packages/tgui/styles/functions.scss +++ b/tgui/packages/tgui/styles/functions.scss @@ -29,11 +29,11 @@ // Increases perceptual color lightness. @function lighten($color, $percent) { $scaled: hsl( - color.hue($color), - color.saturation($color), - color.lightness($color) * (1 + num($percent)) + color.channel($color, 'hue', $space: hsl), + color.channel($color, 'saturation', $space: hsl), + color.channel($color, 'lightness', $space: hsl) * (1 + num($percent)) ); - $mixed: color.mix(#ffffff, $color, 100% * num($percent)); + $mixed: color.mix(hsl(0, 0%, 100%), $color, 100% * num($percent)); @return color.mix($scaled, $mixed, 75%); } @@ -41,9 +41,9 @@ // 1 is pure white, 0 is pure black. @function luminance($color) { $colors: ( - 'red': color.red($color), - 'green': color.green($color), - 'blue': color.blue($color), + 'red': color.channel($color, 'red', $space: rgb), + 'green': color.channel($color, 'green', $space: rgb), + 'blue': color.channel($color, 'blue', $space: rgb), ); @each $name, $value in $colors { diff --git a/tgui/packages/tgui/styles/interfaces/DetectiveBoard.scss b/tgui/packages/tgui/styles/interfaces/DetectiveBoard.scss index 8aa8aae48bb1d..7f9c1f7a46155 100644 --- a/tgui/packages/tgui/styles/interfaces/DetectiveBoard.scss +++ b/tgui/packages/tgui/styles/interfaces/DetectiveBoard.scss @@ -26,8 +26,8 @@ } .BoardTab__Selected { - background-color: #edcf64; - border-bottom: 1px solid #edcf64; + background-color: hsl(45, 82%, 66%); + border-bottom: 1px solid hsl(45, 82%, 66%); transition: all 0.2s; } @@ -37,21 +37,21 @@ overflow: hidden; } .Evidence__Pin { - box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); - background-color: #db2828; + box-shadow: 0 0 10px hsla(0, 0%, 0%, 0.2); + background-color: hsl(0, 72%, 50%); border-radius: 20px; width: 15px; height: 15px; } .Evidence__Box { - box-shadow: 0 0 10px rgba(0, 0, 0, 0.4); + box-shadow: 0 0 10px hsla(0, 0%, 0%, 0.4); padding: 5px; color: black; min-width: 200px; max-width: 300px; - background-color: white; - border: 2px solid grey; + background-color: hsl(0, 0%, 100%); + border: 2px solid hsl(0, 0%, 50%); -ms-user-select: none; user-select: none; text-wrap: wrap; @@ -59,7 +59,7 @@ } .Evidence__Box__TextBox { - border-top: 1px solid #eaeaea; + border-top: 1px solid hsl(0, 0%, 92%); text-wrap: wrap; padding: 5px 0; margin-top: 5px; @@ -74,7 +74,7 @@ .Board__Content { position: relative; - background-color: #edcf64; + background-color: hsl(45, 82%, 66%); padding: 5px; overflow: hidden; height: 95%; @@ -82,7 +82,7 @@ .Evidence__Icon { margin-top: 5px; - border: 5px solid #e0e0e0; + border: 5px solid hsl(0, 0%, 88%); width: 100%; } diff --git a/tgui/packages/tgui/styles/interfaces/ExperimentConfigure.scss b/tgui/packages/tgui/styles/interfaces/ExperimentConfigure.scss index b4265b1fba5d0..4b218b397ef5d 100644 --- a/tgui/packages/tgui/styles/interfaces/ExperimentConfigure.scss +++ b/tgui/packages/tgui/styles/interfaces/ExperimentConfigure.scss @@ -1,12 +1,12 @@ .ExperimentTechwebServer__Web, .ExperimentConfigure__ExperimentPanel { - background: #000000; - border: 1px solid #40628a; + background: hsl(0, 0%, 0%); + border: 1px solid hsl(210, 33%, 41%); margin: 3px 0; } .ExperimentTechwebServer__WebHeader { - background: #40628a; + background: hsl(210, 33%, 41%); padding: 2px; } @@ -81,5 +81,5 @@ height: 100%; right: 0; top: 0; - color: rgba(255, 255, 255, 0.5); + color: hsla(0, 0%, 100%, 0.5); } diff --git a/tgui/packages/tgui/styles/interfaces/Fabricator.scss b/tgui/packages/tgui/styles/interfaces/Fabricator.scss index a7488f50a2c98..ccdf89d91fc21 100644 --- a/tgui/packages/tgui/styles/interfaces/Fabricator.scss +++ b/tgui/packages/tgui/styles/interfaces/Fabricator.scss @@ -66,6 +66,7 @@ } .MaterialDock--active .MaterialDock__Dock { + animation: materialdock-open 0.125s ease-out; @keyframes materialdock-open { 0% { opacity: 0; @@ -75,8 +76,6 @@ opacity: 1; } } - - animation: materialdock-open 0.125s ease-out; } .MaterialDock__Button { diff --git a/tgui/packages/tgui/styles/interfaces/Fishing.scss b/tgui/packages/tgui/styles/interfaces/Fishing.scss index f9967b2cb82e6..d65ddf27393ec 100644 --- a/tgui/packages/tgui/styles/interfaces/Fishing.scss +++ b/tgui/packages/tgui/styles/interfaces/Fishing.scss @@ -45,8 +45,8 @@ width: 100%; top: 0%; left: 0; - background: #4d5f2b; - border: 0px #4d5f2b; + background: hsl(80.8, 37.7%, 27.1%); + border: 0px hsl(80.8, 37.7%, 27.1%); border-radius: 10px; } @@ -71,7 +71,7 @@ .fishing .completion .bar { position: absolute; width: 100%; - background: #7cb413; + background: hsl(80.9, 80.9%, 39%); bottom: 0; border-radius: 5px; } diff --git a/tgui/packages/tgui/styles/interfaces/IntegratedCircuit.scss b/tgui/packages/tgui/styles/interfaces/IntegratedCircuit.scss index 7cfecb250acc4..c3fabf9f0212b 100644 --- a/tgui/packages/tgui/styles/interfaces/IntegratedCircuit.scss +++ b/tgui/packages/tgui/styles/interfaces/IntegratedCircuit.scss @@ -62,7 +62,7 @@ $fg-map: colors.$fg-map !default; } } -$border-color: #88bfff !default; +$border-color: hsl(210, 100%, 73%) !default; $border-radius: base.$border-radius !default; .IntegratedCircuit__BlueBorder { diff --git a/tgui/packages/tgui/styles/interfaces/Mecha.scss b/tgui/packages/tgui/styles/interfaces/Mecha.scss index 8795c8cb69da7..30e33d43b4a64 100644 --- a/tgui/packages/tgui/styles/interfaces/Mecha.scss +++ b/tgui/packages/tgui/styles/interfaces/Mecha.scss @@ -2,21 +2,21 @@ @use '../colors.scss'; @use '../functions.scss' as *; -$color-danger: #c92020 !default; +$color-danger: hsl(0, 74%, 45%) !default; .Mecha__displayBox { - background-color: #002003; - border: 0.167em inset #e8e4c9; - color: #03e017; + background-color: hsl(150, 100%, 1%); + border: 0.167em inset hsl(50, 33%, 91%); + color: hsl(132, 100%, 45%); font-size: 2em; font-family: monospace; padding: 0.25em; } .Mecha__displayBoxRed { - background-color: #002003; - border: 0.167em inset #e8e4c9; - color: #f54b4b; + background-color: hsl(150, 100%, 1%); + border: 0.167em inset hsl(50, 33%, 91%); + color: hsl(0, 89%, 64%); font-size: 2em; font-family: monospace; padding: 0.25em; diff --git a/tgui/packages/tgui/styles/interfaces/NtosMessenger.scss b/tgui/packages/tgui/styles/interfaces/NtosMessenger.scss index cc55e53678c6f..5a29d77f4647e 100644 --- a/tgui/packages/tgui/styles/interfaces/NtosMessenger.scss +++ b/tgui/packages/tgui/styles/interfaces/NtosMessenger.scss @@ -19,10 +19,10 @@ $msgpadding: 0.7rem; border-radius: 0; - background-color: lighten($msgcolor-incoming, 10%); + background-color: color.adjust($msgcolor-incoming, $lightness: 10%); &_outgoing { - border-color: lighten($msgcolor-outgoing, 20%); - background-color: lighten($msgcolor-outgoing, 30%); + border-color: color.adjust($msgcolor-outgoing, $lightness: 20%); + background-color: color.adjust($msgcolor-outgoing, $lightness: 30%); } } diff --git a/tgui/packages/tgui/styles/interfaces/NuclearBomb.scss b/tgui/packages/tgui/styles/interfaces/NuclearBomb.scss index 615a3f696afa2..d27311e3f5e60 100644 --- a/tgui/packages/tgui/styles/interfaces/NuclearBomb.scss +++ b/tgui/packages/tgui/styles/interfaces/NuclearBomb.scss @@ -5,12 +5,12 @@ $color-danger: colors.bg(colors.$red) !default; $color-caution: colors.bg(colors.$yellow) !default; -$background-beige: #e8e4c9; +$background-beige: hsl(50, 33%, 84%); .NuclearBomb__displayBox { - background-color: #002003; + background-color: hsl(150, 100%, 1%); border: 0.167em inset $background-beige; - color: #03e017; + color: hsl(132, 100%, 45%); font-size: 2em; font-family: monospace; padding: 0.25em; @@ -33,9 +33,9 @@ $background-beige: #e8e4c9; } .NuclearBomb__Button--1 { - background-color: #d3cfb7 !important; - border-color: #d3cfb7 !important; - color: #a9a692 !important; + background-color: hsl(50, 33%, 78%) !important; + border-color: hsl(50, 33%, 78%) !important; + color: hsl(50, 10%, 70%) !important; } .NuclearBomb__Button--E { diff --git a/tgui/packages/tgui/styles/interfaces/PersonalCrafting.scss b/tgui/packages/tgui/styles/interfaces/PersonalCrafting.scss index ec06d9fd1ba59..0acbafa742e19 100644 --- a/tgui/packages/tgui/styles/interfaces/PersonalCrafting.scss +++ b/tgui/packages/tgui/styles/interfaces/PersonalCrafting.scss @@ -36,7 +36,7 @@ .PersonalCraftingGridItem__content { position: relative; - color: #888; + color: hsl(0, 0%, 53.3%); padding: 0.5em 0.5em 2.5em 0.5em; min-height: 100%; pointer-events: none; @@ -57,7 +57,7 @@ right: 0; left: 0; padding: 0.5em; - color: #fff; + color: hsl(0, 0%, 100%); background-color: rgba(255, 0, 0, 0.1); text-align: center; visibility: hidden; @@ -76,21 +76,21 @@ overflow: hidden; font-weight: bold; margin-bottom: 0.5em; - color: #aaa; + color: hsl(0, 0%, 66.7%); } .PersonalCraftingGridItem--craftable .PersonalCraftingGridItem__name { - color: #fff; + color: hsl(0, 0%, 100%); } .PersonalCraftingGridItem__prereq { - color: #777; + color: hsl(0, 0%, 46.7%); overflow: hidden; white-space: nowrap; } .PersonalCraftingGridItem--craftable .PersonalCraftingGridItem__prereq { - color: #bbb; + color: hsl(0, 0%, 73.3%); } .PersonalCraftingGridItem__extra { diff --git a/tgui/packages/tgui/styles/interfaces/PreferencesMenu.scss b/tgui/packages/tgui/styles/interfaces/PreferencesMenu.scss index 6a1d241b83fec..1ee0bf9bf7e00 100644 --- a/tgui/packages/tgui/styles/interfaces/PreferencesMenu.scss +++ b/tgui/packages/tgui/styles/interfaces/PreferencesMenu.scss @@ -10,7 +10,7 @@ $department_map: ( 'Cargo': colors.$brown, 'Command': colors.$yellow, 'Security': colors.$red, - 'Engineering': #f1a839, + 'Engineering': hsl(36, 89%, 60%), 'Medical': colors.$teal, 'Science': colors.fg(colors.$purple), 'Service': colors.$green, @@ -110,7 +110,7 @@ $department_map: ( .antagonist-days-left { text-align: center; - text-shadow: 1px 1px 1px #222; + text-shadow: 1px 1px 1px hsl(0, 0%, 13.3%); width: 100%; @@ -140,9 +140,9 @@ $department_map: ( } background: colors.fg($color-value); - border-bottom: 2px solid rgba(0, 0, 0, 0.3); - border-left: 2px solid rgba(0, 0, 0, 0.3); - border-right: 2px solid rgba(0, 0, 0, 0.3); + border-bottom: 2px solid hsla(0, 0%, 0%, 0.3); + border-left: 2px solid hsla(0, 0%, 0%, 0.3); + border-right: 2px solid hsla(0, 0%, 0%, 0.3); color: black; > * { @@ -151,20 +151,20 @@ $department_map: ( } &:first-child { - border-top: 2px solid rgba(0, 0, 0, 0.3); + border-top: 2px solid hsla(0, 0%, 0%, 0.3); } .options { - background: rgba(0, 0, 0, 0.2); + background: hsla(0, 0%, 0%, 0.2); height: 100%; } } &--Captain { - border: 3px solid rgba(200, 200, 0, 1); + border: 3px solid hsla(60, 100%, 39.2%, 1); &:first-child { - border-top: 3px solid rgba(200, 200, 0, 1); + border-top: 3px solid hsla(60, 100%, 39.2%, 1); } .job-name { @@ -174,12 +174,12 @@ $department_map: ( } &__priority { - border: 1px solid rgba(0, 0, 0, 0.3); + border: 1px solid hsla(0, 0%, 0%, 0.3); &--off::after { content: ''; - background: rgba(0, 0, 0, 0.2); + background: hsla(0, 0%, 0%, 0.2); display: block; height: 80%; left: 50%; @@ -209,7 +209,7 @@ $department_map: ( &__quirk { background-color: colors.$white; border-bottom: 1px solid black; - color: #111; + color: hsl(0, 0%, 6.7%); transition: background-color 0.1s ease-in; $quality_map: ( diff --git a/tgui/packages/tgui/styles/interfaces/Safe.scss b/tgui/packages/tgui/styles/interfaces/Safe.scss index 2f9f3d9d3613b..706d1b3f965ec 100644 --- a/tgui/packages/tgui/styles/interfaces/Safe.scss +++ b/tgui/packages/tgui/styles/interfaces/Safe.scss @@ -4,18 +4,18 @@ height: 96%; left: 2.5%; top: 2%; - border: 5px outset #3e4f6a; + border: 5px outset hsl(217, 27%, 34%); padding: 5px; text-align: center; } .Safe__engraving-arrow { - color: #35435a; + color: hsl(217, 27%, 27%); } .Safe__engraving-hinge { content: ' '; - background-color: #191f2a; + background-color: hsl(217, 27%, 15%); width: 25px; height: 40px; position: absolute; @@ -39,17 +39,17 @@ } .Safe__dialer-number { - color: #bbbbbb; + color: hsl(0, 0%, 73.3%); display: inline; - background-color: #191f2a; + background-color: hsl(217, 27%, 15%); font-size: 1.5rem; font-weight: bold; padding: 0 0.5rem; } .Safe__contents { - border: 10px solid #191f2a; - background-color: #0f131a; + border: 10px solid hsl(217, 27%, 15%); + background-color: hsl(217, 27%, 10%); height: calc(85% + 7.5px); text-align: left; padding: 5px; @@ -64,8 +64,12 @@ font-family: 'Comic Sans MS', cursive, sans-serif; font-style: italic; color: black; - box-shadow: 5px 5px #111111; - background-image: linear-gradient(to bottom, #b2ae74 0%, #8e8b5d 100%); + box-shadow: 5px 5px hsl(0, 0%, 6.7%); + background-image: linear-gradient( + to bottom, + hsl(50, 20%, 58.8%) 0%, + hsl(50, 6%, 45.5%) 100% + ); transform: rotate(-1deg); &:before { @@ -73,8 +77,12 @@ display: block; width: 24px; height: 40px; - background-image: linear-gradient(to bottom, transparent 0%, #ffffff 100%); - box-shadow: 1px 1px #111111; + background-image: linear-gradient( + to bottom, + transparent 0%, + hsl(0, 0%, 100%) 100% + ); + box-shadow: 1px 1px hsl(0, 0%, 6.7%); opacity: 0.2; position: absolute; top: -30px; diff --git a/tgui/packages/tgui/styles/interfaces/Techweb.scss b/tgui/packages/tgui/styles/interfaces/Techweb.scss index 684267185d104..f73aaa6ca7a5d 100644 --- a/tgui/packages/tgui/styles/interfaces/Techweb.scss +++ b/tgui/packages/tgui/styles/interfaces/Techweb.scss @@ -23,7 +23,7 @@ .Techweb__HeaderContent { background-color: black; padding: 6px; - border: 1px solid #40628a; + border: 1px solid hsl(210, 33%, 41%); } .Techweb__HeaderContent > * > :not(:last-child) { @@ -33,13 +33,13 @@ .Techweb__HeaderSectionTabs { margin-top: 8px; background-color: black; - border: 1px solid #40628a; + border: 1px solid hsl(210, 33%, 41%); padding-left: 5px; padding-right: 5px; } .Techweb__HeaderTabTitle { - border-right: 1px solid #40628a; + border-right: 1px solid hsl(210, 33%, 41%); padding-right: 0.5em; margin-right: 0.5em; font-weight: bold; diff --git a/tgui/packages/tgui/styles/interfaces/Uplink.scss b/tgui/packages/tgui/styles/interfaces/Uplink.scss index 58cf956a9027a..bb3d2834bb994 100644 --- a/tgui/packages/tgui/styles/interfaces/Uplink.scss +++ b/tgui/packages/tgui/styles/interfaces/Uplink.scss @@ -1,9 +1,39 @@ -$badGradient: linear-gradient(to right, #9c1e1e, #6c2828, #9c1e1e); -$normalGradient: linear-gradient(to right, #5d5041, #40372d, #5d5041); -$goodGradient: linear-gradient(to right, #515d6c, #252a30, #515d6c); -$veryGoodGradient: linear-gradient(to right, #977949, #534328, #977949); -$superGoodGradient: linear-gradient(to right, #9d9948, #777437, #9d9948); -$bestGradient: linear-gradient(to right, #9d486b, #57283c, #9d486b); +$badGradient: linear-gradient( + to right, + hsl(0, 67%, 37%), + hsl(0, 43%, 28%), + hsl(0, 67%, 37%) +); +$normalGradient: linear-gradient( + to right, + hsl(30, 14%, 34%), + hsl(30, 20%, 19%), + hsl(30, 14%, 34%) +); +$goodGradient: linear-gradient( + to right, + hsl(210, 11%, 37%), + hsl(210, 14%, 17%), + hsl(210, 11%, 37%) +); +$veryGoodGradient: linear-gradient( + to right, + hsl(36, 38%, 44%), + hsl(36, 33%, 19%), + hsl(36, 38%, 44%) +); +$superGoodGradient: linear-gradient( + to right, + hsl(60, 39%, 45%), + hsl(60, 35%, 34%), + hsl(60, 39%, 45%) +); +$bestGradient: linear-gradient( + to right, + hsl(330, 34%, 45%), + hsl(330, 43%, 26%), + hsl(330, 34%, 45%) +); $_rep_map: ( 'bad': $badGradient, diff --git a/tgui/packages/tgui/styles/layouts/Layout.scss b/tgui/packages/tgui/styles/layouts/Layout.scss index eaadcd9a6978b..ecf750ecc0740 100644 --- a/tgui/packages/tgui/styles/layouts/Layout.scss +++ b/tgui/packages/tgui/styles/layouts/Layout.scss @@ -4,7 +4,7 @@ */ @use 'sass:color'; -@use '../base.scss'; +@use '../base'; $scrollbar-color-multiplier: 1 !default; diff --git a/tgui/packages/tgui/styles/layouts/NtosWindow.scss b/tgui/packages/tgui/styles/layouts/NtosWindow.scss index bed4abab53cec..7c75cdfafe9c3 100644 --- a/tgui/packages/tgui/styles/layouts/NtosWindow.scss +++ b/tgui/packages/tgui/styles/layouts/NtosWindow.scss @@ -3,7 +3,7 @@ * SPDX-License-Identifier: MIT */ -@use '../base.scss'; +@use '../base'; .NtosWindow__header { position: absolute; @@ -12,7 +12,7 @@ right: 0; height: 2em; line-height: 1.928em; - background-color: rgba(0, 0, 0, 0.5); + background-color: hsla(0, 0, 0, 0.5); font-family: Consolas, monospace; font-size: base.em(14px); user-select: none; diff --git a/tgui/packages/tgui/styles/layouts/TitleBar.scss b/tgui/packages/tgui/styles/layouts/TitleBar.scss index 1a26dd9e29ebf..517f2b8ad811e 100644 --- a/tgui/packages/tgui/styles/layouts/TitleBar.scss +++ b/tgui/packages/tgui/styles/layouts/TitleBar.scss @@ -4,13 +4,13 @@ */ @use 'sass:color'; -@use '../base.scss'; -@use '../colors.scss'; +@use '../base'; +@use '../colors'; -$text-color: rgba(255, 255, 255, 0.75) !default; -$background-color: #363636 !default; -$shadow-color-core: #161616 !default; -$shadow-color: rgba(0, 0, 0, 0.1) !default; +$text-color: hsla(0, 0%, 100%, 0.75) !default; +$background-color: hsl(0, 0%, 21%) !default; +$shadow-color-core: hsl(0, 0%, 8.6%) !default; +$shadow-color: hsla(0, 0%, 0%, 0.1) !default; .TitleBar { background-color: $background-color; @@ -30,7 +30,7 @@ $shadow-color: rgba(0, 0, 0, 0.1) !default; &:hover { color: rgba(255, 255, 255, 1); - background-color: #cc0000; + background-color: hsl(0, 100%, 40%); transition: color 0ms, background-color 0ms; @@ -105,7 +105,7 @@ $shadow-color: rgba(0, 0, 0, 0.1) !default; min-width: base.rem(20px); padding: 2px 4px; padding: base.rem(2px) base.rem(4px); - background-color: rgba(colors.$good, 0.75); - color: #fff; + background-color: darken(colors.$good, 10%); + color: hsl(120, 100%, 100%); text-align: center; } diff --git a/tgui/packages/tgui/styles/layouts/Window.scss b/tgui/packages/tgui/styles/layouts/Window.scss index 232dd8396bbf2..1bb1e2acd6975 100644 --- a/tgui/packages/tgui/styles/layouts/Window.scss +++ b/tgui/packages/tgui/styles/layouts/Window.scss @@ -4,8 +4,8 @@ */ @use 'sass:color'; -@use '../base.scss'; -@use '../functions.scss' as *; +@use '../base'; +@use '../functions' as *; .Window { position: fixed; diff --git a/tgui/packages/tgui/styles/main.scss b/tgui/packages/tgui/styles/main.scss index 5a0e80715ee3b..4d6697ebc1219 100644 --- a/tgui/packages/tgui/styles/main.scss +++ b/tgui/packages/tgui/styles/main.scss @@ -4,7 +4,7 @@ */ @use 'sass:meta'; -@use './base.scss'; +@use 'base'; // Core styles @include meta.load-css('./reset.scss'); diff --git a/tgui/packages/tgui/styles/reset.scss b/tgui/packages/tgui/styles/reset.scss index e7fff7f936dae..69d03ce4801af 100644 --- a/tgui/packages/tgui/styles/reset.scss +++ b/tgui/packages/tgui/styles/reset.scss @@ -3,7 +3,7 @@ * SPDX-License-Identifier: MIT */ -@use './base.scss'; +@use 'base'; html, body { diff --git a/tgui/packages/tgui/styles/themes/abductor.scss b/tgui/packages/tgui/styles/themes/abductor.scss index 39dac5773c063..0dc17087c28b1 100644 --- a/tgui/packages/tgui/styles/themes/abductor.scss +++ b/tgui/packages/tgui/styles/themes/abductor.scss @@ -6,13 +6,13 @@ @use 'sass:color'; @use 'sass:meta'; -@use '../colors.scss' with ( - $primary: #ad2350, +@use '../colors' with ( + $primary: hsl(340, 67%, 41%), $fg-map-keys: (), $bg-map-keys: () ); -@use '../base.scss' with ( - $color-bg: #2a314a, +@use '../base' with ( + $color-bg: hsl(227, 29%, 23%), $color-bg-grad-spread: 6%, $border-radius: 2px ); @@ -26,32 +26,32 @@ '../components/Button.scss', $with: ( 'color-default': colors.$primary, - 'color-disabled': #363636, - 'color-selected': #465899, - 'color-caution': #be6209, - 'color-danger': #9a9d00 + 'color-disabled': hsl(0, 0%, 21%), + 'color-selected': hsl(227, 37%, 45%), + 'color-caution': hsl(30, 88%, 39%), + 'color-danger': hsl(62, 100%, 30%) ) ); @include meta.load-css( '../components/Input.scss', - $with: ('border-color': #404b6e) + $with: ('border-color': hsl(227, 29%, 27%)) ); @include meta.load-css( '../components/NoticeBox.scss', - $with: ('background-color': #a82d55) + $with: ('background-color': hsl(340, 67%, 41%)) ); @include meta.load-css( '../components/NumberInput.scss', - $with: ('border-color': #404b6e) + $with: ('border-color': hsl(227, 29%, 27%)) ); @include meta.load-css( '../components/ProgressBar.scss', - $with: ('background-color': rgba(0, 0, 0, 0.5)) + $with: ('background-color': hsla(0, 0%, 0%, 0.5)) ); @include meta.load-css('../components/Section.scss'); @include meta.load-css( '../components/Tooltip.scss', - $with: ('background-color': #a82d55) + $with: ('background-color': hsl(340, 67%, 41%)) ); // Layouts @@ -59,7 +59,7 @@ @include meta.load-css('../layouts/Window.scss'); @include meta.load-css( '../layouts/TitleBar.scss', - $with: ('background-color': #9e1b46) + $with: ('background-color': hsl(340, 71%, 36%)) ); .Layout__content { diff --git a/tgui/packages/tgui/styles/themes/admin.scss b/tgui/packages/tgui/styles/themes/admin.scss index c36d5305beffb..73940e47f9cd6 100644 --- a/tgui/packages/tgui/styles/themes/admin.scss +++ b/tgui/packages/tgui/styles/themes/admin.scss @@ -7,12 +7,13 @@ @use 'sass:meta'; @use '../colors.scss' with ( - $primary: #1596b6, + // convert to hsl + $primary: hsl(191.93, 79.31%, 39.8%), $fg-map-keys: (), $bg-map-keys: () ); @use '../base.scss' with ( - $color-bg: #29333a, + $color-bg: hsl(204.7, 17.2%, 19.4%), $color-bg-grad-spread: 6%, $border-radius: 2px ); diff --git a/tgui/packages/tgui/styles/themes/cardtable.scss b/tgui/packages/tgui/styles/themes/cardtable.scss index e5047e2e2f0c7..79e3b5469569a 100644 --- a/tgui/packages/tgui/styles/themes/cardtable.scss +++ b/tgui/packages/tgui/styles/themes/cardtable.scss @@ -6,13 +6,13 @@ @use 'sass:color'; @use 'sass:meta'; -@use '../colors.scss' with ( - $primary: #000000, +@use '../colors' with ( + $primary: hsl(0, 0%, 0%), $fg-map-keys: (), $bg-map-keys: () ); -@use '../base.scss' with ( - $color-bg: #117039, +@use '../base' with ( + $color-bg: hsl(145.26, 73.64%, 25.29%), $color-bg-grad-spread: 0%, $border-radius: 0 ); @@ -26,11 +26,11 @@ @include meta.load-css( '../components/Button.scss', $with: ( - 'color-default': #117039, - 'color-disabled': #363636, - 'color-selected': #9d0808, - 'color-caution': #be6209, - 'color-danger': #9a9d00 + 'color-default': hsl(145.26, 73.64%, 25.29%), + 'color-disabled': hsl(0, 0%, 21.18%), + 'color-selected': hsl(0, 90.3%, 32.35%), + 'color-caution': hsl(29.5, 90.95%, 39.02%), + 'color-danger': hsl(61.15, 100%, 30.78%) ) ); @include meta.load-css( @@ -48,7 +48,7 @@ @include meta.load-css('../layouts/Window.scss'); @include meta.load-css( '../layouts/TitleBar.scss', - $with: ('background-color': #381608) + $with: ('background-color': hsl(17.5, 75%, 12.5%)) ); .Button { diff --git a/tgui/packages/tgui/styles/themes/hackerman.scss b/tgui/packages/tgui/styles/themes/hackerman.scss index 51befcf1b3668..3cf1bbe337eca 100644 --- a/tgui/packages/tgui/styles/themes/hackerman.scss +++ b/tgui/packages/tgui/styles/themes/hackerman.scss @@ -7,12 +7,12 @@ @use 'sass:meta'; @use '../colors.scss' with ( - $primary: #00ff00, + $primary: hsl(120, 100%, 50%), $fg-map-keys: (), $bg-map-keys: () ); @use '../base.scss' with ( - $color-bg: #121b12, + $color-bg: hsl(120, 20%, 8.8%), $color-bg-grad-spread: 0% ); @@ -25,16 +25,16 @@ '../components/Button.scss', $with: ( 'color-default': colors.$primary, - 'color-disabled': #4a6a4a, - 'color-selected': #00ff00 + 'color-disabled': hsl(120, 17.78%, 35.29%), + 'color-selected': hsl(120, 100%, 50%) ) ); @include meta.load-css( '../components/Tabs.scss', $with: ( 'color-default': colors.$primary, - 'tab-color-selected': #00ff003f, - 'text-color': #e7e7e7 + 'tab-color-selected': hsla(120, 100%, 50%, 0.25), + 'text-color': hsl(0, 0%, 90.59%) ) ); @include meta.load-css( @@ -49,7 +49,7 @@ @include meta.load-css('../layouts/Window.scss'); @include meta.load-css( '../layouts/TitleBar.scss', - $with: ('background-color': #223d22) + $with: ('background-color': hsl(120, 28.4%, 18.6%)) ); .Layout__content { @@ -60,7 +60,7 @@ font-family: monospace; border-width: base.em(2px); border-style: outset; - border-color: #00aa00; + border-color: hsl(120, 100%, 33.33%); outline: base.em(1px) solid rgb(0, 122, 0); } diff --git a/tgui/packages/tgui/styles/themes/malfunction.scss b/tgui/packages/tgui/styles/themes/malfunction.scss index d32113ba5e661..eb42eadee4dc5 100644 --- a/tgui/packages/tgui/styles/themes/malfunction.scss +++ b/tgui/packages/tgui/styles/themes/malfunction.scss @@ -7,12 +7,12 @@ @use 'sass:meta'; @use '../colors.scss' with ( - $primary: #910101, + $primary: hsl(0, 99%, 29%), $fg-map-keys: (), $bg-map-keys: () ); @use '../base.scss' with ( - $color-bg: #1b3443, + $color-bg: hsl(204, 43%, 19%), $color-bg-grad-spread: 6% ); @@ -25,32 +25,32 @@ '../components/Button.scss', $with: ( 'color-default': colors.$primary, - 'color-disabled': #363636, - 'color-selected': #1e5881, - 'color-caution': #be6209, - 'color-danger': #9a9d00 + 'color-disabled': hsl(0, 0%, 21%), + 'color-selected': hsl(204, 61%, 31%), + 'color-caution': hsl(30, 88%, 39%), + 'color-danger': hsl(62, 100%, 30%) ) ); @include meta.load-css( '../components/Input.scss', - $with: ('border-color': #910101) + $with: ('border-color': hsl(0, 99%, 29%)) ); @include meta.load-css( '../components/NoticeBox.scss', - $with: ('background-color': #1a3f57) + $with: ('background-color': hsl(204, 54%, 23%)) ); @include meta.load-css( '../components/NumberInput.scss', - $with: ('border-color': #910101) + $with: ('border-color': hsl(0, 99%, 29%)) ); @include meta.load-css( '../components/ProgressBar.scss', - $with: ('background-color': rgba(0, 0, 0, 0.5)) + $with: ('background-color': hsla(0, 0%, 0%, 0.5)) ); @include meta.load-css('../components/Section.scss'); @include meta.load-css( '../components/Tooltip.scss', - $with: ('background-color': #235577) + $with: ('background-color': hsl(204, 54%, 29%)) ); // Layouts @@ -58,7 +58,7 @@ @include meta.load-css('../layouts/Window.scss'); @include meta.load-css( '../layouts/TitleBar.scss', - $with: ('background-color': #1a3f57) + $with: ('background-color': hsl(204, 54%, 23%)) ); .Layout__content { diff --git a/tgui/packages/tgui/styles/themes/neutral.scss b/tgui/packages/tgui/styles/themes/neutral.scss index e8ed3ca7da98b..d8c893539ddf2 100644 --- a/tgui/packages/tgui/styles/themes/neutral.scss +++ b/tgui/packages/tgui/styles/themes/neutral.scss @@ -6,7 +6,7 @@ @use 'sass:color'; @use 'sass:meta'; -$neutral: #ffb300; +$neutral: hsl(42.12, 100%, 50%); @use '../colors.scss' with ( $primary: $neutral, diff --git a/tgui/packages/tgui/styles/themes/ntOS95.scss b/tgui/packages/tgui/styles/themes/ntOS95.scss index df541bf18a44e..b59665ea5638e 100644 --- a/tgui/packages/tgui/styles/themes/ntOS95.scss +++ b/tgui/packages/tgui/styles/themes/ntOS95.scss @@ -6,19 +6,19 @@ @use 'sass:color'; @use 'sass:meta'; -$light-gray: #c3c3c3; -$dark-gray: #858585; +$light-gray: hsl(0, 0%, 76%); +$dark-gray: hsl(0, 0%, 52%); $scrollbar-color-multiplier: 1; @use '../colors.scss' with ( - $primary: #000000, - $good: #007c11, - $average: #f0ec11, - $bad: #db2828, - $label: #000000 + $primary: hsl(0, 0%, 0%), + $good: hsl(134, 100%, 24.3%), + $average: hsl(56, 88%, 50%), + $bad: hsl(0, 72%, 50%), + $label: hsl(0, 0%, 0%) ); @use '../base.scss' with ( - $color-bg: #008081, + $color-bg: hsl(180, 100%, 25.3%), $color-bg-grad-spread: 0%, $border-radius: 0 ); @@ -31,11 +31,11 @@ $scrollbar-color-multiplier: 1; @include meta.load-css( '../components/Button.scss', $with: ( - 'color-default': #e8e4c9, - 'color-disabled': #707070, - 'color-selected': #007c11, - 'color-caution': #be6209, - 'color-danger': #9d0808 + 'color-default': hsl(52.3, 40.3%, 84.9%), + 'color-disabled': hsl(0, 0%, 43.9%), + 'color-selected': hsl(128.2, 100%, 24.3%), + 'color-caution': hsl(29.5, 91%, 39%), + 'color-danger': hsl(0, 90.3%, 32.4%) ) ); @include meta.load-css( @@ -49,39 +49,39 @@ $scrollbar-color-multiplier: 1; @include meta.load-css( '../components/Tooltip.scss', - $with: ('background-color': #ecee9e) + $with: ('background-color': hsl(61.5, 70.2%, 77.6%)) ); // Layouts @include meta.load-css('../layouts/Layout.scss'); @include meta.load-css('../layouts/Window.scss'); @include meta.load-css( '../layouts/TitleBar.scss', - $with: ('background-color': #000080) + $with: ('background-color': hsl(240, 100%, 25.1%)) ); .Button { - color: #161613; - background-color: #c2c2c2; - //border: base.em(2px) outset #E8E4C9; - outline: base.em(2px) outset #c3c3c3; + color: hsl(60, 7.3%, 8%); + background-color: hsl(0, 0%, 76.1%); + //border: base.em(2px) outset hsl(52.3, 40.3%, 84.9%); + outline: base.em(2px) outset hsl(0, 0%, 76.5%); } .Button:hover { - background-color: #002ead; + background-color: hsl(224, 100%, 33.9%); transition: 0.1s; } .Section { + color: black; + background-color: hsl(0, 0%, 75.3%); + outline: base.em(2px) outset hsl(0, 0%, 76.5%); &__titleText { color: black; } - color: black; - background-color: #c0c0c0; - outline: base.em(2px) outset #c3c3c3; } .Input { background-color: white; - outline: base.em(2px) inset #c3c3c3; + outline: base.em(2px) inset hsl(0, 0%, 76.5%); color: black; &__input:-ms-input-placeholder { color: black; @@ -90,7 +90,7 @@ $scrollbar-color-multiplier: 1; .TextArea { background-color: white; - outline: base.em(2px) inset #c3c3c3; + outline: base.em(2px) inset hsl(0, 0%, 76.5%); } .Layout__content { @@ -131,13 +131,13 @@ $scrollbar-color-multiplier: 1; } .Tab { - color: #000000; - background-color: #ecee9e; + color: hsl(0, 0%, 0%); + background-color: hsl(61.5, 70.2%, 77.6%); } .Tab--selected { - color: #9d0808; - background-color: #c3c3c3; + color: hsl(0, 90.3%, 32.4%); + background-color: hsl(0, 0%, 76.5%); } body { @@ -151,11 +151,11 @@ $scrollbar-color-multiplier: 1; .Table__cell { display: table-cell; padding: 0 0.25em; - background-color: #c3c3c3; - //outline: base.em(3px) outset #c0c0c0 + background-color: hsl(0, 0%, 76.5%); + //outline: base.em(3px) outset hsl(0.0, 0.0%, 75.3%) } .Box { - outline: base.em(3px) outset #c0c0c0; + outline: base.em(3px) outset hsl(0, 0%, 75.3%); } .Tooltip { color: black; diff --git a/tgui/packages/tgui/styles/themes/ntos.scss b/tgui/packages/tgui/styles/themes/ntos.scss index 8b102b4777813..306273e73bea0 100644 --- a/tgui/packages/tgui/styles/themes/ntos.scss +++ b/tgui/packages/tgui/styles/themes/ntos.scss @@ -6,7 +6,7 @@ @use 'sass:color'; @use 'sass:meta'; -$nanotrasen: #384e68; +$nanotrasen: hsl(213, 30%, 32%); @use '../colors.scss' with ( $fg-map-keys: (), diff --git a/tgui/packages/tgui/styles/themes/ntos_cat.scss b/tgui/packages/tgui/styles/themes/ntos_cat.scss index ae6236b5aa39c..003c55e105f26 100644 --- a/tgui/packages/tgui/styles/themes/ntos_cat.scss +++ b/tgui/packages/tgui/styles/themes/ntos_cat.scss @@ -8,27 +8,26 @@ //@use 'sass:map'; //palette -$cyan: #5edba5; -$pink: #ed12f5; -$orange: #ff9900; -$purple: #463191; +$cyan: hsl(156, 65%, 60%); +$pink: hsl(300, 91%, 52%); +$orange: hsl(36, 100%, 50%); +$purple: hsl(248, 47%, 37%); -$light-gray: #c3c3c3; -$dark-gray: #858585; +$light-gray: hsl(0, 0%, 76%); +$dark-gray: hsl(0, 0%, 52%); $scrollbar-color-multiplier: 0.5; @use '../colors.scss' with ( $primary: black, - $label: rgb(255, 132, 153), - $good: pink, - + $label: hsl(350, 100%, 76.5%), + $good: hsl(300, 91%, 52%), $bad: red, // $fg-map-keys: (), // $bg-map-keys: (), ); @use '../base.scss' with ( - $color-bg: orange, + $color-bg: hsl(36, 100%, 50%), $color-bg-grad-spread: 12%, //$border-radius: 0, ); @@ -41,24 +40,24 @@ $scrollbar-color-multiplier: 0.5; @include meta.load-css( '../components/Button.scss', $with: ( - 'color-default': pink, - 'color-transparent-text': rgba(227, 240, 255, 0.75), - 'color-disabled': #363636, - 'color-selected': #465899, - 'color-caution': #be6209 + 'color-default': hsl(300, 91%, 52%), + 'color-transparent-text': hsla(210, 100%, 94%, 0.75), + 'color-disabled': hsl(0, 0%, 21%), + 'color-selected': hsl(227, 37%, 45%), + 'color-caution': hsl(30, 88%, 39%) ) ); @include meta.load-css( '../components/ProgressBar.scss', - $with: ('color-default-fill': rgb(255, 132, 153, 0.75)) + $with: ('color-default-fill': hsla(350, 100%, 76.5%, 0.75)) ); @include meta.load-css( '../components/Section.scss', - $with: ('background-color': rgba(124, 62, 34, 0.75)) + $with: ('background-color': hsla(24, 56%, 31%, 0.75)) ); @include meta.load-css( '../components/Tooltip.scss', - $with: ('background-color': rgba(255, 153, 0, 0.75)) + $with: ('background-color': hsla(36, 100%, 50%, 0.75)) ); // Layouts @@ -66,16 +65,16 @@ $scrollbar-color-multiplier: 0.5; @include meta.load-css('../layouts/Window.scss'); @include meta.load-css( '../layouts/TitleBar.scss', - $with: ('background-color': rgb(255, 132, 153, 0.75)) + $with: ('background-color': hsla(350, 100%, 76.5%, 0.75)) ); .Section { color: black; - outline: base.em(2px) inset rgb(255, 132, 153); + outline: base.em(2px) inset hsl(350, 100%, 76.5%); } .Button { - color: rgb(255, 132, 153); - background-color: rgb(255, 255, 255); + color: hsl(350, 100%, 76.5%); + background-color: hsl(0, 0%, 100%); } .ProgressBar { @@ -91,58 +90,58 @@ $scrollbar-color-multiplier: 0.5; .Layout * { // Fancy scrollbar scrollbar-base-color: color.scale( - #454255, + hsl(248, 17%, 27%), $lightness: -25% * $scrollbar-color-multiplier ); scrollbar-face-color: color.scale( - #454255, + hsl(248, 17%, 27%), $lightness: 10% * $scrollbar-color-multiplier ); scrollbar-3dlight-color: color.scale( - orange, + hsl(36, 100%, 50%), $lightness: 0% * $scrollbar-color-multiplier ); scrollbar-highlight-color: color.scale( - orange, + hsl(36, 100%, 50%), $lightness: 0% * $scrollbar-color-multiplier ); scrollbar-track-color: color.scale( - #ba753a, + hsl(30, 47%, 47%), $lightness: -25% * $scrollbar-color-multiplier ); scrollbar-arrow-color: color.scale( - orange, + hsl(36, 100%, 50%), $lightness: 50% * $scrollbar-color-multiplier ); scrollbar-shadow-color: color.scale( - #454255, + hsl(248, 17%, 27%), $lightness: 10% * $scrollbar-color-multiplier ); } .Tab { - color: rgb(255, 132, 153); - background-color: rgba(255, 255, 255, 0.5); + color: hsl(350, 100%, 76.5%); + background-color: hsla(0, 0%, 100%, 0.5); } .Tab--selected { color: black; - background-color: rgb(255, 132, 153); + background-color: hsl(350, 100%, 76.5%); } .Box { - outline: base.em(3px) outset #c0c0c0; + outline: base.em(3px) outset hsl(0, 0%, 76%); } .Tooltip { color: black; } .Input { - background-color: white; - outline: base.em(2px) inset rgb(255, 132, 153); + background-color: hsl(0, 0%, 100%); + outline: base.em(2px) inset hsl(350, 100%, 76.5%); } .NtosWindow__header { - background-color: #454255; + background-color: hsl(248, 17%, 27%); } .Flex { - color: white; - background-color: rgba(0, 0, 0, 0); + color: hsl(0, 0%, 100%); + background-color: hsla(0, 0%, 0%, 0); } } diff --git a/tgui/packages/tgui/styles/themes/ntos_darkmode.scss b/tgui/packages/tgui/styles/themes/ntos_darkmode.scss index b22ad60fc3f2f..15127fafb428e 100644 --- a/tgui/packages/tgui/styles/themes/ntos_darkmode.scss +++ b/tgui/packages/tgui/styles/themes/ntos_darkmode.scss @@ -6,7 +6,7 @@ @use 'sass:color'; @use 'sass:meta'; -$nanotrasen: #2c2c2c; +$nanotrasen: hsl(0, 0%, 17.25%); @use '../colors.scss' with ( $fg-map-keys: (), diff --git a/tgui/packages/tgui/styles/themes/ntos_lightmode.scss b/tgui/packages/tgui/styles/themes/ntos_lightmode.scss index 9cf1a647b778d..170601c17e340 100644 --- a/tgui/packages/tgui/styles/themes/ntos_lightmode.scss +++ b/tgui/packages/tgui/styles/themes/ntos_lightmode.scss @@ -6,14 +6,14 @@ @use 'sass:color'; @use 'sass:meta'; -$nanotrasen: #ffffff; +$nanotrasen: hsl(0, 0%, 100%); @use '../colors.scss' with ( - $primary: #000000, - $label: #000000 + $primary: hsl(0, 0%, 0%), + $label: hsl(0, 0%, 0%) ); @use '../base.scss' with ( - $color-bg: white + $color-bg: hsl(0, 0%, 100%) ); .theme-ntos_lightmode { @@ -27,16 +27,16 @@ $nanotrasen: #ffffff; '../components/ProgressBar.scss', $with: ( 'color-default-fill': $nanotrasen, - 'background-color': rgba(0, 0, 0, 0.5) + 'background-color': hsla(0, 0%, 0%, 0.5) ) ); @include meta.load-css( '../components/Section.scss', - $with: ('background-color': rgba(119, 119, 119, 0.4)) + $with: ('background-color': hsla(0, 0%, 47%, 0.4)) ); @include meta.load-css( '../components/Tooltip.scss', - $with: ('background-color': white) + $with: ('background-color': hsl(0, 0%, 100%)) ); // Layouts @@ -44,24 +44,24 @@ $nanotrasen: #ffffff; @include meta.load-css('../layouts/Window.scss'); @include meta.load-css( '../layouts/TitleBar.scss', - $with: ('background-color': gray) + $with: ('background-color': hsl(0, 0%, 50%)) ); .Button { - color: #161613; + color: hsl(45, 6%, 8%); } .Button:hover { - background-color: #777777; + background-color: hsl(0, 0%, 47%); transition: 0.1s; } .Section { - color: black; + color: hsl(0, 0%, 0%); } .Tab { - color: black; + color: hsl(0, 0%, 0%); } .Tab--selected { - color: white; - background-color: darkgray; + color: hsl(0, 0%, 100%); + background-color: hsl(0, 0%, 66%); } } diff --git a/tgui/packages/tgui/styles/themes/ntos_spooky.scss b/tgui/packages/tgui/styles/themes/ntos_spooky.scss index 147464218568c..b8ea8451caccb 100644 --- a/tgui/packages/tgui/styles/themes/ntos_spooky.scss +++ b/tgui/packages/tgui/styles/themes/ntos_spooky.scss @@ -3,12 +3,12 @@ @use 'sass:map'; @use '../colors.scss' with ( - $primary: #3f021a, - $good: #e62626, - $bad: #970934 + $primary: hsl(345, 96%, 12%), + $good: hsl(0, 82%, 52%), + $bad: hsl(340, 91%, 32%) ); @use '../base.scss' with ( - $color-bg: #240101, + $color-bg: hsl(0, 98%, 7%), $color-bg-grad-spread: 12% ); @@ -20,11 +20,11 @@ @include meta.load-css( '../components/Button.scss', $with: ( - 'color-default': #7e0322, - 'color-disabled': #363636, - 'color-selected': #610a0a, - 'color-caution': #1416a3, - 'color-danger': #5c1e80 + 'color-default': hsl(345, 96%, 25%), + 'color-disabled': hsl(0, 0%, 21%), + 'color-selected': hsl(0, 85%, 21%), + 'color-caution': hsl(240, 80%, 35%), + 'color-danger': hsl(282, 61%, 30%) ) ); @include meta.load-css( @@ -33,25 +33,25 @@ ); @include meta.load-css( '../components/Input.scss', - $with: ('border-color': #473a37) + $with: ('border-color': hsl(15, 14%, 26%)) ); @include meta.load-css('../components/Modal.scss'); @include meta.load-css( '../components/NoticeBox.scss', - $with: ('background-color': #740707) + $with: ('background-color': hsl(0, 90%, 23%)) ); @include meta.load-css('../components/NumberInput.scss'); @include meta.load-css('../components/Section.scss'); @include meta.load-css('../components/Table.scss'); @include meta.load-css( '../components/Tooltip.scss', - $with: ('background-color': #000000) + $with: ('background-color': hsl(0, 0%, 0%)) ); @include meta.load-css( '../components/ProgressBar.scss', $with: ( - 'color-default-fill': rgba(190, 0, 0, 0.75), - 'background-color': rgba(34, 1, 1, 0.5) + 'color-default-fill': hsla(0, 100%, 37%, 0.75), + 'background-color': hsla(0, 97%, 7%, 0.5) ) ); @@ -60,7 +60,7 @@ @include meta.load-css('../layouts/Window.scss'); @include meta.load-css( '../layouts/TitleBar.scss', - $with: ('background-color': #6b0808) + $with: ('background-color': hsl(0, 88%, 23%)) ); .Layout__content { diff --git a/tgui/packages/tgui/styles/themes/ntos_synth.scss b/tgui/packages/tgui/styles/themes/ntos_synth.scss index 5085308dd3bcd..c290e62319c1f 100644 --- a/tgui/packages/tgui/styles/themes/ntos_synth.scss +++ b/tgui/packages/tgui/styles/themes/ntos_synth.scss @@ -8,10 +8,10 @@ //@use 'sass:map'; //palette -$cyan: #5edba5; -$pink: #ed12f5; -$orange: #ff9900; -$purple: #463191; +$cyan: hsl(156, 65%, 60%); +$pink: hsl(300, 91%, 52%); +$orange: hsl(36, 100%, 50%); +$purple: hsl(248, 47%, 37%); @use '../colors.scss' with ( $primary: $pink, @@ -35,23 +35,23 @@ $purple: #463191; '../components/Button.scss', $with: ( 'color-default': $cyan, - 'color-transparent-text': rgba(227, 240, 255, 0.75), - 'color-disabled': #363636, - 'color-selected': #465899, - 'color-caution': #be6209 + 'color-transparent-text': hsla(210, 100%, 94%, 0.75), + 'color-disabled': hsl(0, 0%, 21%), + 'color-selected': hsl(227, 37%, 45%), + 'color-caution': hsl(30, 88%, 39%) ) ); @include meta.load-css( '../components/ProgressBar.scss', - $with: ('color-default-fill': rgba(237, 18, 245, 0.75)) + $with: ('color-default-fill': hsla(300, 91%, 52%, 0.75)) ); @include meta.load-css( '../components/Section.scss', - $with: ('background-color': rgba(0, 0, 0, 0.3)) + $with: ('background-color': hsla(0, 0%, 0%, 0.3)) ); @include meta.load-css( '../components/Tooltip.scss', - $with: ('background-color': rgba(255, 153, 0, 0.75)) + $with: ('background-color': hsla(36, 100%, 50%, 0.75)) ); // Layouts @@ -59,15 +59,15 @@ $purple: #463191; @include meta.load-css('../layouts/Window.scss'); @include meta.load-css( '../layouts/TitleBar.scss', - $with: ('background-color': rgba(3, 100, 117, 0.75)) + $with: ('background-color': hsla(185, 95%, 23%, 0.75)) ); .Section { color: $cyan; background-image: linear-gradient( to right, - rgba(194, 0, 219, 0.75), - rgba(3, 100, 117, 0.75) + hsla(300, 100%, 42%, 0.75), + hsla(185, 95%, 23%, 0.75) ); } .Button { @@ -89,8 +89,8 @@ $purple: #463191; color: $cyan; background-image: linear-gradient( to right, - rgba(255, 153, 0, 0.4), - rgba(194, 0, 219, 0.75) + hsla(36, 100%, 50%, 0.4), + hsla(300, 100%, 42%, 0.75) ); } .Tab--selected { diff --git a/tgui/packages/tgui/styles/themes/ntos_terminal.scss b/tgui/packages/tgui/styles/themes/ntos_terminal.scss index 234e20fce7605..3814a568937d0 100644 --- a/tgui/packages/tgui/styles/themes/ntos_terminal.scss +++ b/tgui/packages/tgui/styles/themes/ntos_terminal.scss @@ -7,14 +7,14 @@ @use 'sass:meta'; @use '../colors.scss' with ( - $primary: #24e87e, - $label: #24e87e, - $good: rgba(36, 232, 127, 0.5), + $primary: hsl(146, 82%, 53%), + $label: hsl(146, 82%, 53%), + $good: hsla(146, 82%, 53%, 0.5), // $fg-map-keys: (), // $bg-map-keys: (), ); @use '../base.scss' with ( - $color-bg: #121b12, + $color-bg: hsl(120, 10%, 9%), $color-bg-grad-spread: 0% ); @@ -27,8 +27,8 @@ '../components/Button.scss', $with: ( 'color-default': rgba(0, 0, 0, 0), - 'color-disabled': #4a6a4a, - 'color-selected': rgba(36, 232, 127, 0.25) + 'color-disabled': hsl(120, 18%, 35%), + 'color-selected': hsla(146, 82%, 53%, 0.25) ) ); @include meta.load-css( @@ -38,8 +38,8 @@ @include meta.load-css( '../components/ProgressBar.scss', $with: ( - 'background-color': rgba(0, 0, 0, 0.5), - 'color-default-fill': rgba(36, 232, 127, 0.5) + 'background-color': hsla(0, 0%, 0%, 0.5), + 'color-default-fill': hsla(146, 82%, 53%, 0.5) ) ); @include meta.load-css('../components/Modal.scss'); @@ -50,63 +50,63 @@ @include meta.load-css('../layouts/Window.scss'); @include meta.load-css( '../layouts/TitleBar.scss', - $with: ('background-color': rgba(0, 97, 0, 0.25)) + $with: ('background-color': hsla(120, 100%, 19%, 0.25)) ); .Layout__content { //background-image: none; background-image: repeating-linear-gradient( 0deg, - rgba(black, 0.15), - rgba(black, 0.15) 1px, + hsla(0, 0%, 0%, 0.15), + hsla(0, 0%, 0%, 0.15) 1px, transparent 2.5px, transparent 5px ), - radial-gradient(rgba(0, 97, 0, 0.75), black 120%); + radial-gradient(hsla(120, 100%, 19%, 0.75), black 120%); background-size: 100%, 100%; background-position: center, center; } .Button { font: Inconsolata; - color: #24e87e; - text-shadow: 0 0 2px #24e87e; + color: hsl(146, 82%, 53%); + text-shadow: 0 0 2px hsl(146, 82%, 53%); } .Button:hover { - background-color: rgba(36, 232, 127, 0.25); + background-color: hsla(146, 82%, 53%, 0.25); transition: 0.1s; } .Button--selected { - color: #24e87e; + color: hsl(146, 82%, 53%); } body { //background-color: black; - color: white; + color: hsl(0, 0%, 100%); font: 1.3rem Inconsolata; - text-shadow: 0 0 2px #24e87e; + text-shadow: 0 0 2px hsl(146, 82%, 53%); //font: bold 12px Arial, 'Helvetica Neue', Helvetica, sans-serif; } .Section { - color: rgb(36, 232, 126); + color: hsl(146, 82%, 53%); } .Tab { - color: #24e87e; + color: hsl(146, 82%, 53%); } .Tab--selected { - color: #24e87e; - border: 2px solid #24e87e; - background-color: rgba(36, 232, 127, 0.25); + color: hsl(146, 82%, 53%); + border: 2px solid hsl(146, 82%, 53%); + background-color: hsla(146, 82%, 53%, 0.25); } ::selection { - background: #0080ff; + background: hsl(210, 100%, 50%); text-shadow: none; } .Table { - text-shadow: 0 0 2px #24e87e; + text-shadow: 0 0 2px hsl(146, 82%, 53%); } .Flex { - text-shadow: 0 0 2px #24e87e; + text-shadow: 0 0 2px hsl(146, 82%, 53%); } } diff --git a/tgui/packages/tgui/styles/themes/paper.scss b/tgui/packages/tgui/styles/themes/paper.scss index 2f9fa6e16f2bd..23e3c83517a91 100644 --- a/tgui/packages/tgui/styles/themes/paper.scss +++ b/tgui/packages/tgui/styles/themes/paper.scss @@ -7,7 +7,7 @@ @use 'sass:meta'; @use '../colors.scss' with ( - $primary: #ffffff, + $primary: hsl(0, 0%, 100%), $bg-lightness: 25%, $fg-lightness: -10%, // Commenting out color maps will adjust all colors based on the lightness @@ -16,8 +16,8 @@ $bg-map-keys: () ); @use '../base.scss' with ( - $color-fg: #000000, - $color-bg: #dfdfdf, + $color-fg: hsl(0, 0%, 0%), + $color-bg: hsl(0, 0%, 87%), $color-bg-grad-spread: 0% ); @@ -33,17 +33,17 @@ $font-size: 24px; @include meta.load-css('../components/Tabs.scss'); @include meta.load-css( '../components/Section.scss', - $with: ('background-color': rgba(0, 0, 0, 0.1)) + $with: ('background-color': hsla(0, 0%, 0%, 0.1)) ); @include meta.load-css( '../components/Button.scss', $with: ( - 'color-default': #e8e4c9, - 'color-disabled': #363636, - 'color-selected': #9d0808, - 'color-caution': #be6209, - 'color-danger': #9a9d00, - 'color-transparent-text': rgba(0, 0, 0, 0.5) + 'color-default': hsl(50, 50%, 90%), + 'color-disabled': hsl(0, 0%, 21%), + 'color-selected': hsl(0, 100%, 30%), + 'color-caution': hsl(30, 90%, 40%), + 'color-danger': hsl(60, 100%, 30%), + 'color-transparent-text': hsla(0, 0%, 0%, 0.5) ) ); @@ -56,9 +56,9 @@ $font-size: 24px; @include meta.load-css( '../layouts/TitleBar.scss', $with: ( - 'text-color': rgba(0, 0, 0, 0.75), + 'text-color': hsla(0, 0%, 0%, 0.75), 'background-color': base.$color-bg, - 'shadow-color-core': rgba(0, 0, 0, 0.25) + 'shadow-color-core': hsla(0, 0%, 0%, 0.25) ) ); @@ -68,9 +68,9 @@ $font-size: 24px; width: 120px; border: none; background: transparent; - border-bottom: 1px solid #000; + border-bottom: 1px solid hsl(0, 0%, 0%); outline: none; - background-color: rgba(255, 255, 62, 0.8); + background-color: hsla(60, 100%, 60%, 0.8); padding: 0 4px; margin-right: 2px; line-height: 17px; @@ -99,13 +99,13 @@ $font-size: 24px; padding: 0 6px; font-family: Verdana, sans-serif; background-color: transparent; - color: #fff; + color: hsl(0, 0%, 100%); color: inherit; &:-ms-input-placeholder { font-style: italic; - color: #777; - color: rgba(255, 255, 255, 0.45); + color: hsl(0, 0%, 47%); + color: hsla(0, 0%, 100%, 0.45); } } @@ -124,9 +124,9 @@ $font-size: 24px; display: inline-block; border: none; background: transparent; - border-bottom: 1px solid #000; + border-bottom: 1px solid hsl(0, 0%, 0%); outline: none; - background-color: rgba(255, 255, 62, 0.8); + background-color: hsla(60, 100%, 60%, 0.8); padding: 0 4px; margin-right: 2px; line-height: 17px; @@ -138,9 +138,9 @@ $font-size: 24px; display: inline-block; border: none; background: transparent; - border-bottom: 1px solid #000; + border-bottom: 1px solid hsl(0, 0%, 0%); outline: none; - background-color: rgba(255, 255, 62, 0.8); + background-color: hsla(60, 100%, 60%, 0.8); padding: 0 4px; margin-right: 2px; line-height: 17px; @@ -158,9 +158,9 @@ $font-size: 24px; border: none; background: transparent; - border-bottom: 1px solid #000; + border-bottom: 1px solid hsl(0, 0%, 0%); outline: none; - background-color: rgba(255, 255, 62, 0.8); + background-color: hsla(60, 100%, 60%, 0.8); padding: 0 4px; margin-right: 2px; line-height: 17px; @@ -172,9 +172,9 @@ $font-size: 24px; border: none; background: transparent; - border-bottom: 1px solid #000; + border-bottom: 1px solid hsl(0, 0%, 0%); outline: none; - background-color: rgba(255, 255, 62, 0.8); + background-color: hsla(60, 100%, 60%, 0.8); padding: 0 4px; margin-right: 2px; line-height: 17px; diff --git a/tgui/packages/tgui/styles/themes/retro.scss b/tgui/packages/tgui/styles/themes/retro.scss index 9e08c8b9caef6..c98af3bb093be 100644 --- a/tgui/packages/tgui/styles/themes/retro.scss +++ b/tgui/packages/tgui/styles/themes/retro.scss @@ -7,12 +7,12 @@ @use 'sass:meta'; @use '../colors.scss' with ( - $primary: #000000, + $primary: hsl(0, 0%, 0%), $fg-map-keys: (), $bg-map-keys: () ); @use '../base.scss' with ( - $color-bg: #e8e4c9, + $color-bg: hsl(48, 38%, 84%), $color-bg-grad-spread: 0%, $border-radius: 0 ); @@ -27,16 +27,16 @@ @include meta.load-css( '../components/Button.scss', $with: ( - 'color-default': #e8e4c9, - 'color-disabled': #505046, - 'color-selected': #9d0808, - 'color-caution': #be6209, - 'color-danger': #9a9d00 + 'color-default': hsl(48, 38%, 84%), + 'color-disabled': hsl(60, 6%, 28%), + 'color-selected': hsl(0, 91%, 31%), + 'color-caution': hsl(28, 87%, 39%), + 'color-danger': hsl(61, 100%, 30%) ) ); @include meta.load-css( '../components/ProgressBar.scss', - $with: ('background-color': rgba(0, 0, 0, 0.5)) + $with: ('background-color': hsla(0, 0%, 0%, 0.5)) ); @include meta.load-css('../components/Section.scss'); @@ -45,24 +45,24 @@ @include meta.load-css('../layouts/Window.scss'); @include meta.load-css( '../layouts/TitleBar.scss', - $with: ('background-color': #585337) + $with: ('background-color': hsl(48, 10%, 28%)) ); .Button { font-family: monospace; - color: #161613; - border: base.em(2px) outset #e8e4c9; - outline: base.em(1px) solid #161613; + color: hsl(60, 6%, 8%); + border: base.em(2px) outset hsl(48, 38%, 84%); + outline: base.em(1px) solid hsl(60, 6%, 8%); } .Button--disabled { - color: #c5c5c2; + color: hsl(60, 6%, 77%); font-family: monospace; &:hover { - color: #ffffff; + color: hsl(0, 0%, 100%); } &:focus { - color: #ffffff; + color: hsl(0, 0%, 100%); } } diff --git a/tgui/packages/tgui/styles/themes/spookyconsole.scss b/tgui/packages/tgui/styles/themes/spookyconsole.scss index 07fd5b4dbe3d8..3f6cd32182cb7 100644 --- a/tgui/packages/tgui/styles/themes/spookyconsole.scss +++ b/tgui/packages/tgui/styles/themes/spookyconsole.scss @@ -3,14 +3,14 @@ @use 'sass:map'; @use '../colors.scss' with ( - $primary: #3f021a, - $good: #010005, - $bad: #970934, + $primary: hsl(345, 96%, 12%), + $good: hsl(240, 100%, 1%), + $bad: hsl(340, 91%, 32%), $fg-map-keys: (), $bg-map-keys: () ); @use '../base.scss' with ( - $color-bg: #240101, + $color-bg: hsl(0, 100%, 7%), $color-bg-grad-spread: 12% ); @@ -30,11 +30,11 @@ $updated-bg-map: map.set($updated-bg-map, 'bad', colors.$bad); @include meta.load-css( '../components/Button.scss', $with: ( - 'color-default': #7e0322, - 'color-disabled': #363636, - 'color-selected': #610a0a, - 'color-caution': #1416a3, - 'color-danger': #5c1e80, + 'color-default': hsl(345, 96%, 25%), + 'color-disabled': hsl(0, 0%, 21%), + 'color-selected': hsl(0, 85%, 21%), + 'color-caution': hsl(240, 80%, 35%), + 'color-danger': hsl(282, 61%, 30%), 'bg-map': $updated-bg-map ) ); @@ -44,19 +44,19 @@ $updated-bg-map: map.set($updated-bg-map, 'bad', colors.$bad); ); @include meta.load-css( '../components/Input.scss', - $with: ('border-color': #473a37) + $with: ('border-color': hsl(15, 14%, 26%)) ); @include meta.load-css('../components/Modal.scss'); @include meta.load-css( '../components/NoticeBox.scss', - $with: ('background-color': #740707) + $with: ('background-color': hsl(0, 90%, 23%)) ); @include meta.load-css('../components/NumberInput.scss'); @include meta.load-css('../components/Section.scss'); @include meta.load-css('../components/Table.scss'); @include meta.load-css( '../components/Tooltip.scss', - $with: ('background-color': #000000) + $with: ('background-color': hsl(0, 0%, 0%)) ); // Layouts @@ -64,7 +64,7 @@ $updated-bg-map: map.set($updated-bg-map, 'bad', colors.$bad); @include meta.load-css('../layouts/Window.scss'); @include meta.load-css( '../layouts/TitleBar.scss', - $with: ('background-color': #6b0808) + $with: ('background-color': hsl(0, 88%, 23%)) ); .Layout__content { diff --git a/tgui/packages/tgui/styles/themes/syndicate.scss b/tgui/packages/tgui/styles/themes/syndicate.scss index 4a547edef9b66..8e07101c7e562 100644 --- a/tgui/packages/tgui/styles/themes/syndicate.scss +++ b/tgui/packages/tgui/styles/themes/syndicate.scss @@ -7,12 +7,12 @@ @use 'sass:meta'; @use '../colors.scss' with ( - $primary: #397439, + $primary: hsl(120, 34%, 35%), $fg-map-keys: (), $bg-map-keys: () ); @use '../base.scss' with ( - $color-bg: #550202, + $color-bg: hsl(0, 96%, 17%), $color-bg-grad-spread: 6% ); @@ -25,32 +25,32 @@ '../components/Button.scss', $with: ( 'color-default': colors.$primary, - 'color-disabled': #363636, - 'color-selected': #9d0808, - 'color-caution': #be6209, - 'color-danger': #9a9d00 + 'color-disabled': hsl(0, 0%, 21%), + 'color-selected': hsl(0, 91%, 31%), + 'color-caution': hsl(28, 87%, 39%), + 'color-danger': hsl(61, 100%, 30%) ) ); @include meta.load-css( '../components/Input.scss', - $with: ('border-color': #87ce87) + $with: ('border-color': hsl(120, 60%, 70%)) ); @include meta.load-css( '../components/NoticeBox.scss', - $with: ('background-color': #910101) + $with: ('background-color': hsl(0, 98%, 28%)) ); @include meta.load-css( '../components/NumberInput.scss', - $with: ('border-color': #87ce87) + $with: ('border-color': hsl(120, 60%, 70%)) ); @include meta.load-css( '../components/ProgressBar.scss', - $with: ('background-color': rgba(0, 0, 0, 0.5)) + $with: ('background-color': hsla(0, 0%, 0%, 0.5)) ); @include meta.load-css('../components/Section.scss'); @include meta.load-css( '../components/Tooltip.scss', - $with: ('background-color': #4a0202) + $with: ('background-color': hsl(0, 96%, 14%)) ); // Layouts @@ -58,7 +58,7 @@ @include meta.load-css('../layouts/Window.scss'); @include meta.load-css( '../layouts/TitleBar.scss', - $with: ('background-color': #910101) + $with: ('background-color': hsl(0, 98%, 28%)) ); .Layout__content { diff --git a/tgui/packages/tgui/styles/themes/wizard.scss b/tgui/packages/tgui/styles/themes/wizard.scss index 9c4056cc1289a..6c726ab964eeb 100644 --- a/tgui/packages/tgui/styles/themes/wizard.scss +++ b/tgui/packages/tgui/styles/themes/wizard.scss @@ -7,12 +7,12 @@ @use 'sass:meta'; @use '../colors.scss' with ( - $primary: #1596b6, + $primary: hsl(191, 79%, 41%), $fg-map-keys: (), $bg-map-keys: () ); @use '../base.scss' with ( - $color-bg: #213e4e, + $color-bg: hsl(204, 40%, 21%), $color-bg-grad-spread: 6%, $border-radius: 2px ); @@ -26,32 +26,32 @@ '../components/Button.scss', $with: ( 'color-default': colors.$primary, - 'color-disabled': #02426d, - 'color-selected': #465899, - 'color-caution': #be6209, - 'color-danger': #b30707 + 'color-disabled': hsl(204, 97%, 21%), + 'color-selected': hsl(227, 40%, 44%), + 'color-caution': hsl(28, 89%, 39%), + 'color-danger': hsl(0, 91%, 35%) ) ); @include meta.load-css( '../components/Input.scss', - $with: ('border-color': #404b6e) + $with: ('border-color': hsl(227, 25%, 34%)) ); @include meta.load-css( '../components/NoticeBox.scss', - $with: ('background-color': #a82d55) + $with: ('background-color': hsl(340, 58%, 41%)) ); @include meta.load-css( '../components/NumberInput.scss', - $with: ('border-color': #404b6e) + $with: ('border-color': hsl(227, 25%, 34%)) ); @include meta.load-css( '../components/ProgressBar.scss', - $with: ('background-color': rgba(0, 0, 0, 0.5)) + $with: ('background-color': hsla(0, 0%, 0%, 0.5)) ); @include meta.load-css('../components/Section.scss'); @include meta.load-css( '../components/Tooltip.scss', - $with: ('background-color': #2da848) + $with: ('background-color': hsl(134, 61%, 42%)) ); // Layouts @@ -59,7 +59,7 @@ @include meta.load-css('../layouts/Window.scss'); @include meta.load-css( '../layouts/TitleBar.scss', - $with: ('background-color': #1b9e26) + $with: ('background-color': hsl(134, 71%, 31%)) ); .Layout__content { diff --git a/tgui/yarn.lock b/tgui/yarn.lock index b41f103989440..4b73fde334514 100644 --- a/tgui/yarn.lock +++ b/tgui/yarn.lock @@ -17137,9 +17137,9 @@ __metadata: languageName: node linkType: hard -"sass-loader@npm:^14.2.1": - version: 14.2.1 - resolution: "sass-loader@npm:14.2.1" +"sass-loader@npm:^16.0.3": + version: 16.0.3 + resolution: "sass-loader@npm:16.0.3" dependencies: neo-async: "npm:^2.6.2" peerDependencies: @@ -17159,7 +17159,7 @@ __metadata: optional: true webpack: optional: true - checksum: 10c0/9a48d454584d96d6c562eb323bb9e3c6808e930eeaaa916975b97d45831e0b87936a8655cdb3a4512a25abc9587dea65a9616e42396be0d7e7c507a4795a8146 + checksum: 10c0/2dc188dd0d5276ed0251eee7f245848ccf9df6ec121227462403f322c17a3dbe100fb60d47968f078e585e4aced452eb7fa1a8e55b415d5de3151fa1bbf2d561 languageName: node linkType: hard @@ -18815,7 +18815,7 @@ __metadata: mini-css-extract-plugin: "npm:^2.9.2" prettier: "npm:^3.2.5" sass: "npm:^1.80.6" - sass-loader: "npm:^14.2.1" + sass-loader: "npm:^16.0.3" style-loader: "npm:^4.0.0" swc-loader: "npm:^0.2.6" typescript: "npm:^5.6.3" diff --git a/tools/hslify/README.md b/tools/hslify/README.md new file mode 100644 index 0000000000000..cc6937ed4f69c --- /dev/null +++ b/tools/hslify/README.md @@ -0,0 +1,21 @@ +# HSLify + +This is a simple Python script that converts all hex colors in a directory to their corresponding HSL values. + +## Usage + +1. Install the required dependencies: + +```bash +pip install colormath +``` + +2. Move files so that hslify is in the same directory as the files you want to process. That can be in this folder, or by moving this folder to the same directory as the files you want to process. + +3. Run the script: + +```bash +py hslify.py +``` + +4. Formatting is strange, so it may be necessary to save the file manually for prettier to format it. diff --git a/tools/hslify/hslify.py b/tools/hslify/hslify.py new file mode 100644 index 0000000000000..9a87ad4415710 --- /dev/null +++ b/tools/hslify/hslify.py @@ -0,0 +1,27 @@ +import re +import glob +from colormath.color_objects import sRGBColor, HSLColor +from colormath.color_conversions import convert_color + +def hex_to_hsl(hex_color): + rgb = sRGBColor.new_from_rgb_hex(hex_color) + hsl = convert_color(rgb, HSLColor) + return f"hsl({hsl.hsl_h:.1f}, {hsl.hsl_s * 100:.1f}%, {hsl.hsl_l * 100:.1f}%)" + +def replace_hex_with_hsl(file_path): + with open(file_path, 'r') as file: + content = file.read() + + hex_pattern = re.compile(r'#([0-9a-fA-F]{6})') + updated_content = hex_pattern.sub(lambda match: hex_to_hsl(match.group(0)), content) + + with open(file_path, 'w') as file: + file.write(updated_content) + +def process_all_scss_files(): + scss_files = glob.glob('*.scss') + for scss_file in scss_files: + replace_hex_with_hsl(scss_file) + +if __name__ == "__main__": + process_all_scss_files() From 46d4ac9d8e6e58b2c35482bf1dbe3c1444ff3b58 Mon Sep 17 00:00:00 2001 From: Waterpig <49160555+Majkl-J@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:57:48 +0100 Subject: [PATCH 007/222] Mech fabricator output direction can now be changed with a drag pull (#87828) ## About The Pull Request See name, makes it consistent with all the other printing machines. For some reason we have three different paths for all of them but refactoring is out of scope for me. Comes with updatepaths too ## Why It's Good For The Game No more confusion with how to change the direction, it's the same as all the other ones now. ## Changelog :cl: qol: mech fabricator output direction can now be changed with a drag pull /:cl: --------- Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> --- _maps/map_files/Birdshot/birdshot.dmm | 2 +- .../map_files/Deltastation/DeltaStation2.dmm | 2 +- _maps/map_files/MetaStation/MetaStation.dmm | 4 +-- .../map_files/NebulaStation/NebulaStation.dmm | 2 +- _maps/map_files/NorthStar/north_star.dmm | 4 +-- _maps/map_files/wawastation/wawastation.dmm | 4 +-- _maps/shuttles/ruin_cyborg_mothership.dmm | 2 +- .../modules/vehicles/mecha/mech_fabricator.dm | 30 ++++++++++++------- .../Scripts/87828_exofab_directions.txt | 1 + 9 files changed, 30 insertions(+), 21 deletions(-) create mode 100644 tools/UpdatePaths/Scripts/87828_exofab_directions.txt diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index b42c05f4ea49b..ed07ca2ba6784 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -29342,7 +29342,7 @@ "jYr" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/mecha_part_fabricator{ - dir = 8 + drop_direction = 8 }, /obj/effect/turf_decal/stripes/box, /turf/open/floor/iron/dark, diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 3cc15f7deffa7..13c2c019fdb31 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -59893,7 +59893,7 @@ /area/station/service/abandoned_gambling_den/gaming) "pcJ" = ( /obj/machinery/mecha_part_fabricator{ - dir = 4 + drop_direction = 4 }, /obj/effect/turf_decal/bot_red, /obj/effect/turf_decal/tile/neutral/full, diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 68433b5278535..0455a78b4c083 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -43417,7 +43417,7 @@ dir = 4 }, /obj/machinery/mecha_part_fabricator{ - dir = 4 + drop_direction = 4 }, /obj/structure/noticeboard/directional/west, /turf/open/floor/iron, @@ -51130,7 +51130,7 @@ dir = 4 }, /obj/machinery/mecha_part_fabricator{ - dir = 4 + drop_direction = 4 }, /turf/open/floor/iron, /area/station/science/robotics/lab) diff --git a/_maps/map_files/NebulaStation/NebulaStation.dmm b/_maps/map_files/NebulaStation/NebulaStation.dmm index 7a3b22d254f9e..9be370d5fc1bb 100644 --- a/_maps/map_files/NebulaStation/NebulaStation.dmm +++ b/_maps/map_files/NebulaStation/NebulaStation.dmm @@ -141111,7 +141111,7 @@ /area/station/hallway/primary/central) "uYT" = ( /obj/machinery/mecha_part_fabricator{ - dir = 1 + drop_direction = 1 }, /obj/effect/turf_decal/delivery, /turf/open/floor/iron/dark, diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm index 973b6209da885..95c02b17936dc 100644 --- a/_maps/map_files/NorthStar/north_star.dmm +++ b/_maps/map_files/NorthStar/north_star.dmm @@ -16182,7 +16182,7 @@ dir = 8 }, /obj/machinery/mecha_part_fabricator{ - dir = 4 + drop_direction = 4 }, /obj/machinery/light/small/directional/west, /turf/open/floor/iron/white/smooth_large, @@ -41584,7 +41584,7 @@ dir = 4 }, /obj/machinery/mecha_part_fabricator{ - dir = 8 + drop_direction = 8 }, /obj/machinery/light/small/directional/east, /turf/open/floor/iron/white/smooth_large, diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm index 66345284283e1..322a7fb820929 100644 --- a/_maps/map_files/wawastation/wawastation.dmm +++ b/_maps/map_files/wawastation/wawastation.dmm @@ -5609,7 +5609,7 @@ /area/station/security/lockers) "bYo" = ( /obj/machinery/mecha_part_fabricator{ - dir = 1 + drop_direction = 1 }, /obj/effect/turf_decal/delivery, /obj/structure/sign/poster/contraband/borg_fancy_1/directional/south, @@ -39502,7 +39502,7 @@ /area/station/maintenance/central/lesser) "oac" = ( /obj/machinery/mecha_part_fabricator{ - dir = 1 + drop_direction = 1 }, /obj/effect/turf_decal/delivery, /obj/machinery/digital_clock/directional/south, diff --git a/_maps/shuttles/ruin_cyborg_mothership.dmm b/_maps/shuttles/ruin_cyborg_mothership.dmm index 7864564eab185..ea07e4354de65 100644 --- a/_maps/shuttles/ruin_cyborg_mothership.dmm +++ b/_maps/shuttles/ruin_cyborg_mothership.dmm @@ -346,7 +346,7 @@ "ry" = ( /obj/machinery/mecha_part_fabricator/maint{ name = "forgotten exosuit fabricator"; - dir = 8 + drop_direction = 8 }, /obj/machinery/conveyor{ dir = 8; diff --git a/code/modules/vehicles/mecha/mech_fabricator.dm b/code/modules/vehicles/mecha/mech_fabricator.dm index 54f8cee9ed4c5..ad28886d99f22 100644 --- a/code/modules/vehicles/mecha/mech_fabricator.dm +++ b/code/modules/vehicles/mecha/mech_fabricator.dm @@ -10,6 +10,7 @@ subsystem_type = /datum/controller/subsystem/processing/fastprocess + interaction_flags_atom = parent_type::interaction_flags_atom | INTERACT_ATOM_MOUSEDROP_IGNORE_CHECKS /// Current items in the build queue. var/list/datum/design/queue = list() @@ -49,12 +50,15 @@ /// All designs in the techweb that can be fabricated by this machine, since the last update. var/list/datum/design/cached_designs - //looping sound for printing items + /// Looping sound for printing items var/datum/looping_sound/lathe_print/print_sound /// Local designs that only this mechfab have(using when mechfab emaged so it's illegal designs). var/list/datum/design/illegal_local_designs + /// Direction the produced items will drop (0 means on top of us) + var/drop_direction = SOUTH + /obj/machinery/mecha_part_fabricator/Initialize(mapload) print_sound = new(src, FALSE) rmat = AddComponent(/datum/component/remote_materials, mapload && link_on_init) @@ -136,15 +140,19 @@ . = ..() if(in_range(user, src) || isobserver(user)) . += span_notice("The status display reads: Storing up to [rmat.local_size] material units.
Material consumption at [component_coeff*100]%.
Build time reduced by [100-time_coeff*100]%.") - if(panel_open) - . += span_notice("Alt-click to rotate the output direction.") + . += span_notice("Currently configured to drop printed objects [dir2text(drop_direction)].") -/obj/machinery/mecha_part_fabricator/click_alt(mob/user) - if(!panel_open) - return CLICK_ACTION_BLOCKING - dir = turn(dir, -90) - balloon_alert(user, "rotated to [dir2text(dir)].") - return CLICK_ACTION_SUCCESS +/obj/machinery/mecha_part_fabricator/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params) + if(!can_interact(user) || (!HAS_SILICON_ACCESS(user) && !isAdminGhostAI(user)) && !Adjacent(user)) + return + if(being_built) + balloon_alert(user, "printing started!") + return + var/direction = get_dir(src, over_location) + if(!direction) + return + drop_direction = direction + balloon_alert(user, "dropping [dir2text(drop_direction)]") /obj/machinery/mecha_part_fabricator/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) @@ -267,7 +275,7 @@ /obj/machinery/mecha_part_fabricator/process() // If there's a stored part to dispense due to an obstruction, try to dispense it. if(stored_part) - var/turf/exit = get_step(src,(dir)) + var/turf/exit = get_step(src, drop_direction) if(exit.density) return TRUE @@ -305,7 +313,7 @@ being_built = null - var/turf/exit = get_step(src,(dir)) + var/turf/exit = get_step(src, drop_direction) if(exit.density) say("Error! The part outlet is obstructed.") desc = "It's trying to dispense the fabricated [dispensed_design.name], but the part outlet is obstructed." diff --git a/tools/UpdatePaths/Scripts/87828_exofab_directions.txt b/tools/UpdatePaths/Scripts/87828_exofab_directions.txt new file mode 100644 index 0000000000000..468bc23847a98 --- /dev/null +++ b/tools/UpdatePaths/Scripts/87828_exofab_directions.txt @@ -0,0 +1 @@ +/obj/machinery/mecha_part_fabricator/@SUBTYPES{dir = @ANY} : /obj/machinery/mecha_part_fabricator/@SUBTYPES{@OLD;dir=@SKIP;drop_direction=@OLD:dir} From 0b06d2ddc33481c1564238a978b7624373b8e640 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:58:09 +0000 Subject: [PATCH 008/222] Automatic changelog for PR #87828 [ci skip] --- html/changelogs/AutoChangeLog-pr-87828.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87828.yml diff --git a/html/changelogs/AutoChangeLog-pr-87828.yml b/html/changelogs/AutoChangeLog-pr-87828.yml new file mode 100644 index 0000000000000..7ad2026a16b44 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87828.yml @@ -0,0 +1,4 @@ +author: "Majkl-J" +delete-after: True +changes: + - qol: "mech fabricator output direction can now be changed with a drag pull" \ No newline at end of file From c13aa55c19fa3b839cf7392e348a74cb65d69258 Mon Sep 17 00:00:00 2001 From: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Date: Wed, 13 Nov 2024 15:53:00 +0200 Subject: [PATCH 009/222] small slime ai tweaks (#87871) --- code/modules/mob/living/basic/slime/ai/behaviours.dm | 1 + code/modules/mob/living/basic/slime/ai/controller.dm | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/living/basic/slime/ai/behaviours.dm b/code/modules/mob/living/basic/slime/ai/behaviours.dm index fe8102eee112f..934404d88dd53 100644 --- a/code/modules/mob/living/basic/slime/ai/behaviours.dm +++ b/code/modules/mob/living/basic/slime/ai/behaviours.dm @@ -25,6 +25,7 @@ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED /datum/ai_behavior/find_hunt_target/find_slime_food + action_cooldown = 7.5 SECONDS // Check if the slime can drain the target /datum/ai_behavior/find_hunt_target/find_slime_food/valid_dinner(mob/living/basic/slime/hunter, mob/living/dinner, radius, datum/ai_controller/controller, seconds_per_tick) diff --git a/code/modules/mob/living/basic/slime/ai/controller.dm b/code/modules/mob/living/basic/slime/ai/controller.dm index 41466b2973498..1d5f00e6c4381 100644 --- a/code/modules/mob/living/basic/slime/ai/controller.dm +++ b/code/modules/mob/living/basic/slime/ai/controller.dm @@ -4,7 +4,6 @@ BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends, BB_SLIME_RABID = FALSE, BB_SLIME_HUNGER_DISABLED = FALSE, - BB_CURRENT_HUNTING_TARGET = null, // people whose energy we want to drain ) ai_movement = /datum/ai_movement/basic_avoidance @@ -13,13 +12,12 @@ /datum/ai_planning_subtree/change_slime_face, /datum/ai_planning_subtree/use_mob_ability/evolve, /datum/ai_planning_subtree/use_mob_ability/reproduce, - /datum/ai_planning_subtree/target_retaliate, /datum/ai_planning_subtree/pet_planning, + /datum/ai_planning_subtree/target_retaliate, /datum/ai_planning_subtree/find_and_hunt_target/find_slime_food, /datum/ai_planning_subtree/basic_melee_attack_subtree/slime, /datum/ai_planning_subtree/random_speech/slime, ) - can_idle = FALSE /datum/ai_controller/basic_controller/slime/CancelActions() ..() From b5abf952d6d35703596e5adc59fdeae1d0b9d580 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Wed, 13 Nov 2024 15:35:41 +0100 Subject: [PATCH 010/222] Fixes ayylmao's brain examine lines (#87869) ## About The Pull Request Closes #87861 Merge skew my beloved ## Changelog :cl: fix: Fixed ayylmao's brain examine lines /:cl: --- code/modules/mob/living/brain/brain_item.dm | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 7907fabbfc0a5..32f8660d62da1 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -50,15 +50,6 @@ // Brain size logic transform = transform.Scale(brain_size) -/obj/item/organ/brain/examine() - . = ..() - if (smooth_brain) - . += span_notice("All the pesky wrinkles are gone. Now it just needs a good drying...") - if(brain_size < 1) - . += span_notice("It is a bit on the smaller side...") - if(brain_size > 1) - . += span_notice("It is bigger than average...") - /obj/item/organ/brain/mob_insert(mob/living/carbon/brain_owner, special = FALSE, movement_flags) . = ..() if(!.) @@ -241,6 +232,8 @@ if(length(skillchips)) . += span_info("It has a skillchip embedded in it.") . += brain_damage_examine() + if (smooth_brain) + . += span_notice("All the pesky wrinkles are gone. Now it just needs a good drying...") if(brain_size < 1) . += span_notice("It is a bit on the smaller side...") if(brain_size > 1) From fad5f1ab62bdf9d00bdbe6d75c21ea2db72fdb01 Mon Sep 17 00:00:00 2001 From: grungussuss <96586172+Sadboysuss@users.noreply.github.com> Date: Wed, 13 Nov 2024 17:36:11 +0300 Subject: [PATCH 011/222] party popper doesn't make sloshing sounds (#87872) ## About The Pull Request closes https://github.com/tgstation/tgstation/issues/87330 ## Changelog :cl: grungussuss sound: party popper no longer makes reagent sloshing sounds /:cl: --- code/modules/reagents/reagent_containers/spray.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 17ce2fea149f4..04ff332a9ea31 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -402,6 +402,7 @@ spray_range = 2 spray_sound = 'sound/effects/snap.ogg' possible_transfer_amounts = list(5) + reagent_container_liquid_sound = null /obj/item/reagent_containers/spray/chemsprayer/party/spray(atom/A, mob/user) . = ..() From e904a754f095eada492ff3f72c5bec0ea281f5ac Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 14:36:12 +0000 Subject: [PATCH 012/222] Automatic changelog for PR #87869 [ci skip] --- html/changelogs/AutoChangeLog-pr-87869.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87869.yml diff --git a/html/changelogs/AutoChangeLog-pr-87869.yml b/html/changelogs/AutoChangeLog-pr-87869.yml new file mode 100644 index 0000000000000..41532da000586 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87869.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Fixed ayylmao's brain examine lines" \ No newline at end of file From 7f42fe05eac5f8de78866c6100287855f4118577 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 14:36:36 +0000 Subject: [PATCH 013/222] Automatic changelog for PR #87872 [ci skip] --- html/changelogs/AutoChangeLog-pr-87872.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87872.yml diff --git a/html/changelogs/AutoChangeLog-pr-87872.yml b/html/changelogs/AutoChangeLog-pr-87872.yml new file mode 100644 index 0000000000000..b2752f40caa72 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87872.yml @@ -0,0 +1,4 @@ +author: "grungussuss" +delete-after: True +changes: + - sound: "party popper no longer makes reagent sloshing sounds" \ No newline at end of file From c0e3ba73205e59b60fe28844b2a51f73c32dc417 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 13 Nov 2024 09:16:03 -0600 Subject: [PATCH 014/222] Fix infinite metal holodeck exploit (#87806) ## About The Pull Request This stops people from using chairs to create free metal. It was possible to pick up a chair or place it down and it would lose it's hologram status since a new object is created. Now anyone that attempts to place down or pick up a chair will have it vanish. ## Why It's Good For The Game No more free metal. ## Changelog :cl: fix: Fix using chairs in holodeck to create infinite metal /:cl: --- .../objects/structures/beds_chairs/chair.dm | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index 50d06bafef0fd..38aadbb266229 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -271,11 +271,16 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool, 0) return if(!item_chair || has_buckled_mobs()) return + if(flags_1 & HOLOGRAM_1) + to_chat(user, span_notice("You try to pick up \the [src], but it fades away!")) + qdel(src) + return + user.visible_message(span_notice("[user] grabs \the [src.name]."), span_notice("You grab \the [src.name].")) - var/obj/item/C = new item_chair(loc) - C.set_custom_materials(custom_materials) - TransferComponents(C) - user.put_in_hands(C) + var/obj/item/chair_item = new item_chair(loc) + chair_item.set_custom_materials(custom_materials) + TransferComponents(chair_item) + user.put_in_hands(chair_item) qdel(src) /obj/structure/chair/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE) @@ -344,6 +349,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) if(isgroundlessturf(T)) to_chat(user, span_warning("You need ground to plant this on!")) return + if(flags_1 & HOLOGRAM_1) + to_chat(user, span_notice("You try to place down \the [src], but it fades away!")) + qdel(src) + return + for(var/obj/A in T) if(istype(A, /obj/structure/chair)) to_chat(user, span_warning("There is already a chair here!")) @@ -353,10 +363,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) return user.visible_message(span_notice("[user] rights \the [src.name]."), span_notice("You right \the [name].")) - var/obj/structure/chair/C = new origin_type(get_turf(loc)) - C.set_custom_materials(custom_materials) - TransferComponents(C) - C.setDir(user.dir) + var/obj/structure/chair/chair = new origin_type(get_turf(loc)) + chair.set_custom_materials(custom_materials) + TransferComponents(chair) + chair.setDir(user.dir) qdel(src) /obj/item/chair/proc/smash(mob/living/user) From 32caaae15b819e5852de6089ac500e8f22040791 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 15:16:25 +0000 Subject: [PATCH 015/222] Automatic changelog for PR #87806 [ci skip] --- html/changelogs/AutoChangeLog-pr-87806.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87806.yml diff --git a/html/changelogs/AutoChangeLog-pr-87806.yml b/html/changelogs/AutoChangeLog-pr-87806.yml new file mode 100644 index 0000000000000..8bcd6dd178a41 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87806.yml @@ -0,0 +1,4 @@ +author: "timothymtorres" +delete-after: True +changes: + - bugfix: "Fix using chairs in holodeck to create infinite metal" \ No newline at end of file From 0417cc711770879f410f29c28975f76f509c932b Mon Sep 17 00:00:00 2001 From: Alexis Date: Wed, 13 Nov 2024 13:07:04 -0500 Subject: [PATCH 016/222] Rewrites the code in beserk.dm (#87820) ## About The Pull Request Does as the title says, cleans up the code a bit and modernizes it, as well as making it call its parent. ## Why It's Good For The Game It's more readable this way, plus it properly calls its parent proc now. --- code/datums/actions/items/beserk.dm | 31 ++++++++++++++------ code/modules/mining/lavaland/tendril_loot.dm | 6 ++++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/code/datums/actions/items/beserk.dm b/code/datums/actions/items/beserk.dm index 43e29dbd150cd..01183fd8e3f6e 100644 --- a/code/datums/actions/items/beserk.dm +++ b/code/datums/actions/items/beserk.dm @@ -7,14 +7,27 @@ overlay_icon_state = "bg_demon_border" /datum/action/item_action/berserk_mode/Trigger(trigger_flags) - if(istype(target, /obj/item/clothing/head/hooded/berserker)) - var/obj/item/clothing/head/hooded/berserker/berserk = target - if(berserk.berserk_active) + . = ..() + if(!.) + return FALSE + var/obj/item/clothing/head/hooded/berserker/berserk = target + berserk.berserk_mode(owner) + return TRUE + +/datum/action/item_action/berserk_mode/IsAvailable(feedback = FALSE) + . = ..() + if(!.) + return FALSE + if(!istype(target, /obj/item/clothing/head/hooded/berserker)) + return FALSE + + var/obj/item/clothing/head/hooded/berserker/berserk = target + if(berserk.berserk_active) + if(feedback) to_chat(owner, span_warning("You are already berserk!")) - return - if(berserk.berserk_charge < 100) + return FALSE + if(berserk.berserk_charge < 100) + if(feedback) to_chat(owner, span_warning("You don't have a full charge.")) - return - berserk.berserk_mode(owner) - return - return ..() + return FALSE + return TRUE diff --git a/code/modules/mining/lavaland/tendril_loot.dm b/code/modules/mining/lavaland/tendril_loot.dm index fe338b35ccb93..cfcffa6fea17d 100644 --- a/code/modules/mining/lavaland/tendril_loot.dm +++ b/code/modules/mining/lavaland/tendril_loot.dm @@ -760,8 +760,10 @@ berserk_value *= PROJECTILE_HIT_MULTIPLIER berserk_charge = clamp(round(berserk_charge + berserk_value), 0, MAX_BERSERK_CHARGE) if(berserk_charge >= MAX_BERSERK_CHARGE) + var/datum/action/item_action/berserk_mode/ragemode = locate() in actions to_chat(owner, span_notice("Berserk mode is fully charged.")) balloon_alert(owner, "berserk charged") + ragemode?.build_all_button_icons(UPDATE_BUTTON_STATUS) /obj/item/clothing/head/hooded/berserker/IsReflect() if(berserk_active) @@ -769,6 +771,7 @@ /// Starts berserk, reducing incoming brute by 50%, doubled attacking speed, NOGUNS trait, adding a color and giving them the berserk movespeed modifier /obj/item/clothing/head/hooded/berserker/proc/berserk_mode(mob/living/carbon/human/user) + var/datum/action/item_action/berserk_mode/ragemode = locate() in actions to_chat(user, span_warning("You enter berserk mode.")) playsound(user, 'sound/effects/magic/staff_healing.ogg', 50) user.add_movespeed_modifier(/datum/movespeed_modifier/berserk) @@ -779,6 +782,7 @@ ADD_TRAIT(src, TRAIT_NODROP, BERSERK_TRAIT) berserk_active = TRUE START_PROCESSING(SSobj, src) + ragemode?.build_all_button_icons(UPDATE_BUTTON_STATUS) /// Ends berserk, reverting the changes from the proc [berserk_mode] /obj/item/clothing/head/hooded/berserker/proc/end_berserk(mob/living/carbon/human/user) @@ -787,6 +791,8 @@ berserk_active = FALSE if(QDELETED(user)) return + var/datum/action/item_action/berserk_mode/ragemode = locate() in actions + ragemode?.build_all_button_icons(UPDATE_BUTTON_STATUS) to_chat(user, span_warning("You exit berserk mode.")) playsound(user, 'sound/effects/magic/summonitems_generic.ogg', 50) user.remove_movespeed_modifier(/datum/movespeed_modifier/berserk) From 69d3cd5fc82a181e8963021d03bad8fef016be21 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 18:07:23 +0000 Subject: [PATCH 017/222] Automatic changelog for PR #87820 [ci skip] --- html/changelogs/AutoChangeLog-pr-87820.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87820.yml diff --git a/html/changelogs/AutoChangeLog-pr-87820.yml b/html/changelogs/AutoChangeLog-pr-87820.yml new file mode 100644 index 0000000000000..fafad94cc04ff --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87820.yml @@ -0,0 +1,4 @@ +author: "xPokee, waterpig" +delete-after: True +changes: + - code_imp: "cleaned up beserk.dm" \ No newline at end of file From 09f868f59e8f40bdb87ba6f87145ed40346a6cab Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Wed, 13 Nov 2024 19:11:18 +0100 Subject: [PATCH 018/222] Fixes stingbangs using wrong sprites (#87812) ## About The Pull Request Stingbangs (and much rarer rotfrags) used their disassembled sprite until primed this entire time. Yeah. ## Why It's Good For The Game Handle appearing out of nowhere looks very jarring --- code/game/objects/items/grenades/flashbang.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/grenades/flashbang.dm b/code/game/objects/items/grenades/flashbang.dm index c83801d81fc53..2300d2c67174d 100644 --- a/code/game/objects/items/grenades/flashbang.dm +++ b/code/game/objects/items/grenades/flashbang.dm @@ -53,7 +53,7 @@ /obj/item/grenade/stingbang name = "stingbang" - icon_state = "timeg" + icon_state = "timeg_locked" inhand_icon_state = "flashbang" lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' @@ -121,7 +121,7 @@ /obj/item/grenade/primer name = "rotfrag grenade" desc = "A grenade that generates more shrapnel the more you rotate it in your hand after pulling the pin. This one releases shrapnel shards." - icon_state = "timeg" + icon_state = "timeg_locked" inhand_icon_state = "flashbang" lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' From feebe34d4b99ea468818f6100c7f9538495ce4db Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Wed, 13 Nov 2024 19:11:47 +0100 Subject: [PATCH 019/222] Fixes detective action palette being invisible (#87814) ## About The Pull Request Closes #87809 --- icons/hud/64x16_actions.dmi | Bin 3920 -> 3919 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/hud/64x16_actions.dmi b/icons/hud/64x16_actions.dmi index 812d888846ebd76191628e35628847cfb88f4158..23865a80f03541e01515363a588b903ebf066205 100644 GIT binary patch delta 230 zcmVfFDZ*Bkpc$}5dF>b>!3fFDZ*Bkpc$}5dv1-FW5CqU#_Z5rXhZu~z zYl2KrVgG{JoYtpBr#rE`$j;xVNNHSbH_c-PW)ENI@8JslWe6LIa;p&G`0*LK2ah&E zgwru}6LFplA{R4;SjpJ;9Nrg`9&0_>P4xvG(Vcm zZutAtBzsl%FU$p1y=dXFa-PiV+Dd}P8+qaC|7$I%3*K4WWkM#+i?r}UsrlPXP^r$f hJ-u=yqh!3j1$#JOd+0Ai_yeb)0!7_xM%l6cQ4Yz5b94Xz From 8da8b8dd8798b3839e80579244201593ad5ef71e Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 18:11:54 +0000 Subject: [PATCH 020/222] Automatic changelog for PR #87812 [ci skip] --- html/changelogs/AutoChangeLog-pr-87812.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87812.yml diff --git a/html/changelogs/AutoChangeLog-pr-87812.yml b/html/changelogs/AutoChangeLog-pr-87812.yml new file mode 100644 index 0000000000000..17d9bbfac7c50 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87812.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Fixed stingbangs using wrong sprites" \ No newline at end of file From 0273e54d5a681920600a70f9698bc68880a81431 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 18:12:10 +0000 Subject: [PATCH 021/222] Automatic changelog for PR #87814 [ci skip] --- html/changelogs/AutoChangeLog-pr-87814.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87814.yml diff --git a/html/changelogs/AutoChangeLog-pr-87814.yml b/html/changelogs/AutoChangeLog-pr-87814.yml new file mode 100644 index 0000000000000..23e490d2aaffd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87814.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Fixed detective action palette being invisible" \ No newline at end of file From 0d7398d9d47e00d317faf7d30bc408013f59994c Mon Sep 17 00:00:00 2001 From: Rhials <28870487+Rhials@users.noreply.github.com> Date: Wed, 13 Nov 2024 13:21:32 -0500 Subject: [PATCH 022/222] Reduces required crayons for crayon bounty (#87848) ## About The Pull Request This reduces the bounty size of the crayon civilian pack. Instead of 24 crayons, it only needs 8. Same payout, less quantity. ## Why It's Good For The Game Crayons are not easily produced or scavenged. Even if a map contains 2 full crayon packs in the Library, it still isn't enough to fulfill a single bounty for crayons. This new deal will get you a full payout with a full pack plus one _mystery crayon._ Go rob the clown or detective or something if you need the last one. Get that money! --- code/modules/cargo/bounties/assistant.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/cargo/bounties/assistant.dm b/code/modules/cargo/bounties/assistant.dm index 23e578c2ed2db..a93fdc97d8e69 100644 --- a/code/modules/cargo/bounties/assistant.dm +++ b/code/modules/cargo/bounties/assistant.dm @@ -174,7 +174,7 @@ name = "Crayons" description = "Dr. Jones's kid ate all of our crayons again. Please send us yours." reward = CARGO_CRATE_VALUE * 4 - required_count = 24 + required_count = 8 wanted_types = list(/obj/item/toy/crayon = TRUE) /datum/bounty/item/assistant/pens From b6a74572deaca0bc7e0a9cc408c776019a61b52e Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 18:21:56 +0000 Subject: [PATCH 023/222] Automatic changelog for PR #87848 [ci skip] --- html/changelogs/AutoChangeLog-pr-87848.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87848.yml diff --git a/html/changelogs/AutoChangeLog-pr-87848.yml b/html/changelogs/AutoChangeLog-pr-87848.yml new file mode 100644 index 0000000000000..5754465ce3ea4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87848.yml @@ -0,0 +1,4 @@ +author: "Rhials" +delete-after: True +changes: + - qol: "Crayon bounties are less demanding, and require less crayons for payout." \ No newline at end of file From 0f26f6e9ee6400e6c014d1562b0f565234252372 Mon Sep 17 00:00:00 2001 From: Fikou <23585223+Fikou@users.noreply.github.com> Date: Wed, 13 Nov 2024 19:29:35 +0100 Subject: [PATCH 024/222] modsuit given traits use refs + fixes their deletion not working right + need boot out for ai to move (#87726) ## About The Pull Request so there is a problem of: if 2 modsuit modules were to apply the same trait and 1 were removed, shit would break so now all instances of mod_trait applied to the modsuit wearer are refs instead, with mod_trait used for stuff added to items as that isnt likely to have the same thing also qdeleted modsuits delete their parts apparently accidentally removed at some point. the previous time they did it caused qdel loops but this time it doesnt makes boots need to be out for an ai to move someone in a modsuit improves the ui, non-standard cores now have unique colors for the charging bar, and you can extend/retract things from ui, also adds a configurable button to config menu so that the tether doesnt repurpose the pin function made for circuits redoes modsuit balloon alerts to use simpler language makes the weapon recall module make you pick up the weapon if its on your tile as throws dont work on same tile ![image](https://github.com/user-attachments/assets/97a0eb85-8127-4297-b679-3e5488ce73be) ## Why It's Good For The Game futureproofing (also technically presentproofing, if you wear something like infiltrator and normal back modsuit and both have ai control they both will give you a trait) also ai movement doesnt have any checks currently, i think it makes sense that it would require your boots to be out so that the ai has something to move fix stuff change break boom wack --- code/__DEFINES/dcs/signals/signals_mod.dm | 6 +- code/modules/mod/mod_activation.dm | 71 ++++++++------- code/modules/mod/mod_ai.dm | 29 +++--- code/modules/mod/mod_construction.dm | 15 ++-- code/modules/mod/mod_control.dm | 75 ++++++++-------- code/modules/mod/mod_core.dm | 89 ++++++++++++++++--- code/modules/mod/mod_link.dm | 6 +- code/modules/mod/mod_paint.dm | 4 +- code/modules/mod/mod_ui.dm | 32 ++++--- code/modules/mod/modules/_module.dm | 4 +- code/modules/mod/modules/module_pathfinder.dm | 8 +- code/modules/mod/modules/modules_antag.dm | 57 ++++++------ .../mod/modules/modules_engineering.dm | 18 ++-- code/modules/mod/modules/modules_general.dm | 18 ++-- code/modules/mod/modules/modules_maint.dm | 8 +- code/modules/mod/modules/modules_medical.dm | 8 +- code/modules/mod/modules/modules_ninja.dm | 12 +-- code/modules/mod/modules/modules_science.dm | 8 +- code/modules/mod/modules/modules_security.dm | 18 ++-- code/modules/mod/modules/modules_service.dm | 6 +- code/modules/mod/modules/modules_supply.dm | 14 +-- code/modules/mod/modules/modules_timeline.dm | 4 +- code/modules/mod/modules/modules_visor.dm | 4 +- tgui/packages/tgui/interfaces/MODsuit.tsx | 86 ++++++++++-------- 24 files changed, 355 insertions(+), 245 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_mod.dm b/code/__DEFINES/dcs/signals/signals_mod.dm index 09b29c9378490..58fd8ca689ed1 100644 --- a/code/__DEFINES/dcs/signals/signals_mod.dm +++ b/code/__DEFINES/dcs/signals/signals_mod.dm @@ -5,10 +5,12 @@ #define COMSIG_MOD_DEPLOYED "mod_deployed" /// Called when a MOD user retracts one or more of its parts. #define COMSIG_MOD_RETRACTED "mod_retracted" -/// Called when a MOD deploys a part. +/// Called when a MOD deploys a part. (mob/user, datum/mod_part/part) #define COMSIG_MOD_PART_DEPLOYED "mod_part_deployed" -/// Called when a MOD retracts a part. +/// Called when a MOD retracts a part. (mob/user, datum/mod_part/part) #define COMSIG_MOD_PART_RETRACTED "mod_part_retracted" +/// Called when a MOD seals/unseals a part. (datum/mod_part/part) +#define COMSIG_MOD_PART_SEALED "mod_part_sealed" /// Called when a MOD is finished toggling itself. #define COMSIG_MOD_TOGGLED "mod_toggled" /// Called when a MOD activation is called from toggle_activate(mob/user) diff --git a/code/modules/mod/mod_activation.dm b/code/modules/mod/mod_activation.dm index ee4725075aadc..ecc3eaaedc241 100644 --- a/code/modules/mod/mod_activation.dm +++ b/code/modules/mod/mod_activation.dm @@ -26,7 +26,7 @@ return var/parts_to_check = parts - part if(part.loc == src) - if(!deploy(user, part) || (active && !delayed_seal_part(part))) + if(!deploy(user, part)) return SEND_SIGNAL(src, COMSIG_MOD_DEPLOYED, user) for(var/obj/item/checking_part as anything in parts_to_check) @@ -35,7 +35,7 @@ choose_deploy(user) break else - if((active && !delayed_seal_part(part, silent = TRUE)) || !retract(user, part)) + if(!retract(user, part)) return SEND_SIGNAL(src, COMSIG_MOD_RETRACTED, user) for(var/obj/item/checking_part as anything in parts_to_check) @@ -64,12 +64,7 @@ if(deploy && part.loc == src) if(!deploy(null, part)) continue - if(active && !delayed_seal_part(part)) - retract(null, part) - return else if(!deploy && part.loc != src) - if(active && !delayed_seal_part(part)) - return retract(null, part) if(deploy) SEND_SIGNAL(src, COMSIG_MOD_DEPLOYED, user) @@ -78,7 +73,7 @@ return TRUE /// Deploys a part of the suit onto the user. -/obj/item/mod/control/proc/deploy(mob/user, obj/item/part) +/obj/item/mod/control/proc/deploy(mob/user, obj/item/part, instant = FALSE) var/datum/mod_part/part_datum = get_part_datum(part) if(!wearer) playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) @@ -86,7 +81,7 @@ if(part.loc != src) if(!user) return FALSE - balloon_alert(user, "[part.name] already deployed!") + balloon_alert(user, "already deployed!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) if(part_datum.can_overslot) var/obj/item/overslot = wearer.get_item_by_slot(part.slot_flags) @@ -97,14 +92,21 @@ if(wearer.equip_to_slot_if_possible(part, part.slot_flags, qdel_on_fail = FALSE, disable_warning = TRUE)) ADD_TRAIT(part, TRAIT_NODROP, MOD_TRAIT) wearer.update_clothing(slot_flags) - if(!user) + SEND_SIGNAL(src, COMSIG_MOD_PART_DEPLOYED, user, part_datum) + if(user) + wearer.visible_message(span_notice("[wearer]'s [part.name] deploy[part.p_s()] with a mechanical hiss."), + span_notice("[part] deploy[part.p_s()] with a mechanical hiss."), + span_hear("You hear a mechanical hiss.")) + playsound(src, 'sound/vehicles/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + if(!active || part_datum.sealed) return TRUE - wearer.visible_message(span_notice("[wearer]'s [part.name] deploy[part.p_s()] with a mechanical hiss."), - span_notice("[part] deploy[part.p_s()] with a mechanical hiss."), - span_hear("You hear a mechanical hiss.")) - playsound(src, 'sound/vehicles/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - SEND_SIGNAL(src, COMSIG_MOD_PART_DEPLOYED, user, part) - return TRUE + if(instant) + seal_part(part, is_sealed = TRUE) + return TRUE + else if(delayed_seal_part(part)) + return TRUE + balloon_alert(user, "can't seal, retracting!") + retract(user, part, instant = TRUE) else if(part_datum.overslotting) var/obj/item/overslot = part_datum.overslotting @@ -117,14 +119,21 @@ return FALSE /// Retract a part of the suit from the user. -/obj/item/mod/control/proc/retract(mob/user, obj/item/part) +/obj/item/mod/control/proc/retract(mob/user, obj/item/part, instant = FALSE) var/datum/mod_part/part_datum = get_part_datum(part) if(part.loc == src) if(!user) return FALSE - balloon_alert(user, "[part.name] already retracted!") + balloon_alert(user, "already retracted!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return FALSE + if(active && part_datum.sealed) + if(instant) + seal_part(part, is_sealed = FALSE) + else if(!delayed_seal_part(part)) + balloon_alert(user, "can't unseal!") + playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return FALSE REMOVE_TRAIT(part, TRAIT_NODROP, MOD_TRAIT) wearer.transferItemToLoc(part, src, force = TRUE) if(part_datum.overslotting) @@ -132,7 +141,7 @@ if(!QDELING(wearer) && !wearer.equip_to_slot_if_possible(overslot, overslot.slot_flags, qdel_on_fail = FALSE, disable_warning = TRUE)) wearer.dropItemToGround(overslot, force = TRUE, silent = TRUE) wearer.update_clothing(slot_flags) - SEND_SIGNAL(src, COMSIG_MOD_PART_RETRACTED, user, part) + SEND_SIGNAL(src, COMSIG_MOD_PART_RETRACTED, user, part_datum) if(!user) return TRUE wearer.visible_message(span_notice("[wearer]'s [part.name] retract[part.p_s()] back into [src] with a mechanical hiss."), @@ -145,7 +154,7 @@ /obj/item/mod/control/proc/toggle_activate(mob/user, force_deactivate = FALSE) if(!wearer) if(!force_deactivate) - balloon_alert(user, "equip suit first!") + balloon_alert(user, "not equipped!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return FALSE if(!force_deactivate && (SEND_SIGNAL(src, COMSIG_MOD_ACTIVATE, user) & MOD_CANCEL_ACTIVATE)) @@ -156,16 +165,16 @@ playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return FALSE if(!get_charge() && !force_deactivate) - balloon_alert(user, "suit not powered!") + balloon_alert(user, "no power source!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return FALSE if(open && !force_deactivate) - balloon_alert(user, "close the suit panel!") + balloon_alert(user, "panel open!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return FALSE if(activating) if(!force_deactivate) - balloon_alert(user, "suit already [active ? "shutting down" : "starting up"]!") + balloon_alert(user, "already [active ? "shutting down" : "starting up"]!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return FALSE for(var/obj/item/mod/module/module as anything in modules) @@ -221,13 +230,12 @@ SEND_SIGNAL(src, COMSIG_MOD_TOGGLED, user) return TRUE -/obj/item/mod/control/proc/delayed_seal_part(obj/item/clothing/part, silent = FALSE) +/obj/item/mod/control/proc/delayed_seal_part(obj/item/clothing/part) . = FALSE var/datum/mod_part/part_datum = get_part_datum(part) if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(get_wearer)), hidden = TRUE)) - if(!silent) - to_chat(wearer, span_notice("[part] [!part_datum.sealed ? part_datum.sealed_message : part_datum.unsealed_message].")) - playsound(src, 'sound/vehicles/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + to_chat(wearer, span_notice("[part] [!part_datum.sealed ? part_datum.sealed_message : part_datum.unsealed_message].")) + playsound(src, 'sound/vehicles/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) seal_part(part, is_sealed = !part_datum.sealed) return TRUE @@ -262,6 +270,7 @@ wearer.update_obscured_slots(part.visor_flags_inv) if((part.clothing_flags & (MASKINTERNALS|HEADINTERNALS)) && wearer.invalid_internals()) wearer.cutoff_internals() + SEND_SIGNAL(src, COMSIG_MOD_PART_SEALED, part_datum) if(is_sealed) if (!active) return @@ -308,12 +317,8 @@ /// Quickly deploys all the suit parts and if successful, seals them and turns on the suit. Intended mostly for outfits. /obj/item/mod/control/proc/quick_activation() - for(var/obj/item/part as anything in get_parts()) - deploy(null, part) - for(var/obj/item/part as anything in get_parts()) - if(part.loc == src) - continue - seal_part(part, is_sealed = TRUE) control_activation(is_on = TRUE) + for(var/obj/item/part as anything in get_parts()) + deploy(null, part, instant = TRUE) #undef MOD_ACTIVATION_STEP_FLAGS diff --git a/code/modules/mod/mod_ai.dm b/code/modules/mod/mod_ai.dm index 1336ff1707449..62e9188fddd1a 100644 --- a/code/modules/mod/mod_ai.dm +++ b/code/modules/mod/mod_ai.dm @@ -3,19 +3,19 @@ if(!.) return if(!open) //mod must be open - balloon_alert(user, "suit must be open to transfer!") + balloon_alert(user, "panel closed!") return switch(interaction) if(AI_TRANS_TO_CARD) if(!ai_assistant) - balloon_alert(user, "no ai in suit!") + balloon_alert(user, "no ai in unit!") return balloon_alert(user, "transferring to card...") if(!do_after(user, 5 SECONDS, target = src)) balloon_alert(user, "interrupted!") return if(!ai_assistant) - balloon_alert(user, "no ai in suit!") + balloon_alert(user, "no ai in unit!") return balloon_alert(user, "ai transferred to card") ai_exit_mod(card) @@ -33,13 +33,13 @@ if(intAI.stat || !intAI.client) balloon_alert(user, "ai unresponsive!") return - balloon_alert(user, "transferring to suit...") + balloon_alert(user, "transferring to unit...") if(!do_after(user, 5 SECONDS, target = src)) balloon_alert(user, "interrupted!") return if(ai_assistant) return - balloon_alert(user, "ai transferred to suit") + balloon_alert(user, "ai transferred to unit") ai_enter_mod(intAI) card.AI = null @@ -74,14 +74,14 @@ if (isnull(card.pai?.mind)) balloon_alert(user, "pAI unresponsive!") return FALSE - balloon_alert(user, "transferring to suit...") + balloon_alert(user, "transferring to unit...") if (!do_after(user, 5 SECONDS, target = src)) balloon_alert(user, "interrupted!") return FALSE if (!user.transferItemToLoc(card, src)) balloon_alert(user, "transfer failed!") return FALSE - balloon_alert(user, "pAI transferred to suit") + balloon_alert(user, "pAI transferred to unit") var/mob/living/silicon/pai/pai_assistant = card.pai pai_assistant.can_transmit = TRUE pai_assistant.can_receive = TRUE @@ -99,14 +99,14 @@ return FALSE if (!forced) if (!open) - balloon_alert(user, "suit panel closed!") + balloon_alert(user, "panel closed!") return FALSE balloon_alert(user, "uninstalling card...") if (!do_after(user, 5 SECONDS, target = src)) balloon_alert(user, "interrupted!") return FALSE - balloon_alert(user, "pAI removed from suit") + balloon_alert(user, "pAI removed") var/mob/living/silicon/pai/pai_helper = ai_assistant pai_helper.can_holo = TRUE pai_helper.card.forceMove(get_turf(src)) @@ -115,7 +115,7 @@ /// Called when a new ai assistant is inserted /obj/item/mod/control/proc/on_gained_assistant(mob/living/silicon/new_helper) ai_assistant = new_helper - balloon_alert(new_helper, "transferred to a suit") + balloon_alert(new_helper, "transferred to a mod unit") for(var/datum/action/action as anything in actions) action.Grant(new_helper) @@ -134,7 +134,10 @@ #define AI_FALL_TIME (1 SECONDS) /obj/item/mod/control/relaymove(mob/user, direction) - if((!active && wearer) || get_charge() < CHARGE_PER_STEP || user != ai_assistant || !COOLDOWN_FINISHED(src, cooldown_mod_move) || (wearer?.pulledby?.grab_state > GRAB_PASSIVE)) + if((!active && wearer) || get_charge() < CHARGE_PER_STEP || user != ai_assistant || !COOLDOWN_FINISHED(src, cooldown_mod_move) || (wearer?.pulledby?.grab_state > GRAB_PASSIVE)) + return FALSE + var/datum/mod_part/legs_to_move = get_part_datum_from_slot(ITEM_SLOT_FEET) + if(wearer && (!legs_to_move || !legs_to_move.sealed)) return FALSE var/timemodifier = MOVE_DELAY * (ISDIAGONALDIR(direction) ? sqrt(2) : 1) * (wearer ? WEARER_DELAY : LONE_DELAY) if(wearer && !wearer.Process_Spacemove(direction)) @@ -147,7 +150,7 @@ if(ismovable(wearer?.loc)) return wearer.loc.relaymove(wearer, direction) else if(wearer) - ADD_TRAIT(wearer, TRAIT_FORCED_STANDING, MOD_TRAIT) + ADD_TRAIT(wearer, TRAIT_FORCED_STANDING, REF(src)) addtimer(CALLBACK(src, PROC_REF(ai_fall)), AI_FALL_TIME, TIMER_UNIQUE | TIMER_OVERRIDE) var/atom/movable/mover = wearer || src return mover.try_step_multiz(direction) @@ -160,7 +163,7 @@ /obj/item/mod/control/proc/ai_fall() if(!wearer) return - REMOVE_TRAIT(wearer, TRAIT_FORCED_STANDING, MOD_TRAIT) + REMOVE_TRAIT(wearer, TRAIT_FORCED_STANDING, REF(src)) /obj/item/mod/ai_minicard name = "AI mini-card" diff --git a/code/modules/mod/mod_construction.dm b/code/modules/mod/mod_construction.dm index 16ce70df94563..3581c04e606a9 100644 --- a/code/modules/mod/mod_construction.dm +++ b/code/modules/mod/mod_construction.dm @@ -162,7 +162,7 @@ if(!istype(part, /obj/item/mod/core)) return if(!user.transferItemToLoc(part, src)) - balloon_alert(user, "core stuck to your hand!") + balloon_alert(user, "it's stuck!") return playsound(src, 'sound/machines/click.ogg', 30, TRUE) balloon_alert(user, "core inserted") @@ -181,7 +181,7 @@ if(SCREWED_CORE_STEP) if(istype(part, /obj/item/mod/construction/helmet)) //Construct if(!user.transferItemToLoc(part, src)) - balloon_alert(user, "helmet stuck to your hand!") + balloon_alert(user, "it's stuck!") return playsound(src, 'sound/machines/click.ogg', 30, TRUE) balloon_alert(user, "helmet added") @@ -194,7 +194,7 @@ if(HELMET_STEP) if(istype(part, /obj/item/mod/construction/chestplate)) //Construct if(!user.transferItemToLoc(part, src)) - balloon_alert(user, "chestplate stuck to your hand!") + balloon_alert(user, "it's stuck!") return playsound(src, 'sound/machines/click.ogg', 30, TRUE) balloon_alert(user, "chestplate added") @@ -209,7 +209,7 @@ if(CHESTPLATE_STEP) if(istype(part, /obj/item/mod/construction/gauntlets)) //Construct if(!user.transferItemToLoc(part, src)) - balloon_alert(user, "gauntlets stuck to your hand!") + balloon_alert(user, "it's stuck!") return playsound(src, 'sound/machines/click.ogg', 30, TRUE) balloon_alert(user, "gauntlets added") @@ -224,10 +224,10 @@ if(GAUNTLETS_STEP) if(istype(part, /obj/item/mod/construction/boots)) //Construct if(!user.transferItemToLoc(part, src)) - balloon_alert(user, "boots added") + balloon_alert(user, "it's stuck!") return playsound(src, 'sound/machines/click.ogg', 30, TRUE) - balloon_alert(user, "fit [part.name]") + balloon_alert(user, "boots added") boots = part step = BOOTS_STEP else if(part.tool_behaviour == TOOL_CROWBAR) //Deconstruct @@ -260,13 +260,14 @@ if(istype(part, /obj/item/mod/construction/plating)) //Construct var/obj/item/mod/construction/plating/external_plating = part if(!user.transferItemToLoc(part, src)) + balloon_alert(user, "it's stuck!") return playsound(src, 'sound/machines/click.ogg', 30, TRUE) var/obj/item/mod = new /obj/item/mod/control(drop_location(), external_plating.theme, null, core) core = null qdel(src) user.put_in_hands(mod) - mod.balloon_alert(user, "suit finished") + mod.balloon_alert(user, "unit finished") else if(part.tool_behaviour == TOOL_SCREWDRIVER) //Construct if(part.use_tool(src, user, 0, volume=30)) balloon_alert(user, "assembly unscrewed") diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm index 0f521e40691f4..436c9e7c20d88 100644 --- a/code/modules/mod/mod_control.dm +++ b/code/modules/mod/mod_control.dm @@ -97,7 +97,6 @@ theme.set_up_parts(src, new_skin) for(var/obj/item/part as anything in get_parts()) RegisterSignal(part, COMSIG_ATOM_DESTRUCTION, PROC_REF(on_part_destruction)) - RegisterSignal(part, COMSIG_QDELETING, PROC_REF(on_part_deletion)) set_wires(new /datum/wires/mod(src)) if(length(req_access)) locked = TRUE @@ -118,14 +117,19 @@ QDEL_NULL(core) QDEL_NULL(mod_link) for(var/datum/mod_part/part_datum as anything in get_part_datums(all = TRUE)) + var/obj/item/part_item = part_datum.part_item part_datum.part_item = null part_datum.overslotting = null + mod_parts -= part_datum + if(!QDELING(part_item)) + qdel(part_item) return ..() /obj/item/mod/control/atom_destruction(damage_flag) + var/atom/visible_atom = wearer || src if(wearer) - wearer.visible_message(span_danger("[src] fall[p_s()] apart, completely destroyed!"), vision_distance = COMBAT_MESSAGE_RANGE) clean_up() + visible_atom.visible_message(span_bolddanger("[src] fall[p_s()] apart, completely destroyed!"), vision_distance = COMBAT_MESSAGE_RANGE) for(var/obj/item/mod/module/module as anything in modules) uninstall(module) if(ai_assistant) @@ -220,12 +224,12 @@ if(user != wearer) return ..() if(active) - balloon_alert(wearer, "deactivate the suit first!") + balloon_alert(wearer, "unit active!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, FALSE, SILENCED_SOUND_EXTRARANGE) return for(var/obj/item/part as anything in get_parts()) if(part.loc != src) - balloon_alert(user, "retract parts first!") + balloon_alert(user, "parts extended!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, FALSE, SILENCED_SOUND_EXTRARANGE) return FALSE @@ -233,12 +237,12 @@ if(user != wearer || !istype(over_object, /atom/movable/screen/inventory/hand)) return if(active) - balloon_alert(wearer, "deactivate the suit first!") + balloon_alert(wearer, "unit active!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, FALSE, SILENCED_SOUND_EXTRARANGE) return for(var/obj/item/part as anything in get_parts()) if(part.loc != src) - balloon_alert(wearer, "retract parts first!") + balloon_alert(wearer, "parts extended!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, FALSE, SILENCED_SOUND_EXTRARANGE) return if(!wearer.incapacitated) @@ -266,14 +270,15 @@ /obj/item/mod/control/screwdriver_act(mob/living/user, obj/item/screwdriver) if(active || activating || ai_controller) - balloon_alert(user, "deactivate suit first!") + balloon_alert(user, "unit active!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return ITEM_INTERACT_BLOCKING balloon_alert(user, "[open ? "closing" : "opening"] cover...") screwdriver.play_tool_sound(src, 100) if(screwdriver.use_tool(src, user, 1 SECONDS)) if(active || activating) - balloon_alert(user, "deactivate suit first!") + balloon_alert(user, "unit active!") + return ITEM_INTERACT_SUCCESS screwdriver.play_tool_sound(src, 100) balloon_alert(user, "cover [open ? "closed" : "opened"]") open = !open @@ -283,7 +288,7 @@ /obj/item/mod/control/crowbar_act(mob/living/user, obj/item/crowbar) if(!open) - balloon_alert(user, "open the cover first!") + balloon_alert(user, "cover closed!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return ITEM_INTERACT_BLOCKING if(!allowed(user)) @@ -315,14 +320,14 @@ /obj/item/mod/control/tool_act(mob/living/user, obj/item/tool, list/modifiers) if(istype(tool, /obj/item/pai_card)) if(!open) - balloon_alert(user, "open the cover first!") + balloon_alert(user, "cover closed!") return NONE // shoves the card in the storage anyways insert_pai(user, tool) return ITEM_INTERACT_SUCCESS if(istype(tool, /obj/item/mod/paint)) var/obj/item/mod/paint/paint_kit = tool if(active || activating) - balloon_alert(user, "suit is active!") + balloon_alert(user, "unit active!") return ITEM_INTERACT_BLOCKING if(LAZYACCESS(modifiers, RIGHT_CLICK)) // Right click if(paint_kit.editing_mod == src) @@ -341,7 +346,7 @@ return ITEM_INTERACT_SUCCESS if(istype(tool, /obj/item/mod/module)) if(!open) - balloon_alert(user, "open the cover first!") + balloon_alert(user, "cover closed!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return ITEM_INTERACT_BLOCKING install(tool, user) @@ -349,11 +354,11 @@ return ITEM_INTERACT_SUCCESS if(istype(tool, /obj/item/mod/core)) if(!open) - balloon_alert(user, "open the cover first!") + balloon_alert(user, "cover closed!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return ITEM_INTERACT_BLOCKING if(core) - balloon_alert(user, "core already installed!") + balloon_alert(user, "already has core!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return ITEM_INTERACT_BLOCKING var/obj/item/mod/core/attacking_core = tool @@ -385,7 +390,7 @@ /obj/item/mod/control/emag_act(mob/user, obj/item/card/emag/emag_card) locked = !locked - balloon_alert(user, "suit access [locked ? "locked" : "unlocked"]") + balloon_alert(user, "access [locked ? "locked" : "unlocked"]") return TRUE /obj/item/mod/control/emp_act(severity) @@ -445,12 +450,11 @@ CRASH("get_part_datum called with incorrect item [part] passed.") /obj/item/mod/control/proc/get_part_from_slot(slot) - slot = "[slot]" - for(var/part_slot in mod_parts) - if(slot != part_slot) - continue - var/datum/mod_part/part = mod_parts[part_slot] - return part.part_item + var/datum/mod_part/part = mod_parts["[slot]"] + return part?.part_item + +/obj/item/mod/control/proc/get_part_datum_from_slot(slot) + return mod_parts["[slot]"] /obj/item/mod/control/proc/set_wearer(mob/living/carbon/human/user) if(wearer == user) @@ -511,7 +515,7 @@ for(var/obj/item/part as anything in get_parts()) seal_part(part, is_sealed = FALSE) for(var/obj/item/part as anything in get_parts()) - retract(null, part) + INVOKE_ASYNC(src, PROC_REF(retract), wearer, part, /* instant = */ TRUE) // async to appease spaceman DMM because the branch we don't run has a do_after if(active) control_activation(is_on = FALSE) mod_link?.end_call() @@ -579,24 +583,24 @@ for(var/obj/item/mod/module/old_module as anything in modules) if(is_type_in_list(new_module, old_module.incompatible_modules) || is_type_in_list(old_module, new_module.incompatible_modules)) if(user) - balloon_alert(user, "[new_module] incompatible with [old_module]!") + balloon_alert(user, "incompatible with [old_module]!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return var/complexity_with_module = complexity complexity_with_module += new_module.complexity if(complexity_with_module > complexity_max) if(user) - balloon_alert(user, "[new_module] would make [src] too complex!") + balloon_alert(user, "above complexity max!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return if(!new_module.has_required_parts(mod_parts)) if(user) - balloon_alert(user, "[new_module] incompatible with [src]'s parts!") + balloon_alert(user, "lacking required parts!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return if(!new_module.can_install(src)) if(user) - balloon_alert(user, "[new_module] cannot be installed into [src]!") + balloon_alert(user, "can't install!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return new_module.forceMove(src) @@ -661,6 +665,12 @@ /obj/item/mod/control/proc/check_charge(amount) return core?.check_charge(amount) || FALSE +/obj/item/mod/control/proc/get_chargebar_color() + return core?.get_chargebar_color() || "transparent" + +/obj/item/mod/control/proc/get_chargebar_string() + return core?.get_chargebar_string() || "No Core Detected" + /** * Updates the wearer's hud according to the current state of the MODsuit */ @@ -706,6 +716,9 @@ uninstall(part) return if(part in get_parts()) + if(QDELING(part) && !QDELING(src)) + qdel(src) + return var/datum/mod_part/part_datum = get_part_datum(part) if(part_datum.sealed) seal_part(part, is_sealed = FALSE) @@ -714,7 +727,7 @@ if(!wearer) part.forceMove(src) return - retract(wearer, part) + INVOKE_ASYNC(src, PROC_REF(retract), wearer, part, /* instant = */ TRUE) // async to appease spaceman DMM because the branch we don't run has a do_after /obj/item/mod/control/proc/on_part_destruction(obj/item/part, damage_flag) SIGNAL_HANDLER @@ -723,14 +736,6 @@ return atom_destruction(damage_flag) -/obj/item/mod/control/proc/on_part_deletion(obj/item/part) - SIGNAL_HANDLER - - if(QDELING(src)) - return - part.moveToNullspace() - qdel(src) - /obj/item/mod/control/proc/on_overslot_exit(obj/item/part, atom/movable/overslot, direction) SIGNAL_HANDLER diff --git a/code/modules/mod/mod_core.dm b/code/modules/mod/mod_core.dm index 79a8eff5e290a..01e0902b6b03c 100644 --- a/code/modules/mod/mod_core.dm +++ b/code/modules/mod/mod_core.dm @@ -25,30 +25,45 @@ mod.update_charge_alert() mod = null +/// Returns the item responsible for charging the suit, like a power cell, an ethereal's stomach, the core itself, etc. /obj/item/mod/core/proc/charge_source() return +/// Returns the amount of charge in the core. /obj/item/mod/core/proc/charge_amount() return 0 +/// Returns the max amount of charge stored in the core. /obj/item/mod/core/proc/max_charge_amount() return 1 +/// Adds a set amount of charge to the core. /obj/item/mod/core/proc/add_charge(amount) return FALSE +/// Subtracts a set amount of charge from the core. /obj/item/mod/core/proc/subtract_charge(amount) return FALSE +/// Checks if there's enough charge in the core to use an amount of energy. /obj/item/mod/core/proc/check_charge(amount) return FALSE -/** - * Gets what icon state to display on the HUD for the charge level of this core - */ +/// Returns what icon state to display on the HUD for the charge level of this core /obj/item/mod/core/proc/get_charge_icon_state() return "0" +/// Gets what the UI should use for the charge bar color. +/obj/item/mod/core/proc/get_chargebar_color() + return "bad" + +/// Gets what the UI should use for the charge bar text. +/obj/item/mod/core/proc/get_chargebar_string() + var/charge_amount = charge_amount() + var/max_charge_amount = max_charge_amount() + return "[display_energy(charge_amount)] of [display_energy(max_charge_amount())] \ + ([round((100 * charge_amount) / max_charge_amount, 1)]%)" + /obj/item/mod/core/infinite name = "MOD infinite core" icon_state = "mod-core-infinite" @@ -76,6 +91,12 @@ /obj/item/mod/core/infinite/get_charge_icon_state() return "high" +/obj/item/mod/core/infinite/get_chargebar_color() + return "teal" + +/obj/item/mod/core/infinite/get_chargebar_string() + return "Infinite" + /obj/item/mod/core/standard name = "MOD standard core" icon_state = "mod-core-standard" @@ -163,6 +184,22 @@ return "empty" +/obj/item/mod/core/standard/get_chargebar_color() + if(isnull(charge_source())) + return "transparent" + switch(round(charge_amount() / max_charge_amount(), 0.01)) + if(-INFINITY to 0.33) + return "bad" + if(0.33 to 0.66) + return "average" + if(0.66 to INFINITY) + return "good" + +/obj/item/mod/core/standard/get_chargebar_string() + if(isnull(charge_source())) + return "Power Cell Missing" + return ..() + /obj/item/mod/core/standard/proc/install_cell(new_cell) cell = new_cell cell.forceMove(src) @@ -222,11 +259,11 @@ if(!istype(attacking_item, /obj/item/stock_parts/power_store/cell)) return FALSE if(!mod.open) - mod.balloon_alert(user, "open the cover first!") + mod.balloon_alert(user, "cover closed!") playsound(mod, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return FALSE if(cell) - mod.balloon_alert(user, "cell already installed!") + mod.balloon_alert(user, "already has cell!") playsound(mod, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return FALSE install_cell(attacking_item) @@ -260,7 +297,9 @@ name = "MOD ethereal core" icon_state = "mod-core-ethereal" desc = "A reverse engineered core of a Modular Outerwear Device. Using natural liquid electricity from Ethereals, \ - preventing the need to use external sources to convert electric charge." + preventing the need to use external sources to convert electric charge. As the suits are naturally charged by \ + liquid electricity, this core makes it much more efficient, running all soft, hard, and wetware with several \ + times less energy usage." /// A modifier to all charge we use, ethereals don't need to spend as much energy as normal suits. var/charge_modifier = 0.1 @@ -279,22 +318,41 @@ /obj/item/mod/core/ethereal/add_charge(amount) var/obj/item/organ/stomach/ethereal/charge_source = charge_source() - if(!charge_source) + if(isnull(charge_source)) return FALSE - charge_source.adjust_charge(amount*charge_modifier) + charge_source.adjust_charge(amount * charge_modifier) return TRUE /obj/item/mod/core/ethereal/subtract_charge(amount) var/obj/item/organ/stomach/ethereal/charge_source = charge_source() - if(!charge_source) + if(isnull(charge_source)) return FALSE - return -charge_source.adjust_charge(-amount*charge_modifier) + return -charge_source.adjust_charge(-amount * charge_modifier) /obj/item/mod/core/ethereal/check_charge(amount) - return charge_amount() >= amount*charge_modifier + return charge_amount() >= amount * charge_modifier /obj/item/mod/core/ethereal/get_charge_icon_state() - return charge_source() ? "0" : "missing" + return isnull(charge_source()) ? "missing" : "0" + +/obj/item/mod/core/ethereal/get_chargebar_color() + if(isnull(charge_source())) + return "transparent" + switch(charge_amount()) + if(-INFINITY to ETHEREAL_CHARGE_LOWPOWER) + return "bad" + if(ETHEREAL_CHARGE_LOWPOWER to ETHEREAL_CHARGE_NORMAL) + return "average" + if(ETHEREAL_CHARGE_NORMAL to ETHEREAL_CHARGE_FULL) + return "good" + if(ETHEREAL_CHARGE_FULL to INFINITY) + return "teal" + +/obj/item/mod/core/ethereal/get_chargebar_string() + var/obj/item/organ/stomach/ethereal/charge_source = charge_source() + if(isnull(charge_source()) || isnull(charge_source.cell)) + return "Biological Battery Missing" + return ..() #define PLASMA_CORE_ORE_CHARGE (1.5 * STANDARD_CELL_CHARGE) #define PLASMA_CORE_SHEET_CHARGE (2 * STANDARD_CELL_CHARGE) @@ -355,6 +413,13 @@ return "empty" +/obj/item/mod/core/plasma/get_chargebar_color() + switch(round(charge_amount() / max_charge_amount(), 0.01)) + if(-INFINITY to 0.33) + return "bad" + if(0.33 to INFINITY) + return "purple" + /obj/item/mod/core/plasma/proc/on_mod_interaction(datum/source, mob/living/user, obj/item/thing) SIGNAL_HANDLER diff --git a/code/modules/mod/mod_link.dm b/code/modules/mod/mod_link.dm index e7a5a20d9f370..0750c3c41be26 100644 --- a/code/modules/mod/mod_link.dm +++ b/code/modules/mod/mod_link.dm @@ -213,7 +213,7 @@ if(!user.transferItemToLoc(attacked_by, src)) return cell = attacked_by - balloon_alert(user, "installed [cell.name]") + balloon_alert(user, "cell installed") /obj/item/clothing/neck/link_scryer/update_name(updates) . = ..() @@ -227,7 +227,7 @@ /obj/item/clothing/neck/link_scryer/attack_hand_secondary(mob/user, list/modifiers) if(!cell) return SECONDARY_ATTACK_CONTINUE_CHAIN - balloon_alert(user, "removed [cell.name]") + balloon_alert(user, "cell removed") user.put_in_hands(cell) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN @@ -409,7 +409,7 @@ if(!link_user) return if(HAS_TRAIT(link_user, TRAIT_IN_CALL)) - holder.balloon_alert(user, "user already in call!") + holder.balloon_alert(user, "already calling!") return var/mob/living/link_target = called.get_user_callback.Invoke() if(!link_target) diff --git a/code/modules/mod/mod_paint.dm b/code/modules/mod/mod_paint.dm index e3e42e55f613c..2f658e9df2470 100644 --- a/code/modules/mod/mod_paint.dm +++ b/code/modules/mod/mod_paint.dm @@ -153,10 +153,10 @@ return NONE var/obj/item/mod/control/mod = attacked_atom if(mod.active || mod.activating) - balloon_alert(user, "suit is active!") + balloon_alert(user, "unit active!") return ITEM_INTERACT_BLOCKING if(!(skin in mod.theme.variants)) - balloon_alert(user, "incompatible theme!") + balloon_alert(user, "wrong theme for skin!") return ITEM_INTERACT_BLOCKING mod.theme.set_skin(mod, skin) balloon_alert(user, "skin applied") diff --git a/code/modules/mod/mod_ui.dm b/code/modules/mod/mod_ui.dm index 2a8ccf7b4bf94..9a8e77f7e8e76 100644 --- a/code/modules/mod/mod_ui.dm +++ b/code/modules/mod/mod_ui.dm @@ -9,8 +9,10 @@ // Suit information var/suit_status = list( "core_name" = core?.name, - "cell_charge_current" = get_charge(), - "cell_charge_max" = get_max_charge(), + "charge_current" = get_charge(), + "charge_max" = get_max_charge(), + "chargebar_color" = get_chargebar_color(), + "chargebar_string" = get_chargebar_string(), "active" = active, "ai_name" = ai_assistant?.name, "has_pai" = ispAI(ai_assistant), @@ -56,23 +58,25 @@ "configuration_data" = module.get_configuration(user), )) data["module_custom_status"] = module_custom_status - data["module_info"] = module_info - return data - -/obj/item/mod/control/ui_static_data(mob/user) - var/data = list() - data["ui_theme"] = ui_theme data["control"] = name - data["complexity_max"] = complexity_max + data["module_info"] = module_info var/part_info = list() for(var/obj/item/part as anything in get_parts()) part_info += list(list( "slot" = english_list(parse_slot_flags(part.slot_flags)), "name" = part.name, + "deployed" = part.loc != src, + "ref" = REF(part), )) data["parts"] = part_info return data +/obj/item/mod/control/ui_static_data(mob/user) + var/data = list() + data["ui_theme"] = ui_theme + data["complexity_max"] = complexity_max + return data + /obj/item/mod/control/ui_state(mob/user) if(user == ai_assistant) return GLOB.contained_state @@ -89,7 +93,7 @@ if("lock") if(!locked || allowed(ui.user)) locked = !locked - balloon_alert(ui.user, "[locked ? "locked" : "unlocked"]!") + balloon_alert(ui.user, "[locked ? "locked" : "unlocked"]") else balloon_alert(ui.user, "access insufficent!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) @@ -115,6 +119,14 @@ if(!module) return module.pin(ui.user) + if("deploy") + var/obj/item/mod_part = locate(params["ref"]) in get_parts() + if(!mod_part) + return + if(mod_part.loc == src) + deploy(ui.user, mod_part) + else + retract(ui.user, mod_part) if("eject_pai") if (!ishuman(ui.user)) return diff --git a/code/modules/mod/modules/_module.dm b/code/modules/mod/modules/_module.dm index 28a588609a783..390431300d541 100644 --- a/code/modules/mod/modules/_module.dm +++ b/code/modules/mod/modules/_module.dm @@ -300,7 +300,7 @@ /obj/item/mod/module/proc/add_ui_data() return list() -/// Creates a list of configuring options for this module +/// Creates a list of configuring options for this module, possible configs include number, bool, color, list, button. /obj/item/mod/module/proc/get_configuration(mob/user) return list() @@ -491,7 +491,7 @@ balloon_alert(user, "no core!") return if(!core_removable) - balloon_alert(user, "can't remove core!") + balloon_alert(user, "already has core!") return balloon_alert(user, "removing core...") if(!do_after(user, 3 SECONDS, target = src)) diff --git a/code/modules/mod/modules/module_pathfinder.dm b/code/modules/mod/modules/module_pathfinder.dm index f0a92e3a05153..487844bc2a04f 100644 --- a/code/modules/mod/modules/module_pathfinder.dm +++ b/code/modules/mod/modules/module_pathfinder.dm @@ -117,19 +117,19 @@ /obj/item/implant/mod/proc/recall() if(!module?.mod) - balloon_alert(imp_in, "no connected suit!") + balloon_alert(imp_in, "no connected unit!") return FALSE if(module.mod.open) - balloon_alert(imp_in, "suit is open!") + balloon_alert(imp_in, "cover open!") return FALSE if(module.mod.ai_controller) - balloon_alert(imp_in, "already in transit!") + balloon_alert(imp_in, "already moving!") return FALSE if(ismob(get_atom_on_turf(module.mod))) balloon_alert(imp_in, "already on someone!") return FALSE if(module.z != z || get_dist(imp_in, module.mod) > MOD_AI_RANGE) - balloon_alert(imp_in, "too far away!") + balloon_alert(imp_in, "too far!") return FALSE var/datum/ai_controller/mod_ai = new /datum/ai_controller/mod(module.mod) module.mod.ai_controller = mod_ai diff --git a/code/modules/mod/modules/modules_antag.dm b/code/modules/mod/modules/modules_antag.dm index 0401dbfdbe969..ec550f3cfde3a 100644 --- a/code/modules/mod/modules/modules_antag.dm +++ b/code/modules/mod/modules/modules_antag.dm @@ -52,9 +52,10 @@ playsound(src, 'sound/vehicles/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) balloon_alert(mod.wearer, "armor boosted, EVA lost") actual_speed_added = max(0, min(mod.slowdown_active, speed_added)) - var/obj/item/clothing/head_cover = mod.get_part_from_slot(ITEM_SLOT_HEAD) || mod.get_part_from_slot(ITEM_SLOT_MASK) || mod.get_part_from_slot(ITEM_SLOT_EYES) - if(istype(head_cover)) - ADD_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, MOD_TRAIT) + var/datum/mod_part/head_cover = mod.get_part_datum_from_slot(ITEM_SLOT_HEAD) || mod.get_part_datum_from_slot(ITEM_SLOT_MASK) || mod.get_part_datum_from_slot(ITEM_SLOT_EYES) + if(head_cover) + RegisterSignal(mod, COMSIG_MOD_PART_SEALED, PROC_REF(seal_helmet)) + seal_helmet(mod, head_cover) var/list/mod_parts = mod.get_parts(all = TRUE) for(var/obj/item/part as anything in mod.get_parts(all = TRUE)) part.set_armor(part.get_armor().add_other_armor(armor_mod)) @@ -71,9 +72,10 @@ if(!deleting) playsound(src, 'sound/vehicles/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) balloon_alert(mod.wearer, "armor retracts, EVA ready") - var/obj/item/clothing/head_cover = mod.get_part_from_slot(ITEM_SLOT_HEAD) || mod.get_part_from_slot(ITEM_SLOT_MASK) || mod.get_part_from_slot(ITEM_SLOT_EYES) - if(istype(head_cover)) - REMOVE_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, MOD_TRAIT) + var/datum/mod_part/head_cover = mod.get_part_datum_from_slot(ITEM_SLOT_HEAD) || mod.get_part_datum_from_slot(ITEM_SLOT_MASK) || mod.get_part_datum_from_slot(ITEM_SLOT_EYES) + if(head_cover) + UnregisterSignal(mod, COMSIG_MOD_PART_SEALED) + REMOVE_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, REF(src)) var/list/mod_parts = mod.get_parts(all = TRUE) for(var/obj/item/part as anything in mod.get_parts(all = TRUE)) part.set_armor(part.get_armor().subtract_other_armor(armor_mod)) @@ -91,6 +93,15 @@ overlay_state_active = "[initial(overlay_state_active)]-[mod.skin]" return ..() +/obj/item/mod/module/armor_booster/proc/seal_helmet(datum/source, datum/mod_part/part) + var/datum/mod_part/head_cover = mod.get_part_datum_from_slot(ITEM_SLOT_HEAD) || mod.get_part_datum_from_slot(ITEM_SLOT_MASK) || mod.get_part_datum_from_slot(ITEM_SLOT_EYES) + if(part != head_cover) + return + if(part.sealed) + ADD_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, REF(src)) + else + REMOVE_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, REF(src)) + ///Energy Shield - Gives you a rechargeable energy shield that nullifies attacks. /obj/item/mod/module/energy_shield name = "MOD energy shield module" @@ -184,10 +195,10 @@ required_slots = list(ITEM_SLOT_BACK) /obj/item/mod/module/anti_magic/on_part_activation() - mod.wearer.add_traits(list(TRAIT_ANTIMAGIC, TRAIT_HOLY), MOD_TRAIT) + mod.wearer.add_traits(list(TRAIT_ANTIMAGIC, TRAIT_HOLY), REF(src)) /obj/item/mod/module/anti_magic/on_part_deactivation(deleting = FALSE) - mod.wearer.remove_traits(list(TRAIT_ANTIMAGIC, TRAIT_HOLY), MOD_TRAIT) + mod.wearer.remove_traits(list(TRAIT_ANTIMAGIC, TRAIT_HOLY), REF(src)) /obj/item/mod/module/anti_magic/wizard name = "MOD magic neutralizer module" @@ -199,10 +210,10 @@ required_slots = list() /obj/item/mod/module/anti_magic/wizard/on_part_activation() - mod.wearer.add_traits(list(TRAIT_ANTIMAGIC, TRAIT_ANTIMAGIC_NO_SELFBLOCK), MOD_TRAIT) + mod.wearer.add_traits(list(TRAIT_ANTIMAGIC, TRAIT_ANTIMAGIC_NO_SELFBLOCK), REF(src)) /obj/item/mod/module/anti_magic/wizard/on_part_deactivation(deleting = FALSE) - mod.wearer.remove_traits(list(TRAIT_ANTIMAGIC, TRAIT_ANTIMAGIC_NO_SELFBLOCK), MOD_TRAIT) + mod.wearer.remove_traits(list(TRAIT_ANTIMAGIC, TRAIT_ANTIMAGIC_NO_SELFBLOCK), REF(src)) ///Insignia - Gives you a skin specific stripe. /obj/item/mod/module/insignia @@ -262,24 +273,20 @@ required_slots = list(ITEM_SLOT_FEET) /obj/item/mod/module/noslip/on_part_activation() - ADD_TRAIT(mod.wearer, TRAIT_NO_SLIP_WATER, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_NO_SLIP_WATER, REF(src)) /obj/item/mod/module/noslip/on_part_deactivation(deleting = FALSE) - REMOVE_TRAIT(mod.wearer, TRAIT_NO_SLIP_WATER, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_NO_SLIP_WATER, REF(src)) //Bite of 87 Springlock - Equips faster, disguised as DNA lock. /obj/item/mod/module/springlock/bite_of_87 + name = /obj/item/mod/module/dna_lock::name + desc = /obj/item/mod/module/dna_lock::desc + icon_state = /obj/item/mod/module/dna_lock::icon_state + complexity = /obj/item/mod/module/dna_lock::complexity + use_energy_cost = /obj/item/mod/module/dna_lock::use_energy_cost step_change = 0.1 -/obj/item/mod/module/springlock/bite_of_87/Initialize(mapload) - . = ..() - var/obj/item/mod/module/dna_lock/the_dna_lock_behind_the_slaughter = /obj/item/mod/module/dna_lock - name = initial(the_dna_lock_behind_the_slaughter.name) - desc = initial(the_dna_lock_behind_the_slaughter.desc) - icon_state = initial(the_dna_lock_behind_the_slaughter.icon_state) - complexity = initial(the_dna_lock_behind_the_slaughter.complexity) - use_energy_cost = initial(the_dna_lock_behind_the_slaughter.use_energy_cost) - /obj/item/mod/module/springlock/bite_of_87/on_part_activation() ..() if(check_holidays(APRIL_FOOLS) || prob(1)) @@ -404,7 +411,7 @@ /obj/item/mod/module/chameleon/used() if(mod.active || mod.activating) - balloon_alert(mod.wearer, "suit active!") + balloon_alert(mod.wearer, "unit active!") return FALSE return ..() @@ -514,7 +521,7 @@ mod.item_flags &= ~EXAMINE_SKIP /obj/item/mod/module/infiltrator/on_part_activation() - mod.wearer.add_traits(traits_to_add, MOD_TRAIT) + mod.wearer.add_traits(traits_to_add, REF(src)) RegisterSignal(mod.wearer, COMSIG_TRY_MODIFY_SPEECH, PROC_REF(on_speech_modification)) var/obj/item/organ/tongue/user_tongue = mod.wearer.get_organ_slot(ORGAN_SLOT_TONGUE) user_tongue.temp_say_mod = "states" @@ -523,7 +530,7 @@ head_cover.flash_protect = FLASH_PROTECTION_WELDER_HYPER_SENSITIVE /obj/item/mod/module/infiltrator/on_part_deactivation(deleting = FALSE) - mod.wearer.remove_traits(traits_to_add, MOD_TRAIT) + mod.wearer.remove_traits(traits_to_add, REF(src)) UnregisterSignal(mod.wearer, COMSIG_TRY_MODIFY_SPEECH) var/obj/item/organ/tongue/user_tongue = mod.wearer.get_organ_slot(ORGAN_SLOT_TONGUE) user_tongue.temp_say_mod = initial(user_tongue.temp_say_mod) @@ -573,7 +580,7 @@ balloon_alert(mod.wearer, "can't reach that!") return if(istype(target, /obj/machinery/power/apc)) //Bit too strong for a module so this is blacklisted - balloon_alert(mod.wearer, "cant disable apc!") + balloon_alert(mod.wearer, "can't disable apc!") return var/list/things_to_disrupt = list(target) diff --git a/code/modules/mod/modules/modules_engineering.dm b/code/modules/mod/modules/modules_engineering.dm index aea9a415cf4e4..9c96d9edd82b9 100644 --- a/code/modules/mod/modules/modules_engineering.dm +++ b/code/modules/mod/modules/modules_engineering.dm @@ -62,12 +62,12 @@ var/list/active_traits = list(TRAIT_NO_SLIP_WATER, TRAIT_NO_SLIP_ICE, TRAIT_NO_SLIP_SLIDE, TRAIT_NEGATES_GRAVITY) /obj/item/mod/module/magboot/on_activation() - mod.wearer.add_traits(active_traits, MOD_TRAIT) + mod.wearer.add_traits(active_traits, REF(src)) mod.slowdown += slowdown_active mod.wearer.update_equipment_speed_mods() /obj/item/mod/module/magboot/on_deactivation(display_message = TRUE, deleting = FALSE) - mod.wearer.remove_traits(active_traits, MOD_TRAIT) + mod.wearer.remove_traits(active_traits, REF(src)) mod.slowdown -= slowdown_active mod.wearer.update_equipment_speed_mods() @@ -104,7 +104,7 @@ /obj/item/mod/module/tether/get_configuration() . = ..() - .["cut_tethers"] = add_ui_configuration("Cut Tethers", "pin", TRUE) + .["cut_tethers"] = add_ui_configuration("Cut Tethers", "button", "scissors") /obj/item/mod/module/tether/configure_edit(key, value) if (key != "cut_tethers") @@ -267,14 +267,14 @@ /obj/item/mod/module/rad_protection/on_part_activation() AddComponent(/datum/component/geiger_sound) - ADD_TRAIT(mod.wearer, TRAIT_BYPASS_EARLY_IRRADIATED_CHECK, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_BYPASS_EARLY_IRRADIATED_CHECK, REF(src)) RegisterSignal(mod.wearer, COMSIG_IN_RANGE_OF_IRRADIATION, PROC_REF(on_pre_potential_irradiation)) for(var/obj/item/part in mod.get_parts(all = TRUE)) ADD_TRAIT(part, TRAIT_RADIATION_PROTECTED_CLOTHING, MOD_TRAIT) /obj/item/mod/module/rad_protection/on_part_deactivation(deleting = FALSE) qdel(GetComponent(/datum/component/geiger_sound)) - REMOVE_TRAIT(mod.wearer, TRAIT_BYPASS_EARLY_IRRADIATED_CHECK, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_BYPASS_EARLY_IRRADIATED_CHECK, REF(src)) UnregisterSignal(mod.wearer, COMSIG_IN_RANGE_OF_IRRADIATION) for(var/obj/item/part in mod.get_parts(all = TRUE)) REMOVE_TRAIT(part, TRAIT_RADIATION_PROTECTED_CLOTHING, MOD_TRAIT) @@ -309,10 +309,10 @@ required_slots = list(ITEM_SLOT_GLOVES) /obj/item/mod/module/constructor/on_part_activation() - ADD_TRAIT(mod.wearer, TRAIT_QUICK_BUILD, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_QUICK_BUILD, REF(src)) /obj/item/mod/module/constructor/on_part_deactivation(deleting = FALSE) - REMOVE_TRAIT(mod.wearer, TRAIT_QUICK_BUILD, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_QUICK_BUILD, REF(src)) /obj/item/mod/module/constructor/on_use() rcd_scan(src, fade_time = 10 SECONDS) @@ -332,10 +332,10 @@ required_slots = list(ITEM_SLOT_HEAD) /obj/item/mod/module/headprotector/on_part_activation() - ADD_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, REF(src)) /obj/item/mod/module/headprotector/on_part_deactivation(deleting = FALSE) - REMOVE_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, REF(src)) ///Mister - Sprays water over an area. /obj/item/mod/module/mister diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index 42e4c56f55ec1..dc273965e8188 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -148,9 +148,9 @@ if (!isnull(mod) && !isnull(mod.wearer) && mod.wearer.get_item_by_slot(slot_flags) == src) if (!stabilize) - ADD_TRAIT(mod.wearer, TRAIT_NOGRAV_ALWAYS_DRIFT, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_NOGRAV_ALWAYS_DRIFT, REF(src)) else - REMOVE_TRAIT(mod.wearer, TRAIT_NOGRAV_ALWAYS_DRIFT, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_NOGRAV_ALWAYS_DRIFT, REF(src)) /obj/item/mod/module/jetpack/get_configuration() . = ..() @@ -171,11 +171,11 @@ /obj/item/mod/module/jetpack/on_activation() mod.wearer.add_movespeed_modifier(/datum/movespeed_modifier/jetpack/full_speed) if (!stabilize) - ADD_TRAIT(mod.wearer, TRAIT_NOGRAV_ALWAYS_DRIFT, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_NOGRAV_ALWAYS_DRIFT, REF(src)) /obj/item/mod/module/jetpack/on_deactivation(display_message = TRUE, deleting = FALSE) mod.wearer.remove_movespeed_modifier(/datum/movespeed_modifier/jetpack/full_speed) - REMOVE_TRAIT(mod.wearer, TRAIT_NOGRAV_ALWAYS_DRIFT, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_NOGRAV_ALWAYS_DRIFT, REF(src)) /obj/item/mod/module/jetpack/advanced name = "MOD advanced ion jetpack module" @@ -672,10 +672,10 @@ return ..() /obj/item/mod/module/plasma_stabilizer/on_equip() - ADD_TRAIT(mod.wearer, TRAIT_HEAD_ATMOS_SEALED, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_HEAD_ATMOS_SEALED, REF(src)) /obj/item/mod/module/plasma_stabilizer/on_unequip() - REMOVE_TRAIT(mod.wearer, TRAIT_HEAD_ATMOS_SEALED, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_HEAD_ATMOS_SEALED, REF(src)) //Finally, https://pipe.miroware.io/5b52ba1d94357d5d623f74aa/mspfa/Nuke%20Ops/Panels/0648.gif can be real: @@ -731,10 +731,10 @@ required_slots = list(ITEM_SLOT_GLOVES) /obj/item/mod/module/signlang_radio/on_part_activation() - ADD_TRAIT(mod.wearer, TRAIT_CAN_SIGN_ON_COMMS, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_CAN_SIGN_ON_COMMS, REF(src)) /obj/item/mod/module/signlang_radio/on_part_deactivation(deleting = FALSE) - REMOVE_TRAIT(mod.wearer, TRAIT_CAN_SIGN_ON_COMMS, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_CAN_SIGN_ON_COMMS, REF(src)) ///A module that recharges the suit by an itsy tiny bit whenever the user takes a step. Originally called "magneto module" but the videogame reference sounds cooler. /obj/item/mod/module/joint_torsion @@ -952,7 +952,7 @@ if(!istype(tool, /obj/item/fishing_rod)) return ..() if(equipped) - balloon_alert(user, "remove current rod first!") + balloon_alert(user, "already has rod!") if(!user.transferItemToLoc(tool, src)) user.balloon_alert(user, "it's stuck!") equipped = tool diff --git a/code/modules/mod/modules/modules_maint.dm b/code/modules/mod/modules/modules_maint.dm index f6b978d05352f..cd5a575302d9f 100644 --- a/code/modules/mod/modules/modules_maint.dm +++ b/code/modules/mod/modules/modules_maint.dm @@ -295,8 +295,8 @@ mod.wearer.AddElement(/datum/element/forced_gravity, NEGATIVE_GRAVITY) RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, PROC_REF(check_upstairs)) RegisterSignal(mod.wearer, COMSIG_MOB_SAY, PROC_REF(on_talk)) - ADD_TRAIT(mod.wearer, TRAIT_SILENT_FOOTSTEPS, MOD_TRAIT) - passtable_on(mod.wearer, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_SILENT_FOOTSTEPS, REF(src)) + passtable_on(mod.wearer, REF(src)) check_upstairs() //todo at some point flip your screen around /obj/item/mod/module/atrocinator/deactivate(display_message = TRUE, deleting = FALSE) @@ -312,8 +312,8 @@ UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED) UnregisterSignal(mod.wearer, COMSIG_MOB_SAY) step_count = 0 - REMOVE_TRAIT(mod.wearer, TRAIT_SILENT_FOOTSTEPS, MOD_TRAIT) - passtable_off(mod.wearer, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_SILENT_FOOTSTEPS, REF(src)) + passtable_off(mod.wearer, REF(src)) var/turf/open/openspace/current_turf = get_turf(mod.wearer) if(istype(current_turf)) current_turf.zFall(mod.wearer, falling_from_move = TRUE) diff --git a/code/modules/mod/modules/modules_medical.dm b/code/modules/mod/modules/modules_medical.dm index 154717cbcc11c..7c0e1c85b0536 100644 --- a/code/modules/mod/modules/modules_medical.dm +++ b/code/modules/mod/modules/modules_medical.dm @@ -77,13 +77,13 @@ /obj/item/mod/module/quick_carry/on_part_activation() . = ..() - ADD_TRAIT(mod.wearer, TRAIT_FASTMED, MOD_TRAIT) - ADD_TRAIT(mod.wearer, quick_carry_trait, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_FASTMED, REF(src)) + ADD_TRAIT(mod.wearer, quick_carry_trait, REF(src)) /obj/item/mod/module/quick_carry/on_part_deactivation(deleting = FALSE) . = ..() - REMOVE_TRAIT(mod.wearer, TRAIT_FASTMED, MOD_TRAIT) - REMOVE_TRAIT(mod.wearer, quick_carry_trait, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_FASTMED, REF(src)) + REMOVE_TRAIT(mod.wearer, quick_carry_trait, REF(src)) /obj/item/mod/module/quick_carry/advanced name = "MOD advanced quick carry module" diff --git a/code/modules/mod/modules/modules_ninja.dm b/code/modules/mod/modules/modules_ninja.dm index c4e8962c4476d..a6ade06a9098c 100644 --- a/code/modules/mod/modules/modules_ninja.dm +++ b/code/modules/mod/modules/modules_ninja.dm @@ -73,11 +73,11 @@ /obj/item/mod/module/stealth/ninja/on_activation() . = ..() - ADD_TRAIT(mod.wearer, TRAIT_SILENT_FOOTSTEPS, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_SILENT_FOOTSTEPS, REF(src)) /obj/item/mod/module/stealth/ninja/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() - REMOVE_TRAIT(mod.wearer, TRAIT_SILENT_FOOTSTEPS, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_SILENT_FOOTSTEPS, REF(src)) ///Camera Vision - Prevents flashes, blocks tracking. /obj/item/mod/module/welding/camera_vision @@ -173,16 +173,16 @@ var/accepted_type = /obj/item/energy_katana /obj/item/mod/module/weapon_recall/on_part_activation() - mod.wearer.add_traits(list(TRAIT_NOGUNS, TRAIT_TOSS_GUN_HARD), MOD_TRAIT) + mod.wearer.add_traits(list(TRAIT_NOGUNS, TRAIT_TOSS_GUN_HARD), REF(src)) /obj/item/mod/module/weapon_recall/on_part_deactivation(deleting = FALSE) - mod.wearer.remove_traits(list(TRAIT_NOGUNS, TRAIT_TOSS_GUN_HARD), MOD_TRAIT) + mod.wearer.remove_traits(list(TRAIT_NOGUNS, TRAIT_TOSS_GUN_HARD), REF(src)) /obj/item/mod/module/weapon_recall/on_use() if(!linked_weapon) var/obj/item/weapon_to_link = mod.wearer.is_holding_item_of_type(accepted_type) if(!weapon_to_link) - balloon_alert(mod.wearer, "can't locate weapon!") + balloon_alert(mod.wearer, "no linked weapon!") return set_weapon(weapon_to_link) balloon_alert(mod.wearer, "[linked_weapon.name] linked") @@ -191,7 +191,7 @@ balloon_alert(mod.wearer, "already on self!") return var/distance = get_dist(mod.wearer, linked_weapon) - var/in_view = (linked_weapon in view(mod.wearer)) + var/in_view = (linked_weapon in view(mod.wearer)) && !(linked_weapon in get_turf(mod.wearer)) if(!in_view && !drain_power(use_energy_cost * distance)) balloon_alert(mod.wearer, "not enough charge!") return diff --git a/code/modules/mod/modules/modules_science.dm b/code/modules/mod/modules/modules_science.dm index 409b442336636..1d15abece56d0 100644 --- a/code/modules/mod/modules/modules_science.dm +++ b/code/modules/mod/modules/modules_science.dm @@ -14,10 +14,10 @@ required_slots = list(ITEM_SLOT_HEAD|ITEM_SLOT_EYES|ITEM_SLOT_MASK) /obj/item/mod/module/reagent_scanner/on_activation() - ADD_TRAIT(mod.wearer, TRAIT_REAGENT_SCANNER, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_REAGENT_SCANNER, REF(src)) /obj/item/mod/module/reagent_scanner/on_deactivation(display_message = TRUE, deleting = FALSE) - REMOVE_TRAIT(mod.wearer, TRAIT_REAGENT_SCANNER, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_REAGENT_SCANNER, REF(src)) /obj/item/mod/module/reagent_scanner/advanced name = "MOD advanced reagent scanner module" @@ -31,12 +31,12 @@ /obj/item/mod/module/reagent_scanner/advanced/on_activation() . = ..() - ADD_TRAIT(mod.wearer, TRAIT_RESEARCH_SCANNER, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_RESEARCH_SCANNER, REF(src)) RegisterSignal(SSdcs, COMSIG_GLOB_EXPLOSION, PROC_REF(sense_explosion)) /obj/item/mod/module/reagent_scanner/advanced/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() - REMOVE_TRAIT(mod.wearer, TRAIT_RESEARCH_SCANNER, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_RESEARCH_SCANNER, REF(src)) UnregisterSignal(SSdcs, COMSIG_GLOB_EXPLOSION) /obj/item/mod/module/reagent_scanner/advanced/proc/sense_explosion(datum/source, turf/epicenter, diff --git a/code/modules/mod/modules/modules_security.dm b/code/modules/mod/modules/modules_security.dm index c25dd75275574..0903231830486 100644 --- a/code/modules/mod/modules/modules_security.dm +++ b/code/modules/mod/modules/modules_security.dm @@ -123,7 +123,7 @@ balloon_alert(mod.wearer, "nothing to holster!") return if(!istype(holding) || holding.w_class > WEIGHT_CLASS_BULKY) - balloon_alert(mod.wearer, "it doesn't fit!") + balloon_alert(mod.wearer, "doesn't fit!") return if(mod.wearer.transferItemToLoc(holding, src, force = FALSE, silent = TRUE)) holstered = holding @@ -522,11 +522,11 @@ idle_power_cost = 0 if(STORMTROOPER_MODE) idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.4 - mod.wearer.add_traits(list(TRAIT_NO_GUN_AKIMBO, TRAIT_DOUBLE_TAP), MOD_TRAIT) + mod.wearer.add_traits(list(TRAIT_NO_GUN_AKIMBO, TRAIT_DOUBLE_TAP), REF(src)) RegisterSignal(mod.wearer, COMSIG_MOB_FIRED_GUN, PROC_REF(stormtrooper_fired_gun)) if(SHARPSHOOTER_MODE) idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.6 - mod.wearer.add_traits(list(TRAIT_NO_GUN_AKIMBO, TRAIT_NICE_SHOT), MOD_TRAIT) + mod.wearer.add_traits(list(TRAIT_NO_GUN_AKIMBO, TRAIT_NICE_SHOT), REF(src)) RegisterSignal(mod.wearer, COMSIG_MOB_FIRED_GUN, PROC_REF(sharpshooter_fired_gun)) RegisterSignal(mod.wearer, COMSIG_PROJECTILE_FIRER_BEFORE_FIRE, PROC_REF(apply_ricochet)) mod.wearer.add_movespeed_modifier(/datum/movespeed_modifier/shooting_assistant) @@ -535,10 +535,10 @@ switch(selected_mode) if(STORMTROOPER_MODE) UnregisterSignal(mod.wearer, COMSIG_MOB_FIRED_GUN) - mod.wearer.remove_traits(list(TRAIT_NO_GUN_AKIMBO, TRAIT_DOUBLE_TAP), MOD_TRAIT) + mod.wearer.remove_traits(list(TRAIT_NO_GUN_AKIMBO, TRAIT_DOUBLE_TAP), REF(src)) if(SHARPSHOOTER_MODE) UnregisterSignal(mod.wearer, list(COMSIG_MOB_FIRED_GUN, COMSIG_PROJECTILE_FIRER_BEFORE_FIRE)) - mod.wearer.remove_traits(list(TRAIT_NO_GUN_AKIMBO, TRAIT_NICE_SHOT), MOD_TRAIT) + mod.wearer.remove_traits(list(TRAIT_NO_GUN_AKIMBO, TRAIT_NICE_SHOT), REF(src)) mod.wearer.remove_movespeed_modifier(/datum/movespeed_modifier/shooting_assistant) /obj/item/mod/module/shooting_assistant/drain_power(amount) @@ -582,10 +582,10 @@ required_slots = list(ITEM_SLOT_OCLOTHING) /obj/item/mod/module/shove_blocker/on_part_activation() - mod.wearer.add_traits(list(TRAIT_BRAWLING_KNOCKDOWN_BLOCKED, TRAIT_NO_STAGGER, TRAIT_NO_THROW_HITPUSH), MOD_TRAIT) + mod.wearer.add_traits(list(TRAIT_BRAWLING_KNOCKDOWN_BLOCKED, TRAIT_NO_STAGGER, TRAIT_NO_THROW_HITPUSH), REF(src)) /obj/item/mod/module/shove_blocker/on_part_deactivation(deleting = FALSE) - mod.wearer.remove_traits(list(TRAIT_BRAWLING_KNOCKDOWN_BLOCKED, TRAIT_NO_STAGGER, TRAIT_NO_THROW_HITPUSH), MOD_TRAIT) + mod.wearer.remove_traits(list(TRAIT_BRAWLING_KNOCKDOWN_BLOCKED, TRAIT_NO_STAGGER, TRAIT_NO_THROW_HITPUSH), REF(src)) /obj/item/mod/module/shove_blocker/locked name = "superglued MOD bulwark module" @@ -602,8 +602,8 @@ /obj/item/mod/module/quick_cuff/on_part_activation() . = ..() - ADD_TRAIT(mod.wearer, TRAIT_FAST_CUFFING, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_FAST_CUFFING, REF(src)) /obj/item/mod/module/quick_cuff/on_part_deactivation(deleting = FALSE) . = ..() - REMOVE_TRAIT(mod.wearer, TRAIT_FAST_CUFFING, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_FAST_CUFFING, REF(src)) diff --git a/code/modules/mod/modules/modules_service.dm b/code/modules/mod/modules/modules_service.dm index 79d2d3779e0ff..70c11f069f090 100644 --- a/code/modules/mod/modules/modules_service.dm +++ b/code/modules/mod/modules/modules_service.dm @@ -46,7 +46,7 @@ if(!isitem(target)) return if(!isturf(target.loc)) - balloon_alert(mod.wearer, "must be on the floor!") + balloon_alert(mod.wearer, "not in storage!") return var/obj/item/microwave_target = target var/datum/effect_system/spark_spread/spark_effect = new() @@ -80,7 +80,7 @@ var/obj/item/shoes = mod.get_part_from_slot(ITEM_SLOT_FEET) if(shoes) shoes.AddComponent(/datum/component/squeak, list('sound/effects/footstep/clownstep1.ogg'=1,'sound/effects/footstep/clownstep2.ogg'=1), 50, falloff_exponent = 20) //die off quick please - mod.wearer.AddElementTrait(TRAIT_WADDLING, MOD_TRAIT, /datum/element/waddling) + mod.wearer.AddElementTrait(TRAIT_WADDLING, REF(src), /datum/element/waddling) if(is_clown_job(mod.wearer.mind?.assigned_role)) mod.wearer.add_mood_event("clownshoes", /datum/mood_event/clownshoes) @@ -88,6 +88,6 @@ var/obj/item/shoes = mod.get_part_from_slot(ITEM_SLOT_FEET) if(shoes && !deleting) qdel(shoes.GetComponent(/datum/component/squeak)) - REMOVE_TRAIT(mod.wearer, TRAIT_WADDLING, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_WADDLING, REF(src)) if(is_clown_job(mod.wearer.mind?.assigned_role)) mod.wearer.clear_mood_event("clownshoes") diff --git a/code/modules/mod/modules/modules_supply.dm b/code/modules/mod/modules/modules_supply.dm index 8be66e0b3e38c..bc34cf8781ec4 100644 --- a/code/modules/mod/modules/modules_supply.dm +++ b/code/modules/mod/modules/modules_supply.dm @@ -61,7 +61,7 @@ return stored_crates += picked_crate picked_crate.forceMove(src) - balloon_alert(mod.wearer, "picked up [picked_crate]") + balloon_alert(mod.wearer, "picked up crate") drain_power(use_energy_cost) else if(length(stored_crates)) var/turf/target_turf = get_turf(target) @@ -407,11 +407,11 @@ )) /obj/item/mod/module/ash_accretion/on_part_activation() - mod.wearer.add_traits(list(TRAIT_ASHSTORM_IMMUNE, TRAIT_SNOWSTORM_IMMUNE), MOD_TRAIT) + mod.wearer.add_traits(list(TRAIT_ASHSTORM_IMMUNE, TRAIT_SNOWSTORM_IMMUNE), REF(src)) RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) /obj/item/mod/module/ash_accretion/on_part_deactivation(deleting = FALSE) - mod.wearer.remove_traits(list(TRAIT_ASHSTORM_IMMUNE, TRAIT_SNOWSTORM_IMMUNE), MOD_TRAIT) + mod.wearer.remove_traits(list(TRAIT_ASHSTORM_IMMUNE, TRAIT_SNOWSTORM_IMMUNE), REF(src)) UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED) if(!traveled_tiles) return @@ -496,10 +496,10 @@ mod.wearer.base_pixel_y -= 4 animate(mod.wearer, animate_time, pixel_y = mod.wearer.base_pixel_y, flags = ANIMATION_PARALLEL) mod.wearer.SpinAnimation(1.5) - mod.wearer.add_traits(user_traits, MOD_TRAIT) + mod.wearer.add_traits(user_traits, REF(src)) mod.wearer.RemoveElement(/datum/element/footstep, FOOTSTEP_MOB_HUMAN, 1, -6) mod.wearer.AddElement(/datum/element/footstep, FOOTSTEP_OBJ_ROBOT, 1, -6, sound_vary = TRUE) - mod.wearer.add_movespeed_mod_immunities(MOD_TRAIT, /datum/movespeed_modifier/damage_slowdown) + mod.wearer.add_movespeed_mod_immunities(REF(src), /datum/movespeed_modifier/damage_slowdown) mod.wearer.add_movespeed_modifier(/datum/movespeed_modifier/sphere) RegisterSignal(mod.wearer, COMSIG_MOB_STATCHANGE, PROC_REF(on_statchange)) @@ -509,8 +509,8 @@ mod.wearer.base_pixel_y += 4 animate(mod.wearer, animate_time, pixel_y = mod.wearer.base_pixel_y) addtimer(CALLBACK(mod.wearer, TYPE_PROC_REF(/datum, remove_filter), list("mod_ball", "mod_blur", "mod_outline")), animate_time) - mod.wearer.remove_traits(user_traits, MOD_TRAIT) - mod.wearer.remove_movespeed_mod_immunities(MOD_TRAIT, /datum/movespeed_modifier/damage_slowdown) + mod.wearer.remove_traits(user_traits, REF(src)) + mod.wearer.remove_movespeed_mod_immunities(REF(src), /datum/movespeed_modifier/damage_slowdown) mod.wearer.RemoveElement(/datum/element/footstep, FOOTSTEP_OBJ_ROBOT, 1, -6, sound_vary = TRUE) mod.wearer.AddElement(/datum/element/footstep, FOOTSTEP_MOB_HUMAN, 1, -6) mod.wearer.remove_movespeed_modifier(/datum/movespeed_modifier/sphere) diff --git a/code/modules/mod/modules/modules_timeline.dm b/code/modules/mod/modules/modules_timeline.dm index c14825bf3c70d..bfb22da0c20da 100644 --- a/code/modules/mod/modules/modules_timeline.dm +++ b/code/modules/mod/modules/modules_timeline.dm @@ -133,13 +133,13 @@ ///Signal fired when wearer attempts to trigger modules, if attempting while time is stopped /obj/item/mod/module/timestopper/proc/on_module_triggered(datum/source) SIGNAL_HANDLER - balloon_alert(mod.wearer, "not while channelling timestop!") + balloon_alert(mod.wearer, "not while stopping time!") return MOD_ABORT_USE ///Signal fired when wearer attempts to activate/deactivate suits, if attempting while time is stopped /obj/item/mod/module/timestopper/proc/on_activate_block(datum/source, user) SIGNAL_HANDLER - balloon_alert(user, "not while channelling timestop!") + balloon_alert(user, "not while stopping time!") return MOD_CANCEL_ACTIVATE ///Timeline Jumper - Infinite phasing. needs some special effects diff --git a/code/modules/mod/modules/modules_visor.dm b/code/modules/mod/modules/modules_visor.dm index d4b6154f88620..64ddc69d2edbf 100644 --- a/code/modules/mod/modules/modules_visor.dm +++ b/code/modules/mod/modules/modules_visor.dm @@ -14,12 +14,12 @@ /obj/item/mod/module/visor/on_activation() if(length(visor_traits)) - mod.wearer.add_traits(visor_traits, MOD_TRAIT) + mod.wearer.add_traits(visor_traits, REF(src)) mod.wearer.update_sight() /obj/item/mod/module/visor/on_deactivation(display_message = TRUE, deleting = FALSE) if(length(visor_traits)) - mod.wearer.remove_traits(visor_traits, MOD_TRAIT) + mod.wearer.remove_traits(visor_traits, REF(src)) mod.wearer.update_sight() //Medical Visor - Gives you a medical HUD. diff --git a/tgui/packages/tgui/interfaces/MODsuit.tsx b/tgui/packages/tgui/interfaces/MODsuit.tsx index 11d1e294824aa..966b534ead560 100644 --- a/tgui/packages/tgui/interfaces/MODsuit.tsx +++ b/tgui/packages/tgui/interfaces/MODsuit.tsx @@ -25,25 +25,29 @@ import { Window } from '../layouts'; type MODsuitData = { // Static ui_theme: string; - control: string; complexity_max: number; - parts: PartData[]; // Dynamic suit_status: SuitStatus; user_status: UserStatus; module_custom_status: ModuleCustomStatus; module_info: Module[]; + control: string; + parts: PartData[]; }; type PartData = { slot: string; name: string; + deployed: BooleanLike; + ref: string; }; type SuitStatus = { core_name: string; - cell_charge_current: number; - cell_charge_max: number; + charge_current: number; + charge_max: number; + chargebar_color: string; + chargebar_string: string; active: BooleanLike; open: BooleanLike; seconds_electrified: number; @@ -53,8 +57,8 @@ type SuitStatus = { complexity: number; selected_module: string; ai_name: string; - has_pai: boolean; - is_ai: boolean; + has_pai: BooleanLike; + is_ai: BooleanLike; link_id: string; link_freq: string; link_call: string; @@ -257,6 +261,20 @@ const ConfigurePinEntry = (props) => { ); }; +// fuck u smartkar configs werent meant to be used as actions 🖕🖕🖕 +// and really u couldnt be bothered to make this and instead used +// the pin entry? 🖕🖕🖕🖕🖕🖕🖕🖕🖕🖕🖕🖕🖕🖕🖕🖕🖕🖕🖕🖕 +const ConfigureButtonEntry = (props) => { + const { name, value, module_ref } = props; + const { act } = useBackend(); + return ( + ))} From 4a0c4fd318294c8c0007098800048267c38d1c98 Mon Sep 17 00:00:00 2001 From: grungussuss <96586172+Sadboysuss@users.noreply.github.com> Date: Thu, 14 Nov 2024 03:24:29 +0300 Subject: [PATCH 036/222] increases volume of shoes pickup sound (#87875) ## About The Pull Request closes https://github.com/tgstation/tgstation/issues/87538 ## Changelog :cl: grungussuss sound: shoes pickup volume is louder now /:cl: --- .../items/handling/shoes/sneakers_pickup1.ogg | Bin 8636 -> 9160 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/sound/items/handling/shoes/sneakers_pickup1.ogg b/sound/items/handling/shoes/sneakers_pickup1.ogg index 9670ec324e37261a523f16c9df7aa9aafd404e67..7d86eaa562f13bc42366b8cdd91c6df9d2fe5797 100644 GIT binary patch delta 5029 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 From 3c2b44d816cccc34e3fce5d858da09fbb0b78b45 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 00:24:39 +0000 Subject: [PATCH 037/222] Automatic changelog for PR #87868 [ci skip] --- html/changelogs/AutoChangeLog-pr-87868.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87868.yml diff --git a/html/changelogs/AutoChangeLog-pr-87868.yml b/html/changelogs/AutoChangeLog-pr-87868.yml new file mode 100644 index 0000000000000..6b008e7a6ab01 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87868.yml @@ -0,0 +1,4 @@ +author: "MTandi" +delete-after: True +changes: + - qol: "Chem dispenser UI droplets now have a shadow to not blend with the background" \ No newline at end of file From 3006b4206c4a756d1e3ff480efcfa50982127be5 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 00:24:50 +0000 Subject: [PATCH 038/222] Automatic changelog for PR #87875 [ci skip] --- html/changelogs/AutoChangeLog-pr-87875.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87875.yml diff --git a/html/changelogs/AutoChangeLog-pr-87875.yml b/html/changelogs/AutoChangeLog-pr-87875.yml new file mode 100644 index 0000000000000..125cfb45d5ff6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87875.yml @@ -0,0 +1,4 @@ +author: "grungussuss" +delete-after: True +changes: + - sound: "shoes pickup volume is louder now" \ No newline at end of file From 2f8acae66b3ddd13abf376e90458ce5d7de8cb18 Mon Sep 17 00:00:00 2001 From: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Date: Thu, 14 Nov 2024 05:55:53 +0530 Subject: [PATCH 039/222] Improves code for remote materials (#87870) ## About The Pull Request - Moves remote materials attack chain to item interaction level. Another step in moving away from `attackby()` - Fixes #40070. Though the timer subsystem maybe affected by FPS, round start trigger is always done after everything is set up which is now used by remote materials ## Changelog :cl: fix: silo connection on some machines won't time out when changing FPS settings code: improved attack chain code for silo connection /:cl: --- .../components/material/remote_materials.dm | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/code/datums/components/material/remote_materials.dm b/code/datums/components/material/remote_materials.dm index 3c919ab15d4a4..65ba94e8b021b 100644 --- a/code/datums/components/material/remote_materials.dm +++ b/code/datums/components/material/remote_materials.dm @@ -44,11 +44,9 @@ handles linking back and forth. var/connect_to_silo = FALSE if(force_connect || (mapload && is_station_level(T.z))) connect_to_silo = TRUE - if(!(mat_container_flags & MATCONTAINER_NO_INSERT)) - RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, TYPE_PROC_REF(/datum/component/remote_materials, SiloAttackBy)) if(mapload) // wait for silo to initialize during mapload - addtimer(CALLBACK(src, PROC_REF(_PrepareStorage), connect_to_silo)) + SSticker.OnRoundstart(CALLBACK(src, PROC_REF(_PrepareStorage), connect_to_silo)) else //directly register in round _PrepareStorage(connect_to_silo) @@ -66,17 +64,19 @@ handles linking back and forth. silo = GLOB.ore_silo_default if (silo) silo.ore_connected_machines += src - mat_container = silo.GetComponent(/datum/component/material_container) + mat_container = silo.materials + if(!(mat_container_flags & MATCONTAINER_NO_INSERT)) + RegisterSignal(parent, COMSIG_ATOM_ITEM_INTERACTION, PROC_REF(on_item_insert)) + if (!mat_container && allow_standalone) _MakeLocal() /datum/component/remote_materials/Destroy() - if (silo) - silo.ore_connected_machines -= src - silo.holds -= src - silo = null - UnregisterSignal(parent, COMSIG_ATOM_ATTACKBY) + if(silo) + allow_standalone = FALSE + disconnect_from(silo) mat_container = null + return ..() /datum/component/remote_materials/proc/_MakeLocal() @@ -93,13 +93,12 @@ handles linking back and forth. allowed_items = /obj/item/stack \ ) -/datum/component/remote_materials/proc/toggle_holding(force_hold = FALSE) +/// Adds/Removes this connection from the silo +/datum/component/remote_materials/proc/toggle_holding() if(isnull(silo)) return - if(force_hold) - silo.holds[src] = TRUE - else if(!silo.holds[src]) + if(!silo.holds[src]) silo.holds[src] = TRUE else silo.holds -= src @@ -122,28 +121,17 @@ handles linking back and forth. * old_silo- The silo we are trying to disconnect from */ /datum/component/remote_materials/proc/disconnect_from(obj/machinery/ore_silo/old_silo) - if (!old_silo || silo != old_silo) + if (QDELETED(old_silo) || silo != old_silo) return + + UnregisterSignal(parent, COMSIG_ATOM_ITEM_INTERACTION) silo.ore_connected_machines -= src silo = null mat_container = null - UnregisterSignal(parent, COMSIG_ATOM_ATTACKBY) + if (allow_standalone) _MakeLocal() -///Insert mats into silo -/datum/component/remote_materials/proc/SiloAttackBy(datum/source, obj/item/target, mob/living/user) - SIGNAL_HANDLER - - //Allows you to attack the machine with iron sheets for e.g. - if(!(mat_container_flags & MATCONTAINER_ANY_INTENT) && user.combat_mode) - return - - if(silo) - mat_container.user_insert(target, user, parent) - - return COMPONENT_NO_AFTERATTACK - /datum/component/remote_materials/proc/OnMultitool(datum/source, mob/user, obj/item/multitool/M) SIGNAL_HANDLER @@ -175,10 +163,24 @@ handles linking back and forth. silo.ore_connected_machines += src mat_container = new_container if(!(mat_container_flags & MATCONTAINER_NO_INSERT)) - RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, TYPE_PROC_REF(/datum/component/remote_materials, SiloAttackBy)) + RegisterSignal(parent, COMSIG_ATOM_ITEM_INTERACTION, PROC_REF(on_item_insert)) to_chat(user, span_notice("You connect [parent] to [silo] from the multitool's buffer.")) return ITEM_INTERACT_SUCCESS +///Insert mats into silo +/datum/component/remote_materials/proc/on_item_insert(datum/source, mob/living/user, obj/item/target) + SIGNAL_HANDLER + + //Allows you to attack the machine with iron sheets for e.g. + if(!(mat_container_flags & MATCONTAINER_ANY_INTENT) && user.combat_mode) + return + + if(silo) + mat_container.user_insert(target, user, parent) + + return ITEM_INTERACT_SUCCESS + + /** * Checks if the param silo is in the same level as this components parent i.e. connected machine, rcd, etc * From d534dda070823520baa90d0a625933031b621623 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 00:26:03 +0000 Subject: [PATCH 040/222] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-87726.yml | 10 ------ html/changelogs/AutoChangeLog-pr-87806.yml | 4 --- html/changelogs/AutoChangeLog-pr-87812.yml | 4 --- html/changelogs/AutoChangeLog-pr-87814.yml | 4 --- html/changelogs/AutoChangeLog-pr-87820.yml | 4 --- html/changelogs/AutoChangeLog-pr-87824.yml | 4 --- html/changelogs/AutoChangeLog-pr-87828.yml | 4 --- html/changelogs/AutoChangeLog-pr-87848.yml | 4 --- html/changelogs/AutoChangeLog-pr-87853.yml | 4 --- html/changelogs/AutoChangeLog-pr-87867.yml | 4 --- html/changelogs/AutoChangeLog-pr-87868.yml | 4 --- html/changelogs/AutoChangeLog-pr-87869.yml | 4 --- html/changelogs/AutoChangeLog-pr-87872.yml | 4 --- html/changelogs/AutoChangeLog-pr-87875.yml | 4 --- html/changelogs/AutoChangeLog-pr-87879.yml | 5 --- html/changelogs/archive/2024-11.yml | 38 ++++++++++++++++++++++ 16 files changed, 38 insertions(+), 67 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-87726.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87806.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87812.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87814.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87820.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87824.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87828.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87848.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87853.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87867.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87868.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87869.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87872.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87875.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87879.yml diff --git a/html/changelogs/AutoChangeLog-pr-87726.yml b/html/changelogs/AutoChangeLog-pr-87726.yml deleted file mode 100644 index a61ff71412770..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87726.yml +++ /dev/null @@ -1,10 +0,0 @@ -author: "Fikou" -delete-after: True -changes: - - bugfix: "a modsuit being deleted will delete its parts correctly" - - bugfix: "a modsuit needs its boots out to be moved by an AI" - - qol: "you can extend or retract a modsuits parts from the ui panel" - - qol: "modsuit cores have colorcoded charge bars in the ui panel" - - qol: "weapon recall module makes you pick up the weapon if its on your tile" - - code_imp: "tether module has its own button for cutting tethers instead of stealing it from pins" - - bugfix: "armor booster doesnt protect from head injury without the helmet on" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87806.yml b/html/changelogs/AutoChangeLog-pr-87806.yml deleted file mode 100644 index 8bcd6dd178a41..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87806.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothymtorres" -delete-after: True -changes: - - bugfix: "Fix using chairs in holodeck to create infinite metal" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87812.yml b/html/changelogs/AutoChangeLog-pr-87812.yml deleted file mode 100644 index 17d9bbfac7c50..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87812.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Fixed stingbangs using wrong sprites" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87814.yml b/html/changelogs/AutoChangeLog-pr-87814.yml deleted file mode 100644 index 23e490d2aaffd..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87814.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Fixed detective action palette being invisible" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87820.yml b/html/changelogs/AutoChangeLog-pr-87820.yml deleted file mode 100644 index fafad94cc04ff..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87820.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "xPokee, waterpig" -delete-after: True -changes: - - code_imp: "cleaned up beserk.dm" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87824.yml b/html/changelogs/AutoChangeLog-pr-87824.yml deleted file mode 100644 index 6e323bb9556e9..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87824.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SyncIt21" -delete-after: True -changes: - - bugfix: "holosign creators interact with storage items correctly" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87828.yml b/html/changelogs/AutoChangeLog-pr-87828.yml deleted file mode 100644 index 7ad2026a16b44..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87828.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Majkl-J" -delete-after: True -changes: - - qol: "mech fabricator output direction can now be changed with a drag pull" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87848.yml b/html/changelogs/AutoChangeLog-pr-87848.yml deleted file mode 100644 index 5754465ce3ea4..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87848.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Rhials" -delete-after: True -changes: - - qol: "Crayon bounties are less demanding, and require less crayons for payout." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87853.yml b/html/changelogs/AutoChangeLog-pr-87853.yml deleted file mode 100644 index 8147066ed6262..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87853.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "mc-oofert" -delete-after: True -changes: - - bugfix: "meatlovers flatbread no longer tastes raw" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87867.yml b/html/changelogs/AutoChangeLog-pr-87867.yml deleted file mode 100644 index 1f0c1f9eefdb0..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87867.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "LT3" -delete-after: True -changes: - - bugfix: "Server config will now read the map vote configuration file" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87868.yml b/html/changelogs/AutoChangeLog-pr-87868.yml deleted file mode 100644 index 6b008e7a6ab01..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87868.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "MTandi" -delete-after: True -changes: - - qol: "Chem dispenser UI droplets now have a shadow to not blend with the background" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87869.yml b/html/changelogs/AutoChangeLog-pr-87869.yml deleted file mode 100644 index 41532da000586..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87869.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Fixed ayylmao's brain examine lines" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87872.yml b/html/changelogs/AutoChangeLog-pr-87872.yml deleted file mode 100644 index b2752f40caa72..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87872.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "grungussuss" -delete-after: True -changes: - - sound: "party popper no longer makes reagent sloshing sounds" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87875.yml b/html/changelogs/AutoChangeLog-pr-87875.yml deleted file mode 100644 index 125cfb45d5ff6..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87875.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "grungussuss" -delete-after: True -changes: - - sound: "shoes pickup volume is louder now" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87879.yml b/html/changelogs/AutoChangeLog-pr-87879.yml deleted file mode 100644 index 2ddea8bbff383..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87879.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "00-Steven" -delete-after: True -changes: - - bugfix: "A bitrunner avatar spawning with the exact same name as a name currently on the records no longer updates that record to match when the hacker alias gets applied." - - qol: "Net avatar ID cards use the net avatar's name instead of being generic." \ No newline at end of file diff --git a/html/changelogs/archive/2024-11.yml b/html/changelogs/archive/2024-11.yml index 994af6753b8e6..b4f73b08b7b85 100644 --- a/html/changelogs/archive/2024-11.yml +++ b/html/changelogs/archive/2024-11.yml @@ -458,3 +458,41 @@ - bugfix: Fix missing screentips plasmaman helmets and MOD suit hat stabilizer helmets. tmyqlfpir: - bugfix: Airlock shells are properly assigned circuit cameras modules +2024-11-14: + 00-Steven: + - bugfix: A bitrunner avatar spawning with the exact same name as a name currently + on the records no longer updates that record to match when the hacker alias + gets applied. + - qol: Net avatar ID cards use the net avatar's name instead of being generic. + Fikou: + - bugfix: a modsuit being deleted will delete its parts correctly + - bugfix: a modsuit needs its boots out to be moved by an AI + - qol: you can extend or retract a modsuits parts from the ui panel + - qol: modsuit cores have colorcoded charge bars in the ui panel + - qol: weapon recall module makes you pick up the weapon if its on your tile + - code_imp: tether module has its own button for cutting tethers instead of stealing + it from pins + - bugfix: armor booster doesnt protect from head injury without the helmet on + LT3: + - bugfix: Server config will now read the map vote configuration file + MTandi: + - qol: Chem dispenser UI droplets now have a shadow to not blend with the background + Majkl-J: + - qol: mech fabricator output direction can now be changed with a drag pull + Rhials: + - qol: Crayon bounties are less demanding, and require less crayons for payout. + SmArtKar: + - bugfix: Fixed ayylmao's brain examine lines + - bugfix: Fixed stingbangs using wrong sprites + - bugfix: Fixed detective action palette being invisible + SyncIt21: + - bugfix: holosign creators interact with storage items correctly + grungussuss: + - sound: party popper no longer makes reagent sloshing sounds + - sound: shoes pickup volume is louder now + mc-oofert: + - bugfix: meatlovers flatbread no longer tastes raw + timothymtorres: + - bugfix: Fix using chairs in holodeck to create infinite metal + xPokee, waterpig: + - code_imp: cleaned up beserk.dm From d8b4ab129f1289465251f6526543d98386dd2071 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 00:26:14 +0000 Subject: [PATCH 041/222] Automatic changelog for PR #87870 [ci skip] --- html/changelogs/AutoChangeLog-pr-87870.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87870.yml diff --git a/html/changelogs/AutoChangeLog-pr-87870.yml b/html/changelogs/AutoChangeLog-pr-87870.yml new file mode 100644 index 0000000000000..c72aff1a0ed20 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87870.yml @@ -0,0 +1,5 @@ +author: "SyncIt21" +delete-after: True +changes: + - bugfix: "silo connection on some machines won't time out when changing FPS settings" + - code_imp: "improved attack chain code for silo connection" \ No newline at end of file From c7c48ba59a212575ddde71ce71ac27ab4a683fb0 Mon Sep 17 00:00:00 2001 From: carlarctg <53100513+carlarctg@users.noreply.github.com> Date: Wed, 13 Nov 2024 21:28:31 -0300 Subject: [PATCH 042/222] spellecheck: existence not existance (#87862) ## About The Pull Request existance doesnt exist so i changed it to existence ## Why It's Good For The Game existance dosent exist ## Changelog :cl: spellcheck: spellecheck: existence not existance /:cl: --- code/controllers/subsystem/economy.dm | 2 +- code/datums/components/shell.dm | 2 +- code/game/machinery/newscaster/newscaster_machine.dm | 2 +- code/modules/admin/verbs/admin_newscaster.dm | 2 +- code/modules/admin/verbs/adminpm.dm | 2 +- code/modules/antagonists/heretic/influences.dm | 2 +- code/modules/antagonists/heretic/magic/space_crawl.dm | 2 +- .../wizard/equipment/spellbook_entries/_entry.dm | 8 ++++---- .../wizard/equipment/spellbook_entries/defensive.dm | 2 +- .../wizard/equipment/spellbook_entries/offensive.dm | 6 +++--- .../wizard/equipment/spellbook_entries/perks.dm | 2 +- .../living/basic/space_fauna/revenant/revenant_harvest.dm | 2 +- code/modules/power/tesla/energy_ball.dm | 2 +- code/modules/spells/spell_types/jaunt/bloodcrawl.dm | 6 +++--- 14 files changed, 21 insertions(+), 21 deletions(-) diff --git a/code/controllers/subsystem/economy.dm b/code/controllers/subsystem/economy.dm index 867c99cccc62d..ae9afb831f576 100644 --- a/code/controllers/subsystem/economy.dm +++ b/code/controllers/subsystem/economy.dm @@ -30,7 +30,7 @@ SUBSYSTEM_DEF(economy) var/list/bank_accounts_by_id = list() /// A list of bank accounts indexed by their assigned job typepath. var/list/bank_accounts_by_job = list() - ///List of the departmental budget cards in existance. + ///List of the departmental budget cards in existence. var/list/dep_cards = list() /// A var that collects the total amount of credits owned in player accounts on station, reset and recounted on fire() var/station_total = 0 diff --git a/code/datums/components/shell.dm b/code/datums/components/shell.dm index bb3054aea6ae6..9c74920a8628b 100644 --- a/code/datums/components/shell.dm +++ b/code/datums/components/shell.dm @@ -376,7 +376,7 @@ return COMSIG_USB_CABLE_CONNECTED_TO_CIRCUIT /** - * Determines if a user is authorized to see the existance of this shell. Returns false if they are not + * Determines if a user is authorized to see the existence of this shell. Returns false if they are not * * Arguments: * * user - The user to check if they are authorized diff --git a/code/game/machinery/newscaster/newscaster_machine.dm b/code/game/machinery/newscaster/newscaster_machine.dm index 1e03beec6c6de..39fe7ce6cb73e 100644 --- a/code/game/machinery/newscaster/newscaster_machine.dm +++ b/code/game/machinery/newscaster/newscaster_machine.dm @@ -230,7 +230,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30) data["channelLocked"] = current_channel.locked data["channelCensored"] = current_channel.censored - //We send all the information about all messages in existance. + //We send all the information about all messages in existence. data["messages"] = message_list data["wanted"] = wanted_info diff --git a/code/modules/admin/verbs/admin_newscaster.dm b/code/modules/admin/verbs/admin_newscaster.dm index b1be5560d69d9..7cac42e0b998e 100644 --- a/code/modules/admin/verbs/admin_newscaster.dm +++ b/code/modules/admin/verbs/admin_newscaster.dm @@ -128,7 +128,7 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo data["channelLocked"] = current_channel.locked data["channelCensored"] = current_channel.censored - //We send all the information about all channels and all messages in existance. + //We send all the information about all channels and all messages in existence. data["channels"] = channel_list data["messages"] = message_list data["wanted"] = wanted_info diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 834e4741cdecf..abbcbb62ab648 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -502,7 +502,7 @@ ADMIN_VERB(cmd_admin_pm_panel, R_NONE, "Admin PM", "Show a list of clients to PM return TRUE -/// Notifies all admins about the existance of an admin pm, then logs the pm +/// Notifies all admins about the existence of an admin pm, then logs the pm /// message_target here can be either [EXTERNAL_PM_USER], indicating that this message is intended for some external chat channel /// or a /client, in which case we send in the standard form /// log_message is the raw message to send, it will be filtered and treated to ensure we do not break any text handling diff --git a/code/modules/antagonists/heretic/influences.dm b/code/modules/antagonists/heretic/influences.dm index 7b316d6cdb984..494a8d30521b9 100644 --- a/code/modules/antagonists/heretic/influences.dm +++ b/code/modules/antagonists/heretic/influences.dm @@ -114,7 +114,7 @@ their_poor_arm.dismember() qdel(their_poor_arm) else - to_chat(human_user,span_danger("You pull your hand away from the hole as the eldritch energy flails, trying to latch onto existance itself!")) + to_chat(human_user,span_danger("You pull your hand away from the hole as the eldritch energy flails, trying to latch onto existence itself!")) return TRUE /obj/effect/visible_heretic_influence/attack_tk(mob/user) diff --git a/code/modules/antagonists/heretic/magic/space_crawl.dm b/code/modules/antagonists/heretic/magic/space_crawl.dm index cce9f46085bc6..74b02c59c10e7 100644 --- a/code/modules/antagonists/heretic/magic/space_crawl.dm +++ b/code/modules/antagonists/heretic/magic/space_crawl.dm @@ -7,7 +7,7 @@ */ /datum/action/cooldown/spell/jaunt/space_crawl name = "Space Phase" - desc = "Allows you to phase in and out of existance while in space or misc tiles." + desc = "Allows you to phase in and out of existence while in space or misc tiles." background_icon_state = "bg_heretic" overlay_icon_state = "bg_heretic_border" diff --git a/code/modules/antagonists/wizard/equipment/spellbook_entries/_entry.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/_entry.dm index 18e2dae715c34..28432b1ada883 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook_entries/_entry.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook_entries/_entry.dm @@ -31,10 +31,10 @@ /// Whether the spell requires wizard garb or not var/requires_wizard_garb = FALSE /// Used so you can't have specific spells together - var/list/no_coexistance_typecache + var/list/no_coexistence_typecache /datum/spellbook_entry/New() - no_coexistance_typecache = typecacheof(no_coexistance_typecache) + no_coexistence_typecache = typecacheof(no_coexistence_typecache) if(ispath(spell_type)) if(isnull(limit)) @@ -68,13 +68,13 @@ if(!isnull(limit) && times >= limit) return FALSE for(var/spell in user.actions) - if(is_type_in_typecache(spell, no_coexistance_typecache)) + if(is_type_in_typecache(spell, no_coexistence_typecache)) return FALSE var/datum/antagonist/wizard/wizard_datum = user.mind.has_antag_datum(/datum/antagonist/wizard) if(!wizard_datum) return TRUE for(var/perks in wizard_datum.perks) - if(is_type_in_typecache(perks, no_coexistance_typecache)) + if(is_type_in_typecache(perks, no_coexistence_typecache)) return FALSE if(is_type_in_list(src, wizard_datum.perks)) to_chat(user, span_warning("This perk already learned!")) diff --git a/code/modules/antagonists/wizard/equipment/spellbook_entries/defensive.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/defensive.dm index e7c204a39e214..585385e9d2ddf 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook_entries/defensive.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook_entries/defensive.dm @@ -55,7 +55,7 @@ it will become easier for others to find your item of power." spell_type = /datum/action/cooldown/spell/lichdom category = SPELLBOOK_CATEGORY_DEFENSIVE - no_coexistance_typecache = list(/datum/action/cooldown/spell/splattercasting, /datum/spellbook_entry/perks/wormborn) + no_coexistence_typecache = list(/datum/action/cooldown/spell/splattercasting, /datum/spellbook_entry/perks/wormborn) /datum/spellbook_entry/chuunibyou name = "Chuuni Invocations" diff --git a/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm index 6b8272ed5b7ad..d65e14578ec32 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm @@ -77,7 +77,7 @@ spell_type = /datum/action/cooldown/spell/conjure_item/infinite_guns/gun category = SPELLBOOK_CATEGORY_OFFENSIVE cost = 3 - no_coexistance_typecache = list(/datum/action/cooldown/spell/conjure_item/infinite_guns/arcane_barrage) + no_coexistence_typecache = list(/datum/action/cooldown/spell/conjure_item/infinite_guns/arcane_barrage) /datum/spellbook_entry/arcane_barrage name = "Arcane Barrage" @@ -85,7 +85,7 @@ spell_type = /datum/action/cooldown/spell/conjure_item/infinite_guns/arcane_barrage category = SPELLBOOK_CATEGORY_OFFENSIVE cost = 3 - no_coexistance_typecache = list(/datum/action/cooldown/spell/conjure_item/infinite_guns/gun) + no_coexistence_typecache = list(/datum/action/cooldown/spell/conjure_item/infinite_guns/gun) /datum/spellbook_entry/barnyard name = "Barnyard Curse" @@ -99,7 +99,7 @@ draining from you over time. You can replenish it from your victims, specifically their necks." spell_type = /datum/action/cooldown/spell/splattercasting category = SPELLBOOK_CATEGORY_OFFENSIVE - no_coexistance_typecache = list(/datum/action/cooldown/spell/lichdom) + no_coexistence_typecache = list(/datum/action/cooldown/spell/lichdom) /datum/spellbook_entry/sanguine_strike name = "Exsanguinating Strike" diff --git a/code/modules/antagonists/wizard/equipment/spellbook_entries/perks.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/perks.dm index 07c152d113d68..6c4947639f6c5 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook_entries/perks.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook_entries/perks.dm @@ -60,7 +60,7 @@ desc = "Your soul is infested with mana worms. When you die, you will be reborn as a large worm. \ When the worm dies, it has no such luck. Parasitic infection prevents you from binding your soul to objects." hud_icon = "wormborn" - no_coexistance_typecache = list(/datum/action/cooldown/spell/lichdom) + no_coexistence_typecache = list(/datum/action/cooldown/spell/lichdom) /datum/spellbook_entry/perks/wormborn/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book, log_buy) . = ..() diff --git a/code/modules/mob/living/basic/space_fauna/revenant/revenant_harvest.dm b/code/modules/mob/living/basic/space_fauna/revenant/revenant_harvest.dm index c162ecf2c213e..366cb1c5065ba 100644 --- a/code/modules/mob/living/basic/space_fauna/revenant/revenant_harvest.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/revenant_harvest.dm @@ -111,7 +111,7 @@ return FALSE var/datum/beam/draining_beam = Beam(target, icon_state = "drain_life") - if(!do_after(src, 4.6 SECONDS, target, timed_action_flags = (IGNORE_HELD_ITEM | IGNORE_INCAPACITATED))) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining. + if(!do_after(src, 4.6 SECONDS, target, timed_action_flags = (IGNORE_HELD_ITEM | IGNORE_INCAPACITATED))) //As one cannot prove the existence of ghosts, ghosts cannot prove the existence of the target they were draining. to_chat(src, span_revenwarning("[target ? "[target]'s soul has" : "[target_They_have]"] been drawn out of your grasp. The link has been broken.")) if(target) target.visible_message( diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index 2e2931c835c0d..ab210fe1986fe 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -243,7 +243,7 @@ //This also means we have no need to track distance, as the doview() proc does it all for us. //Darkness fucks oview up hard. I've tried dview() but it doesn't seem to work - //I hate existance + //I hate existence for(var/atom/A as anything in typecache_filter_list(oview(zap_range+2, source), things_to_shock)) if(!(zap_flags & ZAP_ALLOW_DUPLICATES) && LAZYACCESS(shocked_targets, A)) continue diff --git a/code/modules/spells/spell_types/jaunt/bloodcrawl.dm b/code/modules/spells/spell_types/jaunt/bloodcrawl.dm index 2795efc2b201b..8c9c6809a0657 100644 --- a/code/modules/spells/spell_types/jaunt/bloodcrawl.dm +++ b/code/modules/spells/spell_types/jaunt/bloodcrawl.dm @@ -5,7 +5,7 @@ */ /datum/action/cooldown/spell/jaunt/bloodcrawl name = "Blood Crawl" - desc = "Allows you to phase in and out of existance via pools of blood." + desc = "Allows you to phase in and out of existence via pools of blood." background_icon_state = "bg_demon" overlay_icon_state = "bg_demon_border" @@ -158,7 +158,7 @@ */ /datum/action/cooldown/spell/jaunt/bloodcrawl/slaughter_demon name = "Voracious Blood Crawl" - desc = "Allows you to phase in and out of existance via pools of blood. If you are dragging someone in critical or dead, \ + desc = "Allows you to phase in and out of existence via pools of blood. If you are dragging someone in critical or dead, \ they will be consumed by you, fully healing you." /// The sound played when someone's consumed. var/consume_sound = 'sound/effects/magic/demon_consume.ogg' @@ -285,7 +285,7 @@ */ /datum/action/cooldown/spell/jaunt/bloodcrawl/slaughter_demon/funny name = "Friendly Blood Crawl" - desc = "Allows you to phase in and out of existance via pools of blood. If you are dragging someone in critical or dead - I mean, \ + desc = "Allows you to phase in and out of existence via pools of blood. If you are dragging someone in critical or dead - I mean, \ sleeping, when entering a blood pool, they will be invited to a party and fully heal you!" consume_sound = 'sound/misc/scary_horn.ogg' From 9167bdf0766cdbe75045c744bd0eebadd78b715b Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 00:28:51 +0000 Subject: [PATCH 043/222] Automatic changelog for PR #87862 [ci skip] --- html/changelogs/AutoChangeLog-pr-87862.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87862.yml diff --git a/html/changelogs/AutoChangeLog-pr-87862.yml b/html/changelogs/AutoChangeLog-pr-87862.yml new file mode 100644 index 0000000000000..68001ac6100d9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87862.yml @@ -0,0 +1,4 @@ +author: "carlarctg" +delete-after: True +changes: + - spellcheck: "spellecheck: existence not existance" \ No newline at end of file From c159d1925ae96f33dc3b809b564bca8d2ca52eec Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Thu, 14 Nov 2024 01:36:19 +0100 Subject: [PATCH 044/222] Fixes scanner gates saying both bypass and detection lines when malfunctioning (#87816) ## About The Pull Request Closes #87542 ## Changelog :cl: fix: Fixed scanner gates saying both bypass and detection lines when malfunctioning /:cl: --- code/game/machinery/scanner_gate.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/game/machinery/scanner_gate.dm b/code/game/machinery/scanner_gate.dm index 3d87e4cb60b9a..d9677e63adb25 100644 --- a/code/game/machinery/scanner_gate.dm +++ b/code/game/machinery/scanner_gate.dm @@ -202,6 +202,7 @@ var/beep = FALSE var/color = null var/detected_thing = null + var/bypassed = FALSE playsound(src, SFX_INDUSTRIAL_SCAN, 20, TRUE, -2, TRUE, FALSE) switch(scangate_mode) if(SCANGATE_NONE) @@ -251,7 +252,7 @@ if((!HAS_TRAIT(scanned_human, TRAIT_MINDSHIELD)) && (isnull(idcard) || !(ACCESS_WEAPONS in idcard.access))) // mindshield or ID card with weapons access, like bartender beep = TRUE break - say("[detected_thing] detection bypassed.") + bypassed = TRUE break else for(var/obj/item/content in thing.get_all_contents_skipping_traits(TRAIT_CONTRABAND_BLOCKER)) @@ -291,6 +292,8 @@ assembly?.activate() else SEND_SIGNAL(src, COMSIG_SCANGATE_PASS_NO_TRIGGER, thing) + if(bypassed) + say("[detected_thing] detection bypassed.") if(!ignore_signals) color = wires.get_color_of_wire(WIRE_DENY) var/obj/item/assembly/assembly = wires.get_attached(color) From a4c52f487b2ee0ec1d3621b9457d2f86821029c0 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 00:36:56 +0000 Subject: [PATCH 045/222] Automatic changelog for PR #87816 [ci skip] --- html/changelogs/AutoChangeLog-pr-87816.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87816.yml diff --git a/html/changelogs/AutoChangeLog-pr-87816.yml b/html/changelogs/AutoChangeLog-pr-87816.yml new file mode 100644 index 0000000000000..cd829eb2934bd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87816.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Fixed scanner gates saying both bypass and detection lines when malfunctioning" \ No newline at end of file From 139b366b5bc9d907d94fe333b5d2be9cf2b20699 Mon Sep 17 00:00:00 2001 From: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Date: Thu, 14 Nov 2024 02:37:29 +0200 Subject: [PATCH 046/222] [no gbp] fixes seedling ai getting stuck (#87885) ## About The Pull Request fixes seedling AI's getting stuck when trying to refill water from water tanks that have been emptied! ## Why It's Good For The Game fixes seedling ai getting stuck ## Changelog :cl: fix: fixes seedling ai getting stuck when trying to refill water from emptied water tanks /:cl: --- .../mob/living/basic/jungle/seedling/seedling_ai.dm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/basic/jungle/seedling/seedling_ai.dm b/code/modules/mob/living/basic/jungle/seedling/seedling_ai.dm index 440cfc2861b69..ee93a9c12366f 100644 --- a/code/modules/mob/living/basic/jungle/seedling/seedling_ai.dm +++ b/code/modules/mob/living/basic/jungle/seedling/seedling_ai.dm @@ -37,6 +37,7 @@ hunt_range = 7 /datum/ai_behavior/find_and_set/treatable_hydro + action_cooldown = 5 SECONDS /datum/ai_behavior/find_and_set/treatable_hydro/search_tactic(datum/ai_controller/controller, locate_path, search_range) var/list/possible_trays = list() @@ -97,6 +98,9 @@ return FALSE set_movement_target(controller, target) +/datum/ai_behavior/find_and_set/beamable_hydroplants + action_cooldown = 15 SECONDS + /datum/ai_behavior/find_and_set/beamable_hydroplants/search_tactic(datum/ai_controller/controller, locate_path, search_range) var/list/possible_trays = list() @@ -136,7 +140,8 @@ return can_see(source, water_source, radius) /datum/ai_behavior/hunt_target/interact_with_target/water_source - behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH + always_reset_target = TRUE hunt_cooldown = 5 SECONDS /datum/ai_controller/basic_controller/seedling/meanie From 6cdfe1a868c6c129efe4b569c01f2b53bad5add8 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 00:39:55 +0000 Subject: [PATCH 047/222] Automatic changelog for PR #87885 [ci skip] --- html/changelogs/AutoChangeLog-pr-87885.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87885.yml diff --git a/html/changelogs/AutoChangeLog-pr-87885.yml b/html/changelogs/AutoChangeLog-pr-87885.yml new file mode 100644 index 0000000000000..d6582ff3aabad --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87885.yml @@ -0,0 +1,4 @@ +author: "Ben10Omintrix" +delete-after: True +changes: + - bugfix: "fixes seedling ai getting stuck when trying to refill water from emptied water tanks" \ No newline at end of file From 9ba27165e511ac53c2bde8d695468cec2ad22c4f Mon Sep 17 00:00:00 2001 From: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Date: Thu, 14 Nov 2024 12:22:48 +0200 Subject: [PATCH 048/222] fixes parriable projectiles runtimes (#87899) --- code/datums/components/bullet_intercepting.dm | 2 +- code/datums/components/parry.dm | 3 +-- code/datums/components/riding/riding_mob.dm | 2 +- code/datums/elements/ranged_armour.dm | 2 +- code/datums/elements/relay_attackers.dm | 2 +- code/modules/projectiles/projectile.dm | 4 ++-- code/modules/vehicles/mecha/combat/durand.dm | 10 +++++----- 7 files changed, 12 insertions(+), 13 deletions(-) diff --git a/code/datums/components/bullet_intercepting.dm b/code/datums/components/bullet_intercepting.dm index 32e757c1823e1..f327cae954306 100644 --- a/code/datums/components/bullet_intercepting.dm +++ b/code/datums/components/bullet_intercepting.dm @@ -56,7 +56,7 @@ wearer = null /// Called when wearer is shot, check if we're going to block the hit -/datum/component/bullet_intercepting/proc/on_wearer_shot(mob/living/victim, list/signal_args, obj/projectile/bullet) +/datum/component/bullet_intercepting/proc/on_wearer_shot(mob/living/victim, obj/projectile/bullet) SIGNAL_HANDLER if (victim != wearer || victim.stat == DEAD || bullet.armor_flag != block_type) return NONE diff --git a/code/datums/components/parry.dm b/code/datums/components/parry.dm index 98bc9e3a84d07..2486796d378bb 100644 --- a/code/datums/components/parry.dm +++ b/code/datums/components/parry.dm @@ -86,10 +86,9 @@ return parriers[user] = world.time + grace_period -/datum/component/parriable_projectile/proc/before_hit(obj/projectile/source, list/bullet_args) +/datum/component/parriable_projectile/proc/before_hit(obj/projectile/source, mob/living/user) SIGNAL_HANDLER - var/mob/user = bullet_args[2] if (!istype(user) || !parriers[user] || parried) return parriers -= user diff --git a/code/datums/components/riding/riding_mob.dm b/code/datums/components/riding/riding_mob.dm index 724495b7c88c6..f5162bf918a35 100644 --- a/code/datums/components/riding/riding_mob.dm +++ b/code/datums/components/riding/riding_mob.dm @@ -541,7 +541,7 @@ RegisterSignal(parent, COMSIG_PROJECTILE_PREHIT, PROC_REF(on_bullet_hit)) RegisterSignal(parent, COMSIG_MOB_AFTER_APPLY_DAMAGE, PROC_REF(on_attacked)) -/datum/component/riding/creature/raptor/proc/on_bullet_hit(atom/target, list/bullet_args, obj/projectile/hit_projectile) +/datum/component/riding/creature/raptor/proc/on_bullet_hit(atom/target, obj/projectile/hit_projectile) SIGNAL_HANDLER if(hit_projectile.armor_flag == ENERGY) diff --git a/code/datums/elements/ranged_armour.dm b/code/datums/elements/ranged_armour.dm index 6d1322c687b1a..de5ba61d22337 100644 --- a/code/datums/elements/ranged_armour.dm +++ b/code/datums/elements/ranged_armour.dm @@ -40,7 +40,7 @@ return ..() /// Modify or ignore bullet damage based on projectile properties -/datum/element/ranged_armour/proc/pre_bullet_impact(atom/parent, list/signal_args, obj/projectile/bullet) +/datum/element/ranged_armour/proc/pre_bullet_impact(atom/parent, obj/projectile/bullet) SIGNAL_HANDLER if (bullet.damage >= minimum_projectile_force || (bullet.damage_type in vulnerable_projectile_types)) return diff --git a/code/datums/elements/relay_attackers.dm b/code/datums/elements/relay_attackers.dm index fd87cb3bc2c8e..5b7202608ec0b 100644 --- a/code/datums/elements/relay_attackers.dm +++ b/code/datums/elements/relay_attackers.dm @@ -60,7 +60,7 @@ relay_attacker(target, attacker, ATTACKER_DAMAGING_ATTACK) /// Even if another component blocked this hit, someone still shot at us -/datum/element/relay_attackers/proc/on_bullet_act(atom/target, list/bullet_args, obj/projectile/hit_projectile) +/datum/element/relay_attackers/proc/on_bullet_act(atom/target, obj/projectile/hit_projectile) SIGNAL_HANDLER if(!hit_projectile.is_hostile_projectile()) return diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 0b03f41293142..3d2834edc62db 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -448,11 +448,11 @@ target = select_target(target_turf, target) continue - if (SEND_SIGNAL(target, COMSIG_PROJECTILE_PREHIT, args, src) & PROJECTILE_INTERRUPT_HIT) + if (SEND_SIGNAL(target, COMSIG_PROJECTILE_PREHIT, src) & PROJECTILE_INTERRUPT_HIT) qdel(src) return - if (SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_PREHIT, args) & PROJECTILE_INTERRUPT_HIT) + if (SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_PREHIT, target) & PROJECTILE_INTERRUPT_HIT) qdel(src) return diff --git a/code/modules/vehicles/mecha/combat/durand.dm b/code/modules/vehicles/mecha/combat/durand.dm index 0e1ab1302db91..da1f7122dd14a 100644 --- a/code/modules/vehicles/mecha/combat/durand.dm +++ b/code/modules/vehicles/mecha/combat/durand.dm @@ -35,8 +35,6 @@ . = ..() shield = new /obj/durand_shield(loc, src, plane, layer, dir) RegisterSignal(src, COMSIG_MECHA_ACTION_TRIGGER, PROC_REF(relay)) - RegisterSignal(src, COMSIG_PROJECTILE_PREHIT, PROC_REF(prehit)) - /obj/vehicle/sealed/mecha/durand/Destroy() if(shield) @@ -84,10 +82,12 @@ shield.setDir(dir) //Redirects projectiles to the shield if defense_check decides they should be blocked and returns true. -/obj/vehicle/sealed/mecha/durand/proc/prehit(obj/projectile/source, list/signal_args) - SIGNAL_HANDLER +/obj/vehicle/sealed/mecha/durand/bullet_act(obj/projectile/source, def_zone, mode) if(defense_check(source.loc) && shield) - signal_args[2] = shield + return shield.bullet_act(source, def_zone, mode) + return ..() + + /**Checks if defense mode is enabled, and if the attacker is standing in an area covered by the shield. Expects a turf. Returns true if the attack should be blocked, false if not.*/ From d0625f017f68815b400281bcf3bad14b5f73b65a Mon Sep 17 00:00:00 2001 From: Alexis Date: Thu, 14 Nov 2024 06:40:38 -0500 Subject: [PATCH 049/222] Fixes brains turning invisible after being washed instead of being smooth (#87898) --- code/modules/mob/living/brain/brain_item.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 32f8660d62da1..d96a1dc4f2e99 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -131,7 +131,7 @@ organ_owner.clear_mood_event("brain_damage") /obj/item/organ/brain/update_icon_state() - icon_state = "[initial(icon_state)][smooth_brain ? "-smooth_brain" : ""]" + icon_state = "[initial(icon_state)][smooth_brain ? "-smooth" : ""]" return ..() /obj/item/organ/brain/proc/transfer_identity(mob/living/L) From b5f46f012c9baf324c77e60d0520fadfe9d9cc58 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 11:40:57 +0000 Subject: [PATCH 050/222] Automatic changelog for PR #87898 [ci skip] --- html/changelogs/AutoChangeLog-pr-87898.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87898.yml diff --git a/html/changelogs/AutoChangeLog-pr-87898.yml b/html/changelogs/AutoChangeLog-pr-87898.yml new file mode 100644 index 0000000000000..aa4f5a81aa944 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87898.yml @@ -0,0 +1,4 @@ +author: "xPokee" +delete-after: True +changes: + - bugfix: "fixed brains turning invisible after being washed" \ No newline at end of file From a3a3fd7a15651ac825f3a9f4610f775a0e8e4eec Mon Sep 17 00:00:00 2001 From: Lucy Date: Thu, 14 Nov 2024 08:05:39 -0500 Subject: [PATCH 051/222] Admin deleting a mob now ghostizes it beforehand, preventing a runtime (#87887) --- code/__DEFINES/dcs/signals/signals_datum.dm | 2 ++ code/datums/mind/initialization.dm | 7 +++++++ code/modules/admin/view_variables/admin_delete.dm | 1 + 3 files changed, 10 insertions(+) diff --git a/code/__DEFINES/dcs/signals/signals_datum.dm b/code/__DEFINES/dcs/signals/signals_datum.dm index 5565c143d6613..696d359ac5700 100644 --- a/code/__DEFINES/dcs/signals/signals_datum.dm +++ b/code/__DEFINES/dcs/signals/signals_datum.dm @@ -14,6 +14,8 @@ #define COMSIG_PREQDELETED "parent_preqdeleted" /// just before a datum's Destroy() is called: (force), at this point none of the other components chose to interrupt qdel and Destroy will be called #define COMSIG_QDELETING "parent_qdeleting" +/// Called whenever an admin manually deletes an object, via the "Delete" verb, before qdel() is called: (client/deleting_admin) +#define COMSIG_ADMIN_DELETING "parent_admin_deleting" /// generic topic handler (usr, href_list) #define COMSIG_TOPIC "handle_topic" /// handler for vv_do_topic (usr, href_list) diff --git a/code/datums/mind/initialization.dm b/code/datums/mind/initialization.dm index e3b3e8225dc7a..a09cb040dbe84 100644 --- a/code/datums/mind/initialization.dm +++ b/code/datums/mind/initialization.dm @@ -11,8 +11,10 @@ mind.set_current(src) // There's nowhere else to set this up, mind code makes me depressed mind.antag_hud = add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/antagonist_hud, "combo_hud", mind) + RegisterSignal(src, COMSIG_ADMIN_DELETING, PROC_REF(ghost_before_admin_delete), override = TRUE) SEND_SIGNAL(src, COMSIG_MOB_MIND_INITIALIZED, mind) + /mob/living/carbon/mind_initialize() ..() last_mind = mind @@ -35,3 +37,8 @@ . = ..() mind.set_assigned_role(SSjob.get_job_type(/datum/job/personal_ai)) mind.special_role = "" + +/// Signal proc for [COMSIG_ADMIN_DELETING], to ghostize a mob beforehand if an admin is manually deleting it. +/mob/proc/ghost_before_admin_delete(datum/source) + SIGNAL_HANDLER + ghostize(can_reenter_corpse = FALSE) diff --git a/code/modules/admin/view_variables/admin_delete.dm b/code/modules/admin/view_variables/admin_delete.dm index 5ef04b351cce3..b9a11b50e6547 100644 --- a/code/modules/admin/view_variables/admin_delete.dm +++ b/code/modules/admin/view_variables/admin_delete.dm @@ -16,6 +16,7 @@ log_admin("[key_name(usr)] deleted [D] [coords]") message_admins("[key_name_admin(usr)] deleted [D] [jmp_coords]") BLACKBOX_LOG_ADMIN_VERB("Delete") + SEND_SIGNAL(D, COMSIG_ADMIN_DELETING, src) if(isturf(D)) var/turf/T = D T.ScrapeAway() From 5a56efbbdfeb61ecd932c6c2737dd52b2c97afbc Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 13:05:59 +0000 Subject: [PATCH 052/222] Automatic changelog for PR #87887 [ci skip] --- html/changelogs/AutoChangeLog-pr-87887.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87887.yml diff --git a/html/changelogs/AutoChangeLog-pr-87887.yml b/html/changelogs/AutoChangeLog-pr-87887.yml new file mode 100644 index 0000000000000..5b0a6f175c032 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87887.yml @@ -0,0 +1,4 @@ +author: "Absolucy" +delete-after: True +changes: + - bugfix: "Admin-deleting a mob now ghostizes it beforehand, preventing a runtime error." \ No newline at end of file From f4a077c6fe3b81fba9bf25c0a694a659ff582855 Mon Sep 17 00:00:00 2001 From: Lucy Date: Thu, 14 Nov 2024 13:10:22 -0500 Subject: [PATCH 053/222] Refactors some more UIs to use DmIcon (#87886) ## About The Pull Request Upstream port of https://github.com/Monkestation/Monkestation2.0/pull/4215 This changes some tgui UIs that used icon2base64/getFlatIcon to display items to instead use DmIcon, just passing the icon/icon_state instead. To be specific: the ORM, the "ore container", and the order console (produce, mining, and bitrunning vendors)

UI screenshots / proof of testing

![2024-11-12 (1731458275) ~ dreamseeker](https://github.com/user-attachments/assets/b1c60677-b117-4c23-8076-8b5072130d55) ![2024-11-12 (1731458281) ~ dreamseeker](https://github.com/user-attachments/assets/b64d3c2f-4754-4e5d-991a-2df69d86eb2a) ![2024-11-12 (1731458286) ~ dreamseeker](https://github.com/user-attachments/assets/287d8db1-8acb-4c4c-a2f0-66227a477d19) ![2024-11-12 (1731458388) ~ dreamseeker](https://github.com/user-attachments/assets/f69f5d51-5cdc-442c-971d-a4abedd4a3d2) ![2024-11-12 (1731458391) ~ dreamseeker](https://github.com/user-attachments/assets/53a95e88-ac41-4f97-a409-10b19d130376)
## Why It's Good For The Game gfi bad, especially in ui(_static)_data, dmicon good. ## Changelog :cl: refactor: The ORM, "ore container", and order console UIs (produce, mining, bitrunner vendors) now load icons in a more efficient manner. /:cl: --- .../orders/order_computer/order_computer.dm | 3 +- .../game/objects/structures/ore_containers.dm | 19 ++------ code/modules/mining/machine_redemption.dm | 29 +++-------- .../packages/tgui/interfaces/OreContainer.tsx | 48 +++++++------------ .../tgui/interfaces/OreRedemptionMachine.jsx | 25 ++++------ .../tgui/interfaces/ProduceConsole.tsx | 19 ++++---- 6 files changed, 48 insertions(+), 95 deletions(-) diff --git a/code/game/machinery/computer/orders/order_computer/order_computer.dm b/code/game/machinery/computer/orders/order_computer/order_computer.dm index 9098d5aeb090b..8ad5d5dde2807 100644 --- a/code/game/machinery/computer/orders/order_computer/order_computer.dm +++ b/code/game/machinery/computer/orders/order_computer/order_computer.dm @@ -120,7 +120,8 @@ GLOBAL_LIST_EMPTY(order_console_products) "cat" = item.category_index, "ref" = REF(item), "cost" = round(item.cost_per_order * cargo_cost_multiplier), - "product_icon" = icon2base64(getFlatIcon(image(icon = initial(item.item_path.icon), icon_state = initial(item.item_path.icon_state)), no_anim=TRUE)) + "icon" = item.item_path::icon, + "icon_state" = item.item_path::icon_state, )) return data diff --git a/code/game/objects/structures/ore_containers.dm b/code/game/objects/structures/ore_containers.dm index 6bc6f680116f4..75c7a03cfcfa9 100644 --- a/code/game/objects/structures/ore_containers.dm +++ b/code/game/objects/structures/ore_containers.dm @@ -23,25 +23,16 @@ ui.open() /obj/structure/ore_container/ui_data(mob/user) - var/list/data = list() - data["ores"] = list() + var/list/ores = list() for(var/obj/item/stack/ore/ore_item in contents) - data["ores"] += list(list( + ores += list(list( "id" = REF(ore_item), "name" = ore_item.name, "amount" = ore_item.amount, + "icon" = ore_item::icon, + "icon_state" = ore_item::icon_state, )) - return data - -/obj/structure/ore_container/ui_static_data(mob/user) - var/list/data = list() - data["ore_images"] = list() - for(var/obj/item/stack/ore_item as anything in subtypesof(/obj/item/stack/ore)) - data["ore_images"] += list(list( - "name" = initial(ore_item.name), - "icon" = icon2base64(getFlatIcon(image(icon = initial(ore_item.icon), icon_state = initial(ore_item.icon_state)), no_anim=TRUE)) - )) - return data + return list("ores" = ores) /obj/structure/ore_container/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) . = ..() diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index 312acb6672014..24e0f53a87ab7 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -229,21 +229,27 @@ for(var/datum/material/material as anything in mat_container.materials) var/amount = mat_container.materials[material] var/sheet_amount = amount / SHEET_MATERIAL_AMOUNT + var/obj/sheet_type = material.sheet_type data["materials"] += list(list( "name" = material.name, "id" = REF(material), "amount" = sheet_amount, "category" = "material", "value" = ore_values[material.type], + "icon" = sheet_type::icon, + "icon_state" = sheet_type::icon_state, )) for(var/research in stored_research.researched_designs) var/datum/design/alloy = SSresearch.techweb_design_by_id(research) + var/obj/alloy_type = alloy.build_path data["materials"] += list(list( "name" = alloy.name, "id" = alloy.id, "category" = "alloy", "amount" = can_smelt_alloy(alloy), + "icon" = alloy_type::icon, + "icon_state" = alloy_type::icon_state, )) data["disconnected"] = null @@ -274,29 +280,6 @@ ) return data -/obj/machinery/mineral/ore_redemption/ui_static_data(mob/user) - var/list/data = list() - - var/datum/component/material_container/mat_container = materials.mat_container - if (mat_container) - for(var/datum/material/material as anything in mat_container.materials) - var/obj/material_display = initial(material.sheet_type) - data["material_icons"] += list(list( - "id" = REF(material), - "product_icon" = icon2base64(getFlatIcon(image(icon = initial(material_display.icon), icon_state = initial(material_display.icon_state)), no_anim=TRUE)), - )) - - for(var/research in stored_research.researched_designs) - var/datum/design/alloy = SSresearch.techweb_design_by_id(research) - var/obj/alloy_display = initial(alloy.build_path) - data["material_icons"] += list(list( - "id" = alloy.id, - "product_icon" = icon2base64(getFlatIcon(image(icon = initial(alloy_display.icon), icon_state = initial(alloy_display.icon_state)), no_anim=TRUE)), - )) - - return data - - /obj/machinery/mineral/ore_redemption/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) . = ..() if(.) diff --git a/tgui/packages/tgui/interfaces/OreContainer.tsx b/tgui/packages/tgui/interfaces/OreContainer.tsx index 261523c6e9501..daae93a8edf36 100644 --- a/tgui/packages/tgui/interfaces/OreContainer.tsx +++ b/tgui/packages/tgui/interfaces/OreContainer.tsx @@ -2,23 +2,27 @@ import { createSearch, toTitleCase } from 'common/string'; import { useState } from 'react'; import { useBackend } from '../backend'; -import { Button, Flex, Image, Input, Section, Stack } from '../components'; +import { + Button, + DmIcon, + Flex, + Icon, + Input, + Section, + Stack, +} from '../components'; import { Window } from '../layouts'; type Ores = { id: string; name: string; amount: number; -}; - -type Ore_images = { - name: string; icon: string; + icon_state: string; }; type Data = { ores: Ores[]; - ore_images: Ore_images[]; }; export const OreContainer = (props) => { @@ -58,7 +62,13 @@ export const OreContainer = (props) => { - + } + /> @@ -87,30 +97,6 @@ export const OreContainer = (props) => { ); }; -const RetrieveIcon = (props) => { - const { data } = useBackend(); - const { ore_images = [] } = data; - const { ore } = props; - - let icon_display = ore_images.find((icon) => icon.name === ore.name); - - if (!icon_display) { - return null; - } - - return ( - - ); -}; - const Orename = (props) => { const { ore_name } = props; const return_name = ore_name.split(' '); diff --git a/tgui/packages/tgui/interfaces/OreRedemptionMachine.jsx b/tgui/packages/tgui/interfaces/OreRedemptionMachine.jsx index 3bb87d7dce240..b9088f32e0d4a 100644 --- a/tgui/packages/tgui/interfaces/OreRedemptionMachine.jsx +++ b/tgui/packages/tgui/interfaces/OreRedemptionMachine.jsx @@ -6,8 +6,8 @@ import { BlockQuote, Box, Button, + DmIcon, Icon, - Image, Input, LabeledList, Section, @@ -175,14 +175,7 @@ export const OreRedemptionMachine = (props) => { }; const MaterialRow = (props) => { - const { data } = useBackend(); - const { compact } = props; - const { material_icons } = data; - const { material, onRelease } = props; - - const display = material_icons.find( - (mat_icon) => mat_icon.id === material.id, - ); + const { compact, material, onRelease } = props; const sheet_amounts = Math.floor(material.amount); const print_amount = 5; @@ -192,14 +185,12 @@ const MaterialRow = (props) => { {!compact && ( - } /> )} diff --git a/tgui/packages/tgui/interfaces/ProduceConsole.tsx b/tgui/packages/tgui/interfaces/ProduceConsole.tsx index 686b194abea8c..b13fda8af077c 100644 --- a/tgui/packages/tgui/interfaces/ProduceConsole.tsx +++ b/tgui/packages/tgui/interfaces/ProduceConsole.tsx @@ -8,8 +8,8 @@ import { Button, Dimmer, Divider, + DmIcon, Icon, - Image, Input, NumberInput, Section, @@ -26,7 +26,8 @@ type OrderDatum = { cat: string; ref: string; cost: number; - product_icon: string; + icon: string; + icon_state: string; }; type Item = { @@ -127,13 +128,13 @@ const ShoppingTab = (props) => { />{' '} {!condensed && ( - } /> )} From 3cdaf62fea9db9d0037f015437e779175d172acd Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Thu, 14 Nov 2024 19:11:00 +0100 Subject: [PATCH 054/222] Tenacious element no longer prints a wear off message when added outside of soft crit and properly removes its effects when detached (#87901) ## About The Pull Request Wear off message is only printed if the user actually had the effect active before, and speed modifier is removed alongside the element. ## Changelog :cl: fix: Fixed tenacity effect printing its messages when it shouldn't be, and not removing its' effects when it should've. /:cl: --- code/datums/elements/tenacious.dm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/datums/elements/tenacious.dm b/code/datums/elements/tenacious.dm index 4d906812c13ab..35dd5774cf4be 100644 --- a/code/datums/elements/tenacious.dm +++ b/code/datums/elements/tenacious.dm @@ -18,6 +18,9 @@ /datum/element/tenacious/Detach(datum/target) UnregisterSignal(target, COMSIG_MOB_STATCHANGE) REMOVE_TRAIT(target, TRAIT_TENACIOUS, ELEMENT_TRAIT(type)) + var/mob/living/carbon/human/valid_target = target + if(valid_target.remove_movespeed_modifier(/datum/movespeed_modifier/tenacious)) + valid_target.balloon_alert(valid_target, "your tenacity wears off") return ..() ///signal called by the stat of the target changing @@ -27,6 +30,5 @@ if(new_stat == SOFT_CRIT) target.balloon_alert(target, "your tenacity kicks in") target.add_movespeed_modifier(/datum/movespeed_modifier/tenacious) - else + else if(target.remove_movespeed_modifier(/datum/movespeed_modifier/tenacious)) target.balloon_alert(target, "your tenacity wears off") - target.remove_movespeed_modifier(/datum/movespeed_modifier/tenacious) From 266a4af0e1b2f6d751a3ff1e6250f028495f6533 Mon Sep 17 00:00:00 2001 From: zxaber <37497534+zxaber@users.noreply.github.com> Date: Thu, 14 Nov 2024 10:11:14 -0800 Subject: [PATCH 055/222] Fixes Mech Spin Sounds (#87900) ## About The Pull Request Mechs were playing spin sound effects (_on top_ of normal step sounds) every time they'd take a step while strafing. Additionally, they would not play the spin sound effect when actually turning. This fixes both. ## Why It's Good For The Game Bugfix. Also, cleaner sounding mechs. ## Changelog :cl: Fix: Fixed the triggering of mech turn sound effects /:cl: --- code/modules/vehicles/mecha/mecha_movement.dm | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/code/modules/vehicles/mecha/mecha_movement.dm b/code/modules/vehicles/mecha/mecha_movement.dm index a4b21190a1ec3..130e0e807b438 100644 --- a/code/modules/vehicles/mecha/mecha_movement.dm +++ b/code/modules/vehicles/mecha/mecha_movement.dm @@ -139,6 +139,8 @@ // if we're not strafing or if we are forced to rotate or if we are holding down the key if(dir != direction && (!strafe || forcerotate || keyheld)) setDir(direction) + if(!(mecha_flags & QUIET_TURNS)) + playsound(src, turnsound, 40, TRUE) if(keyheld || !pivot_step) //If we pivot step, we don't return here so we don't just come to a stop return TRUE @@ -146,10 +148,6 @@ //Otherwise just walk normally . = try_step_multiz(direction) - //dir and olddir are the current direction of the sprite and the old direction of the sprite respectively - if (dir != olddir && !(mecha_flags & QUIET_TURNS)) - playsound(src, turnsound, 40, TRUE) - if(phasing) use_energy(phasing_energy_drain) if(strafe) From 9dadb4b2cfda30db998ff74bd7071e4d23c78c2b Mon Sep 17 00:00:00 2001 From: grungussuss <96586172+Sadboysuss@users.noreply.github.com> Date: Thu, 14 Nov 2024 21:11:25 +0300 Subject: [PATCH 056/222] sandstone blocks have the correct sound now (#87896) ## About The Pull Request closes https://github.com/tgstation/tgstation/issues/87611 ## Why It's Good For The Game it makes sense ## Changelog :cl: grungussuss sound: sandstone blocks have the correct sound now /:cl: --- code/game/objects/items/stacks/sheets/mineral.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 0d4393efea6a4..ef3ddb77c0e44 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -41,6 +41,8 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \ merge_type = /obj/item/stack/sheet/mineral/sandstone walltype = /turf/closed/wall/mineral/sandstone material_type = /datum/material/sandstone + drop_sound = SFX_STONE_DROP + pickup_sound = SFX_STONE_PICKUP /obj/item/stack/sheet/mineral/sandstone/get_main_recipes() . = ..() From 43d1164580d3cbfbc1a326d127559c142f2f40e9 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 14 Nov 2024 12:12:31 -0600 Subject: [PATCH 057/222] Lower singularity beacon cost and time (#87891) ## About The Pull Request This lowers the cost of the singularity beacon to 4 crystals. Right now this item never gets used due to the high cost and niche requirements. According to the statistics it is not even on the list: https://superset.moth.fans/superset/dashboard/4/?native_filters_key=Gd84-_rrITStPTkyo7BlqnE5aYcHmofhLU2GjWEiWdqY-ZaK2WVxrq1eG6qS0bNa Before we had the SM, the singularity engine was often sabotaged with this beacon since all you needed to do was disable an emitter or cut a wire and the singularity would break loose. It was a relatively easy process. The criteria to achieve a singularity now is very difficult. You either have to overload the SM and fight off anyone who tries to fix it OR purchase one from cargo and make a pipe setup to feed it a ton of gas. All the crew has to do to prevent it, is leak the gas by opening an airlock, breach the floor, or a window. If there is an AI or cyborgs, your job is now ten times harder. Then you have another problem. The beacon requires powered wires and if the SMESs gets destroyed by the singularity it's useless. This is guaranteed to happen if using the SM from engineering since it's so close to the SMESs. So now you have to either rely on solars or a generator to power the device. The hassle of spending 10 crystals on this item is not worth it. Too many things can go wrong and it would be a waste of points. ## Why It's Good For The Game This item never gets picked due to it's high cost and difficulty. By lowering the cost, it would make it a more reasonable choice. ## Changelog :cl: balance: Lower the telecrystal price of the singularity beacon from 10 to 4 and reduce the timer to 20 minutes before it can be purchased. /:cl: --- code/modules/uplink/uplink_items/device_tools.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/uplink/uplink_items/device_tools.dm b/code/modules/uplink/uplink_items/device_tools.dm index 714c3133482c4..ef2ab6fd1fddc 100644 --- a/code/modules/uplink/uplink_items/device_tools.dm +++ b/code/modules/uplink/uplink_items/device_tools.dm @@ -242,9 +242,9 @@ active gravitational singularities or tesla balls towards it. This will not work when the engine is still \ in containment. Because of its size, it cannot be carried. Ordering this \ sends you a small beacon that will teleport the larger beacon to your location upon activation." - progression_minimum = 30 MINUTES + progression_minimum = 20 MINUTES item = /obj/item/sbeacondrop - cost = 10 + cost = 4 surplus = 0 // not while there isnt one on any station purchasable_from = ~UPLINK_ALL_SYNDIE_OPS From 8c819ea1c5363c5f5b6f0b2c6f9e7f138401453d Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Thu, 14 Nov 2024 12:13:07 -0600 Subject: [PATCH 058/222] Speeds up part of the dust animation by a frame or so, makes remains/dust spawn aligned lower on the tile (#87858) ## About The Pull Request - Speeds up the torso part of the dust animation by a few frames, as was requested but I didn't do before merge - Makes remains/dust spawn from being dusted towards the bottom of the tile Videos (take before the remains/dust change) https://github.com/user-attachments/assets/7e9fe699-a44b-49d5-a4d0-2304e09283d5 https://github.com/user-attachments/assets/7b426340-5d3d-49fa-91f1-52b2fc3a560c ## Why It's Good For The Game Should help sell the effect a bit more ## Changelog :cl: Melbert image: Speeds up some frames of the dust animation slightly image: Dust/remains spawned after being dusted are now aligned towards the bottom of the tile image: Bigger mobs now produce bigger piles of ash image: Plasmamen now dust into plasma bones /:cl: --- code/modules/mob/living/carbon/alien/death.dm | 9 +++++++-- .../mob/living/carbon/alien/larva/death.dm | 9 +++++++-- code/modules/mob/living/carbon/human/death.dm | 14 ++++++++++---- code/modules/mob/living/death.dm | 15 +++++++++++++-- code/modules/mob/living/silicon/death.dm | 9 +++++++-- code/modules/mob/living/silicon/robot/death.dm | 3 --- icons/mob/dust_animation.dmi | Bin 865 -> 861 bytes 7 files changed, 44 insertions(+), 15 deletions(-) diff --git a/code/modules/mob/living/carbon/alien/death.dm b/code/modules/mob/living/carbon/alien/death.dm index 85092244510a7..8671a66c98aec 100644 --- a/code/modules/mob/living/carbon/alien/death.dm +++ b/code/modules/mob/living/carbon/alien/death.dm @@ -7,5 +7,10 @@ /mob/living/carbon/alien/gib_animation() new /obj/effect/temp_visual/gib_animation(loc, "gibbed-a") -/mob/living/carbon/alien/spawn_dust() - new /obj/effect/decal/remains/xeno(loc) +/mob/living/carbon/alien/spawn_dust(just_ash) + if(just_ash) + return ..() + + var/obj/effect/decal/remains/xeno/bones = new(loc) + bones.pixel_z = -6 + bones.pixel_w = rand(-1, 1) diff --git a/code/modules/mob/living/carbon/alien/larva/death.dm b/code/modules/mob/living/carbon/alien/larva/death.dm index f33ee4efdf17d..3c4500518de89 100644 --- a/code/modules/mob/living/carbon/alien/larva/death.dm +++ b/code/modules/mob/living/carbon/alien/larva/death.dm @@ -15,5 +15,10 @@ /mob/living/carbon/alien/larva/gib_animation() new /obj/effect/temp_visual/gib_animation(loc, "gibbed-l") -/mob/living/carbon/alien/larva/spawn_dust() - new /obj/effect/decal/remains/xeno(loc) +/mob/living/carbon/alien/larva/spawn_dust(just_ash) + if(just_ash) + return ..() + + var/obj/effect/decal/remains/xeno/bones = new(loc) + bones.pixel_z = -6 + bones.pixel_w = rand(-1, 1) diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 7e8fa7f1f8d2c..dad45038f137d 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -10,11 +10,17 @@ GLOBAL_LIST_EMPTY(dead_players_during_shift) else new /obj/effect/gibspawner/human/bodypartless(drop_location(), src, get_static_viruses()) -/mob/living/carbon/human/spawn_dust(just_ash = FALSE) +/mob/living/carbon/human/spawn_dust(just_ash) if(just_ash) - new /obj/effect/decal/cleanable/ash(loc) - else - new /obj/effect/decal/remains/human(loc) + return ..() + + var/bone_type = /obj/effect/decal/remains/human + if(isplasmaman(src)) + bone_type = /obj/effect/decal/remains/plasma + + var/obj/effect/decal/remains/human/bones = new bone_type(loc) + bones.pixel_z = -6 + bones.pixel_w = rand(-1, 1) /mob/living/carbon/human/death(gibbed) if(stat == DEAD) diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 8688e256022ba..6616736a61064 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -98,7 +98,7 @@ ghostize() QDEL_IN(src, DUST_ANIMATION_TIME) // since this is sometimes called in the middle of movement, allow half a second for movement to finish, ghosting to happen and animation to play. Looks much nicer and doesn't cause multiple runtimes. -/// Animates turning into dust +/// Animates turning into dust. /// Does not delete src afterwards, BUT it will become invisible (and grey), so ensure you handle that yourself /atom/movable/proc/dust_animation(atom/anim_loc = src.loc) if(isnull(anim_loc)) // the effect breaks if we have a null loc @@ -130,8 +130,19 @@ #undef DUST_ANIMATION_TIME +/** + * Spawns dust / ash or remains where the mob was + * + * just_ash: If TRUE, just ash will spawn where the mob was, as opposed to remains + */ /mob/living/proc/spawn_dust(just_ash = FALSE) - new /obj/effect/decal/cleanable/ash(loc) + var/ash_type = /obj/effect/decal/cleanable/ash + if(mob_size >= MOB_SIZE_LARGE) + ash_type = /obj/effect/decal/cleanable/ash/large + + var/obj/effect/decal/cleanable/ash/ash = new ash_type(loc) + ash.pixel_z = -5 + ash.pixel_w = rand(-1, 1) /* * Called when the mob dies. Can also be called manually to kill a mob. diff --git a/code/modules/mob/living/silicon/death.dm b/code/modules/mob/living/silicon/death.dm index 85e749d276541..67083168eb30e 100644 --- a/code/modules/mob/living/silicon/death.dm +++ b/code/modules/mob/living/silicon/death.dm @@ -1,8 +1,13 @@ /mob/living/silicon/spawn_gibs() new /obj/effect/gibspawner/robot(drop_location(), src) -/mob/living/silicon/spawn_dust() - new /obj/effect/decal/remains/robot(loc) +/mob/living/silicon/spawn_dust(just_ash) + if(just_ash) + return ..() + + var/obj/effect/decal/remains/robot/robones = new(loc) + robones.pixel_z = -6 + robones.pixel_w = rand(-1, 1) /mob/living/silicon/death(gibbed) diag_hud_set_status() diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm index 91627b5099fe5..99c5686aa5325 100644 --- a/code/modules/mob/living/silicon/robot/death.dm +++ b/code/modules/mob/living/silicon/robot/death.dm @@ -7,9 +7,6 @@ QDEL_NULL(mmi) return ..() -/mob/living/silicon/robot/spawn_dust() - new /obj/effect/decal/remains/robot(loc) - /mob/living/silicon/robot/death(gibbed) if(stat == DEAD) return diff --git a/icons/mob/dust_animation.dmi b/icons/mob/dust_animation.dmi index 459fc2aa3c4b369f2d43f4ff08d8e08109bf8678..10d8418a144530f80b8dd4d4e7e0e3aa883d0859 100644 GIT binary patch delta 631 zcmV--0*L+L2Hggb@qbrIL_t(&f$ffCStI#8tPYgiL-MAX*>C zuzej8;JR?+cK}?4Q@GF{q``cA%|VkL?f^D`v_^mce}6c?PXLJ`8L3?&On2&h8_Z{5Vdx+ z3l!PFa>hg83gF>u$R_f#puptO0Ckum~9E z4M+qJD{z3{1B}|yoV3Av2RKiIOzYpw3O;ToxA91QC7o~Y#%kW7<#ewA zB;PjH&G{g0oLj4vRcU**`Y?&sqXRmi13I7sI-mo70+4Z delta 635 zcmV->0)+kD2H^&f@qb%ML_t(&f$fwbSasXg@0Bp?xW^TY#-2WIxn(4{q%gr+5W zJNNvb%-tHaTp!gAh;_JIfPbvH{s(~W4?3U&I-mpI2`F2bN@OCfM&KXD^UVq=X8h9#c`ZQbW-FMaO}3H6Id4ZIR|h^ zqd~y19dtkr;G+L?Y01@nT6^c8@S{445HfZufk V)!yBe2<`v?002ovPDHLkV1hObBjo@9 From 631acd143baa6fe1b1beddf71f928052a26af6a1 Mon Sep 17 00:00:00 2001 From: Dawnseer <126404225+Dawnseer@users.noreply.github.com> Date: Thu, 14 Nov 2024 19:13:39 +0100 Subject: [PATCH 059/222] Fixes cigarettes not fitting in gas masks (#87817) ## About The Pull Request You couldn't put cigarettes in gas masks due to a check for if the masks mouth is covered ## Why It's Good For The Game You can now filter the air through your cigarettes as was intended. ## Changelog :cl: fix: removes the gas mask check for if the gas mask mouth is covered. Now it only checks for filters and other cigs /:cl: --- code/modules/clothing/masks/gasmask.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index afbdeef519224..a59280ff04517 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -94,9 +94,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( var/valid_wearer = ismob(loc) var/mob/wearer = loc if(istype(tool, /obj/item/cigarette)) - if(flags_cover & MASKCOVERSMOUTH) - balloon_alert(user, "mask's mouth is covered!") - return ..() if(max_filters <= 0 || cig) balloon_alert(user, "can't hold that!") From ab749572ce4d175f5294739249e3e2e84ccd6425 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:14:19 +0000 Subject: [PATCH 060/222] Automatic changelog for PR #87886 [ci skip] --- html/changelogs/AutoChangeLog-pr-87886.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87886.yml diff --git a/html/changelogs/AutoChangeLog-pr-87886.yml b/html/changelogs/AutoChangeLog-pr-87886.yml new file mode 100644 index 0000000000000..56c04b1ca024a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87886.yml @@ -0,0 +1,4 @@ +author: "Absolucy" +delete-after: True +changes: + - refactor: "The ORM, \"ore container\", and order console UIs (produce, mining, bitrunner vendors) now load icons in a more efficient manner." \ No newline at end of file From 44d3c5f774b4983ca43e7ca8b4e9dc8eeb28bd91 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:14:29 +0000 Subject: [PATCH 061/222] Automatic changelog for PR #87901 [ci skip] --- html/changelogs/AutoChangeLog-pr-87901.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87901.yml diff --git a/html/changelogs/AutoChangeLog-pr-87901.yml b/html/changelogs/AutoChangeLog-pr-87901.yml new file mode 100644 index 0000000000000..af44465c11ddd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87901.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Fixed tenacity effect printing its messages when it shouldn't be, and not removing its' effects when it should've." \ No newline at end of file From ce8208d4c8ad18f2faec514495377206762c5ecf Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:14:38 +0000 Subject: [PATCH 062/222] Automatic changelog for PR #87896 [ci skip] --- html/changelogs/AutoChangeLog-pr-87896.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87896.yml diff --git a/html/changelogs/AutoChangeLog-pr-87896.yml b/html/changelogs/AutoChangeLog-pr-87896.yml new file mode 100644 index 0000000000000..a1308fb4a9f38 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87896.yml @@ -0,0 +1,4 @@ +author: "grungussuss" +delete-after: True +changes: + - sound: "sandstone blocks have the correct sound now" \ No newline at end of file From d68dce4b26ca369b7696fa2e67d358d497181324 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:14:54 +0000 Subject: [PATCH 063/222] Automatic changelog for PR #87891 [ci skip] --- html/changelogs/AutoChangeLog-pr-87891.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87891.yml diff --git a/html/changelogs/AutoChangeLog-pr-87891.yml b/html/changelogs/AutoChangeLog-pr-87891.yml new file mode 100644 index 0000000000000..43acec0776451 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87891.yml @@ -0,0 +1,4 @@ +author: "timothymtorres" +delete-after: True +changes: + - balance: "Lower the telecrystal price of the singularity beacon from 10 to 4 and reduce the timer to 20 minutes before it can be purchased." \ No newline at end of file From af015b9c7cc49253bab0bd33a6d838ccd7a023e7 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:15:16 +0000 Subject: [PATCH 064/222] Automatic changelog for PR #87858 [ci skip] --- html/changelogs/AutoChangeLog-pr-87858.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87858.yml diff --git a/html/changelogs/AutoChangeLog-pr-87858.yml b/html/changelogs/AutoChangeLog-pr-87858.yml new file mode 100644 index 0000000000000..073a04f7237e7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87858.yml @@ -0,0 +1,7 @@ +author: "Melbert" +delete-after: True +changes: + - image: "Speeds up some frames of the dust animation slightly" + - image: "Dust/remains spawned after being dusted are now aligned towards the bottom of the tile" + - image: "Bigger mobs now produce bigger piles of ash" + - image: "Plasmamen now dust into plasma bones" \ No newline at end of file From 54bdf078be16b2bad76faf5140334afeb83cc348 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:15:29 +0000 Subject: [PATCH 065/222] Automatic changelog for PR #87817 [ci skip] --- html/changelogs/AutoChangeLog-pr-87817.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87817.yml diff --git a/html/changelogs/AutoChangeLog-pr-87817.yml b/html/changelogs/AutoChangeLog-pr-87817.yml new file mode 100644 index 0000000000000..04ed21be2aaa6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87817.yml @@ -0,0 +1,4 @@ +author: "Dawnseer" +delete-after: True +changes: + - bugfix: "removes the gas mask check for if the gas mask mouth is covered. Now it only checks for filters and other cigs" \ No newline at end of file From 7534273bb0f86ca4e1b8af7f10b03d6df4b5441d Mon Sep 17 00:00:00 2001 From: Waterpig <49160555+Majkl-J@users.noreply.github.com> Date: Thu, 14 Nov 2024 19:48:44 +0100 Subject: [PATCH 066/222] Fixes SSWardrobe stealing a camera from the camera app when on a dummy, causing a harddel (#87903) ## About The Pull Request See name, if a dummy somehow gets hold of a PDA with the camera app installed (This just so happens to be a default PDA program in the case on Nova, Skyrat, and Bubber), and the delete_equipment proc is called, the camera inside the PDA gets sent to the wardrobe because of `/datum/outfit/job/assistant/gimmick/hall_monitor` having one, and then qdelled with the PDA, leaving a hanging ref This causes a harddel during tests that has caused me great pains to locate. Turns out a single example holodisk with the clown holds a magical key to trigger all this: a single PDA ## Why It's Good For The Game Fixes a harddel. There might be other similar ones hiding in the dark like cameras in other objects. ## Changelog :cl: fix: Fixes SSWardrobe stealing a camera from the camera app when on a dummy, causing a harddel /:cl: --- .../file_system/programs/maintenance/camera.dm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/code/modules/modular_computers/file_system/programs/maintenance/camera.dm b/code/modules/modular_computers/file_system/programs/maintenance/camera.dm index f851dada495f3..e62aa35a6088c 100644 --- a/code/modules/modular_computers/file_system/programs/maintenance/camera.dm +++ b/code/modules/modular_computers/file_system/programs/maintenance/camera.dm @@ -11,12 +11,18 @@ circuit_comp_type = /obj/item/circuit_component/mod_program/camera /// Camera built-into the tablet. - var/obj/item/camera/internal_camera + var/obj/item/camera/app/internal_camera /// Latest picture taken by the app. var/datum/picture/internal_picture /// How many pictures were taken already, used for the camera's TGUI photo display var/picture_number = 1 +// Special type of camera for this exact usecase to prevent harddels +/obj/item/camera/app + name = "internal camera" + desc = "Specialized internal camera protected from the hellish depths of SSWardrobe. \ + Yell at coders if you somehow manage to see this" + /datum/computer_file/program/maintenance/camera/on_install() . = ..() internal_camera = new(computer) From a3f4e6003e326488c375998d52fb0641bfe7d24c Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:50:13 +0000 Subject: [PATCH 067/222] Automatic changelog for PR #87903 [ci skip] --- html/changelogs/AutoChangeLog-pr-87903.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87903.yml diff --git a/html/changelogs/AutoChangeLog-pr-87903.yml b/html/changelogs/AutoChangeLog-pr-87903.yml new file mode 100644 index 0000000000000..2a11a63c40a77 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87903.yml @@ -0,0 +1,4 @@ +author: "Majkl-J" +delete-after: True +changes: + - bugfix: "Fixes SSWardrobe stealing a camera from the camera app when on a dummy, causing a harddel" \ No newline at end of file From b8013f5e7659c85dc2954af8c0261c34a8c11470 Mon Sep 17 00:00:00 2001 From: Lucy Date: Thu, 14 Nov 2024 13:50:35 -0500 Subject: [PATCH 068/222] Rebuild plane masters after client login if switching between 515 and 516 (#87889) ## About The Pull Request This makes `/datum/player_details` properly track BYOND version and build separately, as opposed to just the full version string. Whenever a client logs in, and their BYOND version is 516, while their previous version was 515, or vice versa, it'll set a newly added client var, `rebuild_plane_masters`, to TRUE. During the `COMSIG_MOB_LOGIN` signal handler of a mob's HUD (`/datum/hud/proc/client_refresh`), it will check to see if `rebuild_plane_masters` is TRUE - if so, it will set the appropriate `relay_loc` of (based on client BYOND version) of its plane master groups, and rebuild their plane masters. ## Why It's Good For The Game Makes testing stuff across 515 and 516 easier, as your screen won't break when switching between the two. ## Changelog 516 is _still_ in private alpha, so no user-facing changes. --- code/_onclick/hud/hud.dm | 12 ++++++++++-- code/controllers/subsystem/blackbox.dm | 2 +- code/modules/client/client_defines.dm | 4 ++++ code/modules/client/client_procs.dm | 14 ++++++++++++-- code/modules/client/player_details.dm | 14 +++++++++++--- 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index f92bb4682e1c8..a2185b0386d2e 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -151,8 +151,16 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /datum/hud/proc/client_refresh(datum/source) SIGNAL_HANDLER - RegisterSignal(mymob.canon_client, COMSIG_CLIENT_SET_EYE, PROC_REF(on_eye_change)) - on_eye_change(null, null, mymob.canon_client.eye) + var/client/client = mymob.canon_client + if(client.rebuild_plane_masters) + var/new_relay_loc = (client.byond_version > 515) ? "1,1" : "CENTER" + for(var/group_key as anything in master_groups) + var/datum/plane_master_group/group = master_groups[group_key] + group.relay_loc = new_relay_loc + group.rebuild_plane_masters() + client.rebuild_plane_masters = FALSE + RegisterSignal(client, COMSIG_CLIENT_SET_EYE, PROC_REF(on_eye_change)) + on_eye_change(null, null, client.eye) /datum/hud/proc/clear_client(datum/source) SIGNAL_HANDLER diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm index 83c666de64ac4..e869f21c61560 100644 --- a/code/controllers/subsystem/blackbox.dm +++ b/code/controllers/subsystem/blackbox.dm @@ -88,7 +88,7 @@ SUBSYSTEM_DEF(blackbox) for(var/player_key in GLOB.player_details) var/datum/player_details/PD = GLOB.player_details[player_key] - record_feedback("tally", "client_byond_version", 1, PD.byond_version) + record_feedback("tally", "client_byond_version", 1, PD.full_byond_version()) /datum/controller/subsystem/blackbox/Shutdown() sealed = FALSE diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index c8e9e9a64c270..fe559b2b71bfa 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -269,3 +269,7 @@ ///Which ambient sound this client is currently being provided. var/current_ambient_sound + + /// Does this client's mob need to rebuild its plane masters after login? + /// This is currently only used so a client can switch between 515 and 516 without breaking their rendering. + var/rebuild_plane_masters = FALSE diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index e0f359ac1e639..bc720ddb1dcc5 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -329,10 +329,20 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if(GLOB.player_details[ckey]) reconnecting = TRUE player_details = GLOB.player_details[ckey] - player_details.byond_version = full_version + var/old_version = player_details.byond_version + player_details.byond_version = byond_version + player_details.byond_build = byond_build + +#if MIN_COMPILER_VERSION > 516 + #warn Fully change default relay_loc to "1,1", rather than changing it based on client version +#endif + if(old_version != byond_version) + rebuild_plane_masters = TRUE + else player_details = new(ckey) - player_details.byond_version = full_version + player_details.byond_version = byond_version + player_details.byond_build = byond_build GLOB.player_details[ckey] = player_details diff --git a/code/modules/client/player_details.dm b/code/modules/client/player_details.dm index 3a880dcdbb550..d0982a0c31268 100644 --- a/code/modules/client/player_details.dm +++ b/code/modules/client/player_details.dm @@ -1,6 +1,6 @@ ///assoc list of ckey -> /datum/player_details -GLOBAL_LIST_EMPTY(player_details) +GLOBAL_LIST_EMPTY_TYPED(player_details, /datum/player_details) /// Tracks information about a client between log in and log outs /datum/player_details @@ -18,8 +18,10 @@ GLOBAL_LIST_EMPTY(player_details) /// Lazylist of preference slots this client has joined the round under /// Numbers are stored as strings var/list/joined_as_slots - /// Version of byond this client is using - var/byond_version = "Unknown" + /// Major version of BYOND this client is using. + var/byond_version + /// Build number of BYOND this client is using. + var/byond_build /// Tracks achievements they have earned var/datum/achievement_data/achievements /// World.time this player last died @@ -35,6 +37,12 @@ GLOBAL_LIST_EMPTY(player_details) previous_names += html_encode("[previous_name] ([played_names[previous_name]])") return previous_names.Join("; ") +/// Returns the full version string (i.e 515.1642) of the BYOND version and build. +/datum/player_details/proc/full_byond_version() + if(!byond_version) + return "Unknown" + return "[byond_version].[byond_build || "xxx"]" + /// Adds the new names to the player's played_names list on their /datum/player_details for use of admins. /// `ckey` should be their ckey, and `data` should be an associative list with the keys being the names they played under and the values being the unique mob ID tied to that name. /proc/log_played_names(ckey, data) From 168162f9a3416df5d19e482cfcc67e7da94da391 Mon Sep 17 00:00:00 2001 From: jimmyl <70376633+mc-oofert@users.noreply.github.com> Date: Thu, 14 Nov 2024 19:51:09 +0100 Subject: [PATCH 069/222] a few tiny birdshot tweaks and fixes (#87785) ## About The Pull Request 1st SM filter is now set to N2 by default A random hallway apc that started unwired is now wired Chef gets a dehydrator Surgery theatre now has a surgery tray instead and surplus prosthetic limbs to fill in the empty space Greater central maintenance owns all of its walls The chemical closet in pharmacy now has multiver, formaldehyde, epinephrine, basic buffer and the other kind of buffer to compensate for not having a chemstorage room atmos distro air mixer now mixes correctly ## Why It's Good For The Game closes #87729 also maintenance is supposed to own all of its walls ## Changelog :cl: fix: Added dehydrator to birdshot kitchen. Surgery theatre now has a surgery tray and surplus prosthetics. An unwired hallway APC is now wired. 1st SM filter is now set to Nitrogen. Chemistry closet in pharmacy now contains extra chemicals to compensate for not having a chemical storage. Atmos air for distro mixer now mixes correctly /:cl: --- _maps/map_files/Birdshot/birdshot.dmm | 83 ++++++++++++++++----------- 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index ed07ca2ba6784..b251d9f463ed6 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -2837,6 +2837,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "bfe" = ( @@ -2858,6 +2859,7 @@ /obj/structure/disposalpipe/junction/flip{ dir = 8 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "bfU" = ( @@ -6737,6 +6739,7 @@ /area/space/nearstation) "cCM" = ( /obj/structure/cable, +/obj/structure/sink/kitchen/directional/east, /turf/open/floor/iron/kitchen/small, /area/station/service/kitchen) "cCP" = ( @@ -10712,15 +10715,12 @@ /turf/open/floor/iron/white, /area/station/medical/medbay/aft) "dZa" = ( -/obj/structure/table/reinforced, /obj/machinery/camera/directional/west, /obj/effect/decal/cleanable/cobweb, -/obj/item/retractor, -/obj/item/hemostat, -/obj/item/cautery, /obj/machinery/camera/autoname/directional/north, /obj/structure/sign/poster/official/random/directional/north, /obj/machinery/status_display/ai/directional/west, +/obj/item/surgery_tray/full/deployed, /turf/open/floor/iron/showroomfloor, /area/station/medical/surgery/theatre) "dZk" = ( @@ -13995,13 +13995,13 @@ /turf/open/floor/iron/small, /area/station/security/office) "fhp" = ( -/obj/structure/table, /obj/effect/spawner/random/food_or_drink/donkpockets{ pixel_y = 6 }, /obj/effect/turf_decal/siding{ dir = 8 }, +/obj/structure/table, /turf/open/floor/iron/dark/textured_large, /area/station/service/kitchen) "fhT" = ( @@ -14979,6 +14979,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "fyZ" = ( @@ -15861,6 +15862,7 @@ dir = 1 }, /obj/machinery/power/apc/auto_name/directional/south, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "fMg" = ( @@ -17874,10 +17876,6 @@ pixel_y = 8 }, /obj/item/clothing/mask/surgical, -/obj/item/surgical_drapes{ - pixel_x = -1; - pixel_y = 4 - }, /obj/machinery/status_display/evac/directional/west, /turf/open/floor/iron/showroomfloor, /area/station/medical/surgery/theatre) @@ -20068,6 +20066,11 @@ name = "Pharmacy Shutters Control"; req_access = list("pharmacy") }, +/obj/item/reagent_containers/cup/bottle/multiver, +/obj/item/reagent_containers/cup/bottle/epinephrine, +/obj/item/reagent_containers/cup/bottle/formaldehyde, +/obj/item/reagent_containers/cup/bottle/acidic_buffer, +/obj/item/reagent_containers/cup/bottle/basic_buffer, /turf/open/floor/iron/dark, /area/station/medical/pharmacy) "hdT" = ( @@ -24186,6 +24189,7 @@ pixel_y = 18 }, /obj/structure/extinguisher_cabinet/directional/east, +/obj/item/circuitboard/mecha/ripley/main, /turf/open/floor/iron/dark, /area/station/science/robotics/lab) "ivC" = ( @@ -25595,6 +25599,16 @@ }, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) +"iPx" = ( +/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ + dir = 1; + filter_type = list(/datum/gas/nitrogen) + }, +/obj/effect/turf_decal/bot{ + dir = 1 + }, +/turf/open/floor/engine, +/area/station/engineering/supermatter/room) "iPy" = ( /obj/structure/cable, /turf/open/floor/iron, @@ -26328,6 +26342,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "jab" = ( @@ -35514,7 +35529,7 @@ "mae" = ( /obj/structure/cable, /turf/closed/wall, -/area/station/service/bar) +/area/station/maintenance/central/greater) "maf" = ( /turf/closed/wall/rust, /area/station/hallway/primary/fore) @@ -40681,6 +40696,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "nSd" = ( @@ -43687,6 +43703,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "oYj" = ( @@ -46106,6 +46123,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron/small, /area/station/hallway/primary/port) "pOQ" = ( @@ -51221,10 +51239,10 @@ pixel_y = 2 }, /obj/item/holosign_creator/robot_seat/restaurant, -/obj/structure/table, /obj/effect/turf_decal/siding{ dir = 9 }, +/obj/structure/table, /turf/open/floor/iron/dark/textured_large, /area/station/service/kitchen) "rya" = ( @@ -52583,7 +52601,7 @@ /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) "rVI" = ( -/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped{ +/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped/inverse{ dir = 8 }, /turf/open/floor/iron, @@ -54601,13 +54619,7 @@ /turf/open/misc/sandy_dirt, /area/station/security/tram) "sGt" = ( -/obj/structure/table/reinforced, -/obj/item/scalpel{ - pixel_y = 12 - }, -/obj/item/blood_filter, -/obj/item/circular_saw, -/obj/item/bonesetter, +/obj/structure/closet/crate/freezer/surplus_limbs, /turf/open/floor/iron/showroomfloor, /area/station/medical/surgery/theatre) "sGE" = ( @@ -61586,6 +61598,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "uQT" = ( @@ -62426,15 +62439,12 @@ /turf/open/floor/iron/smooth_large, /area/station/science/robotics/mechbay) "vfI" = ( -/obj/machinery/microwave{ - pixel_y = 5 - }, /obj/machinery/light_switch/directional/north, /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/structure/table, /obj/effect/turf_decal/siding/end, +/obj/machinery/smartfridge/drying, /turf/open/floor/iron/dark/textured_large, /area/station/service/kitchen) "vfK" = ( @@ -65162,9 +65172,15 @@ /turf/open/floor/iron/dark, /area/station/command/corporate_dock) "vTP" = ( -/obj/structure/sink/kitchen/directional/east, /obj/machinery/firealarm/directional/west, -/turf/open/floor/iron/kitchen/small, +/obj/structure/table, +/obj/machinery/microwave{ + pixel_y = 5 + }, +/obj/effect/turf_decal/siding/end{ + dir = 4 + }, +/turf/open/floor/iron/dark/textured_large, /area/station/service/kitchen) "vTV" = ( /turf/closed/wall/r_wall, @@ -67829,7 +67845,7 @@ /obj/effect/spawner/random/maintenance, /obj/structure/rack, /turf/open/floor/plating, -/area/station/service/bar) +/area/station/maintenance/central/greater) "wKO" = ( /obj/structure/disposalpipe/segment, /obj/machinery/camera/directional/east, @@ -69552,6 +69568,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "xiT" = ( @@ -90216,7 +90233,7 @@ jNV guh cBl fJe -aJb +iPx cay fMB maK @@ -98003,8 +98020,8 @@ xRV jVM xjQ jVM -tGq -tGq +jVM +jVM xmt xmt xmt @@ -100316,7 +100333,7 @@ jVM jVM jVM jVM -vkh +jVM lnD fzw bKO @@ -101344,7 +101361,7 @@ jgb hRc jVM kXC -vkh +jVM dxV jDT fOq @@ -101601,7 +101618,7 @@ vGe xno jVM kXC -vkh +jVM vkh kWF wtw @@ -102115,7 +102132,7 @@ xHD xHD jVM jBu -vkh +jVM vkh vkh vkh From c875e1b797740a9fb942b2517c5be3edbef001e1 Mon Sep 17 00:00:00 2001 From: jimmyl <70376633+mc-oofert@users.noreply.github.com> Date: Thu, 14 Nov 2024 19:51:24 +0100 Subject: [PATCH 070/222] floor lights have the same light range during nightshift (#87786) ## About The Pull Request floor lights have the same light range during nightshifts ## Why It's Good For The Game theyre horrendously bad at lighting up stuff in nightshift and birdshots bar looks horrendous as a result ## Changelog :cl: fix: floor lights have the same light range during nightshift, so you can actually see the bar during a night shift on birdshot /:cl: --- code/modules/power/lighting/light.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/power/lighting/light.dm b/code/modules/power/lighting/light.dm index 3657bb84db83a..a13483e82c5e2 100644 --- a/code/modules/power/lighting/light.dm +++ b/code/modules/power/lighting/light.dm @@ -725,7 +725,7 @@ plane = FLOOR_PLANE light_type = /obj/item/light/bulb fitting = "bulb" - nightshift_brightness = 3 + nightshift_brightness = 4 fire_brightness = 4.5 /obj/machinery/light/floor/get_light_offset() From 2b072515b40696c03209f525b03bd6651cc0cbb6 Mon Sep 17 00:00:00 2001 From: larentoun <31931237+larentoun@users.noreply.github.com> Date: Thu, 14 Nov 2024 21:51:45 +0300 Subject: [PATCH 071/222] Fix flap emote runtimes (#87789) ## About The Pull Request Wingless creatures don't cause runtimes when they flap their imaginery wings ## Why It's Good For The Game Runtimes bad ## Changelog :cl: fix: Fixes a runtime when wingless creature flaps their wings /:cl: --- code/modules/mob/living/emote.dm | 35 ++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index 360d975cb9ed8..3b5c012d591d4 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -140,22 +140,27 @@ /datum/emote/living/flap/run_emote(mob/user, params, type_override, intentional) . = ..() - if(ishuman(user)) - var/mob/living/carbon/human/human_user = user - var/open = FALSE - var/obj/item/organ/wings/functional/wings = human_user.get_organ_slot(ORGAN_SLOT_EXTERNAL_WINGS) - - // open/close functional wings - if(istype(wings)) - if(wings.wings_open) - open = TRUE - wings.close_wings() - else - wings.open_wings() - addtimer(CALLBACK(wings, open ? TYPE_PROC_REF(/obj/item/organ/wings/functional, open_wings) : TYPE_PROC_REF(/obj/item/organ/wings/functional, close_wings)), wing_time) + if(!ishuman(user)) + return + var/mob/living/carbon/human/human_user = user + var/obj/item/organ/wings/wings = human_user.get_organ_slot(ORGAN_SLOT_EXTERNAL_WINGS) - // play a flapping noise if the wing has this implemented - wings.make_flap_sound(human_user) + // play a flapping noise if the wing has this implemented + if(!istype(wings)) + return + wings.make_flap_sound(human_user) + + // open/close functional wings + var/obj/item/organ/wings/functional/wings_functional = wings + if(!istype(wings_functional)) + return + var/open = FALSE + if(wings_functional.wings_open) + open = TRUE + wings_functional.close_wings() + else + wings_functional.open_wings() + addtimer(CALLBACK(wings_functional, open ? TYPE_PROC_REF(/obj/item/organ/wings/functional, open_wings) : TYPE_PROC_REF(/obj/item/organ/wings/functional, close_wings)), wing_time) /datum/emote/living/flap/aflap key = "aflap" From 1df5339db06f6d439206ddbc6d5c94bcce747efe Mon Sep 17 00:00:00 2001 From: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Date: Fri, 15 Nov 2024 00:22:04 +0530 Subject: [PATCH 072/222] Fixes storage & evidence bag pre attack (#87793) ## About The Pull Request - Fixes #87788 Usually when you force move an item anywhere `obj/item/doMove()` is responsible for removing the item from the players hand & updating the visuals. When you move that item from say your pocket to your hand we call `attempt_pickup()` which also updates visuals. The one case where these 2 procs don't help is when that item is equipped from anywhere else but the hand(pockets for e.g) into a storage medium that is held in hand. For this edge case we have to drop the item to ground to update the visuals of whatever inventory slot it was attached to Now evidence bag uses the storage pre attack mode rather than implementing its own item interaction thus fixing the visual glitch not just for it but for all items that have `allow_quick_gather = TRUE` ## Changelog :cl: fix: Fixed visual glitches when inserting items from an slot other than the hands into evidence bags & other storages that have quick gather mode enabled /:cl: --- code/datums/storage/storage.dm | 4 +++- code/modules/detectivework/evidence.dm | 17 +++++------------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index 96233e59405b9..856c1204c720f 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -693,10 +693,12 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /datum/storage/proc/on_preattack(datum/source, obj/item/thing, mob/user, params) SIGNAL_HANDLER - if(!istype(thing) || !allow_quick_gather || thing.atom_storage) + if(!istype(thing) || thing == parent.loc || !allow_quick_gather || thing.atom_storage) return if(collection_mode == COLLECT_ONE) + if(thing.loc == user) + user.dropItemToGround(thing, silent = TRUE) //this is nessassary to update any inventory slot it is attached to attempt_insert(thing, user) return COMPONENT_CANCEL_ATTACK_CHAIN diff --git a/code/modules/detectivework/evidence.dm b/code/modules/detectivework/evidence.dm index c81852958b4a8..59e2f0feb86b1 100644 --- a/code/modules/detectivework/evidence.dm +++ b/code/modules/detectivework/evidence.dm @@ -18,23 +18,13 @@ max_slots = 1, max_specific_storage = WEIGHT_CLASS_NORMAL, ) + atom_storage.allow_quick_gather = TRUE + atom_storage.collection_mode = COLLECT_ONE RegisterSignal(atom_storage, COMSIG_STORAGE_STORED_ITEM, PROC_REF(on_insert)) RegisterSignal(atom_storage, COMSIG_STORAGE_REMOVED_ITEM, PROC_REF(on_remove)) atom_storage.rustle_sound = 'sound/items/evidence_bag/evidence_bag_zip.ogg' atom_storage.remove_rustle_sound = 'sound/items/evidence_bag/evidence_bag_unzip.ogg' -/obj/item/evidencebag/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) - if(interacting_with == loc || !isitem(interacting_with) || HAS_TRAIT(interacting_with, TRAIT_COMBAT_MODE_SKIP_INTERACTION)) - return NONE - if(atom_storage.attempt_insert(interacting_with, user)) - return ITEM_INTERACT_SUCCESS - return NONE - -/obj/item/evidencebag/item_interaction(mob/living/user, obj/item/tool, list/modifiers) - if(atom_storage.attempt_insert(tool, user)) - return ITEM_INTERACT_SUCCESS - return NONE - /obj/item/evidencebag/update_desc(updates) . = ..() if(!atom_storage.get_total_weight()) @@ -65,12 +55,15 @@ /obj/item/evidencebag/proc/on_insert(datum/storage/storage, obj/item/to_insert, mob/user, force) SIGNAL_HANDLER + update_weight_class(to_insert.w_class) /obj/item/evidencebag/proc/on_remove(datum/storage/storage, obj/item/to_remove, atom/remove_to_loc, silent) SIGNAL_HANDLER + if(!atom_storage.get_total_weight()) return + update_weight_class(WEIGHT_CLASS_TINY) /obj/item/evidencebag/attack_self(mob/user) From 9bc094ed7cc3dbe6c1ddaafa9fe4cb527d0a7193 Mon Sep 17 00:00:00 2001 From: Time-Green <7501474+Time-Green@users.noreply.github.com> Date: Thu, 14 Nov 2024 19:52:23 +0100 Subject: [PATCH 073/222] Fixes nooartrium having no downsides (#87798) Having a non-organic heart ignored the heart damage, so you could just be immortal forever :cl: fix: Nooartrium heart damage can no longer be bypassed with non-organic hearts /:cl: Balance maybe? I don't feel this was ever intended and an oversight in not setting the correct flag --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> --- .../reagents/impure_reagents/impure_medicine_reagents.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm index b8a2250722534..ebd392f536892 100644 --- a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm @@ -480,6 +480,7 @@ Basically, we fill the time between now and 2s from now with hands based off the overdose_threshold = 20 self_consuming = TRUE //No pesky liver shenanigans chemical_flags = REAGENT_DONOTSPLIT | REAGENT_DEAD_PROCESS + affected_organ_flags = NONE ///If we brought someone back from the dead var/back_from_the_dead = FALSE /// List of trait buffs to give to the affected mob, and remove as needed. From a2c1e27105b5bfc7c9e1b746b1281f7d9d1a57e0 Mon Sep 17 00:00:00 2001 From: carlarctg <53100513+carlarctg@users.noreply.github.com> Date: Thu, 14 Nov 2024 15:53:29 -0300 Subject: [PATCH 074/222] cuffsnapping is on right click (#87634) ## About The Pull Request title ## Why It's Good For The Game OOC: Blard of Jard: I was trying to cut a cargo tech's leg off for a spy bounty, but instead of just cutting his leg with it targetted on harm intent, it immediately cut his ties and he mag dumped me with his laz gun. ## Changelog :cl: fix: you now snip cuffs with right click to prevent accidental cuts /:cl: --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> --- code/datums/elements/cuffsnapping.dm | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/code/datums/elements/cuffsnapping.dm b/code/datums/elements/cuffsnapping.dm index df445f4acc971..1abdc4a7a6bd2 100644 --- a/code/datums/elements/cuffsnapping.dm +++ b/code/datums/elements/cuffsnapping.dm @@ -42,13 +42,20 @@ src.snap_time_strong = snap_time_strong RegisterSignal(target, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) - RegisterSignal(target, COMSIG_ITEM_ATTACK , PROC_REF(try_cuffsnap_target)) + RegisterSignal(target, COMSIG_ITEM_ATTACK_SECONDARY, PROC_REF(try_cuffsnap_target)) + RegisterSignal(target, COMSIG_ITEM_REQUESTING_CONTEXT_FOR_TARGET, PROC_REF(add_item_context)) /datum/element/cuffsnapping/Detach(datum/target) - UnregisterSignal(target, list(COMSIG_ITEM_ATTACK, COMSIG_ATOM_EXAMINE)) - + UnregisterSignal(target, list(COMSIG_ITEM_ATTACK_SECONDARY, COMSIG_ATOM_EXAMINE, COMSIG_ITEM_REQUESTING_CONTEXT_FOR_TARGET)) return ..() +/datum/element/cuffsnapping/proc/add_item_context(obj/item/source, list/context, mob/living/carbon/target, mob/living/user) + SIGNAL_HANDLER + if(!iscarbon(target) || !target.handcuffed) + return NONE + context[SCREENTIP_CONTEXT_RMB] = "Cut Restraints" + return CONTEXTUAL_SCREENTIP_SET + ///signal called on parent being examined /datum/element/cuffsnapping/proc/on_examine(datum/target, mob/user, list/examine_list) SIGNAL_HANDLER @@ -56,7 +63,7 @@ var/examine_string if(isnull(snap_time_weak)) return - examine_string = "It looks like it could cut zipties or cable restraints off someone in [snap_time_weak] seconds" + examine_string = "It looks like it could be used to cut zipties or cable restraints off someone in [snap_time_weak] seconds" if(!isnull(snap_time_strong)) examine_string += ", and handcuffs in [snap_time_strong] seconds." @@ -65,7 +72,7 @@ examine_list += span_notice(examine_string) -/datum/element/cuffsnapping/proc/try_cuffsnap_target(obj/item/cutter, mob/living/carbon/target, mob/cutter_user, params) +/datum/element/cuffsnapping/proc/try_cuffsnap_target(obj/item/cutter, mob/living/carbon/target, mob/living/cutter_user, params) SIGNAL_HANDLER if(!istype(target)) //we aren't the kind of mob that can even have cuffs, so we skip. From 97cd0ea5fbbaab1933ef1c97b823a6cc5ba8715e Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Thu, 14 Nov 2024 19:53:57 +0100 Subject: [PATCH 075/222] Guncode Agony 4.1: Portal Intermission (#87803) ## About The Pull Request Closes #75447 by allowing projectiles to pass through portals. This does not allow for infinite loops for sanity (including host's) reasons. Can safely be merged before #87740 ## Changelog :cl: fix: Many years later, projectiles finally can pass through portals - this time without crashing the server. /:cl: --- code/game/objects/effects/portals.dm | 32 +++++++++++-------- code/modules/events/wormholes.dm | 2 +- .../mining/equipment/wormhole_jaunter.dm | 2 +- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index 18f633504264f..21a51ba9bcb42 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -130,29 +130,35 @@ linked = null return ..() -/obj/effect/portal/attack_ghost(mob/dead/observer/O) - if(!teleport(O, TRUE)) +/obj/effect/portal/attack_ghost(mob/dead/observer/ghost) + if(!teleport(ghost, force = TRUE)) return ..() + return BULLET_ACT_FORCE_PIERCE -/obj/effect/portal/proc/teleport(atom/movable/M, force = FALSE) - if(!force && (!istype(M) || iseffect(M) || (ismecha(M) && !mech_sized) || (!isobj(M) && !ismob(M)))) //Things that shouldn't teleport. +/obj/effect/portal/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit) + if (!teleport(hitting_projectile, force = TRUE)) + return ..() + return BULLET_ACT_FORCE_PIERCE + +/obj/effect/portal/proc/teleport(atom/movable/moving, force = FALSE) + if(!force && (!istype(moving) || iseffect(moving) || (ismecha(moving) && !mech_sized) || (!isobj(moving) && !ismob(moving)))) //Things that shouldn't teleport. return var/turf/real_target = get_link_target_turf() if(!istype(real_target)) return FALSE - if(!force && (!ismecha(M) && !isprojectile(M) && M.anchored && !allow_anchored)) + if(!force && (!ismecha(moving) && !isprojectile(moving) && moving.anchored && !allow_anchored)) return var/no_effect = FALSE if(last_effect == world.time || sparkless) no_effect = TRUE else last_effect = world.time - var/turf/start_turf = get_turf(M) - if(do_teleport(M, real_target, innate_accuracy_penalty, no_effects = no_effect, channel = teleport_channel, forced = force_teleport)) - if(isprojectile(M)) - var/obj/projectile/P = M + var/turf/start_turf = get_turf(moving) + if(do_teleport(moving, real_target, innate_accuracy_penalty, no_effects = no_effect, channel = teleport_channel, forced = force_teleport)) + if(isprojectile(moving)) + var/obj/projectile/P = moving P.ignore_source_check = TRUE - new /obj/effect/temp_visual/portal_animation(start_turf, src, M) + new /obj/effect/temp_visual/portal_animation(start_turf, src, moving) playsound(start_turf, SFX_PORTAL_ENTER, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) playsound(real_target, SFX_PORTAL_ENTER, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) return TRUE @@ -189,7 +195,7 @@ linked = P break -/obj/effect/portal/permanent/teleport(atom/movable/M, force = FALSE) +/obj/effect/portal/permanent/teleport(atom/movable/moving, force = FALSE) set_linked() // update portal links . = ..() @@ -213,9 +219,9 @@ name = "one-use portal" desc = "This is probably the worst decision you'll ever make in your life." -/obj/effect/portal/permanent/one_way/one_use/teleport(atom/movable/M, force = FALSE) +/obj/effect/portal/permanent/one_way/one_use/teleport(atom/movable/moving, force = FALSE) . = ..() - if (. && !isdead(M)) + if (. && !isdead(moving)) expire() /** diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm index 83028d129c4a8..5db33818d1276 100644 --- a/code/modules/events/wormholes.dm +++ b/code/modules/events/wormholes.dm @@ -65,7 +65,7 @@ GLOBAL_LIST_EMPTY(all_wormholes) // So we can pick wormholes to teleport to . = ..() GLOB.all_wormholes -= src -/obj/effect/portal/wormhole/teleport(atom/movable/M) +/obj/effect/portal/wormhole/teleport(atom/movable/M, force = FALSE) if(iseffect(M)) //sparks don't teleport return if(M.anchored) diff --git a/code/modules/mining/equipment/wormhole_jaunter.dm b/code/modules/mining/equipment/wormhole_jaunter.dm index 6ffcfa7bc6752..fa9b63a4658a7 100644 --- a/code/modules/mining/equipment/wormhole_jaunter.dm +++ b/code/modules/mining/equipment/wormhole_jaunter.dm @@ -103,7 +103,7 @@ light_on = FALSE wibbles = FALSE -/obj/effect/portal/jaunt_tunnel/teleport(atom/movable/M) +/obj/effect/portal/jaunt_tunnel/teleport(atom/movable/M, force = FALSE) . = ..() if(.) // KERPLUNK From b46fbe3b49abd22ef12a86f4e0edd842d2c6c800 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:54:53 +0000 Subject: [PATCH 076/222] Automatic changelog for PR #87785 [ci skip] --- html/changelogs/AutoChangeLog-pr-87785.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87785.yml diff --git a/html/changelogs/AutoChangeLog-pr-87785.yml b/html/changelogs/AutoChangeLog-pr-87785.yml new file mode 100644 index 0000000000000..d7bd7a8c9401f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87785.yml @@ -0,0 +1,4 @@ +author: "mc-oofert" +delete-after: True +changes: + - bugfix: "Added dehydrator to birdshot kitchen. Surgery theatre now has a surgery tray and surplus prosthetics. An unwired hallway APC is now wired. 1st SM filter is now set to Nitrogen. Chemistry closet in pharmacy now contains extra chemicals to compensate for not having a chemical storage. Atmos air for distro mixer now mixes correctly" \ No newline at end of file From 02f1241ea07ec696d620184dafc9f73853e04a73 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:54:58 +0000 Subject: [PATCH 077/222] Automatic changelog for PR #87789 [ci skip] --- html/changelogs/AutoChangeLog-pr-87789.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87789.yml diff --git a/html/changelogs/AutoChangeLog-pr-87789.yml b/html/changelogs/AutoChangeLog-pr-87789.yml new file mode 100644 index 0000000000000..062e7ea55b11e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87789.yml @@ -0,0 +1,4 @@ +author: "larentoun" +delete-after: True +changes: + - bugfix: "Fixes a runtime when wingless creature flaps their wings" \ No newline at end of file From ced06906e46f89cedf80fba15625a464f12fb8bf Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:54:59 +0000 Subject: [PATCH 078/222] Automatic changelog for PR #87798 [ci skip] --- html/changelogs/AutoChangeLog-pr-87798.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87798.yml diff --git a/html/changelogs/AutoChangeLog-pr-87798.yml b/html/changelogs/AutoChangeLog-pr-87798.yml new file mode 100644 index 0000000000000..0e94f42326a72 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87798.yml @@ -0,0 +1,4 @@ +author: "Time-Green" +delete-after: True +changes: + - bugfix: "Nooartrium heart damage can no longer be bypassed with non-organic hearts" \ No newline at end of file From 3e14fcd5af409520fcb407dc10a06b63871ed116 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:55:01 +0000 Subject: [PATCH 079/222] Automatic changelog for PR #87793 [ci skip] --- html/changelogs/AutoChangeLog-pr-87793.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87793.yml diff --git a/html/changelogs/AutoChangeLog-pr-87793.yml b/html/changelogs/AutoChangeLog-pr-87793.yml new file mode 100644 index 0000000000000..258030b1226f2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87793.yml @@ -0,0 +1,4 @@ +author: "SyncIt21" +delete-after: True +changes: + - bugfix: "Fixed visual glitches when inserting items from an slot other than the hands into evidence bags & other storages that have quick gather mode enabled" \ No newline at end of file From c0c5c92a185d55c117a01c9112d60e8072ca4c55 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:55:09 +0000 Subject: [PATCH 080/222] Automatic changelog for PR #87634 [ci skip] --- html/changelogs/AutoChangeLog-pr-87634.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87634.yml diff --git a/html/changelogs/AutoChangeLog-pr-87634.yml b/html/changelogs/AutoChangeLog-pr-87634.yml new file mode 100644 index 0000000000000..8d8e95fdf1f5c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87634.yml @@ -0,0 +1,4 @@ +author: "carlarctg" +delete-after: True +changes: + - bugfix: "you now snip cuffs with right click to prevent accidental cuts" \ No newline at end of file From 01978387f5f2fd38a7167199f0d480a233266e14 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:55:15 +0000 Subject: [PATCH 081/222] Automatic changelog for PR #87803 [ci skip] --- html/changelogs/AutoChangeLog-pr-87803.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87803.yml diff --git a/html/changelogs/AutoChangeLog-pr-87803.yml b/html/changelogs/AutoChangeLog-pr-87803.yml new file mode 100644 index 0000000000000..e9f054ddbc26c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87803.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Many years later, projectiles finally can pass through portals - this time without crashing the server." \ No newline at end of file From f38061b728fd6f06b6d1288073c3143065fa287b Mon Sep 17 00:00:00 2001 From: Koi <168238458+GremlinSeeker@users.noreply.github.com> Date: Thu, 14 Nov 2024 12:55:19 -0600 Subject: [PATCH 082/222] [NO GBP] Syndicate Biodome Fixes (#87792) ## About The Pull Request Fixed cheesing by monkeyification by changing the gorillas factions to hostile. Tweaked the loot to be consistent and nerfed slightly (Makarovs instead of APS) Also changed one of the observation cells to a cytology room with a clown glutton ![image](https://github.com/user-attachments/assets/2b3f5ea0-75ea-42f1-98f7-50b7ebd60b04) ![image](https://github.com/user-attachments/assets/9d700be2-7108-4d7a-90f9-7a8f19737879) ## Why It's Good For The Game It fixes stuff and prevents cheese. ## Changelog :cl: fix: Syndicate Biodome fixes /:cl: --- .../icemoon_underground_syndidome.dmm | 241 ++++++++++-------- .../basic/farm_animals/gorilla/gorilla.dm | 13 + 2 files changed, 149 insertions(+), 105 deletions(-) diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm index e2b11a02964eb..228c55292fbb0 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm @@ -90,6 +90,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) +"bp" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/structure/cable/layer3, +/turf/open/floor/catwalk_floor/iron_dark, +/area/ruin/syndibiodome) "bu" = ( /obj/effect/turf_decal/siding/wood, /obj/structure/table/wood, @@ -216,9 +223,15 @@ /obj/effect/turf_decal/siding/wideplating/dark{ dir = 5 }, -/obj/machinery/smartfridge/organ, -/obj/item/organ/alien/resinspinner, -/obj/item/organ/eyes/night_vision, +/obj/structure/table/reinforced/plastitaniumglass, +/obj/item/clothing/gloves/latex/coroner{ + pixel_x = -1; + pixel_y = 8 + }, +/obj/item/clothing/mask/surgical{ + pixel_x = 6; + pixel_y = 10 + }, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) "cE" = ( @@ -498,9 +511,10 @@ /obj/effect/decal/cleanable/blood/gibs/down, /turf/open/floor/iron/cafeteria, /area/ruin/syndibiodome) -"gX" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/warm/directional/west, +"gZ" = ( +/obj/machinery/door/airlock/maintenance_hatch, +/obj/structure/cable/layer1, +/obj/structure/cable, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) "ha" = ( @@ -509,10 +523,10 @@ /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/noteleport) "he" = ( -/mob/living/basic/gorilla/genetics, /obj/effect/turf_decal/siding/wood/corner{ dir = 1 }, +/mob/living/basic/gorilla/hostile, /turf/open/floor/wood, /area/ruin/syndibiodome) "hf" = ( @@ -527,8 +541,8 @@ /turf/open/floor/iron/dark, /area/ruin/syndibiodome) "hm" = ( -/mob/living/basic/gorilla/genetics, /obj/effect/decal/cleanable/dirt/dust, +/mob/living/basic/gorilla/hostile, /turf/open/floor/iron/dark/small, /area/ruin/syndibiodome) "hr" = ( @@ -639,14 +653,12 @@ }, /turf/open/floor/iron/dark/herringbone, /area/ruin/syndibiodome) -"iq" = ( -/obj/structure/flora/rock/pile/style_random, -/mob/living/carbon/human/species/monkey/angry, -/turf/open/floor/grass, -/area/ruin/syndibiodome) "ir" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/dim/directional/east, +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/structure/cable/layer3, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) "iG" = ( @@ -723,16 +735,6 @@ }, /obj/effect/decal/cleanable/blood/drip, /obj/effect/decal/cleanable/dirt, -/obj/structure/table/reinforced/plastitaniumglass, -/obj/item/surgery_tray/full, -/obj/item/clothing/gloves/latex/coroner{ - pixel_x = -1; - pixel_y = 8 - }, -/obj/item/clothing/mask/surgical{ - pixel_x = 6; - pixel_y = 10 - }, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) "jd" = ( @@ -771,9 +773,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) -"jQ" = ( -/turf/closed/indestructible/syndicate/nodiagonal, -/area/icemoon/surface/outdoors/noteleport) "jR" = ( /obj/effect/decal/cleanable/blood/trails{ dir = 4 @@ -1025,9 +1024,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) -"mK" = ( -/turf/open/misc/asteroid/snow/icemoon, -/area/ruin/syndibiodome) "mV" = ( /obj/effect/turf_decal/siding/wideplating/dark, /obj/effect/decal/cleanable/dirt/dust, @@ -1040,6 +1036,9 @@ "mW" = ( /obj/effect/spawner/random/trash, /obj/effect/decal/cleanable/dirt, +/obj/structure/cable/layer3, +/obj/structure/cable/layer1, +/obj/structure/cable, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) "mZ" = ( @@ -1113,6 +1112,13 @@ /obj/effect/turf_decal/trimline/dark_red/line, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) +"on" = ( +/obj/machinery/door/airlock/maintenance_hatch, +/obj/structure/cable/layer3, +/obj/structure/cable/layer1, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/ruin/syndibiodome) "oq" = ( /obj/effect/decal/cleanable/blood/trails{ dir = 10 @@ -1147,7 +1153,7 @@ /obj/machinery/light/warm/directional/west, /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/dirt, -/mob/living/basic/gorilla/genetics, +/mob/living/basic/gorilla/hostile, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) "oH" = ( @@ -1346,7 +1352,6 @@ /obj/effect/turf_decal/siding/wideplating/dark{ dir = 1 }, -/mob/living/carbon/human/species/monkey/angry, /obj/machinery/light/warm/directional/north, /obj/machinery/digital_clock/directional/north, /obj/effect/decal/cleanable/dirt, @@ -1354,8 +1359,8 @@ /area/ruin/syndibiodome) "rQ" = ( /obj/effect/decal/cleanable/dirt, -/mob/living/basic/gorilla/genetics, /obj/effect/decal/cleanable/dirt/dust, +/mob/living/basic/gorilla/hostile, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) "rX" = ( @@ -1434,7 +1439,6 @@ }, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt/dust, -/obj/effect/mapping_helpers/broken_machine, /turf/open/floor/iron/dark/herringbone, /area/ruin/syndibiodome) "td" = ( @@ -1701,12 +1705,20 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) +"vH" = ( +/obj/effect/spawner/random/trash, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/structure/cable/layer3, +/turf/open/floor/catwalk_floor/iron_dark, +/area/ruin/syndibiodome) "vJ" = ( /obj/effect/decal/cleanable/dirt, -/mob/living/basic/gorilla/genetics, /obj/effect/turf_decal/trimline/purple/corner, /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/dirt, +/mob/living/basic/gorilla/hostile, /turf/open/floor/iron/dark/herringbone, /area/ruin/syndibiodome) "vK" = ( @@ -1959,7 +1971,6 @@ /obj/effect/turf_decal/trimline/dark/line{ dir = 1 }, -/mob/living/carbon/human/species/monkey/angry, /obj/effect/turf_decal/siding/wideplating/dark{ dir = 1 }, @@ -2100,7 +2111,6 @@ /turf/open/floor/grass, /area/ruin/syndibiodome) "yU" = ( -/mob/living/carbon/human/species/monkey/angry, /obj/effect/turf_decal/weather/dirt{ dir = 9 }, @@ -2235,6 +2245,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) +"Az" = ( +/obj/machinery/door/airlock/maintenance_hatch, +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/structure/cable/layer3, +/turf/open/floor/catwalk_floor/iron_dark, +/area/ruin/syndibiodome) "AA" = ( /obj/effect/turf_decal/siding/wideplating/dark{ dir = 5 @@ -2262,9 +2279,9 @@ /obj/effect/decal/cleanable/dirt/dust, /obj/item/storage/belt/security/webbing, /obj/item/storage/toolbox/syndicate, -/obj/item/gun/ballistic/automatic/pistol, -/obj/item/ammo_box/magazine/m10mm, -/obj/item/ammo_box/magazine/m10mm, +/obj/item/gun/ballistic/automatic/pistol/contraband, +/obj/item/ammo_box/magazine/m9mm, +/obj/item/ammo_box/magazine/m9mm, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) "Ba" = ( @@ -2496,7 +2513,6 @@ /turf/open/floor/iron/white/small, /area/ruin/syndibiodome) "EE" = ( -/mob/living/carbon/human/species/monkey/angry, /obj/effect/decal/cleanable/blood/trails{ dir = 1 }, @@ -2727,7 +2743,6 @@ "Hs" = ( /obj/structure/flora/bush/flowers_br/style_3, /obj/structure/flora/bush/flowers_yw/style_3, -/mob/living/carbon/human/species/monkey/angry, /obj/effect/gibspawner/human/bodypartless, /obj/effect/mob_spawn/corpse/human/syndicatecommando/lessenedgear, /turf/open/floor/grass, @@ -2810,6 +2825,14 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) +"Iq" = ( +/obj/machinery/light/small/dim/directional/west, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/layer3, +/obj/structure/cable/layer1, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/ruin/syndibiodome) "IF" = ( /obj/effect/mob_spawn/corpse/human/syndicatecommando/lessenedgear, /obj/effect/turf_decal/siding/wideplating/dark/end{ @@ -2947,6 +2970,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark/herringbone, /area/ruin/syndibiodome) +"Kl" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/layer3, +/obj/structure/cable/layer1, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/ruin/syndibiodome) "Kn" = ( /obj/effect/decal/cleanable/blood/footprints{ dir = 2 @@ -3087,6 +3117,9 @@ "LA" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/dim/directional/west, +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/structure/cable/layer3, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) "LB" = ( @@ -3192,6 +3225,8 @@ /turf/open/floor/iron/cafeteria, /area/ruin/syndibiodome) "Mr" = ( +/obj/machinery/light/warm/directional/west, +/obj/effect/decal/cleanable/dirt, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) "Mt" = ( @@ -3266,7 +3301,6 @@ /obj/effect/turf_decal/siding/wideplating/dark{ dir = 1 }, -/mob/living/carbon/human/species/monkey/angry, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/trimline/dark/line, /obj/effect/decal/cleanable/dirt/dust, @@ -3348,7 +3382,7 @@ /obj/effect/turf_decal/weather/dirt{ dir = 6 }, -/mob/living/basic/gorilla/genetics, +/mob/living/basic/gorilla/hostile, /turf/open/floor/grass, /area/ruin/syndibiodome) "NN" = ( @@ -3364,7 +3398,6 @@ /obj/effect/turf_decal/siding/wideplating/dark{ dir = 6 }, -/obj/effect/gibspawner/generic, /obj/machinery/digital_clock/directional/east, /obj/effect/decal/cleanable/dirt, /turf/open/floor/mineral/plastitanium/red, @@ -3379,11 +3412,8 @@ /turf/open/floor/iron/dark, /area/ruin/syndibiodome) "Os" = ( -/obj/structure/bodycontainer/morgue/beeper_off{ - dir = 8 - }, /obj/effect/turf_decal/trimline/tram/filled, -/turf/open/floor/pod/dark, +/turf/closed/indestructible/syndicate/nodiagonal, /area/ruin/syndibiodome) "Oy" = ( /obj/effect/spawner/structure/window/reinforced/plasma/plastitanium, @@ -3392,13 +3422,6 @@ }, /turf/open/floor/plating, /area/ruin/syndibiodome) -"OD" = ( -/mob/living/carbon/human/species/monkey/angry, -/obj/effect/turf_decal/weather/dirt{ - dir = 6 - }, -/turf/open/floor/grass, -/area/ruin/syndibiodome) "OH" = ( /obj/effect/decal/cleanable/blood/trails{ dir = 8 @@ -3428,8 +3451,8 @@ /obj/machinery/light/warm/directional/east, /obj/item/storage/belt/security/webbing, /obj/item/gun/ballistic/automatic/pistol/contraband, -/obj/item/ammo_box/magazine/m10mm, -/obj/item/ammo_box/magazine/m10mm, +/obj/item/ammo_box/magazine/m9mm, +/obj/item/ammo_box/magazine/m9mm, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) "OM" = ( @@ -3446,6 +3469,9 @@ "ON" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/dim/directional/south, +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/structure/cable/layer3, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) "OO" = ( @@ -3640,7 +3666,6 @@ /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) "RK" = ( -/mob/living/carbon/human/species/monkey/angry, /obj/structure/chair/office/tactical{ dir = 4 }, @@ -3659,8 +3684,9 @@ /area/icemoon/surface/outdoors/noteleport) "RX" = ( /obj/effect/turf_decal/siding/wideplating/dark, -/mob/living/basic/gorilla/genetics, /obj/effect/decal/cleanable/dirt, +/obj/effect/gibspawner/generic, +/mob/living/basic/gorilla/hostile, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) "Se" = ( @@ -3823,6 +3849,10 @@ dir = 1 }, /area/ruin/syndibiodome) +"To" = ( +/obj/machinery/door/airlock/maintenance_hatch, +/turf/open/floor/iron/dark, +/area/ruin/syndibiodome) "Tu" = ( /obj/structure/table/reinforced/plastitaniumglass, /obj/effect/turf_decal/siding/wideplating/dark{ @@ -3897,6 +3927,7 @@ /obj/item/stack/sheet/mineral/uranium/five, /obj/item/stack/sheet/mineral/uranium/five, /obj/effect/decal/cleanable/dirt, +/obj/machinery/light/warm/directional/east, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) "TL" = ( @@ -3971,12 +4002,12 @@ /turf/open/floor/iron/dark/small, /area/ruin/syndibiodome) "Ux" = ( -/mob/living/basic/gorilla/genetics, /obj/effect/gibspawner/human/bodypartless, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/trimline/blue/corner{ dir = 4 }, +/mob/living/basic/gorilla/hostile, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) "Uz" = ( @@ -4223,8 +4254,8 @@ /obj/effect/decal/cleanable/blood/tracks{ dir = 4 }, -/mob/living/basic/gorilla/genetics, /obj/effect/decal/cleanable/dirt, +/mob/living/basic/gorilla/hostile, /turf/open/floor/iron/dark/herringbone, /area/ruin/syndibiodome) "XG" = ( @@ -4362,13 +4393,13 @@ /area/ruin/syndibiodome) "YZ" = ( /obj/effect/turf_decal/siding/wideplating/dark, -/mob/living/basic/gorilla/genetics, /obj/structure/fluff/fake_vent, /obj/effect/decal/cleanable/blood/trails{ dir = 1 }, /obj/effect/decal/cleanable/dirt, /obj/effect/gibspawner/human/bodypartless, +/mob/living/basic/gorilla/hostile, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) "Zd" = ( @@ -4690,7 +4721,7 @@ oq Mc zM zM -mK +ys ys ys tL @@ -4727,8 +4758,8 @@ ck ys ys zM -Ut -vx +Kl +on xi kw wL @@ -4820,8 +4851,8 @@ jS ys ys zM -Ut -Ut +Kl +Kl zM Sr zM @@ -4867,7 +4898,7 @@ pg pg zM zM -Ut +Kl zM zM Ab @@ -4914,7 +4945,7 @@ zd ys zM Db -Ut +Kl zM kK MB @@ -4961,7 +4992,7 @@ pg pg zM ic -Ut +Kl zM rK YZ @@ -5008,7 +5039,7 @@ uD ys zM wY -Ut +Kl zM cB ja @@ -5102,10 +5133,10 @@ AI ys ys zM -Ut -Ut -zM -zM +Kl +Kl +Iq +Ro zM zM zM @@ -5151,8 +5182,8 @@ Hi zM zM Ut -LA -Ro +Kl +Ut zM qN qU @@ -5198,10 +5229,10 @@ ys ys zM zM -Ut -Ut -Ut -vx +Kl +Kl +Kl +gZ je kt XC @@ -5582,7 +5613,7 @@ Fl qN IU vu -iq +MH YD Fp xz @@ -5664,13 +5695,13 @@ ys ck zM zM -mW -Ut +vH +bp ir -Ut -Ut -Ut -vx +bp +bp +bp +Az kw Eq CV @@ -5711,7 +5742,7 @@ ys ys zM MP -Ut +bp zM zM Ut @@ -5758,7 +5789,7 @@ ys ys zM qa -Ut +bp zM zM dS @@ -5805,7 +5836,7 @@ ys zM zM Sv -Ut +bp zM wx RH @@ -5852,7 +5883,7 @@ zM zM rZ Ut -Ut +bp zM Ra RX @@ -5899,7 +5930,7 @@ zM zM zM zM -Ut +bp zM Pw Oi @@ -5993,12 +6024,12 @@ Uc qp sR zM -Ut -Ut +bp +bp LA -mW -Ut -vx +vH +bp +Az Nt uW Vv @@ -6049,7 +6080,7 @@ qN pY XC XC -qN +To Ut zM Vj @@ -6060,7 +6091,7 @@ XE Mt WB iX -OD +cN zM ys uD @@ -6188,8 +6219,8 @@ zM zM zM zM -Vv zM +To zM LU qN @@ -6235,8 +6266,8 @@ zM ek Dc zM -zM -zM +Mr +Ut Mr Ut qN @@ -6283,7 +6314,7 @@ MM bu zM Kz -gX +Ut Ut Ut zM @@ -6428,7 +6459,7 @@ zM zM zM ys -jQ +zM zM zM zM diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm index 363243a283388..7e572c2d92f63 100644 --- a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -177,6 +177,19 @@ paralyze_chance = 0 initial_size = 0.9 +/mob/living/basic/gorilla/hostile + name = "Feral Gorilla" + maxHealth = 180 + health = 180 + desc = "A gorilla created via \"advanced genetic science\". While not quite as strong as their wildborne brethren, this simian still packs a punch." + melee_damage_lower = 15 + melee_damage_upper = 18 + obj_damage = 25 + speed = 0.1 + paralyze_chance = 0 + initial_size = 0.9 + faction = list(FACTION_HOSTILE) + /mob/living/basic/gorilla/genetics/Initialize(mapload) . = ..() qdel(GetComponent(/datum/component/amputating_limbs)) From f176ef87b52107432425d570a21c1c13b52cd918 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:55:42 +0000 Subject: [PATCH 083/222] Automatic changelog for PR #87792 [ci skip] --- html/changelogs/AutoChangeLog-pr-87792.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87792.yml diff --git a/html/changelogs/AutoChangeLog-pr-87792.yml b/html/changelogs/AutoChangeLog-pr-87792.yml new file mode 100644 index 0000000000000..e8ff0af1935b3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87792.yml @@ -0,0 +1,4 @@ +author: "GremlinSeeker" +delete-after: True +changes: + - bugfix: "Syndicate Biodome fixes" \ No newline at end of file From 31459b4883a03059d21b8ce7f12a78876a43c4d7 Mon Sep 17 00:00:00 2001 From: carlarctg <53100513+carlarctg@users.noreply.github.com> Date: Thu, 14 Nov 2024 15:56:30 -0300 Subject: [PATCH 084/222] Buffs the Anomalock modules (#87743) ## About The Pull Request Significantly buffed the anomalock modules. Anomalock modules can be used with eachother. Antigravity module costs 2 complexity. Teleporter module is thrice as fast at teleporting with a slightly reduced cooldown, but has a much larger power cost. Changed how teleporter tracks maximum range to be less painful to the end user. Kinesis module's default range has been extended to 8. Kinesis module can drag around people in critical condition or worse. ## Why It's Good For The Game These modules have historically been, well, kind of a complete joke. They seem to have been crippled out of fear of them being overpowering with the end result of being unusable. Anomaly items are allowed and meant to be fun, strong, and wild, so I really don't see why these need to be so weak. The amount of times I'd rather make a teleporter that takes 3 seconds to get you anywhere instead of an instant portal gun or a bag of holding is roughly zero. People hate modsuits, and in part that hate is because of modules which do very, very little due to severe undertuning. Let's fix that with the anomaly ones here. > Anomalock modules can be used with eachother. Let people get a buncha anomaly modulse together if they want to. An antigravity user with teleporting and kinesis could be something to fear, but not so much as to strike it from existence altogether without even letting people mess around with it first. > Antigravity module costs 2 complexity. Antigravity module is glorified wittel -> gravitum, but it takes a core and 3 complexity. At least let it be somewhat cheap. > Teleporter module is thrice as fast at teleporting with a slightly reduced cooldown, but has a much larger power cost. Teleporter module is a big damn joke ATM, as stated above being effectively overshadowed in every way by the portal gun. This now gives it a fun niche instead, of being able to teleport around everywhere at the cost of a massive power draw. > Changed how teleporter tracks maximum range to be less painful to the end user. view() was working weirdly when I was using it. It was failing to register tiles somewhat near the end of the screen, so I just ditched it for a get_dist check that I threw 9 in as a somewhat arbitrary value for. > Kinesis module's default range has been extended to 8. There's this bug on live where when you kinesis someone it flies all the way to the SW corner of the screen for seemingly no reason. I don't know why it happens but it drives me mad. Even without that bug, 5 tiles is extremely frustrating to handle - it's super, super annoying to find a middleground between 'not slapping you in the face', 'not losing your grip'. 8 tiles is a lot more forgiving and makes the module actually fun to use. > Kinesis module can drag around people in critical condition or worse. This one might be a bit nuts, but I really want to see this ingame, it's kind of the best part of the module yet is unobtainable. Maybe some stuff would need to be tuned for it, like making human throws flimsy. ## Changelog :cl: balance: Significantly buffed the anomalock modules. balance: Anomalock modules can be used with eachother. balance: Antigravity module costs 2 complexity. balance: Teleporter module is thrice as fast at teleporting with a slightly reduced cooldown, but has a much larger power cost. code: Changed how teleporter tracks maximum range to be less painful to the end user. refactor: Refactored LoS checks to be a proc on atom, los_check balance: Kinesis module's default range has been extended to 8. balance: Kinesis module can drag around people in critical condition or worse. /:cl: --- code/__HELPERS/atoms.dm | 40 ++++++++++++++ .../antagonists/heretic/magic/star_touch.dm | 29 ---------- code/modules/mod/modules/_module.dm | 2 +- code/modules/mod/modules/module_kinesis.dm | 2 +- code/modules/mod/modules/modules_science.dm | 25 ++++++--- .../projectiles/guns/special/medbeam.dm | 54 +++++-------------- 6 files changed, 73 insertions(+), 79 deletions(-) diff --git a/code/__HELPERS/atoms.dm b/code/__HELPERS/atoms.dm index d54b29b3f4ac9..e94d58dd69399 100644 --- a/code/__HELPERS/atoms.dm +++ b/code/__HELPERS/atoms.dm @@ -316,6 +316,46 @@ rough example of the "cone" made by the 3 dirs checked loc = loc.loc return null +/** + * Line of sight check! + * Spawns a dummy object and then iterates through each turf to see if it's blocked by something not handled by pass_args. + * Contains a mid_los_check, meant to be overriden by subtypes. + * args: + * * user = Origin to start at. + * * target = End point. + * * pass_args = pass_flags given to dummy object to allow it to ignore certain types of blockades. + */ +/proc/los_check(atom/movable/user, mob/target, pass_args = PASSTABLE|PASSGLASS|PASSGRILLE, datum/callback/mid_check) + var/turf/user_turf = user.loc + if(!istype(user_turf)) + return FALSE + var/obj/dummy = new(user_turf) + dummy.pass_flags |= pass_args //Grille/Glass so it can be used through common windows + var/turf/previous_step = user_turf + var/first_step = TRUE + for(var/turf/next_step as anything in (get_line(user_turf, target) - user_turf)) + if(first_step) + for(var/obj/blocker in user_turf) + if(!blocker.density || !(blocker.flags_1 & ON_BORDER_1)) + continue + if(blocker.CanPass(dummy, get_dir(user_turf, next_step))) + continue + return FALSE // Could not leave the first turf. + first_step = FALSE + if(next_step.density) + qdel(dummy) + return FALSE + for(var/atom/movable/movable as anything in next_step) + if(!movable.CanPass(dummy, get_dir(next_step, previous_step))) + qdel(dummy) + return FALSE + if(mid_check?.Invoke(user, target, pass_args, next_step, dummy) == FALSE) // specify false as it may return null if there's no check + qdel(dummy) + return FALSE + previous_step = next_step + qdel(dummy) + return TRUE + ///Returns true if the src countain the atom target /atom/proc/contains(atom/target) if(!target) diff --git a/code/modules/antagonists/heretic/magic/star_touch.dm b/code/modules/antagonists/heretic/magic/star_touch.dm index d9cd5a05eab2b..e8e824cc71851 100644 --- a/code/modules/antagonists/heretic/magic/star_touch.dm +++ b/code/modules/antagonists/heretic/magic/star_touch.dm @@ -201,35 +201,6 @@ if(current_target) on_beam_hit(current_target) -/// Checks if the beam is going through an invalid turf -/datum/status_effect/cosmic_beam/proc/los_check(atom/movable/user, mob/target) - var/turf/user_turf = user.loc - if(!istype(user_turf)) - return FALSE - var/obj/dummy = new(user_turf) - dummy.pass_flags |= PASSTABLE|PASSGLASS|PASSGRILLE //Grille/Glass so it can be used through common windows - var/turf/previous_step = user_turf - var/first_step = TRUE - for(var/turf/next_step as anything in (get_line(user_turf, target) - user_turf)) - if(first_step) - for(var/obj/blocker in user_turf) - if(!blocker.density || !(blocker.flags_1 & ON_BORDER_1)) - continue - if(blocker.CanPass(dummy, get_dir(user_turf, next_step))) - continue - return FALSE // Could not leave the first turf. - first_step = FALSE - if(next_step.density) - qdel(dummy) - return FALSE - for(var/atom/movable/movable as anything in next_step) - if(!movable.CanPass(dummy, get_dir(next_step, previous_step))) - qdel(dummy) - return FALSE - previous_step = next_step - qdel(dummy) - return TRUE - /// What to add when the beam connects to a target /datum/status_effect/cosmic_beam/proc/on_beam_hit(mob/living/target) if(!istype(target, /mob/living/basic/heretic_summon/star_gazer)) diff --git a/code/modules/mod/modules/_module.dm b/code/modules/mod/modules/_module.dm index 390431300d541..565919c07ecd5 100644 --- a/code/modules/mod/modules/_module.dm +++ b/code/modules/mod/modules/_module.dm @@ -418,7 +418,7 @@ /obj/item/mod/module/anomaly_locked name = "MOD anomaly locked module" desc = "A form of a module, locked behind an anomalous core to function." - incompatible_modules = list(/obj/item/mod/module/anomaly_locked) + incompatible_modules = list() /// The core item the module runs off. var/obj/item/assembly/signaler/anomaly/core /// Accepted types of anomaly cores. diff --git a/code/modules/mod/modules/module_kinesis.dm b/code/modules/mod/modules/module_kinesis.dm index 3c9ae3310b755..733e5ab40d97b 100644 --- a/code/modules/mod/modules/module_kinesis.dm +++ b/code/modules/mod/modules/module_kinesis.dm @@ -17,7 +17,7 @@ accepted_anomalies = list(/obj/item/assembly/signaler/anomaly/grav) required_slots = list(ITEM_SLOT_GLOVES) /// Range of the knesis grab. - var/grab_range = 5 + var/grab_range = 8 /// Time between us hitting objects with kinesis. var/hit_cooldown_time = 1 SECONDS /// Stat required for us to grab a mob. diff --git a/code/modules/mod/modules/modules_science.dm b/code/modules/mod/modules/modules_science.dm index 1d15abece56d0..8cb15d35370aa 100644 --- a/code/modules/mod/modules/modules_science.dm +++ b/code/modules/mod/modules/modules_science.dm @@ -55,9 +55,9 @@ desc = "A module that uses a gravitational core to make the user completely weightless." icon_state = "antigrav" module_type = MODULE_TOGGLE - complexity = 3 + complexity = 2 active_power_cost = DEFAULT_CHARGE_DRAIN * 0.7 - incompatible_modules = list(/obj/item/mod/module/anomaly_locked, /obj/item/mod/module/atrocinator) + incompatible_modules = list(/obj/item/mod/module/atrocinator, /obj/item/mod/module/anomaly_locked/antigrav) accepted_anomalies = list(/obj/item/assembly/signaler/anomaly/grav) required_slots = list(ITEM_SLOT_BACK|ITEM_SLOT_BELT) @@ -88,21 +88,34 @@ icon_state = "teleporter" module_type = MODULE_ACTIVE complexity = 3 - use_energy_cost = DEFAULT_CHARGE_DRAIN * 5 - cooldown_time = 5 SECONDS + use_energy_cost = DEFAULT_CHARGE_DRAIN * 25 + cooldown_time = 4 SECONDS + incompatible_modules = list(/obj/item/mod/module/anomaly_locked/teleporter) accepted_anomalies = list(/obj/item/assembly/signaler/anomaly/bluespace) required_slots = list(ITEM_SLOT_BACK|ITEM_SLOT_BELT) /// Time it takes to teleport - var/teleport_time = 3 SECONDS + var/teleport_time = 1 SECONDS + /// Maximum turf range + var/max_range = 9 /obj/item/mod/module/anomaly_locked/teleporter/on_select_use(atom/target) . = ..() if(!.) return var/turf/open/target_turf = get_turf(target) - if(!istype(target_turf) || target_turf.is_blocked_turf_ignore_climbable() || !(target_turf in view(mod.wearer))) + if(get_dist(target_turf, mod.wearer) > max_range) + balloon_alert(mod.wearer, "too far!") + return + if(!istype(target_turf)) balloon_alert(mod.wearer, "invalid target!") return + if(target_turf.is_blocked_turf_ignore_climbable() || !los_check(mod.wearer, target, pass_args = PASSTABLE|PASSGLASS|PASSGRILLE|PASSMOB|PASSMACHINE|PASSSTRUCTURE|PASSFLAPS|PASSWINDOW)) + balloon_alert(mod.wearer, "blocked destination!") + return + // check early so we don't go through the whole loops + if(!check_teleport_valid(mod.wearer, target_turf, channel = TELEPORT_CHANNEL_BLUESPACE, original_destination = target_turf)) + balloon_alert(mod.wearer, "something holds you back!") + return balloon_alert(mod.wearer, "teleporting...") var/matrix/pre_matrix = matrix() pre_matrix.Scale(4, 0.25) diff --git a/code/modules/projectiles/guns/special/medbeam.dm b/code/modules/projectiles/guns/special/medbeam.dm index 0ad5caf2fec82..95da571baf547 100644 --- a/code/modules/projectiles/guns/special/medbeam.dm +++ b/code/modules/projectiles/guns/special/medbeam.dm @@ -83,56 +83,26 @@ last_check = world.time - if(!los_check(loc, current_target)) + if(!los_check(loc, current_target, mid_check = CALLBACK(src, PROC_REF(mid_los_check)))) QDEL_NULL(current_beam)//this will give the target lost message return if(current_target) on_beam_tick(current_target) -/obj/item/gun/medbeam/proc/los_check(atom/movable/user, mob/target) - var/turf/user_turf = user.loc - if(mounted) - user_turf = get_turf(user) - else if(!istype(user_turf)) - return FALSE - var/obj/dummy = new(user_turf) - dummy.pass_flags |= PASSTABLE|PASSGLASS|PASSGRILLE //Grille/Glass so it can be used through common windows - var/turf/previous_step = user_turf - var/first_step = TRUE - for(var/turf/next_step as anything in (get_line(user_turf, target) - user_turf)) - if(first_step) - for(var/obj/blocker in user_turf) - if(!blocker.density || !(blocker.flags_1 & ON_BORDER_1)) - continue - if(blocker.CanPass(dummy, get_dir(user_turf, next_step))) - continue - return FALSE // Could not leave the first turf. - first_step = FALSE - if(mounted && next_step == user_turf) - - continue //Mechs are dense and thus fail the check - if(next_step.density) +/obj/item/gun/medbeam/proc/mid_los_check(atom/movable/user, mob/target, pass_args = PASSTABLE|PASSGLASS|PASSGRILLE, turf/next_step, obj/dummy) + for(var/obj/effect/ebeam/medical/B in next_step)// Don't cross the str-beams! + if(QDELETED(current_beam)) + break //We shouldn't be processing anymore. + if(QDELETED(B)) + continue + if(!B.owner) + stack_trace("beam without an owner! [B]") + continue + if(B.owner.origin != current_beam.origin) + explosion(B.loc, heavy_impact_range = 3, light_impact_range = 5, flash_range = 8, explosion_cause = src) qdel(dummy) return FALSE - for(var/atom/movable/movable as anything in next_step) - if(!movable.CanPass(dummy, get_dir(next_step, previous_step))) - qdel(dummy) - return FALSE - for(var/obj/effect/ebeam/medical/B in next_step)// Don't cross the str-beams! - if(QDELETED(current_beam)) - break //We shouldn't be processing anymore. - if(QDELETED(B)) - continue - if(!B.owner) - stack_trace("beam without an owner! [B]") - continue - if(B.owner.origin != current_beam.origin) - explosion(B.loc, heavy_impact_range = 3, light_impact_range = 5, flash_range = 8, explosion_cause = src) - qdel(dummy) - return FALSE - previous_step = next_step - qdel(dummy) return TRUE /obj/item/gun/medbeam/proc/on_beam_hit(mob/living/target) From 820dd15348b26fdb291dd5a35f51a0dbc01892b7 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:57:05 +0000 Subject: [PATCH 085/222] Automatic changelog for PR #87743 [ci skip] --- html/changelogs/AutoChangeLog-pr-87743.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87743.yml diff --git a/html/changelogs/AutoChangeLog-pr-87743.yml b/html/changelogs/AutoChangeLog-pr-87743.yml new file mode 100644 index 0000000000000..f485fa992178c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87743.yml @@ -0,0 +1,11 @@ +author: "carlarctg" +delete-after: True +changes: + - balance: "Significantly buffed the anomalock modules." + - balance: "Anomalock modules can be used with eachother." + - balance: "Antigravity module costs 2 complexity." + - balance: "Teleporter module is thrice as fast at teleporting with a slightly reduced cooldown, but has a much larger power cost." + - code_imp: "Changed how teleporter tracks maximum range to be less painful to the end user." + - refactor: "Refactored LoS checks to be a proc on atom, los_check" + - balance: "Kinesis module's default range has been extended to 8." + - balance: "Kinesis module can drag around people in critical condition or worse." \ No newline at end of file From 251c0accb7af0f6bd74361d531ea6b3282b65977 Mon Sep 17 00:00:00 2001 From: carlarctg <53100513+carlarctg@users.noreply.github.com> Date: Thu, 14 Nov 2024 16:09:05 -0300 Subject: [PATCH 086/222] vampires are a human subtype & have stomachs/lungs (#87622) ## About The Pull Request Vampires have stomachs and lungs. They still don't have hunger. Vampires are a human subtype. Vamp bloodtype from "U"nknown to "V"ampire ## Why It's Good For The Game For some stupid reason vampires lacked stomachs. Vampires drinking wine is a classic trope that currently results in vomit magically appearing below you. Evidence of wine: ![ielbiv4shad81](https://github.com/user-attachments/assets/ef39c522-282d-4763-8802-a6fb180aafb2) Vampires are a human subtype too like felinids because this resulted in dumb bugs like no screaming sound. Vamp bloodtype from "U"nknown to "V"ampire I mean if we haev these guys on halloween. We probably know their blood right. ## Changelog :cl: fix: vampires are a human subtype & have stomachs/lungs /:cl: --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> --- code/__DEFINES/is_helpers.dm | 2 +- code/modules/mob/living/carbon/human/human.dm | 2 +- .../carbon/human/species_types/vampire.dm | 29 ++++++++---------- .../spell_types/self/splattercasting_spell.dm | 2 +- ...umanoids__datum_species_human_vampire.png} | Bin 5 files changed, 16 insertions(+), 19 deletions(-) rename code/modules/unit_tests/screenshots/{screenshot_humanoids__datum_species_vampire.png => screenshot_humanoids__datum_species_human_vampire.png} (100%) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 5b3d50cdadd17..26baf69940954 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -115,7 +115,7 @@ GLOBAL_LIST_INIT(turfs_pass_meteor, typecacheof(list( #define ismoth(A) (is_species(A, /datum/species/moth)) #define isfelinid(A) (is_species(A, /datum/species/human/felinid)) #define isethereal(A) (is_species(A, /datum/species/ethereal)) -#define isvampire(A) (is_species(A,/datum/species/vampire)) +#define isvampire(A) (is_species(A,/datum/species/human/vampire)) #define isdullahan(A) (is_species(A, /datum/species/dullahan)) #define ismonkey(A) (is_species(A, /datum/species/monkey)) #define isandroid(A) (is_species(A, /datum/species/android)) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 5b0e64547a016..bd72ff464a958 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1192,7 +1192,7 @@ race = /datum/species/snail /mob/living/carbon/human/species/vampire - race = /datum/species/vampire + race = /datum/species/human/vampire /mob/living/carbon/human/species/zombie race = /datum/species/zombie diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm index d0b052a888865..44b5d9590387a 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -4,7 +4,7 @@ ///maximum a vampire will drain, they will drain less if they hit their cap #define VAMP_DRAIN_AMOUNT 50 -/datum/species/vampire +/datum/species/human/vampire name = "Vampire" id = SPECIES_VAMPIRE examine_limb_id = SPECIES_HUMAN @@ -18,33 +18,30 @@ ) inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID changesource_flags = MIRROR_BADMIN | MIRROR_PRIDE | WABBAJACK | ERT_SPAWN - exotic_bloodtype = "U" + exotic_bloodtype = "V" blood_deficiency_drain_rate = BLOOD_DEFICIENCY_MODIFIER // vampires already passively lose blood, so this just makes them lose it slightly more quickly when they have blood deficiency. mutantheart = /obj/item/organ/heart/vampire mutanttongue = /obj/item/organ/tongue/vampire - mutantstomach = null - mutantlungs = null - skinned_type = /obj/item/stack/sheet/animalhide/human ///some starter text sent to the vampire initially, because vampires have shit to do to stay alive var/info_text = "You are a Vampire. You will slowly but constantly lose blood if outside of a coffin. If inside a coffin, you will slowly heal. You may gain more blood by grabbing a live victim and using your drain ability." -/datum/species/vampire/check_roundstart_eligible() +/datum/species/human/vampire/check_roundstart_eligible() if(check_holidays(HALLOWEEN)) return TRUE return ..() -/datum/species/vampire/on_species_gain(mob/living/carbon/human/new_vampire, datum/species/old_species) +/datum/species/human/vampire/on_species_gain(mob/living/carbon/human/new_vampire, datum/species/old_species) . = ..() to_chat(new_vampire, "[info_text]") new_vampire.skin_tone = "albino" new_vampire.update_body(0) RegisterSignal(new_vampire, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS, PROC_REF(damage_weakness)) -/datum/species/vampire/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load) +/datum/species/human/vampire/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load) . = ..() UnregisterSignal(C, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS) -/datum/species/vampire/spec_life(mob/living/carbon/human/vampire, seconds_per_tick, times_fired) +/datum/species/human/vampire/spec_life(mob/living/carbon/human/vampire, seconds_per_tick, times_fired) . = ..() if(istype(vampire.loc, /obj/structure/closet/crate/coffin)) var/need_mob_update = FALSE @@ -66,27 +63,27 @@ vampire.adjust_fire_stacks(3 * seconds_per_tick) vampire.ignite_mob() -/datum/species/vampire/proc/damage_weakness(datum/source, list/damage_mods, damage_amount, damagetype, def_zone, sharpness, attack_direction, obj/item/attacking_item) +/datum/species/human/vampire/proc/damage_weakness(datum/source, list/damage_mods, damage_amount, damagetype, def_zone, sharpness, attack_direction, obj/item/attacking_item) SIGNAL_HANDLER if(istype(attacking_item, /obj/item/nullrod/whip)) damage_mods += 2 -/datum/species/vampire/get_physical_attributes() +/datum/species/human/vampire/get_physical_attributes() return "Vampires are afflicted with the Thirst, needing to sate it by draining the blood out of another living creature. However, they do not need to breathe or eat normally. \ They will instantly turn into dust if they run out of blood or enter a holy area. However, coffins stabilize and heal them, and they can transform into bats!" -/datum/species/vampire/get_species_description() +/datum/species/human/vampire/get_species_description() return "A classy Vampire! They descend upon Space Station Thirteen Every year to spook the crew! \"Bleeg!!\"" -/datum/species/vampire/get_species_lore() +/datum/species/human/vampire/get_species_lore() return list( "Vampires are unholy beings blessed and cursed with The Thirst. \ The Thirst requires them to feast on blood to stay alive, and in return it gives them many bonuses. \ Because of this, Vampires have split into two clans, one that embraces their powers as a blessing and one that rejects it.", ) -/datum/species/vampire/create_pref_unique_perks() +/datum/species/human/vampire/create_pref_unique_perks() var/list/to_add = list() to_add += list( @@ -115,7 +112,7 @@ return to_add // Vampire blood is special, so it needs to be handled with its own entry. -/datum/species/vampire/create_pref_blood_perks() +/datum/species/human/vampire/create_pref_blood_perks() var/list/to_add = list() to_add += list(list( @@ -132,7 +129,7 @@ return to_add // There isn't a "Minor Undead" biotype, so we have to explain it in an override (see: dullahans) -/datum/species/vampire/create_pref_biotypes_perks() +/datum/species/human/vampire/create_pref_biotypes_perks() var/list/to_add = list() to_add += list(list( diff --git a/code/modules/spells/spell_types/self/splattercasting_spell.dm b/code/modules/spells/spell_types/self/splattercasting_spell.dm index 184a2afab7ca2..e76f8e3c1b9bf 100644 --- a/code/modules/spells/spell_types/self/splattercasting_spell.dm +++ b/code/modules/spells/spell_types/self/splattercasting_spell.dm @@ -28,7 +28,7 @@ brings unimaginable momentary torment as your heart stops, and your skin grows cold. You are now \ merely a vessel for the arcane flow. Soon, all that is left is not pain, but hunger.")) - cast_on.set_species(/datum/species/vampire) + cast_on.set_species(/datum/species/human/vampire) cast_on.blood_volume = BLOOD_VOLUME_NORMAL ///for predictable blood total amounts when the spell is first cast. cast_on.AddComponent(/datum/component/splattercasting) diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_vampire.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_human_vampire.png similarity index 100% rename from code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_vampire.png rename to code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_human_vampire.png From 6579fda0173b44e03d6e7ef43de206821b336a7c Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 19:09:28 +0000 Subject: [PATCH 087/222] Automatic changelog for PR #87622 [ci skip] --- html/changelogs/AutoChangeLog-pr-87622.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87622.yml diff --git a/html/changelogs/AutoChangeLog-pr-87622.yml b/html/changelogs/AutoChangeLog-pr-87622.yml new file mode 100644 index 0000000000000..03a06eab36cec --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87622.yml @@ -0,0 +1,4 @@ +author: "carlarctg" +delete-after: True +changes: + - bugfix: "vampires are a human subtype & have stomachs/lungs" \ No newline at end of file From 6fa26ecbb57cd698b2455ffc6e7d0ca5360155b0 Mon Sep 17 00:00:00 2001 From: grungussuss <96586172+Sadboysuss@users.noreply.github.com> Date: Fri, 15 Nov 2024 00:15:05 +0300 Subject: [PATCH 088/222] gives mulebot wires some messages when cut (#87895) ## About The Pull Request closes https://github.com/tgstation/tgstation/issues/87640 ## Why It's Good For The Game feedback is cool ## Changelog :cl: grungussuss qol: added feedback for cutting mulebot wires /:cl: --- code/datums/wires/mulebot.dm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/datums/wires/mulebot.dm b/code/datums/wires/mulebot.dm index beb58fb1ce3b4..ec38d72898196 100644 --- a/code/datums/wires/mulebot.dm +++ b/code/datums/wires/mulebot.dm @@ -29,18 +29,24 @@ if(WIRE_MOTOR1, WIRE_MOTOR2) if(is_cut(WIRE_MOTOR1) && is_cut(WIRE_MOTOR2)) ADD_TRAIT(mule, TRAIT_IMMOBILIZED, MOTOR_LACK_TRAIT) + holder.audible_message(span_hear("The motors of [src] go silent."), null, 1) else REMOVE_TRAIT(mule, TRAIT_IMMOBILIZED, MOTOR_LACK_TRAIT) + holder.audible_message(span_hear("The motors of [src] whir to life!"), null, 1) if(is_cut(WIRE_MOTOR1)) mule.set_varspeed(FAST_MOTOR_SPEED) + holder.audible_message(span_hear("The motors of [src] speed up!"), null, 1) else if(is_cut(WIRE_MOTOR2)) mule.set_varspeed(AVERAGE_MOTOR_SPEED) + holder.audible_message(span_hear("The motors of [src] whir."), null, 1) else mule.set_varspeed(SLOW_MOTOR_SPEED) + holder.audible_message(span_hear("The motors of [src] move gently."), null, 1) if(WIRE_AVOIDANCE) if (!isnull(source)) log_combat(source, mule, "[is_cut(WIRE_AVOIDANCE) ? "cut" : "mended"] the MULE safety wire of") + holder.audible_message(span_hear("Something inside [src] clicks ominously!"), null, 1) /datum/wires/mulebot/on_pulse(wire) var/mob/living/simple_animal/bot/mulebot/mule = holder From c937e156f17a123620e150c510a13dc17b8538d9 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 21:15:30 +0000 Subject: [PATCH 089/222] Automatic changelog for PR #87895 [ci skip] --- html/changelogs/AutoChangeLog-pr-87895.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87895.yml diff --git a/html/changelogs/AutoChangeLog-pr-87895.yml b/html/changelogs/AutoChangeLog-pr-87895.yml new file mode 100644 index 0000000000000..7bf21a61dba8f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87895.yml @@ -0,0 +1,4 @@ +author: "grungussuss" +delete-after: True +changes: + - qol: "added feedback for cutting mulebot wires" \ No newline at end of file From db4cf804b8f8de3d8fece23342003000b5d33e94 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 00:29:12 +0000 Subject: [PATCH 090/222] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-87622.yml | 4 -- html/changelogs/AutoChangeLog-pr-87634.yml | 4 -- html/changelogs/AutoChangeLog-pr-87743.yml | 11 ---- html/changelogs/AutoChangeLog-pr-87785.yml | 4 -- html/changelogs/AutoChangeLog-pr-87789.yml | 4 -- html/changelogs/AutoChangeLog-pr-87792.yml | 4 -- html/changelogs/AutoChangeLog-pr-87793.yml | 4 -- html/changelogs/AutoChangeLog-pr-87798.yml | 4 -- html/changelogs/AutoChangeLog-pr-87803.yml | 4 -- html/changelogs/AutoChangeLog-pr-87816.yml | 4 -- html/changelogs/AutoChangeLog-pr-87817.yml | 4 -- html/changelogs/AutoChangeLog-pr-87858.yml | 7 --- html/changelogs/AutoChangeLog-pr-87862.yml | 4 -- html/changelogs/AutoChangeLog-pr-87870.yml | 5 -- html/changelogs/AutoChangeLog-pr-87885.yml | 4 -- html/changelogs/AutoChangeLog-pr-87886.yml | 4 -- html/changelogs/AutoChangeLog-pr-87887.yml | 4 -- html/changelogs/AutoChangeLog-pr-87891.yml | 4 -- html/changelogs/AutoChangeLog-pr-87895.yml | 4 -- html/changelogs/AutoChangeLog-pr-87896.yml | 4 -- html/changelogs/AutoChangeLog-pr-87898.yml | 4 -- html/changelogs/AutoChangeLog-pr-87901.yml | 4 -- html/changelogs/AutoChangeLog-pr-87903.yml | 4 -- html/changelogs/archive/2024-11.yml | 66 ++++++++++++++++++++++ 24 files changed, 66 insertions(+), 103 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-87622.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87634.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87743.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87785.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87789.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87792.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87793.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87798.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87803.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87816.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87817.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87858.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87862.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87870.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87885.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87886.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87887.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87891.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87895.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87896.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87898.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87901.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87903.yml diff --git a/html/changelogs/AutoChangeLog-pr-87622.yml b/html/changelogs/AutoChangeLog-pr-87622.yml deleted file mode 100644 index 03a06eab36cec..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87622.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "carlarctg" -delete-after: True -changes: - - bugfix: "vampires are a human subtype & have stomachs/lungs" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87634.yml b/html/changelogs/AutoChangeLog-pr-87634.yml deleted file mode 100644 index 8d8e95fdf1f5c..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87634.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "carlarctg" -delete-after: True -changes: - - bugfix: "you now snip cuffs with right click to prevent accidental cuts" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87743.yml b/html/changelogs/AutoChangeLog-pr-87743.yml deleted file mode 100644 index f485fa992178c..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87743.yml +++ /dev/null @@ -1,11 +0,0 @@ -author: "carlarctg" -delete-after: True -changes: - - balance: "Significantly buffed the anomalock modules." - - balance: "Anomalock modules can be used with eachother." - - balance: "Antigravity module costs 2 complexity." - - balance: "Teleporter module is thrice as fast at teleporting with a slightly reduced cooldown, but has a much larger power cost." - - code_imp: "Changed how teleporter tracks maximum range to be less painful to the end user." - - refactor: "Refactored LoS checks to be a proc on atom, los_check" - - balance: "Kinesis module's default range has been extended to 8." - - balance: "Kinesis module can drag around people in critical condition or worse." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87785.yml b/html/changelogs/AutoChangeLog-pr-87785.yml deleted file mode 100644 index d7bd7a8c9401f..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87785.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "mc-oofert" -delete-after: True -changes: - - bugfix: "Added dehydrator to birdshot kitchen. Surgery theatre now has a surgery tray and surplus prosthetics. An unwired hallway APC is now wired. 1st SM filter is now set to Nitrogen. Chemistry closet in pharmacy now contains extra chemicals to compensate for not having a chemical storage. Atmos air for distro mixer now mixes correctly" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87789.yml b/html/changelogs/AutoChangeLog-pr-87789.yml deleted file mode 100644 index 062e7ea55b11e..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87789.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "larentoun" -delete-after: True -changes: - - bugfix: "Fixes a runtime when wingless creature flaps their wings" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87792.yml b/html/changelogs/AutoChangeLog-pr-87792.yml deleted file mode 100644 index e8ff0af1935b3..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87792.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "GremlinSeeker" -delete-after: True -changes: - - bugfix: "Syndicate Biodome fixes" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87793.yml b/html/changelogs/AutoChangeLog-pr-87793.yml deleted file mode 100644 index 258030b1226f2..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87793.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SyncIt21" -delete-after: True -changes: - - bugfix: "Fixed visual glitches when inserting items from an slot other than the hands into evidence bags & other storages that have quick gather mode enabled" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87798.yml b/html/changelogs/AutoChangeLog-pr-87798.yml deleted file mode 100644 index 0e94f42326a72..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87798.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Time-Green" -delete-after: True -changes: - - bugfix: "Nooartrium heart damage can no longer be bypassed with non-organic hearts" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87803.yml b/html/changelogs/AutoChangeLog-pr-87803.yml deleted file mode 100644 index e9f054ddbc26c..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87803.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Many years later, projectiles finally can pass through portals - this time without crashing the server." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87816.yml b/html/changelogs/AutoChangeLog-pr-87816.yml deleted file mode 100644 index cd829eb2934bd..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87816.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Fixed scanner gates saying both bypass and detection lines when malfunctioning" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87817.yml b/html/changelogs/AutoChangeLog-pr-87817.yml deleted file mode 100644 index 04ed21be2aaa6..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87817.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Dawnseer" -delete-after: True -changes: - - bugfix: "removes the gas mask check for if the gas mask mouth is covered. Now it only checks for filters and other cigs" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87858.yml b/html/changelogs/AutoChangeLog-pr-87858.yml deleted file mode 100644 index 073a04f7237e7..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87858.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: "Melbert" -delete-after: True -changes: - - image: "Speeds up some frames of the dust animation slightly" - - image: "Dust/remains spawned after being dusted are now aligned towards the bottom of the tile" - - image: "Bigger mobs now produce bigger piles of ash" - - image: "Plasmamen now dust into plasma bones" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87862.yml b/html/changelogs/AutoChangeLog-pr-87862.yml deleted file mode 100644 index 68001ac6100d9..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87862.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "carlarctg" -delete-after: True -changes: - - spellcheck: "spellecheck: existence not existance" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87870.yml b/html/changelogs/AutoChangeLog-pr-87870.yml deleted file mode 100644 index c72aff1a0ed20..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87870.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SyncIt21" -delete-after: True -changes: - - bugfix: "silo connection on some machines won't time out when changing FPS settings" - - code_imp: "improved attack chain code for silo connection" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87885.yml b/html/changelogs/AutoChangeLog-pr-87885.yml deleted file mode 100644 index d6582ff3aabad..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87885.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ben10Omintrix" -delete-after: True -changes: - - bugfix: "fixes seedling ai getting stuck when trying to refill water from emptied water tanks" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87886.yml b/html/changelogs/AutoChangeLog-pr-87886.yml deleted file mode 100644 index 56c04b1ca024a..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87886.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Absolucy" -delete-after: True -changes: - - refactor: "The ORM, \"ore container\", and order console UIs (produce, mining, bitrunner vendors) now load icons in a more efficient manner." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87887.yml b/html/changelogs/AutoChangeLog-pr-87887.yml deleted file mode 100644 index 5b0a6f175c032..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87887.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Absolucy" -delete-after: True -changes: - - bugfix: "Admin-deleting a mob now ghostizes it beforehand, preventing a runtime error." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87891.yml b/html/changelogs/AutoChangeLog-pr-87891.yml deleted file mode 100644 index 43acec0776451..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87891.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothymtorres" -delete-after: True -changes: - - balance: "Lower the telecrystal price of the singularity beacon from 10 to 4 and reduce the timer to 20 minutes before it can be purchased." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87895.yml b/html/changelogs/AutoChangeLog-pr-87895.yml deleted file mode 100644 index 7bf21a61dba8f..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87895.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "grungussuss" -delete-after: True -changes: - - qol: "added feedback for cutting mulebot wires" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87896.yml b/html/changelogs/AutoChangeLog-pr-87896.yml deleted file mode 100644 index a1308fb4a9f38..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87896.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "grungussuss" -delete-after: True -changes: - - sound: "sandstone blocks have the correct sound now" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87898.yml b/html/changelogs/AutoChangeLog-pr-87898.yml deleted file mode 100644 index aa4f5a81aa944..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87898.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "xPokee" -delete-after: True -changes: - - bugfix: "fixed brains turning invisible after being washed" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87901.yml b/html/changelogs/AutoChangeLog-pr-87901.yml deleted file mode 100644 index af44465c11ddd..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87901.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Fixed tenacity effect printing its messages when it shouldn't be, and not removing its' effects when it should've." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87903.yml b/html/changelogs/AutoChangeLog-pr-87903.yml deleted file mode 100644 index 2a11a63c40a77..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87903.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Majkl-J" -delete-after: True -changes: - - bugfix: "Fixes SSWardrobe stealing a camera from the camera app when on a dummy, causing a harddel" \ No newline at end of file diff --git a/html/changelogs/archive/2024-11.yml b/html/changelogs/archive/2024-11.yml index b4f73b08b7b85..51197f3841a72 100644 --- a/html/changelogs/archive/2024-11.yml +++ b/html/changelogs/archive/2024-11.yml @@ -496,3 +496,69 @@ - bugfix: Fix using chairs in holodeck to create infinite metal xPokee, waterpig: - code_imp: cleaned up beserk.dm +2024-11-15: + Absolucy: + - refactor: The ORM, "ore container", and order console UIs (produce, mining, bitrunner + vendors) now load icons in a more efficient manner. + - bugfix: Admin-deleting a mob now ghostizes it beforehand, preventing a runtime + error. + Ben10Omintrix: + - bugfix: fixes seedling ai getting stuck when trying to refill water from emptied + water tanks + Dawnseer: + - bugfix: removes the gas mask check for if the gas mask mouth is covered. Now it + only checks for filters and other cigs + GremlinSeeker: + - bugfix: Syndicate Biodome fixes + Majkl-J: + - bugfix: Fixes SSWardrobe stealing a camera from the camera app when on a dummy, + causing a harddel + Melbert: + - image: Speeds up some frames of the dust animation slightly + - image: Dust/remains spawned after being dusted are now aligned towards the bottom + of the tile + - image: Bigger mobs now produce bigger piles of ash + - image: Plasmamen now dust into plasma bones + SmArtKar: + - bugfix: Many years later, projectiles finally can pass through portals - this + time without crashing the server. + - bugfix: Fixed tenacity effect printing its messages when it shouldn't be, and + not removing its' effects when it should've. + - bugfix: Fixed scanner gates saying both bypass and detection lines when malfunctioning + SyncIt21: + - bugfix: Fixed visual glitches when inserting items from an slot other than the + hands into evidence bags & other storages that have quick gather mode enabled + - bugfix: silo connection on some machines won't time out when changing FPS settings + - code_imp: improved attack chain code for silo connection + Time-Green: + - bugfix: Nooartrium heart damage can no longer be bypassed with non-organic hearts + carlarctg: + - bugfix: you now snip cuffs with right click to prevent accidental cuts + - spellcheck: 'spellecheck: existence not existance' + - balance: Significantly buffed the anomalock modules. + - balance: Anomalock modules can be used with eachother. + - balance: Antigravity module costs 2 complexity. + - balance: Teleporter module is thrice as fast at teleporting with a slightly reduced + cooldown, but has a much larger power cost. + - code_imp: Changed how teleporter tracks maximum range to be less painful to the + end user. + - refactor: Refactored LoS checks to be a proc on atom, los_check + - balance: Kinesis module's default range has been extended to 8. + - balance: Kinesis module can drag around people in critical condition or worse. + - bugfix: vampires are a human subtype & have stomachs/lungs + grungussuss: + - sound: sandstone blocks have the correct sound now + - qol: added feedback for cutting mulebot wires + larentoun: + - bugfix: Fixes a runtime when wingless creature flaps their wings + mc-oofert: + - bugfix: Added dehydrator to birdshot kitchen. Surgery theatre now has a surgery + tray and surplus prosthetics. An unwired hallway APC is now wired. 1st SM filter + is now set to Nitrogen. Chemistry closet in pharmacy now contains extra chemicals + to compensate for not having a chemical storage. Atmos air for distro mixer + now mixes correctly + timothymtorres: + - balance: Lower the telecrystal price of the singularity beacon from 10 to 4 and + reduce the timer to 20 minutes before it can be purchased. + xPokee: + - bugfix: fixed brains turning invisible after being washed From 9592b333e27ef22531efb6b6589e37e5bd39ddce Mon Sep 17 00:00:00 2001 From: Lucy Date: Fri, 15 Nov 2024 03:04:32 -0500 Subject: [PATCH 091/222] byond-tracy additions and refactors (#87067) ## About The Pull Request This adds plenty of useful stuff regarding byond-tracy, altho mostly focused on the [Paradise fork](https://github.com/ParadiseSS13/byond-tracy). - Adds two new config options **(THEY ARE DISABLED BY DEFAULT)** - `ALLOW_TRACY_START` gives admins with +DEBUG the "Run Tracy Now" verb, which will allow them to start profiling with byond-tracy mid-round. - `ALLOW_TRACY_QUEUE` gives admins with +DEBUG the "Toggle Tracy Next Round" verb, which will initialize byond-tracy during world init the next round (in the same way as passing `-params tracy` or defining `USE_BYOND_TRACY`) - If byond-tracy fails to initialize, the error will be logged and available to view for the whole round. - If `MC_TAB_TRACY_INFO` is defined, information about byond-tracy now appears in the MC tab - if it's running or not, if it errored (and what the error is), why it's running, if its queued for next round, etc. - byond-tracy is now properly shut down when the world shuts down/reboots, minimizing the risk of data loss or crashing - More info regarding byond-tracy init is sent to `world.log` ## Why It's Good For The Game Profiling is super helpful, and this should make things quite easier ## Changelog No user-facing changes --- code/__DEFINES/tracy.dm | 5 ++ code/_compile_options.dm | 6 +- .../configuration/entries/general.dm | 8 +++ code/controllers/subsystem/statpanel.dm | 18 +++++ code/game/world.dm | 66 ++++++++++++++----- code/modules/admin/verbs/debug.dm | 39 +++++++++++ config/config.txt | 6 ++ tgstation.dme | 1 + 8 files changed, 132 insertions(+), 17 deletions(-) create mode 100644 code/__DEFINES/tracy.dm diff --git a/code/__DEFINES/tracy.dm b/code/__DEFINES/tracy.dm new file mode 100644 index 0000000000000..0a9ab8d68ee24 --- /dev/null +++ b/code/__DEFINES/tracy.dm @@ -0,0 +1,5 @@ +/// File path used for the "enable tracy next round" functionality +#define TRACY_ENABLE_PATH "data/enable_tracy" + +/// The DLL path for byond-tracy. +#define TRACY_DLL_PATH (world.system_type == MS_WINDOWS ? "prof.dll" : "./libprof.so") diff --git a/code/_compile_options.dm b/code/_compile_options.dm index 3fe456e488ecb..9772ebff8d10f 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -85,9 +85,13 @@ // If this is uncommented, will attempt to load and initialize prof.dll/libprof.so by default. // Even if it's not defined, you can pass "tracy" via -params in order to try to load it. -// We do not ship byond-tracy. Build it yourself here: https://github.com/mafemergency/byond-tracy/ +// We do not ship byond-tracy. Build it yourself here: https://github.com/mafemergency/byond-tracy, +// or the fork which writes profiling data to a file: https://github.com/ParadiseSS13/byond-tracy // #define USE_BYOND_TRACY +// If uncommented, will display info about byond-tracy's status in the MC tab. +// #define MC_TAB_TRACY_INFO + // If defined, we will compile with FULL timer debug info, rather then a limited scope // Be warned, this increases timer creation cost by 5x // #define TIMER_DEBUG diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index e1ed3284441f6..3648a1b564e8c 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -762,3 +762,11 @@ default = 100 min_val = 0 max_val = 100 + +/// If admins with +DEBUG can initialize byond-tracy midround. +/datum/config_entry/flag/allow_tracy_start + protection = CONFIG_ENTRY_LOCKED + +/// If admins with +DEBUG can queue byond-tracy to run the next round. +/datum/config_entry/flag/allow_tracy_queue + protection = CONFIG_ENTRY_LOCKED diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index cf158586ce497..9d33e977e2b7f 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -173,6 +173,24 @@ SUBSYSTEM_DEF(statpanels) list("Failsafe Controller:", Failsafe.stat_entry(), text_ref(Failsafe)), list("","") ) +#if defined(MC_TAB_TRACY_INFO) || defined(SPACEMAN_DMM) + var/static/tracy_dll + var/static/tracy_present + if(isnull(tracy_dll)) + tracy_dll = TRACY_DLL_PATH + tracy_present = fexists(tracy_dll) + if(tracy_present) + if(GLOB.tracy_initialized) + mc_data.Insert(2, list(list("byond-tracy:", "Active (reason: [GLOB.tracy_init_reason || "N/A"])"))) + else if(GLOB.tracy_init_error) + mc_data.Insert(2, list(list("byond-tracy:", "Errored ([GLOB.tracy_init_error])"))) + else if(fexists(TRACY_ENABLE_PATH)) + mc_data.Insert(2, list(list("byond-tracy:", "Queued for next round"))) + else + mc_data.Insert(2, list(list("byond-tracy:", "Inactive"))) + else + mc_data.Insert(2, list(list("byond-tracy:", "[tracy_dll] not present"))) +#endif for(var/datum/controller/subsystem/sub_system as anything in Master.subsystems) mc_data[++mc_data.len] = list("\[[sub_system.state_letter()]][sub_system.name]", sub_system.stat_entry(), text_ref(sub_system)) mc_data[++mc_data.len] = list("Camera Net", "Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]", text_ref(GLOB.cameranet)) diff --git a/code/game/world.dm b/code/game/world.dm index fe55b3963b504..48ab5b1bd7c24 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -8,6 +8,13 @@ GLOBAL_VAR(restart_counter) GLOBAL_VAR(tracy_log) +GLOBAL_PROTECT(tracy_log) +GLOBAL_VAR(tracy_initialized) +GLOBAL_PROTECT(tracy_initialized) +GLOBAL_VAR(tracy_init_error) +GLOBAL_PROTECT(tracy_init_error) +GLOBAL_VAR(tracy_init_reason) +GLOBAL_PROTECT(tracy_init_reason) /** * WORLD INITIALIZATION @@ -66,15 +73,29 @@ GLOBAL_VAR(tracy_log) /world/proc/Genesis(tracy_initialized = FALSE) RETURN_TYPE(/datum/controller/master) + GLOB.tracy_initialized = FALSE +#ifndef OPENDREAM + if(!tracy_initialized) #ifdef USE_BYOND_TRACY #warn USE_BYOND_TRACY is enabled - if(!tracy_initialized) + var/should_init_tracy = TRUE + GLOB.tracy_init_reason = "USE_BYOND_TRACY defined" #else - if(!tracy_initialized && (USE_TRACY_PARAMETER in params)) + var/should_init_tracy = FALSE + if(USE_TRACY_PARAMETER in params) + should_init_tracy = TRUE + GLOB.tracy_init_reason = "world.params" + if(fexists(TRACY_ENABLE_PATH)) + GLOB.tracy_init_reason ||= "enabled for round" + SEND_TEXT(world.log, "[TRACY_ENABLE_PATH] exists, initializing byond-tracy!") + should_init_tracy = TRUE + fdel(TRACY_ENABLE_PATH) +#endif + if(should_init_tracy) + init_byond_tracy() + Genesis(tracy_initialized = TRUE) + return #endif - GLOB.tracy_log = init_byond_tracy() - Genesis(tracy_initialized = TRUE) - return Profile(PROFILE_RESTART) Profile(PROFILE_RESTART, type = "sendmaps") @@ -331,6 +352,7 @@ GLOBAL_VAR(tracy_log) if(do_hard_reboot) log_world("World hard rebooted at [time_stamp()]") shutdown_logging() // See comment below. + shutdown_byond_tracy() auxcleanup() TgsEndProcess() return ..() @@ -338,6 +360,7 @@ GLOBAL_VAR(tracy_log) log_world("World rebooted at [time_stamp()]") shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss. + shutdown_byond_tracy() auxcleanup() TgsReboot() // TGS can decide to kill us right here, so it's important to do it last @@ -351,6 +374,7 @@ GLOBAL_VAR(tracy_log) call_ext(debug_server, "auxtools_shutdown")() /world/Del() + shutdown_byond_tracy() auxcleanup() . = ..() @@ -483,21 +507,31 @@ GLOBAL_VAR(tracy_log) DREAMLUAU_SET_EXECUTION_LIMIT_MILLIS(tick_lag * 100) /world/proc/init_byond_tracy() - var/library - - switch (system_type) - if (MS_WINDOWS) - library = "prof.dll" - if (UNIX) - library = "libprof.so" - else - CRASH("Unsupported platform: [system_type]") + if(!fexists(TRACY_DLL_PATH)) + SEND_TEXT(world.log, "Error initializing byond-tracy: [TRACY_DLL_PATH] not found!") + CRASH("Error initializing byond-tracy: [TRACY_DLL_PATH] not found!") - var/init_result = call_ext(library, "init")("block") + var/init_result = call_ext(TRACY_DLL_PATH, "init")("block") if(length(init_result) != 0 && init_result[1] == ".") // if first character is ., then it returned the output filename - return init_result + SEND_TEXT(world.log, "byond-tracy initialized (logfile: [init_result])") + GLOB.tracy_initialized = TRUE + return GLOB.tracy_log = init_result + else if(init_result == "already initialized") // not gonna question it. + GLOB.tracy_initialized = TRUE + SEND_TEXT(world.log, "byond-tracy already initialized ([GLOB.tracy_log ? "logfile: [GLOB.tracy_log]" : "no logfile"])") else if(init_result != "0") + GLOB.tracy_init_error = init_result + SEND_TEXT(world.log, "Error initializing byond-tracy: [init_result]") CRASH("Error initializing byond-tracy: [init_result]") + else + GLOB.tracy_initialized = TRUE + SEND_TEXT(world.log, "byond-tracy initialized (no logfile)") + +/world/proc/shutdown_byond_tracy() + if(GLOB.tracy_initialized) + SEND_TEXT(world.log, "Shutting down byond-tracy") + GLOB.tracy_initialized = FALSE + call_ext(TRACY_DLL_PATH, "destroy")() /world/proc/init_debugger() var/dll = GetConfig("env", "AUXTOOLS_DEBUG_DLL") diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index b6c5e10ca1d81..13f1995c9ba3d 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -852,3 +852,42 @@ ADMIN_VERB(check_missing_sprites, R_DEBUG, "Debug Worn Item Sprites", "We're can actual_file_name = 'icons/mob/clothing/belt_mirror.dmi' if(!(sprite.icon_state in icon_states(actual_file_name))) to_chat(user, span_warning("ERROR sprites for [sprite.type]. Suit Storage slot."), confidential = TRUE) + +#ifndef OPENDREAM +ADMIN_VERB(start_tracy, R_DEBUG, "Run Tracy Now", "Start running the byond-tracy profiler immediately", ADMIN_CATEGORY_DEBUG) + if(GLOB.tracy_initialized) + to_chat(user, span_warning("byond-tracy is already running!"), avoid_highlighting = TRUE, type = MESSAGE_TYPE_DEBUG, confidential = TRUE) + return + else if(GLOB.tracy_init_error) + to_chat(user, span_danger("byond-tracy failed to initialize during an earlier attempt: [GLOB.tracy_init_error]"), avoid_highlighting = TRUE, type = MESSAGE_TYPE_DEBUG, confidential = TRUE) + return + message_admins(span_adminnotice("[key_name_admin(user)] is trying to start the byond-tracy profiler.")) + log_admin("[key_name(user)] is trying to start the byond-tracy profiler.") + GLOB.tracy_initialized = FALSE + GLOB.tracy_init_reason = "[user.ckey]" + world.init_byond_tracy() + if(GLOB.tracy_init_error) + to_chat(user, span_danger("byond-tracy failed to initialize: [GLOB.tracy_init_error]"), avoid_highlighting = TRUE, type = MESSAGE_TYPE_DEBUG, confidential = TRUE) + message_admins(span_adminnotice("[key_name_admin(user)] tried to start the byond-tracy profiler, but it failed to initialize ([GLOB.tracy_init_error])")) + log_admin("[key_name(user)] tried to start the byond-tracy profiler, but it failed to initialize ([GLOB.tracy_init_error])") + return + to_chat(user, span_notice("byond-tracy successfully started!"), avoid_highlighting = TRUE, type = MESSAGE_TYPE_DEBUG, confidential = TRUE) + message_admins(span_adminnotice("[key_name_admin(user)] started the byond-tracy profiler.")) + log_admin("[key_name(user)] started the byond-tracy profiler.") + if(GLOB.tracy_log) + rustg_file_write("[GLOB.tracy_log]", "[GLOB.log_directory]/tracy.loc") + +ADMIN_VERB_CUSTOM_EXIST_CHECK(start_tracy) + return CONFIG_GET(flag/allow_tracy_start) && fexists(TRACY_DLL_PATH) + +ADMIN_VERB(queue_tracy, R_DEBUG, "Toggle Tracy Next Round", "Toggle running the byond-tracy profiler next round", ADMIN_CATEGORY_DEBUG) + if(fexists(TRACY_ENABLE_PATH)) + fdel(TRACY_ENABLE_PATH) + else + rustg_file_write("[user.ckey]", TRACY_ENABLE_PATH) + message_admins(span_adminnotice("[key_name_admin(user)] [fexists(TRACY_ENABLE_PATH) ? "enabled" : "disabled"] the byond-tracy profiler for next round.")) + log_admin("[key_name(user)] [fexists(TRACY_ENABLE_PATH) ? "enabled" : "disabled"] the byond-tracy profiler for next round.") + +ADMIN_VERB_CUSTOM_EXIST_CHECK(queue_tracy) + return CONFIG_GET(flag/allow_tracy_queue) && fexists(TRACY_DLL_PATH) +#endif diff --git a/config/config.txt b/config/config.txt index 1e5f5cb10e4af..4d11dcd2ea24f 100644 --- a/config/config.txt +++ b/config/config.txt @@ -609,3 +609,9 @@ UPLOAD_LIMIT 524288 ## Restricts admin client uploads to the server, defined in bytes, default is 5MB UPLOAD_LIMIT_ADMIN 5242880 + +## Uncomment to allow admins with +DEBUG to start the byond-tracy profiler during the round. +#ALLOW_TRACY_START + +## Uncomment to allow admins with +DEBUG to queue the next round to run the byond-tracy profiler. +#ALLOW_TRACY_QUEUE diff --git a/tgstation.dme b/tgstation.dme index d2d4aca3e0dcc..606ddb3453dfd 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -244,6 +244,7 @@ #include "code\__DEFINES\time.dm" #include "code\__DEFINES\tools.dm" #include "code\__DEFINES\toys.dm" +#include "code\__DEFINES\tracy.dm" #include "code\__DEFINES\trader.dm" #include "code\__DEFINES\transport.dm" #include "code\__DEFINES\tts.dm" From 922af074d18533c7954d9d7e2a4ccd4b882c411e Mon Sep 17 00:00:00 2001 From: zxaber <37497534+zxaber@users.noreply.github.com> Date: Fri, 15 Nov 2024 07:16:05 -0800 Subject: [PATCH 092/222] Fixes mechs with crowbar-like tools holding firelocks open at a distance (#87907) ## About The Pull Request Changes firelock code to register signals on the atom holding the crowbar, not necessarily the mob that initiated the action. Since mobs inside mechs don't technically move, signals listening for the mob's movement wouldn't fire until the mob exits the mech. Registering the signal on the crowbar owner (mech in this case) solves the issue. This makes no change to mobs holding crowbars, as the mob is considered the crowbar owner in that case, and is thus handled identically as before. ## Why It's Good For The Game Prevents this: https://github.com/user-attachments/assets/77150360-c1c2-46a0-8943-3b80fbd5a9e8 ## Changelog :cl: fix: Firelocks opened by a mech will correctly close when the mech moves out of range. /:cl: --- code/game/machinery/doors/firedoor.dm | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 858f2dffefff2..36828273f1944 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -548,18 +548,20 @@ if(welded || operating) return + var/atom/crowbar_owner = acting_object.loc //catchs mechs and any other non-mob using a crowbar + if(density) being_held_open = TRUE - user.balloon_alert_to_viewers("holding firelock open", "holding firelock open") + crowbar_owner.balloon_alert_to_viewers("holding firelock open", "holding firelock open") COOLDOWN_START(src, activation_cooldown, REACTIVATION_DELAY) open() - if(QDELETED(user)) + if(QDELETED(crowbar_owner)) being_held_open = FALSE return - RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(handle_held_open_adjacency)) - RegisterSignal(user, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(handle_held_open_adjacency)) - RegisterSignal(user, COMSIG_QDELETING, PROC_REF(handle_held_open_adjacency)) - handle_held_open_adjacency(user) + RegisterSignal(crowbar_owner, COMSIG_MOVABLE_MOVED, PROC_REF(handle_held_open_adjacency)) + RegisterSignal(crowbar_owner, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(handle_held_open_adjacency)) + RegisterSignal(crowbar_owner, COMSIG_QDELETING, PROC_REF(handle_held_open_adjacency)) + handle_held_open_adjacency(crowbar_owner) else close() From 6f3254ea7ac58b3bea114cb79efe2317595a6ceb Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 15:16:35 +0000 Subject: [PATCH 093/222] Automatic changelog for PR #87907 [ci skip] --- html/changelogs/AutoChangeLog-pr-87907.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87907.yml diff --git a/html/changelogs/AutoChangeLog-pr-87907.yml b/html/changelogs/AutoChangeLog-pr-87907.yml new file mode 100644 index 0000000000000..f193ce7beefb7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87907.yml @@ -0,0 +1,4 @@ +author: "zxaber" +delete-after: True +changes: + - bugfix: "Firelocks opened by a mech will correctly close when the mech moves out of range." \ No newline at end of file From d301e90513c4d091f5fee8edbe9d6c57e7658732 Mon Sep 17 00:00:00 2001 From: memecraft22 <159744229+memecraft22@users.noreply.github.com> Date: Fri, 15 Nov 2024 12:03:06 -0600 Subject: [PATCH 094/222] Round start janitor tip (#87919) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## About The Pull Request Adds a new janitor tooltip ## Why It's Good For The Game This feature isn’t very well known --- strings/tips.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/strings/tips.txt b/strings/tips.txt index 7d5f9f82ccc2e..2e80296af2258 100644 --- a/strings/tips.txt +++ b/strings/tips.txt @@ -55,6 +55,7 @@ As a Heretic, the Path of Cosmos allows you to take rightful ownership of the ve As a Janitor Cyborg, you are the bane of all slaughter demons and even Bubblegum himself. Cleaning up blood stains will severely gimp them. As a Janitor, if someone steals your janicart, you can instead use your space cleaner spray, grenades, water sprayer, exact bloody revenge or order another from Cargo. As a Janitor, mousetraps can be used to create bombs or booby-trap containers. +As a Janitor, you can command cleanbots by pointing at a tile and saying mop/clean. As a Medical Cyborg, you can fully perform surgery and even augment people. As a Medical Doctor, almost every type of wound can be treated at least temporarily with gauze. When in doubt, wrap it up! As a Medical Doctor, corpses placed inside a freezer or morgue tray will have their organs frozen preventing decay. If you don't have time to revive multiple dead bodies, transfer them to the morgue temporarily! From 6c30a0179b1e39dcf2411dcf39561b3043ac19e1 Mon Sep 17 00:00:00 2001 From: carlarctg <53100513+carlarctg@users.noreply.github.com> Date: Fri, 15 Nov 2024 15:25:25 -0300 Subject: [PATCH 095/222] Adds the Perceptomatrix Helm, a hallucination anomaly core item. (#87701) ## About The Pull Request Changes the color of hallucination cores from red (?) to hot pink. Adds the Perceptomatrix Helm, a hallucination anomaly core item. ![image](https://github.com/user-attachments/assets/d1b37313-f141-4638-b950-7d58556dbf8d) This helmet shields the user's brain from all external stimuli while creating a 1:1 replica of it, beamed straight into their mind. What this means in practice is that the user's perception is hypercharged and their brain shielded from psychic phenomena. The sprite is a resprited marine helmet. It's mid and I don't like it but I'm not a spriter. List of effects: Perception: - Flash/Weld Immunity - True Night Vision - Blindness and blurriness immunity - Expanded FOV Brain Shielding: - Perceptual Trauma Immunity - Hallucination Immunity Psyshield: - Conversion and Mindswap Immunity - Magical Mind Resistance (Much more limited than normal resistance) - Technically counts as casting clothes Additionally, you can an ability to invoke hallucinations on others on a 25-second cooldown. ![image](https://github.com/user-attachments/assets/7dd4eaba-90ba-4e67-a302-2aae844009a7) ## Why It's Good For The Game I'm kinda tired of half the anomaly cores in the game having jack and shit going for them. I also think there's a moderate lack of psychic content in the game, so here we go. ### Yeah this is cool but like isn't it kinda fucking nuts? Holy shit dude Let's dissect this. > Perception: > - Flash/Weld Immunity > - True Night Vision > - Blindness and blurriness immunity > - Expanded FOV This part effectively amounts to nothing but night vision sunglasses. > Brain Shielding: > - Perceptual Trauma Immunity > - Hallucination Immunity This isn't all that impactful, either. Hallucination immunity is immensely irrelevant. Perceptual trauma immunity, which means you ignore effects like blindness or imaginary friends, is very, very niche. > Psyshield: > - Conversion and Mindswap Immunity > - Magical Mind Resistance (Much more limited than normal resistance) > - Technically counts as casting clothes Basically just having a mindshield, and that only if you don't get it taken off anyways. Mindswap immunity could be nice, that's really not something you can even get otherwise. Magical mind resistance isn't very good. It blocks mind reading, nullblade sneak attacks, eye of god, many forms of telepathy, psyker magic, the curse of madness, the curse of babel, and that's about it. It's nice, but it won't stop a fireball. A lot of this can in the end be duplicated with sunglasses & oculine/mesons and welding protection, and a tinfoil hat, which is partly why I added the ability. It staggers for a small duration and causes hallucinations, and it's pretty fun to use, despite its effects being rather understated. --- code/__DEFINES/traits/declarations.dm | 6 + code/_globalvars/traits/_traits.dm | 3 + code/datums/components/earprotection.dm | 9 +- .../status_effects/debuffs/blindness.dm | 41 ++- .../status_effects/debuffs/hallucination.dm | 14 +- .../status_effects/debuffs/screen_blur.dm | 10 +- code/modules/client/client_colour.dm | 3 + code/modules/clothing/head/perceptomatrix.dm | 248 ++++++++++++++++++ icons/effects/beam.dmi | Bin 128198 -> 130816 bytes icons/mob/clothing/head/helmet.dmi | Bin 45093 -> 44167 bytes icons/obj/clothing/head/helmet.dmi | Bin 20826 -> 18939 bytes icons/obj/devices/new_assemblies.dmi | Bin 27087 -> 27564 bytes tgstation.dme | 1 + 13 files changed, 324 insertions(+), 11 deletions(-) create mode 100644 code/modules/clothing/head/perceptomatrix.dm diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index f4f5688819bb2..a0448be48c039 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -391,6 +391,12 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_DETECT_STORM "detect_storm" #define TRAIT_PRIMITIVE "primitive" #define TRAIT_GUNFLIP "gunflip" +/// eignore blindness or blurriness or nearsightedness +#define TRAIT_SIGHT_BYPASS "perfect_sight" +/// ignore traumas that make you 'hallucinate' something +#define TRAIT_PERCEPTUAL_TRAUMA_BYPASS "trauma_bypass" +/// mob is immune to hallucinations +#define TRAIT_HALLUCINATION_IMMUNE "hallucination_immune" /// Increases chance of getting special traumas, makes them harder to cure #define TRAIT_SPECIAL_TRAUMA_BOOST "special_trauma_boost" #define TRAIT_SPACEWALK "spacewalk" diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 46a91854931ef..f7556662b97f1 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -275,6 +275,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_GREENTEXT_CURSED" = TRAIT_GREENTEXT_CURSED, "TRAIT_GUNFLIP" = TRAIT_GUNFLIP, "TRAIT_GUN_NATURAL" = TRAIT_GUN_NATURAL, + "TRAIT_HALLUCINATION_IMMUNE" = TRAIT_HALLUCINATION_IMMUNE, "TRAIT_HALT_RADIATION_EFFECTS" = TRAIT_HALT_RADIATION_EFFECTS, "TRAIT_HANDS_BLOCKED" = TRAIT_HANDS_BLOCKED, "TRAIT_HARDLY_WOUNDED" = TRAIT_HARDLY_WOUNDED, @@ -416,6 +417,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_PASSTABLE" = TRAIT_PASSTABLE, "TRAIT_PASSWINDOW" = TRAIT_PASSWINDOW, "TRAIT_PERCEIVED_AS_CLOWN" = TRAIT_PERCEIVED_AS_CLOWN, + "TRAIT_PERCEPTUAL_TRAUMA_BYPASS" = TRAIT_PERCEPTUAL_TRAUMA_BYPASS, "TRAIT_PERFECT_ATTACKER" = TRAIT_PERFECT_ATTACKER, "TRAIT_PERMANENTLY_MORTAL" = TRAIT_PERMANENTLY_MORTAL, "TRAIT_PHOTOGRAPHER" = TRAIT_PHOTOGRAPHER, @@ -465,6 +467,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_SHAVED" = TRAIT_SHAVED, "TRAIT_SHIFTY_EYES" = TRAIT_SHIFTY_EYES, "TRAIT_SHOCKIMMUNE" = TRAIT_SHOCKIMMUNE, + "TRAIT_SIGHT_BYPASS" = TRAIT_SIGHT_BYPASS, "TRAIT_SIGN_LANG" = TRAIT_SIGN_LANG, "TRAIT_SILENT_FOOTSTEPS" = TRAIT_SILENT_FOOTSTEPS, "TRAIT_SILICON_ACCESS" = TRAIT_SILICON_ACCESS, diff --git a/code/datums/components/earprotection.dm b/code/datums/components/earprotection.dm index 6439e49b831f5..6dfa7d9568baf 100644 --- a/code/datums/components/earprotection.dm +++ b/code/datums/components/earprotection.dm @@ -2,10 +2,13 @@ signals = list(COMSIG_CARBON_SOUNDBANG) mobtype = /mob/living/carbon proctype = PROC_REF(reducebang) + var/reduce_amount = 1 -/datum/component/wearertargeting/earprotection/Initialize(_valid_slots) +/datum/component/wearertargeting/earprotection/Initialize(valid_slots, reduce_amount = 1) . = ..() - valid_slots = _valid_slots + src.valid_slots = valid_slots + if(reduce_amount) + src.reduce_amount = reduce_amount /datum/component/wearertargeting/earprotection/proc/reducebang(datum/source, list/reflist) - reflist[1]-- + reflist[1] -= reduce_amount diff --git a/code/datums/status_effects/debuffs/blindness.dm b/code/datums/status_effects/debuffs/blindness.dm index 06a5a46b9427b..edb10d27ba44b 100644 --- a/code/datums/status_effects/debuffs/blindness.dm +++ b/code/datums/status_effects/debuffs/blindness.dm @@ -11,7 +11,12 @@ // fullheal should instead remove all the sources and in turn cure this /// Static list of signals that, when received, we force an update to our nearsighted overlay - var/static/list/update_signals = list(SIGNAL_ADDTRAIT(TRAIT_NEARSIGHTED_CORRECTED), SIGNAL_REMOVETRAIT(TRAIT_NEARSIGHTED_CORRECTED)) + var/static/list/update_signals = list( + SIGNAL_ADDTRAIT(TRAIT_NEARSIGHTED_CORRECTED), + SIGNAL_REMOVETRAIT(TRAIT_NEARSIGHTED_CORRECTED), + SIGNAL_ADDTRAIT(TRAIT_SIGHT_BYPASS), + SIGNAL_REMOVETRAIT(TRAIT_SIGHT_BYPASS), + ) /// How severe is our nearsightedness right now var/overlay_severity = 2 @@ -37,7 +42,11 @@ var/mob/living/carbon/human/human_owner = owner if (human_owner.get_eye_scars()) return TRUE - return !HAS_TRAIT(owner, TRAIT_NEARSIGHTED_CORRECTED) + if(HAS_TRAIT(owner, TRAIT_NEARSIGHTED_CORRECTED)) + return FALSE + if(HAS_TRAIT(owner, TRAIT_SIGHT_BYPASS)) + return FALSE + return TRUE /// Updates our nearsightd overlay, either removing it if we have the trait or adding it if we don't /datum/status_effect/grouped/nearsighted/proc/update_nearsighted_overlay() @@ -61,6 +70,10 @@ id = "blindness" tick_interval = STATUS_EFFECT_NO_TICK alert_type = /atom/movable/screen/alert/status_effect/blind + var/static/list/update_signals = list( + SIGNAL_REMOVETRAIT(TRAIT_SIGHT_BYPASS), + SIGNAL_ADDTRAIT(TRAIT_SIGHT_BYPASS), + ) // This is not "remove on fullheal" as in practice, // fullheal should instead remove all the sources and in turn cure this @@ -68,14 +81,34 @@ if(!CAN_BE_BLIND(owner)) return FALSE + RegisterSignals(owner, update_signals, PROC_REF(update_blindness)) + + update_blindness() + + return ..() + +/datum/status_effect/grouped/blindness/proc/update_blindness() + if(!CAN_BE_BLIND(owner)) // future proofing + qdel(src) + return + + if(HAS_TRAIT(owner, TRAIT_SIGHT_BYPASS)) + make_unblind() + return + make_blind() + +/datum/status_effect/grouped/blindness/proc/make_blind() owner.overlay_fullscreen(id, /atom/movable/screen/fullscreen/blind) // You are blind - at most, able to make out shapes near you owner.add_client_colour(/datum/client_colour/monochrome/blind) - return ..() -/datum/status_effect/grouped/blindness/on_remove() +/datum/status_effect/grouped/blindness/proc/make_unblind() owner.clear_fullscreen(id) owner.remove_client_colour(/datum/client_colour/monochrome/blind) + +/datum/status_effect/grouped/blindness/on_remove() + make_unblind() + UnregisterSignal(owner, update_signals) return ..() /atom/movable/screen/alert/status_effect/blind diff --git a/code/datums/status_effects/debuffs/hallucination.dm b/code/datums/status_effects/debuffs/hallucination.dm index 3f24ab02e60ac..66e85f1900a23 100644 --- a/code/datums/status_effects/debuffs/hallucination.dm +++ b/code/datums/status_effects/debuffs/hallucination.dm @@ -14,27 +14,39 @@ /// The cooldown for when the next hallucination can occur COOLDOWN_DECLARE(hallucination_cooldown) -/datum/status_effect/hallucination/on_creation(mob/living/new_owner, duration) +/datum/status_effect/hallucination/on_creation(mob/living/new_owner, duration, lower_tick_interval, upper_tick_interval) if(isnum(duration)) src.duration = duration + if(isnum(lower_tick_interval)) + src.lower_tick_interval = lower_tick_interval + if(isnum(upper_tick_interval)) + src.upper_tick_interval = upper_tick_interval return ..() /datum/status_effect/hallucination/on_apply() if(owner.mob_biotypes & barred_biotypes) return FALSE + if(HAS_TRAIT(owner, TRAIT_HALLUCINATION_IMMUNE)) + return FALSE RegisterSignal(owner, COMSIG_LIVING_HEALTHSCAN, PROC_REF(on_health_scan)) + RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_HALLUCINATION_IMMUNE), PROC_REF(delete_self)) if(iscarbon(owner)) RegisterSignal(owner, COMSIG_CARBON_CHECKING_BODYPART, PROC_REF(on_check_bodypart)) RegisterSignal(owner, COMSIG_CARBON_BUMPED_AIRLOCK_OPEN, PROC_REF(on_bump_airlock)) return TRUE +/datum/status_effect/hallucination/proc/delete_self() + SIGNAL_HANDLER + qdel(src) + /datum/status_effect/hallucination/on_remove() UnregisterSignal(owner, list( COMSIG_LIVING_HEALTHSCAN, COMSIG_CARBON_CHECKING_BODYPART, COMSIG_CARBON_BUMPED_AIRLOCK_OPEN, + SIGNAL_ADDTRAIT(TRAIT_HALLUCINATION_IMMUNE), )) /// Signal proc for [COMSIG_LIVING_HEALTHSCAN]. Show we're hallucinating to (advanced) scanners. diff --git a/code/datums/status_effects/debuffs/screen_blur.dm b/code/datums/status_effects/debuffs/screen_blur.dm index abdd07d3cd59b..acdce13b5a08a 100644 --- a/code/datums/status_effects/debuffs/screen_blur.dm +++ b/code/datums/status_effects/debuffs/screen_blur.dm @@ -18,7 +18,8 @@ return FALSE // Refresh the blur when a client jumps into the mob, in case we get put on a clientless mob with no hud - RegisterSignal(owner, COMSIG_MOB_LOGIN, PROC_REF(update_blur)) + RegisterSignals(owner, list(COMSIG_MOB_LOGIN, SIGNAL_ADDTRAIT(TRAIT_SIGHT_BYPASS), SIGNAL_REMOVETRAIT(TRAIT_SIGHT_BYPASS)), PROC_REF(update_blur)) + // Apply initial blur update_blur() return TRUE @@ -43,10 +44,13 @@ if(!owner.hud_used) return + var/atom/movable/plane_master_controller/game_plane_master_controller = owner.hud_used.plane_master_controllers[PLANE_MASTERS_GAME] + if(HAS_TRAIT(owner, TRAIT_SIGHT_BYPASS)) + game_plane_master_controller.remove_filter("eye_blur") + return + var/time_left_in_seconds = (duration - world.time) / (1 SECONDS) var/amount_of_blur = clamp(time_left_in_seconds * BLUR_DURATION_TO_INTENSITY, 0.6, 3) - - var/atom/movable/plane_master_controller/game_plane_master_controller = owner.hud_used.plane_master_controllers[PLANE_MASTERS_GAME] game_plane_master_controller.add_filter("eye_blur", 1, gauss_blur_filter(amount_of_blur)) #undef BLUR_DURATION_TO_INTENSITY diff --git a/code/modules/client/client_colour.dm b/code/modules/client/client_colour.dm index 4ca500a9e7198..08e79c305a454 100644 --- a/code/modules/client/client_colour.dm +++ b/code/modules/client/client_colour.dm @@ -220,6 +220,9 @@ /datum/client_colour/malfunction colour = list(/*R*/ 0,0,0,0, /*G*/ 0,175,0,0, /*B*/ 0,0,0,0, /*A*/ 0,0,0,1, /*C*/0,-130,0,0) // Matrix colors +/datum/client_colour/perceptomatrix + colour = list(/*R*/ 1,0,0,0, /*G*/ 0,1,0,0, /*B*/ 0,0,1,0, /*A*/ 0,0,0,1, /*C*/0,-0.02,-0.02,0) // veeery slightly pink + /datum/client_colour/monochrome colour = COLOR_MATRIX_GRAYSCALE priority = PRIORITY_HIGH //we can't see colors anyway! diff --git a/code/modules/clothing/head/perceptomatrix.dm b/code/modules/clothing/head/perceptomatrix.dm new file mode 100644 index 0000000000000..f11bad99eaf5b --- /dev/null +++ b/code/modules/clothing/head/perceptomatrix.dm @@ -0,0 +1,248 @@ + +#define PERCEPTOMATRIX_INACTIVE_FLAGS SNUG_FIT|STACKABLE_HELMET_EXEMPT|STOPSPRESSUREDAMAGE|BLOCK_GAS_SMOKE_EFFECT +#define PERCEPTOMATRIX_ACTIVE_FLAGS PERCEPTOMATRIX_INACTIVE_FLAGS|CASTING_CLOTHES // we love casting spells + +/// Belt which can turn you into a beast, once an anomaly core is inserted +/obj/item/clothing/head/helmet/perceptomatrix + name = "perceptomatrix helm" + desc = "This piece of headgear harnesses the energies of a hallucinative anomaly to create a safe audiovisual replica of -all- external stimuli directly into the cerebral cortex, \ + granting the user effective immunity to both psychic threats, and anything that would affect their perception - be it ear, eye, or even brain damage. \ + It can also violently discharge said energy, inducing hallucinations in others." + icon_state = "perceptomatrix_helmet_inactive" + worn_icon_state = "perceptomatrix_helmet_inactive" + base_icon_state = "perceptomatrix_helmet" + force = 10 + dog_fashion = null + cold_protection = HEAD + min_cold_protection_temperature = HELMET_MIN_TEMP_PROTECT + heat_protection = HEAD + max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT + strip_delay = 8 SECONDS + clothing_flags = PERCEPTOMATRIX_ACTIVE_FLAGS + clothing_traits = list( + /* eye/ear protection */ + TRAIT_NOFLASH, + TRAIT_TRUE_NIGHT_VISION, + TRAIT_SIGHT_BYPASS, + TRAIT_EXPANDED_FOV, + TRAIT_GOOD_HEARING, + /* mental protection */ + TRAIT_PERCEPTUAL_TRAUMA_BYPASS, + TRAIT_RDS_SUPPRESSED, + TRAIT_MADNESS_IMMUNE, + TRAIT_HALLUCINATION_IMMUNE, + /* psychic protection */ + TRAIT_NO_MINDSWAP, + TRAIT_UNCONVERTABLE, + ) + flags_cover = HEADCOVERSEYES|EARS_COVERED + flags_inv = HIDEHAIR|HIDEFACE + flash_protect = FLASH_PROTECTION_WELDER_SENSITIVE + resistance_flags = FIRE_PROOF | ACID_PROOF + equip_sound = 'sound/items/handling/helmet/helmet_equip1.ogg' + pickup_sound = 'sound/items/handling/helmet/helmet_pickup1.ogg' + drop_sound = 'sound/items/handling/helmet/helmet_drop1.ogg' + armor_type = /datum/armor/head_helmet_matrix + actions_types = list(/datum/action/cooldown/spell/pointed/percept_hallucination) + + /// If we have a core or not + var/core_installed = FALSE + /// Active components to add onto the mob, deleted and created on core installation/removal + var/list/active_components = list() + +// weaker overall but better against energy +/datum/armor/head_helmet_matrix + melee = 15 + bullet = 15 + laser = 45 + energy = 60 + bomb = 15 + fire = 50 + acid = 50 + wound = 10 + +/obj/item/clothing/head/helmet/perceptomatrix/Initialize(mapload) + . = ..() + + update_appearance(UPDATE_ICON_STATE) + update_anomaly_state() + +/obj/item/clothing/head/helmet/perceptomatrix/equipped(mob/living/user, slot) + . = ..() + if(slot & ITEM_SLOT_HEAD) + RegisterSignal(user, COMSIG_MOB_BEFORE_SPELL_CAST, PROC_REF(pre_cast_core_check)) + +/obj/item/clothing/head/helmet/perceptomatrix/dropped(mob/living/user, silent) + UnregisterSignal(user, COMSIG_MOB_BEFORE_SPELL_CAST) + ..() + +// Prevent casting the spell w/o the core. +/obj/item/clothing/head/helmet/perceptomatrix/proc/pre_cast_core_check(mob/caster, datum/action/cooldown/spell/spell) + SIGNAL_HANDLER + if((!core_installed) && spell.school == SCHOOL_PSYCHIC) + to_chat(caster, span_warning("You can't zap minds through [src]'s shielding without a core installed!")) + return SPELL_CANCEL_CAST + +/obj/item/clothing/head/helmet/perceptomatrix/proc/update_anomaly_state() + + // If the core isn't installed, or it's temporarily deactivated, disable special functions. + if(!core_installed) + clothing_flags = PERCEPTOMATRIX_INACTIVE_FLAGS + detach_clothing_traits(clothing_traits) + QDEL_LIST(active_components) + RemoveElement(/datum/element/wearable_client_colour, /datum/client_colour/perceptomatrix, ITEM_SLOT_HEAD, forced = TRUE) + return + + clothing_flags = PERCEPTOMATRIX_ACTIVE_FLAGS + attach_clothing_traits(initial(clothing_traits)) + + // When someone makes TRAIT_DEAF an element, or status effect, or whatever, give this item a way to bypass said deafness. + // just blocking future instances of deafness isn't what the item is meant to do but there's no proper way to do it otherwise at the moment. + active_components += AddComponent(/datum/component/wearertargeting/earprotection, list(ITEM_SLOT_HEAD), reduce_amount = 2) // should be same as highest value + active_components += AddComponent( + /datum/component/anti_magic, \ + antimagic_flags = MAGIC_RESISTANCE_MIND, \ + inventory_flags = ITEM_SLOT_HEAD, \ + ) + AddElement(/datum/element/wearable_client_colour, /datum/client_colour/perceptomatrix, ITEM_SLOT_HEAD, forced = TRUE) + + update_icon_state() + +/obj/item/clothing/head/helmet/perceptomatrix/Destroy(force) + QDEL_LIST(active_components) + return ..() + +/obj/item/clothing/head/helmet/perceptomatrix/examine(mob/user) + . = ..() + if (!core_installed) + . += span_warning("It requires a hallucination anomaly core in order to function.") + +/obj/item/clothing/head/helmet/perceptomatrix/item_action_slot_check(slot, mob/user, datum/action/action) + return slot & ITEM_SLOT_HEAD + +/obj/item/clothing/head/helmet/perceptomatrix/update_icon_state() + icon_state = base_icon_state + (core_installed ? "" : "_inactive") + worn_icon_state = base_icon_state + (core_installed ? "" : "_inactive") + return ..() + +/obj/item/clothing/head/helmet/perceptomatrix/item_interaction(mob/user, obj/item/weapon, params) + if (!istype(weapon, /obj/item/assembly/signaler/anomaly/hallucination)) + return NONE + balloon_alert(user, "inserting...") + if (!do_after(user, delay = 3 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING + qdel(weapon) + core_installed = TRUE + update_anomaly_state() + update_appearance(UPDATE_ICON_STATE) + playsound(src, 'sound/machines/crate/crate_open.ogg', 50, FALSE) + return ITEM_INTERACT_SUCCESS + +/obj/item/clothing/head/helmet/perceptomatrix/functioning + core_installed = TRUE + +/datum/action/cooldown/spell/pointed/percept_hallucination + name = "Hallucinate" + desc = "Redirect perceptual energies towards a target, staggering them." + button_icon_state = "blind" + ranged_mousepointer = 'icons/effects/mouse_pointers/blind_target.dmi' + + sound = 'sound/items/weapons/emitter2.ogg' + school = SCHOOL_PSYCHIC + cooldown_time = 15 SECONDS + + invocation_type = INVOCATION_NONE + spell_requirements = NONE + antimagic_flags = MAGIC_RESISTANCE_MIND + + active_msg = "You prepare to zap a target with hallucinations..." + + /// The amount of blurriness to apply + var/eye_blur_duration = 7 SECONDS + /// The amount of stagger to apply + var/stagger_duration = 3 SECONDS + /// The amount of hallucination to apply + var/hallucination_duration = 25 SECONDS + /// Spark system + var/datum/effect_system/spark_spread/quantum/spark_sys + +/datum/action/cooldown/spell/pointed/percept_hallucination/New(Target) + . = ..() + + spark_sys = new /datum/effect_system/spark_spread/quantum + +/datum/action/cooldown/spell/pointed/percept_hallucination/Destroy() + QDEL_NULL(spark_sys) + return ..() + +/datum/action/cooldown/spell/pointed/percept_hallucination/is_valid_target(atom/cast_on) + . = ..() + if(!.) + return FALSE + if(ishuman(cast_on)) + return TRUE + if(istype(cast_on, /obj/item/food/pancakes)) + return TRUE + + return FALSE + +/datum/action/cooldown/spell/pointed/percept_hallucination/proc/blows_up_pancakes_with_mind(obj/item/food/pancakes/pancakes) + + owner.visible_message( + span_userdanger("[owner] blows up [pancakes] with [owner.p_their()] mind!"), + span_userdanger("You blow up [pancakes] with your mind!") + ) + + for(var/mob/chef in get_hearers_in_view(7, pancakes)) + if(!chef.mind) + continue + // if cooked by chef, or if EITHER 5% chance OR its april fools. a || (b || c) + if(HAS_TRAIT_FROM(pancakes, TRAIT_FOOD_CHEF_MADE, REF(chef.mind)) || (prob(5) || check_holidays(APRIL_FOOLS))) + chef.say("Ma fuckin' pancakes!") + + playsound(pancakes, 'sound/effects/fuse.ogg', 80) + animate(pancakes, time = 1, pixel_z = 12, easing = ELASTIC_EASING) + animate(time = 1, pixel_z = 0, easing = BOUNCE_EASING) + for(var/i in 1 to 15) + animate(color = (i % 2) ? "#ffffff": "#ff6739", time = 1, easing = QUAD_EASING, flags = ANIMATION_CONTINUE) + + addtimer(CALLBACK(src, PROC_REF(pancake_explosion), pancakes), 1.5 SECONDS) + +/datum/action/cooldown/spell/pointed/percept_hallucination/proc/pancake_explosion(obj/pancakes) + explosion(pancakes, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 1, flame_range = 2) + qdel(pancakes) + StartCooldown() + +/datum/action/cooldown/spell/pointed/percept_hallucination/proc/cast_fx(atom/cast_on) + owner.Beam(cast_on, icon_state = "greyscale_lightning", beam_color = COLOR_FADED_PINK, time = 0.5 SECONDS) + + spark_sys.set_up(2, 1, get_turf(owner)) + spark_sys.start() + spark_sys.set_up(4, 1, get_turf(cast_on)) + spark_sys.start() + +/datum/action/cooldown/spell/pointed/percept_hallucination/cast(mob/living/carbon/human/cast_on) + . = ..() + + cast_fx(cast_on) + + if(istype(cast_on, /obj/item/food/pancakes)) + blows_up_pancakes_with_mind(cast_on) + return + + if(cast_on.can_block_magic(antimagic_flags)) + to_chat(cast_on, span_notice("You feel psychic energies reflecting off you.")) + to_chat(owner, span_warning("[cast_on] deflects the energy!")) + return + + to_chat(cast_on, span_warning("Your brain feels like it's on fire!")) + cast_on.emote("scream") + cast_on.set_eye_blur_if_lower(eye_blur_duration) + cast_on.adjust_staggered(stagger_duration) + cast_on.apply_status_effect(/datum/status_effect/hallucination, hallucination_duration, \ + hallucination_duration * 0.2, hallucination_duration) // lower/upper hallucination freq. bound + + return + +#undef PERCEPTOMATRIX_INACTIVE_FLAGS +#undef PERCEPTOMATRIX_ACTIVE_FLAGS diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index 85d450e03bdd64fa5d1ca6c01d239ce43876784a..41bdf992bbf4146752a8549734f2d90cafe9b63a 100644 GIT binary patch literal 130816 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 pfvYf%&@At6E2W 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 literal 128198 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 diff --git a/icons/mob/clothing/head/helmet.dmi b/icons/mob/clothing/head/helmet.dmi index db48dda1fd61c6343bbac93b9a7ff84fbf604e54..05fe660a33a290c53823ca765f902b53ace93b7b 100644 GIT binary patch literal 44167 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 Nw=HbVt4!U<{{gqv53~RP literal 20826 zcmcG$byOT*vo_jDa1HK|1PKJ!1cDQSO9T%P2=49-4nY%wyIYXp?h=B#Gq?vIWEkK! zzxO@gI`^}C&L4LzdhMC%X3wrIPgOltHDRjCvbb23SO5Uv%Dt6V2LL4ThYJG@{A4I5 zuNVN3(C)_w8BZKdx|HhS(?!*lgPZft;ki0SZ z%*3Ir{u0w{*#|#Ua!$;Cmg+6k7V(8gF4gmF{d#*K#ofbu_ktztGneJr)n89R;h3S} zpFAezf-8YGUmQ-;pUFrZqh z*?>P^k~<-q_2QFyewHW=^P#PZ*MSKs1yhwk`1R-3#Cuvj3(FU_&%fivOc1}A3i+;w zN!s&9-;~iqwRwMs;T*Qf!=vf{Q|JcOI(Ur1bBej>i>u$8gc~)2{hU`FR2;BNr_apB zQRwXKnqp$Zz3(U?`%LB@Zam&E1w;%;MqOeSp5A7uVfpM7kq=8bDpM10JB zV0W7PGEre|t%uwA)m+D7g<+~V; ze8q^@!QMxFI{jZ(X!dS47|WY^$7r2dnJY}GDKTPV?CeS`j7M24zq48BEBn{{Ga*=^Ec0YqpE^iX-7T>T zA@u&F^3O*ro%O#TDtNStjVCdg&oh}bnG25`HEzjorN%aFrw%SU)+T*>#>C`Lk0BW` ztLcf3;ZOhb5e2;jL3R*M3_Zq}B-&eoKr;rEXBd*zF-VV58MJ=`nEnLp#t>AAP*NUo ze|qWgv>I0kS41I8-KWLN+}!Wj(~D%>lAE@Afvmn^MRlD+-sYkcxHkq9Z{!qQf2-yz zhkapS(7T51&y=rLjkwkd--7>Yy4M;7*rj71QSz9yke}LG-%e}aohGFuSwdS89=l1r zZx;m$mUaa{-hDrI-XF@cRVQ*gR5;TL!J|3OXhFZqlM2D}P*THq=v}=iv z$XiDl{rM=44Lgg1IS^A@yY1I09ehx`YL|*1LtR@NXBgo8q=*Kj3fX_vzr4g>nZT5g zk$L31vbkY=hE5%lk%9o*~E%v-?E`H7dJwKcnymDS4jw(SW5 z1r(aYckyLU#?|I?Sydld;rW+diNS<}+$DUrKBSYjKM`qNAxTQmT(y;hgBP>SwZyS+ zWY-36$&dhNO=*j3-Z?e9Op)PEED?`F_sOt_~UDF+~L&mvobby-YejI}0({ zu5S3<-(MT=!vv}LQ!HQK(2&(wJkNTKUOfQq?=O<@QdX|*`2+QbdkjFwuhD@SLe6Xf z80(*RQ2-5{8G(Mf1M2W^0FMa8uIr``WrXn$=s#}d z=uL&cnF9JEX+|y%ZsoJzvu3?#{g#&2!>Kz9b}rW&NyGWu?&`{(Xx232=m$$2*46d3 zpk{r5EutRtuYB7ftLChlz?1x%4SiOaSw*$R!xu#&28@_0yR99cZT^uIQfQ%kvDnWU zoitl^-f)`mHY0+&u2s$(A~}7G)A5~1Str~_UA^BCVA4_0C*t0#%RjB#2;82|F4wx- zniQ-@`#p6x$Y}Lqy-&$N|L>docqH-#eBHpmi>M{%6ln`dykj586$ z7Kv(?9ed6Hfh*YmJsA40J#HP5#A{MT)3jFe30`TWA(HaasFt3ylfgUtwb8i3H;nzU zqpZ8o<`OoSgRiC`zCwY0>2B2DTrtm{*o-r4vz;6%e<33CVOkYcTEe5q^plopfUUJM zGsfvwO#9^K>#mCl_j^@O%RzY*Q$%CkJ#S9;A3bWga_SQZZ@KqBH?1_Kb87F@NT}@V zq~WrLE1DFy_M`o7$xN2oA(PZm5M%xGH>t7wDUe!@?fI|~VAH?bo`|6rJ>MHy8CA_K z$UE7O7e9b6_8VV249qXhW#zYm+?&XM!O) zY^|?qwY|-wO?<^T{p6PGl!f z$^4u$-z3?hc##+^CF3W{OKu|zbs~{6MLfwzbpivi*N+b8h;Gcn{V*{6-$$#<7H+iRBx*U@tWt^7NtCO+6n zR>nDST`$j}wi=j@!nG^r?(huUySaIFtOH-LOh5SfwO}!trkWa(xZXsA`}&&zx1vcD z`8XCnnhKxX3`y|W6ZyVotv_T1MZ$W4Jek@yFX z{lT%U?rvJU{GHC`jE%HX*Jq+K|Aw%2e=q8FF%s5{WCgxj{Jv?+?p=nUny8b$_I%sI zwOitii{mzsbGn+p0nMc}P*xWBSbV@$uY=^%QcQ~Yuof&c} zTke9}ycwOI1hBBQ8*cU{L6Rh&`gEkU@`eX7v3Za6#WO#Q6UgT>jVIxxW4zZjwx9qx4R! zz{&pk3mPLjrp-MEtV7fO@QJZU*1+0YRtNdSda|Ma34Bzd)7u|F2s~+~0fT3+8|qL8*W{&-D#2r-{9tyFQfs+!%W*9o}0>>FNbV5T!_YJC}zDB&%W zlacHYd4KTiY)qTkd%)oD`pCQ@XiZS3QP*^`vaz1bZ3{PxAZ)TH{Y2cys*$ z8YH7Y)a~qS%GNOx0-GnNWo6nYl4F$TEiK+^sxjdTNsJ&qz4ImA(B7c8!iBpBJyPA+ z7T?2tC_=QeSCGeLRYFapjP62Kh*w+O0p_5M#-r40XjbB_)T zBgV(at2*rKA_d%2BdzQY9TLmd58i)e_ zOWFK_f*f0Yn9Ryx60bH>VKlc1;mZE(8=e}>#c7{-`6?GF#2lbI!OYg%CACGg? z(x|QGPGqkZ-@26{T4mqGdefS7l0T9yL*p0uwtw&GfG3CH?Rg3bl!4o1n+$8M7*%F` zrk_&BC@Ryo#>rpfbG`a#&ErnRTrv5>@;BQH$Yp@evoU(`n}n%PN$c4cx%nw{aW_p)a$31X~<6j zT}dCcPXTc%qSvOf} zWosq5Jvf(tSDC<{zB^16&6NEg(5&{*)myBv>bxQu%F_`rL||!<2?o?DC>i+E&!fI8 z=&l^E%)cSi(_4&aWKR5--}rD(`oCtA{m-zOjwY3edmT~8F_b5_nC_Irzc1UrIb`$n zIk#Gch^CId)o4q5pjIJo#tqI}cme^F8Q$%yGj1~~$;6l%SPupT{n%%x!M?h%+y>_i z6MhNDo&CgUi3P3#Of8)@_Q#9~VwiwjSQs?15tpZ3Kweijb=vcJt<93f82Sf`J+i9% zF6-Ja@0W@>0lL>>{ZhC6*nFS;gZYq<=%0v)bm_u9EItj{7`YTEqu*~I4$D^OB8IXu z)IFd7CSYf1qJJUxL-($E%R~M18gsr?2prI1uyJrdv#rC&m(|s!1`PJ6OJn+$rw(i% zyME%{dB*?oekrb$mMFPjfZAF} zsoo>H@?!hWfEGXKh@8EK;HJw`a$@|oT;5*0?|o2qV=^>2q~-Pfl0u$j$aTHmehb_F%e)ytz&k9fW zebnGD_C@HT7pgw;^jv|mIrp=XAXNU+yymhZIBpXYAq>n807ci)B^oR$3tsB20U*hg zHzw*S8S=uOLZn;BK@Ej3ig?_GtvdnGi1e_B#(tOQ(6kg|Qcj)qnjjGO^70BV53C#b zvvQ!@mY!pX7OAH9t;=@?VXbvy{c~{~^DG_ZW2@y!mECskU(gSZ;l$uX^o?uY7-go#hL#=cVDUQy%ba-&tJ#=<)M;_Y~wRi}(CrUEXT{-`h zEM@wWsp|X*X{w*hn2(E-f0q7ztz%id^GE>F7=0q@$RD!6!$h$H8XSXT{c3DKE3?N7 zO;4ygGbL(6-3zdFcy5vQ@Tzh5AzWMhNpQl=jrM#RkH zn3&nnUyqW>G+_ak=>aUlk>0|XSL6rBkno0wJ#Y#i*Tlumn>QRe@5jZ}6#o1v(-7>d z@v+$8Xl1gwwVhArZgI1w66?d%lr6;{yd`LG-#0aR&Wzs>5W{G3z23XGKW5|YV*fO z%m7QNSOtw`@k!5A3Cpiv9j`Ah(Dqj%C;cT+ZxFa~jyTON%_n`k)&K-Ti>>-Ge+l*d z6f)Tar1%e|_!8p7WkCO!-DHDuo1|6-dVzM_CvS1zYYh#mk9Qy#3ubRP0QKeh#aMRg zDXo*eXkW+Sr$v>3*V=}%7_@J(w@7kDbUWF1FZ>d z8mG5FQ3?{X+(&K0>(Q`~?ODKk@iYu#AEKC_qw-p82!fOK2}Ngr3Blt1xr^fnVhZ#_O-yKOkk&e2gyF02u6*n1{ohQHnX z7w>F=a9s)??w8N?@N6P7vYEnb`}3VKsn_ht;_^usHH|ONct7Z0J`-`@69L)FE^YgpfEyw_Xn&q>aHQuwPT^c0*1kusTQ(G&_ z(Kl4ijxIZ+S@rH``O97?`3b&`cKmEc(PEBCnK5uCeE-}BlNZ_wKzL1u`M4PLdLt;h zF8(f<+WAone>{as1T0P~P+kX(!jl!l(>eeH=yYlGE(ry~oBM!NA7txvZ@fC+cfR`lHX8Pwl%U&Eg$^6JvR|+~};pCc?=XeP2eg zy|a@0MJPWxTH0R`Fa+o&>|KCchy(N z%o3YUU!R2pYj&r|n?K%H%2G&jH^qN>VPS0zmEBj$Y^YCP;T%SpDSAfEYl5Rwb5lYB zR9KwmlDN3IH1E#N6$w@ygmY>D?Uk788g^|+fYDI&grYpF`_Z4cTv#+-1AapJVz=Jq zMQ=A(DCR*aRAU48T~r37{%QfNk|ID;J`(Y0*_s% zq*M(aYMgw~!Jy)u%4PX}IWJl8j<5z@?;P9S*YFJ6XUM{@81|!|1Cg6z)TeO^;qzOpDT(fHbX zao`SqW2>m!N)5!Ys@|2BLW$#9?&J4#gzxir1m{t0!rT*4ltJPhH2|&O1LkQkzwx1| zt#XUQJjvjl`C#dQ-rVO62ZZA~)4lBePU@-hFw?g4Fv)*2q>8Il~3^V;cYz#GsFWojFDVqnsQhz@b5RA7Ai%<*D~L zS!`>@`y{`GaD%jI6yuw}b3l14HG{BcHo(jjz)(o^D-#7e`1c1#&;c71%Z6i0>|LTj4u^(R#=X|Q zBrft;oKYnXQwdty_GWkSH)sUJfeUOJWq(o4THQZ!o$s3VZ~pASZW&VH02a||UA0?N zXL@gro{sRqQ9GU{3{YIkF_}>^%>a(YC5ClsdYHvUzXTWXYA9}9p+RYSHB;x9Cp?Dl z`I_EohD%&tug&T=BwkvfZaBQehSl{%wcI~_%7;w(h$&Q{JG2k2Y8a`kqAso-ZO;{H zljK9^l$!r2{d0Y`XE5y zZeFk{Xfm6ct_%sjP(KXcjxb(otY80V^T^8T8OH9$*Y38{n$&v+X!O0C~KAoBvTdWf&oP>!#R46wTN_J|}o;&B7eBQR{6q zH|7BiIqlxA-k+mUiqpo;s&9T% zWK`xD#h&z%XLX>FgSr$18^YJd7`2SdMqA9VfOJ75D^RO;!*=`vb7Tp@2L`Q?KhJC@ zk_rbrdgLt8Tl2p37^jzjc(UgSlaS@~3#PNn?HS&xs*{sGI-NoRZga3PV27a| zGdBynN$q_O2=%;GEq3rrn0)ko?s{Yd?h zwi+6M;pi|XpF?G%OtfL)!a+kPp=2%qv=2||v*D5*j-L?H->3vAjjl90XqvJ3o(jr1 zIPidLiM#Z(BUF!0b>=Q#SK&d01OE|kt#?yv(FenRi4N>>M|6CGxL#`4x`wu3~+uO*c0;D-zzXo);0ly}P8gfwqRR6(z(ZByd(Y$KQzs9Cm;gp>A95 zPc#`uR_XK8uJ&aTmip3ka~H-T6d<$ENy0>p-6rqOudp?U<)`t^3&((*mg{D>3dP`NUTox=C5 zz{*5!ejY_LQLZg{US1F4690DU#(u5)xzCcm$}7iCe$R<=Jrv;l?*f_WaO&y|e@c(! zsun_QahpxTG>Mqi1O?K82H9Uad!c?)oqHFkHm0bChI;kt>F5ZimY}WC`FZTyR!zJw zFT0F*@jGTF2&0EYP=QcNSJKyw4GbckxWiGkJ0yo8V^6cS$|_0OX^8tviu|I}XihCA zYnCU!^0d|#m`5a=4~7NEa=w4g(cU4ov{?FlXe*^Px%YQLf2-lB3oeg%*_+tp_~6NE zKG5E_pzs6Z>nk?PK8!$DNW ztzRH|P9g8sH2H*4FRaVA(9%a;!?XTXi2;hiIlcbDEkAkAcTf8C_TzJZ1kH&? z<>OBr?NuP%uI30XTX1tSB_bKL<;uc9f$5+VGc!MH+QEY+l!+};_1f=%Y7h46=|-Wt zF2uB!S$8FjC%PA1-if;&&Fz1(7}ixJ^VBf`H-`>nKpa%x^+(H|xJ!Jyb%Z=sRb$-r zz(@o|!0+F0F=s~HPu65Epx!qzNlRWtJ=D1crUqA`C*Rk6p{Byo#lWJ3*!{rZl4Omz z!VWVNlRQ(zSCe6v_QJj=C!2SU^_+twzIpN4mD-P7O?BRXoa$WY!h1~BPKp!vp~kKv zmOeY2cibkysAB`et9kpekI=Ws_=`tOMHUdXrvT7Ki@*bpqm`5W8?SP6*WKpJWJa{c zI(w(-hWn3<&a-6z$n8B`G6uIipE32w1Opi4D$&rlqI9eYjLsfshM8{OO zSry^(#P4}r&knS$?W5aB`Zs_ByVx4{b_t#68NlVWW3aXP#IK<4wJr^#olE5-3rj;w zOB7CgPoY_4j$xO=pQ!SGJ`@JCfBi$gd?nP-qofb)C8yPqJ$d?6?c>Mb^H(_&j6y=> z92^|=iB8mQCMIjo)2_OX6b+(V8W(nMzbzM`O5I)y!oS?^)}Przb!;U(3MwU~+OT##fQQocBMYEdEEt4D;9q>L82*kbZ|#Hg%yosC zUKcp0s@ywh{JZPqjMg(w0fCPSrrX15O2Li`NR(pt$$ahkJ}i8nXJ&fH-x0+keGStf zQ~WG;paZmxUN<)kf$C}Du7?3M?E2%v(>oF}Xsk}82o?D`91V-kMmEs1AD2?`bX$<)HA9}njE{Af{yE!P3hiz6t3g8_alP0?`eaCQyL8EyBUv5L2hIvK&@SxTaX1HjPho{qh;`W14DWIHv}ZCs%~#C zQZoW3?P?>*6X$6Go_m4c+~)uEW$3lK0TWu=sF@qpTb-#hEH z?J}pd`I`TY#h;gecw65dRIS833QPjn7~&t{b#-<95g#wf8kb#Ii1Fyr=Iqs{W)@b4 zWLrNr4h}S+zNyKw1$S6A!h?P<#kOU@Kfs@W2F3-fK*OKc3-f@^T8tC&E(Ha_JZcTD zP|&@I_twvq`BEk5Ny_U&FNf3~7@hAkN|2K1uC-pc8j)&ymZ)?;IxnL*12o);EUB&b zz6oov>w%^GHSt+#tTW|SQBjGYxWq_JOC8OULf_clMghJm$X6KNn%dbNx2LcLd5cx? zlfU+;hQo3W58d$QuF5SnM3vXpAO()^D)MF@^-e#IEJoTgF=Y^9c{^|g&ZEPLWG4kz zK}%LUkucIC4MkMyqDY5jRwJDH^Ej9TLS(b_xD@giTfZ;5f94v-De6T9af!6u``+f^Xu@h zmeq+R9rlG-Gssrrq7^N>Z_{)r&5TW9+O&SEcpZx*T^xxIXljvI@v;&S%uVg&SB~Yh zgH!mse`wv3=KhnSgt84SxFsT%evH|n-5m80cc=gMm+Aw+rZN%9ap7`AI|Rum8~{)d zq#a_GX)>?|goEa*dyO*PF|6(Bp`tc(D0ixYP>>^LK?V3SH$Sy&Il6YOZ)3kcS-+Pv zR^JO3ydqVaJkDsH_E)l(dw&@NW@j~RU)b_1*492NCZD2$gb=!{tSq?xU2}63SV71j zuVLrv+NUCx)?O7$7XoH)t<4l*^E@&e&y_>Cw0Y|13+iG}>!q!19%2IZXx3*FIM^5% zX2;p*`CPLA)N5Z44Pf*kxtiJLdED$PW#d8$HeGF^32JK^S#ioNpu`p63gOY9s5;A9 z`%__wuzzk(z0*iQUz>k~FT#0GJ;UL)QZj(TUOb`)0W{B%QGpO2IdMrzWRPg|PvSLQ z`xD3Z_U+sDEd9rW`6pN3>z?fkSWWVjRva&1abLg6y`vcu=9w(CPO|R%8CYJ0Jdp851$>ssaRk~I4_=%%-6JguCHqrlI}W|WLQMWqc{CTPEd>&FU4$@uvnc56TYO=@cD8zUYE23SuPmG@^c?;*%^lXw9+hW8s%P2&eW#5Kh z=JBuW?R}lsrkb5!VBplj>?KEj<=!3 zl|N%^Wy1S>Xdsc-w`-`D$Y238deNXg5*dKVD$xRDA`Z2{oB-?36Ba?Yls75?4GRsz z2ruu+A&z?-)a^$dHPia5?OTyheo&`Le;rjU}|h2 zf54Y2>R9V{ck6v~yefHIS4rJ^holXkktfDI4>~{>Iaff&yS+mBq}5Ceak-l**BJ^) z2~X(78Q0c-WlBBFnA!<~m3zPh&B|=+v9s67>O!+&ZAjQ?0w+{lQxij1PcQ3zQA~z@ z#OWXE`o?(4qW9UgwWJ?D@K?CLfTX3-G`F;X38vN;w-`7$-9ssYu+{)gj)W>O*6A%~ zIYn*-NfBseb~nEpK*Y_B%%Fqt1T#te<_B(VtNE*R19Y9uzlw_3EI}EzbQ>F6NC2o8 zR<`#8Ru)CPJan$u)IkV4JX%oA(5cJyasKlte4qK*GlSd4DX%u@dbIS@SFb2BF}F(G z9hLN#sOCC5J)gd47VMoabz~}VA6NiILqgditYu71OHi1FPJL|J6qz&JqRm>_%L9hkwhvK{@ zV{W|L>M?;M3B1Zp?i?7#0g`$|BcHm}RNp!9Cc_zY$8o!+^UAJXI&%f|ae&=gR3 z6HPnha&hQC>)7Bi@pFGY@~5R>L^8J7q_i2H9uX>i;q|V?4IG_bh$Xa*sN*r(A|zD(g{D~@#cEs8C0 znBTuYMqIYt^EdUTI~!T`u`d_EE&iGW^@ zoG83u7B)61IXO%h?>iJ*r=}SZqZ0KZF7vq#(j?8@~{|q$TY`i5c9Z4`v}2i z-y&diZ-1hNQTZ*(V(aCzo7>}$IMhM}ebID%0nt5%y|Z^FQ!kH~r9txkvq;_Af`F~= z)|<03f++BP&Ji-wd?C`~HRBWi>xdHEyF{-vI@GZPlu2rK(FD6c2WP;2vwEiuR9OlU zKeb{3Au{EZDNxSZaZS)kp|v7>3No z_{~-yB^uyMDz!P_0(S6j8S2FwnzmF?do{LnGvQGbwJ?E@pZ6^N;UiJjm9_lldu;ya z_i3W`gdMKVK^bjCbn&rz9VzrnPktS_x8<%g}t6(e>jt(;Z^{g9RkZM^xm&%nXUb z65HL|ijQ}tX-CukF9-Wl;rWNMDg5GsX&T3IJML-d*}n3idEO6 zn40RB{3DM|GD|W{{7%bx!AgO8+@G7BmO!q~)qTQ9=s5hIsE#>I+jr0i)|bJ}G|QCI zZsYKBe|;5cFa_P%7?6+D);X_nW-gn%i0J0RrtuHG3-85iBOp ziN+^qaH@hu6Yjl3etqmh#m!fuqz5+MYjoMG*FTJsMQ2`!?rHW#B7pNdH zOW33%r1c>H*50X)_G7^pFZ>jgdc!~5cd8IBAOShGlp+|PkEP9q5kMwaouN`J_C7h~ zc&57*-rCxlCdfvD&1eXB>IW9Ps-HN51Apv3W{K1F5|ELFH1hq`)^|C1%o8V1OuUhk zNl%v~&uC1>8OC(~dB!xsPe;t0^ML0q6!jrC$Xi{UE&raR2wMFiF{Pkpr#EE+wE;&4 zpTfVvaT^(cbLH0n?TZbLAblM=Z98Amda%Y=+A|KH9&Ve3&3*YBbgnc3X6Wy%Pkg%{ zrbs)?<}7Uh1Cg7&P-4gJVHt3syRo9Xu|8Gg#*jLj+_j^&$C27LOK%-W;|h{Oegc5IXQx=$zWh@j33DNex%MDN7$Y)QEAEHjFyCv{x9qEP*+; z4!tzVBfAF;pbBOmBy26!kxi7^gXIYp5gydjoio$F4liLHyMY;YzUQiUQ8D2D z5j{B7H|oXp`Tuu7u!Y;M$?DZ2Fl?}>s`&iYN`79&l3vObIg)NV0XkG zY}EgqLaYB3d(3&GyJt3X0@Ow<%i6eD`&Y;q>X;A1zjLBN+P*)Y(E{;C`^M0`JNf7$ zv>#upA|7*h4=ezxG58y+ssSCpF)T&s2txzi!DM9c3|G^J#nr!-JC-$^O3J_o4um6W z;-_c2m04&0_(t-mO~P9|j4&^k9-A0MA}o`kL5}l%8F>R4T=-y-!5>rUU&B&<+|fvj z1!W9aZ+zVx3hRkuiV!oLgM{t?TK;m%G%OXpR_~|<1JI>TDZ6#|l-+?`% ztsEI|NZX8sul8e03rFLnU+FHE<8{+Mn(v_V?#zQIk;p_~>Dl}S3zr1Jv{6d4p`)+K z=Y<0l{(s^|dptfx{cet}MDJs<#bm7N@ws)&>*vXZ-7!d1&DIDs)i_x$ztX`PYl z*AM5;bItC&w$hGUgTF$z1R7G^0gMR@g;H$Wa3-^37CSIY4;vd-28??o3cGSVTdG-~ z`?3;%FDl+Smh%t^xse#1Klc?bXt@sY;01Sn2beh&akLsjx77vuj!5E~Pbc}>#P~aJ zB&_|hG|QOk9j^CrEwTnQ%DA-`=utMxtnBUW!LDs$&Bd-(P^^|3Ng&r{f#81pJUwIF z|DDllrQHwVAubM7R#slY*88H3{?6CtiHI@2c_LtOgz8U%C&?if~Rj3n~c(}k7nfWx8n=+syryWcs35||U0QN+` zg@$7M6Dk0s@T$;lLUQuohfSBCa$Ntx8!FSjD4OrP69v3rF~=E7roijNCiNm|8JVD- z!RVXncuZvR&!5*+92&d|i`oQ#1N`My5W}>l#x`@zf31`B1nNr^v=^2>)4?UTj7&^- zsK-n~IPHW+bzfBJGN0#YZBZjV1j4IYIfPvfVyxyWWxyJ(4tAYdt8WJ3$79e2b4OqWCn?9(udoJGP{EbpIadb`~*B^uwdSAKaR;slOY}s!I48Q9&}EkE1$)aAF{Oru{UU(_Ntwq+by3 zSHf4-C5Ooh4hdGy9uuf@{4L9Qj@8 zCQ9q`48~LQShU11+i2xjo<0qX_P;JT2%qG+o}-}U>C_oM71QkG&%)fFV3PG~VLjkp zZ%4X=%->DE8=O+}qqaOGW?%&^$vDBb9_%e%r2tDDkY@8gN+1_uA^1{o?FC*#)IV zGFwK)FV*Y5KLiK=8y@}GY-E8m^`xh}dnfY#?&gTXAeFE-sjkx=g&uN8X^{1fA860Y zmOgg(1J67TP@L{Ti-#_XM1NpO0Q=Hr#DN}_>GY|4J=KE7143I+{l_h6Q0UORe-yn>W2$>4#)+p z5+!a%O)MbPNc@bDwE6RTE`?!nNHw>R`Z{K`-%OET`E^Tyx?a0ii(>)L#cUiJ+M3UcXz z+BZ)ZD!)6@XJ1h^vzK6jMF=j8CNZ8l=F4ae5CW7yLeC*n^gr*7eoiXz{H?wAAoUGBz)2EUw+=>5SIf3c76C!>||w zG0i`yj;xkomTni7q4F1Y2UbgV2Vv@&#U(yFtaNuP7V6enh$$`AS0$7JvmWfQiOMfm z<70#p(IS;b(7W5Kw*47bYR@%HCovygJ8N;hoAtqHaB(F{pm6Mas*D$6CMAUG&W!;MmN^m36GrH@);C(%jymxQc9vJE!72O%1gRU_pzS9c#r-U^!9zD9_JHi+8`h{e)W@2RLOxxQ%6x>Bdb!@&& z=Wls)bAtk4VPpS##b)VIp8oou*3giF$LBgInhdLKw*=qS*0e*Zg8OXUtOyhD+xd9Mk(%-JD1KnUuQ=bR-Ja~}CDgu-Z z04sBrn*P}FUO!HMuiM#15}!0R?dm8VyT8>tGedTBc@%Q!CZnybjdG@-sMvjXd$YQ~ zZ#i14Gl`z)v_^O5`L;q|LEsDVw8xd8;`a{#fLHbKy8seX??#N0M*tQ9{6}jhXR8e< z8V2*mjMV8KpHy$bQWJS_>vc`n*BeN9yaF!XJmy(`<~{5^rf);6-91~?pLCURs91nd;wQ%J;#IjS|m(a6=Yy5xMAgU5wqP3 zqTKXQ=;+7| zo<#8X1)gwo6M_Nvd(=!4G$2Pdx)+od35b1=eE8`?WL5H0RGZQ52t=Z z{!#?io>4^bwf(-B)?3fBt)cHP9k(iQzkN%*y@YBeri9O=rLn(ye6YUn2PG;y-N%39 zDkW!MmYJMf({}1`>w0H)fu3xn8rbA1mE8joI+GLh(_`FNt2U>|j;m!AQU zhGVlWjV;633d8Rpka7Xq{GHw1(xpOD+zn`EuJF3HCkNkda?C;JRqqEG`MCdA<8!@4O9lSf1h6YSS>eeRe}m(YjxG{FD)%8znGvaI{O(4 z1QhPc&jS3f*nb|)aB^~5I(64IFgZBd#iopaTqsDql+G`JP(qce3GzYij+1;+WxlGe zor55x9IGW{Vhan5gU^)>w07J8x?grUQyJ}TtU^Yqkq0eWyZ8X?GW zUwfNzh>weldC>)PvR{loxw?hLvg4;si}C8ceZjveLj)cvW0M`*LlYAgR61OnKL`N! zJ~19IaEDh6uS`WnU&J)#fs0G7Pl;kg0UDj{xcd>nN|1ZG{QpzPbwxF?ZsCbRf)pc{ z5)cqj0Y!>R6gYH5l&+#65Q_9(RC<5_(o_ss$N{B^^mb4IF=*(KCY=D1!T|ytAap_? zz@4+s!+p4G-TN^Ap7lS>+W*X+Z@%^Yd%m1gD(R3WJ0EN3v4VKk7r9eWBG!Y$h!59I zGN1q`Ww|^xEeL#cApGL(55pcF!&~*-zII!ZjlrHUVJ*gUqAE;kx=i3_V{Y{ooqm*Q z7Sib9%nyE9Tz3!{Mu)|9s?PiV5EN-@OXU);s=;`Sp zx1Z=>rlrBHRyw`#E6)%;wIw@-hiK+nP7l@v)8x&vrOpN|sW`f#f?F=f@}|YVh5xt` zdSzNIev%MFXa;Y#8h0al_GD+e<8byLx8Y0<;P&s50Mh-T^F^IJ%FJZp_Sp6`e~L^G zyhQbLk$0GWmgJ2`a2*lK8IIP-Cp7P9(HG(@2WKTvJ*C%$PoL~8>f`mD*CFX zfk*zP>+JP4_=LatyM9BG$fTmbOQrPjV9PHx8k&iGVxyiY%gJ~JoR3!-Wn-@HYU=7Y2FjKM@DH+ueM~(DlIU7ZAd)5x z6AEtO^?y&lx`7ml`$IU3UaXGo1IegRB&P|ow{N&q=}B|l|NO42ev@&MJJ7$wEGK97z0~vUW@}8NGa1l}SWD`maX>qM_#qd-BJfS%0s5NgCk2aLHI^mpob331f=C@10Izc#WP5eWXbH@&Ua?|BJZjR`ks~{B`)ee zo+E-$3gGQwZaM3 zscCo&OY*tXD_rVu*W8TTnQ=DU@cxITC~k_&)tJT)g>D-}lb&Ll*0cEl(Ooq=tr;)H z%8_e1?skdV{x7vhfYh1c*jfdJ(mc`bb2E4>&h( zF3av}vAGs;2d)hsRP8{8RIH&aui0#y?TzC^A z*Y&{x?95n41NE5Iw)WALnz(LJuH4llN)FXLEnFQ`X+0$QbwJ2U| z>)&Htv;!=FFJT8S^CsT0vbFaRl2#~NNT{_O#~w_o{Qeijt6cCIM24~6hJi;(&}POk zuv59iy|^;3xIoyxHg-?=qLTe#tz_1+0q<%K5%tZu22mAO)5Fhf2&PXT$Tt+e*}jG| z{u1%#G_b*OsaX%3=yWr0J0yw2{}qjuxkQ9!(ldtM(;jj*;$c&NZUrjtKO?ouXp`gb zH_!4qVFGuV)jOiaRJ5Q;uxS-_N$X{A6vgB3xgD>Z+rQ32k+CK*=oi*GHN-+4Z4!5k zhog+Ff%>s3$$e6=!QSra=^et&%F>l~HPpShDhR`jJ@|N3!LDMYE%0Ibdp2EB4Hm-L zZQasIf*+zxV1PnIxHc41Pf-#5+Pux|CuiMbDb6*1eq<$u1b*em0;qvi}sv0Ec! zsnHY4pEZSN=wSOv$ry$>w z2V0r*iGAjf)7Rq_hpP1d6(>@+=NhGcK?xOiqngWfUb5BQf5)N!@Q_UF?eztVIqE^P z-Yl^B7G>as{TenExUu+xJuHBUQUj2l+@V~NBI6`6R*h(wlp%MY3=V@8>)5h+c#Q1w z!7$)cuV@}h=>}-@19HzNC?yyWNNott&(!ETiZf?G0bll4j*Z-qp=6rFaN)>P9^C5MVSVVK zbPy>>oR~|+r{c+%1Bi^YEIy)}hTlzfmosEtE2I)pfzMZ6_~ylV*e|DBLo$DH3%}ot zADf4FHr*_KaRF)XJT&&c^HP?*2kCbB>u~ppQL=R%YXRH(Hh({#!W4U$3q!L`QCFDX zC69k^WNb|LlE+UTC*+xNCGt8#76qc0@60Y=4*KvQ_oCYSwf?<|ebwU}4}o$2WOMu8y}Nhswqez?&5y(a-~?_xzE{0{jg+chvu`4o6*f04 zEvp>jO^K$qiZ*436STjm$d#;#)84)G*dE$8lEa5GXx#zTHIXX<9Ln~FMzsrr(GNlf z;#@q+xRG8yz8`OAW|s&9#pY%2%ly~oD(dbC$$3{?e9-PxV!rcf?23qMU6cgpjo0IA z!7~yU2Zm3y(UJ#;X|1&6kHrcDl^y!MzrXBC4boAud|+y&0gepvtb30}a;GR&gGM6WpB3Ht~;P6w5*q7;!4Wo-n_2id=R9cSA_*{J-}nS}5q(~syH z)$%t!&Q#P0U0r%Kn^hM>_e>8v^yO=JBO-FjN&xsq&&(7+y?nF+qlGxk`a0}Vh*01A@MbV zi%lN@G9Jr;i}iQRb!S8<>i^;2H{|@G4nx#gnvV75Ihf+og7I`#oXlHqX^^R}fB&0q zHR(d5L$!ac_ zRL@T^8&G6RS*02rH?Ks^0Y&5Uul zMG`datdVW05T7I-k3WhzRVerJtWipxH$v~M(Mv1i1ChA1Mn)!_dH;7@l>7kgCEr{# S#DboQfYEhxgDQQexPJqQV?SsB diff --git a/icons/obj/devices/new_assemblies.dmi b/icons/obj/devices/new_assemblies.dmi index 7bf96e5ba92e3a08e731c61a103dee930215526b..f80f89ce20a09f44f03487f52590fd6961711ed6 100644 GIT binary patch literal 27564 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%0DSHnLLrD9wxEYP-7xBgiPzGlbV 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 Date: Fri, 15 Nov 2024 18:25:46 +0000 Subject: [PATCH 096/222] Automatic changelog for PR #87701 [ci skip] --- html/changelogs/AutoChangeLog-pr-87701.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87701.yml diff --git a/html/changelogs/AutoChangeLog-pr-87701.yml b/html/changelogs/AutoChangeLog-pr-87701.yml new file mode 100644 index 0000000000000..1f05ead77f3f7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87701.yml @@ -0,0 +1,4 @@ +author: "carlarctg" +delete-after: True +changes: + - rscadd: "Adds the Perceptomatrix Helm, a hallucination anomaly core item" \ No newline at end of file From 7376a7b34da6ec1f1c89349cba64fcfcfe730836 Mon Sep 17 00:00:00 2001 From: Sprite <78328959+TheRealSpriteMan1337@users.noreply.github.com> Date: Fri, 15 Nov 2024 18:39:23 -0300 Subject: [PATCH 097/222] Fix computer tips' grammar (#87921) --- code/game/machinery/computer/buildandrepair.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index 220870cb11981..3e947d33d7bff 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -85,14 +85,14 @@ . += span_warning("An [circuit.name] is installed and should be [EXAMINE_HINT("screwed")] in place.") . += span_notice("The circuit board can be [EXAMINE_HINT("pried")] out.") if(FRAME_COMPUTER_STATE_BOARD_SECURED) - . += span_warning("Its requires [EXAMINE_HINT("5 cable")] pieces to wire it.") + . += span_warning("It can be [EXAMINE_HINT("wired")] with some cable.") . += span_notice("The circuit board can be [EXAMINE_HINT("screwed")] loose.") if(FRAME_COMPUTER_STATE_WIRED) - . += span_notice("The wires can be cut out with [EXAMINE_HINT("wire cutters")].") - . += span_warning("Its requires [EXAMINE_HINT("2 glass")] sheets to complete the screen.") + . += span_notice("The wires can be cut with [EXAMINE_HINT("wirecutters")].") + . += span_warning("There is a slot for 2 [EXAMINE_HINT("glass panels")].") if(FRAME_COMPUTER_STATE_GLASSED) . += span_notice("The screen can be [EXAMINE_HINT("pried")] out.") - . += span_notice("The moniter can be [EXAMINE_HINT("screwed")] to complete it") + . += span_notice("The monitor can be [EXAMINE_HINT("screwed")] on to complete it") /obj/structure/frame/computer/circuit_added(obj/item/circuitboard/added) state = FRAME_COMPUTER_STATE_BOARD_INSTALLED From c8732045ca322e9d2d73e41fee609def75adafce Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 21:45:35 +0000 Subject: [PATCH 098/222] Automatic changelog for PR #87921 [ci skip] --- html/changelogs/AutoChangeLog-pr-87921.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87921.yml diff --git a/html/changelogs/AutoChangeLog-pr-87921.yml b/html/changelogs/AutoChangeLog-pr-87921.yml new file mode 100644 index 0000000000000..6cd0df74d9035 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87921.yml @@ -0,0 +1,4 @@ +author: "TheRealSpriteMan1337" +delete-after: True +changes: + - spellcheck: "Fixed some of the typos in computers' build & repair tips, adjusted wording" \ No newline at end of file From e8013b82cb7aef882bc77295c5d9387a15dd879c Mon Sep 17 00:00:00 2001 From: Hardly3D <66234359+Hardly3D@users.noreply.github.com> Date: Fri, 15 Nov 2024 19:47:50 -0300 Subject: [PATCH 099/222] Fixes watchers not dealing melee damage (#87923) ## About The Pull Request Watchers dealt no melee damage which led them to only nuzzle their targets. This PR brings back their 15 damage back. ## Why It's Good For The Game Little bug fix. ## Changelog :cl: Hardly fix: Fixes watchers not attacking their targets in melee range /:cl: --- code/modules/mob/living/basic/lavaland/watcher/watcher.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/modules/mob/living/basic/lavaland/watcher/watcher.dm b/code/modules/mob/living/basic/lavaland/watcher/watcher.dm index c7648aa38b259..5c4183b48ee6c 100644 --- a/code/modules/mob/living/basic/lavaland/watcher/watcher.dm +++ b/code/modules/mob/living/basic/lavaland/watcher/watcher.dm @@ -13,6 +13,9 @@ speed = 3 maxHealth = 160 health = 160 + melee_damage_lower = 15 + melee_damage_upper = 15 + attack_sound = 'sound/items/weapons/bladeslice.ogg' attack_verb_continuous = "buffets" attack_verb_simple = "buffet" crusher_loot = /obj/item/crusher_trophy/watcher_wing From 329b40b55bd5e69163d96e9b3b9d6019b8f66159 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 22:48:12 +0000 Subject: [PATCH 100/222] Automatic changelog for PR #87923 [ci skip] --- html/changelogs/AutoChangeLog-pr-87923.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87923.yml diff --git a/html/changelogs/AutoChangeLog-pr-87923.yml b/html/changelogs/AutoChangeLog-pr-87923.yml new file mode 100644 index 0000000000000..0cb0e4f5a83df --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87923.yml @@ -0,0 +1,4 @@ +author: "Hardly" +delete-after: True +changes: + - bugfix: "Fixes watchers not attacking their targets in melee range" \ No newline at end of file From 90b52e590a8945f6fe160930ec0c9cdffdbcdba1 Mon Sep 17 00:00:00 2001 From: Xander3359 <66163761+Xander3359@users.noreply.github.com> Date: Fri, 15 Nov 2024 17:48:22 -0500 Subject: [PATCH 101/222] [NO GBP] furious steel fix (#87926) ## About The Pull Request Fix a few runtimes with furious steel due to object / effect fuckery ## Why It's Good For The Game bugfix ## Changelog :cl: fix: fix furious steel and blade ascension being jank /:cl: --- code/modules/antagonists/heretic/knife_effect.dm | 4 ++++ code/modules/antagonists/heretic/magic/furious_steel.dm | 7 +++++-- code/modules/antagonists/heretic/status_effects/buffs.dm | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/code/modules/antagonists/heretic/knife_effect.dm b/code/modules/antagonists/heretic/knife_effect.dm index 1bd44921cf957..e11fd79ab9f75 100644 --- a/code/modules/antagonists/heretic/knife_effect.dm +++ b/code/modules/antagonists/heretic/knife_effect.dm @@ -12,3 +12,7 @@ AddElement(/datum/element/movetype_handler) ADD_TRAIT(src, TRAIT_MOVE_FLYING, INNATE_TRAIT) add_filter("dio_knife", 2, list("type" = "outline", "color" = glow_color, "size" = 1)) + +/obj/effect/floating_blade/haunted + icon = 'icons/obj/weapons/khopesh.dmi' + icon_state = "render" diff --git a/code/modules/antagonists/heretic/magic/furious_steel.dm b/code/modules/antagonists/heretic/magic/furious_steel.dm index 9414ca9d7116d..dceb9023bdbcc 100644 --- a/code/modules/antagonists/heretic/magic/furious_steel.dm +++ b/code/modules/antagonists/heretic/magic/furious_steel.dm @@ -19,9 +19,11 @@ active_msg = "You summon forth three blades of furious silver." deactive_msg = "You conceal the blades of furious silver." cast_range = 20 - projectile_type = /obj/effect/floating_blade + projectile_type = /obj/projectile/floating_blade projectile_amount = 3 + ///Effect of the projectile that surrounds us while the spell is active + var/projectile_effect = /obj/effect/floating_blade /// A ref to the status effect surrounding our heretic on activation. var/datum/status_effect/protective_blades/blade_effect @@ -67,7 +69,7 @@ QDEL_NULL(blade_effect) var/mob/living/living_user = on_who - blade_effect = living_user.apply_status_effect(/datum/status_effect/protective_blades, null, projectile_amount, 25, 0.66 SECONDS, projectile_type) + blade_effect = living_user.apply_status_effect(/datum/status_effect/protective_blades, null, projectile_amount, 25, 0.66 SECONDS, projectile_effect) RegisterSignal(blade_effect, COMSIG_QDELETING, PROC_REF(on_status_effect_deleted)) /datum/action/cooldown/spell/pointed/projectile/furious_steel/on_deactivation(mob/on_who, refund_cooldown = TRUE) @@ -167,3 +169,4 @@ deactive_msg = "You conceal the cursed blades." projectile_amount = 2 projectile_type = /obj/projectile/floating_blade/haunted + projectile_effect = /obj/effect/floating_blade/haunted diff --git a/code/modules/antagonists/heretic/status_effects/buffs.dm b/code/modules/antagonists/heretic/status_effects/buffs.dm index 3004bdd9ee0ce..362e9750b49c1 100644 --- a/code/modules/antagonists/heretic/status_effects/buffs.dm +++ b/code/modules/antagonists/heretic/status_effects/buffs.dm @@ -260,7 +260,7 @@ max_num_blades = 4, blade_orbit_radius = 20, time_between_initial_blades = 0.25 SECONDS, - blade_type = /obj/effect/floating_blade, + blade_type = /obj/projectile/floating_blade, blade_recharge_time = 1 MINUTES, ) From 6046120e5f98514a630090bfc1059f2749810ec8 Mon Sep 17 00:00:00 2001 From: Lucy Date: Fri, 15 Nov 2024 17:49:13 -0500 Subject: [PATCH 102/222] Updating player last seen info and connection log no longer blocks (#87906) ## About The Pull Request Was investigating some stuff downstream related to undeleted SQL queries, and these two queries were related. thought it'd be best to make them not block `/client/proc/set_client_age_from_db`, as the results are never checked anyways, not even for errors. I've added a new proc to SSdbcore, `FireAndForget` - takes the same parameters as NewQuery, but instead of returning the query, it just asynchronously executes and then deletes it. ## Why It's Good For The Game less undeleted sql queries, less blocking. yay? ## Changelog does this count as user-facing? unsure how i'd changelog this tbh --- code/controllers/subsystem/dbcore.dm | 22 +++++++++++++++++++--- code/modules/admin/IsBanned.dm | 2 +- code/modules/client/client_procs.dm | 10 ++-------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/code/controllers/subsystem/dbcore.dm b/code/controllers/subsystem/dbcore.dm index 7d01226b2cfde..115250104f008 100644 --- a/code/controllers/subsystem/dbcore.dm +++ b/code/controllers/subsystem/dbcore.dm @@ -384,12 +384,30 @@ SUBSYSTEM_DEF(dbcore) return FALSE return new /datum/db_query(connection, sql_query, arguments) +/** + * Creates and executes a query without waiting for or tracking the results. + * Query is executed asynchronously (without blocking) and deleted afterwards - any results or errors are discarded. + * + * Arguments: + * * sql_query - The SQL query string to execute + * * arguments - List of arguments to pass to the query for parameter binding + * * allow_during_shutdown - If TRUE, allows query to be created during subsystem shutdown. Generally, only cleanup queries should set this. + */ +/datum/controller/subsystem/dbcore/proc/FireAndForget(sql_query, arguments, allow_during_shutdown = FALSE) + var/datum/db_query/query = NewQuery(sql_query, arguments, allow_during_shutdown) + if(!query) + return + ASYNC + query.Execute() + qdel(query) + /** QuerySelect Run a list of query datums in parallel, blocking until they all complete. * queries - List of queries or single query datum to run. * warn - Controls rather warn_execute() or Execute() is called. * qdel - If you don't care about the result or checking for errors, you can have the queries be deleted afterwards. - This can be combined with invoke_async as a way of running queries async without having to care about waiting for them to finish so they can be deleted. + This can be combined with invoke_async as a way of running queries async without having to care about waiting for them to finish so they can be deleted, + however you should probably just use FireAndForget instead if it's just a single query. */ /datum/controller/subsystem/dbcore/proc/QuerySelect(list/queries, warn = FALSE, qdel = FALSE) if (!islist(queries)) @@ -415,8 +433,6 @@ SUBSYSTEM_DEF(dbcore) if (qdel) qdel(query) - - /* Takes a list of rows (each row being an associated list of column => value) and inserts them via a single mass query. Rows missing columns present in other rows will resolve to SQL NULL diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 52c9c65e5b917..f98520bb84a69 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -214,7 +214,7 @@ if (ban["fromdb"]) if(SSdbcore.Connect()) - INVOKE_ASYNC(SSdbcore, /datum/controller/subsystem/dbcore/proc.QuerySelect, list( + INVOKE_ASYNC(SSdbcore, TYPE_PROC_REF(/datum/controller/subsystem/dbcore, QuerySelect), list( SSdbcore.NewQuery( "INSERT INTO [format_table_name("stickyban_matched_ckey")] (matched_ckey, stickyban) VALUES (:ckey, :bannedckey) ON DUPLICATE KEY UPDATE last_matched = now()", list("ckey" = ckey, "bannedckey" = bannedckey) diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index bc720ddb1dcc5..4bd8ce5497e2d 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -736,22 +736,16 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( qdel(query_datediff) qdel(query_get_client_age) if(!new_player) - var/datum/db_query/query_log_player = SSdbcore.NewQuery( + SSdbcore.FireAndForget( "UPDATE [format_table_name("player")] SET lastseen = Now(), lastseen_round_id = :round_id, ip = INET_ATON(:ip), computerid = :computerid, lastadminrank = :admin_rank, accountjoindate = :account_join_date WHERE ckey = :ckey", list("round_id" = GLOB.round_id, "ip" = address, "computerid" = computer_id, "admin_rank" = admin_rank, "account_join_date" = account_join_date || null, "ckey" = ckey) ) - if(!query_log_player.Execute()) - qdel(query_log_player) - return - qdel(query_log_player) if(!account_join_date) account_join_date = "Error" - var/datum/db_query/query_log_connection = SSdbcore.NewQuery({" + SSdbcore.FireAndForget({" INSERT INTO `[format_table_name("connection_log")]` (`id`,`datetime`,`server_ip`,`server_port`,`round_id`,`ckey`,`ip`,`computerid`) VALUES(null,Now(),INET_ATON(:internet_address),:port,:round_id,:ckey,INET_ATON(:ip),:computerid) "}, list("internet_address" = world.internet_address || "0", "port" = world.port, "round_id" = GLOB.round_id, "ckey" = ckey, "ip" = address, "computerid" = computer_id)) - query_log_connection.Execute() - qdel(query_log_connection) SSserver_maint.UpdateHubStatus() From 0b48f15aea08a493736c2c3522dbb9ebe0857b3f Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 22:51:46 +0000 Subject: [PATCH 103/222] Automatic changelog for PR #87926 [ci skip] --- html/changelogs/AutoChangeLog-pr-87926.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87926.yml diff --git a/html/changelogs/AutoChangeLog-pr-87926.yml b/html/changelogs/AutoChangeLog-pr-87926.yml new file mode 100644 index 0000000000000..e9f5cf6610b1e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87926.yml @@ -0,0 +1,4 @@ +author: "Xander3359" +delete-after: True +changes: + - bugfix: "fix furious steel and blade ascension being jank" \ No newline at end of file From 67bb5db02db1c640a9e2b8f7079ad99bd5a0b77f Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 16 Nov 2024 00:27:07 +0000 Subject: [PATCH 104/222] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-87701.yml | 4 ---- html/changelogs/AutoChangeLog-pr-87907.yml | 4 ---- html/changelogs/AutoChangeLog-pr-87921.yml | 4 ---- html/changelogs/AutoChangeLog-pr-87923.yml | 4 ---- html/changelogs/AutoChangeLog-pr-87926.yml | 4 ---- html/changelogs/archive/2024-11.yml | 13 +++++++++++++ 6 files changed, 13 insertions(+), 20 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-87701.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87907.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87921.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87923.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87926.yml diff --git a/html/changelogs/AutoChangeLog-pr-87701.yml b/html/changelogs/AutoChangeLog-pr-87701.yml deleted file mode 100644 index 1f05ead77f3f7..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87701.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "carlarctg" -delete-after: True -changes: - - rscadd: "Adds the Perceptomatrix Helm, a hallucination anomaly core item" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87907.yml b/html/changelogs/AutoChangeLog-pr-87907.yml deleted file mode 100644 index f193ce7beefb7..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87907.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "zxaber" -delete-after: True -changes: - - bugfix: "Firelocks opened by a mech will correctly close when the mech moves out of range." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87921.yml b/html/changelogs/AutoChangeLog-pr-87921.yml deleted file mode 100644 index 6cd0df74d9035..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87921.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "TheRealSpriteMan1337" -delete-after: True -changes: - - spellcheck: "Fixed some of the typos in computers' build & repair tips, adjusted wording" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87923.yml b/html/changelogs/AutoChangeLog-pr-87923.yml deleted file mode 100644 index 0cb0e4f5a83df..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87923.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Hardly" -delete-after: True -changes: - - bugfix: "Fixes watchers not attacking their targets in melee range" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87926.yml b/html/changelogs/AutoChangeLog-pr-87926.yml deleted file mode 100644 index e9f5cf6610b1e..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87926.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Xander3359" -delete-after: True -changes: - - bugfix: "fix furious steel and blade ascension being jank" \ No newline at end of file diff --git a/html/changelogs/archive/2024-11.yml b/html/changelogs/archive/2024-11.yml index 51197f3841a72..fa2369b588efa 100644 --- a/html/changelogs/archive/2024-11.yml +++ b/html/changelogs/archive/2024-11.yml @@ -562,3 +562,16 @@ reduce the timer to 20 minutes before it can be purchased. xPokee: - bugfix: fixed brains turning invisible after being washed +2024-11-16: + Hardly: + - bugfix: Fixes watchers not attacking their targets in melee range + TheRealSpriteMan1337: + - spellcheck: Fixed some of the typos in computers' build & repair tips, adjusted + wording + Xander3359: + - bugfix: fix furious steel and blade ascension being jank + carlarctg: + - rscadd: Adds the Perceptomatrix Helm, a hallucination anomaly core item + zxaber: + - bugfix: Firelocks opened by a mech will correctly close when the mech moves out + of range. From ae35a773f19560d30a511cce6718623ddcd42b1c Mon Sep 17 00:00:00 2001 From: carlarctg <53100513+carlarctg@users.noreply.github.com> Date: Fri, 15 Nov 2024 22:00:51 -0300 Subject: [PATCH 105/222] [no gbp] renmoves bartender skillchip from chipped quuirk (#87918) ## About The Pull Request job skillchip, combat skilchip, bad skilchip ## Why It's Good For The Game combat is bad job is bad no quirk no good no no no, no quirk get combat no quirk get job contant, ver ybad not good ## Changelog :cl: fix: [no gbp] renmoves bartender skillchip from chipped quirk /:cl: --- code/_globalvars/lists/quirks.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/_globalvars/lists/quirks.dm b/code/_globalvars/lists/quirks.dm index 825c217d055cc..5bd44e667f92d 100644 --- a/code/_globalvars/lists/quirks.dm +++ b/code/_globalvars/lists/quirks.dm @@ -118,7 +118,6 @@ GLOBAL_LIST_INIT(quirk_chipped_choice, list( "GENUINE ID Appraisal Now!" = /obj/item/skillchip/appraiser, "Le S48R4G3" = /obj/item/skillchip/sabrage, "Integrated Intuitive Thinking and Judging" = /obj/item/skillchip/intj, - "F0RC3 4DD1CT10N" = /obj/item/skillchip/drunken_brawler, "\"Space Station 13: The Musical\"" = /obj/item/skillchip/musical, "Mast-Angl-Er" = /obj/item/skillchip/master_angler, "Kommand" = /obj/item/skillchip/big_pointer, From 4fbab25406595bbe0050c2c49fcfba5fc8a959af Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 16 Nov 2024 01:01:46 +0000 Subject: [PATCH 106/222] Automatic changelog for PR #87918 [ci skip] --- html/changelogs/AutoChangeLog-pr-87918.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87918.yml diff --git a/html/changelogs/AutoChangeLog-pr-87918.yml b/html/changelogs/AutoChangeLog-pr-87918.yml new file mode 100644 index 0000000000000..5ba6fe31b931e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87918.yml @@ -0,0 +1,4 @@ +author: "carlarctg" +delete-after: True +changes: + - bugfix: "[no gbp] renmoves bartender skillchip from chipped quirk" \ No newline at end of file From c14e214af5690a893d8ccf708d5f25291c074759 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 15 Nov 2024 21:23:01 -0600 Subject: [PATCH 107/222] Fix radio jammer screentips (#87927) ## About The Pull Request This fixes the radio jammer screentips since it was using the wrong path. ## Why It's Good For The Game Consistency. ## Changelog :cl: fix: Fix radio jammer screentips /:cl: --- code/game/objects/items/devices/traitordevices.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 5a108c83e823b..c1ed690a3143c 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -341,7 +341,7 @@ effective or pretty fucking useless. . = ..() register_context() -/atom/movable/screen/alert/give/add_context(atom/source, list/context, obj/item/held_item, mob/user) +/obj/item/jammer/add_context(atom/source, list/context, obj/item/held_item, mob/user) context[SCREENTIP_CONTEXT_LMB] = "Release distruptor wave" context[SCREENTIP_CONTEXT_RMB] = "Toggle" return CONTEXTUAL_SCREENTIP_SET From 1b9bdd1938c86313c9df7e0326607c5807d6d49c Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 16 Nov 2024 03:23:21 +0000 Subject: [PATCH 108/222] Automatic changelog for PR #87927 [ci skip] --- html/changelogs/AutoChangeLog-pr-87927.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87927.yml diff --git a/html/changelogs/AutoChangeLog-pr-87927.yml b/html/changelogs/AutoChangeLog-pr-87927.yml new file mode 100644 index 0000000000000..68e0a869a57e1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87927.yml @@ -0,0 +1,4 @@ +author: "timothymtorres" +delete-after: True +changes: + - bugfix: "Fix radio jammer screentips" \ No newline at end of file From f6e727cc1bed00f135e502cb877789c126356dd6 Mon Sep 17 00:00:00 2001 From: JagOfTroy <87827746+JagOfTroy@users.noreply.github.com> Date: Fri, 15 Nov 2024 21:24:00 -0600 Subject: [PATCH 109/222] AAS - Research Node Announcement Message fix (#87928) ((First Pull Request, please bare with me)) There was a reported error from a user across all maps that updating the Research Node message with the AAS system would never update. It turns out to just be a syntax error. the ' around %NODE ' translates them into ASCI code. Leaving out the ', it will properly update the message as intended by the user. I have tested this multiple times and taken screenshots for proof. I also adjusted the other variable of new_text to newText so that it matches the other variables for other announcement messages. ## Why It's Good For The Game This fixes just a plain old broken bug that seems to have gone unnoticed for the most part. ## Changelog :cl: fix: Fixed Automatic Announcement System bug with the Research Node Announcement message not updating properly. It will now properly save and announce whatever input the user desires! :cl: --- code/game/machinery/announcement_system.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/machinery/announcement_system.dm b/code/game/machinery/announcement_system.dm index 029f4a17ea99b..eb66e140d98fb 100644 --- a/code/game/machinery/announcement_system.dm +++ b/code/game/machinery/announcement_system.dm @@ -34,7 +34,7 @@ GLOBAL_LIST_EMPTY(announcement_systems) ///If true, researched nodes will be announced to the appropriate channels var/announce_research_node = TRUE /// The text that we send when announcing researched nodes. - var/node_message = "The '%NODE' techweb node has been researched" + var/node_message = "The %NODE techweb node has been researched" /obj/machinery/announcement_system/Initialize(mapload) . = ..() @@ -164,7 +164,7 @@ GLOBAL_LIST_EMPTY(announcement_systems) newhead = new_message usr.log_message("updated the head announcement to: [new_message]", LOG_GAME) if("node_message") - var/new_message = trim(html_encode(param["new_text"]), MAX_MESSAGE_LEN) + var/new_message = trim(html_encode(param["newText"]), MAX_MESSAGE_LEN) if(new_message) node_message = new_message usr.log_message("updated the researched node announcement to: [node_message]", LOG_GAME) From 202ec68f710ad6fd3122e38dbf2c3a501341ada6 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 16 Nov 2024 03:24:24 +0000 Subject: [PATCH 110/222] Automatic changelog for PR #87928 [ci skip] --- html/changelogs/AutoChangeLog-pr-87928.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87928.yml diff --git a/html/changelogs/AutoChangeLog-pr-87928.yml b/html/changelogs/AutoChangeLog-pr-87928.yml new file mode 100644 index 0000000000000..34bec5c1fcfe0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87928.yml @@ -0,0 +1,4 @@ +author: "JagOfTroy" +delete-after: True +changes: + - bugfix: "Fixed Automatic Announcement System bug with the Research Node Announcement message not updating properly. It will now properly save and announce whatever input the user desires!\n:cl:" \ No newline at end of file From c7d7c7625ab82399af00d46e97f9be99a3d66ffc Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Sat, 16 Nov 2024 04:24:33 +0100 Subject: [PATCH 111/222] [NO GBP] Fixes tethers being able to move immovable objects (and delete gravgens) (#87911) ## About The Pull Request Closes #87203 Forgot that move_force was a thing ## Changelog :cl: fix: Fixed tethers being able to move immovable objects (and delete gravgens) /:cl: --- code/datums/components/tether.dm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/datums/components/tether.dm b/code/datums/components/tether.dm index 1e8313fa53b2b..b9eb40647acd1 100644 --- a/code/datums/components/tether.dm +++ b/code/datums/components/tether.dm @@ -72,9 +72,11 @@ to_chat(source, span_warning("[tether_name] prevents you from entering [new_loc]!")) return COMPONENT_MOVABLE_BLOCK_PRE_MOVE + // If this was called, we know its a movable + var/atom/movable/movable_source = source var/atom/movable/anchor = (source == tether_target ? parent : tether_target) if (get_dist(anchor, new_loc) > cur_dist) - if (!istype(anchor) || anchor.anchored || !anchor.Move(get_step_towards(anchor, new_loc))) + if (!istype(anchor) || anchor.anchored || !(!anchor.anchored && anchor.move_resist <= movable_source.move_force && anchor.Move(get_step_towards(anchor, new_loc)))) to_chat(source, span_warning("[tether_name] runs out of slack and prevents you from moving!")) return COMPONENT_MOVABLE_BLOCK_PRE_MOVE @@ -105,7 +107,6 @@ if (get_dist(anchor, new_loc) != cur_dist || !ismovable(source)) return - var/atom/movable/movable_source = source var/datum/drift_handler/handler = movable_source.drift_handler if (isnull(handler)) return @@ -179,12 +180,12 @@ var/atom/movable/movable_parent = parent var/atom/movable/movable_target = tether_target - if (istype(movable_parent) && movable_parent.Move(get_step(movable_parent.loc, get_dir(movable_parent, movable_target)))) + if (istype(movable_parent) && !movable_parent.anchored && movable_parent.move_resist <= movable_target.move_force && movable_parent.Move(get_step(movable_parent.loc, get_dir(movable_parent, movable_target)))) cur_dist -= 1 location.balloon_alert(user, "tether shortened") return - if (istype(movable_target) && movable_target.Move(get_step(movable_target.loc, get_dir(movable_target, movable_parent)))) + if (istype(movable_target) && !movable_target.anchored && movable_target.move_resist <= movable_parent.move_force && movable_target.Move(get_step(movable_target.loc, get_dir(movable_target, movable_parent)))) cur_dist -= 1 location.balloon_alert(user, "tether shortened") return From 29ab4ff1cba180365f6d05615bb3e89520bf0ac4 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 16 Nov 2024 03:24:57 +0000 Subject: [PATCH 112/222] Automatic changelog for PR #87911 [ci skip] --- html/changelogs/AutoChangeLog-pr-87911.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87911.yml diff --git a/html/changelogs/AutoChangeLog-pr-87911.yml b/html/changelogs/AutoChangeLog-pr-87911.yml new file mode 100644 index 0000000000000..408f14fce5fe1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87911.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Fixed tethers being able to move immovable objects (and delete gravgens)" \ No newline at end of file From c8e49fd01bdfa85beae171168ba26255bf19fd2c Mon Sep 17 00:00:00 2001 From: Fikou <23585223+Fikou@users.noreply.github.com> Date: Sat, 16 Nov 2024 11:43:30 +0100 Subject: [PATCH 113/222] xeno princesses no longer lose their unique identifier (#87917) --- .../mob/living/carbon/alien/adult/adult.dm | 14 ++++++++------ .../mob/living/carbon/alien/adult/queen.dm | 17 +++++------------ code/modules/mob/living/carbon/alien/alien.dm | 2 +- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/code/modules/mob/living/carbon/alien/adult/adult.dm b/code/modules/mob/living/carbon/alien/adult/adult.dm index d2c41e61a12fb..45e9dea454dce 100644 --- a/code/modules/mob/living/carbon/alien/adult/adult.dm +++ b/code/modules/mob/living/carbon/alien/adult/adult.dm @@ -56,14 +56,16 @@ GLOBAL_LIST_INIT(strippable_alien_humanoid_items, create_strippable_list(list( ..() //For alien evolution/promotion/queen finder procs. Checks for an active alien of that type -/proc/get_alien_type(alienpath) - for(var/mob/living/carbon/alien/adult/A in GLOB.alive_mob_list) - if(!istype(A, alienpath)) +/proc/get_alien_type(alien_path, mob/ignored) + for(var/mob/living/carbon/alien/alien in GLOB.carbon_list) + if(alien == ignored) continue - if(!A.key || A.stat == DEAD) //Only living aliens with a ckey are valid. + if(!istype(alien, alien_path)) continue - return A - return FALSE + if(!alien.key || alien.stat == DEAD) //Only living aliens with a ckey are valid. + continue + return alien + return null /mob/living/carbon/alien/adult/check_breath(datum/gas_mixture/breath) if(breath?.total_moles() > 0 && !HAS_TRAIT(src, TRAIT_SNEAK)) diff --git a/code/modules/mob/living/carbon/alien/adult/queen.dm b/code/modules/mob/living/carbon/alien/adult/queen.dm index 8cbd55719774c..cfe6f45320a73 100644 --- a/code/modules/mob/living/carbon/alien/adult/queen.dm +++ b/code/modules/mob/living/carbon/alien/adult/queen.dm @@ -44,18 +44,6 @@ alien_speed = 2 /mob/living/carbon/alien/adult/royal/queen/Initialize(mapload) - //there should only be one queen - for(var/mob/living/carbon/alien/adult/royal/queen/Q in GLOB.carbon_list) - if(Q == src) - continue - if(Q.stat == DEAD) - continue - if(Q.client) - name = "alien princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it. - break - - real_name = src.name - var/static/list/innate_actions = list( /datum/action/cooldown/alien/promote, /datum/action/cooldown/spell/aoe/repulse/xeno, @@ -72,6 +60,11 @@ organs += new /obj/item/organ/alien/eggsac return ..() +/mob/living/carbon/alien/adult/royal/queen/set_name() + if(get_alien_type(/mob/living/carbon/alien/adult/royal/queen, ignored = src)) + name = "alien princess" + return ..() + //Queen verbs /datum/action/cooldown/alien/make_structure/lay_egg name = "Lay Egg" diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 120633acdfe4a..124711098674d 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -22,7 +22,7 @@ gib_type = /obj/effect/decal/cleanable/xenoblood/xgibs unique_name = TRUE - var/static/regex/alien_name_regex = new("alien (larva|sentinel|drone|hunter|praetorian|queen)( \\(\\d+\\))?") + var/static/regex/alien_name_regex = new("alien (larva|sentinel|drone|hunter|praetorian|princess|queen)( \\(\\d+\\))?") var/static/list/xeno_allowed_items = typecacheof(list( /obj/item/clothing/mask/facehugger, /obj/item/toy/basketball, // playing ball against a xeno is rigged since they cannot be disarmed, their game is out of this world From 3b5739334636e658efdaba56edf7611bc1f7a166 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 16 Nov 2024 10:43:49 +0000 Subject: [PATCH 114/222] Automatic changelog for PR #87917 [ci skip] --- html/changelogs/AutoChangeLog-pr-87917.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87917.yml diff --git a/html/changelogs/AutoChangeLog-pr-87917.yml b/html/changelogs/AutoChangeLog-pr-87917.yml new file mode 100644 index 0000000000000..8614ffbf1c890 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87917.yml @@ -0,0 +1,4 @@ +author: "Fikou" +delete-after: True +changes: + - bugfix: "xeno princesses no longer lose their unique identifier" \ No newline at end of file From 34156c60f2920219fde018c8db7c8667bf273a15 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Sat, 16 Nov 2024 13:53:44 +0100 Subject: [PATCH 115/222] Removes N-Spect scanner's and scanner gate's ability to scan people for contraband (#87882) ## About The Pull Request What title says. Handheld N-Spect scanners and scanner gates can no longer scan people for contraband. N-Spect scanners can still scan items and storage containers. ## Why It's Good For The Game Contraband scanners are a direct (and pretty much binary) antag check (which goes against our general disdain towards antag checks) and a significantly faster and easier bag check (which goes against our server policy established eons ago). This interaction isn't logged either which is also very bad. There is no way to avoid being caught if someone comes up to you intending to scan/bag check you, which is why bag check policy was made in the first place - if you don't agree to it, you must have something to hide. Scans aren't logged either, you can only check nspect's says to see if there was an attempted scan but not if its been finished or what the results were. ## Changelog :cl: del: Removed N-Spect scanner's and scanner gate's ability to scan people for contraband. /:cl: --- code/game/machinery/scanner_gate.dm | 62 ------------------- code/game/objects/items/inspector.dm | 14 +---- tgui/packages/tgui/interfaces/ScannerGate.jsx | 25 -------- 3 files changed, 2 insertions(+), 99 deletions(-) diff --git a/code/game/machinery/scanner_gate.dm b/code/game/machinery/scanner_gate.dm index d9677e63adb25..af097605bc3ae 100644 --- a/code/game/machinery/scanner_gate.dm +++ b/code/game/machinery/scanner_gate.dm @@ -5,7 +5,6 @@ #define SCANGATE_WANTED "Wanted" #define SCANGATE_SPECIES "Species" #define SCANGATE_NUTRITION "Nutrition" -#define SCANGATE_CONTRABAND "Contraband" /obj/machinery/scanner_gate name = "scanner gate" @@ -39,8 +38,6 @@ var/minus_false_beep = 0 ///Base false positive/negative chance var/base_false_beep = 5 - ///Is an n-spect scanner attached to the gate? Enables contraband scanning. - var/obj/item/inspector/n_spect = null ///List of species that can be scanned by the gate. Supports adding more species' IDs during in-game. var/list/available_species = list( SPECIES_HUMAN, @@ -76,12 +73,6 @@ for(var/datum/stock_part/scanning_module/scanning_module in component_parts) minus_false_beep = scanning_module.tier //The better are scanninning modules - the lower is chance of False Positives -/obj/machinery/scanner_gate/atom_deconstruct(disassembled) - . = ..() - if(n_spect) - n_spect.forceMove(drop_location()) - n_spect = null - /obj/machinery/scanner_gate/examine(mob/user) . = ..() @@ -90,18 +81,6 @@ . += span_notice("The control panel is ID-locked. Swipe a valid ID to unlock it.") else . += span_notice("The control panel is unlocked. Swipe an ID to lock it.") - if(n_spect) - . += span_notice("The scanner is equipped with an N-Spect scanner. Use a [span_boldnotice("crowbar")] to uninstall.") - -/obj/machinery/scanner_gate/add_context(atom/source, list/context, obj/item/held_item, mob/user) - . = ..() - if(n_spect && held_item?.tool_behaviour == TOOL_CROWBAR) - context[SCREENTIP_CONTEXT_LMB] = "Remove N-Spect scanner" - return CONTEXTUAL_SCREENTIP_SET - if(!n_spect && istype(held_item, /obj/item/inspector)) - context[SCREENTIP_CONTEXT_LMB] = "Install N-Spect scanner" - return CONTEXTUAL_SCREENTIP_SET - /obj/machinery/scanner_gate/proc/on_entered(datum/source, atom/movable/thing) SIGNAL_HANDLER @@ -136,19 +115,6 @@ return set_scanline("passive") -/obj/machinery/scanner_gate/item_interaction(mob/living/user, obj/item/tool, list/modifiers) - if(istype(tool, /obj/item/inspector)) - if(n_spect) - to_chat(user, span_warning("The scanner is already equipped with an N-Spect scanner.")) - return ITEM_INTERACT_BLOCKING - else - to_chat(user, span_notice("You install an N-Spect scanner on [src].")) - n_spect = tool - if(!user.transferItemToLoc(tool, src)) - return ITEM_INTERACT_BLOCKING - return ITEM_INTERACT_SUCCESS - return NONE - /obj/machinery/scanner_gate/attackby(obj/item/attacking_item, mob/user, params) var/obj/item/card/id/card = attacking_item.GetID() if(card) @@ -171,24 +137,6 @@ wires.interact(user) return ..() -/obj/machinery/scanner_gate/crowbar_act(mob/living/user, obj/item/tool) - . = ..() - if(n_spect) - if(locked) - balloon_alert(user, "locked!") - return ITEM_INTERACT_BLOCKING - - to_chat(user, span_notice("You uninstall [n_spect] from [src].")) - n_spect.forceMove(drop_location()) - return ITEM_INTERACT_SUCCESS - -/obj/machinery/scanner_gate/Exited(atom/gone) - . = ..() - if(gone == n_spect) - n_spect = null - if(scangate_mode == SCANGATE_CONTRABAND) - scangate_mode = SCANGATE_NONE - /obj/machinery/scanner_gate/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) return FALSE @@ -268,14 +216,6 @@ if(scanned_human.nutrition >= detect_nutrition && detect_nutrition == NUTRITION_LEVEL_FAT) beep = TRUE detected_thing = "Obesity" - if(SCANGATE_CONTRABAND) - for(var/obj/item/content in thing.get_all_contents_skipping_traits(TRAIT_CONTRABAND_BLOCKER)) - detected_thing = "Contraband" - if(content.is_contraband()) - beep = TRUE - break - if(!n_spect.scans_correctly) - beep = !beep //We do a little trolling if(reverse) beep = !beep @@ -341,7 +281,6 @@ data["disease_threshold"] = disease_threshold data["target_species_id"] = detect_species_id data["target_nutrition"] = detect_nutrition - data["contraband_enabled"] = !!n_spect data["target_zombie"] = (detect_species_id == SPECIES_ZOMBIE) return data @@ -398,4 +337,3 @@ #undef SCANGATE_WANTED #undef SCANGATE_SPECIES #undef SCANGATE_NUTRITION -#undef SCANGATE_CONTRABAND diff --git a/code/game/objects/items/inspector.dm b/code/game/objects/items/inspector.dm index d4abe4c1d1a5b..7783dcff072b5 100644 --- a/code/game/objects/items/inspector.dm +++ b/code/game/objects/items/inspector.dm @@ -20,7 +20,6 @@ interaction_flags_click = NEED_DEXTERITY throw_range = 1 throw_speed = 1 - COOLDOWN_DECLARE(scanning_person) //Cooldown for scanning a carbon ///How long it takes to print on time each mode, ordered NORMAL, FAST, HONK var/list/time_list = list(5 SECONDS, 1 SECONDS, 0.1 SECONDS) ///Which print time mode we're on. @@ -108,17 +107,8 @@ balloon_alert(user, "check cell!") return ITEM_INTERACT_BLOCKING - if(iscarbon(interacting_with)) //Prevents insta scanning people - if(!COOLDOWN_FINISHED(src, scanning_person)) - return ITEM_INTERACT_BLOCKING - - visible_message(span_warning("[user] starts scanning [interacting_with] with [src]")) - to_chat(interacting_with, span_userdanger("[user] is trying to scan you for contraband!")) - balloon_alert_to_viewers("scanning...") - playsound(src, SFX_INDUSTRIAL_SCAN, 20, TRUE, -2, TRUE, FALSE) - COOLDOWN_START(src, scanning_person, 4 SECONDS) - if(!do_after(user, 4 SECONDS, interacting_with)) - return ITEM_INTERACT_BLOCKING + if(iscarbon(interacting_with)) // Prevents scanning people + return if(contraband_scan(interacting_with, user)) playsound(src, 'sound/machines/uplink/uplinkerror.ogg', 40) diff --git a/tgui/packages/tgui/interfaces/ScannerGate.jsx b/tgui/packages/tgui/interfaces/ScannerGate.jsx index 51e32cbdc6e67..8eb61cea7f270 100644 --- a/tgui/packages/tgui/interfaces/ScannerGate.jsx +++ b/tgui/packages/tgui/interfaces/ScannerGate.jsx @@ -67,10 +67,6 @@ const SCANNER_GATE_ROUTES = { title: 'Scanner Mode: Nutrition', component: () => ScannerGateNutrition, }, - Contraband: { - title: 'Scanner Mode: Contraband', - component: () => ScannerGateContraband, - }, }; const ScannerGateControl = (props) => { @@ -98,7 +94,6 @@ const ScannerGateControl = (props) => { const ScannerGateOff = (props) => { const { act, data } = useBackend(); - const { contraband_enabled } = data; return ( <> Select a scanning mode below. @@ -127,11 +122,6 @@ const ScannerGateOff = (props) => { content="Nutrition" onClick={() => act('set_mode', { new_mode: 'Nutrition' })} /> - + + ))} + + + ); +} diff --git a/tgui/packages/tgui/interfaces/SimpleBot.tsx b/tgui/packages/tgui/interfaces/SimpleBot.tsx index 8ac2b4201a74c..2085dcd46459f 100644 --- a/tgui/packages/tgui/interfaces/SimpleBot.tsx +++ b/tgui/packages/tgui/interfaces/SimpleBot.tsx @@ -35,7 +35,7 @@ type Settings = { export function SimpleBot(props) { const { data } = useBackend(); - const { can_hack, custom_controls, locked } = data; + const { can_hack, locked } = data; const access = !locked || !!can_hack; return ( @@ -43,25 +43,11 @@ export function SimpleBot(props) { -
}> - {!access ? Locked! : } -
+
{!!access && ( -
- - {Object.entries(custom_controls).map((control) => ( - - - - ))} - -
+
)}
@@ -70,6 +56,36 @@ export function SimpleBot(props) { ); } +export function BotSettings(props) { + const { act, data } = useBackend(); + const { can_hack, locked } = data; + const access = !locked || !!can_hack; + return ( +
}> + {!access ? Locked! : } +
+ ); +} + +export function BotControl(props) { + const { act, data } = useBackend(); + const { custom_controls } = data; + return ( +
+ + {Object.entries(custom_controls).map((control) => ( + + + + ))} + +
+ ); +} /** Creates a lock button at the top of the controls */ function TabDisplay(props) { const { act, data } = useBackend(); From 3c8fa5630fb13ad9224c392feccccada96d4c752 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 20:20:23 +0000 Subject: [PATCH 208/222] Automatic changelog for PR #86084 [ci skip] --- html/changelogs/AutoChangeLog-pr-86084.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86084.yml diff --git a/html/changelogs/AutoChangeLog-pr-86084.yml b/html/changelogs/AutoChangeLog-pr-86084.yml new file mode 100644 index 0000000000000..6baf5b4ba8a72 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86084.yml @@ -0,0 +1,5 @@ +author: "Ben10Omintrix" +delete-after: True +changes: + - refactor: "floorbots have been refactored, please report any bugs" + - rscadd: "adds repairbots to the game!" \ No newline at end of file From b67a0901f2a5f2f32a12b75f5114af30896a60b5 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 19 Nov 2024 15:24:52 -0500 Subject: [PATCH 209/222] Fix issues discovered via TypeMaker (#87596) ## About The Pull Request Fixes issues with var typing and proc arguments, discovered using OpenDream's WIP TypeMaker feature (using improvements I haven't PR'd upstream yet). ## Why It's Good For The Game Codebase maintenance. --- code/__HELPERS/game.dm | 4 +- code/controllers/subsystem/dynamic/dynamic.dm | 2 +- code/controllers/subsystem/ipintel.dm | 2 +- code/controllers/subsystem/pathfinder.dm | 2 +- code/controllers/subsystem/research.dm | 2 +- code/controllers/subsystem/spatial_gridmap.dm | 4 +- code/controllers/subsystem/tgui.dm | 2 +- code/datums/components/infective.dm | 2 +- code/datums/components/manual_breathing.dm | 2 +- code/datums/outfit.dm | 2 +- .../datums/status_effects/agent_pinpointer.dm | 2 +- .../game/machinery/computer/communications.dm | 2 +- .../orders/order_computer/mining_order.dm | 2 +- .../orders/order_computer/order_computer.dm | 8 +- .../order_items/cook/order_milk_eggs.dm | 58 ++++++------- .../orders/order_items/cook/order_reagents.dm | 42 +++++----- .../orders/order_items/cook/order_veggies.dm | 82 +++++++++---------- .../order_items/mining/order_consumables.dm | 24 +++--- .../orders/order_items/mining/order_golem.dm | 16 ++-- .../orders/order_items/mining/order_mining.dm | 64 +++++++-------- .../orders/order_items/mining/order_pka.dm | 22 ++--- .../orders/order_items/mining/order_toys.dm | 18 ++-- .../orders/order_items/order_datum.dm | 13 +-- code/game/machinery/harvester.dm | 2 +- code/game/machinery/scanner_gate.dm | 2 +- .../objects/items/robot/robot_upgrades.dm | 2 +- .../stacks/golem_food/golem_status_effects.dm | 2 +- code/game/objects/items/weaponry.dm | 2 +- .../cannons/mounted_guns/mounted_gun.dm | 2 +- code/game/objects/structures/spawner.dm | 2 +- code/game/turfs/closed/minerals.dm | 2 +- code/modules/admin/verbs/ert.dm | 4 +- .../antagonists/cult/cult_turf_overlay.dm | 3 +- .../antagonists/heretic/heretic_antag.dm | 6 +- .../antagonists/heretic/heretic_knowledge.dm | 18 ++-- .../antagonists/heretic/knowledge/ash_lore.dm | 6 +- .../heretic/knowledge/blade_lore.dm | 4 +- .../heretic/knowledge/cosmic_lore.dm | 8 +- .../heretic/knowledge/flesh_lore.dm | 2 +- .../heretic/knowledge/lock_lore.dm | 4 +- .../heretic/knowledge/moon_lore.dm | 8 +- .../heretic/knowledge/rust_lore.dm | 6 +- .../heretic/knowledge/side_blade_rust.dm | 2 +- .../heretic/knowledge/side_cosmos_ash.dm | 2 +- .../heretic/knowledge/side_flesh_void.dm | 6 +- .../heretic/knowledge/side_lock_flesh.dm | 4 +- .../heretic/knowledge/side_lock_moon.dm | 2 +- .../heretic/knowledge/starting_lore.dm | 4 +- .../heretic/knowledge/void_lore.dm | 6 +- code/modules/antagonists/spy/spy_bounty.dm | 4 +- .../environmental/LINDA_turf_tile.dm | 2 +- code/modules/autowiki/pages/fishing.dm | 2 +- code/modules/bitrunning/objects/vendor.dm | 2 +- code/modules/bitrunning/orders/bepis.dm | 8 +- code/modules/bitrunning/orders/flair.dm | 18 ++-- code/modules/bitrunning/orders/tech.dm | 22 ++--- code/modules/bitrunning/server/_parent.dm | 2 +- code/modules/capture_the_flag/ctf_game.dm | 2 +- code/modules/cargo/bounties/botany.dm | 6 +- code/modules/cargo/centcom_podlauncher.dm | 2 +- code/modules/fishing/fishing_equipment.dm | 10 +-- .../food_and_drinks/machinery/smartfridge.dm | 2 +- code/modules/hallucination/stray_bullet.dm | 1 - code/modules/hydroponics/seeds.dm | 2 +- .../jobs/job_types/security_officer.dm | 2 +- .../ruins/objects_and_mobs/ash_walker_den.dm | 10 +-- .../spaceruin_code/hauntedtradingpost.dm | 2 +- code/modules/mining/equipment/grapple_gun.dm | 2 +- .../jungle/seedling/seedling_projectiles.dm | 2 +- .../mob/living/silicon/robot/robot_defense.dm | 2 +- .../hostile/mining_mobs/curse_blob.dm | 2 +- code/modules/mod/modules/modules_general.dm | 2 +- .../file_system/programs/virtual_pet.dm | 2 +- code/modules/power/singularity/singularity.dm | 2 +- code/modules/projectiles/guns/energy/laser.dm | 2 +- .../projectile/energy/nuclear_particle.dm | 2 +- code/modules/reagents/chemistry/reagents.dm | 2 +- code/modules/religion/rites.dm | 5 +- .../modules/research/techweb/_techweb_node.dm | 2 +- code/modules/shuttle/supply.dm | 2 +- .../spells/spell_types/jaunt/bloodcrawl.dm | 2 +- .../spells/spell_types/pointed/_pointed.dm | 2 +- code/modules/station_goals/bsa.dm | 2 +- code/modules/surgery/bodyparts/parts.dm | 4 +- .../species_parts/ethereal_bodyparts.dm | 2 +- .../bodyparts/species_parts/misc_bodyparts.dm | 14 ++-- .../species_parts/plasmaman_bodyparts.dm | 2 +- .../modules/transport/tram/tram_controller.dm | 2 +- code/modules/unit_tests/orderable_items.dm | 12 +-- code/modules/uplink/uplink_items.dm | 6 +- code/modules/vehicles/secway.dm | 4 +- .../wiremod/components/action/laserpointer.dm | 4 +- .../wiremod/components/admin/getvar.dm | 2 +- 93 files changed, 336 insertions(+), 338 deletions(-) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 1740402e62799..2c285a348fac2 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -75,8 +75,8 @@ return !player_mind || !player_mind.current || !player_mind.current.client || player_mind.current.client.is_afk() ///Return an object with a new maptext (not currently in use) -/proc/screen_text(obj/object_to_change, maptext = "", screen_loc = "CENTER-7,CENTER-7", maptext_height = 480, maptext_width = 480) - if(!isobj(object_to_change)) +/proc/screen_text(atom/movable/object_to_change, maptext = "", screen_loc = "CENTER-7,CENTER-7", maptext_height = 480, maptext_width = 480) + if(!istype(object_to_change)) object_to_change = new /atom/movable/screen/text() object_to_change.maptext = MAPTEXT(maptext) object_to_change.maptext_height = maptext_height diff --git a/code/controllers/subsystem/dynamic/dynamic.dm b/code/controllers/subsystem/dynamic/dynamic.dm index d037d48d85475..8cfe55398a151 100644 --- a/code/controllers/subsystem/dynamic/dynamic.dm +++ b/code/controllers/subsystem/dynamic/dynamic.dm @@ -569,7 +569,7 @@ SUBSYSTEM_DEF(dynamic) /datum/controller/subsystem/dynamic/proc/post_setup(report) for(var/datum/dynamic_ruleset/roundstart/rule in executed_rules) rule.candidates.Cut() // The rule should not use candidates at this point as they all are null. - addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/controller/subsystem/dynamic/, execute_roundstart_rule), rule), rule.delay) + addtimer(CALLBACK(src, PROC_REF(execute_roundstart_rule), rule), rule.delay) if (!CONFIG_GET(flag/no_intercept_report)) addtimer(CALLBACK(src, PROC_REF(send_intercept)), rand(waittime_l, waittime_h)) diff --git a/code/controllers/subsystem/ipintel.dm b/code/controllers/subsystem/ipintel.dm index db397d514742f..3ae9cfab0c564 100644 --- a/code/controllers/subsystem/ipintel.dm +++ b/code/controllers/subsystem/ipintel.dm @@ -8,7 +8,7 @@ SUBSYSTEM_DEF(ipintel) /// Cache for previously queried IP addresses and those stored in the database var/list/datum/ip_intel/cached_queries = list() /// The store for rate limiting - var/list/rate_limit_minute + var/rate_limit_minute /// The ip intel for a given address /datum/ip_intel diff --git a/code/controllers/subsystem/pathfinder.dm b/code/controllers/subsystem/pathfinder.dm index 70dc152b06df2..17ee754718e5e 100644 --- a/code/controllers/subsystem/pathfinder.dm +++ b/code/controllers/subsystem/pathfinder.dm @@ -82,7 +82,7 @@ SUBSYSTEM_DEF(pathfinder) // Otherwise we're gonna make a new one, and turn it into a path for the callbacks passed into us var/list/datum/callback/pass_in = list() - pass_in += CALLBACK(GLOBAL_PROC, /proc/path_map_passalong, on_finish, get_turf(caller), mintargetdist, skip_first) + pass_in += CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(path_map_passalong), on_finish, get_turf(caller), mintargetdist, skip_first) // And to allow subsequent calls to reuse the same map, we'll put a placeholder in the cache, and fill it up when the pathing finishes var/datum/path_map/empty = new() empty.pass_info = new(caller, access) diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm index 7bb83fa133d50..9979a1a731262 100644 --- a/code/controllers/subsystem/research.dm +++ b/code/controllers/subsystem/research.dm @@ -171,7 +171,7 @@ SUBSYSTEM_DEF(research) /datum/controller/subsystem/research/proc/initialize_all_techweb_designs(clearall = FALSE) if(islist(techweb_designs) && clearall) - item_to_design = null + item_to_design = list() QDEL_LIST(techweb_designs) var/list/returned = list() for(var/path in subtypesof(/datum/design)) diff --git a/code/controllers/subsystem/spatial_gridmap.dm b/code/controllers/subsystem/spatial_gridmap.dm index 65bcb0ec365b0..d906de2dc7bcf 100644 --- a/code/controllers/subsystem/spatial_gridmap.dm +++ b/code/controllers/subsystem/spatial_gridmap.dm @@ -45,9 +45,9 @@ atmos_contents = dummy_list /datum/spatial_grid_cell/Destroy(force) - if(force)//the response to someone trying to qdel this is a right proper fuck you + if(!force)//the response to someone trying to qdel this is a right proper fuck you stack_trace("dont try to destroy spatial grid cells without a good reason. if you need to do it use force") - return + return QDEL_HINT_LETMELIVE . = ..() diff --git a/code/controllers/subsystem/tgui.dm b/code/controllers/subsystem/tgui.dm index cd03e1f3e5225..fe0910807827b 100644 --- a/code/controllers/subsystem/tgui.dm +++ b/code/controllers/subsystem/tgui.dm @@ -62,7 +62,7 @@ SUBSYSTEM_DEF(tgui) * Returns null if pool was exhausted. * * required user mob - * return datum/tgui + * return datum/tgui_window */ /datum/controller/subsystem/tgui/proc/request_pooled_window(mob/user) if(!user.client) diff --git a/code/datums/components/infective.dm b/code/datums/components/infective.dm index 62e2246bfd8bc..f168a3eba35de 100644 --- a/code/datums/components/infective.dm +++ b/code/datums/components/infective.dm @@ -13,7 +13,7 @@ return COMPONENT_INCOMPATIBLE if(!islist(diseases)) - diseases = islist(diseases) + diseases = list(diseases) ///Make sure the diseases list is populated with instances of diseases so that it doesn't have to be for each AddComponent call. for(var/datum/disease/disease as anything in diseases) diff --git a/code/datums/components/manual_breathing.dm b/code/datums/components/manual_breathing.dm index 8e5f096766a92..c8b1af483d034 100644 --- a/code/datums/components/manual_breathing.dm +++ b/code/datums/components/manual_breathing.dm @@ -71,7 +71,7 @@ /datum/component/manual_breathing/proc/check_added_organ(mob/who_cares, obj/item/organ/O) SIGNAL_HANDLER - var/obj/item/organ/eyes/new_lungs = O + var/obj/item/organ/lungs/new_lungs = O if(istype(new_lungs,/obj/item/organ/lungs)) L = new_lungs diff --git a/code/datums/outfit.dm b/code/datums/outfit.dm index 20660ede6f527..38e1c81b7417a 100644 --- a/code/datums/outfit.dm +++ b/code/datums/outfit.dm @@ -98,7 +98,7 @@ /** * extra types for chameleon outfit changes, mostly guns * - * Format of this list is (typepath, typepath, typepath) + * Valid values are a single typepath or list of typepaths * * These are all added and returns in the list for get_chamelon_diguise_info proc */ diff --git a/code/datums/status_effects/agent_pinpointer.dm b/code/datums/status_effects/agent_pinpointer.dm index 4df9d1733f0e7..653b04f626175 100644 --- a/code/datums/status_effects/agent_pinpointer.dm +++ b/code/datums/status_effects/agent_pinpointer.dm @@ -22,7 +22,7 @@ ///The range until you're considered 'too far away' var/range_far = 16 ///The target we are pointing towards, refreshes every tick. - var/mob/scan_target + var/atom/movable/scan_target /datum/status_effect/agent_pinpointer/tick(seconds_between_ticks) if(!owner) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index abbfb055e1647..9acdaf695286b 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -142,7 +142,7 @@ playsound(src, 'sound/machines/terminal/terminal_alert.ogg', 50, FALSE) return TRUE -/obj/machinery/computer/communications/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) +/obj/machinery/computer/communications/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/ui_state) var/static/list/approved_states = list(STATE_BUYING_SHUTTLE, STATE_CHANGING_STATUS, STATE_MAIN, STATE_MESSAGES) . = ..() diff --git a/code/game/machinery/computer/orders/order_computer/mining_order.dm b/code/game/machinery/computer/orders/order_computer/mining_order.dm index 94fda727d5f79..98c1e8eed2f28 100644 --- a/code/game/machinery/computer/orders/order_computer/mining_order.dm +++ b/code/game/machinery/computer/orders/order_computer/mining_order.dm @@ -34,7 +34,7 @@ /obj/machinery/computer/order_console/mining/order_groceries(mob/living/purchaser, obj/item/card/id/card, list/groceries) var/list/things_to_order = list() for(var/datum/orderable_item/item as anything in groceries) - things_to_order[item.item_path] = groceries[item] + things_to_order[item.purchase_path] = groceries[item] var/datum/supply_pack/custom/mining_pack = new( purchaser = purchaser, \ diff --git a/code/game/machinery/computer/orders/order_computer/order_computer.dm b/code/game/machinery/computer/orders/order_computer/order_computer.dm index 8ad5d5dde2807..b74601ee8a35d 100644 --- a/code/game/machinery/computer/orders/order_computer/order_computer.dm +++ b/code/game/machinery/computer/orders/order_computer/order_computer.dm @@ -50,7 +50,7 @@ GLOBAL_LIST_EMPTY(order_console_products) if(GLOB.order_console_products.len) return for(var/datum/orderable_item/path as anything in subtypesof(/datum/orderable_item)) - if(!initial(path.item_path)) + if(!initial(path.purchase_path)) continue GLOB.order_console_products += new path @@ -120,8 +120,8 @@ GLOBAL_LIST_EMPTY(order_console_products) "cat" = item.category_index, "ref" = REF(item), "cost" = round(item.cost_per_order * cargo_cost_multiplier), - "icon" = item.item_path::icon, - "icon_state" = item.item_path::icon_state, + "icon" = item.purchase_path::icon, + "icon_state" = item.purchase_path::icon_state, )) return data @@ -199,7 +199,7 @@ GLOBAL_LIST_EMPTY(order_console_products) grocery_list.Remove(item) continue for(var/amt in 1 to grocery_list[item])//every order amount - ordered_paths += item.item_path + ordered_paths += item.purchase_path podspawn(list( "target" = get_turf(living_user), "style" = /datum/pod_style/advanced, diff --git a/code/game/machinery/computer/orders/order_items/cook/order_milk_eggs.dm b/code/game/machinery/computer/orders/order_items/cook/order_milk_eggs.dm index 63966795f2d15..8ec5e9a53a80c 100644 --- a/code/game/machinery/computer/orders/order_items/cook/order_milk_eggs.dm +++ b/code/game/machinery/computer/orders/order_items/cook/order_milk_eggs.dm @@ -3,111 +3,111 @@ /datum/orderable_item/milk_eggs/milk name = "Milk" - item_path = /obj/item/reagent_containers/condiment/milk + purchase_path = /obj/item/reagent_containers/condiment/milk cost_per_order = 30 /datum/orderable_item/milk_eggs/soymilk name = "Soy Milk" - item_path = /obj/item/reagent_containers/condiment/soymilk + purchase_path = /obj/item/reagent_containers/condiment/soymilk cost_per_order = 30 /datum/orderable_item/milk_eggs/cream name = "Cream" - item_path = /obj/item/reagent_containers/cup/glass/bottle/juice/cream + purchase_path = /obj/item/reagent_containers/cup/glass/bottle/juice/cream cost_per_order = 40 /datum/orderable_item/milk_eggs/yoghurt name = "Yoghurt" - item_path = /obj/item/reagent_containers/condiment/yoghurt + purchase_path = /obj/item/reagent_containers/condiment/yoghurt cost_per_order = 40 /datum/orderable_item/milk_eggs/eggs name = "Egg Carton" - item_path = /obj/item/storage/fancy/egg_box + purchase_path = /obj/item/storage/fancy/egg_box cost_per_order = 40 /datum/orderable_item/milk_eggs/fillet name = "Fish Fillet" - item_path = /obj/item/food/fishmeat + purchase_path = /obj/item/food/fishmeat cost_per_order = 12 /datum/orderable_item/milk_eggs/octopus name = "Octopus Tentacle" - item_path = /obj/item/food/fishmeat/octopus + purchase_path = /obj/item/food/fishmeat/octopus cost_per_order = 12 /datum/orderable_item/milk_eggs/chicken name = "Chicken Breast" - item_path = /obj/item/food/meat/slab/chicken + purchase_path = /obj/item/food/meat/slab/chicken cost_per_order = 15 /datum/orderable_item/milk_eggs/spider_eggs name = "Spider Eggs" - item_path = /obj/item/food/spidereggs + purchase_path = /obj/item/food/spidereggs /datum/orderable_item/milk_eggs/moonfish_eggs name = "Moonfish Eggs" - item_path = /obj/item/food/moonfish_eggs + purchase_path = /obj/item/food/moonfish_eggs cost_per_order = 30 /datum/orderable_item/milk_eggs/desert_snails name = "Canned Desert Snails" - item_path = /obj/item/food/canned/desert_snails + purchase_path = /obj/item/food/canned/desert_snails cost_per_order = 20 /datum/orderable_item/milk_eggs/canned_jellyfish name = "Canned Gunner Jellyfish" - item_path = /obj/item/food/canned/jellyfish + purchase_path = /obj/item/food/canned/jellyfish cost_per_order = 20 /datum/orderable_item/milk_eggs/canned_larvae name = "Canned Larvae" - item_path = /obj/item/food/canned/larvae + purchase_path = /obj/item/food/canned/larvae cost_per_order = 20 /datum/orderable_item/milk_eggs/canned_tomatoes name = "Canned San Marzano Tomatoes" - item_path = /obj/item/food/canned/tomatoes + purchase_path = /obj/item/food/canned/tomatoes cost_per_order = 30 /datum/orderable_item/milk_eggs/canned_pine_nuts name = "Canned Pine Nuts" - item_path = /obj/item/food/canned/pine_nuts + purchase_path = /obj/item/food/canned/pine_nuts cost_per_order = 20 /datum/orderable_item/milk_eggs/canned_squid_ink name = "Canned Squid Ink" - item_path = /obj/item/food/canned/squid_ink + purchase_path = /obj/item/food/canned/squid_ink cost_per_order = 20 /datum/orderable_item/milk_eggs/chap name = "Can of CHAP" - item_path = /obj/item/food/canned/chap + purchase_path = /obj/item/food/canned/chap cost_per_order = 20 /datum/orderable_item/milk_eggs/ready_donk name = "Ready-Donk Meal: Bachelor Chow" - item_path = /obj/item/food/ready_donk + purchase_path = /obj/item/food/ready_donk cost_per_order = 40 /datum/orderable_item/milk_eggs/ready_donk_mac name = "Ready-Donk Meal: Donk-a-Roni" - item_path = /obj/item/food/ready_donk/mac_n_cheese + purchase_path = /obj/item/food/ready_donk/mac_n_cheese cost_per_order = 40 /datum/orderable_item/milk_eggs/ready_donk_mex name = "Ready-Donk Meal: Donkhiladas" - item_path = /obj/item/food/ready_donk/donkhiladas + purchase_path = /obj/item/food/ready_donk/donkhiladas cost_per_order = 40 /datum/orderable_item/milk_eggs/ready_donk_nachos name = "Ready-Donk Meal: Donk Sol Series Boritos Nachos Grandes" - item_path = /obj/item/food/ready_donk/nachos_grandes + purchase_path = /obj/item/food/ready_donk/nachos_grandes cost_per_order = 40 /datum/orderable_item/milk_eggs/ready_donk_orange name = "Ready-Donk Meal: Donk-range Chicken" - item_path = /obj/item/food/ready_donk/donkrange_chicken + purchase_path = /obj/item/food/ready_donk/donkrange_chicken cost_per_order = 40 /datum/orderable_item/milk_eggs/ready_donk_salisbury @@ -122,35 +122,35 @@ /datum/orderable_item/milk_eggs/tiziran_goods name = "Tiziran Farm-Fresh Pack" - item_path = /obj/item/storage/box/tiziran_goods + purchase_path = /obj/item/storage/box/tiziran_goods cost_per_order = 120 /datum/orderable_item/milk_eggs/tiziran_cans name = "Tiziran Canned Goods Pack" - item_path = /obj/item/storage/box/tiziran_cans + purchase_path = /obj/item/storage/box/tiziran_cans cost_per_order = 120 /datum/orderable_item/milk_eggs/tiziran_meats name = "Tiziran Meatmarket Pack" - item_path = /obj/item/storage/box/tiziran_meats + purchase_path = /obj/item/storage/box/tiziran_meats cost_per_order = 120 /datum/orderable_item/milk_eggs/mothic_goods name = "Mothic Farm-Fresh Pack" - item_path = /obj/item/storage/box/mothic_goods + purchase_path = /obj/item/storage/box/mothic_goods cost_per_order = 120 /datum/orderable_item/milk_eggs/mothic_cans_sauces name = "Mothic Pantry Pack" - item_path = /obj/item/storage/box/mothic_cans_sauces + purchase_path = /obj/item/storage/box/mothic_cans_sauces cost_per_order = 120 /datum/orderable_item/milk_eggs/armorfish name = "Cleaned Armorfish" - item_path = /obj/item/food/fishmeat/armorfish + purchase_path = /obj/item/food/fishmeat/armorfish cost_per_order = 30 /datum/orderable_item/milk_eggs/moonfish name = "Moonfish" - item_path = /obj/item/food/fishmeat/moonfish + purchase_path = /obj/item/food/fishmeat/moonfish cost_per_order = 30 diff --git a/code/game/machinery/computer/orders/order_items/cook/order_reagents.dm b/code/game/machinery/computer/orders/order_items/cook/order_reagents.dm index 39fb38df550ef..06bd251368a90 100644 --- a/code/game/machinery/computer/orders/order_items/cook/order_reagents.dm +++ b/code/game/machinery/computer/orders/order_items/cook/order_reagents.dm @@ -3,105 +3,105 @@ /datum/orderable_item/reagents/flour name = "Flour Sack" - item_path = /obj/item/reagent_containers/condiment/flour + purchase_path = /obj/item/reagent_containers/condiment/flour cost_per_order = 30 /datum/orderable_item/reagents/sugar name = "Sugar Sack" - item_path = /obj/item/reagent_containers/condiment/sugar + purchase_path = /obj/item/reagent_containers/condiment/sugar cost_per_order = 30 /datum/orderable_item/reagents/rice name = "Rice Sack" - item_path = /obj/item/reagent_containers/condiment/rice + purchase_path = /obj/item/reagent_containers/condiment/rice cost_per_order = 30 /datum/orderable_item/reagents/cornmeal name = "Cornmeal Box" - item_path = /obj/item/reagent_containers/condiment/cornmeal + purchase_path = /obj/item/reagent_containers/condiment/cornmeal cost_per_order = 30 /datum/orderable_item/reagents/enzyme name = "Universal Enzyme" - item_path = /obj/item/reagent_containers/condiment/enzyme + purchase_path = /obj/item/reagent_containers/condiment/enzyme cost_per_order = 40 /datum/orderable_item/reagents/salt name = "Salt Shaker" - item_path = /obj/item/reagent_containers/condiment/saltshaker + purchase_path = /obj/item/reagent_containers/condiment/saltshaker cost_per_order = 15 /datum/orderable_item/reagents/pepper name = "Pepper Mill" - item_path = /obj/item/reagent_containers/condiment/peppermill + purchase_path = /obj/item/reagent_containers/condiment/peppermill cost_per_order = 15 /datum/orderable_item/reagents/soysauce name = "Soy Sauce" - item_path = /obj/item/reagent_containers/condiment/soysauce + purchase_path = /obj/item/reagent_containers/condiment/soysauce cost_per_order = 15 /datum/orderable_item/reagents/bbqsauce name = "BBQ Sauce" - item_path = /obj/item/reagent_containers/condiment/bbqsauce + purchase_path = /obj/item/reagent_containers/condiment/bbqsauce cost_per_order = 60 /datum/orderable_item/reagents/vinegar name = "Vinegar" - item_path = /obj/item/reagent_containers/condiment/vinegar + purchase_path = /obj/item/reagent_containers/condiment/vinegar cost_per_order = 30 /datum/orderable_item/reagents/olive_oil name = "Olive Oil" - item_path = /obj/item/reagent_containers/condiment/olive_oil + purchase_path = /obj/item/reagent_containers/condiment/olive_oil cost_per_order = 50 //Extra Virgin, just like you, the reader /datum/orderable_item/reagents/peanut_butter name = "Peanut Butter" - item_path = /obj/item/reagent_containers/condiment/peanut_butter + purchase_path = /obj/item/reagent_containers/condiment/peanut_butter cost_per_order = 30 /datum/orderable_item/reagents/cherryjelly name = "Cherry Jelly" - item_path = /obj/item/reagent_containers/condiment/cherryjelly + purchase_path = /obj/item/reagent_containers/condiment/cherryjelly cost_per_order = 30 /datum/orderable_item/reagents/worcestershire name = "Worcestershire Sauce" - item_path = /obj/item/reagent_containers/condiment/worcestershire + purchase_path = /obj/item/reagent_containers/condiment/worcestershire cost_per_order = 30 /datum/orderable_item/reagents/red_bay name = "Red Bay Seasoning" - item_path = /obj/item/reagent_containers/condiment/red_bay + purchase_path = /obj/item/reagent_containers/condiment/red_bay cost_per_order = 30 /datum/orderable_item/reagents/curry_powder name = "Curry Powder" - item_path = /obj/item/reagent_containers/condiment/curry_powder + purchase_path = /obj/item/reagent_containers/condiment/curry_powder cost_per_order = 30 /datum/orderable_item/reagents/dashi_concentrate name = "Dashi Concentrate" - item_path = /obj/item/reagent_containers/condiment/dashi_concentrate + purchase_path = /obj/item/reagent_containers/condiment/dashi_concentrate cost_per_order = 30 /datum/orderable_item/reagents/coconut_milk name = "Coconut Milk" - item_path = /obj/item/reagent_containers/condiment/coconut_milk + purchase_path = /obj/item/reagent_containers/condiment/coconut_milk cost_per_order = 30 /datum/orderable_item/reagents/grounding_solution name = "Grounding Solution" - item_path = /obj/item/reagent_containers/condiment/grounding_solution + purchase_path = /obj/item/reagent_containers/condiment/grounding_solution cost_per_order = 30 /datum/orderable_item/reagents/honey name = "Honey" - item_path = /obj/item/reagent_containers/condiment/honey + purchase_path = /obj/item/reagent_containers/condiment/honey cost_per_order = 125 //its high quality honey :) /datum/orderable_item/reagents/mayonnaise name = "Mayonnaise" - item_path = /obj/item/reagent_containers/condiment/mayonnaise + purchase_path = /obj/item/reagent_containers/condiment/mayonnaise cost_per_order = 30 diff --git a/code/game/machinery/computer/orders/order_items/cook/order_veggies.dm b/code/game/machinery/computer/orders/order_items/cook/order_veggies.dm index f96562724d27d..5eff7055b9fae 100644 --- a/code/game/machinery/computer/orders/order_items/cook/order_veggies.dm +++ b/code/game/machinery/computer/orders/order_items/cook/order_veggies.dm @@ -3,177 +3,177 @@ /datum/orderable_item/veggies/potato name = "Potato" - item_path = /obj/item/food/grown/potato + purchase_path = /obj/item/food/grown/potato /datum/orderable_item/veggies/tomato name = "Tomato" - item_path = /obj/item/food/grown/tomato + purchase_path = /obj/item/food/grown/tomato /datum/orderable_item/veggies/carrot name = "Carrot" - item_path = /obj/item/food/grown/carrot + purchase_path = /obj/item/food/grown/carrot /datum/orderable_item/veggies/eggplant name = "Eggplant" - item_path = /obj/item/food/grown/eggplant + purchase_path = /obj/item/food/grown/eggplant /datum/orderable_item/veggies/mushroom name = "Plump Helmet" desc = "Plumus Hellmus: Plump, soft and s-so inviting~" - item_path = /obj/item/food/grown/mushroom/plumphelmet + purchase_path = /obj/item/food/grown/mushroom/plumphelmet /datum/orderable_item/veggies/cabbage name = "Cabbage" - item_path = /obj/item/food/grown/cabbage + purchase_path = /obj/item/food/grown/cabbage /datum/orderable_item/veggies/onion name = "Onion" - item_path = /obj/item/food/grown/onion + purchase_path = /obj/item/food/grown/onion /datum/orderable_item/veggies/apple name = "Apple" - item_path = /obj/item/food/grown/apple + purchase_path = /obj/item/food/grown/apple /datum/orderable_item/veggies/pumpkin name = "Pumpkin" - item_path = /obj/item/food/grown/pumpkin + purchase_path = /obj/item/food/grown/pumpkin /datum/orderable_item/veggies/watermelon name = "Watermelon" - item_path = /obj/item/food/grown/watermelon + purchase_path = /obj/item/food/grown/watermelon /datum/orderable_item/veggies/corn name = "Corn" - item_path = /obj/item/food/grown/corn + purchase_path = /obj/item/food/grown/corn /datum/orderable_item/veggies/soybean name = "Soybeans" - item_path = /obj/item/food/grown/soybeans + purchase_path = /obj/item/food/grown/soybeans /datum/orderable_item/veggies/garlic name = "Garlic" - item_path = /obj/item/food/grown/garlic + purchase_path = /obj/item/food/grown/garlic /datum/orderable_item/veggies/cherries name = "Cherries" - item_path = /obj/item/food/grown/cherries + purchase_path = /obj/item/food/grown/cherries /datum/orderable_item/veggies/chanterelle name = "Chanterelle" - item_path = /obj/item/food/grown/mushroom/chanterelle + purchase_path = /obj/item/food/grown/mushroom/chanterelle /datum/orderable_item/veggies/cocoa name = "Cocoa" - item_path = /obj/item/food/grown/cocoapod + purchase_path = /obj/item/food/grown/cocoapod /datum/orderable_item/veggies/herbs name = "Bundle of Herbs" - item_path = /obj/item/food/grown/herbs + purchase_path = /obj/item/food/grown/herbs cost_per_order = 5 /datum/orderable_item/veggies/bell_pepper name = "Bell Pepper" - item_path = /obj/item/food/grown/bell_pepper + purchase_path = /obj/item/food/grown/bell_pepper /datum/orderable_item/veggies/cucumbers name = "Cucumber" - item_path = /obj/item/food/grown/cucumber + purchase_path = /obj/item/food/grown/cucumber cost_per_order = 10 /datum/orderable_item/veggies/pickles name = "Jar of pickles" - item_path = /obj/item/storage/fancy/pickles_jar + purchase_path = /obj/item/storage/fancy/pickles_jar cost_per_order = 60 /datum/orderable_item/veggies/pickled_voltvine name = "Pickled Voltvine" - item_path = /obj/item/food/pickled_voltvine + purchase_path = /obj/item/food/pickled_voltvine cost_per_order = 5 /datum/orderable_item/veggies/chili name = "Chili" - item_path = /obj/item/food/grown/chili + purchase_path = /obj/item/food/grown/chili /datum/orderable_item/veggies/berries name = "Berries" - item_path = /obj/item/food/grown/berries + purchase_path = /obj/item/food/grown/berries /datum/orderable_item/veggies/pineapple name = "Pineapple" - item_path = /obj/item/food/grown/pineapple + purchase_path = /obj/item/food/grown/pineapple /datum/orderable_item/veggies/peas name = "Peas" - item_path = /obj/item/food/grown/peas + purchase_path = /obj/item/food/grown/peas /datum/orderable_item/veggies/korta_nut //nanotrasen does not devote as much of their resources to pathetic lizard crops name = "Korta Nut" - item_path = /obj/item/food/grown/korta_nut + purchase_path = /obj/item/food/grown/korta_nut cost_per_order = 15 /datum/orderable_item/veggies/parsnip name = "Parsnip" - item_path = /obj/item/food/grown/parsnip + purchase_path = /obj/item/food/grown/parsnip /datum/orderable_item/veggies/redbeet name = "Red Beet" - item_path = /obj/item/food/grown/redbeet + purchase_path = /obj/item/food/grown/redbeet /datum/orderable_item/veggies/orange name = "Orange" - item_path = /obj/item/food/grown/citrus/orange + purchase_path = /obj/item/food/grown/citrus/orange /datum/orderable_item/veggies/vanillapod name = "Vanilla" - item_path = /obj/item/food/grown/vanillapod + purchase_path = /obj/item/food/grown/vanillapod cost_per_order = 25 //food items that are treated as mutations in game should be more expensive. groceries shouldnt include ACTUAL mutations but i think real foods are ok /datum/orderable_item/veggies/sweetkorta name = "Sweet Korta Nut" - item_path = /obj/item/food/grown/korta_nut/sweet + purchase_path = /obj/item/food/grown/korta_nut/sweet cost_per_order = 30 /datum/orderable_item/veggies/redonion name = "Red Onion" - item_path = /obj/item/food/grown/onion/red + purchase_path = /obj/item/food/grown/onion/red cost_per_order = 25 /datum/orderable_item/veggies/peanut name = "Peanut" - item_path = /obj/item/food/grown/peanut + purchase_path = /obj/item/food/grown/peanut /datum/orderable_item/veggies/sweetpotato name = "Sweet Potato" - item_path = /obj/item/food/grown/potato/sweet + purchase_path = /obj/item/food/grown/potato/sweet cost_per_order = 25 /datum/orderable_item/veggies/oat name = "Oat" - item_path = /obj/item/food/grown/oat + purchase_path = /obj/item/food/grown/oat /datum/orderable_item/veggies/trumpet name = "Spaceman's Trumpet" - item_path = /obj/item/food/grown/trumpet + purchase_path = /obj/item/food/grown/trumpet cost_per_order = 25 /datum/orderable_item/veggies/banana name = "Banana" - item_path = /obj/item/food/grown/banana + purchase_path = /obj/item/food/grown/banana /datum/orderable_item/veggies/ghostchili name = "Ghost Chili" - item_path = /obj/item/food/grown/ghost_chili + purchase_path = /obj/item/food/grown/ghost_chili cost_per_order = 25 /datum/orderable_item/veggies/lemon name = "Lemon" - item_path = /obj/item/food/grown/citrus/lemon + purchase_path = /obj/item/food/grown/citrus/lemon /datum/orderable_item/veggies/lime name = "Lime" - item_path = /obj/item/food/grown/citrus/lime + purchase_path = /obj/item/food/grown/citrus/lime /datum/orderable_item/veggies/toechtauese name = "Töchtaüse berries" - item_path = /obj/item/food/grown/toechtauese + purchase_path = /obj/item/food/grown/toechtauese cost_per_order = 15 diff --git a/code/game/machinery/computer/orders/order_items/mining/order_consumables.dm b/code/game/machinery/computer/orders/order_items/mining/order_consumables.dm index a91a34b46f2da..79e82ac954b22 100644 --- a/code/game/machinery/computer/orders/order_items/mining/order_consumables.dm +++ b/code/game/machinery/computer/orders/order_items/mining/order_consumables.dm @@ -2,53 +2,53 @@ category_index = CATEGORY_CONSUMABLES /datum/orderable_item/consumables/survival_pen - item_path = /obj/item/reagent_containers/hypospray/medipen/survival + purchase_path = /obj/item/reagent_containers/hypospray/medipen/survival cost_per_order = 250 /datum/orderable_item/consumables/luxury_pen - item_path = /obj/item/reagent_containers/hypospray/medipen/survival/luxury + purchase_path = /obj/item/reagent_containers/hypospray/medipen/survival/luxury cost_per_order = 750 /datum/orderable_item/consumables/medkit - item_path = /obj/item/storage/medkit/brute + purchase_path = /obj/item/storage/medkit/brute cost_per_order = 400 /datum/orderable_item/consumables/medkit_fire - item_path = /obj/item/storage/medkit/fire + purchase_path = /obj/item/storage/medkit/fire desc = "For emergency magmatic burn relief." cost_per_order = 500 /datum/orderable_item/consumables/whiskey - item_path = /obj/item/reagent_containers/cup/glass/bottle/whiskey + purchase_path = /obj/item/reagent_containers/cup/glass/bottle/whiskey cost_per_order = 100 /datum/orderable_item/consumables/absinthe - item_path = /obj/item/reagent_containers/cup/glass/bottle/absinthe/premium + purchase_path = /obj/item/reagent_containers/cup/glass/bottle/absinthe/premium cost_per_order = 100 /datum/orderable_item/consumables/bubblegum - item_path = /obj/item/storage/box/gum/bubblegum + purchase_path = /obj/item/storage/box/gum/bubblegum cost_per_order = 100 /datum/orderable_item/consumables/havana_cigars - item_path = /obj/item/cigarette/cigar/havana + purchase_path = /obj/item/cigarette/cigar/havana cost_per_order = 150 /datum/orderable_item/consumables/havana_cigars - item_path = /obj/item/cigarette/cigar/havana + purchase_path = /obj/item/cigarette/cigar/havana cost_per_order = 150 /datum/orderable_item/consumables/tracking_implants - item_path = /obj/item/storage/box/minertracker + purchase_path = /obj/item/storage/box/minertracker cost_per_order = 600 /datum/orderable_item/consumables/space_cash - item_path = /obj/item/stack/spacecash/c1000 + purchase_path = /obj/item/stack/spacecash/c1000 desc = "A stack of space cash worth 1000 credits." cost_per_order = 2000 /datum/orderable_item/consumables/rescue_hook name = "Rescue Fishing Rod" - item_path = /obj/item/fishing_rod/rescue + purchase_path = /obj/item/fishing_rod/rescue desc = "For when your fellow miner has inevitably fallen into a chasm, and it's up to you to save them." cost_per_order = 600 diff --git a/code/game/machinery/computer/orders/order_items/mining/order_golem.dm b/code/game/machinery/computer/orders/order_items/mining/order_golem.dm index cbd037230f242..237360978e8d4 100644 --- a/code/game/machinery/computer/orders/order_items/mining/order_golem.dm +++ b/code/game/machinery/computer/orders/order_items/mining/order_golem.dm @@ -2,34 +2,34 @@ category_index = CATEGORY_GOLEM /datum/orderable_item/golem/mining_id - item_path = /obj/item/card/id/advanced/mining + purchase_path = /obj/item/card/id/advanced/mining cost_per_order = 200 /datum/orderable_item/golem/science_goggles - item_path = /obj/item/clothing/glasses/science + purchase_path = /obj/item/clothing/glasses/science cost_per_order = 200 /datum/orderable_item/golem/monkeycubes - item_path = /obj/item/food/monkeycube + purchase_path = /obj/item/food/monkeycube cost_per_order = 250 /datum/orderable_item/golem/belt - item_path = /obj/item/storage/belt/utility + purchase_path = /obj/item/storage/belt/utility cost_per_order = 300 /datum/orderable_item/golem/royal_cape - item_path = /obj/item/bedsheet/rd/royal_cape + purchase_path = /obj/item/bedsheet/rd/royal_cape cost_per_order = 400 /datum/orderable_item/golem/grey_extract - item_path = /obj/item/slime_extract/grey + purchase_path = /obj/item/slime_extract/grey cost_per_order = 800 /datum/orderable_item/golem/trigger_guard - item_path = /obj/item/borg/upgrade/modkit/trigger_guard + purchase_path = /obj/item/borg/upgrade/modkit/trigger_guard cost_per_order = 750 /datum/orderable_item/golem/rnd_boards - item_path = /obj/item/storage/box/rndboards + purchase_path = /obj/item/storage/box/rndboards cost_per_order = 1000 diff --git a/code/game/machinery/computer/orders/order_items/mining/order_mining.dm b/code/game/machinery/computer/orders/order_items/mining/order_mining.dm index 76af0dc806c96..babbd4a47381e 100644 --- a/code/game/machinery/computer/orders/order_items/mining/order_mining.dm +++ b/code/game/machinery/computer/orders/order_items/mining/order_mining.dm @@ -2,132 +2,132 @@ category_index = CATEGORY_MINING /datum/orderable_item/mining/marker_beacon - item_path = /obj/item/stack/marker_beacon/ten + purchase_path = /obj/item/stack/marker_beacon/ten cost_per_order = 80 /datum/orderable_item/mining/skeleton_key - item_path = /obj/item/skeleton_key + purchase_path = /obj/item/skeleton_key cost_per_order = 675 /datum/orderable_item/mining/mining_stabilizer - item_path = /obj/item/mining_stabilizer + purchase_path = /obj/item/mining_stabilizer cost_per_order = 320 /datum/orderable_item/mining/fulton_core - item_path = /obj/item/fulton_core + purchase_path = /obj/item/fulton_core cost_per_order = 320 /datum/orderable_item/mining/mining_modsuit - item_path = /obj/item/mod/control/pre_equipped/mining + purchase_path = /obj/item/mod/control/pre_equipped/mining desc = "A mining-themed MODsuit that works best when in a mining environment." cost_per_order = 2500 /datum/orderable_item/mining/mining_belt - item_path = /obj/item/storage/belt/mining + purchase_path = /obj/item/storage/belt/mining cost_per_order = 450 /datum/orderable_item/mining/jaunter - item_path = /obj/item/wormhole_jaunter + purchase_path = /obj/item/wormhole_jaunter cost_per_order = 650 /datum/orderable_item/mining/crusher - item_path = /obj/item/kinetic_crusher + purchase_path = /obj/item/kinetic_crusher cost_per_order = 650 /datum/orderable_item/mining/crusher_retool_kit - item_path = /obj/item/crusher_trophy/retool_kit + purchase_path = /obj/item/crusher_trophy/retool_kit cost_per_order = 150 /datum/orderable_item/mining/crusher_retool_kit_harpoon - item_path = /obj/item/crusher_trophy/retool_kit/harpoon + purchase_path = /obj/item/crusher_trophy/retool_kit/harpoon cost_per_order = 150 /datum/orderable_item/mining/crusher_retool_kit_dagger - item_path = /obj/item/crusher_trophy/retool_kit/dagger + purchase_path = /obj/item/crusher_trophy/retool_kit/dagger cost_per_order = 150 /datum/orderable_item/mining/resonator - item_path = /obj/item/resonator + purchase_path = /obj/item/resonator cost_per_order = 710 /datum/orderable_item/mining/resonator_advanced - item_path = /obj/item/resonator/upgraded + purchase_path = /obj/item/resonator/upgraded cost_per_order = 2000 /datum/orderable_item/mining/mining_scanner - item_path = /obj/item/t_scanner/adv_mining_scanner + purchase_path = /obj/item/t_scanner/adv_mining_scanner cost_per_order = 675 /datum/orderable_item/mining/fulton - item_path = /obj/item/extraction_pack + purchase_path = /obj/item/extraction_pack cost_per_order = 800 /datum/orderable_item/mining/lazarus - item_path = /obj/item/lazarus_injector + purchase_path = /obj/item/lazarus_injector cost_per_order = 1000 /datum/orderable_item/mining/gar_mesons - item_path = /obj/item/clothing/glasses/meson/gar + purchase_path = /obj/item/clothing/glasses/meson/gar cost_per_order = 500 /datum/orderable_item/mining/silver_pickaxe - item_path = /obj/item/pickaxe/silver + purchase_path = /obj/item/pickaxe/silver cost_per_order = 1000 /datum/orderable_item/mining/diamond_pickaxe - item_path = /obj/item/pickaxe/diamond + purchase_path = /obj/item/pickaxe/diamond cost_per_order = 2000 /datum/orderable_item/mining/conscription_kit - item_path = /obj/item/storage/backpack/duffelbag/mining_conscript + purchase_path = /obj/item/storage/backpack/duffelbag/mining_conscript desc = "A kit containing everything a crewmember needs to support a shaft miner in the field." cost_per_order = 1200 /datum/orderable_item/mining/capsule - item_path = /obj/item/survivalcapsule + purchase_path = /obj/item/survivalcapsule cost_per_order = 350 /datum/orderable_item/mining/capsule/bathroom - item_path = /obj/item/survivalcapsule/bathroom + purchase_path = /obj/item/survivalcapsule/bathroom cost_per_order = 300 /datum/orderable_item/mining/capsule_luxury - item_path = /obj/item/survivalcapsule/luxury + purchase_path = /obj/item/survivalcapsule/luxury cost_per_order = 2300 /datum/orderable_item/mining/capsule_luxuryelite - item_path = /obj/item/survivalcapsule/luxuryelite + purchase_path = /obj/item/survivalcapsule/luxuryelite cost_per_order = 7000 /datum/orderable_item/mining/kheiralcuffs - item_path = /obj/item/kheiral_cuffs + purchase_path = /obj/item/kheiral_cuffs cost_per_order = 675 /datum/orderable_item/mining/bhop - item_path = /obj/item/clothing/shoes/bhop + purchase_path = /obj/item/clothing/shoes/bhop cost_per_order = 2000 /datum/orderable_item/mining/hiking_boots - item_path = /obj/item/clothing/shoes/winterboots/ice_boots + purchase_path = /obj/item/clothing/shoes/winterboots/ice_boots cost_per_order = 2000 /datum/orderable_item/mining/style_meter - item_path = /obj/item/style_meter + purchase_path = /obj/item/style_meter cost_per_order = 1200 /datum/orderable_item/mining/weather_radio - item_path = /obj/item/radio/weather_monitor + purchase_path = /obj/item/radio/weather_monitor cost_per_order = 320 /datum/orderable_item/mining/ventpointer - item_path = /obj/item/pinpointer/vent + purchase_path = /obj/item/pinpointer/vent cost_per_order = 1150 /datum/orderable_item/mining/boulder_processing - item_path = /obj/item/boulder_beacon + purchase_path = /obj/item/boulder_beacon desc = "A Bouldertech brand all-in-one boulder processing beacon. Each use will teleport in a component of a full boulder processing assembly line. Good for when you need to process additional boulders." cost_per_order = 875 /datum/orderable_item/mining/grapple_gun - item_path = /obj/item/grapple_gun + purchase_path = /obj/item/grapple_gun cost_per_order = 3000 diff --git a/code/game/machinery/computer/orders/order_items/mining/order_pka.dm b/code/game/machinery/computer/orders/order_items/mining/order_pka.dm index f239e9f2a7eaf..ceaa83d8ef734 100644 --- a/code/game/machinery/computer/orders/order_items/mining/order_pka.dm +++ b/code/game/machinery/computer/orders/order_items/mining/order_pka.dm @@ -2,45 +2,45 @@ category_index = CATEGORY_PKA /datum/orderable_item/accelerator/gun - item_path = /obj/item/gun/energy/recharge/kinetic_accelerator + purchase_path = /obj/item/gun/energy/recharge/kinetic_accelerator cost_per_order = 600 /datum/orderable_item/accelerator/range - item_path = /obj/item/borg/upgrade/modkit/range + purchase_path = /obj/item/borg/upgrade/modkit/range cost_per_order = 675 /datum/orderable_item/accelerator/damage - item_path = /obj/item/borg/upgrade/modkit/damage + purchase_path = /obj/item/borg/upgrade/modkit/damage cost_per_order = 675 /datum/orderable_item/accelerator/cooldown - item_path = /obj/item/borg/upgrade/modkit/cooldown + purchase_path = /obj/item/borg/upgrade/modkit/cooldown cost_per_order = 675 /datum/orderable_item/accelerator/chasis - item_path = /obj/item/borg/upgrade/modkit/chassis_mod + purchase_path = /obj/item/borg/upgrade/modkit/chassis_mod cost_per_order = 250 /datum/orderable_item/accelerator/chasis_orange - item_path = /obj/item/borg/upgrade/modkit/chassis_mod/orange + purchase_path = /obj/item/borg/upgrade/modkit/chassis_mod/orange cost_per_order = 300 /datum/orderable_item/accelerator/tracer - item_path = /obj/item/borg/upgrade/modkit/tracer + purchase_path = /obj/item/borg/upgrade/modkit/tracer cost_per_order = 100 /datum/orderable_item/accelerator/adjustable_tracer - item_path = /obj/item/borg/upgrade/modkit/tracer/adjustable + purchase_path = /obj/item/borg/upgrade/modkit/tracer/adjustable cost_per_order = 150 /datum/orderable_item/accelerator/aoe_mobs - item_path = /obj/item/borg/upgrade/modkit/aoe/mobs + purchase_path = /obj/item/borg/upgrade/modkit/aoe/mobs cost_per_order = 1500 /datum/orderable_item/accelerator/minebot_passthrough - item_path = /obj/item/borg/upgrade/modkit/minebot_passthrough + purchase_path = /obj/item/borg/upgrade/modkit/minebot_passthrough cost_per_order = 800 /datum/orderable_item/accelerator/friendly_fire - item_path = /obj/item/borg/upgrade/modkit/human_passthrough + purchase_path = /obj/item/borg/upgrade/modkit/human_passthrough cost_per_order = 750 diff --git a/code/game/machinery/computer/orders/order_items/mining/order_toys.dm b/code/game/machinery/computer/orders/order_items/mining/order_toys.dm index fab03cabaa4b6..65bbee24ead6e 100644 --- a/code/game/machinery/computer/orders/order_items/mining/order_toys.dm +++ b/code/game/machinery/computer/orders/order_items/mining/order_toys.dm @@ -2,38 +2,38 @@ category_index = CATEGORY_TOYS_DRONE /datum/orderable_item/toys_drones/soap - item_path = /obj/item/soap/nanotrasen + purchase_path = /obj/item/soap/nanotrasen cost_per_order = 180 /datum/orderable_item/toys_drones/laser_pointer - item_path = /obj/item/laser_pointer + purchase_path = /obj/item/laser_pointer cost_per_order = 275 /datum/orderable_item/toys_drones/facehugger - item_path = /obj/item/clothing/mask/facehugger/toy + purchase_path = /obj/item/clothing/mask/facehugger/toy cost_per_order = 275 /datum/orderable_item/toys_drones/mining_drone - item_path = /mob/living/basic/mining_drone + purchase_path = /mob/living/basic/mining_drone cost_per_order = 675 /datum/orderable_item/toys_drones/drone_health - item_path = /obj/item/mine_bot_upgrade/health + purchase_path = /obj/item/mine_bot_upgrade/health cost_per_order = 350 /datum/orderable_item/toys_drones/drone_shield - item_path = /obj/item/mine_bot_upgrade/regnerative_shield + purchase_path = /obj/item/mine_bot_upgrade/regnerative_shield cost_per_order = 500 /datum/orderable_item/toys_drones/drone_remote - item_path = /obj/item/minebot_remote_control + purchase_path = /obj/item/minebot_remote_control cost_per_order = 500 /datum/orderable_item/toys_drones/drone_pka - item_path = /obj/item/borg/upgrade/modkit/cooldown/minebot + purchase_path = /obj/item/borg/upgrade/modkit/cooldown/minebot cost_per_order = 525 /datum/orderable_item/toys_drones/drone_sentience - item_path = /obj/item/slimepotion/slime/sentience/mining + purchase_path = /obj/item/slimepotion/slime/sentience/mining cost_per_order = 850 diff --git a/code/game/machinery/computer/orders/order_items/order_datum.dm b/code/game/machinery/computer/orders/order_items/order_datum.dm index 13684fc742b44..28c21a14f267e 100644 --- a/code/game/machinery/computer/orders/order_items/order_datum.dm +++ b/code/game/machinery/computer/orders/order_items/order_datum.dm @@ -5,7 +5,7 @@ ///Description shown in the shop, set automatically unless it's hard set by the subtype var/desc ///Path of the item that is purchased when ordering us. - var/obj/item/item_path + var/atom/movable/purchase_path ///The category this item will be displayed in. var/category_index = NONE ///How much this item costs to order. @@ -15,14 +15,9 @@ . = ..() if(!category_index) CRASH("[type] doesn't have a category_index assigned!") - if(!item_path) + if(!purchase_path) CRASH("[type] orderable item datum with no item path was created!") if(!name) - name = initial(item_path.name) + name = initial(purchase_path.name) if(!desc) - desc = initial(item_path.desc) - -/datum/orderable_item/Destroy(force) - if(item_path) - qdel(item_path) - return ..() + desc = initial(purchase_path.desc) diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm index 4949f53adfbfe..bbb6f33236d23 100644 --- a/code/game/machinery/harvester.dm +++ b/code/game/machinery/harvester.dm @@ -179,7 +179,7 @@ obj_flags |= EMAGGED allow_living = TRUE allow_clothing = TRUE - balloon_alert(!user, "lifesign scanners overloaded") + balloon_alert(user, "lifesign scanners overloaded") return TRUE /obj/machinery/harvester/container_resist_act(mob/living/user) diff --git a/code/game/machinery/scanner_gate.dm b/code/game/machinery/scanner_gate.dm index af097605bc3ae..ee93f41cf552e 100644 --- a/code/game/machinery/scanner_gate.dm +++ b/code/game/machinery/scanner_gate.dm @@ -327,7 +327,7 @@ /obj/machinery/scanner_gate/preset_guns locked = TRUE - req_access = ACCESS_SECURITY + req_access = list(ACCESS_SECURITY) scangate_mode = SCANGATE_GUNS #undef SCANGATE_NONE diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index e7b62b07cf1e2..b65c4a7ae90df 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -12,7 +12,7 @@ var/require_model = FALSE var/list/model_type = null /// Bitflags listing model compatibility. Used in the exosuit fabricator for creating sub-categories. - var/list/model_flags = NONE + var/model_flags = NONE /// List of items to add with the module, if any var/list/items_to_add diff --git a/code/game/objects/items/stacks/golem_food/golem_status_effects.dm b/code/game/objects/items/stacks/golem_food/golem_status_effects.dm index 95c87cbb5dac9..330cd86ff1d47 100644 --- a/code/game/objects/items/stacks/golem_food/golem_status_effects.dm +++ b/code/game/objects/items/stacks/golem_food/golem_status_effects.dm @@ -418,7 +418,7 @@ return owner.body_position == LYING_DOWN /datum/status_effect/golem/bananium/on_remove() - owner.remove_traits(owner, list(TRAIT_WADDLING, TRAIT_NO_SLIP_WATER), TRAIT_STATUS_EFFECT(id)) + owner.remove_traits(list(TRAIT_WADDLING, TRAIT_NO_SLIP_WATER), TRAIT_STATUS_EFFECT(id)) QDEL_NULL(slipperiness) return ..() diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 21247879dc195..dc0375ac04bd2 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -64,7 +64,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/balloon_mallet/examine(mob/user) . = ..() if(HAS_TRAIT(user,TRAIT_BALLOON_SUTRA)) - . = "A sacred weapon of the higher castes from the clown planet, used to strike fear into the hearts of their foes. Wield it with care." + . += "A sacred weapon of the higher castes from the clown planet, used to strike fear into the hearts of their foes. Wield it with care." /obj/item/balloon_mallet/attack(mob/living/target, mob/living/user) playsound(loc, 'sound/mobs/non-humanoids/clown/hehe.ogg', 20) diff --git a/code/game/objects/structures/cannons/mounted_guns/mounted_gun.dm b/code/game/objects/structures/cannons/mounted_guns/mounted_gun.dm index f0fa9e27d7869..fa49fe0a106d5 100644 --- a/code/game/objects/structures/cannons/mounted_guns/mounted_gun.dm +++ b/code/game/objects/structures/cannons/mounted_guns/mounted_gun.dm @@ -22,7 +22,7 @@ ///Accepted "ammo" type var/obj/item/ammo_type = /obj/item/ammo_casing/strilka310 ///Projectile from said gun. Doesnt automatically inherit said ammo's projectile in case you wanted to make a gun that shoots floor tiles or something. - var/obj/item/projectile_type = /obj/projectile/bullet/strilka310 + var/obj/projectile/projectile_type = /obj/projectile/bullet/strilka310 ///If the gun has anything in it. var/loaded_gun = TRUE ///If the gun is currently loaded with its maximum capacity. diff --git a/code/game/objects/structures/spawner.dm b/code/game/objects/structures/spawner.dm index db4981aeac77a..6a0bc3123d1f5 100644 --- a/code/game/objects/structures/spawner.dm +++ b/code/game/objects/structures/spawner.dm @@ -299,5 +299,5 @@ proteon.add_filter("sentient_proteon", 3, list("type" = "outline", "color" = COLOR_CULT_RED, "size" = 2, "alpha" = 40)) /obj/structure/spawner/sentient/proteon_spawner/handle_deconstruct(disassembled) - playsound('sound/effects/hallucinations/veryfar_noise.ogg', 125) + playsound(src, 'sound/effects/hallucinations/veryfar_noise.ogg', 75) visible_message(span_cult_bold("[src] completely falls apart, the screams of the damned reaching a feverous pitch before slowly fading away into nothing.")) diff --git a/code/game/turfs/closed/minerals.dm b/code/game/turfs/closed/minerals.dm index 3a6546f6eaa85..967c13f337220 100644 --- a/code/game/turfs/closed/minerals.dm +++ b/code/game/turfs/closed/minerals.dm @@ -25,7 +25,7 @@ transform = MAP_SWITCH(TRANSLATE_MATRIX(-4, -4), matrix()) temperature = TCMB - var/turf/open/floor/plating/turf_type = /turf/open/misc/asteroid/airless + var/turf/turf_type = /turf/open/misc/asteroid/airless /// The path of the ore stack we spawn when we're mined. var/obj/item/stack/ore/mineralType = null /// If we spawn a boulder like on the gulag, we use this in lou of mineralType diff --git a/code/modules/admin/verbs/ert.dm b/code/modules/admin/verbs/ert.dm index 71722eb6d64ab..09903e7642978 100644 --- a/code/modules/admin/verbs/ert.dm +++ b/code/modules/admin/verbs/ert.dm @@ -157,7 +157,7 @@ spawn_turfs += get_turf(spawner) if(!brief_spawn) - brief_spawn = locate(/obj/effect/landmark/ert_shuttle_brief_spawn) in affected_turf + brief_spawn = get_turf(locate(/obj/effect/landmark/ert_shuttle_brief_spawn) in affected_turf) if(!length(spawn_turfs)) stack_trace("ERT shuttle loaded but found no spawnpoints, placing the ERT at wherever inside the shuttle instead.") @@ -206,7 +206,7 @@ candidate_living_exps = sort_list(candidate_living_exps, cmp=/proc/cmp_numeric_dsc) if(candidate_living_exps.len > ERT_EXPERIENCED_LEADER_CHOOSE_TOP) - candidate_living_exps = candidate_living_exps.Cut(ERT_EXPERIENCED_LEADER_CHOOSE_TOP+1) // pick from the top ERT_EXPERIENCED_LEADER_CHOOSE_TOP contenders in playtime + candidate_living_exps.Cut(ERT_EXPERIENCED_LEADER_CHOOSE_TOP+1) // pick from the top ERT_EXPERIENCED_LEADER_CHOOSE_TOP contenders in playtime earmarked_leader = pick(candidate_living_exps) else earmarked_leader = pick(candidates) diff --git a/code/modules/antagonists/cult/cult_turf_overlay.dm b/code/modules/antagonists/cult/cult_turf_overlay.dm index df92d7aec90f0..e5e70bac1f722 100644 --- a/code/modules/antagonists/cult/cult_turf_overlay.dm +++ b/code/modules/antagonists/cult/cult_turf_overlay.dm @@ -10,7 +10,8 @@ /obj/effect/cult_turf/examine(mob/user) if(linked) - linked.examine(user) + return linked.examine(user) + return list() /obj/effect/cult_turf/singularity_act() return diff --git a/code/modules/antagonists/heretic/heretic_antag.dm b/code/modules/antagonists/heretic/heretic_antag.dm index 9063760c5bcdc..fe7a6f1b125b4 100644 --- a/code/modules/antagonists/heretic/heretic_antag.dm +++ b/code/modules/antagonists/heretic/heretic_antag.dm @@ -93,9 +93,9 @@ //if the knowledge is a spell, use the spell's button else if(ispath(knowledge,/datum/heretic_knowledge/spell)) var/datum/heretic_knowledge/spell/spell_knowledge = knowledge - var/datum/action/cooldown/spell/result_spell = spell_knowledge.spell_to_add - icon_path = result_spell.button_icon - icon_state = result_spell.button_icon_state + var/datum/action/result_action = spell_knowledge.action_to_add + icon_path = result_action.button_icon + icon_state = result_action.button_icon_state //if the knowledge is a summon, use the mob sprite else if(ispath(knowledge,/datum/heretic_knowledge/summon)) diff --git a/code/modules/antagonists/heretic/heretic_knowledge.dm b/code/modules/antagonists/heretic/heretic_knowledge.dm index d4fdf79dfbb59..0e445c862f495 100644 --- a/code/modules/antagonists/heretic/heretic_knowledge.dm +++ b/code/modules/antagonists/heretic/heretic_knowledge.dm @@ -187,26 +187,26 @@ /datum/heretic_knowledge/spell abstract_parent_type = /datum/heretic_knowledge/spell /// Spell path we add to the heretic. Type-path. - var/datum/action/cooldown/spell/spell_to_add + var/datum/action/action_to_add /// The spell we actually created. - var/datum/weakref/created_spell_ref + var/datum/weakref/created_action_ref /datum/heretic_knowledge/spell/Destroy() - QDEL_NULL(created_spell_ref) + QDEL_NULL(created_action_ref) return ..() /datum/heretic_knowledge/spell/on_gain(mob/user, datum/antagonist/heretic/our_heretic) // Added spells are tracked on the body, and not the mind, // because we handle heretic mind transfers // via the antag datum (on_gain and on_lose). - var/datum/action/cooldown/spell/created_spell = created_spell_ref?.resolve() || new spell_to_add(user) - created_spell.Grant(user) - created_spell_ref = WEAKREF(created_spell) + var/datum/action/created_action = created_action_ref?.resolve() || new action_to_add(user) + created_action.Grant(user) + created_action_ref = WEAKREF(created_action) /datum/heretic_knowledge/spell/on_lose(mob/user, datum/antagonist/heretic/our_heretic) - var/datum/action/cooldown/spell/created_spell = created_spell_ref?.resolve() - if(created_spell?.owner == user) - created_spell.Remove(user) + var/datum/action/cooldown/spell/created_action = created_action_ref?.resolve() + if(created_action?.owner == user) + created_action.Remove(user) /** * A knowledge subtype for knowledge that can only diff --git a/code/modules/antagonists/heretic/knowledge/ash_lore.dm b/code/modules/antagonists/heretic/knowledge/ash_lore.dm index 61056d4210f40..3b5b80a621461 100644 --- a/code/modules/antagonists/heretic/knowledge/ash_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/ash_lore.dm @@ -63,7 +63,7 @@ desc = "Grants you Ashen Passage, a spell that lets you phase out of reality and traverse a short distance, passing though any walls." gain_text = "He knew how to walk between the planes." - spell_to_add = /datum/action/cooldown/spell/jaunt/ethereal_jaunt/ash + action_to_add = /datum/action/cooldown/spell/jaunt/ethereal_jaunt/ash cost = 1 @@ -99,7 +99,7 @@ at a nearby enemy, setting them on fire and burning them. If they do not extinguish themselves, \ the beam will continue to another target." gain_text = "No fire was hot enough to rekindle them. No fire was bright enough to save them. No fire is eternal." - spell_to_add = /datum/action/cooldown/spell/charged/beam/fire_blast + action_to_add = /datum/action/cooldown/spell/charged/beam/fire_blast cost = 1 research_tree_icon_frame = 7 @@ -145,7 +145,7 @@ If any victims afflicted are in critical condition, they will also instantly die." gain_text = "The fire was inescapable, and yet, life remained in his charred body. \ The Nightwatcher was a particular man, always watching." - spell_to_add = /datum/action/cooldown/spell/aoe/fiery_rebirth + action_to_add = /datum/action/cooldown/spell/aoe/fiery_rebirth cost = 1 research_tree_icon_frame = 5 diff --git a/code/modules/antagonists/heretic/knowledge/blade_lore.dm b/code/modules/antagonists/heretic/knowledge/blade_lore.dm index 5cffc7bc304f2..dcca07b00af70 100644 --- a/code/modules/antagonists/heretic/knowledge/blade_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/blade_lore.dm @@ -185,7 +185,7 @@ During this process, you will rapidly regenerate stamina and quickly recover from stuns, however, you will be unable to attack. \ This spell can be cast in rapid succession, but doing so will increase the cooldown." gain_text = "In the flurry of death, he found peace within himself. Despite insurmountable odds, he forged on." - spell_to_add = /datum/action/cooldown/spell/realignment + action_to_add = /datum/action/cooldown/spell/realignment cost = 1 @@ -364,7 +364,7 @@ at a target, dealing damage and causing bleeding." gain_text = "Without thinking, I took the knife of a fallen soldier and threw with all my might. My aim was true! \ The Torn Champion smiled at their first taste of agony, and with a nod, their blades became my own." - spell_to_add = /datum/action/cooldown/spell/pointed/projectile/furious_steel + action_to_add = /datum/action/cooldown/spell/pointed/projectile/furious_steel cost = 1 /datum/heretic_knowledge/ultimate/blade_final diff --git a/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm b/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm index 6a895a7ffdfd2..90fe514cde946 100644 --- a/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm @@ -62,7 +62,7 @@ However, people with a star mark will get transported along with another person using the rune." gain_text = "The distant stars crept into my dreams, roaring and screaming without reason. \ I spoke, and heard my own words echoed back." - spell_to_add = /datum/action/cooldown/spell/cosmic_rune + action_to_add = /datum/action/cooldown/spell/cosmic_rune cost = 1 @@ -86,7 +86,7 @@ The beam lasts a minute, until the beam is obstructed or until a new target has been found." gain_text = "After waking in a cold sweat I felt a palm on my scalp, a sigil burned onto me. \ My veins now emitted a strange purple glow, the Beast knows I will surpass its expectations." - spell_to_add = /datum/action/cooldown/spell/touch/star_touch + action_to_add = /datum/action/cooldown/spell/touch/star_touch cost = 1 /datum/heretic_knowledge/spell/star_blast @@ -94,7 +94,7 @@ desc = "Fires a projectile that moves very slowly, raising a short-lived wall of cosmic fields where it goes. \ Anyone hit by the projectile will receive burn damage, a knockdown, and give people in a three tile range a star mark." gain_text = "The Beast was behind me now at all times, with each sacrifice words of affirmation coursed through me." - spell_to_add = /datum/action/cooldown/spell/pointed/projectile/star_blast + action_to_add = /datum/action/cooldown/spell/pointed/projectile/star_blast cost = 1 /datum/heretic_knowledge/blade_upgrade/cosmic @@ -199,7 +199,7 @@ desc = "Grants you Cosmic Expansion, a spell that creates a 3x3 area of cosmic fields around you. \ Nearby beings will also receive a star mark." gain_text = "The ground now shook beneath me. The Beast inhabited me, and their voice was intoxicating." - spell_to_add = /datum/action/cooldown/spell/conjure/cosmic_expansion + action_to_add = /datum/action/cooldown/spell/conjure/cosmic_expansion cost = 1 /datum/heretic_knowledge/ultimate/cosmic_final diff --git a/code/modules/antagonists/heretic/knowledge/flesh_lore.dm b/code/modules/antagonists/heretic/knowledge/flesh_lore.dm index 976ce2ae7ba4e..57e60c46b6367 100644 --- a/code/modules/antagonists/heretic/knowledge/flesh_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/flesh_lore.dm @@ -214,7 +214,7 @@ This spell also allows you to heal your minions and summons, or restore failing organs to acceptable status." gain_text = "But they were not out of my reach for long. With every step, the screams grew, until at last \ I learned that they could be silenced." - spell_to_add = /datum/action/cooldown/spell/touch/flesh_surgery + action_to_add = /datum/action/cooldown/spell/touch/flesh_surgery cost = 1 /datum/heretic_knowledge/summon/raw_prophet diff --git a/code/modules/antagonists/heretic/knowledge/lock_lore.dm b/code/modules/antagonists/heretic/knowledge/lock_lore.dm index 28e02112fd70e..6333e9a8fa4fc 100644 --- a/code/modules/antagonists/heretic/knowledge/lock_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/lock_lore.dm @@ -136,7 +136,7 @@ that puts a random item from the victims backpack into your hand." gain_text = "Consorting with Burglar spirits is frowned upon, but a Steward will always want to learn about new doors." - spell_to_add = /datum/action/cooldown/spell/pointed/burglar_finesse + action_to_add = /datum/action/cooldown/spell/pointed/burglar_finesse cost = 1 /datum/heretic_knowledge/blade_upgrade/flesh/lock //basically a chance-based weeping avulsion version of the former @@ -158,7 +158,7 @@ While in refuge, you cannot use your hands or spells, and you are immune to slowdown. \ You are invincible but unable to harm anything. Cancelled by being hit with an anti-magic item." gain_text = "Jealously, the Guard and the Hound hunted me. But I unlocked my form, and was but a haze, untouchable." - spell_to_add = /datum/action/cooldown/spell/caretaker + action_to_add = /datum/action/cooldown/spell/caretaker cost = 1 /datum/heretic_knowledge/ultimate/lock_final diff --git a/code/modules/antagonists/heretic/knowledge/moon_lore.dm b/code/modules/antagonists/heretic/knowledge/moon_lore.dm index 2ab75e96c5a78..9628305f50b46 100644 --- a/code/modules/antagonists/heretic/knowledge/moon_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/moon_lore.dm @@ -32,7 +32,7 @@ research_tree_icon_state = "moon_blade" /datum/heretic_knowledge/limited_amount/starting/base_moon/on_gain(mob/user, datum/antagonist/heretic/our_heretic) - add_traits(user ,TRAIT_EMPATH, REF(src)) + ADD_TRAIT(user, TRAIT_EMPATH, REF(src)) /datum/heretic_knowledge/moon_grasp name = "Grasp of Lunacy" @@ -70,7 +70,7 @@ duration based on their sanity." gain_text = "The moon smiles upon us all and those who see its true side can bring its joy." - spell_to_add = /datum/action/cooldown/spell/pointed/moon_smile + action_to_add = /datum/action/cooldown/spell/pointed/moon_smile cost = 1 /datum/heretic_knowledge/mark/moon_mark @@ -89,7 +89,7 @@ desc = "Grants you Lunar Parade, a spell that - after a short charge - sends a carnival forward \ when hitting someone they are forced to join the parade and suffer hallucinations." gain_text = "The music like a reflection of the soul compelled them, like moths to a flame they followed" - spell_to_add = /datum/action/cooldown/spell/pointed/projectile/moon_parade + action_to_add = /datum/action/cooldown/spell/pointed/projectile/moon_parade cost = 1 /datum/heretic_knowledge/moon_amulet @@ -144,7 +144,7 @@ gain_text = "I grabbed his hand and we rose, those who saw the truth rose with us. \ The ringleader pointed up and the dim light of truth illuminated us further." - spell_to_add = /datum/action/cooldown/spell/aoe/moon_ringleader + action_to_add = /datum/action/cooldown/spell/aoe/moon_ringleader cost = 1 diff --git a/code/modules/antagonists/heretic/knowledge/rust_lore.dm b/code/modules/antagonists/heretic/knowledge/rust_lore.dm index a2f0a91e69a06..f624767f33e82 100644 --- a/code/modules/antagonists/heretic/knowledge/rust_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/rust_lore.dm @@ -104,7 +104,7 @@ Anyone overtop the wall will be throw aside (or upwards) and sustain damage." gain_text = "Images of foreign and ominous structures began to dance in my mind. Covered head to toe in thick rust, \ they no longer looked man made. Or perhaps they never were in the first place." - spell_to_add = /datum/action/cooldown/spell/pointed/rust_construction + action_to_add = /datum/action/cooldown/spell/pointed/rust_construction cost = 1 /datum/heretic_knowledge/spell/area_conversion @@ -112,7 +112,7 @@ desc = "Grants you Aggressive Spread, a spell that spreads rust to nearby surfaces. \ Already rusted surfaces are destroyed \ Also improves the rusting abilities of non rust-heretics." gain_text = "All wise men know well not to visit the Rusted Hills... Yet the Blacksmith's tale was inspiring." - spell_to_add = /datum/action/cooldown/spell/aoe/rust_conversion + action_to_add = /datum/action/cooldown/spell/aoe/rust_conversion cost = 1 research_tree_icon_frame = 5 @@ -147,7 +147,7 @@ gain_text = "The corrosion was unstoppable. The rust was unpleasable. \ The Blacksmith was gone, and you hold their blade. Champions of hope, the Rustbringer is nigh!" - spell_to_add = /datum/action/cooldown/spell/cone/staggered/entropic_plume + action_to_add = /datum/action/cooldown/spell/cone/staggered/entropic_plume cost = 1 diff --git a/code/modules/antagonists/heretic/knowledge/side_blade_rust.dm b/code/modules/antagonists/heretic/knowledge/side_blade_rust.dm index 05b414fe34634..a09c9cd87973d 100644 --- a/code/modules/antagonists/heretic/knowledge/side_blade_rust.dm +++ b/code/modules/antagonists/heretic/knowledge/side_blade_rust.dm @@ -112,7 +112,7 @@ desc = "A charge that must be started on a rusted tile and will destroy any rusted objects you come into contact with, will deal high damage to others and rust around you during the charge." gain_text = "The hills sparkled now, as I neared them my mind began to wander. I quickly regained my resolve and pushed forward, this last leg would be the most treacherous." - spell_to_add = /datum/action/cooldown/mob_cooldown/charge/rust + action_to_add = /datum/action/cooldown/mob_cooldown/charge/rust cost = 1 diff --git a/code/modules/antagonists/heretic/knowledge/side_cosmos_ash.dm b/code/modules/antagonists/heretic/knowledge/side_cosmos_ash.dm index 03b4fc477ad1b..d15bb242989cf 100644 --- a/code/modules/antagonists/heretic/knowledge/side_cosmos_ash.dm +++ b/code/modules/antagonists/heretic/knowledge/side_cosmos_ash.dm @@ -36,7 +36,7 @@ You can only phase in and out when you are on a space or misc turf." gain_text = "You feel like your body can move through space as if you where dust." - spell_to_add = /datum/action/cooldown/spell/jaunt/space_crawl + action_to_add = /datum/action/cooldown/spell/jaunt/space_crawl cost = 1 diff --git a/code/modules/antagonists/heretic/knowledge/side_flesh_void.dm b/code/modules/antagonists/heretic/knowledge/side_flesh_void.dm index 7891b50aabcc9..bd7f1cf621c6f 100644 --- a/code/modules/antagonists/heretic/knowledge/side_flesh_void.dm +++ b/code/modules/antagonists/heretic/knowledge/side_flesh_void.dm @@ -35,7 +35,7 @@ Also has a chance to transfer wounds from you to the victim." gain_text = "\"No matter the man, we bleed all the same.\" That's what the Marshal told me." - spell_to_add = /datum/action/cooldown/spell/pointed/blood_siphon + action_to_add = /datum/action/cooldown/spell/pointed/blood_siphon cost = 1 /datum/heretic_knowledge/spell/void_prison @@ -47,7 +47,7 @@ But the only welts made are on my own beating fist. \ My smiling face turns to regard me, reflecting back in glassy eyes the empty path I have been lead down." - spell_to_add = /datum/action/cooldown/spell/pointed/void_prison + action_to_add = /datum/action/cooldown/spell/pointed/void_prison cost = 1 /datum/heretic_knowledge/spell/cleave @@ -57,7 +57,7 @@ gain_text = "At first I didn't understand these instruments of war, but the Priest \ told me to use them regardless. Soon, he said, I would know them well." - spell_to_add = /datum/action/cooldown/spell/pointed/cleave + action_to_add = /datum/action/cooldown/spell/pointed/cleave cost = 1 diff --git a/code/modules/antagonists/heretic/knowledge/side_lock_flesh.dm b/code/modules/antagonists/heretic/knowledge/side_lock_flesh.dm index aa85f31d006c5..0f7c9d9fc70e1 100644 --- a/code/modules/antagonists/heretic/knowledge/side_lock_flesh.dm +++ b/code/modules/antagonists/heretic/knowledge/side_lock_flesh.dm @@ -22,7 +22,7 @@ However, you will fall unconscious a short time after casting this spell." gain_text = "My shackles undone in dark fury, their feeble bindings crumble before my power." - spell_to_add = /datum/action/cooldown/spell/aoe/wave_of_desperation + action_to_add = /datum/action/cooldown/spell/aoe/wave_of_desperation cost = 1 /datum/heretic_knowledge/spell/apetra_vulnera @@ -32,7 +32,7 @@ Wounds a random limb if no limb is sufficiently damaged." gain_text = "Flesh opens, and blood spills. My master seeks sacrifice, and I shall appease." - spell_to_add = /datum/action/cooldown/spell/pointed/apetra_vulnera + action_to_add = /datum/action/cooldown/spell/pointed/apetra_vulnera cost = 1 diff --git a/code/modules/antagonists/heretic/knowledge/side_lock_moon.dm b/code/modules/antagonists/heretic/knowledge/side_lock_moon.dm index f8a3cdf465bd8..5d3795b0ce961 100644 --- a/code/modules/antagonists/heretic/knowledge/side_lock_moon.dm +++ b/code/modules/antagonists/heretic/knowledge/side_lock_moon.dm @@ -25,7 +25,7 @@ The caster takes 20 brain damage per use." gain_text = "My mind swings open like a gate, and its insight will let me perceive the truth." - spell_to_add = /datum/action/cooldown/spell/pointed/mind_gate + action_to_add = /datum/action/cooldown/spell/pointed/mind_gate cost = 1 /datum/heretic_knowledge/unfathomable_curio diff --git a/code/modules/antagonists/heretic/knowledge/starting_lore.dm b/code/modules/antagonists/heretic/knowledge/starting_lore.dm index d6c9d1bc216a7..b20009febcf4b 100644 --- a/code/modules/antagonists/heretic/knowledge/starting_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/starting_lore.dm @@ -21,7 +21,7 @@ GLOBAL_LIST_INIT(heretic_start_knowledge, initialize_starting_knowledge()) desc = "Starts your journey into the Mansus. \ Grants you the Mansus Grasp, a powerful and upgradable \ disabling spell that can be cast regardless of having a focus." - spell_to_add = /datum/action/cooldown/spell/touch/mansus_grasp + action_to_add = /datum/action/cooldown/spell/touch/mansus_grasp cost = 0 is_starting_knowledge = TRUE @@ -211,7 +211,7 @@ GLOBAL_LIST_INIT(heretic_start_knowledge, initialize_starting_knowledge()) name = "Cloak of Shadow" desc = "Grants you the spell Cloak of Shadow. This spell will completely conceal your identity in a purple smoke \ for three minutes, assisting you in keeping secrecy. Requires a focus to cast." - spell_to_add = /datum/action/cooldown/spell/shadow_cloak + action_to_add = /datum/action/cooldown/spell/shadow_cloak cost = 0 is_starting_knowledge = TRUE diff --git a/code/modules/antagonists/heretic/knowledge/void_lore.dm b/code/modules/antagonists/heretic/knowledge/void_lore.dm index fb4bc57924784..14e2ffe0e9ad5 100644 --- a/code/modules/antagonists/heretic/knowledge/void_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/void_lore.dm @@ -116,7 +116,7 @@ gain_text = "The hum in the still, cold air turns to a cacophonous rattle. \ Over the noise, there is no distinction to the clattering of window panes and the yawning knowledge that ricochets through my skull. \ The doors won't close. I can't keep the cold out now." - spell_to_add = /datum/action/cooldown/spell/conjure/void_conduit + action_to_add = /datum/action/cooldown/spell/conjure/void_conduit cost = 1 /datum/heretic_knowledge/spell/void_phase @@ -125,7 +125,7 @@ Additionally causes damage to heathens around your original and target destination." gain_text = "The entity calls themself the Aristocrat. They effortlessly walk through air like \ nothing - leaving a harsh, cold breeze in their wake. They disappear, and I am left in the blizzard." - spell_to_add = /datum/action/cooldown/spell/pointed/void_phase + action_to_add = /datum/action/cooldown/spell/pointed/void_phase cost = 1 research_tree_icon_frame = 7 @@ -162,7 +162,7 @@ gain_text = "All is fleeting, but what else stays? I'm close to ending what was started. \ The Aristocrat reveals themselves to me again. They tell me I am late. Their pull is immense, I cannot turn back." - spell_to_add = /datum/action/cooldown/spell/aoe/void_pull + action_to_add = /datum/action/cooldown/spell/aoe/void_pull cost = 1 diff --git a/code/modules/antagonists/spy/spy_bounty.dm b/code/modules/antagonists/spy/spy_bounty.dm index 1aa318fb6828d..f45da0fdce832 100644 --- a/code/modules/antagonists/spy/spy_bounty.dm +++ b/code/modules/antagonists/spy/spy_bounty.dm @@ -639,7 +639,7 @@ theft_time = 10 SECONDS black_market_prob = 0 /// What typepath of bot we want to steal. - var/mob/living/simple_animal/bot/bot_type + var/mob/living/bot_type /// Weakref to the bot we want to steal. VAR_FINAL/datum/weakref/target_bot_ref @@ -655,7 +655,7 @@ /datum/spy_bounty/some_bot/init_bounty(datum/spy_bounty_handler/handler) for(var/datum/spy_bounty/some_bot/existing_bounty in handler.get_all_bounties()) - var/mob/living/simple_animal/bot/existing_bot_type = existing_bounty.bot_type + var/mob/living/existing_bot_type = existing_bounty.bot_type // ensures we don't get two similar bounties. // may occasionally cast a wider net than we'd desire, but it's not that bad. if(ispath(bot_type, initial(existing_bot_type.parent_type))) diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm index 8b99d5a3edc24..ebdb64b9afd9d 100644 --- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm +++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm @@ -37,7 +37,7 @@ ///Are we active? var/excited = FALSE ///Our gas mix - var/datum/gas_mixture/turf/air + var/datum/gas_mixture/air ///If there is an active hotspot on us store a reference to it here var/obj/effect/hotspot/active_hotspot diff --git a/code/modules/autowiki/pages/fishing.dm b/code/modules/autowiki/pages/fishing.dm index eab26bd6c6c03..ce2872235bb4a 100644 --- a/code/modules/autowiki/pages/fishing.dm +++ b/code/modules/autowiki/pages/fishing.dm @@ -44,7 +44,7 @@ if(fish::breeding_timeout != def_breeding) extra_info += "It takes [DisplayTimeText(fish::breeding_timeout)] to reproduce instead of [def_breeding_text]" if(length(extra_info)) - description += "
[extra_info.Join(extra_info,"
")]" + description += "
[extra_info.Join("
")]" var/list/output_list = list( "name" = full_capitalize(escape_value(fish::name)), diff --git a/code/modules/bitrunning/objects/vendor.dm b/code/modules/bitrunning/objects/vendor.dm index d44630bc3beed..f373a8617b445 100644 --- a/code/modules/bitrunning/objects/vendor.dm +++ b/code/modules/bitrunning/objects/vendor.dm @@ -33,7 +33,7 @@ /obj/machinery/computer/order_console/bitrunning/order_groceries(mob/living/purchaser, obj/item/card/id/card, list/groceries) var/list/things_to_order = list() for(var/datum/orderable_item/item as anything in groceries) - things_to_order[item.item_path] = groceries[item] + things_to_order[item.purchase_path] = groceries[item] var/datum/supply_pack/bitrunning/pack = new( purchaser = purchaser, \ diff --git a/code/modules/bitrunning/orders/bepis.dm b/code/modules/bitrunning/orders/bepis.dm index 4b7253bdaf24a..f10eaaf3245a2 100644 --- a/code/modules/bitrunning/orders/bepis.dm +++ b/code/modules/bitrunning/orders/bepis.dm @@ -2,18 +2,18 @@ category_index = CATEGORY_BEPIS /datum/orderable_item/bepis/circuit_stack - item_path = /obj/item/stack/circuit_stack/full + purchase_path = /obj/item/stack/circuit_stack/full cost_per_order = 150 /datum/orderable_item/bepis/survival_pen - item_path = /obj/item/pen/survival + purchase_path = /obj/item/pen/survival cost_per_order = 150 /datum/orderable_item/bepis/party_sleeper - item_path = /obj/item/circuitboard/machine/sleeper/party + purchase_path = /obj/item/circuitboard/machine/sleeper/party cost_per_order = 750 desc = "A decommissioned sleeper circuitboard, repurposed for recreational purposes." /datum/orderable_item/bepis/sprayoncan - item_path = /obj/item/toy/sprayoncan + purchase_path = /obj/item/toy/sprayoncan cost_per_order = 750 diff --git a/code/modules/bitrunning/orders/flair.dm b/code/modules/bitrunning/orders/flair.dm index ef36348eb6ae9..0b1b79b03d0b9 100644 --- a/code/modules/bitrunning/orders/flair.dm +++ b/code/modules/bitrunning/orders/flair.dm @@ -2,39 +2,39 @@ category_index = CATEGORY_BITRUNNING_FLAIR /datum/orderable_item/bitrunning_flair/cornchips - item_path = /obj/item/food/cornchips + purchase_path = /obj/item/food/cornchips cost_per_order = 100 /datum/orderable_item/bitrunning_flair/mountain_wind - item_path = /obj/item/reagent_containers/cup/soda_cans/space_mountain_wind + purchase_path = /obj/item/reagent_containers/cup/soda_cans/space_mountain_wind cost_per_order = 100 /datum/orderable_item/bitrunning_flair/pwr_game - item_path = /obj/item/reagent_containers/cup/soda_cans/pwr_game + purchase_path = /obj/item/reagent_containers/cup/soda_cans/pwr_game cost_per_order = 200 /datum/orderable_item/bitrunning_flair/grey_bull - item_path = /obj/item/reagent_containers/cup/soda_cans/grey_bull + purchase_path = /obj/item/reagent_containers/cup/soda_cans/grey_bull cost_per_order = 200 /datum/orderable_item/bitrunning_flair/medkit - item_path = /obj/item/storage/medkit/brute + purchase_path = /obj/item/storage/medkit/brute desc = "Don't beat yourself up, it's just a game!" cost_per_order = 500 /datum/orderable_item/bitrunning_flair/medkit_fire - item_path = /obj/item/storage/medkit/fire + purchase_path = /obj/item/storage/medkit/fire desc = "Great after heated gaming sessions." cost_per_order = 500 /datum/orderable_item/bitrunning_flair/oval_sunglasses - item_path = /obj/item/clothing/glasses/sunglasses/oval + purchase_path = /obj/item/clothing/glasses/sunglasses/oval cost_per_order = 1000 /datum/orderable_item/bitrunning_flair/trenchcoat - item_path = /obj/item/clothing/suit/jacket/trenchcoat + purchase_path = /obj/item/clothing/suit/jacket/trenchcoat cost_per_order = 1000 /datum/orderable_item/bitrunning_flair/jackboots - item_path = /obj/item/clothing/shoes/jackboots + purchase_path = /obj/item/clothing/shoes/jackboots cost_per_order = 1000 diff --git a/code/modules/bitrunning/orders/tech.dm b/code/modules/bitrunning/orders/tech.dm index 9dd1db17c799d..cb509fb625201 100644 --- a/code/modules/bitrunning/orders/tech.dm +++ b/code/modules/bitrunning/orders/tech.dm @@ -3,54 +3,54 @@ /datum/orderable_item/bitrunning_tech/item_tier1 cost_per_order = 750 - item_path = /obj/item/bitrunning_disk/item/tier1 + purchase_path = /obj/item/bitrunning_disk/item/tier1 desc = "This disk contains a program that lets you equip a medical beamgun, a C4 explosive, or a box of infinite pizza." /datum/orderable_item/bitrunning_tech/item_tier2 cost_per_order = 1250 - item_path = /obj/item/bitrunning_disk/item/tier2 + purchase_path = /obj/item/bitrunning_disk/item/tier2 desc = "This disk contains a program that lets you equip a luxury medipen, a pistol, or an armour vest." /datum/orderable_item/bitrunning_tech/item_tier3 cost_per_order = 2000 - item_path = /obj/item/bitrunning_disk/item/tier3 + purchase_path = /obj/item/bitrunning_disk/item/tier3 desc = "This disk contains a program that lets you equip an advanced energy gun, a dual bladed energy sword, or a minibomb." /datum/orderable_item/bitrunning_tech/ability_tier1 cost_per_order = 750 - item_path = /obj/item/bitrunning_disk/ability/tier1 + purchase_path = /obj/item/bitrunning_disk/ability/tier1 desc = "This disk contains a program that lets you cast Summon Cheese or Lesser Heal." /datum/orderable_item/bitrunning_tech/ability_tier2 cost_per_order = 1500 - item_path = /obj/item/bitrunning_disk/ability/tier2 + purchase_path = /obj/item/bitrunning_disk/ability/tier2 desc = "This disk contains a program that lets you cast Fireball, Lightning Bolt, or Forcewall." /datum/orderable_item/bitrunning_tech/ability_tier3 cost_per_order = 2500 - item_path = /obj/item/bitrunning_disk/ability/tier3 + purchase_path = /obj/item/bitrunning_disk/ability/tier3 desc = "This disk contains a program that lets you shapeshift into a lesser ashdrake, or a polar bear." /datum/orderable_item/bitrunning_tech/flip_skillchip - item_path = /obj/item/skillchip/matrix_taunt + purchase_path = /obj/item/skillchip/matrix_taunt cost_per_order = 1500 /datum/orderable_item/bitrunning_tech/pka_mod - item_path = /obj/item/bitrunning_disk/item/pka_mods + purchase_path = /obj/item/bitrunning_disk/item/pka_mods cost_per_order = 750 desc = "This disk contains a program that lets you equip modkits for the proto-kinetic accelerator. Proto-kinetic accelerator not included." /datum/orderable_item/bitrunning_tech/pka_mod/premium - item_path = /obj/item/bitrunning_disk/item/pka_mods/premium + purchase_path = /obj/item/bitrunning_disk/item/pka_mods/premium cost_per_order = 1600 desc = "This disk contains a program that lets you equip stronger modkits for the proto-kinetic accelerator. Proto-kinetic accelerator not included." /datum/orderable_item/bitrunning_tech/pkc_mod - item_path = /obj/item/bitrunning_disk/item/pkc_mods + purchase_path = /obj/item/bitrunning_disk/item/pkc_mods cost_per_order = 750 desc = "This disk contains a program that lets you equip trophies for the proto-kinetic crusher. Proto-kinetic crusher no included." /datum/orderable_item/bitrunning_tech/pkc_mod/premium - item_path = /obj/item/bitrunning_disk/item/pkc_mods/premium + purchase_path = /obj/item/bitrunning_disk/item/pkc_mods/premium cost_per_order = 1600 desc = "This disk contains a program that lets you equip stronger trophies for the proto-kinetic crusher. Proto-kinetic crusher not included." diff --git a/code/modules/bitrunning/server/_parent.dm b/code/modules/bitrunning/server/_parent.dm index 672a79ba72cef..5e29c1729b490 100644 --- a/code/modules/bitrunning/server/_parent.dm +++ b/code/modules/bitrunning/server/_parent.dm @@ -45,7 +45,7 @@ /// Maximum rate at which a glitch can spawn var/threat_prob_max = 15 /// The turfs we can place a hololadder on. - var/turf/exit_turfs = list() + var/list/turf/exit_turfs = list() /// Determines if we broadcast to entertainment monitors or not var/broadcasting = FALSE /// Cooldown between being able to toggle broadcasting diff --git a/code/modules/capture_the_flag/ctf_game.dm b/code/modules/capture_the_flag/ctf_game.dm index 2f292218e79f6..968e6e2953e95 100644 --- a/code/modules/capture_the_flag/ctf_game.dm +++ b/code/modules/capture_the_flag/ctf_game.dm @@ -403,7 +403,7 @@ alpha = 255 /obj/structure/trap/ctf/examine(mob/user) - return + return list() /obj/structure/trap/ctf/trap_effect(mob/living/living) if(!is_ctf_target(living)) diff --git a/code/modules/cargo/bounties/botany.dm b/code/modules/cargo/bounties/botany.dm index 905122584bf34..042bb60636f09 100644 --- a/code/modules/cargo/bounties/botany.dm +++ b/code/modules/cargo/bounties/botany.dm @@ -1,8 +1,8 @@ /datum/bounty/item/botany reward = CARGO_CRATE_VALUE * 10 - var/datum/bounty/item/botany/multiplier = 0 //adds bonus reward money; increased for higher tier or rare mutations - var/datum/bounty/item/botany/bonus_desc //for adding extra flavor text to bounty descriptions - var/datum/bounty/item/botany/foodtype = "meal" //same here + var/multiplier = 0 //adds bonus reward money; increased for higher tier or rare mutations + var/bonus_desc //for adding extra flavor text to bounty descriptions + var/foodtype = "meal" //same here /datum/bounty/item/botany/New() ..() diff --git a/code/modules/cargo/centcom_podlauncher.dm b/code/modules/cargo/centcom_podlauncher.dm index 1ba739d3343a4..bb1c4ea8a8b86 100644 --- a/code/modules/cargo/centcom_podlauncher.dm +++ b/code/modules/cargo/centcom_podlauncher.dm @@ -303,7 +303,7 @@ ADMIN_VERB(centcom_podlauncher, R_ADMIN, "Config/Launch Supplypod", "Configure a return if (!isnum(boomInput[i])) //If the user doesn't input a number, set that specific explosion value to zero tgui_alert(usr, "That wasn't a number! Value set to default (zero) instead.") - boomInput = 0 + boomInput[i] = 0 explosionChoice = 1 temp_pod.explosionSize = boomInput . = TRUE diff --git a/code/modules/fishing/fishing_equipment.dm b/code/modules/fishing/fishing_equipment.dm index 1b589e18be3da..ab72b0b0fb26e 100644 --- a/code/modules/fishing/fishing_equipment.dm +++ b/code/modules/fishing/fishing_equipment.dm @@ -12,8 +12,8 @@ icon = 'icons/obj/fishing.dmi' icon_state = "reel_blue" w_class = WEIGHT_CLASS_SMALL - ///A list of traits that this fishing line has, checked by fish traits and the minigame. - var/list/fishing_line_traits + ///A bitfield of traits that this fishing line has, checked by fish traits and the minigame. + var/fishing_line_traits /// Color of the fishing line var/line_color = COLOR_GRAY ///The description given to the autowiki @@ -146,11 +146,11 @@ icon_state = "hook" w_class = WEIGHT_CLASS_TINY - /// A list of traits that this fishing hook has, checked by fish traits and the minigame - var/list/fishing_hook_traits + /// A bitfield of traits that this fishing hook has, checked by fish traits and the minigame + var/fishing_hook_traits /// icon state added to main rod icon when this hook is equipped var/rod_overlay_icon_state = "hook_overlay" - /// What subtype of `/obj/item/chasm_detritus` do we fish out of chasms? Defaults to `/obj/item/chasm_detritus`. + /// What subtype of `/datum/chasm_detritus` do we fish out of chasms? Defaults to `/datum/chasm_detritus`. var/chasm_detritus_type = /datum/chasm_detritus ///The description given to the autowiki var/wiki_desc = "A generic fishing hook. You won't be able to fish without one." diff --git a/code/modules/food_and_drinks/machinery/smartfridge.dm b/code/modules/food_and_drinks/machinery/smartfridge.dm index 0481d1c491092..afd566b7e479d 100644 --- a/code/modules/food_and_drinks/machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/machinery/smartfridge.dm @@ -526,7 +526,7 @@ /obj/machinery/smartfridge/drying/proc/toggle_drying(forceoff, mob/user) if(drying || forceoff) drying = FALSE - current_user = FALSE + current_user = null update_use_power(IDLE_POWER_USE) else drying = TRUE diff --git a/code/modules/hallucination/stray_bullet.dm b/code/modules/hallucination/stray_bullet.dm index 13ace2933350a..11f88c8c964ed 100644 --- a/code/modules/hallucination/stray_bullet.dm +++ b/code/modules/hallucination/stray_bullet.dm @@ -101,7 +101,6 @@ spawn_hit(target, TRUE) qdel(src) - return TRUE /// Called when a mob is hit by the fake projectile /obj/projectile/hallucination/proc/on_mob_hit(mob/living/hit_mob) diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index 4589a3c4312b5..e0e88f7c402d9 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -50,7 +50,7 @@ var/list/genes = list() /// A list of reagents to add to product. var/list/reagents_add - // Format: "reagent_id" = potency multiplier + // Format: /datum/reagent/type = potency multiplier // Stronger reagents must always come first to avoid being displaced by weaker ones. // Total amount of any reagent in plant is calculated by formula: max(round(potency * multiplier), 1) ///If the chance below passes, then this many weeds sprout during growth diff --git a/code/modules/jobs/job_types/security_officer.dm b/code/modules/jobs/job_types/security_officer.dm index 9b2dc91137cd5..a84d4e0e73765 100644 --- a/code/modules/jobs/job_types/security_officer.dm +++ b/code/modules/jobs/job_types/security_officer.dm @@ -83,7 +83,7 @@ GLOBAL_LIST_EMPTY(security_officer_distribution) var/ears = null var/accessory = null - var/list/dep_trim = null + var/datum/id_trim/dep_trim = null var/destination = null switch(department) diff --git a/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm b/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm index 7ef451ddc303a..ce57035a7661c 100644 --- a/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm +++ b/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm @@ -59,13 +59,13 @@ if(offeredmob.mind?.has_antag_datum(/datum/antagonist/ashwalker) && (offeredmob.ckey || offeredmob.get_ghost(FALSE, TRUE))) //special interactions for dead lava lizards with ghosts attached visible_message(span_warning("Serrated tendrils carefully pull [offeredmob] to [src], absorbing the body and creating it anew.")) - var/datum/mind/deadmind + var/mob/deadmob if(offeredmob.ckey) - deadmind = offeredmob + deadmob = offeredmob else - deadmind = offeredmob.get_ghost(FALSE, TRUE) - to_chat(deadmind, "Your body has been returned to the nest. You are being remade anew, and will awaken shortly.
Your memories will remain intact in your new body, as your soul is being salvaged") - SEND_SOUND(deadmind, sound('sound/effects/magic/enter_blood.ogg',volume=100)) + deadmob = offeredmob.get_ghost(FALSE, TRUE) + to_chat(deadmob, "Your body has been returned to the nest. You are being remade anew, and will awaken shortly.
Your memories will remain intact in your new body, as your soul is being salvaged") + SEND_SOUND(deadmob, sound('sound/effects/magic/enter_blood.ogg',volume=100)) addtimer(CALLBACK(src, PROC_REF(remake_walker), offeredmob), 20 SECONDS) offeredmob.forceMove(src) return diff --git a/code/modules/mapfluff/ruins/spaceruin_code/hauntedtradingpost.dm b/code/modules/mapfluff/ruins/spaceruin_code/hauntedtradingpost.dm index 39458ac942964..ac4f257dc2a52 100644 --- a/code/modules/mapfluff/ruins/spaceruin_code/hauntedtradingpost.dm +++ b/code/modules/mapfluff/ruins/spaceruin_code/hauntedtradingpost.dm @@ -245,7 +245,7 @@ //is this being used as part of the haunted trading post ruin? if true, will self destruct when boss dies var/donk_ai_slave = FALSE // machine that the trap inhabits - var/obj/structure/host_machine + var/obj/machinery/host_machine // turf that the trap is on var/turf/my_turf //how long until trap zaps everything, after it detects something diff --git a/code/modules/mining/equipment/grapple_gun.dm b/code/modules/mining/equipment/grapple_gun.dm index 0247d0164b025..fa7f0b0b73570 100644 --- a/code/modules/mining/equipment/grapple_gun.dm +++ b/code/modules/mining/equipment/grapple_gun.dm @@ -10,7 +10,7 @@ inhand_icon_state = "gun" item_flags = NOBLUDGEON ///overlay when the hook is retracted - var/static/mutable_appearance/hook_overlay = new(icon = 'icons/obj/mining.dmi', icon_state = "grapple_gun_hooked") + var/static/mutable_appearance/hook_overlay = mutable_appearance(icon = 'icons/obj/mining.dmi', icon_state = "grapple_gun_hooked") ///is the hook retracted var/hooked = TRUE ///addtimer id for launching the user diff --git a/code/modules/mob/living/basic/jungle/seedling/seedling_projectiles.dm b/code/modules/mob/living/basic/jungle/seedling/seedling_projectiles.dm index 303776384d1f6..4e9e045958732 100644 --- a/code/modules/mob/living/basic/jungle/seedling/seedling_projectiles.dm +++ b/code/modules/mob/living/basic/jungle/seedling/seedling_projectiles.dm @@ -17,7 +17,7 @@ var/mob/living/living_target = target if(FACTION_JUNGLE in living_target.faction) - return + return BULLET_ACT_BLOCK return ..() diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index d9caad422927e..323420cb8ae7f 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -456,7 +456,7 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real if(EXPLODE_DEVASTATE) investigate_log("has been gibbed by an explosion.", INVESTIGATE_DEATHS) gib(DROP_ALL_REMAINS) - return + return TRUE if(EXPLODE_HEAVY) if (stat != DEAD) adjustBruteLoss(60) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm index 03d79c108d60d..f57ea3e058203 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm @@ -121,7 +121,7 @@ IGNORE_PROC_IF_NOT_TARGET(attack_animal) /mob/living/simple_animal/hostile/asteroid/curseblob/bullet_act(obj/projectile/Proj) if(Proj.firer != set_target) - return + return BULLET_ACT_BLOCK return ..() /mob/living/simple_animal/hostile/asteroid/curseblob/attacked_by(obj/item/I, mob/living/L) diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index dc273965e8188..d1817e5170ba3 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -926,7 +926,7 @@ icon_state = "fishing_glove" complexity = 1 overlay_state_inactive = "fishing_glove" - incompatible_modules = (/obj/item/mod/module/fishing_glove) + incompatible_modules = list(/obj/item/mod/module/fishing_glove) required_slots = list(ITEM_SLOT_GLOVES) var/obj/item/fishing_rod/equipped diff --git a/code/modules/modular_computers/file_system/programs/virtual_pet.dm b/code/modules/modular_computers/file_system/programs/virtual_pet.dm index 746824f8d8bf7..ed30fdbd70326 100644 --- a/code/modules/modular_computers/file_system/programs/virtual_pet.dm +++ b/code/modules/modular_computers/file_system/programs/virtual_pet.dm @@ -445,7 +445,7 @@ GLOBAL_LIST_EMPTY(virtual_pets_list) for(var/type_index as anything in hat_selections) if(level >= hat_selections[type_index]) var/obj/item/hat = type_index - var/obj/item/hat_name = initial(hat.name) + var/hat_name = initial(hat.name) if(length(SSachievements.achievements)) // The Achievements subsystem is active. var/datum/award/required_cheevo = cheevo_hats[hat] if(required_cheevo && !user.client.get_award_status(required_cheevo)) diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 1993a51e29b46..a53d959c9e31e 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -149,7 +149,7 @@ if(current_size <= STAGE_TWO) investigate_log("has been destroyed by a heavy explosion.", INVESTIGATE_ENGINE) qdel(src) - return + return TRUE energy -= round(((energy + 1) / 2), 1) if(EXPLODE_HEAVY) diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 9c69a718986e4..08cce7d73151c 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -154,7 +154,7 @@ /obj/projectile/beam/laser/accelerator/Range() ..() damage += 7 - transform = 0 + transform = matrix() transform *= min(1 + (decayedRange - range) * size_per_tile, max_scale) ///X-ray gun diff --git a/code/modules/projectiles/projectile/energy/nuclear_particle.dm b/code/modules/projectiles/projectile/energy/nuclear_particle.dm index b82ff478a05b4..6626cb9b5ed75 100644 --- a/code/modules/projectiles/projectile/energy/nuclear_particle.dm +++ b/code/modules/projectiles/projectile/energy/nuclear_particle.dm @@ -29,7 +29,7 @@ if (ishuman(target)) SSradiation.irradiate(target) - ..() + return ..() /atom/proc/fire_nuclear_particle(angle = rand(0,360)) //used by fusion to fire random nuclear particles. Fires one particle in a random direction. var/obj/projectile/energy/nuclear_particle/P = new /obj/projectile/energy/nuclear_particle(src) diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 4ed21b0e29871..f65383fbfcc7f 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -82,7 +82,7 @@ var/purge_multiplier = 1 ///The default reagent container for the reagent, used for icon generation - var/obj/item/reagent_containers/default_container = /obj/item/reagent_containers/cup/bottle + var/obj/default_container = /obj/item/reagent_containers/cup/bottle // Used for restaurants. ///The amount a robot will pay for a glass of this (20 units but can be higher if you pour more, be frugal!) diff --git a/code/modules/religion/rites.dm b/code/modules/religion/rites.dm index cd0fabba84974..67526918167a7 100644 --- a/code/modules/religion/rites.dm +++ b/code/modules/religion/rites.dm @@ -20,9 +20,8 @@ LAZYADD(GLOB.religious_sect.active_rites, src) /datum/religion_rites/Destroy() - if(!GLOB?.religious_sect) - return - LAZYREMOVE(GLOB.religious_sect.active_rites, src) + if(GLOB?.religious_sect) + LAZYREMOVE(GLOB.religious_sect.active_rites, src) return ..() /datum/religion_rites/proc/can_afford(mob/living/user) diff --git a/code/modules/research/techweb/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm index b6d3bd74d6979..79b8b27986c9f 100644 --- a/code/modules/research/techweb/_techweb_node.dm +++ b/code/modules/research/techweb/_techweb_node.dm @@ -34,7 +34,7 @@ var/category = "Misc" /// The list of experiments required to research the node var/list/required_experiments = list() - /// If completed, these experiments give a specific point amount discount to the node.area + /// If completed, these experiments give a specific point amount discount to the node. var/list/discount_experiments = list() /// When this node is completed, allows these experiments to be performed. var/list/experiments_to_unlock = list() diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 4eed7f3e9a7e1..b5b7cc6f6ef85 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -151,7 +151,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( investigate_log("Chef's [SSshuttle.chef_groceries.len] sized produce order arrived. Cost was deducted from orderer, not cargo.", INVESTIGATE_CARGO) for(var/datum/orderable_item/item as anything in SSshuttle.chef_groceries)//every order for(var/amt in 1 to SSshuttle.chef_groceries[item])//every order amount - new item.item_path(grocery_crate) + new item.purchase_path(grocery_crate) SSshuttle.chef_groceries.Cut() //This lets the console know it can order another round. if(!SSshuttle.shopping_list.len) diff --git a/code/modules/spells/spell_types/jaunt/bloodcrawl.dm b/code/modules/spells/spell_types/jaunt/bloodcrawl.dm index 8c9c6809a0657..aa6a58b1341be 100644 --- a/code/modules/spells/spell_types/jaunt/bloodcrawl.dm +++ b/code/modules/spells/spell_types/jaunt/bloodcrawl.dm @@ -332,7 +332,7 @@ // Heals them back to state one if(!friend.revive(ADMIN_HEAL_ALL, force_grab_ghost = TRUE)) continue - playsound(release_turf, consumed_mobs, 50, TRUE, -1) + friend.playsound_local(release_turf, 'sound/effects/magic/exit_blood.ogg', 50, TRUE, -1) to_chat(friend, span_clown("You leave [source]'s warm embrace, and feel ready to take on the world.")) diff --git a/code/modules/spells/spell_types/pointed/_pointed.dm b/code/modules/spells/spell_types/pointed/_pointed.dm index 9189106d87424..a96e2fe9fd291 100644 --- a/code/modules/spells/spell_types/pointed/_pointed.dm +++ b/code/modules/spells/spell_types/pointed/_pointed.dm @@ -101,7 +101,7 @@ */ /datum/action/cooldown/spell/pointed/projectile /// What projectile we create when we shoot our spell. - var/obj/projectile/magic/projectile_type = /obj/projectile/magic/teleport + var/obj/projectile/projectile_type = /obj/projectile/magic/teleport /// How many projectiles we can fire per cast. Not all at once, per click, kinda like charges var/projectile_amount = 1 /// How many projectiles we have yet to fire, based on projectile_amount diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm index 683afe605c983..7467f85d79e93 100644 --- a/code/modules/station_goals/bsa.dm +++ b/code/modules/station_goals/bsa.dm @@ -212,7 +212,7 @@ GLOBAL_VAR_INIT(bsa_unlock, FALSE) var/turf/point = get_front_turf() var/turf/target = get_target_turf() - var/atom/movable/blocker + var/atom/blocker for(var/T in get_line(get_step(point, dir), target)) var/turf/tile = T if(SEND_SIGNAL(tile, COMSIG_ATOM_BSA_BEAM) & COMSIG_ATOM_BLOCKS_BSA_BEAM) diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm index 25f66f40af9a8..c7e1f7f7846da 100644 --- a/code/modules/surgery/bodyparts/parts.dm +++ b/code/modules/surgery/bodyparts/parts.dm @@ -106,7 +106,7 @@ bodypart_flags = BODYPART_UNREMOVABLE max_damage = LIMB_MAX_HP_ALIEN_CORE acceptable_bodyshape = BODYSHAPE_HUMANOID - wing_types = NONE + wing_types = null /obj/item/bodypart/chest/larva icon = 'icons/mob/human/species/alien/bodyparts.dmi' @@ -119,7 +119,7 @@ max_damage = LIMB_MAX_HP_ALIEN_LARVA bodytype = BODYTYPE_LARVA_PLACEHOLDER | BODYTYPE_ORGANIC acceptable_bodytype = BODYTYPE_LARVA_PLACEHOLDER - wing_types = NONE + wing_types = null /// Parent Type for arms, should not appear in game. /obj/item/bodypart/arm diff --git a/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm index 756cda32fa327..3b1d56ee5b664 100644 --- a/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm @@ -22,7 +22,7 @@ is_dimorphic = FALSE dmg_overlay_type = null brute_modifier = 1.25 //ethereal are weak to brute damages - wing_types = NONE + wing_types = null bodypart_traits = list(TRAIT_NO_UNDERWEAR) /obj/item/bodypart/chest/ethereal/update_limb(dropping_limb, is_creating) diff --git a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm index 08b22373d32ae..74219a32cf22b 100644 --- a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm @@ -12,7 +12,7 @@ is_dimorphic = FALSE burn_modifier = 2 biological_state = (BIO_FLESH|BIO_BLOODED) - wing_types = NONE + wing_types = null /obj/item/bodypart/arm/left/snail limb_id = SPECIES_SNAIL @@ -58,7 +58,7 @@ limb_id = SPECIES_ABDUCTOR is_dimorphic = FALSE should_draw_greyscale = FALSE - wing_types = NONE + wing_types = null /obj/item/bodypart/chest/abductor/get_butt_sprite() return icon('icons/mob/butts.dmi', BUTT_SPRITE_GREY) @@ -177,7 +177,7 @@ limb_id = SPECIES_ZOMBIE is_dimorphic = FALSE should_draw_greyscale = FALSE - wing_types = NONE + wing_types = null /obj/item/bodypart/arm/left/zombie limb_id = SPECIES_ZOMBIE @@ -216,7 +216,7 @@ limb_id = SPECIES_PODPERSON is_dimorphic = TRUE burn_modifier = 1.25 - wing_types = NONE + wing_types = null /obj/item/bodypart/chest/pod/get_butt_sprite() return icon('icons/mob/butts.dmi', BUTT_SPRITE_FLOWERPOT) @@ -292,7 +292,7 @@ is_dimorphic = FALSE should_draw_greyscale = FALSE burn_modifier = 1.5 - wing_types = NONE + wing_types = null /obj/item/bodypart/arm/left/shadow limb_id = SPECIES_SHADOW @@ -380,7 +380,7 @@ is_dimorphic = TRUE bodypart_traits = list(TRAIT_NO_JUMPSUIT) burn_modifier = 1.25 - wing_types = NONE + wing_types = null /obj/item/bodypart/arm/left/mushroom limb_id = SPECIES_MUSHROOM @@ -483,7 +483,7 @@ should_draw_greyscale = FALSE dmg_overlay_type = null bodypart_traits = list(TRAIT_NO_JUMPSUIT) - wing_types = NONE + wing_types = null /obj/item/bodypart/chest/golem/Initialize(mapload) worn_belt_offset = new( diff --git a/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm index 0125601bda5a7..b668008e44c05 100644 --- a/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm @@ -28,7 +28,7 @@ brute_modifier = 1.5 //Plasmemes are weak burn_modifier = 1.5 //Plasmemes are weak bodypart_flags = BODYPART_UNHUSKABLE - wing_types = NONE + wing_types = null /obj/item/bodypart/chest/plasmaman/get_butt_sprite() return icon('icons/mob/butts.dmi', BUTT_SPRITE_PLASMA) diff --git a/code/modules/transport/tram/tram_controller.dm b/code/modules/transport/tram/tram_controller.dm index 5ac6d5bc748bc..37220034b664b 100644 --- a/code/modules/transport/tram/tram_controller.dm +++ b/code/modules/transport/tram/tram_controller.dm @@ -144,7 +144,7 @@ tram_registration.active = FALSE SSblackbox.record_feedback("amount", "tram_destroyed", 1) SSpersistence.save_tram_history(specific_transport_id) - ..() + return ..() /** * Register transport modules to the controller diff --git a/code/modules/unit_tests/orderable_items.dm b/code/modules/unit_tests/orderable_items.dm index 8d3db8c3c751f..e94b2985a5475 100644 --- a/code/modules/unit_tests/orderable_items.dm +++ b/code/modules/unit_tests/orderable_items.dm @@ -6,19 +6,19 @@ /datum/unit_test/orderable_items/Run() var/list/all_paths = list() for (var/datum/orderable_item/orderable_item as anything in subtypesof(/datum/orderable_item)) - if(isnull(initial(orderable_item.item_path))) // don't check if they're not actual orderable items + if(isnull(initial(orderable_item.purchase_path))) // don't check if they're not actual orderable items continue if (!isnull(initial(orderable_item.desc))) //don't check if they have a custom description continue - var/item_path = initial(orderable_item.item_path) + var/purchase_path = initial(orderable_item.purchase_path) - var/obj/item/item_instance = allocate(item_path) + var/obj/item/item_instance = allocate(purchase_path) var/initial_desc = initial(item_instance.desc) - if(item_path in all_paths) + if(purchase_path in all_paths) TEST_FAIL("[orderable_item] is purchasable under two different orderable_item types,") - all_paths += item_path + all_paths += purchase_path if (item_instance.desc != initial_desc) - TEST_FAIL("[orderable_item] has an item ([item_path]) that has a dynamic description. [item_instance.desc] (dynamic description) != [initial_desc] (initial description)") + TEST_FAIL("[orderable_item] has a product ([purchase_path]) that has a dynamic description. [item_instance.desc] (dynamic description) != [initial_desc] (initial description)") diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index 404ede1cca0b8..77eaeba11140f 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -225,9 +225,13 @@ category = /datum/uplink_category/discounts purchasable_from = parent_type::purchasable_from & ~UPLINK_SPY // Probably not necessary but just in case +/datum/uplink_category/objective_special + name = "Objective-Specific Equipment" + weight = -3 + // Special equipment (Dynamically fills in uplink component) /datum/uplink_item/special_equipment - category = "Objective-Specific Equipment" + category = /datum/uplink_category/objective_special name = "Objective-Specific Equipment" desc = "Equipment necessary for accomplishing specific objectives. If you are seeing this, something has gone wrong." limited_stock = 1 diff --git a/code/modules/vehicles/secway.dm b/code/modules/vehicles/secway.dm index 6726fb02ef150..ab366da4b283e 100644 --- a/code/modules/vehicles/secway.dm +++ b/code/modules/vehicles/secway.dm @@ -101,5 +101,5 @@ if(!buckled_mobs || prob(40)) return ..() for(var/mob/rider as anything in buckled_mobs) - rider.bullet_act(P) - return TRUE + return rider.bullet_act(P) + return ..() diff --git a/code/modules/wiremod/components/action/laserpointer.dm b/code/modules/wiremod/components/action/laserpointer.dm index 0eb7f822db1ea..8693a5c1ab18b 100644 --- a/code/modules/wiremod/components/action/laserpointer.dm +++ b/code/modules/wiremod/components/action/laserpointer.dm @@ -11,8 +11,8 @@ /// The input port var/datum/port/input/target_input - var/datum/port/input/image_pixel_x = 0 - var/datum/port/input/image_pixel_y = 0 + var/datum/port/input/image_pixel_x + var/datum/port/input/image_pixel_y var/max_range = 7 diff --git a/code/modules/wiremod/components/admin/getvar.dm b/code/modules/wiremod/components/admin/getvar.dm index 2fe8f18b09e3d..e467963fe345b 100644 --- a/code/modules/wiremod/components/admin/getvar.dm +++ b/code/modules/wiremod/components/admin/getvar.dm @@ -45,7 +45,7 @@ output_value.set_datatype(expected_output_type.value) /obj/item/circuit_component/get_variable/input_received(datum/port/input/port) - var/atom/object = entity?.value + var/datum/object = entity?.value if(getvar_options.value == "Global") object = GLOB From 859f9c228260c4b30ccde382b1c101a4d5aa0d91 Mon Sep 17 00:00:00 2001 From: Jerry <55355646+Jewelry-x@users.noreply.github.com> Date: Tue, 19 Nov 2024 20:27:43 +0000 Subject: [PATCH 210/222] Remove non-functioning and
for changeling victim's memories (#87650) ## About The Pull Request This PR removes the `` and `
` from changeling memories since they did not function at all and ruined immersion. * Closes https://github.com/tgstation/tgstation/issues/84586 Before: ![345110418-fa95f4ba-d26a-47f5-bc5e-4d23454bb066](https://github.com/user-attachments/assets/11fd72d5-472b-468b-af2b-4fafe7c83ae8) After: ![image](https://github.com/user-attachments/assets/a07691e6-fb2a-40e0-8f2b-17826bbe8b14) ## Why It's Good For The Game Remove immersion breaking text. ## Changelog :cl: fix: changeling memories of victims no longer include `` and `
` /:cl: --- code/modules/antagonists/changeling/powers/absorb.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm index 71b1509ec816c..167371b4d675d 100644 --- a/code/modules/antagonists/changeling/powers/absorb.dm +++ b/code/modules/antagonists/changeling/powers/absorb.dm @@ -106,12 +106,12 @@ var/list/recent_speech = target.copy_recent_speech() if(recent_speech.len) - changeling.antag_memory += "Some of [target]'s speech patterns, we should study these to better impersonate [target.p_them()]!
" + changeling.antag_memory += "Some of [target]'s speech patterns, we should study these to better impersonate [target.p_them()]: " to_chat(owner, span_boldnotice("Some of [target]'s speech patterns, we should study these to better impersonate [target.p_them()]!")) for(var/spoken_memory in recent_speech) - changeling.antag_memory += "\"[spoken_memory]\"
" + changeling.antag_memory += " \"[spoken_memory]\"" to_chat(owner, span_notice("\"[spoken_memory]\"")) - changeling.antag_memory += "We have no more knowledge of [target]'s speech patterns.
" + changeling.antag_memory += ". We have no more knowledge of [target]'s speech patterns. " to_chat(owner, span_boldnotice("We have no more knowledge of [target]'s speech patterns.")) From 0a36d42160df3c1f142517beb00c5ee4d5d48d9c Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 20:28:05 +0000 Subject: [PATCH 211/222] Automatic changelog for PR #87650 [ci skip] --- html/changelogs/AutoChangeLog-pr-87650.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87650.yml diff --git a/html/changelogs/AutoChangeLog-pr-87650.yml b/html/changelogs/AutoChangeLog-pr-87650.yml new file mode 100644 index 0000000000000..332972460ba70 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87650.yml @@ -0,0 +1,4 @@ +author: "Jewelry-x" +delete-after: True +changes: + - bugfix: "changeling memories of victims no longer include `` and `
`" \ No newline at end of file From 4f6ef1cde52bcf87e15bf0285ee3f606d5f3e982 Mon Sep 17 00:00:00 2001 From: grungussuss <96586172+Sadboysuss@users.noreply.github.com> Date: Wed, 20 Nov 2024 01:02:50 +0300 Subject: [PATCH 212/222] fixes master (#88032) ## About The Pull Request it's purchase path ## Changelog :cl: grungussuss fix: a bug regarding orderable items has been fixed /:cl: --- _maps/map_files/NebulaStation/NebulaStation.dmm | 2 +- .../computer/orders/order_items/cook/order_milk_eggs.dm | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_maps/map_files/NebulaStation/NebulaStation.dmm b/_maps/map_files/NebulaStation/NebulaStation.dmm index 9fcaa3cb5b314..fc9b1b99823b4 100644 --- a/_maps/map_files/NebulaStation/NebulaStation.dmm +++ b/_maps/map_files/NebulaStation/NebulaStation.dmm @@ -108959,7 +108959,7 @@ /turf/open/floor/iron/dark, /area/station/hallway/primary/port) "qfy" = ( -/mob/living/simple_animal/bot/floorbot, +/mob/living/basic/bot/repairbot, /obj/effect/turf_decal/bot_white, /obj/machinery/status_display/ai/directional/east, /turf/open/floor/iron/dark/textured_large, diff --git a/code/game/machinery/computer/orders/order_items/cook/order_milk_eggs.dm b/code/game/machinery/computer/orders/order_items/cook/order_milk_eggs.dm index 8ec5e9a53a80c..e53d595c4982a 100644 --- a/code/game/machinery/computer/orders/order_items/cook/order_milk_eggs.dm +++ b/code/game/machinery/computer/orders/order_items/cook/order_milk_eggs.dm @@ -112,12 +112,12 @@ /datum/orderable_item/milk_eggs/ready_donk_salisbury name = "Ready-Donk Meal: Donkriginals Salisbury Steak" - item_path = /obj/item/food/ready_donk/salisbury_steak + purchase_path = /obj/item/food/ready_donk/salisbury_steak cost_per_order = 40 /datum/orderable_item/milk_eggs/ready_donk_chicken name = "Ready-Donk Meal: Donkriginals Country-Fried Chicken" - item_path = /obj/item/food/ready_donk/country_chicken + purchase_path = /obj/item/food/ready_donk/country_chicken cost_per_order = 40 /datum/orderable_item/milk_eggs/tiziran_goods From 290b8448c604366b222bec54b5444ca2a4949554 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 22:05:03 +0000 Subject: [PATCH 213/222] Automatic changelog for PR #88032 [ci skip] --- html/changelogs/AutoChangeLog-pr-88032.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-88032.yml diff --git a/html/changelogs/AutoChangeLog-pr-88032.yml b/html/changelogs/AutoChangeLog-pr-88032.yml new file mode 100644 index 0000000000000..cf21ab2cfc0c8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-88032.yml @@ -0,0 +1,4 @@ +author: "grungussuss" +delete-after: True +changes: + - bugfix: "a bug regarding orderable items has been fixed" \ No newline at end of file From 048a0292344f988a130cd129885847d272a91e35 Mon Sep 17 00:00:00 2001 From: Hatterhat <31829017+Hatterhat@users.noreply.github.com> Date: Tue, 19 Nov 2024 18:07:07 -0600 Subject: [PATCH 214/222] crate chaos crate position randomizes again (#88011) ## About The Pull Request moves the crate chaos randomizer marker to the far corner of the domain. this fixes the crate always spawning in one place, somehow. running theory is that the map didn't initialize enough before the crate randomizer was placed, so it never found the encrypted crate so it could never randomize its position. moving it to the corner makes it so it only loads after most of the map does, so it can shuffle the crate around. i tested it ![image](https://github.com/user-attachments/assets/82861120-9375-4800-8c58-008916391903) ## Why It's Good For The Game woe, bitrunners must now interact with the map gimmick again ## Changelog :cl: fix: Crate Chaos's encrypted cache is now randomly placed again. /:cl: Co-authored-by: Hatterhat --- _maps/virtual_domains/psyker_shuffle.dmm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_maps/virtual_domains/psyker_shuffle.dmm b/_maps/virtual_domains/psyker_shuffle.dmm index c3434167bb18f..c744cecf0b430 100644 --- a/_maps/virtual_domains/psyker_shuffle.dmm +++ b/_maps/virtual_domains/psyker_shuffle.dmm @@ -246,7 +246,7 @@ Y Q Q Q -i +Q Y o o @@ -848,7 +848,7 @@ o "} (26,1,1) = {" Y -Q +i Q Q Q From baf8289ba2c084e6e9865aee807f2bdc479e1ff8 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 00:07:27 +0000 Subject: [PATCH 215/222] Automatic changelog for PR #88011 [ci skip] --- html/changelogs/AutoChangeLog-pr-88011.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-88011.yml diff --git a/html/changelogs/AutoChangeLog-pr-88011.yml b/html/changelogs/AutoChangeLog-pr-88011.yml new file mode 100644 index 0000000000000..59ff34d50d83a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-88011.yml @@ -0,0 +1,4 @@ +author: "Hatterhat" +delete-after: True +changes: + - bugfix: "Crate Chaos's encrypted cache is now randomly placed again." \ No newline at end of file From 542bf1afaa69df66967a574f2a3fc7c6acadb2d7 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 00:29:51 +0000 Subject: [PATCH 216/222] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-86084.yml | 5 --- html/changelogs/AutoChangeLog-pr-87650.yml | 4 --- html/changelogs/AutoChangeLog-pr-87904.yml | 7 ----- html/changelogs/AutoChangeLog-pr-87968.yml | 4 --- html/changelogs/AutoChangeLog-pr-87976.yml | 4 --- html/changelogs/AutoChangeLog-pr-87983.yml | 5 --- html/changelogs/AutoChangeLog-pr-88003.yml | 4 --- html/changelogs/AutoChangeLog-pr-88011.yml | 4 --- html/changelogs/AutoChangeLog-pr-88016.yml | 4 --- html/changelogs/AutoChangeLog-pr-88018.yml | 5 --- html/changelogs/AutoChangeLog-pr-88019.yml | 4 --- html/changelogs/AutoChangeLog-pr-88032.yml | 4 --- html/changelogs/archive/2024-11.yml | 36 ++++++++++++++++++++++ 13 files changed, 36 insertions(+), 54 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-86084.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87650.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87904.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87968.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87976.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-87983.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88003.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88011.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88016.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88018.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88019.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-88032.yml diff --git a/html/changelogs/AutoChangeLog-pr-86084.yml b/html/changelogs/AutoChangeLog-pr-86084.yml deleted file mode 100644 index 6baf5b4ba8a72..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-86084.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Ben10Omintrix" -delete-after: True -changes: - - refactor: "floorbots have been refactored, please report any bugs" - - rscadd: "adds repairbots to the game!" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87650.yml b/html/changelogs/AutoChangeLog-pr-87650.yml deleted file mode 100644 index 332972460ba70..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87650.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Jewelry-x" -delete-after: True -changes: - - bugfix: "changeling memories of victims no longer include `` and `
`" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87904.yml b/html/changelogs/AutoChangeLog-pr-87904.yml deleted file mode 100644 index 1b32efd644ec9..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87904.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: "Melbert" -delete-after: True -changes: - - balance: "Having a broken arm affects your accuracy with ranged weapons fired with that arm. Utilizing a painkiller will nullify this effect, however." - - balance: "Painkillers will prevent your punches from being cancelled due to having a broken arm. You'll still take damage, though." - - balance: "Being drunk now affects your accuracy with ranged weapon. The bartender is immune to this effect via their skillchip." - - code_imp: "A lot of code involving left and right hand handling has been cleaned up, easier to read. Report any oddities, like left and rights being flipped" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87968.yml b/html/changelogs/AutoChangeLog-pr-87968.yml deleted file mode 100644 index 4b4ea2da2ec4b..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87968.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Dmeto" -delete-after: True -changes: - - map: "removes a unused disposal pipe from Cargo, fixes mining dock intercom.\nmap:adds access helper to disposals south airlock." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87976.yml b/html/changelogs/AutoChangeLog-pr-87976.yml deleted file mode 100644 index 61fe8a3b4a247..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87976.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Dawnseer" -delete-after: True -changes: - - rscadd: "Unleashed a great evil upon hoplines, in the form of a paperwork implant." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87983.yml b/html/changelogs/AutoChangeLog-pr-87983.yml deleted file mode 100644 index 5686574f8f65f..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87983.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "grungussuss" -delete-after: True -changes: - - server: "drone area restrictions are now config" - - balance: "drones now take less time to become \"un-shy\" of something after it's been touched." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88003.yml b/html/changelogs/AutoChangeLog-pr-88003.yml deleted file mode 100644 index 9ed69c869a2fc..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88003.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "EnterTheJake" -delete-after: True -changes: - - bugfix: "FIxes insulated modsuits not granting full insulation." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88011.yml b/html/changelogs/AutoChangeLog-pr-88011.yml deleted file mode 100644 index 59ff34d50d83a..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88011.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Hatterhat" -delete-after: True -changes: - - bugfix: "Crate Chaos's encrypted cache is now randomly placed again." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88016.yml b/html/changelogs/AutoChangeLog-pr-88016.yml deleted file mode 100644 index 5d034f67affa7..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88016.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "grungussuss" -delete-after: True -changes: - - bugfix: "mobs can no longer hear their own breathing while deaf" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88018.yml b/html/changelogs/AutoChangeLog-pr-88018.yml deleted file mode 100644 index cebd1d3d58dc3..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88018.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "larentoun" -delete-after: True -changes: - - bugfix: "Mafia: Psych's reveal ability now correctly has a single use" - - bugfix: "Mafia: Fugitive's vest ability now correctly should have two uses" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88019.yml b/html/changelogs/AutoChangeLog-pr-88019.yml deleted file mode 100644 index d8d385545f185..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88019.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Gaxeer" -delete-after: True -changes: - - bugfix: "AI controlled monkeys can again activate items in active hand" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88032.yml b/html/changelogs/AutoChangeLog-pr-88032.yml deleted file mode 100644 index cf21ab2cfc0c8..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88032.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "grungussuss" -delete-after: True -changes: - - bugfix: "a bug regarding orderable items has been fixed" \ No newline at end of file diff --git a/html/changelogs/archive/2024-11.yml b/html/changelogs/archive/2024-11.yml index 3224f148e8b48..61fd21d9b4c51 100644 --- a/html/changelogs/archive/2024-11.yml +++ b/html/changelogs/archive/2024-11.yml @@ -678,3 +678,39 @@ - bugfix: Haunted 8-ball UI now correctly displays your selected answer - qol: Made the haunted 8-ball UI look a pinch better. Just a smidge. - code_imp: Haunted 8-balls no longer use a duplicate answer list +2024-11-20: + Ben10Omintrix: + - refactor: floorbots have been refactored, please report any bugs + - rscadd: adds repairbots to the game! + Dawnseer: + - rscadd: Unleashed a great evil upon hoplines, in the form of a paperwork implant. + Dmeto: + - map: 'removes a unused disposal pipe from Cargo, fixes mining dock intercom. + + map:adds access helper to disposals south airlock.' + EnterTheJake: + - bugfix: FIxes insulated modsuits not granting full insulation. + Gaxeer: + - bugfix: AI controlled monkeys can again activate items in active hand + Hatterhat: + - bugfix: Crate Chaos's encrypted cache is now randomly placed again. + Jewelry-x: + - bugfix: changeling memories of victims no longer include `` and `
` + Melbert: + - balance: Having a broken arm affects your accuracy with ranged weapons fired with + that arm. Utilizing a painkiller will nullify this effect, however. + - balance: Painkillers will prevent your punches from being cancelled due to having + a broken arm. You'll still take damage, though. + - balance: Being drunk now affects your accuracy with ranged weapon. The bartender + is immune to this effect via their skillchip. + - code_imp: A lot of code involving left and right hand handling has been cleaned + up, easier to read. Report any oddities, like left and rights being flipped + grungussuss: + - bugfix: mobs can no longer hear their own breathing while deaf + - bugfix: a bug regarding orderable items has been fixed + - server: drone area restrictions are now config + - balance: drones now take less time to become "un-shy" of something after it's + been touched. + larentoun: + - bugfix: 'Mafia: Psych''s reveal ability now correctly has a single use' + - bugfix: 'Mafia: Fugitive''s vest ability now correctly should have two uses' From 33d5ade6f3c734c2c1263d17d01fb356fd32aad9 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Wed, 20 Nov 2024 03:36:31 +0300 Subject: [PATCH 217/222] Revert "implements hair masking for some hats (#87940)" (#88007) ## About The Pull Request The original PR wasn't ready to merge. Berets need their own masks, otherwise you can see naked scalp poking from underneath them. Will probably PR proper masks a bit later. Closes #87991 ## Changelog :cl: fix: Berets no longer make you go bald above your earline. /:cl: --- code/modules/clothing/head/frenchberet.dm | 1 - code/modules/clothing/head/jobs.dm | 11 ----------- code/modules/clothing/head/soft_caps.dm | 4 ---- 3 files changed, 16 deletions(-) diff --git a/code/modules/clothing/head/frenchberet.dm b/code/modules/clothing/head/frenchberet.dm index ffd0cc81668ad..de63c6fddfdd1 100644 --- a/code/modules/clothing/head/frenchberet.dm +++ b/code/modules/clothing/head/frenchberet.dm @@ -5,7 +5,6 @@ greyscale_config = /datum/greyscale_config/beret greyscale_config_worn = /datum/greyscale_config/beret/worn greyscale_colors = "#972A2A" - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW /obj/item/clothing/head/frenchberet/Initialize(mapload) . = ..() diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index f643b5cb72658..640867a7c9334 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -17,7 +17,6 @@ var/mouse_control_probability = 20 /// Allowed time between movements COOLDOWN_DECLARE(move_cooldown) - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW /// Admin variant of the chef hat where every mouse pilot input will always be transferred to the wearer /obj/item/clothing/head/utility/chefhat/i_am_assuming_direct_control @@ -104,7 +103,6 @@ armor_type = /datum/armor/hats_caphat strip_delay = 60 dog_fashion = /datum/dog_fashion/head/captain - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW //Captain: This is no longer space-worthy /datum/armor/hats_caphat @@ -122,7 +120,6 @@ desc = "Worn only by Captains with an abundance of class." icon_state = "capcap" dog_fashion = null - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW /obj/item/clothing/head/caphat/beret name = "captain's beret" @@ -131,7 +128,6 @@ greyscale_config = /datum/greyscale_config/beret_badge greyscale_config_worn = /datum/greyscale_config/beret_badge/worn greyscale_colors = "#0070B7#FFCE5B" - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW //Head of Personnel /obj/item/clothing/head/hats/hopcap @@ -140,7 +136,6 @@ desc = "The symbol of true bureaucratic micromanagement." armor_type = /datum/armor/hats_hopcap dog_fashion = /datum/dog_fashion/head/hop - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW //Chaplain /datum/armor/hats_hopcap @@ -186,7 +181,6 @@ var/flask_path = /obj/item/reagent_containers/cup/glass/flask/det /// Cooldown for retrieving precious candy corn with rmb COOLDOWN_DECLARE(candy_cooldown) - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW /datum/armor/fedora_det_hat @@ -260,7 +254,6 @@ var/max_items = 4 ///items above this weight cannot be put in the hat var/max_weight = WEIGHT_CLASS_NORMAL - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW /obj/item/clothing/head/fedora/inspector_hat/Initialize(mapload) . = ..() @@ -399,7 +392,6 @@ greyscale_config_worn = /datum/greyscale_config/beret/worn greyscale_colors = "#972A2A" flags_1 = IS_PLAYER_COLORABLE_1 - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW //Security /obj/item/clothing/head/hats/hos @@ -407,7 +399,6 @@ desc = "Please contact the Nanotrasen Costuming Department if found." armor_type = /datum/armor/hats_hos strip_delay = 8 SECONDS - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW /obj/item/clothing/head/hats/hos/cap name = "head of security cap" @@ -473,7 +464,6 @@ armor_type = /datum/armor/hats_warden strip_delay = 60 dog_fashion = /datum/dog_fashion/head/warden - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW /datum/armor/hats_warden melee = 40 @@ -626,7 +616,6 @@ name = "chief medical officer beret" desc = "A beret in a distinct surgical turquoise!" greyscale_colors = "#5EB8B8" - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW /obj/item/clothing/head/utility/surgerycap name = "blue surgery cap" diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm index d05fbe1cc35f0..a25a8eb3ca902 100644 --- a/code/modules/clothing/head/soft_caps.dm +++ b/code/modules/clothing/head/soft_caps.dm @@ -136,7 +136,6 @@ armor_type = /datum/armor/cosmetic_sec strip_delay = 60 dog_fashion = null - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW /obj/item/clothing/head/soft/veteran name = "veteran cap" @@ -146,7 +145,6 @@ armor_type = /datum/armor/cosmetic_sec strip_delay = 60 dog_fashion = null - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW /obj/item/clothing/head/soft/paramedic name = "paramedic cap" @@ -154,7 +152,6 @@ icon_state = "paramedicsoft" soft_type = "paramedic" dog_fashion = null - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW /obj/item/clothing/head/soft/fishing_hat name = "legendary fishing hat" @@ -173,7 +170,6 @@ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE dog_fashion = null clothing_traits = list(TRAIT_SCARY_FISHERMAN) //Fish, carps, lobstrosities and frogs fear me. - hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_LOW /obj/item/clothing/head/soft/fishing_hat/Initialize(mapload) . = ..() From 1df0b90e65e4f5f46ec4d4380fca463257cb2bfb Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 00:42:15 +0000 Subject: [PATCH 218/222] Automatic changelog for PR #88007 [ci skip] --- html/changelogs/AutoChangeLog-pr-88007.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-88007.yml diff --git a/html/changelogs/AutoChangeLog-pr-88007.yml b/html/changelogs/AutoChangeLog-pr-88007.yml new file mode 100644 index 0000000000000..e0edf1ba61878 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-88007.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Berets no longer make you go bald above your earline." \ No newline at end of file From ee271daf4648129c2b8d51d850e7fb6f3b8db595 Mon Sep 17 00:00:00 2001 From: jimmyl <70376633+mc-oofert@users.noreply.github.com> Date: Wed, 20 Nov 2024 02:07:05 +0100 Subject: [PATCH 219/222] clickable alerts glow + the slimed status effect now actually tells you how to get it off without water in the description (#87902) ## About The Pull Request clickable alerts glow (regex: /atom/movable/screen/alert/.*/Click) ## Why It's Good For The Game people are much more likely to look at the chat or anywhere else than the status effect (really, its usually never worth reading 99% of them so they end up ignored) ## Changelog :cl: qol: alerts that do stuff when clicked glow gold /:cl: --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> --- code/_onclick/hud/alert.dm | 20 +++++++++++++++++++ code/datums/status_effects/debuffs/debuffs.dm | 1 + code/datums/status_effects/debuffs/hooked.dm | 1 + .../status_effects/debuffs/slime/slimed.dm | 1 + .../status_effects/debuffs/strandling.dm | 1 + code/datums/status_effects/neutral.dm | 2 ++ code/modules/bitrunning/alerts.dm | 1 + code/modules/mod/mod_link.dm | 1 + .../spell_types/shapeshift/_shape_status.dm | 1 + 9 files changed, 29 insertions(+) diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 5eaff57b6096d..c3fb19352ab05 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -107,6 +107,8 @@ name = "Alert" desc = "Something seems to have gone wrong with this alert, so report this bug please" mouse_opacity = MOUSE_OPACITY_ICON + /// do we glow to represent we do stuff when clicked + var/clickable_glow = FALSE var/timeout = 0 //If set to a number, this alert will clear itself after that many deciseconds var/severity = 0 var/alerttooltipstyle = "" @@ -116,6 +118,10 @@ /// Boolean. If TRUE, the Click() proc will attempt to Click() on the master first if there is a master. var/click_master = TRUE +/atom/movable/screen/alert/Initialize(mapload, datum/hud/hud_owner) + . = ..() + if(clickable_glow) + add_filter("clickglow", 2, outline_filter(color = COLOR_GOLD, size = 1)) /atom/movable/screen/alert/MouseEntered(location,control,params) . = ..() @@ -237,6 +243,7 @@ name = "Mind Control" desc = "Your mind has been hijacked! Click to view the mind control command." icon_state = ALERT_MIND_CONTROL + clickable_glow = TRUE var/command /atom/movable/screen/alert/mind_control/Click() @@ -250,6 +257,7 @@ desc = "Something got lodged into your flesh and is causing major bleeding. It might fall out with time, but surgery is the safest way. \ If you're feeling frisky, examine yourself and click the underlined item to pull the object out." icon_state = ALERT_EMBEDDED_OBJECT + clickable_glow = TRUE /atom/movable/screen/alert/embeddedobject/Click() . = ..() @@ -287,6 +295,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." name = "On Fire" desc = "You're on fire. Stop, drop and roll to put the fire out or move to a vacuum area." icon_state = "fire" + clickable_glow = TRUE /atom/movable/screen/alert/fire/Click() . = ..() @@ -305,6 +314,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." /atom/movable/screen/alert/give // information set when the give alert is made icon_state = "default" + clickable_glow = TRUE /// The offer we're linked to, yes this is suspiciously like a status effect alert var/datum/status_effect/offering/offer /// Additional text displayed in the description of the alert. @@ -476,6 +486,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." name = "Succumb" desc = "Shuffle off this mortal coil." icon_state = ALERT_SUCCUMB + clickable_glow = TRUE var/static/list/death_titles = list( "Goodnight, Sweet Prince", "Game Over, Man", @@ -811,6 +822,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." additional processing time to unlock more malfunction abilities." icon_state = ALERT_HACKING_APC timeout = 60 SECONDS + clickable_glow = TRUE var/atom/target = null /atom/movable/screen/alert/hackingapc/Click() @@ -838,6 +850,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." desc = "Someone is trying to revive you. Re-enter your corpse if you want to be revived!" icon_state = "template" timeout = 300 + clickable_glow = TRUE /atom/movable/screen/alert/revival/Click() . = ..() @@ -851,6 +864,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." desc = "This can be clicked on to perform an action." icon_state = "template" timeout = 30 SECONDS + clickable_glow = TRUE /// Weakref to the target atom to use the action on var/datum/weakref/target_ref /// If we want to interact on click rather than jump/orbit @@ -1028,6 +1042,10 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." name = "Buckled" desc = "You've been buckled to something. Click the alert to unbuckle unless you're handcuffed." icon_state = ALERT_BUCKLED + clickable_glow = TRUE + +/atom/movable/screen/alert/restrained + clickable_glow = TRUE /atom/movable/screen/alert/restrained/handcuffed name = "Handcuffed" @@ -1075,6 +1093,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." name = "Knotted Shoes" desc = "Someone tied your shoelaces together! Click the alert or your shoes to undo the knot." icon_state = ALERT_SHOES_KNOT + clickable_glow = TRUE /atom/movable/screen/alert/shoes/Click() . = ..() @@ -1093,6 +1112,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." name = "Unpossess" desc = "You are possessing an object. Click this alert to unpossess it." icon_state = "buckled" + clickable_glow = TRUE /atom/movable/screen/alert/unpossess_object/Click() . = ..() diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index 3cf51d34c48d7..25c133e46d14a 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -874,6 +874,7 @@ name = "Ants!" desc = span_warning("JESUS FUCKING CHRIST! CLICK TO GET THOSE THINGS OFF!") icon_state = "antalert" + clickable_glow = TRUE /atom/movable/screen/alert/status_effect/ants/Click() . = ..() diff --git a/code/datums/status_effects/debuffs/hooked.dm b/code/datums/status_effects/debuffs/hooked.dm index d7fcb2b1821dd..8d160305b54f5 100644 --- a/code/datums/status_effects/debuffs/hooked.dm +++ b/code/datums/status_effects/debuffs/hooked.dm @@ -29,6 +29,7 @@ name = "Snagged By Hook" desc = "You're being caught like a fish by some asshat! Click to safely remove the hook or move away far enough to snap it off." icon_state = "hooked" + clickable_glow = TRUE /atom/movable/screen/alert/status_effect/hooked/Click() . = ..() diff --git a/code/datums/status_effects/debuffs/slime/slimed.dm b/code/datums/status_effects/debuffs/slime/slimed.dm index 2540c4df5136c..6cd107c74a9d8 100644 --- a/code/datums/status_effects/debuffs/slime/slimed.dm +++ b/code/datums/status_effects/debuffs/slime/slimed.dm @@ -7,6 +7,7 @@ name = "Covered in Slime" desc = "You are covered in slime and it's eating away at you! Click to start cleaning it off, or find a faster way to wash it away!" icon_state = "slimed" + clickable_glow = TRUE /atom/movable/screen/alert/status_effect/slimed/Click() . = ..() diff --git a/code/datums/status_effects/debuffs/strandling.dm b/code/datums/status_effects/debuffs/strandling.dm index 0ce0ad4188221..d37961c13c903 100644 --- a/code/datums/status_effects/debuffs/strandling.dm +++ b/code/datums/status_effects/debuffs/strandling.dm @@ -88,6 +88,7 @@ desc = "Strands of Durathread are wrapped around your neck, preventing you from breathing! Click this icon to remove the strand." icon_state = "his_grace" alerttooltipstyle = "hisgrace" + clickable_glow = TRUE /atom/movable/screen/alert/status_effect/strandling/Click(location, control, params) . = ..() diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm index b2869b6a30e3a..43c4ad7a3f09a 100644 --- a/code/datums/status_effects/neutral.dm +++ b/code/datums/status_effects/neutral.dm @@ -176,6 +176,7 @@ name = "Holding Up" desc = "You're currently pointing a gun at someone. Click to cancel." icon_state = "aimed" + clickable_glow = TRUE /atom/movable/screen/alert/status_effect/holdup/Click(location, control, params) . = ..() @@ -358,6 +359,7 @@ name = "Surrender" desc = "Looks like you're in trouble now, bud. Click here to surrender. (Warning: You will be incapacitated.)" icon_state = "surrender" + clickable_glow = TRUE /atom/movable/screen/alert/status_effect/surrender/Click(location, control, params) . = ..() diff --git a/code/modules/bitrunning/alerts.dm b/code/modules/bitrunning/alerts.dm index 54738b594c22d..478ae3c04cbd3 100644 --- a/code/modules/bitrunning/alerts.dm +++ b/code/modules/bitrunning/alerts.dm @@ -7,6 +7,7 @@ name = "Domain Completed" desc = "The domain is completed. Activate to exit." timeout = 20 SECONDS + clickable_glow = TRUE /atom/movable/screen/alert/bitrunning/qserver_domain_complete/Click(location, control, params) . = ..() diff --git a/code/modules/mod/mod_link.dm b/code/modules/mod/mod_link.dm index 0750c3c41be26..a93ebec8b570c 100644 --- a/code/modules/mod/mod_link.dm +++ b/code/modules/mod/mod_link.dm @@ -511,6 +511,7 @@ desc = "Someone is calling you! Left-click this to accept the call. Right-click to deny it." icon_state = "called" timeout = 10 SECONDS + clickable_glow = TRUE var/end_message = "call timed out!" /// A weak reference to the MODlink that is calling. var/datum/weakref/caller_ref diff --git a/code/modules/spells/spell_types/shapeshift/_shape_status.dm b/code/modules/spells/spell_types/shapeshift/_shape_status.dm index f8f44817a5932..9e1284d27f60c 100644 --- a/code/modules/spells/spell_types/shapeshift/_shape_status.dm +++ b/code/modules/spells/spell_types/shapeshift/_shape_status.dm @@ -243,6 +243,7 @@ desc = "Your form is not your own... you're shapeshifted into another creature! \ A wizard could turn you back - or maybe you're stuck like this for good?" icon_state = "shapeshifted" + clickable_glow = TRUE /atom/movable/screen/alert/status_effect/shapeshifted/Click(location, control, params) . = ..() From f83d741b719a744f9310943c34b4fb08e6560c86 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 01:07:27 +0000 Subject: [PATCH 220/222] Automatic changelog for PR #87902 [ci skip] --- html/changelogs/AutoChangeLog-pr-87902.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-87902.yml diff --git a/html/changelogs/AutoChangeLog-pr-87902.yml b/html/changelogs/AutoChangeLog-pr-87902.yml new file mode 100644 index 0000000000000..fd16ccdeafb71 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87902.yml @@ -0,0 +1,4 @@ +author: "mc-oofert" +delete-after: True +changes: + - qol: "alerts that do stuff when clicked glow gold" \ No newline at end of file From ee16f1fccc27024c4bcd93091ebd27ff66c6e6e0 Mon Sep 17 00:00:00 2001 From: tonty <39193182+tontyGH@users.noreply.github.com> Date: Tue, 19 Nov 2024 20:12:22 -0500 Subject: [PATCH 221/222] Everything uses trim(), trim returns "" if empty, removes the SDQL2 trimtext (#87994) ## About The Pull Request Title. I may have been wrong about how depended on this behaviour was Also, uh, fixes #87986 ## Why It's Good For The Game trim_reduced no longer needs to exist because trimtext() does it faster, and there's no reason to have a special proc if trim just calls that proc anyways. I sincerely doubt the proc overhead is so severe that we need another proc that will ever only be called directly 3 times in the code. Since trimtext() does something we don't expect, it's better to just have SDQL2 queries use trim() so we're all on the same page. ## Changelog NO!!! --- code/__HELPERS/text.dm | 4 ++-- code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm | 3 --- code/modules/mapping/reader.dm | 6 +++--- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 0232b64bf461f..989b45976f227 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -270,7 +270,7 @@ if(!filter_name_ic(trimmed)) // Contains IC chat prohibited words return - return trimtext(trimmed) + return trim(trimmed) /// Helper proc to check if a name is valid for the IC filter @@ -357,7 +357,7 @@ /proc/trim(text, max_length) if(max_length) text = copytext_char(text, 1, max_length) - return trimtext(text) + return trimtext(text) || "" //users expect atleast an empty string //Returns a string with the first element of the string capitalized. /proc/capitalize(t) diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm index 4da97d2c447bf..1305e5a660d6e 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm @@ -117,9 +117,6 @@ /proc/_text2num(T) return text2num(T) -/proc/_trimtext(Text) - return trimtext(Text) - /proc/_ohearers(Dist, Center = usr) return ohearers(Dist, Center) diff --git a/code/modules/mapping/reader.dm b/code/modules/mapping/reader.dm index bca2ace626062..10d506f8c48e5 100644 --- a/code/modules/mapping/reader.dm +++ b/code/modules/mapping/reader.dm @@ -839,7 +839,7 @@ GLOBAL_LIST_EMPTY(map_model_default) if(member_string[length(member_string)] == "}") variables_start = findtext(member_string, "{") - var/path_text = trimtext(copytext(member_string, 1, variables_start)) + var/path_text = trim(copytext(member_string, 1, variables_start)) var/atom_def = text2path(path_text) //path definition, e.g /obj/foo/bar if(!ispath(atom_def, /atom)) // Skip the item if the path does not exist. Fix your crap, mappers! @@ -1011,7 +1011,7 @@ GLOBAL_LIST_EMPTY(map_model_default) // check if this is a simple variable (as in list(var1, var2)) or an associative one (as in list(var1="foo",var2=7)) var/equal_position = findtext(text,"=",old_position, position) - var/trim_left = trimtext(copytext(text,old_position,(equal_position ? equal_position : position))) + var/trim_left = trim(copytext(text,old_position,(equal_position ? equal_position : position))) var/left_constant = parse_constant(trim_left) if(position) old_position = position + length(text[position]) @@ -1021,7 +1021,7 @@ GLOBAL_LIST_EMPTY(map_model_default) if(equal_position && !isnum(left_constant)) // Associative var, so do the association. // Note that numbers cannot be keys - the RHS is dropped if so. - var/trim_right = trimtext(copytext(text, equal_position + length(text[equal_position]), position)) + var/trim_right = trim(copytext(text, equal_position + length(text[equal_position]), position)) var/right_constant = parse_constant(trim_right) .[left_constant] = right_constant else // simple var From 9840c618ad42e24056099bac134a56af7dc67e4a Mon Sep 17 00:00:00 2001 From: Paxilmaniac Date: Tue, 19 Nov 2024 21:15:38 -0600 Subject: [PATCH 222/222] 1 --- modular_doppler/modular_quirks/entombed/code/entombed_mod.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_doppler/modular_quirks/entombed/code/entombed_mod.dm b/modular_doppler/modular_quirks/entombed/code/entombed_mod.dm index 34142ba6bdcc7..b1f77adeffbcf 100644 --- a/modular_doppler/modular_quirks/entombed/code/entombed_mod.dm +++ b/modular_doppler/modular_quirks/entombed/code/entombed_mod.dm @@ -110,7 +110,7 @@ who.balloon_alert(who, "can't strip a fused MODsuit!") return ..() -/obj/item/mod/control/pre_equipped/entombed/retract(mob/user, obj/item/part) +/obj/item/mod/control/pre_equipped/entombed/retract(mob/user, obj/item/part, instant = FALSE) if (ishuman(user)) var/mob/living/carbon/human/human_user = user var/datum/quirk/equipping/entombed/tomb_quirk = human_user.get_quirk(/datum/quirk/equipping/entombed)