From 530dcdeb70d27f7165fe193835d7a7a683d18c11 Mon Sep 17 00:00:00 2001 From: Finket Date: Mon, 6 Nov 2023 13:55:38 +0200 Subject: [PATCH 01/59] Port PR42 files directly --- Content.Client/Chat/Managers/ChatManager.cs | 7 +- .../Chat/ShadowkinChatUpdateSystem.cs | 33 +++ .../Overlays/Shaders/ColorTintOverlay.cs | 61 ++++ .../Overlays/Shaders/EtherealOverlay.cs | 37 +++ .../IgnoreHumanoidWithComponentOverlay.cs | 96 ++++++ .../ShadowkinPowerSystem.DarkSwapped.cs | 74 +++++ .../Systems/ShadowkinSystem.Blackeye.cs | 51 ++++ .../Shadowkin/Systems/ShadowkinSystem.Tint.cs | 111 +++++++ .../Systems/Chat/ChatUIController.cs | 20 +- .../Chat/Controls/ChannelFilterPopup.xaml.cs | 1 + .../Chat/Controls/ChannelSelectorButton.cs | 3 +- .../Chat/Controls/ChannelSelectorPopup.cs | 3 +- Content.Server/Chat/Systems/ChatSystem.cs | 11 +- Content.Server/Magic/MagicSystem.cs | 2 +- .../SimpleStation14/Chat/ESayCommand.cs | 43 +++ .../Chat/SimpleStationChatSystem.cs | 64 ++++ .../ShadowkinBlackeyeTraitComponent.cs | 7 + .../ShadowkinDarkSwapPowerComponent.cs | 7 + .../Components/ShadowkinLightComponent.cs | 22 ++ .../Components/ShadowkinRestPowerComponent.cs | 8 + .../ShadowkinTeleportPowerComponent.cs | 9 + .../Events/ShadowkinEvents.Powers.cs | 86 ++++++ .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 196 +++++++++++++ .../Systems/ShadowkinPowerSystem.Darken.cs | 143 +++++++++ .../Systems/ShadowkinPowerSystem.Rest.cs | 74 +++++ .../Systems/ShadowkinPowerSystem.Teleport.cs | 106 +++++++ .../Shadowkin/Systems/ShadowkinPowerSystem.cs | 274 ++++++++++++++++++ .../Systems/ShadowkinSystem.Blackeye.Trait.cs | 20 ++ .../Systems/ShadowkinSystem.Blackeye.cs | 94 ++++++ .../Shadowkin/Systems/ShadowkinSystem.cs | 230 +++++++++++++++ .../Components/ShadowkinAccentComponent.cs | 4 + .../EntitySystems/ShadowkinAccentSystem.cs | 38 +++ Content.Shared/Alert/AlertCategory.cs | 1 + Content.Shared/Alert/AlertType.cs | 1 + Content.Shared/Chat/ChatChannel.cs | 8 +- Content.Shared/Chat/ChatSelectChannel.cs | 7 +- Content.Shared/Chat/SharedChatSystem.cs | 3 +- Content.Shared/Humanoid/NamingSystem.cs | 3 + .../Humanoid/Prototypes/SpeciesPrototype.cs | 1 + .../Components/EmpathyChatComponent.cs | 9 + .../Components/ShadowkinComponent.cs | 121 ++++++++ .../ShadowkinDarkSwappedComponent.cs | 34 +++ .../Events/ShadowkinEvents.Blackeye.cs | 32 ++ .../Events/ShadowkinEvents.Powers.cs | 19 ++ .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 34 +++ .../Effects/Shadowkin/Powers/darkswapoff.ogg | Bin 0 -> 18887 bytes .../Effects/Shadowkin/Powers/darkswapon.ogg | Bin 0 -> 27207 bytes .../Shadowkin/Powers/futuristic-teleport.ogg | Bin 0 -> 32720 bytes .../Effects/Shadowkin/Powers/license.txt | 4 + .../Effects/Shadowkin/Powers/teleport.ogg | Bin 0 -> 14699 bytes .../en-US/chat/managers/chat-manager.ftl | 4 + Resources/Locale/en-US/chat/ui/chat-box.ftl | 2 + .../Locale/en-US/markings/slimeperson.ftl | 24 +- .../Content/Interaction/interaction-popup.ftl | 6 + .../Content/Species/Shadowkin/shadowkin.ftl | 11 + .../Prototypes/Alerts/shadowkin.ftl | 2 + .../Entities/Mobs/Customization/ears.ftl | 1 + .../Entities/Mobs/Customization/eyes.ftl | 1 + .../Entities/Mobs/Customization/tails.ftl | 5 + .../Prototypes/Guidebook/species.ftl | 1 + .../Prototypes/Magic/shadowkin.ftl | 10 + .../Prototypes/Species/shadowkin.ftl | 1 + Resources/Locale/en-US/species/namepreset.ftl | 5 +- Resources/Prototypes/Alerts/alerts.yml | 1 + .../Prototypes/Catalog/Fills/Crates/fun.yml | 3 +- .../Mobs/Customization/Markings/reptilian.yml | 8 +- .../Mobs/Customization/Markings/slime.yml | 38 ++- .../Mobs/Customization/Markings/tattoos.yml | 16 +- .../Structures/Lighting/base_lighting.yml | 1 + .../SimpleStation14/Alerts/shadowkin.yml | 24 ++ .../SimpleStation14/Damage/containers.yml | 10 + .../SimpleStation14/Damage/modifier_sets.yml | 13 + .../Datasets/Names/shadowkin.yml | 69 +++++ .../Entites/Body/Parts/shadowkin.yml | 156 ++++++++++ .../Entites/Body/Prototypes/shadowkin.yml | 49 ++++ .../Entites/Mobs/Player/shadowkin.yml | 191 ++++++++++++ .../Entites/Objects/Fun/toys.yml | 13 + .../SimpleStation14/Magic/shadowkin.yml | 47 +++ .../SimpleStation14/Shaders/shaders.yml | 9 + .../SimpleStation14/Species/shadowkin.yml | 159 ++++++++++ .../SimpleStation14/Traits/disabilities.yml | 11 + .../SimpleStationSpecies/Shadowkin.Lore.txt | 178 ++++++++++++ .../SimpleStationSpecies/Shadowkin.xml | 34 +++ .../Actions/shadowkin_icons.rsi/darkswap.png | Bin 0 -> 5595 bytes .../Actions/shadowkin_icons.rsi/meta.json | 23 ++ .../Actions/shadowkin_icons.rsi/rest.png | Bin 0 -> 5615 bytes .../Actions/shadowkin_icons.rsi/teleport.png | Bin 0 -> 4114 bytes .../Alerts/shadowkin_power.rsi/meta.json | 43 +++ .../Alerts/shadowkin_power.rsi/power0.png | Bin 0 -> 853 bytes .../Alerts/shadowkin_power.rsi/power1.png | Bin 0 -> 938 bytes .../Alerts/shadowkin_power.rsi/power2.png | Bin 0 -> 1000 bytes .../Alerts/shadowkin_power.rsi/power3.png | Bin 0 -> 1020 bytes .../Alerts/shadowkin_power.rsi/power4.png | Bin 0 -> 1064 bytes .../Alerts/shadowkin_power.rsi/power5.png | Bin 0 -> 1064 bytes .../Alerts/shadowkin_power.rsi/power6.png | Bin 0 -> 1063 bytes .../Alerts/shadowkin_power.rsi/power7.png | Bin 0 -> 1087 bytes .../Mobs/Customization/ears.rsi/meta.json | 87 ++++++ .../Mobs/Customization/ears.rsi/shadowkin.png | Bin 0 -> 9242 bytes .../ears.rsi/shadowkin_stripes.png | Bin 0 -> 789 bytes .../Customization/tails32x32.rsi/axolotl.png | Bin 0 -> 8532 bytes .../tails32x32.rsi/datashark_ears.png | Bin 0 -> 6688 bytes .../tails32x32.rsi/datashark_ears_inner.png | Bin 0 -> 5734 bytes .../tails32x32.rsi/datashark_fin.png | Bin 0 -> 7178 bytes .../tails32x32.rsi/datashark_tail.png | Bin 0 -> 8651 bytes .../tails32x32.rsi/datashark_taildata.png | Bin 0 -> 7294 bytes .../tails32x32.rsi/easternd_primary.png | Bin 0 -> 7539 bytes .../tails32x32.rsi/easternd_secondary.png | Bin 0 -> 7186 bytes .../Customization/tails32x32.rsi/fennec.png | Bin 0 -> 8106 bytes .../tails32x32.rsi/fish_primary.png | Bin 0 -> 7565 bytes .../tails32x32.rsi/fish_secondary.png | Bin 0 -> 7687 bytes .../Customization/tails32x32.rsi/fluffy.png | Bin 0 -> 8939 bytes .../tails32x32.rsi/fox_primary.png | Bin 0 -> 7850 bytes .../tails32x32.rsi/fox_secondary.png | Bin 0 -> 6682 bytes .../tails32x32.rsi/gecko_primary.png | Bin 0 -> 8578 bytes .../tails32x32.rsi/gecko_secondary.png | Bin 0 -> 6951 bytes .../tails32x32.rsi/gecko_tertiary.png | Bin 0 -> 6880 bytes .../tails32x32.rsi/kitsune_primary.png | Bin 0 -> 8093 bytes .../tails32x32.rsi/kitsune_secondary.png | Bin 0 -> 6736 bytes .../Mobs/Customization/tails32x32.rsi/maw.png | Bin 0 -> 9068 bytes .../Customization/tails32x32.rsi/meta.json | 119 ++++++++ .../tails32x32.rsi/shadowkin_medium.png | Bin 0 -> 807 bytes .../tails32x32.rsi/shadowkin_shorter.png | Bin 0 -> 630 bytes .../tails32x32.rsi/shark_fin.png | Bin 0 -> 6877 bytes .../tails32x32.rsi/shark_tail.png | Bin 0 -> 7887 bytes .../Customization/tails32x32.rsi/snake.png | Bin 0 -> 9758 bytes .../Customization/tails32x32.rsi/succubus.png | Bin 0 -> 8025 bytes .../Customization/tails32x32.rsi/tentacle.png | Bin 0 -> 10386 bytes .../Customization/tails64x32.rsi/meta.json | 23 ++ .../tails64x32.rsi/shadowkin.png | Bin 0 -> 4674 bytes .../tails64x32.rsi/shadowkin_big.png | Bin 0 -> 5277 bytes .../tails64x32.rsi/shadowkin_big_fluff.png | Bin 0 -> 1785 bytes .../Mobs/Species/shadowkin.rsi/eyes.png | Bin 0 -> 1643 bytes .../Mobs/Species/shadowkin.rsi/full.png | Bin 0 -> 8794 bytes .../Mobs/Species/shadowkin.rsi/head_f.png | Bin 0 -> 849 bytes .../Mobs/Species/shadowkin.rsi/head_m.png | Bin 0 -> 849 bytes .../Mobs/Species/shadowkin.rsi/l_arm.png | Bin 0 -> 614 bytes .../Mobs/Species/shadowkin.rsi/l_foot.png | Bin 0 -> 1867 bytes .../Mobs/Species/shadowkin.rsi/l_hand.png | Bin 0 -> 450 bytes .../Mobs/Species/shadowkin.rsi/l_leg.png | Bin 0 -> 3086 bytes .../Mobs/Species/shadowkin.rsi/meta.json | 67 +++++ .../Mobs/Species/shadowkin.rsi/r_arm.png | Bin 0 -> 605 bytes .../Mobs/Species/shadowkin.rsi/r_foot.png | Bin 0 -> 1876 bytes .../Mobs/Species/shadowkin.rsi/r_hand.png | Bin 0 -> 460 bytes .../Mobs/Species/shadowkin.rsi/r_leg.png | Bin 0 -> 3090 bytes .../Mobs/Species/shadowkin.rsi/torso_f.png | Bin 0 -> 1442 bytes .../Mobs/Species/shadowkin.rsi/torso_m.png | Bin 0 -> 1432 bytes .../Fun/Plushies/shadowkin.rsi/meta.json | 14 + .../Fun/Plushies/shadowkin.rsi/shadowkin.png | Bin 0 -> 2063 bytes .../SimpleStation14/Shaders/color_tint.swsl | 56 ++++ .../SimpleStation14/Shaders/ethereal.swsl | 75 +++++ 150 files changed, 3779 insertions(+), 43 deletions(-) create mode 100644 Content.Client/SimpleStation14/Chat/ShadowkinChatUpdateSystem.cs create mode 100644 Content.Client/SimpleStation14/Overlays/Shaders/ColorTintOverlay.cs create mode 100644 Content.Client/SimpleStation14/Overlays/Shaders/EtherealOverlay.cs create mode 100644 Content.Client/SimpleStation14/Overlays/Shaders/IgnoreHumanoidWithComponentOverlay.cs create mode 100644 Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs create mode 100644 Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs create mode 100644 Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs create mode 100644 Content.Server/SimpleStation14/Chat/ESayCommand.cs create mode 100644 Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinBlackeyeTraitComponent.cs create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinLightComponent.cs create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinRestPowerComponent.cs create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinTeleportPowerComponent.cs create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.Trait.cs create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs create mode 100644 Content.Server/SimpleStation14/Speech/Components/ShadowkinAccentComponent.cs create mode 100644 Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs create mode 100644 Content.Shared/SimpleStation14/Species/Shadowkin/Components/EmpathyChatComponent.cs create mode 100644 Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs create mode 100644 Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs create mode 100644 Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs create mode 100644 Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs create mode 100644 Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs create mode 100644 Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapoff.ogg create mode 100644 Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapon.ogg create mode 100644 Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/futuristic-teleport.ogg create mode 100644 Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/license.txt create mode 100644 Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/teleport.ogg create mode 100644 Resources/Locale/en-US/simplestation14/Content/Interaction/interaction-popup.ftl create mode 100644 Resources/Locale/en-US/simplestation14/Content/Species/Shadowkin/shadowkin.ftl create mode 100644 Resources/Locale/en-US/simplestation14/Prototypes/Alerts/shadowkin.ftl create mode 100644 Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/ears.ftl create mode 100644 Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/eyes.ftl create mode 100644 Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/tails.ftl create mode 100644 Resources/Locale/en-US/simplestation14/Prototypes/Guidebook/species.ftl create mode 100644 Resources/Locale/en-US/simplestation14/Prototypes/Magic/shadowkin.ftl create mode 100644 Resources/Locale/en-US/simplestation14/Prototypes/Species/shadowkin.ftl create mode 100644 Resources/Prototypes/SimpleStation14/Alerts/shadowkin.yml create mode 100644 Resources/Prototypes/SimpleStation14/Damage/containers.yml create mode 100644 Resources/Prototypes/SimpleStation14/Damage/modifier_sets.yml create mode 100644 Resources/Prototypes/SimpleStation14/Datasets/Names/shadowkin.yml create mode 100644 Resources/Prototypes/SimpleStation14/Entites/Body/Parts/shadowkin.yml create mode 100644 Resources/Prototypes/SimpleStation14/Entites/Body/Prototypes/shadowkin.yml create mode 100644 Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml create mode 100644 Resources/Prototypes/SimpleStation14/Entites/Objects/Fun/toys.yml create mode 100644 Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml create mode 100644 Resources/Prototypes/SimpleStation14/Shaders/shaders.yml create mode 100644 Resources/Prototypes/SimpleStation14/Species/shadowkin.yml create mode 100644 Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.Lore.txt create mode 100644 Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.xml create mode 100644 Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/darkswap.png create mode 100644 Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/meta.json create mode 100644 Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/rest.png create mode 100644 Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/teleport.png create mode 100644 Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/meta.json create mode 100644 Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power0.png create mode 100644 Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power1.png create mode 100644 Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power2.png create mode 100644 Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power3.png create mode 100644 Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power4.png create mode 100644 Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power5.png create mode 100644 Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power6.png create mode 100644 Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power7.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/meta.json create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/shadowkin.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/shadowkin_stripes.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/axolotl.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/datashark_ears.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/datashark_ears_inner.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/datashark_fin.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/datashark_tail.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/datashark_taildata.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/easternd_primary.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/easternd_secondary.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fennec.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fish_primary.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fish_secondary.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fluffy.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fox_primary.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fox_secondary.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/gecko_primary.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/gecko_secondary.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/gecko_tertiary.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/kitsune_primary.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/kitsune_secondary.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/maw.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/meta.json create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/shadowkin_medium.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/shadowkin_shorter.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/shark_fin.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/shark_tail.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/snake.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/succubus.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/tentacle.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails64x32.rsi/meta.json create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails64x32.rsi/shadowkin.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails64x32.rsi/shadowkin_big.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails64x32.rsi/shadowkin_big_fluff.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/eyes.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/full.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/head_f.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/head_m.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_arm.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_foot.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_hand.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_leg.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/meta.json create mode 100644 Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_arm.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_foot.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_hand.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_leg.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/torso_f.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/torso_m.png create mode 100644 Resources/Textures/SimpleStation14/Objects/Fun/Plushies/shadowkin.rsi/meta.json create mode 100644 Resources/Textures/SimpleStation14/Objects/Fun/Plushies/shadowkin.rsi/shadowkin.png create mode 100644 Resources/Textures/SimpleStation14/Shaders/color_tint.swsl create mode 100644 Resources/Textures/SimpleStation14/Shaders/ethereal.swsl diff --git a/Content.Client/Chat/Managers/ChatManager.cs b/Content.Client/Chat/Managers/ChatManager.cs index 18f03cd7db..44ef7dc0ae 100644 --- a/Content.Client/Chat/Managers/ChatManager.cs +++ b/Content.Client/Chat/Managers/ChatManager.cs @@ -72,11 +72,16 @@ public void SendMessage(string text, ChatSelectChannel channel) _consoleHost.ExecuteCommand($"tsay \"{CommandParsing.Escape(str)}\""); break; + // Parkstation - Shadowkin chat + case ChatSelectChannel.Empathy: + _consoleHost.ExecuteCommand($"esay \"{CommandParsing.Escape(str)}\""); + break; + default: throw new ArgumentOutOfRangeException(nameof(channel), channel, null); } } - //Nyano - Summary: fires off the update permissions script. + //Nyano - Summary: fires off the update permissions script. public void UpdatePermissions() { PermissionsUpdated?.Invoke(); diff --git a/Content.Client/SimpleStation14/Chat/ShadowkinChatUpdateSystem.cs b/Content.Client/SimpleStation14/Chat/ShadowkinChatUpdateSystem.cs new file mode 100644 index 0000000000..549e3aff27 --- /dev/null +++ b/Content.Client/SimpleStation14/Chat/ShadowkinChatUpdateSystem.cs @@ -0,0 +1,33 @@ +using Content.Client.Chat.Managers; +using Robust.Client.Player; +using Content.Shared.SimpleStation14.Species.Shadowkin.Components; + +namespace Content.Client.SimpleStation14.Chat +{ + public sealed class ShadowkinChatUpdateSystem : EntitySystem + { + [Dependency] private readonly IChatManager _chatManager = default!; + [Dependency] private readonly IPlayerManager _playerManager = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnRemove); + } + + public EmpathyChatComponent? Player => CompOrNull(_playerManager.LocalPlayer?.ControlledEntity); + public bool IsShadowkin => Player != null; + + private void OnInit(EntityUid uid, EmpathyChatComponent component, ComponentInit args) + { + _chatManager.UpdatePermissions(); + } + + private void OnRemove(EntityUid uid, EmpathyChatComponent component, ComponentRemove args) + { + _chatManager.UpdatePermissions(); + } + } +} diff --git a/Content.Client/SimpleStation14/Overlays/Shaders/ColorTintOverlay.cs b/Content.Client/SimpleStation14/Overlays/Shaders/ColorTintOverlay.cs new file mode 100644 index 0000000000..1dd4e9bfe6 --- /dev/null +++ b/Content.Client/SimpleStation14/Overlays/Shaders/ColorTintOverlay.cs @@ -0,0 +1,61 @@ +using Robust.Client.Graphics; +using Robust.Client.Player; +using Robust.Shared.Enums; +using Robust.Shared.Prototypes; + +namespace Content.Client.SimpleStation14.Overlays.Shaders; + +/// +/// A simple overlay that applies a colored tint to the screen. +/// +public sealed class ColorTintOverlay : Overlay +{ + [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private readonly IEntityManager _entity = default!; + + public override bool RequestScreenTexture => true; + public override OverlaySpace Space => OverlaySpace.WorldSpace; + private readonly ShaderInstance _shader; + + /// + /// The color to tint the screen to as RGB on a scale of 0-1. + /// + public Vector3? TintColor = null; + /// + /// The percent to tint the screen by on a scale of 0-1. + /// + public float? TintAmount = null; + /// + /// Component required to be on the entity to tint the screen. + /// + public Component? Comp = null; + + public ColorTintOverlay() + { + IoCManager.InjectDependencies(this); + + _shader = _prototype.Index("ColorTint").InstanceUnique(); + } + + protected override void Draw(in OverlayDrawArgs args) + { + if (ScreenTexture == null || + _player.LocalPlayer?.ControlledEntity is not { Valid: true } player || + Comp != null && !_entity.HasComponent(player, Comp.GetType())) + return; + + _shader.SetParameter("SCREEN_TEXTURE", ScreenTexture); + if (TintColor != null) + _shader.SetParameter("tint_color", (Vector3) TintColor); + if (TintAmount != null) + _shader.SetParameter("tint_amount", (float) TintAmount); + + var worldHandle = args.WorldHandle; + var viewport = args.WorldBounds; + worldHandle.SetTransform(Matrix3.Identity); + worldHandle.UseShader(_shader); + worldHandle.DrawRect(viewport, Color.White); + worldHandle.UseShader(null); + } +} diff --git a/Content.Client/SimpleStation14/Overlays/Shaders/EtherealOverlay.cs b/Content.Client/SimpleStation14/Overlays/Shaders/EtherealOverlay.cs new file mode 100644 index 0000000000..d1aa0a7152 --- /dev/null +++ b/Content.Client/SimpleStation14/Overlays/Shaders/EtherealOverlay.cs @@ -0,0 +1,37 @@ +using Robust.Client.Graphics; +using Robust.Client.Player; +using Robust.Shared.Enums; +using Robust.Shared.Prototypes; + +namespace Content.Client.SimpleStation14.Overlays.Shaders; + +public sealed class EtherealOverlay : Overlay +{ + [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly IPlayerManager _player = default!; + + public override bool RequestScreenTexture => true; + public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowFOV; + private readonly ShaderInstance _shader; + + public EtherealOverlay() + { + IoCManager.InjectDependencies(this); + _shader = _prototype.Index("Ethereal").InstanceUnique(); + } + + protected override void Draw(in OverlayDrawArgs args) + { + if (ScreenTexture == null) return; + if (_player.LocalPlayer?.ControlledEntity is not { Valid: true } player) return; + + _shader?.SetParameter("SCREEN_TEXTURE", ScreenTexture); + + var worldHandle = args.WorldHandle; + var viewport = args.WorldBounds; + worldHandle.SetTransform(Matrix3.Identity); + worldHandle.UseShader(_shader); + worldHandle.DrawRect(viewport, Color.White); + worldHandle.UseShader(null); + } +} diff --git a/Content.Client/SimpleStation14/Overlays/Shaders/IgnoreHumanoidWithComponentOverlay.cs b/Content.Client/SimpleStation14/Overlays/Shaders/IgnoreHumanoidWithComponentOverlay.cs new file mode 100644 index 0000000000..c0cc302d66 --- /dev/null +++ b/Content.Client/SimpleStation14/Overlays/Shaders/IgnoreHumanoidWithComponentOverlay.cs @@ -0,0 +1,96 @@ +using Content.Shared.Humanoid; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Client.Player; + +namespace Content.Client.SimpleStation14.Overlays.Shaders; + +public sealed class IgnoreHumanoidWithComponentOverlay : Overlay +{ + [Dependency] private readonly IPlayerManager _playerManager = default!; + [Dependency] private readonly IEntityManager _entityManager = default!; + + public List IgnoredComponents = new(); + public List AllowAnywayComponents = new(); + private readonly List _nonVisibleList = new(); + + public IgnoreHumanoidWithComponentOverlay() + { + IoCManager.InjectDependencies(this); + } + + protected override void Draw(in OverlayDrawArgs args) + { + var spriteQuery = _entityManager.GetEntityQuery(); + + foreach (var humanoid in _entityManager.EntityQuery(true)) + { + if (_playerManager.LocalPlayer?.ControlledEntity == humanoid.Owner) + continue; + + var cont = true; + foreach (var comp in IgnoredComponents) + { + if (!_entityManager.HasComponent(humanoid.Owner, comp.GetType())) + continue; + + cont = false; + break; + } + foreach (var comp in AllowAnywayComponents) + { + if (!_entityManager.HasComponent(humanoid.Owner, comp.GetType())) + continue; + + cont = true; + break; + } + if (cont) + { + Reset(humanoid.Owner); + continue; + } + + + if (!spriteQuery.TryGetComponent(humanoid.Owner, out var sprite)) + continue; + + if (!sprite.Visible || _nonVisibleList.Contains(humanoid.Owner)) + continue; + + sprite.Visible = false; + _nonVisibleList.Add(humanoid.Owner); + } + + foreach (var humanoid in _nonVisibleList.ToArray()) + { + if (!_entityManager.Deleted(humanoid)) + continue; + + _nonVisibleList.Remove(humanoid); + } + } + + + public void Reset() + { + foreach (var humanoid in _nonVisibleList.ToArray()) + { + _nonVisibleList.Remove(humanoid); + + if (_entityManager.TryGetComponent(humanoid, out var sprite)) + sprite.Visible = true; + } + } + + public void Reset(EntityUid entity) + { + if (!_nonVisibleList.Contains(entity)) + return; + + _nonVisibleList.Remove(entity); + + if (_entityManager.TryGetComponent(entity, out var sprite)) + sprite.Visible = true; + } +} diff --git a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs new file mode 100644 index 0000000000..f527c4e6d1 --- /dev/null +++ b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs @@ -0,0 +1,74 @@ +using Robust.Client.Graphics; +using Robust.Client.Player; +using Content.Client.SimpleStation14.Overlays; +using Content.Client.SimpleStation14.Overlays.Shaders; +using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Robust.Client.GameObjects; +using Content.Shared.Humanoid; + +namespace Content.Client.SimpleStation14.Species.Shadowkin.Systems; + +public sealed class ShadowkinDarkSwappedSystem : EntitySystem +{ + [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private readonly IOverlayManager _overlay = default!; + + private IgnoreHumanoidWithComponentOverlay _ignoreOverlay = default!; + private EtherealOverlay _etherealOverlay = default!; + + public override void Initialize() + { + base.Initialize(); + + _ignoreOverlay = new IgnoreHumanoidWithComponentOverlay(); + _ignoreOverlay.IgnoredComponents.Add(new HumanoidAppearanceComponent()); + _ignoreOverlay.AllowAnywayComponents.Add(new ShadowkinDarkSwappedComponent()); + _etherealOverlay = new EtherealOverlay(); + + SubscribeLocalEvent(OnStartup); + SubscribeLocalEvent(OnShutdown); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); + } + + + private void OnStartup(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentStartup args) + { + if (_player.LocalPlayer?.ControlledEntity != uid) + return; + + AddOverlay(); + } + + private void OnShutdown(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentShutdown args) + { + if (_player.LocalPlayer?.ControlledEntity != uid) + return; + + RemoveOverlay(); + } + + private void OnPlayerAttached(EntityUid uid, ShadowkinDarkSwappedComponent component, PlayerAttachedEvent args) + { + AddOverlay(); + } + + private void OnPlayerDetached(EntityUid uid, ShadowkinDarkSwappedComponent component, PlayerDetachedEvent args) + { + RemoveOverlay(); + } + + + private void AddOverlay() + { + _overlay.AddOverlay(_ignoreOverlay); + _overlay.AddOverlay(_etherealOverlay); + } + + private void RemoveOverlay() + { + _ignoreOverlay.Reset(); + _overlay.RemoveOverlay(_ignoreOverlay); + _overlay.RemoveOverlay(_etherealOverlay); + } +} diff --git a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs new file mode 100644 index 0000000000..4c33438806 --- /dev/null +++ b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs @@ -0,0 +1,51 @@ +using Content.Shared.SimpleStation14.Species.Shadowkin.Events; +using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Robust.Client.GameObjects; +using Content.Shared.Humanoid; + +namespace Content.Client.SimpleStation14.Species.Shadowkin.Systems; + +public sealed class ShadowkinBlackeyeSystem : EntitySystem +{ + [Dependency] private readonly IEntityManager _entity = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeNetworkEvent(OnBlackeye); + + SubscribeLocalEvent(OnInit); + } + + private void OnBlackeye(ShadowkinBlackeyeEvent ev) + { + SetColor(ev.Uid, Color.Black); + } + + + private void OnInit(EntityUid uid, ShadowkinComponent component, ComponentInit args) + { + if (!_entity.TryGetComponent(uid, out var sprite) || + !sprite.LayerMapTryGet(HumanoidVisualLayers.Eyes, out var index) || + !sprite.TryGetLayer(index, out var layer)) + return; + + // Blackeye if none of the RGB values are greater than 75 + if (layer.Color.R * 255 < 75 && layer.Color.G * 255 < 75 && layer.Color.B * 255 < 75) + { + RaiseNetworkEvent(new ShadowkinBlackeyeEvent(uid, false)); + } + } + + + private void SetColor(EntityUid uid, Color color) + { + if (!_entity.TryGetComponent(uid, out var sprite) || + !sprite.LayerMapTryGet(HumanoidVisualLayers.Eyes, out var index) || + !sprite.TryGetLayer(index, out var layer)) + return; + + sprite.LayerSetColor(index, color); + } +} diff --git a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs new file mode 100644 index 0000000000..482203dde6 --- /dev/null +++ b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs @@ -0,0 +1,111 @@ +using Robust.Client.Graphics; +using Robust.Client.Player; +using Content.Client.SimpleStation14.Overlays; +using Content.Client.SimpleStation14.Overlays.Shaders; +using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Robust.Client.GameObjects; +using Content.Shared.GameTicking; +using Content.Shared.Humanoid; + +namespace Content.Client.SimpleStation14.Species.Shadowkin.Systems; + +public sealed class ShadowkinTintSystem : EntitySystem +{ + [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private readonly IOverlayManager _overlay = default!; + [Dependency] private readonly IEntityManager _entity = default!; + + private ColorTintOverlay _tintOverlay = default!; + + public override void Initialize() + { + base.Initialize(); + + _tintOverlay = new ColorTintOverlay + { + TintColor = new Vector3(0.5f, 0f, 0.5f), + TintAmount = 0.25f, + Comp = new ShadowkinComponent() + }; + + SubscribeLocalEvent(OnStartup); + SubscribeLocalEvent(OnShutdown); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnRoundRestart); + } + + private void OnStartup(EntityUid uid, ShadowkinComponent component, ComponentStartup args) + { + if (_player.LocalPlayer?.ControlledEntity != uid) + return; + + _overlay.AddOverlay(_tintOverlay); + } + + private void OnShutdown(EntityUid uid, ShadowkinComponent component, ComponentShutdown args) + { + if (_player.LocalPlayer?.ControlledEntity != uid) + return; + + _overlay.RemoveOverlay(_tintOverlay); + } + + private void OnPlayerAttached(EntityUid uid, ShadowkinComponent component, PlayerAttachedEvent args) + { + _overlay.AddOverlay(_tintOverlay); + } + + private void OnPlayerDetached(EntityUid uid, ShadowkinComponent component, PlayerDetachedEvent args) + { + _overlay.RemoveOverlay(_tintOverlay); + } + + private void OnRoundRestart(RoundRestartCleanupEvent args) + { + _overlay.RemoveOverlay(_tintOverlay); + } + + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var uid = _player.LocalPlayer?.ControlledEntity; + if (uid == null || + !_entity.TryGetComponent(uid, out ShadowkinComponent? comp) || + !_entity.TryGetComponent(uid, out SpriteComponent? sprite) || + !sprite.LayerMapTryGet(HumanoidVisualLayers.Eyes, out var index) || + !sprite.TryGetLayer(index, out var layer)) + return; + + // Eye color + comp.TintColor = new Vector3(layer.Color.R, layer.Color.G, layer.Color.B); + + // 1/3 = 0.333... + // intensity = min + (power / max) + // intensity = intensity / 0.333 + // intensity = clamp intensity min, max + const float min = 0.45f; + const float max = 0.75f; + comp.TintIntensity = Math.Clamp(min + (comp.PowerLevel / comp.PowerLevelMax) * 0.333f, min, max); + + UpdateShader(comp.TintColor, comp.TintIntensity); + } + + + private void UpdateShader(Vector3? color, float? intensity) + { + while (_overlay.HasOverlay()) + { + _overlay.RemoveOverlay(_tintOverlay); + } + + if (color != null) + _tintOverlay.TintColor = color; + if (intensity != null) + _tintOverlay.TintAmount = intensity; + + _overlay.AddOverlay(_tintOverlay); + } +} diff --git a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs index 9787fc4824..d8fc24243b 100644 --- a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs +++ b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs @@ -11,6 +11,7 @@ using Content.Client.Ghost; using Content.Client.UserInterface.Screens; using Content.Client.UserInterface.Systems.Chat.Widgets; +using Content.Client.SimpleStation14.Chat; using Content.Client.UserInterface.Systems.Gameplay; using Content.Shared.Administration; using Content.Shared.CCVar; @@ -56,6 +57,7 @@ public sealed class ChatUIController : UIController [UISystemDependency] private readonly TypingIndicatorSystem? _typingIndicator = default; [UISystemDependency] private readonly ChatSystem? _chatSys = default; [UISystemDependency] private readonly PsionicChatUpdateSystem? _psionic = default!; //Nyano - Summary: makes the psionic chat available. + [UISystemDependency] private readonly ShadowkinChatUpdateSystem? _shadowkin = default!; private ISawmill _sawmill = default!; @@ -71,7 +73,9 @@ public sealed class ChatUIController : UIController {SharedChatSystem.AdminPrefix, ChatSelectChannel.Admin}, {SharedChatSystem.RadioCommonPrefix, ChatSelectChannel.Radio}, {SharedChatSystem.DeadPrefix, ChatSelectChannel.Dead}, - {SharedChatSystem.TelepathicPrefix, ChatSelectChannel.Telepathic} //Nyano - Summary: adds the telepathic prefix =. + {SharedChatSystem.TelepathicPrefix, ChatSelectChannel.Telepathic}, //Nyano - Summary: adds the telepathic prefix =. + {SharedChatSystem.TelepathicPrefix, ChatSelectChannel.Telepathic}, + {SharedChatSystem.EmpathyPrefix, ChatSelectChannel.Empathy} }; public static readonly Dictionary ChannelPrefixes = new() @@ -85,7 +89,9 @@ public sealed class ChatUIController : UIController {ChatSelectChannel.Admin, SharedChatSystem.AdminPrefix}, {ChatSelectChannel.Radio, SharedChatSystem.RadioCommonPrefix}, {ChatSelectChannel.Dead, SharedChatSystem.DeadPrefix}, - {ChatSelectChannel.Telepathic, SharedChatSystem.TelepathicPrefix } //Nyano - Summary: associates telepathic with =. + {ChatSelectChannel.Telepathic, SharedChatSystem.TelepathicPrefix }, //Nyano - Summary: associates telepathic with =. + {ChatSelectChannel.Telepathic, SharedChatSystem.TelepathicPrefix}, + {ChatSelectChannel.Empathy, SharedChatSystem.EmpathyPrefix} }; /// @@ -530,9 +536,10 @@ private void UpdateChannelPermissions() FilterableChannels |= ChatChannel.AdminChat; CanSendChannels |= ChatSelectChannel.Admin; FilterableChannels |= ChatChannel.Telepathic; //Nyano - Summary: makes admins able to see psionic chat. + FilterableChannels |= ChatChannel.Empathy; } - // Nyano - Summary: - Begin modified code block to add telepathic as a channel for a psionic user. + // Nyano - Summary: - Begin modified code block to add telepathic as a channel for a psionic user. if (_psionic != null && _psionic.IsPsionic) { FilterableChannels |= ChatChannel.Telepathic; @@ -540,6 +547,13 @@ private void UpdateChannelPermissions() } // /Nyano - End modified code block + // Shadowkin + if (_shadowkin != null && _shadowkin.IsShadowkin) + { + FilterableChannels |= ChatChannel.Empathy; + CanSendChannels |= ChatSelectChannel.Empathy; + } + SelectableChannels = CanSendChannels; // Necessary so that we always have a channel to fall back to. diff --git a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelFilterPopup.xaml.cs b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelFilterPopup.xaml.cs index daf124306c..23114f8cfa 100644 --- a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelFilterPopup.xaml.cs +++ b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelFilterPopup.xaml.cs @@ -17,6 +17,7 @@ public sealed partial class ChannelFilterPopup : Popup ChatChannel.Emotes, ChatChannel.Radio, ChatChannel.Telepathic, //Nyano - Summary: adds telepathic chat to where it belongs in order in the chat. + ChatChannel.Empathy, ChatChannel.LOOC, ChatChannel.OOC, ChatChannel.Dead, diff --git a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorButton.cs b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorButton.cs index e28cd2bd44..66f6c62ecc 100644 --- a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorButton.cs +++ b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorButton.cs @@ -82,7 +82,8 @@ public Color ChannelSelectColor(ChatSelectChannel channel) ChatSelectChannel.OOC => Color.LightSkyBlue, ChatSelectChannel.Dead => Color.MediumPurple, ChatSelectChannel.Admin => Color.HotPink, - ChatSelectChannel.Telepathic => Color.PaleVioletRed, //Nyano - Summary: determines the color for the chat. + ChatSelectChannel.Telepathic => Color.PaleVioletRed, //Nyano - Summary: determines the color for the chat. + ChatSelectChannel.Empathy => Color.PaleVioletRed, _ => Color.DarkGray }; } diff --git a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorPopup.cs b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorPopup.cs index c1f3559d79..9999a50360 100644 --- a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorPopup.cs +++ b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorPopup.cs @@ -13,7 +13,8 @@ public sealed class ChannelSelectorPopup : Popup ChatSelectChannel.Whisper, ChatSelectChannel.Emotes, ChatSelectChannel.Radio, - ChatSelectChannel.Telepathic, //Nyano - Summary: determines the order in which telepathic shows. + ChatSelectChannel.Telepathic, //Nyano - Summary: determines the order in which telepathic shows. + ChatSelectChannel.Empathy, ChatSelectChannel.LOOC, ChatSelectChannel.OOC, ChatSelectChannel.Dead, diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 91739d769d..7d41098adc 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -32,6 +32,7 @@ using Robust.Shared.Random; using Robust.Shared.Replays; using Robust.Shared.Utility; +using Content.Server.SimpleStation14.Chat; namespace Content.Server.Chat.Systems; @@ -54,6 +55,7 @@ public sealed partial class ChatSystem : SharedChatSystem [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!; [Dependency] private readonly StationSystem _stationSystem = default!; [Dependency] private readonly MobStateSystem _mobStateSystem = default!; + [Dependency] private readonly SimpleStationChatSystem _simpleStationChatSystem = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly ReplacementAccentSystem _wordreplacement = default!; @@ -252,6 +254,10 @@ public void TrySendInGameICMessage( case InGameICChatType.Telepathic: _nyanoChatSystem.SendTelepathicChat(source, message, range == ChatTransmitRange.HideChat); break; + // Shadowkin + case InGameICChatType.Empathy: + _simpleStationChatSystem.SendEmpathyChat(source, message, range == ChatTransmitRange.HideChat); + break; } } @@ -702,7 +708,7 @@ private string SanitizeInGameICMessage(EntityUid source, string message, out str { var newMessage = message.Trim(); newMessage = SanitizeMessageReplaceWords(newMessage); - + if (capitalize) newMessage = SanitizeMessageCapital(newMessage); if (capitalizeTheWordI) @@ -901,7 +907,8 @@ public enum InGameICChatType : byte Speak, Emote, Whisper, - Telepathic //Nyano - Summary: adds telepathic as a type of message users can receive. + Telepathic, //Nyano - Summary: adds telepathic as a type of message users can receive. + Empathy // Shadowkin } /// diff --git a/Content.Server/Magic/MagicSystem.cs b/Content.Server/Magic/MagicSystem.cs index 4fbd9e3ec7..bbf884a05b 100644 --- a/Content.Server/Magic/MagicSystem.cs +++ b/Content.Server/Magic/MagicSystem.cs @@ -396,7 +396,7 @@ private void SpawnSpellHelper(List entityEntries, EntityCoordi #endregion - private void Speak(BaseActionEvent args) + public void Speak(BaseActionEvent args) { if (args is not ISpeakSpell speak || string.IsNullOrWhiteSpace(speak.Speech)) return; diff --git a/Content.Server/SimpleStation14/Chat/ESayCommand.cs b/Content.Server/SimpleStation14/Chat/ESayCommand.cs new file mode 100644 index 0000000000..4e125bc581 --- /dev/null +++ b/Content.Server/SimpleStation14/Chat/ESayCommand.cs @@ -0,0 +1,43 @@ +using Content.Server.Chat.Systems; +using Content.Shared.Administration; +using Robust.Server.Player; +using Robust.Shared.Console; +using Robust.Shared.Enums; + +namespace Content.Server.SimpleStation14.Chat.Commands +{ + [AnyCommand] + internal sealed class ESayCommand : IConsoleCommand + { + public string Command => "esay"; + public string Description => "Send chat messages to Shadowkin."; + public string Help => $"{Command} "; + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (shell.Player is not IPlayerSession player) + { + shell.WriteError("This command cannot be run from the server."); + return; + } + + if (player.Status != SessionStatus.InGame) + return; + + if (player.AttachedEntity is not {} playerEntity) + { + shell.WriteError("You don't have an entity!"); + return; + } + + if (args.Length < 1) + return; + + var message = string.Join(" ", args).Trim(); + if (string.IsNullOrEmpty(message)) + return; + + EntitySystem.Get().TrySendInGameICMessage(playerEntity, message, InGameICChatType.Empathy, false, shell, player, checkRadioPrefix: false); + } + } +} diff --git a/Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs b/Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs new file mode 100644 index 0000000000..e02dd47229 --- /dev/null +++ b/Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs @@ -0,0 +1,64 @@ +using System.Linq; +using Content.Shared.Chat; +using Content.Shared.Database; +using Content.Shared.Psionics.Glimmer; +using Content.Server.Administration.Managers; +using Content.Server.Administration.Logs; +using Content.Server.Chat.Managers; +using Content.Server.Chat.Systems; +using Robust.Shared.Network; +using Robust.Shared.Player; +using Robust.Shared.Random; +using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Robust.Shared.Utility; +using Content.Server.SimpleStation14.Speech.EntitySystems; + +namespace Content.Server.SimpleStation14.Chat +{ + /// + /// Extensions for parkstation's chat stuff + /// + public sealed class SimpleStationChatSystem : EntitySystem + { + [Dependency] private readonly IAdminManager _adminManager = default!; + [Dependency] private readonly IChatManager _chatManager = default!; + [Dependency] private readonly IAdminLogManager _adminLogger = default!; + [Dependency] private readonly ChatSystem _chatSystem = default!; + + private IEnumerable GetShadowkinChatClients() + { + return Filter.Empty() + .AddWhereAttachedEntity(entity => HasComp(entity)) + .Recipients + .Select(p => p.ConnectedClient); + } + + private IEnumerable GetAdminClients() + { + return _adminManager.ActiveAdmins + .Select(p => p.ConnectedClient); + } + + public void SendEmpathyChat(EntityUid source, string message, bool hideChat) + { + if (!HasComp(source)) return; + + var clients = GetShadowkinChatClients(); + var admins = GetAdminClients(); + var localMessage = EntitySystem.Get().Accentuate(message); + var messageWrap = Loc.GetString("chat-manager-send-empathy-chat-wrap-message", + ("empathyChannelName", Loc.GetString("chat-manager-empathy-channel-name")), + ("message", message)); + var adminMessageWrap = Loc.GetString("chat-manager-send-empathy-chat-wrap-message-admin", + ("empathyChannelName", Loc.GetString("chat-manager-empathy-channel-name")), + ("source", source), + ("message", message)); + + _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Empathy chat from {ToPrettyString(source):Player}: {message}"); + + _chatSystem.TrySendInGameICMessage(source, localMessage, InGameICChatType.Speak, hideChat); + _chatManager.ChatMessageToMany(ChatChannel.Empathy, message, messageWrap, source, hideChat, true, clients.ToList(), Color.PaleVioletRed); + _chatManager.ChatMessageToMany(ChatChannel.Empathy, message, adminMessageWrap, source, hideChat, true, admins, Color.PaleVioletRed); + } + } +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinBlackeyeTraitComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinBlackeyeTraitComponent.cs new file mode 100644 index 0000000000..4946971df8 --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinBlackeyeTraitComponent.cs @@ -0,0 +1,7 @@ +namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; + +[RegisterComponent] +public sealed class ShadowkinBlackeyeTraitComponent : Component +{ + +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs new file mode 100644 index 0000000000..68333a32cd --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs @@ -0,0 +1,7 @@ +namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; + +[RegisterComponent] +public sealed class ShadowkinDarkSwapPowerComponent : Component +{ + +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinLightComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinLightComponent.cs new file mode 100644 index 0000000000..33ba441947 --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinLightComponent.cs @@ -0,0 +1,22 @@ +namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; + +[RegisterComponent] +public sealed class ShadowkinLightComponent : Component +{ + [ViewVariables(VVAccess.ReadOnly)] + public EntityUid AttachedEntity = EntityUid.Invalid; + + + [ViewVariables(VVAccess.ReadOnly)] + public float OldRadius = 0f; + + [ViewVariables(VVAccess.ReadOnly)] + public bool OldRadiusEdited = false; + + + [ViewVariables(VVAccess.ReadOnly)] + public float OldEnergy = 0f; + + [ViewVariables(VVAccess.ReadOnly)] + public bool OldEnergyEdited = false; +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinRestPowerComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinRestPowerComponent.cs new file mode 100644 index 0000000000..f485136b5e --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinRestPowerComponent.cs @@ -0,0 +1,8 @@ +namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; + +[RegisterComponent] +public sealed class ShadowkinRestPowerComponent : Component +{ + [ViewVariables(VVAccess.ReadOnly)] + public bool IsResting = false; +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinTeleportPowerComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinTeleportPowerComponent.cs new file mode 100644 index 0000000000..8643b4a401 --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinTeleportPowerComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; + +[RegisterComponent] +public sealed class ShadowkinTeleportPowerComponent : Component +{ + +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs new file mode 100644 index 0000000000..5ea597fd64 --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs @@ -0,0 +1,86 @@ +using Content.Server.Magic.Events; +using Content.Shared.Actions; +using Robust.Shared.Audio; + +namespace Content.Server.SimpleStation14.Species.Shadowkin.Events; + +/// +/// Raised when the shadowkin teleport action is used. +/// +public sealed class ShadowkinTeleportEvent : WorldTargetActionEvent, ISpeakSpell +{ + [DataField("sound")] + public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/SimpleStation14/Effects/Shadowkin/Powers/teleport.ogg"); + + [DataField("volume")] + public float Volume = 5f; + + + [DataField("powerCost")] + public float PowerCost = 35f; + + [DataField("staminaCost")] + public float StaminaCost = 30f; + + + [DataField("speech")] + public string? Speech { get; } +} + +/// +/// Raised when the shadowkin darkSwap action is used. +/// +public sealed class ShadowkinDarkSwapEvent : InstantActionEvent, ISpeakSpell +{ + [DataField("soundOn")] + public SoundSpecifier SoundOn = new SoundPathSpecifier("/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapon.ogg"); + + [DataField("volumeOn")] + public float VolumeOn = 5f; + + [DataField("soundOff")] + public SoundSpecifier SoundOff = new SoundPathSpecifier("/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapoff.ogg"); + + [DataField("volumeOff")] + public float VolumeOff = 5f; + + + /// + /// How much stamina to drain when darkening. + /// + [DataField("powerCostOn")] + public float PowerCostOn = 45f; + + /// + /// How much stamina to drain when lightening. + /// + [DataField("powerCostOff")] + public float PowerCostOff = 35f; + + /// + /// How much stamina to drain when darkening. + /// + [DataField("staminaCostOn")] + public float StaminaCostOn; + + /// + /// How much stamina to drain when lightening. + /// + [DataField("staminaCostOff")] + public float StaminaCostOff; + + + [DataField("speech")] + public string? Speech { get; } +} + +public sealed class ShadowkinDarkSwapAttemptEvent : CancellableEntityEventArgs +{ + +} + + +public sealed class ShadowkinRestEvent: InstantActionEvent +{ + +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs new file mode 100644 index 0000000000..75b9c252f8 --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -0,0 +1,196 @@ +using Content.Server.Ghost.Components; +using Content.Server.Magic; +using Content.Server.SimpleStation14.Species.Shadowkin.Components; +using Content.Server.SimpleStation14.Species.Shadowkin.Events; +using Content.Server.Visible; +using Content.Shared.Actions; +using Content.Shared.Actions.ActionTypes; +using Content.Shared.CombatMode.Pacification; +using Content.Shared.Damage.Systems; +using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.SimpleStation14.Species.Shadowkin.Events; +using Content.Shared.Stealth; +using Content.Shared.Stealth.Components; +using Robust.Server.GameObjects; +using Robust.Shared.Audio; +using Robust.Shared.Prototypes; + +namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; + +public sealed class ShadowkinDarkSwapSystem : EntitySystem +{ + [Dependency] private readonly ShadowkinPowerSystem _power = default!; + [Dependency] private readonly VisibilitySystem _visibility = default!; + [Dependency] private readonly IEntityManager _entity = default!; + [Dependency] private readonly ShadowkinDarkenSystem _darken = default!; + [Dependency] private readonly StaminaSystem _stamina = default!; + [Dependency] private readonly SharedStealthSystem _stealth = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedActionsSystem _actions = default!; + [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly MagicSystem _magic = default!; + + private InstantAction _action = default!; + + public override void Initialize() + { + base.Initialize(); + + _action = new InstantAction(_prototype.Index("ShadowkinDarkSwap")); + + SubscribeLocalEvent(Startup); + SubscribeLocalEvent(Shutdown); + + SubscribeLocalEvent(DarkSwap); + + SubscribeLocalEvent(OnInvisStartup); + SubscribeLocalEvent(OnInvisShutdown); + } + + + private void Startup(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentStartup args) + { + _actions.AddAction(uid, _action, uid); + } + + private void Shutdown(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentShutdown args) + { + _actions.RemoveAction(uid, _action); + } + + + private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ShadowkinDarkSwapEvent args) + { + var hasComp = _entity.HasComponent(args.Performer); + + SetDarkened( + args.Performer, + !hasComp, + !hasComp, + true, + args.StaminaCostOn, + args.PowerCostOn, + args.SoundOn, + args.VolumeOn, + args.StaminaCostOff, + args.PowerCostOff, + args.SoundOff, + args.VolumeOff + ); + + _magic.Speak(args); + + args.Handled = true; + } + + + public void SetDarkened( + EntityUid performer, + bool addComp, + bool invisible, + bool darken, + float staminaCostOn, + float powerCostOn, + SoundSpecifier soundOn, + float volumeOn, + float staminaCostOff, + float powerCostOff, + SoundSpecifier soundOff, + float volumeOff + ) + { + var ev = new ShadowkinDarkSwapAttemptEvent(); + RaiseLocalEvent(ev); + if (ev.Cancelled) + return; + + if (addComp) + { + var comp = _entity.EnsureComponent(performer); + comp.Invisible = invisible; + comp.Darken = darken; + + RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, true)); + + _audio.PlayPvs(soundOn, performer, AudioParams.Default.WithVolume(volumeOn)); + + _power.TryAddPowerLevel(performer, -powerCostOn); + _stamina.TakeStaminaDamage(performer, staminaCostOn); + } + else + { + _entity.RemoveComponent(performer); + RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, false)); + + _audio.PlayPvs(soundOff, performer, AudioParams.Default.WithVolume(volumeOff)); + + _power.TryAddPowerLevel(performer, -powerCostOff); + _stamina.TakeStaminaDamage(performer, staminaCostOff); + } + } + + + private void OnInvisStartup(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentStartup args) + { + EnsureComp(uid); + + if (component.Invisible) + SetCanSeeInvisibility(uid, true); + } + + private void OnInvisShutdown(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentShutdown args) + { + RemComp(uid); + + if (component.Invisible) + SetCanSeeInvisibility(uid, false); + + component.Darken = false; + + foreach (var light in component.DarkenedLights.ToArray()) + { + if (!_entity.TryGetComponent(light, out var pointLight) || + !_entity.TryGetComponent(light, out var shadowkinLight)) + continue; + + _darken.ResetLight(pointLight, shadowkinLight); + } + + component.DarkenedLights.Clear(); + } + + + public void SetCanSeeInvisibility(EntityUid uid, bool set) + { + var visibility = _entity.EnsureComponent(uid); + + if (set) + { + if (_entity.TryGetComponent(uid, out EyeComponent? eye)) + { + eye.VisibilityMask |= (uint) VisibilityFlags.DarkSwapInvisibility; + } + + _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); + _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + _visibility.RefreshVisibility(uid); + + if (!_entity.TryGetComponent(uid, out var _)) + _stealth.SetVisibility(uid, 0.8f, _entity.EnsureComponent(uid)); + } + else + { + if (_entity.TryGetComponent(uid, out EyeComponent? eye)) + { + eye.VisibilityMask &= ~(uint) VisibilityFlags.DarkSwapInvisibility; + } + + _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); + _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + _visibility.RefreshVisibility(uid); + + if (!_entity.TryGetComponent(uid, out var _)) + _entity.RemoveComponent(uid); + } + } +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs new file mode 100644 index 0000000000..cfec6173d4 --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs @@ -0,0 +1,143 @@ +using System.Linq; +using Content.Server.Light.Components; +using Content.Server.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Robust.Server.GameObjects; +using Robust.Shared.Random; + +namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; + +public sealed class ShadowkinDarkenSystem : EntitySystem +{ + [Dependency] private readonly IEntityManager _entity = default!; + [Dependency] private readonly SharedPointLightSystem _light = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly EntityLookupSystem _lookup = default!; + + + public void ResetLight(PointLightComponent light, ShadowkinLightComponent sLight) + { + sLight.AttachedEntity = EntityUid.Invalid; + + if (sLight.OldRadiusEdited) + _light.SetRadius(light.Owner, sLight.OldRadius); + sLight.OldRadiusEdited = false; + + if (sLight.OldEnergyEdited) + light.Energy = sLight.OldEnergy; + sLight.OldEnergyEdited = false; + } + + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var shadowkins = _entity.EntityQueryEnumerator(); + + while (shadowkins.MoveNext(out var uid, out var shadowkin)) + { + // Don't do anything if this Shadowkin isn't darkening + if (!shadowkin.Darken) + continue; + + var transform = Transform(uid); + + // Cooldown + shadowkin.DarkenAccumulator -= frameTime; + if (shadowkin.DarkenAccumulator > 0f) + continue; + shadowkin.DarkenAccumulator += shadowkin.DarkenRate; + + + var darkened = new List(); + // Get all lights in range + var lightQuery = _lookup.GetEntitiesInRange(transform.MapID, transform.WorldPosition, shadowkin.DarkenRange, flags: LookupFlags.StaticSundries) + .Where(x => _entity.HasComponent(x) && _entity.HasComponent(x)); + + // Add all lights in range to the list if not already there + foreach (var entity in lightQuery) + { + if (!darkened.Contains(entity)) + darkened.Add(entity); + } + + // Randomize the list to avoid bias + _random.Shuffle(darkened); + shadowkin.DarkenedLights = darkened; + + var playerPos = Transform(uid).WorldPosition; + + foreach (var light in shadowkin.DarkenedLights.ToArray()) + { + var lightPos = Transform(light).WorldPosition; + var pointLight = _entity.GetComponent(light); + + + // Not a light we should affect + if (!_entity.TryGetComponent(light, out ShadowkinLightComponent? shadowkinLight)) + continue; + // Not powered, undo changes + if (!_entity.TryGetComponent(light, out PoweredLightComponent? powered) || !powered.On) + { + ResetLight(pointLight, shadowkinLight); + continue; + } + + + // If the light isn't attached to an entity, attach it to this Shadowkin + if (shadowkinLight.AttachedEntity == EntityUid.Invalid) + { + shadowkinLight.AttachedEntity = uid; + } + // Check if the light is being updated by the correct Shadowkin + // Prevents horrible flickering when the light is in range of multiple Shadowkin + if (shadowkinLight.AttachedEntity != EntityUid.Invalid && + shadowkinLight.AttachedEntity != uid) + { + shadowkin.DarkenedLights.Remove(light); + continue; + } + // 10% chance to remove the attached entity so it can become another Shadowkin's light + if (shadowkinLight.AttachedEntity == uid) + { + if (_random.Prob(0.1f)) + shadowkinLight.AttachedEntity = EntityUid.Invalid; + } + + + // If we haven't edited the radius yet, save the old radius + if (!shadowkinLight.OldRadiusEdited) + { + shadowkinLight.OldRadius = pointLight.Radius; + shadowkinLight.OldRadiusEdited = true; + } + if (!shadowkinLight.OldEnergyEdited) + { + shadowkinLight.OldEnergy = pointLight.Energy; + shadowkinLight.OldEnergyEdited = true; + } + + var distance = (lightPos - playerPos).Length(); + var radius = distance * 2f; + var energy = distance * 0.8f; + + // Set new radius based on distance + if (shadowkinLight.OldRadiusEdited && radius > shadowkinLight.OldRadius) + radius = shadowkinLight.OldRadius; + if (shadowkinLight.OldRadiusEdited && radius < shadowkinLight.OldRadius * 0.20f) + radius = shadowkinLight.OldRadius * 0.20f; + + // Set new energy based on distance + if (shadowkinLight.OldEnergyEdited && energy > shadowkinLight.OldEnergy) + energy = shadowkinLight.OldEnergy; + if (shadowkinLight.OldEnergyEdited && energy < shadowkinLight.OldEnergy * 0.20f) + energy = shadowkinLight.OldEnergy * 0.20f; + + // Put changes into effect + _light.SetRadius(pointLight.Owner, radius); + pointLight.Energy = energy; + } + } + } +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs new file mode 100644 index 0000000000..076faae2c7 --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -0,0 +1,74 @@ +using Content.Server.SimpleStation14.Species.Shadowkin.Components; +using Content.Server.SimpleStation14.Species.Shadowkin.Events; +using Content.Shared.Actions; +using Content.Shared.Actions.ActionTypes; +using Content.Shared.Bed.Sleep; +using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Robust.Shared.Prototypes; + +namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; + +public sealed class ShadowkinRestSystem : EntitySystem +{ + [Dependency] private readonly IEntityManager _entity = default!; + [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly SharedActionsSystem _actions = default!; + [Dependency] private readonly ShadowkinPowerSystem _power = default!; + + private InstantAction _action = default!; + + public override void Initialize() + { + base.Initialize(); + + _action = new InstantAction(_prototype.Index("ShadowkinRest")); + + SubscribeLocalEvent(OnStartup); + SubscribeLocalEvent(OnShutdown); + + SubscribeLocalEvent(Rest); + } + + + private void OnStartup(EntityUid uid, ShadowkinRestPowerComponent component, ComponentStartup args) + { + _actions.AddAction(uid, _action, uid); + } + + private void OnShutdown(EntityUid uid, ShadowkinRestPowerComponent component, ComponentShutdown args) + { + _actions.RemoveAction(uid, _action); + } + + private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, ShadowkinRestEvent args) + { + if (!_entity.HasComponent(args.Performer)) + return; + + // Now doing what you weren't before + component.IsResting = !component.IsResting; + + // Resting + if (component.IsResting) + { + // Sleepy time + _entity.EnsureComponent(args.Performer); + // No waking up normally (it would do nothing) + _actions.RemoveAction(args.Performer, new InstantAction(_prototype.Index("Wake"))); + + _power.TryAddMultiplier(args.Performer, 1f); + // No action cooldown + args.Handled = false; + } + // Waking + else + { + // Wake up + _entity.RemoveComponent(args.Performer); + _entity.RemoveComponent(args.Performer); + _power.TryAddMultiplier(args.Performer, -1f); + // Action cooldown + args.Handled = true; + } + } +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs new file mode 100644 index 0000000000..89dc1258a7 --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -0,0 +1,106 @@ +using Content.Server.Magic; +using Content.Server.Pulling; +using Content.Server.SimpleStation14.Species.Shadowkin.Components; +using Content.Server.SimpleStation14.Species.Shadowkin.Events; +using Content.Shared.Actions; +using Content.Shared.Actions.ActionTypes; +using Content.Shared.Damage.Systems; +using Content.Shared.Pulling.Components; +using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Robust.Shared.Audio; +using Robust.Shared.Prototypes; + +namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; + +public sealed class ShadowkinTeleportSystem : EntitySystem +{ + [Dependency] private readonly ShadowkinPowerSystem _power = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly IEntityManager _entity = default!; + [Dependency] private readonly StaminaSystem _stamina = default!; + [Dependency] private readonly PullingSystem _pulling = default!; + [Dependency] private readonly SharedActionsSystem _actions = default!; + [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly MagicSystem _magic = default!; + + private WorldTargetAction _action = default!; + + public override void Initialize() + { + base.Initialize(); + + _action = new WorldTargetAction(_prototype.Index("ShadowkinTeleport")); + + SubscribeLocalEvent(Startup); + SubscribeLocalEvent(Shutdown); + + SubscribeLocalEvent(Teleport); + } + + + private void Startup(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentStartup args) + { + _actions.AddAction(uid, _action, uid); + } + + private void Shutdown(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentShutdown args) + { + _actions.RemoveAction(uid, _action); + } + + + private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, ShadowkinTeleportEvent args) + { + if (args.Handled || + !_entity.TryGetComponent(args.Performer, out var comp)) + return; + + + var transform = Transform(args.Performer); + if (transform.MapID != args.Target.GetMapId(EntityManager)) + return; + + SharedPullableComponent? pullable = null; // To avoid "might not be initialized when accessed" warning + if (_entity.TryGetComponent(args.Performer, out var puller) && + puller.Pulling != null && + _entity.TryGetComponent(puller.Pulling, out pullable) && + pullable.BeingPulled) + { + // Temporarily stop pulling to avoid not teleporting to the target + _pulling.TryStopPull(pullable); + } + + // Teleport the performer to the target + _transform.SetCoordinates(args.Performer, args.Target); + transform.AttachToGridOrMap(); + + if (pullable != null && puller != null) + { + // Get transform of the pulled entity + var pulledTransform = Transform(pullable.Owner); + + // Teleport the pulled entity to the target + // TODO: Relative position to the performer + _transform.SetCoordinates(pullable.Owner, args.Target); + pulledTransform.AttachToGridOrMap(); + + // Resume pulling + // TODO: This does nothing? + _pulling.TryStartPull(puller, pullable); + } + + + // Play the teleport sound + _audio.PlayPvs(args.Sound, args.Performer, AudioParams.Default.WithVolume(args.Volume)); + + // Take power and deal stamina damage + _power.TryAddPowerLevel(comp.Owner, -args.PowerCost); + _stamina.TakeStaminaDamage(args.Performer, args.StaminaCost); + + // Speak + _magic.Speak(args); + + args.Handled = true; + } +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs new file mode 100644 index 0000000000..81ded05b26 --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs @@ -0,0 +1,274 @@ +using Content.Shared.Alert; +using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.SimpleStation14.Species.Shadowkin.Events; +using System.Threading.Tasks; + +namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; + +public sealed class ShadowkinPowerSystem : EntitySystem +{ + [Dependency] private readonly IEntityManager _entity = default!; + [Dependency] private readonly AlertsSystem _alerts = default!; + + private readonly Dictionary _powerDictionary; + + public ShadowkinPowerSystem() + { + var Locale = IoCManager.Resolve(); // Whyyyy + + _powerDictionary = new Dictionary + { + { ShadowkinPowerThreshold.Max, Locale.GetString("shadowkin-power-max") }, + { ShadowkinPowerThreshold.Great, Locale.GetString("shadowkin-power-great") }, + { ShadowkinPowerThreshold.Good, Locale.GetString("shadowkin-power-good") }, + { ShadowkinPowerThreshold.Okay, Locale.GetString("shadowkin-power-okay") }, + { ShadowkinPowerThreshold.Tired, Locale.GetString("shadowkin-power-tired") }, + { ShadowkinPowerThreshold.Min, Locale.GetString("shadowkin-power-min") } + }; + } + + /// The current power level. + /// The name of the power level. + public string GetLevelName(float powerLevel) + { + // Placeholders + var result = ShadowkinPowerThreshold.Min; + var value = ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Max]; + + // Find the highest threshold that is lower than the current power level + foreach (var threshold in ShadowkinComponent.PowerThresholds) + { + if (threshold.Value <= value && + threshold.Value >= powerLevel) + { + result = threshold.Key; + value = threshold.Value; + } + } + + // Return the name of the threshold + _powerDictionary.TryGetValue(result, out var powerType); + powerType ??= Loc.GetString("shadowkin-power-okay"); + return powerType; + } + + /// + /// Sets the alert level of a shadowkin. + /// + /// The entity uid. + /// Enable the alert or not + /// The current power level. + public void UpdateAlert(EntityUid uid, bool enabled, float? powerLevel = null) + { + if (!enabled || powerLevel == null) + { + _alerts.ClearAlert(uid, AlertType.ShadowkinPower); + return; + } + + // Get shadowkin component + if (!_entity.TryGetComponent(uid, out var component)) + { + Logger.ErrorS("ShadowkinPowerSystem", "Tried to update alert of entity without shadowkin component."); + return; + } + + // 250 / 7 ~= 35 + // Pwr / 35 ~= (0-7) + // Round to ensure (0-7) + var power = Math.Clamp(Math.Round(component.PowerLevel / 35), 0, 7); + + // Set the alert level + _alerts.ShowAlert(uid, AlertType.ShadowkinPower, (short) power); + } + + + /// + /// Tries to update the power level of a shadowkin based on an amount of seconds. + /// + /// The entity uid. + /// The time since the last update in seconds. + public bool TryUpdatePowerLevel(EntityUid uid, float frameTime) + { + // Check if the entity has a shadowkin component + if (!_entity.TryGetComponent(uid, out var component)) + return false; + + // Check if power gain is enabled + if (!component.PowerLevelGainEnabled) + return false; + + // Set the new power level + UpdatePowerLevel(uid, frameTime); + + return true; + } + + /// + /// Updates the power level of a shadowkin based on an amount of seconds. + /// + /// The entity uid. + /// The time since the last update in seconds. + public void UpdatePowerLevel(EntityUid uid, float frameTime) + { + // Get shadowkin component + if (!_entity.TryGetComponent(uid, out var component)) + { + Logger.Error("Tried to update power level of entity without shadowkin component."); + return; + } + + // Calculate new power level (P = P + t * G * M) + var newPowerLevel = component.PowerLevel + frameTime * component.PowerLevelGain * component.PowerLevelGainMultiplier; + + // Clamp power level using clamp function + newPowerLevel = Math.Clamp(newPowerLevel, component.PowerLevelMin, component.PowerLevelMax); + + // Set the new power level + SetPowerLevel(uid, newPowerLevel); + } + + + /// + /// Tries to add to the power level of a shadowkin. + /// + /// The entity uid. + /// The amount to add to the power level. + public bool TryAddPowerLevel(EntityUid uid, float amount) + { + // Check if the entity has a shadowkin component + if (!_entity.TryGetComponent(uid, out _)) + return false; + + // Set the new power level + AddPowerLevel(uid, amount); + + return true; + } + + /// + /// Adds to the power level of a shadowkin. + /// + /// The entity uid. + /// The amount to add to the power level. + public void AddPowerLevel(EntityUid uid, float amount) + { + // Get shadowkin component + if (!_entity.TryGetComponent(uid, out var component)) + { + Logger.Error("Tried to add to power level of entity without shadowkin component."); + return; + } + + // Get new power level + var newPowerLevel = component.PowerLevel + amount; + + // Clamp power level using clamp function + newPowerLevel = Math.Clamp(newPowerLevel, component.PowerLevelMin, component.PowerLevelMax); + + // Set the new power level + SetPowerLevel(uid, newPowerLevel); + } + + + /// + /// Sets the power level of a shadowkin. + /// + /// The entity uid. + /// The new power level. + public void SetPowerLevel(EntityUid uid, float newPowerLevel) + { + // Get shadowkin component + if (!_entity.TryGetComponent(uid, out var component)) + { + Logger.Error("Tried to set power level of entity without shadowkin component."); + return; + } + + // Clamp power level using clamp function + newPowerLevel = Math.Clamp(newPowerLevel, component.PowerLevelMin, component.PowerLevelMax); + + // Set the new power level + component._powerLevel = newPowerLevel; + } + + + /// + /// Tries to blackeye a shadowkin. + /// + public bool TryBlackeye(EntityUid uid) + { + // Raise an attempted blackeye event + var ev = new ShadowkinBlackeyeAttemptEvent(uid); + RaiseLocalEvent(ev); + if (ev.Cancelled) + return false; + + Blackeye(uid); + return true; + } + + /// + /// Blackeyes a shadowkin. + /// + public void Blackeye(EntityUid uid) + { + // Get shadowkin component + if (!_entity.TryGetComponent(uid, out var component)) + { + Logger.Error("Tried to blackeye entity without shadowkin component."); + return; + } + + component.Blackeye = true; + RaiseNetworkEvent(new ShadowkinBlackeyeEvent(uid)); + RaiseLocalEvent(new ShadowkinBlackeyeEvent(uid)); + } + + + /// + /// Tries to add a power multiplier. + /// + /// The entity uid. + /// The multiplier to add. + /// The time in seconds to wait before removing the multiplier. + public bool TryAddMultiplier(EntityUid uid, float multiplier, float? time = null) + { + if (!_entity.HasComponent(uid) || + float.IsNaN(multiplier)) + return false; + + AddMultiplier(uid, multiplier, time); + + return true; + } + + /// + /// Adds a power multiplier. + /// + /// The entity uid. + /// The multiplier to add. + /// The time in seconds to wait before removing the multiplier. + public void AddMultiplier(EntityUid uid, float multiplier, float? time = null) + { + // Get shadowkin component + if (!_entity.TryGetComponent(uid, out var component)) + { + Logger.Error("Tried to add multiplier to entity without shadowkin component."); + return; + } + + // Add the multiplier + component.PowerLevelGainMultiplier += multiplier; + + // Remove the multiplier after a certain amount of time + if (time != null) + { + Task.Run(async () => + { + await Task.Delay((int) time * 1000); + component.PowerLevelGainMultiplier -= multiplier; + }); + } + } +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.Trait.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.Trait.cs new file mode 100644 index 0000000000..a98bf50134 --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.Trait.cs @@ -0,0 +1,20 @@ +using Content.Server.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.SimpleStation14.Species.Shadowkin.Events; + +namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; + +public sealed class ShadowkinBlackeyeTraitSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnStartup); + } + + private void OnStartup(EntityUid uid, ShadowkinBlackeyeTraitComponent _, ComponentStartup args) + { + RaiseLocalEvent(uid, new ShadowkinBlackeyeEvent(uid, false)); + RaiseNetworkEvent(new ShadowkinBlackeyeEvent(uid, false)); + } +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs new file mode 100644 index 0000000000..1e20a215aa --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs @@ -0,0 +1,94 @@ +using Content.Server.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.SimpleStation14.Species.Shadowkin.Events; +using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.Damage.Systems; +using Content.Shared.Damage; +using Content.Shared.Damage.Components; +using Content.Shared.Mobs; +using Content.Shared.Damage.Prototypes; +using Robust.Shared.Prototypes; +using Content.Shared.Mobs.Systems; +using Content.Shared.Popups; + +namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; + +public sealed class ShadowkinBlackeyeSystem : EntitySystem +{ + [Dependency] private readonly ShadowkinPowerSystem _power = default!; + [Dependency] private readonly IEntityManager _entity = default!; + [Dependency] private readonly StaminaSystem _stamina = default!; + [Dependency] private readonly DamageableSystem _damageable = default!; + [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly MobThresholdSystem _mobThreshold = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnBlackeyeAttempt); + SubscribeAllEvent(OnBlackeye); + } + + + private void OnBlackeyeAttempt(ShadowkinBlackeyeAttemptEvent ev) + { + if (!_entity.TryGetComponent(ev.Uid, out var component) || + component.Blackeye || + !(component.PowerLevel <= ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Min] + 5)) + ev.Cancel(); + } + + private void OnBlackeye(ShadowkinBlackeyeEvent ev) + { + // Check if the entity is a shadowkin + if (!_entity.TryGetComponent(ev.Uid, out var component)) + return; + + // Stop gaining power + component.Blackeye = true; + component.PowerLevelGainEnabled = false; + _power.SetPowerLevel(ev.Uid, ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Min]); + + // Update client state + Dirty(component); + + // Remove powers + _entity.RemoveComponent(ev.Uid); + _entity.RemoveComponent(ev.Uid); + _entity.RemoveComponent(ev.Uid); + _entity.RemoveComponent(ev.Uid); + + + if (!ev.Damage) + return; + + // Popup + _popup.PopupEntity(Loc.GetString("shadowkin-blackeye"), ev.Uid, ev.Uid, PopupType.Large); + + // Stamina crit + if (_entity.TryGetComponent(ev.Uid, out var stamina)) + { + _stamina.TakeStaminaDamage(ev.Uid, stamina.CritThreshold, null, ev.Uid); + } + + // Nearly crit with cellular damage + // If already 5 damage off of crit, don't do anything + if (!_entity.TryGetComponent(ev.Uid, out var damageable) || + !_mobThreshold.TryGetThresholdForState(ev.Uid, MobState.Critical, out var key)) + return; + + var minus = damageable.TotalDamage; + + _damageable.TryChangeDamage( + ev.Uid, + new DamageSpecifier(_prototype.Index("Cellular"), + Math.Max((double) (key.Value - minus - 5), 0)), + true, + true, + null, + null, + false + ); + } +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs new file mode 100644 index 0000000000..b6d862b693 --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs @@ -0,0 +1,230 @@ +using System.Numerics; +using Content.Server.Mind; +using Content.Server.Mind.Components; +using Content.Server.SimpleStation14.Species.Shadowkin.Events; +using Content.Shared.Examine; +using Content.Shared.IdentityManagement; +using Content.Shared.Interaction; +using Content.Shared.Mobs.Systems; +using Content.Shared.Physics; +using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.SimpleStation14.Species.Shadowkin.Events; +using Robust.Shared.Map; +using Robust.Shared.Random; + +namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; + +public sealed class ShadowkinSystem : EntitySystem +{ + [Dependency] private readonly ShadowkinPowerSystem _power = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly IEntityManager _entity = default!; + [Dependency] private readonly SharedInteractionSystem _interaction = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnExamine); + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnShutdown); + } + + + private void OnExamine(EntityUid uid, ShadowkinComponent component, ExaminedEvent args) + { + if (!args.IsInDetailsRange) + return; + + var powerType = _power.GetLevelName(component.PowerLevel); + + // Show exact values for yourself + if (args.Examined == args.Examiner) + { + args.PushMarkup(Loc.GetString("shadowkin-power-examined-self", + ("power", (int) component.PowerLevel), + ("powerMax", component.PowerLevelMax), + ("powerType", powerType) + )); + } + // Show general values for others + else + { + args.PushMarkup(Loc.GetString("shadowkin-power-examined-other", + ("target", Identity.Entity(uid, _entity)), + ("powerType", powerType) + )); + } + } + + private void OnInit(EntityUid uid, ShadowkinComponent component, ComponentInit args) + { + if (component.PowerLevel <= ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Min] + 1f) + _power.SetPowerLevel(uid, ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Good]); + + var max = _random.NextFloat(component.MaxedPowerRateMin, component.MaxedPowerRateMax); + component.MaxedPowerAccumulator = max; + component.MaxedPowerRoof = max; + + var min = _random.NextFloat(component.MinPowerMin, component.MinPowerMax); + component.MinPowerAccumulator = min; + component.MinPowerRoof = min; + + _power.UpdateAlert(uid, true, component.PowerLevel); + } + + private void OnShutdown(EntityUid uid, ShadowkinComponent component, ComponentShutdown args) + { + _power.UpdateAlert(uid, false); + } + + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = _entity.EntityQueryEnumerator(); + + // Update power level for all shadowkin + while (query.MoveNext(out var uid, out var shadowkin)) + { + // Skip if the shadowkin is dead or catatonic + if (_mobState.IsDead(uid) || + !_entity.System().TryGetMind(uid, out var mind) || + mind.Session == null) + continue; + + var oldPowerLevel = _power.GetLevelName(shadowkin.PowerLevel); + + _power.TryUpdatePowerLevel(uid, frameTime); + + if (oldPowerLevel != _power.GetLevelName(shadowkin.PowerLevel)) + { + _power.TryBlackeye(uid); + Dirty(shadowkin); + } + // I can't figure out how to get this to go to the 100% filled state in the above if statement 😢 + _power.UpdateAlert(uid, true, shadowkin.PowerLevel); + + #region MaxPower + // Check if they're at max power + if (shadowkin.PowerLevel >= ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Max]) + { + // If so, start the timer + shadowkin.MaxedPowerAccumulator -= frameTime; + + // If the time's up, do things + if (shadowkin.MaxedPowerAccumulator <= 0f) + { + // Randomize the timer + var next = _random.NextFloat(shadowkin.MaxedPowerRateMin, shadowkin.MaxedPowerRateMax); + shadowkin.MaxedPowerRoof = next; + shadowkin.MaxedPowerAccumulator = next; + + var chance = _random.Next(7); + + if (chance <= 2) + { + ForceDarkSwap(uid, shadowkin); + } + else if (chance <= 7) + { + ForceTeleport(uid, shadowkin); + } + } + } + else + { + // Slowly regenerate if not maxed + shadowkin.MaxedPowerAccumulator += frameTime / 5f; + shadowkin.MaxedPowerAccumulator = Math.Clamp(shadowkin.MaxedPowerAccumulator, 0f, shadowkin.MaxedPowerRoof); + } + #endregion + + #region MinPower + // Check if they're at the average of the Tired and Okay thresholds + // Just Tired is too little, and Okay is too much, get the average + if (shadowkin.PowerLevel <= + ( + ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Tired] + + ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Okay] + ) / 2f + ) + { + // If so, start the timer + shadowkin.MinPowerAccumulator -= frameTime; + + // If the timer is up, force rest + if (shadowkin.MinPowerAccumulator <= 0f) + { + // Random new timer + var next = _random.NextFloat(shadowkin.MinPowerMin, shadowkin.MinPowerMax); + shadowkin.MinPowerRoof = next; + shadowkin.MinPowerAccumulator = next; + + // Send event to rest + RaiseLocalEvent(uid, new ShadowkinRestEvent { Performer = uid }); + } + } + else + { + // Slowly regenerate if not tired + shadowkin.MinPowerAccumulator += frameTime / 5f; + shadowkin.MinPowerAccumulator = Math.Clamp(shadowkin.MinPowerAccumulator, 0f, shadowkin.MinPowerRoof); + } + #endregion + } + } + + private void ForceDarkSwap(EntityUid uid, ShadowkinComponent component) + { + // Add/Remove DarkSwapped component, which will handle the rest + if (_entity.HasComponent(uid)) + { + RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(uid, false)); + _entity.RemoveComponent(uid); + } + else + { + RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(uid, true)); + _entity.EnsureComponent(uid); + } + } + + private void ForceTeleport(EntityUid uid, ShadowkinComponent component) + { + // Create the event we'll later raise, and set it to our Shadowkin. + var args = new ShadowkinTeleportEvent + { + Performer = uid + }; + + // Pick a random location on the map until we find one that can be reached. + var coords = Transform(uid).Coordinates; + EntityCoordinates? target = null; + + for (var i = 8; i != 0; i--) // It'll iterate up to 8 times, shrinking in distance each time, and if it doesn't find a valid location, it'll return. + { + var angle = Angle.FromDegrees(_random.Next(360)); + var offset = new Vector2((float) (i * Math.Cos(angle)), (float) (i * Math.Sin(angle))); + + target = coords.Offset(offset); + + if (_interaction.InRangeUnobstructed(uid, target.Value, 0, + CollisionGroup.MobMask | CollisionGroup.MobLayer)) + break; + + target = null; + } + + // If we didn't find a valid location, return. + if (target == null) + return; + + args.Target = target.Value; + + // Raise the event to teleport the Shadowkin. + RaiseLocalEvent(uid, args); + } +} diff --git a/Content.Server/SimpleStation14/Speech/Components/ShadowkinAccentComponent.cs b/Content.Server/SimpleStation14/Speech/Components/ShadowkinAccentComponent.cs new file mode 100644 index 0000000000..20ab1723a7 --- /dev/null +++ b/Content.Server/SimpleStation14/Speech/Components/ShadowkinAccentComponent.cs @@ -0,0 +1,4 @@ +namespace Content.Server.Speech.Components; + +[RegisterComponent] +public sealed class ShadowkinAccentComponent : Component {} diff --git a/Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs b/Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs new file mode 100644 index 0000000000..97c036f679 --- /dev/null +++ b/Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs @@ -0,0 +1,38 @@ +using System.Text.RegularExpressions; +using Content.Server.Speech; +using Content.Server.Speech.Components; +using Robust.Shared.Random; + +namespace Content.Server.SimpleStation14.Speech.EntitySystems +{ + public sealed class ShadowkinAccentSystem : EntitySystem + { + [Dependency] private readonly IRobustRandom _random = default!; + + private static readonly Regex mRegex = new(@"[adgjmps]", RegexOptions.Compiled | RegexOptions.IgnoreCase); + private static readonly Regex aRegex = new(@"[behknqtwy]", RegexOptions.Compiled | RegexOptions.IgnoreCase); + private static readonly Regex rRegex = new(@"[cfiloruxz]", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + public override void Initialize() + { + SubscribeLocalEvent(OnAccent); + } + + public string Accentuate(string message) + { + message = message.Trim(); + + // Replace letters with other letters + message = mRegex.Replace(message, "m"); + message = aRegex.Replace(message, "a"); + message = rRegex.Replace(message, "r"); + + return message; + } + + private void OnAccent(EntityUid uid, ShadowkinAccentComponent component, AccentGetEvent args) + { + args.Message = Accentuate(args.Message); + } + } +} diff --git a/Content.Shared/Alert/AlertCategory.cs b/Content.Shared/Alert/AlertCategory.cs index 7450f585a4..bba215c474 100644 --- a/Content.Shared/Alert/AlertCategory.cs +++ b/Content.Shared/Alert/AlertCategory.cs @@ -12,6 +12,7 @@ public enum AlertCategory Health, Internals, Stamina, + ShadowkinPower, Piloting, Hunger, Thirst, diff --git a/Content.Shared/Alert/AlertType.cs b/Content.Shared/Alert/AlertType.cs index e0a7ac99f8..237e13a924 100644 --- a/Content.Shared/Alert/AlertType.cs +++ b/Content.Shared/Alert/AlertType.cs @@ -30,6 +30,7 @@ public enum AlertType : byte Thirsty, Parched, Stamina, + ShadowkinPower, Pulled, Pulling, Magboots, diff --git a/Content.Shared/Chat/ChatChannel.cs b/Content.Shared/Chat/ChatChannel.cs index 890d1282b2..7e34545809 100644 --- a/Content.Shared/Chat/ChatChannel.cs +++ b/Content.Shared/Chat/ChatChannel.cs @@ -84,10 +84,16 @@ public enum ChatChannel : ushort /// Telepathic = 1 << 14, + /// + /// Empathy channel for Shadowkin. + /// + Empathy = 1 << 15, + /// /// Channels considered to be IC. /// - IC = Local | Whisper | Radio | Dead | Emotes | Damage | Visual | Telepathic, //Nyano - Summary: Adds telepathic as an 'IC' labelled chat.. + //Nyano - Summary: Adds telepathic as an 'IC' labelled chat.. Shadowkin: Adds empathy likewise + IC = Local | Whisper | Radio | Dead | Emotes | Damage | Visual | Telepathic | Empathy, AdminRelated = Admin | AdminAlert | AdminChat, } diff --git a/Content.Shared/Chat/ChatSelectChannel.cs b/Content.Shared/Chat/ChatSelectChannel.cs index 5104bbc306..d9b4dbb43f 100644 --- a/Content.Shared/Chat/ChatSelectChannel.cs +++ b/Content.Shared/Chat/ChatSelectChannel.cs @@ -52,10 +52,15 @@ public enum ChatSelectChannel : ushort Admin = ChatChannel.AdminChat, /// - /// Nyano - Summary:. Telepathic channel for all psionic entities. + /// Nyano - Summary:. Telepathic channel for all psionic entities. /// Telepathic = ChatChannel.Telepathic, + /// + /// Shadowkin empathy channel + /// + Empathy = ChatChannel.Empathy, + Console = ChatChannel.Unspecified } } diff --git a/Content.Shared/Chat/SharedChatSystem.cs b/Content.Shared/Chat/SharedChatSystem.cs index 454457fffd..f8317df86f 100644 --- a/Content.Shared/Chat/SharedChatSystem.cs +++ b/Content.Shared/Chat/SharedChatSystem.cs @@ -20,7 +20,8 @@ public abstract class SharedChatSystem : EntitySystem public const char EmotesAltPrefix = '*'; public const char AdminPrefix = ']'; public const char WhisperPrefix = ','; - public const char TelepathicPrefix = '='; //Nyano - Summary: Adds the telepathic channel's prefix. + public const char TelepathicPrefix = '='; //Nyano - Summary: Adds the telepathic channel's prefix. + public const char EmpathyPrefix = '~'; //Shadowkin public const char DefaultChannelKey = 'h'; [ValidatePrototypeId] diff --git a/Content.Shared/Humanoid/NamingSystem.cs b/Content.Shared/Humanoid/NamingSystem.cs index 7ca4fac5b5..ae5dbd73ed 100644 --- a/Content.Shared/Humanoid/NamingSystem.cs +++ b/Content.Shared/Humanoid/NamingSystem.cs @@ -37,6 +37,9 @@ public string GetName(string species, Gender? gender = null) case SpeciesNaming.FirstDashFirst: return Loc.GetString("namepreset-firstdashfirst", ("first1", GetFirstName(speciesProto, gender)), ("first2", GetFirstName(speciesProto, gender))); + case SpeciesNaming.First: + return Loc.GetString("namepreset-first", + ("first", GetFirstName(speciesProto, gender))); case SpeciesNaming.FirstLast: default: return Loc.GetString("namepreset-firstlast", diff --git a/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs b/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs index c1e8f24189..f8a780ca34 100644 --- a/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs +++ b/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs @@ -130,4 +130,5 @@ public enum SpeciesNaming : byte LastNoFirst, //End of Nyano - Summary: for Oni naming TheFirstofLast, + First, // Parkstation-Shadowkin } diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/EmpathyChatComponent.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/EmpathyChatComponent.cs new file mode 100644 index 0000000000..1612003cef --- /dev/null +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/EmpathyChatComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.SimpleStation14.Species.Shadowkin.Components; + +[RegisterComponent, NetworkedComponent] +public sealed partial class EmpathyChatComponent : Component +{ + +} diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs new file mode 100644 index 0000000000..103c8d2d07 --- /dev/null +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs @@ -0,0 +1,121 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; + +namespace Content.Shared.SimpleStation14.Species.Shadowkin.Components; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class ShadowkinComponent : Component +{ + #region Random occurrences + [ViewVariables(VVAccess.ReadWrite)] + public float MaxedPowerAccumulator = 0f; + + [ViewVariables(VVAccess.ReadWrite)] + public float MaxedPowerRoof = 0f; + + [ViewVariables(VVAccess.ReadWrite)] + public float MaxedPowerRateMin = 45f; + + [ViewVariables(VVAccess.ReadWrite)] + public float MaxedPowerRateMax = 150f; + + + [ViewVariables(VVAccess.ReadWrite)] + public float MinPowerAccumulator = 0f; + + [ViewVariables(VVAccess.ReadWrite)] + public float MinPowerRoof = 0f; + + [ViewVariables(VVAccess.ReadWrite)] + public float MinPowerMin = 15f; + + [ViewVariables(VVAccess.ReadWrite)] + public float MinPowerMax = 60f; + #endregion + + + #region Shader + /// + /// Automatically set to eye color. + /// + [ViewVariables(VVAccess.ReadOnly)] + public Vector3 TintColor = new(0.5f, 0f, 0.5f); + + /// + /// Based on PowerLevel. + /// + [ViewVariables(VVAccess.ReadWrite)] + public float TintIntensity = 0.65f; + #endregion + + + #region Power level + /// + /// Current amount of energy. + /// + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public float PowerLevel + { + get => _powerLevel; + set => _powerLevel = Math.Clamp(value, PowerLevelMin, PowerLevelMax); + } + public float _powerLevel = 150f; + + /// + /// Don't let PowerLevel go above this value. + /// + [ViewVariables(VVAccess.ReadOnly), AutoNetworkedField] + public float PowerLevelMax = PowerThresholds[ShadowkinPowerThreshold.Max]; + + /// + /// Blackeyes if PowerLevel is this value. + /// + [ViewVariables(VVAccess.ReadOnly), AutoNetworkedField] + public float PowerLevelMin = PowerThresholds[ShadowkinPowerThreshold.Min]; + + /// + /// How much energy is gained per second. + /// + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public float PowerLevelGain = 2f; + + /// + /// Power gain multiplier + /// + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public float PowerLevelGainMultiplier = 1f; + + /// + /// Whether to gain power or not. + /// + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public bool PowerLevelGainEnabled = true; + + /// + /// Whether they are a blackeye. + /// + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public bool Blackeye = false; + + + public static readonly Dictionary PowerThresholds = new() + { + { ShadowkinPowerThreshold.Max, 250.0f }, + { ShadowkinPowerThreshold.Great, 200.0f }, + { ShadowkinPowerThreshold.Good, 150.0f }, + { ShadowkinPowerThreshold.Okay, 100.0f }, + { ShadowkinPowerThreshold.Tired, 50.0f }, + { ShadowkinPowerThreshold.Min, 0.0f }, + }; + #endregion +} + +public enum ShadowkinPowerThreshold : byte +{ + Max = 1 << 4, + Great = 1 << 3, + Good = 1 << 2, + Okay = 1 << 1, + Tired = 1 << 0, + Min = 0, +} diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs new file mode 100644 index 0000000000..7cfd9ba380 --- /dev/null +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs @@ -0,0 +1,34 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.SimpleStation14.Species.Shadowkin.Components; + +[RegisterComponent, NetworkedComponent] +public sealed partial class ShadowkinDarkSwappedComponent : Component +{ + /// + /// If it should be sent to the dark + /// + [DataField("invisible")] + public bool Invisible = true; + + /// + /// If it should dim nearby lights + /// + [DataField("darken"), ViewVariables(VVAccess.ReadWrite)] + public bool Darken = true; + + /// + /// How far to dim nearby lights + /// + [DataField("range"), ViewVariables(VVAccess.ReadWrite)] + public float DarkenRange = 5f; + + [ViewVariables(VVAccess.ReadOnly)] + public List DarkenedLights = new(); + + [ViewVariables(VVAccess.ReadWrite)] + public float DarkenRate = 0.084f; // 1/12th of a second + + [ViewVariables(VVAccess.ReadWrite)] + public float DarkenAccumulator = 0f; +} diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs new file mode 100644 index 0000000000..353313b2b3 --- /dev/null +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs @@ -0,0 +1,32 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.SimpleStation14.Species.Shadowkin.Events; + +/// +/// Raised to notify other systems of an attempt to blackeye a shadowkin. +/// +public sealed class ShadowkinBlackeyeAttemptEvent : CancellableEntityEventArgs +{ + public readonly EntityUid Uid; + + public ShadowkinBlackeyeAttemptEvent(EntityUid uid) + { + Uid = uid; + } +} + +/// +/// Raised when a shadowkin becomes a blackeye. +/// +[Serializable, NetSerializable] +public sealed class ShadowkinBlackeyeEvent : EntityEventArgs +{ + public readonly EntityUid Uid; + public readonly bool Damage; + + public ShadowkinBlackeyeEvent(EntityUid uid, bool damage = true) + { + Uid = uid; + Damage = damage; + } +} diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs new file mode 100644 index 0000000000..d0d3c67ddf --- /dev/null +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs @@ -0,0 +1,19 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.SimpleStation14.Species.Shadowkin.Events; + +/// +/// Raised over network to notify the client that they're going in/out of The Dark. +/// +[Serializable, NetSerializable] +public sealed class ShadowkinDarkSwappedEvent : EntityEventArgs +{ + public EntityUid Performer { get; } + public bool DarkSwapped { get; } + + public ShadowkinDarkSwappedEvent(EntityUid performer, bool darkSwapped) + { + Performer = performer; + DarkSwapped = darkSwapped; + } +} diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs new file mode 100644 index 0000000000..9cb201bc97 --- /dev/null +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -0,0 +1,34 @@ +using Content.Shared.Interaction.Events; +using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.Popups; +using Robust.Shared.Timing; + +namespace Content.Shared.SimpleStation14.Species.Shadowkin.Systems; + +public sealed class ShadowkinDarken : EntitySystem +{ + [Dependency] private readonly IEntityManager _entity = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly IGameTiming _gameTiming = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInteractionAttempt); + } + + + private void OnInteractionAttempt(EntityUid uid, ShadowkinDarkSwappedComponent component, InteractionAttemptEvent args) + { + if (args.Target == null || !_entity.TryGetComponent(args.Target, out var __) || + _entity.TryGetComponent(args.Target, out _)) + return; + + args.Cancel(); + if (_gameTiming.InPrediction) + return; + + _popup.PopupEntity(Loc.GetString("ethereal-pickup-fail"), args.Target.Value, uid); + } +} diff --git a/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapoff.ogg b/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapoff.ogg new file mode 100644 index 0000000000000000000000000000000000000000..61f331a68a1a8594312d679abc811046b3dcd7f4 GIT binary patch literal 18887 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 literal 0 HcmV?d00001 diff --git a/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapon.ogg b/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapon.ogg new file mode 100644 index 0000000000000000000000000000000000000000..deb6139934ef228ee2dddb1782a22b375bef4318 GIT binary patch literal 27207 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 KyM|pI%1)4={&AE5 literal 0 HcmV?d00001 diff --git a/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/futuristic-teleport.ogg b/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/futuristic-teleport.ogg new file mode 100644 index 0000000000000000000000000000000000000000..87aeb33fdd9656aa2ddc7b7f107b2cf3385e3bc7 GIT binary patch literal 32720 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 QuD^hgpnbJ=ZUylF1Jchjy8r+H literal 0 HcmV?d00001 diff --git a/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/license.txt b/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/license.txt new file mode 100644 index 0000000000..c77ea8eb09 --- /dev/null +++ b/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/license.txt @@ -0,0 +1,4 @@ +darkswapon.ogg licensed under Pixabay Licence taken from https://pixabay.com/users/cristian_changing-30278997/ +darkswapoff.ogg licensed under Pixabay Licence taken from https://pixabay.com/users/cristian_changing-30278997/ +futuristic-teleport.ogg licensed under Pixabay Licence taken from https://pixabay.com/users/cristian_changing-30278997/ +teleport.ogg licensed under Pixabay Licence taken from https://pixabay.com/users/cristian_changing-30278997/ diff --git a/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/teleport.ogg b/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/teleport.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3cca66b47cb1958e4570392e844aaa1d1f789e65 GIT binary patch literal 14699 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 literal 0 HcmV?d00001 diff --git a/Resources/Locale/en-US/chat/managers/chat-manager.ftl b/Resources/Locale/en-US/chat/managers/chat-manager.ftl index 82f598fb4e..29aec8350f 100644 --- a/Resources/Locale/en-US/chat/managers/chat-manager.ftl +++ b/Resources/Locale/en-US/chat/managers/chat-manager.ftl @@ -47,6 +47,10 @@ chat-manager-send-hook-ooc-wrap-message = OOC: (D){$senderName}: {$message} chat-manager-dead-channel-name = DEAD chat-manager-admin-channel-name = ADMIN +chat-manager-send-empathy-chat-wrap-message = {$empathyChannelName}: {$message} +chat-manager-send-empathy-chat-wrap-message-admin = {$empathyChannelName} - {$source}: {$message} +chat-manager-empathy-channel-name = EMPATHY + ## Speech verbs for chat chat-speech-verb-suffix-exclamation = ! diff --git a/Resources/Locale/en-US/chat/ui/chat-box.ftl b/Resources/Locale/en-US/chat/ui/chat-box.ftl index ddf52d8be8..45ef7ac092 100644 --- a/Resources/Locale/en-US/chat/ui/chat-box.ftl +++ b/Resources/Locale/en-US/chat/ui/chat-box.ftl @@ -12,6 +12,7 @@ hud-chatbox-select-channel-OOC = OOC hud-chatbox-select-channel-Damage = Damage hud-chatbox-select-channel-Visual = Actions hud-chatbox-select-channel-Radio = Radio +hud-chatbox-select-channel-Empathy = Empathy hud-chatbox-channel-Admin = Admin Misc hud-chatbox-channel-AdminAlert = Admin Alert @@ -24,6 +25,7 @@ hud-chatbox-channel-LOOC = LOOC hud-chatbox-channel-OOC = OOC hud-chatbox-channel-Radio = Radio hud-chatbox-channel-Server = Server +hud-chatbox-channel-Empathy = Empathy hud-chatbox-channel-Visual = Actions hud-chatbox-channel-Damage = Damage hud-chatbox-channel-Unspecified = Unspecified diff --git a/Resources/Locale/en-US/markings/slimeperson.ftl b/Resources/Locale/en-US/markings/slimeperson.ftl index 0de26b2dbc..b42aea7af5 100644 --- a/Resources/Locale/en-US/markings/slimeperson.ftl +++ b/Resources/Locale/en-US/markings/slimeperson.ftl @@ -1,17 +1,17 @@ -marking-SlimeGradientLeftArm-gradient_left_arm = Slime Left Arm (Gradient) -marking-SlimeGradientLeftArm = Slime Left Arm (Gradient) +marking-SlimeGradientLeftArm-gradient_left_arm = Left Arm (Gradient) +marking-SlimeGradientLeftArm = Left Arm (Gradient) -marking-SlimeGradientRightArm-gradient_right_arm = Slime Right Arm (Gradient) -marking-SlimeGradientRightArm = Slime Right Arm (Gradient) +marking-SlimeGradientRightArm-gradient_right_arm = Right Arm (Gradient) +marking-SlimeGradientRightArm = Right Arm (Gradient) -marking-SlimeGradientLeftLeg-gradient_left_leg = Slime Left Leg (Gradient) -marking-SlimeGradientLeftLeg = Slime Left Leg (Gradient) +marking-SlimeGradientLeftLeg-gradient_left_leg = Left Leg (Gradient) +marking-SlimeGradientLeftLeg = Left Leg (Gradient) -marking-SlimeGradientRightLeg-gradient_right_leg = Slime Right Leg (Gradient) -marking-SlimeGradientRightLeg = Slime Right Leg (Gradient) +marking-SlimeGradientRightLeg-gradient_right_leg = Right Leg (Gradient) +marking-SlimeGradientRightLeg = Right Leg (Gradient) -marking-SlimeGradientLeftHand-gradient_left_hand = Slime Left Hand (Gradient) -marking-SlimeGradientLeftHand = Slime Left Hand (Gradient) +marking-SlimeGradientLeftHand-gradient_left_hand = Left Hand (Gradient) +marking-SlimeGradientLeftHand = Left Hand (Gradient) -marking-SlimeGradientRightHand-gradient_Right_hand = Slime Right Hand (Gradient) -marking-SlimeGradientRightHand = Slime Right Hand (Gradient) +marking-SlimeGradientRightHand-gradient_Right_hand = Right Hand (Gradient) +marking-SlimeGradientRightHand = Right Hand (Gradient) diff --git a/Resources/Locale/en-US/simplestation14/Content/Interaction/interaction-popup.ftl b/Resources/Locale/en-US/simplestation14/Content/Interaction/interaction-popup.ftl new file mode 100644 index 0000000000..55c0b95785 --- /dev/null +++ b/Resources/Locale/en-US/simplestation14/Content/Interaction/interaction-popup.ftl @@ -0,0 +1,6 @@ +petting-success-generic-others = { CAPITALIZE(THE($user)) } pets {THE($target)}. +petting-success-soft-floofy-others = { CAPITALIZE(THE($user)) } pets {THE($target)} on {POSS-ADJ($target)} soft floofy head. + +hugging-failure-generic = You try to hug {THE($target)}, but they don't seem to like it. +hugging-failure-generic-others = {CAPITALIZE(THE($user))} tries to hug {THE($target)}, they don't seem to like it. +hugging-failure-generic-target = {CAPITALIZE(THE($user))} hugs you, you frown back. diff --git a/Resources/Locale/en-US/simplestation14/Content/Species/Shadowkin/shadowkin.ftl b/Resources/Locale/en-US/simplestation14/Content/Species/Shadowkin/shadowkin.ftl new file mode 100644 index 0000000000..65b1c2caab --- /dev/null +++ b/Resources/Locale/en-US/simplestation14/Content/Species/Shadowkin/shadowkin.ftl @@ -0,0 +1,11 @@ +shadowkin-power-examined-other = {CAPITALIZE(SUBJECT($target))} seems to be {$powerType}. +shadowkin-power-examined-self = You have {$power}/{$powerMax} energy, you are {$powerType}. + +shadowkin-power-max = energetic +shadowkin-power-great = great +shadowkin-power-good = good +shadowkin-power-okay = okay +shadowkin-power-tired = exhausted +shadowkin-power-min = a blackeye + +shadowkin-blackeye = You feel your power draining away, you are exhausted! diff --git a/Resources/Locale/en-US/simplestation14/Prototypes/Alerts/shadowkin.ftl b/Resources/Locale/en-US/simplestation14/Prototypes/Alerts/shadowkin.ftl new file mode 100644 index 0000000000..b45ae82583 --- /dev/null +++ b/Resources/Locale/en-US/simplestation14/Prototypes/Alerts/shadowkin.ftl @@ -0,0 +1,2 @@ +alerts-shadowkin-power-name = Power Level +alerts-shadowkin-power-desc = How much energy you have to expend via your abilities. diff --git a/Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/ears.ftl b/Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/ears.ftl new file mode 100644 index 0000000000..9d41e2b645 --- /dev/null +++ b/Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/ears.ftl @@ -0,0 +1 @@ +marking-EarsShadowkin=Shadowkin diff --git a/Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/eyes.ftl b/Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/eyes.ftl new file mode 100644 index 0000000000..6107498e6c --- /dev/null +++ b/Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/eyes.ftl @@ -0,0 +1 @@ +marking-EyesShadowkin=Shadowkin diff --git a/Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/tails.ftl b/Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/tails.ftl new file mode 100644 index 0000000000..ff08e8d864 --- /dev/null +++ b/Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/tails.ftl @@ -0,0 +1,5 @@ +marking-TailShadowkin=Shadowkin +marking-TailShadowkinBig=Shadowkin (Big) +marking-TailShadowkinShorter=Shadowkin (Short) +marking-TailShadowkinMedium=Shadowkin (Medium) +marking-TailShadowkinBigFluff=Shadowkin (Big and Fluffy) diff --git a/Resources/Locale/en-US/simplestation14/Prototypes/Guidebook/species.ftl b/Resources/Locale/en-US/simplestation14/Prototypes/Guidebook/species.ftl new file mode 100644 index 0000000000..14fb0e899b --- /dev/null +++ b/Resources/Locale/en-US/simplestation14/Prototypes/Guidebook/species.ftl @@ -0,0 +1 @@ +guide-entry-shadowkin = Shadowkin diff --git a/Resources/Locale/en-US/simplestation14/Prototypes/Magic/shadowkin.ftl b/Resources/Locale/en-US/simplestation14/Prototypes/Magic/shadowkin.ftl new file mode 100644 index 0000000000..83d316b15e --- /dev/null +++ b/Resources/Locale/en-US/simplestation14/Prototypes/Magic/shadowkin.ftl @@ -0,0 +1,10 @@ +action-name-shadowkin-teleport=Teleport +action-description-shadowkin-teleport=Aaramrra! + +action-name-shadowkin-darkswap=Dark Swap +action-description-shadowkin-darkswap=Mmra Mamm! + +action-name-shadowkin-rest=Rest +action-description-shadowkin-rest=Rama + +ethereal-pickup-fail=Your hand sizzles as it passes through... diff --git a/Resources/Locale/en-US/simplestation14/Prototypes/Species/shadowkin.ftl b/Resources/Locale/en-US/simplestation14/Prototypes/Species/shadowkin.ftl new file mode 100644 index 0000000000..038f4fc29b --- /dev/null +++ b/Resources/Locale/en-US/simplestation14/Prototypes/Species/shadowkin.ftl @@ -0,0 +1 @@ +species-name-shadowkin = Shadowkin diff --git a/Resources/Locale/en-US/species/namepreset.ftl b/Resources/Locale/en-US/species/namepreset.ftl index 2d43b5f00d..2f37b5f8a3 100644 --- a/Resources/Locale/en-US/species/namepreset.ftl +++ b/Resources/Locale/en-US/species/namepreset.ftl @@ -1,3 +1,6 @@ namepreset-firstlast = {$first} {$last} namepreset-firstdashfirst = {$first1}-{$first2} -namepreset-thefirstoflast = The {$first} of {$last} \ No newline at end of file +namepreset-thefirstoflast = The {$first} of {$last} + +## Parkstation +namepreset-first = {$first} diff --git a/Resources/Prototypes/Alerts/alerts.yml b/Resources/Prototypes/Alerts/alerts.yml index e71a8ed381..d5bcea53f0 100644 --- a/Resources/Prototypes/Alerts/alerts.yml +++ b/Resources/Prototypes/Alerts/alerts.yml @@ -6,6 +6,7 @@ order: - category: Health - category: Stamina + - category: ShadowkinPower - alertType: SuitPower - category: Internals - alertType: Fire diff --git a/Resources/Prototypes/Catalog/Fills/Crates/fun.yml b/Resources/Prototypes/Catalog/Fills/Crates/fun.yml index 9c5853d49e..38a8ca58b4 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/fun.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/fun.yml @@ -20,6 +20,7 @@ - id: PlushieSharkGrey orGroup: PlushieShark - id: PlushieAtmosian + - id: PlushieShadowkin - id: PlushieDiona - id: PlushieXeno - id: PlushieHampter @@ -308,4 +309,4 @@ - id: BoxDarts amount: 1 prob: 0.05 - + diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml index c9aba6f4bd..36ee863c58 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml @@ -177,7 +177,11 @@ id: LizardChestTiger bodyPart: Chest markingCategory: Chest - speciesRestriction: [Reptilian] + speciesRestriction: + [ + Reptilian, + Shadowkin, + ] sprites: - sprite: Mobs/Customization/reptilian_parts.rsi state: body_tiger @@ -271,7 +275,7 @@ sprites: - sprite: Mobs/Customization/reptilian_parts.rsi state: horns_kobold_ears - + - type: marking id: LizardHornsFloppyKoboldEars bodyPart: HeadSide diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/slime.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/slime.yml index b827b0221c..4be0de4172 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/slime.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/slime.yml @@ -2,7 +2,11 @@ id: SlimeGradientLeftArm bodyPart: LArm markingCategory: Arms - speciesRestriction: [SlimePerson] + speciesRestriction: + [ + SlimePerson, + Shadowkin, + ] sprites: - sprite: Mobs/Customization/slime_parts.rsi state: gradient_l_arm @@ -11,7 +15,11 @@ id: SlimeGradientRightArm bodyPart: RArm markingCategory: Arms - speciesRestriction: [SlimePerson] + speciesRestriction: + [ + SlimePerson, + Shadowkin, + ] sprites: - sprite: Mobs/Customization/slime_parts.rsi state: gradient_r_arm @@ -20,7 +28,11 @@ id: SlimeGradientLeftLeg bodyPart: LFoot markingCategory: Legs - speciesRestriction: [SlimePerson] + speciesRestriction: + [ + SlimePerson, + Shadowkin, + ] sprites: - sprite: Mobs/Customization/slime_parts.rsi state: gradient_l_leg @@ -29,7 +41,11 @@ id: SlimeGradientRightLeg bodyPart: RFoot markingCategory: Legs - speciesRestriction: [SlimePerson] + speciesRestriction: + [ + SlimePerson, + Shadowkin, + ] sprites: - sprite: Mobs/Customization/slime_parts.rsi state: gradient_r_leg @@ -38,7 +54,11 @@ id: SlimeGradientLeftHand bodyPart: LHand markingCategory: Arms - speciesRestriction: [SlimePerson] + speciesRestriction: + [ + SlimePerson, + Shadowkin, + ] sprites: - sprite: Mobs/Customization/slime_parts.rsi state: gradient_l_hand @@ -47,7 +67,11 @@ id: SlimeGradientRightHand bodyPart: RHand markingCategory: Arms - speciesRestriction: [SlimePerson] + speciesRestriction: + [ + SlimePerson, + Shadowkin, + ] sprites: - sprite: Mobs/Customization/slime_parts.rsi - state: gradient_r_hand \ No newline at end of file + state: gradient_r_hand diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/tattoos.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/tattoos.yml index 04831fd028..4d3b714326 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/tattoos.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/tattoos.yml @@ -2,7 +2,7 @@ id: TattooHiveChest bodyPart: Chest markingCategory: Chest - speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy] + speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy, Shadowkin] coloring: default: type: @@ -16,7 +16,7 @@ id: TattooNightlingChest bodyPart: Chest markingCategory: Chest - speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy] + speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy, Shadowkin] coloring: default: type: @@ -30,7 +30,7 @@ id: TattooSilverburghLeftLeg bodyPart: LLeg markingCategory: Legs - speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy] + speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy, Shadowkin] coloring: default: type: @@ -44,7 +44,7 @@ id: TattooSilverburghRightLeg bodyPart: RLeg markingCategory: Legs - speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy] + speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy, Shadowkin] coloring: default: type: @@ -58,7 +58,7 @@ id: TattooCampbellLeftArm bodyPart: LArm markingCategory: Arms - speciesRestriction: [Human, Dwarf, Felinid, Oni] + speciesRestriction: [Human, Dwarf, Felinid, Oni, Shadowkin] coloring: default: type: @@ -72,7 +72,7 @@ id: TattooCampbellRightArm bodyPart: RArm markingCategory: Arms - speciesRestriction: [Human, Dwarf, Felinid, Oni] + speciesRestriction: [Human, Dwarf, Felinid, Oni, Shadowkin] coloring: default: type: @@ -86,7 +86,7 @@ id: TattooCampbellLeftLeg bodyPart: LLeg markingCategory: Legs - speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy] + speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy, Shadowkin] coloring: default: type: @@ -100,7 +100,7 @@ id: TattooCampbellRightLeg bodyPart: RLeg markingCategory: Legs - speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy] + speciesRestriction: [Human, Dwarf, Felinid, Oni, Harpy, Shadowkin] coloring: default: type: diff --git a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml index ac8d2c5417..2ac32ef54a 100644 --- a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml +++ b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml @@ -107,6 +107,7 @@ components: - type: Sprite state: off + - type: ShadowkinLight - type: PointLight enabled: true - type: PoweredLight diff --git a/Resources/Prototypes/SimpleStation14/Alerts/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Alerts/shadowkin.yml new file mode 100644 index 0000000000..126441b79d --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Alerts/shadowkin.yml @@ -0,0 +1,24 @@ +- type: alert + id: ShadowkinPower + category: ShadowkinPower + icons: + - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + state: power0 + - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + state: power1 + - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + state: power2 + - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + state: power3 + - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + state: power4 + - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + state: power5 + - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + state: power6 + - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + state: power7 + name: alerts-shadowkin-power-name + description: alerts-shadowkin-power-desc + minSeverity: 0 + maxSeverity: 7 diff --git a/Resources/Prototypes/SimpleStation14/Damage/containers.yml b/Resources/Prototypes/SimpleStation14/Damage/containers.yml new file mode 100644 index 0000000000..40a3284e7c --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Damage/containers.yml @@ -0,0 +1,10 @@ +# Use whenever this isn't BS +# - type: damageContainer +# id: Shadowkin +# supportedGroups: +# - Brute +# - Burn +# - Toxin +# - Genetic +# supportedTypes: +# - Bloodloss diff --git a/Resources/Prototypes/SimpleStation14/Damage/modifier_sets.yml b/Resources/Prototypes/SimpleStation14/Damage/modifier_sets.yml new file mode 100644 index 0000000000..2d446c37be --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Damage/modifier_sets.yml @@ -0,0 +1,13 @@ +- type: damageModifierSet + id: Shadowkin + coefficients: + Blunt: 0.95 + Slash: 1.2 + Piercing: 1.1 + Asphyxiation: 0 + Cold: 0.75 + Heat: 1.2 + Cellular: 0.25 + Bloodloss: 1.35 + Shock: 1.25 + Radiation: 1.3 diff --git a/Resources/Prototypes/SimpleStation14/Datasets/Names/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Datasets/Names/shadowkin.yml new file mode 100644 index 0000000000..f656581482 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Datasets/Names/shadowkin.yml @@ -0,0 +1,69 @@ +# Names for the shadowkin, +# Shadowkin names are descriptive of +# Their Primary Emotion, +# A State of Being, +# Or past Memories. + +- type: dataset + id: names_shadowkin + values: + # Mar + # - Mar + + # Sad + - Fragile + - Heartbreak + - Inferior + - Lone + - Lonesome + - Loss + - Solitary + - Solitude + - Sorrow + - Shade + + # Angry + - Fear + - Fearful + - Fury + - Pain + - Rage + - Rush + - Wrath + + # Happy + - Calm + - Content + - Contented + - Happy + - Hope + - Joyous + - Lovely + - Peace + - Peaceful + - Quiet + - Serene + - Serenity + - Tranquil + - Tranquility + + # Memory + - Dillusioned + - Forgotten + - Focusless + - Lost + - Memory + - Recollection + - Remembrance + - Reminisce + - Reminiscence + + # Other + - Apathy + - Collected + - Curiosity + - Free + - Interest + - Jax # White eye (jack of all trades) :) + - Still + - Unbound diff --git a/Resources/Prototypes/SimpleStation14/Entites/Body/Parts/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entites/Body/Parts/shadowkin.yml new file mode 100644 index 0000000000..67762764e0 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entites/Body/Parts/shadowkin.yml @@ -0,0 +1,156 @@ +- type: entity + id: PartShadowkin + parent: BaseItem + name: "Shadowkin body part" + abstract: true + components: + - type: Sprite + netsync: false + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + - type: Icon + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + - type: Damageable + damageContainer: Biological + - type: BodyPart + - type: ContainerContainer + containers: + bodypart: !type:Container + ents: [] + +- type: entity + id: TorsoShadowkin + name: "Shadowkin torso" + parent: PartShadowkin + components: + - type: Sprite + state: "torso_m" + - type: Icon + state: "torso_m" + - type: BodyPart + partType: Torso + +- type: entity + id: HeadShadowkin + name: "Shadowkin head" + parent: PartShadowkin + components: + - type: Sprite + state: "head_m" + - type: Icon + state: "head_m" + - type: BodyPart + partType: Head + - type: Input + context: "ghost" + - type: MovementSpeedModifier + baseWalkSpeed: 0 + baseSprintSpeed: 0 + - type: InputMover + - type: GhostOnMove + +- type: entity + id: LeftArmShadowkin + name: "left Shadowkin arm" + parent: PartShadowkin + components: + - type: Sprite + state: "l_arm" + - type: Icon + state: "l_arm" + - type: BodyPart + partType: Arm + symmetry: Left + +- type: entity + id: RightArmShadowkin + name: "right Shadowkin arm" + parent: PartShadowkin + components: + - type: Sprite + state: "r_arm" + - type: Icon + state: "r_arm" + - type: BodyPart + partType: Arm + symmetry: Right + +- type: entity + id: LeftHandShadowkin + name: "left Shadowkin hand" + parent: PartShadowkin + components: + - type: Sprite + state: "l_hand" + - type: Icon + state: "l_hand" + - type: BodyPart + partType: Hand + symmetry: Left + +- type: entity + id: RightHandShadowkin + name: "right Shadowkin hand" + parent: PartShadowkin + components: + - type: Sprite + state: "r_hand" + - type: Icon + state: "r_hand" + - type: BodyPart + partType: Hand + symmetry: Right + +- type: entity + id: LeftLegShadowkin + name: "left Shadowkin leg" + parent: PartShadowkin + components: + - type: Sprite + state: "l_leg" + - type: Icon + state: "l_leg" + - type: BodyPart + partType: Leg + symmetry: Left + - type: MovementBodyPart + +- type: entity + id: RightLegShadowkin + name: "right Shadowkin leg" + parent: PartShadowkin + components: + - type: Sprite + state: "r_leg" + - type: Icon + state: "r_leg" + - type: BodyPart + partType: Leg + symmetry: Right + - type: MovementBodyPart + +- type: entity + id: LeftFootShadowkin + name: "left Shadowkin foot" + parent: PartShadowkin + components: + - type: Sprite + state: "l_foot" + - type: Icon + state: "l_foot" + - type: BodyPart + partType: Foot + symmetry: Left + +- type: entity + id: RightFootShadowkin + name: "right Shadowkin foot" + parent: PartShadowkin + components: + - type: Sprite + state: "r_foot" + - type: Icon + state: "r_foot" + - type: BodyPart + partType: Foot + symmetry: Right + diff --git a/Resources/Prototypes/SimpleStation14/Entites/Body/Prototypes/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entites/Body/Prototypes/shadowkin.yml new file mode 100644 index 0000000000..2cbe244983 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entites/Body/Prototypes/shadowkin.yml @@ -0,0 +1,49 @@ +- type: body + id: Shadowkin + name: "Shadowkin" + root: torso + slots: + head: + part: HeadShadowkin + connections: + - torso + organs: + brain: OrganHumanBrain + eyes: OrganHumanEyes + torso: + part: TorsoShadowkin + connections: + - left arm + - right arm + - left leg + - right leg + organs: # placeholders + heart: OrganHumanHeart + # lungs: OrganLungs + stomach: OrganHumanStomach + liver: OrganHumanLiver + kidneys: OrganHumanKidneys + right arm: + part: RightArmShadowkin + connections: + - right hand + left arm: + part: LeftArmShadowkin + connections: + - left hand + right hand: + part: RightHandShadowkin + left hand: + part: LeftHandShadowkin + right leg: + part: RightLegShadowkin + connections: + - right foot + left leg: + part: LeftLegShadowkin + connections: + - left foot + right foot: + part: RightFootShadowkin + left foot: + part: LeftFootShadowkin diff --git a/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml new file mode 100644 index 0000000000..0ca063822b --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml @@ -0,0 +1,191 @@ +- type: entity + save: false + parent: BaseMobHuman + id: MobShadowkin + name: Urist McFloof + components: + - type: HumanoidAppearance + species: Shadowkin + - type: Hunger + - type: Thirst + - type: Icon + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: full + - type: Body + prototype: Shadowkin + requiredLegs: 2 + - type: DiseaseCarrier + diseaseResist: 0.1 + - type: Flammable + damage: + types: + Heat: 1.5 # burn more + - type: MobState + - type: MobThresholds + thresholds: # Weak + 0: Alive + 80: Critical + 160: Dead + - type: SlowOnDamage + speedModifierThresholds: + 48: 0.85 + 64: 0.65 + - type: Damageable + damageContainer: Biological # Shadowkin + damageModifierSet: Shadowkin + - type: Barotrauma + damage: + types: + Blunt: 0.35 # per second, scales with pressure and other constants. + - type: Bloodstream + bloodlossDamage: + types: + Bloodloss: + 1 + bloodlossHealDamage: + types: + Bloodloss: + -0.25 + - type: Tag + tags: + - CanPilot + - FootstepSound + - DoorBumpOpener + - type: Temperature + heatDamageThreshold: 330 + coldDamageThreshold: 195 + currentTemperature: 310.15 + specificHeat: 46 + coldDamage: + types: + Cold : 0.05 #per second, scales with temperature & other constants + heatDamage: + types: + Heat : 0.25 #per second, scales with temperature & other constants + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.35 + density: 130 #lower density + restitution: 0.0 + mask: + - MobMask + layer: + - MobLayer + - type: Sprite + scale: 0.85, 0.85 # Small + - type: Eye + zoom: "0.85, 0.85" + - type: MeleeWeapon + soundHit: + collection: Punch + animation: WeaponArcClaw + damage: + types: + Blunt: 2 + Slash: 3 + Piercing: 1 + - type: EmpathyChat + - type: Shadowkin + - type: ShadowkinDarkSwapPower + - type: ShadowkinRestPower + - type: ShadowkinTeleportPower + - type: Vocal + sounds: + Male: MaleSlime + Female: FemaleSlime + Unsexed: UnisexSlime + - type: CombatMode + canDisarm: true + - type: MindContainer + showExamineInfo: true + - type: Input + context: "human" + - type: MobMover + - type: InputMover + - type: Alerts + - type: Actions + - type: CameraRecoil + - type: Examiner + - type: CanHostGuardian + - type: NpcFactionMember + factions: + - NanoTrasen + - type: MailReceiver + - type: InteractionPopup + successChance: 0.75 + interactFailureString: petting-failure-generic + interactSuccessString: petting-success-soft-floofy + interactSuccessSound: /Audio/Effects/thudswoosh.ogg + messagePerceivedByOthers: petting-success-soft-floofy-others + # - type: PotentialPsionic # They've their own abilities. + - type: MovementSpeedModifier + baseWalkSpeed : 4.5 + baseSprintSpeed : 2.7 + + +- type: entity + save: false + parent: MobHumanDummy + id: MobShadowkinDummy + noSpawn: true + description: A dummy shadowkin meant to be used in character setup. + components: + - type: HumanoidAppearance + species: Shadowkin + - type: Sprite # sprite again because we want different layer ordering + netsync: false + noRot: true + drawdepth: Mobs + scale: 0.85, 0.85 # Small + layers: + - map: ["enum.HumanoidVisualLayers.Chest"] + - map: ["enum.HumanoidVisualLayers.Head"] + - map: ["enum.HumanoidVisualLayers.Snout"] + - map: ["enum.HumanoidVisualLayers.Eyes"] + - map: ["enum.HumanoidVisualLayers.RArm"] + - map: ["enum.HumanoidVisualLayers.LArm"] + - map: ["enum.HumanoidVisualLayers.RLeg"] + - map: ["enum.HumanoidVisualLayers.LLeg"] + - shader: StencilClear + sprite: Mobs/Species/Human/parts.rsi + state: l_leg + - shader: StencilMask + map: ["enum.HumanoidVisualLayers.StencilMask"] + sprite: Mobs/Customization/masking_helpers.rsi + state: full + visible: false + - map: ["enum.HumanoidVisualLayers.LFoot"] + - map: ["enum.HumanoidVisualLayers.RFoot"] + - map: ["socks"] + - map: ["underpants"] + - map: ["undershirt"] + - map: ["jumpsuit"] + - map: ["enum.HumanoidVisualLayers.LHand"] + - map: ["enum.HumanoidVisualLayers.RHand"] + - map: ["enum.HumanoidVisualLayers.Handcuffs"] + color: "#ffffff" + sprite: Objects/Misc/handcuffs.rsi + state: body-overlay-2 + visible: false + - map: ["id"] + - map: ["gloves"] + - map: ["shoes"] + - map: ["ears"] + - map: ["outerClothing"] + - map: ["eyes"] + - map: ["belt"] + - map: ["neck"] + - map: ["back"] + - map: ["enum.HumanoidVisualLayers.FacialHair"] + - map: ["enum.HumanoidVisualLayers.Hair"] + - map: ["enum.HumanoidVisualLayers.HeadSide"] + - map: ["enum.HumanoidVisualLayers.HeadTop"] + - map: ["mask"] + - map: ["head"] + - map: ["pocket1"] + - map: ["pocket2"] + - map: ["enum.HumanoidVisualLayers.Tail"] + - map: ["enum.HumanoidVisualLayers.Wings"] diff --git a/Resources/Prototypes/SimpleStation14/Entites/Objects/Fun/toys.yml b/Resources/Prototypes/SimpleStation14/Entites/Objects/Fun/toys.yml new file mode 100644 index 0000000000..a43c36b4e9 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entites/Objects/Fun/toys.yml @@ -0,0 +1,13 @@ +- type: entity + parent: BasePlushie + id: PlushieShadowkin + name: shadowkin plushie + description: A plushie of a Shadowkin. It's very soft. + components: + - type: ShadowkinDarkSwapped + invisible: false + darken: true + range: 4 + - type: Sprite + sprite: SimpleStation14/Objects/Fun/Plushies/shadowkin.rsi + state: shadowkin diff --git a/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml new file mode 100644 index 0000000000..fc78d30a3f --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml @@ -0,0 +1,47 @@ +- type: worldTargetAction + id: ShadowkinTeleport + name: action-name-shadowkin-teleport + description: action-description-shadowkin-teleport + useDelay: 2 + range: 32 + itemIconStyle: NoItem + checkCanAccess: true + repeat: true + priority: -20 + icon: + sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi + state: teleport + serverEvent: !type:ShadowkinTeleportEvent + powerCost: 35 + staminaCost: 15 + speech: action-description-shadowkin-teleport + +- type: instantAction + id: ShadowkinDarkSwap + name: action-name-shadowkin-darkswap + description: action-description-shadowkin-darkswap + useDelay: 3 + itemIconStyle: NoItem + priority: -21 + icon: + sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi + state: darkswap + serverEvent: !type:ShadowkinDarkSwapEvent + powerCostOn: 55 + powerCostOff: 40 + staminaCostOn: 0 + staminaCostOff: 0 + speech: action-description-shadowkin-darkswap + +- type: instantAction + id: ShadowkinRest + name: action-name-shadowkin-rest + description: action-description-shadowkin-rest + useDelay: 60 + itemIconStyle: NoItem + priority: -22 + icon: + sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi + state: rest + checkCanInteract: false + serverEvent: !type:ShadowkinRestEvent diff --git a/Resources/Prototypes/SimpleStation14/Shaders/shaders.yml b/Resources/Prototypes/SimpleStation14/Shaders/shaders.yml new file mode 100644 index 0000000000..b394e308c7 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Shaders/shaders.yml @@ -0,0 +1,9 @@ +- type: shader + id: ColorTint + kind: source + path: "/Textures/SimpleStation14/Shaders/color_tint.swsl" + +- type: shader + id: Ethereal + kind: source + path: "/Textures/SimpleStation14/Shaders/ethereal.swsl" diff --git a/Resources/Prototypes/SimpleStation14/Species/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Species/shadowkin.yml new file mode 100644 index 0000000000..225eb532a1 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Species/shadowkin.yml @@ -0,0 +1,159 @@ +- type: species + id: Shadowkin + name: species-name-shadowkin + roundStart: true + prototype: MobShadowkin + sprites: MobShadowkinSprites + defaultSkinTone: "#FFFFFF" + markingLimits: MobShadowkinMarkingLimits + dollPrototype: MobShadowkinDummy + skinColoration: Hues + naming: First + maleFirstNames: names_shadowkin + femaleFirstNames: names_shadowkin + minAge: 18 + maxAge: 300 + youngAge: 20 + oldAge: 250 + sexes: + - Male + - Female + - Unsexed + +- type: speciesBaseSprites + id: MobShadowkinSprites + sprites: + Head: MobShadowkinHead + Snout: MobShadowkinAnyMarkingFollowSkin + HeadTop: MobShadowkinAnyMarkingFollowSkin + HeadSide: MobShadowkinAnyMarkingFollowSkin + Wings: MobShadowkinAnyMarkingFollowSkin + Tail: MobShadowkinAnyMarkingFollowSkin + Chest: MobShadowkinTorso + Eyes: MobShadowkinEyes + LArm: MobShadowkinLArm + RArm: MobShadowkinRArm + LHand: MobShadowkinLHand + RHand: MobShadowkinRHand + LLeg: MobShadowkinLLeg + RLeg: MobShadowkinRLeg + LFoot: MobShadowkinLFoot + RFoot: MobShadowkinRFoot + +- type: markingPoints + id: MobShadowkinMarkingLimits + points: + Tail: + points: 1 + required: true + defaultMarkings: [TailShadowkin] + HeadTop: + points: 1 + required: true + defaultMarkings: [EarsShadowkin] + Chest: + points: 1 + required: false + Legs: + points: 2 + required: false + Arms: + points: 2 + required: false + +- type: humanoidBaseSprite + id: MobShadowkinAnyMarking + +- type: humanoidBaseSprite + id: MobShadowkinAnyMarkingFollowSkin + markingsMatchSkin: true + +- type: humanoidBaseSprite + id: MobShadowkinHead + baseSprite: + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobShadowkinHeadMale + baseSprite: + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobShadowkinHeadFemale + baseSprite: + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: head_f + +- type: humanoidBaseSprite + id: MobShadowkinTorso + baseSprite: + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobShadowkinTorsoMale + baseSprite: + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobShadowkinTorsoFemale + baseSprite: + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: torso_f + +- type: humanoidBaseSprite + id: MobShadowkinLLeg + baseSprite: + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: l_leg + +- type: humanoidBaseSprite + id: MobShadowkinLHand + baseSprite: + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: l_hand + +- type: humanoidBaseSprite + id: MobShadowkinEyes + baseSprite: + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: eyes + +- type: humanoidBaseSprite + id: MobShadowkinLArm + baseSprite: + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: l_arm + +- type: humanoidBaseSprite + id: MobShadowkinLFoot + baseSprite: + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: l_foot + +- type: humanoidBaseSprite + id: MobShadowkinRLeg + baseSprite: + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: r_leg + +- type: humanoidBaseSprite + id: MobShadowkinRHand + baseSprite: + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: r_hand + +- type: humanoidBaseSprite + id: MobShadowkinRArm + baseSprite: + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: r_arm + +- type: humanoidBaseSprite + id: MobShadowkinRFoot + baseSprite: + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + state: r_foot diff --git a/Resources/Prototypes/SimpleStation14/Traits/disabilities.yml b/Resources/Prototypes/SimpleStation14/Traits/disabilities.yml index f321ec26e2..c910786812 100644 --- a/Resources/Prototypes/SimpleStation14/Traits/disabilities.yml +++ b/Resources/Prototypes/SimpleStation14/Traits/disabilities.yml @@ -6,3 +6,14 @@ components: - type: Nearsighted +- type: trait + id: ShadowkinBlackeye + name: Blackeye + description: You lose your special Shadowkin powers, in return for some points. + cost: 5 + category: Negative + whitelist: + species: + - Shadowkin + components: + - type: ShadowkinBlackeyeTrait diff --git a/Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.Lore.txt b/Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.Lore.txt new file mode 100644 index 0000000000..da40d40b2a --- /dev/null +++ b/Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.Lore.txt @@ -0,0 +1,178 @@ +# Lore + +## Biology + +[color=#a88b5e]Physicality[/color] + +Shadowkin seem very similar to canine species when looked at. +While mammalian in nature, it is nearly impossible to find any sexual dimorphism between genders, if they even have any. +They seem to all share the same body shape and often voices. + +The head consists of a snout with a nose, sharp teeth in the mouth, and two big ears on top of the head. +In addition to the two big ears, Shadowkin have two smaller ears lower down, giving them an exceptionally good ability to detect where exactly sounds come from. + +Shadowkin eyes are usually very large and fully mono-colored; they have no discernible pupils, irises, or similar. +The eye of a Shadowkin is a solid orb of color and, perhaps, their most defining trait. + +All observations show Shadowkin do not seem to age after a certain point. +Some may look older or younger than others, but the aging process seems to stop when the Shadowkin is chronologically in their 20s. + +Unusually, compiled medical data on Shadowkin shows that they have no lungs, thus not needing to breathe. +The compiled medical data also shows that they have a large, more circular shape where their lungs would be. + +[color=#a88b5e]Mentality[/color] + +Shadowkin core personalities are mirrored by their eye color. +Some common colors and their meanings are: + +- Red: Determined to reach a goal, even if it means sacrificing others. +- Green: Eager to learn and fit in with others. +- Blue: Very calm and collected, or shy. + +Other colors also exist in addition to these but are not as common. +The other colors are just mixes of the three main colors. +For example, here are a couple of mixes: + +- Purple: Determined, yet probably won't harm, in some cases shy. +- Yellow: Quite eager to be number one, especially if related to knowledge. +- Orange: Shy and calm, yet will fight if provoked. +- White: Very robust, exceeds expectations in most things they do, but is quite boring to interact with generally. + +There are rumors other colors exist as well. +Shadowkin that lose their ability to travel between dimensions have [color=#000000]black eyes[/color] no matter their core personality. +These black-eyed Shadowkin make up the largest number of them living in Realspace. + +## History + +Shadowkin are creatures native to their so-called Pocket Dimension, a part of space that is unable to be accurately pinpointed and/or visited by most people. +From there, Shadowkin visit our worlds, and sometimes a large number of them are forced into our world in mass migrations and then live among us. +What exactly causes these mass migrations is unknown, but may be related to them losing their ability to travel between dimensions. + +[color=#a88b5e]Homeworld[/color] + +While no home system or world has been found, some Shadowkin talk about dreaming of their homeworld, describing a lush and green land with abundant resources. + +[color=#a88b5e]Racial/Government Status[/color] + +There currently exists no Shadowkin government, and with Shadowkin being as rare as they are, they tend to fit into currently established societies and civilizations, with varying degrees of success in the past. +In recent years, however, many cultures have taken to accepting Shadowkin as another galactic constant, going as far as allowing them lives similar to those that any of the other species would lead. + +Some systems early on took and experimented on Shadowkin, in an attempt to utilize their powers in various technology, and even recreating them with very experimental technology. +The tests failed and this was met with a lot of resistance from Shadowkin, many of them being killed or becoming Blackeyes in the process. +After this, those systems realized that Shadowkin were a sentient species, and deeply apologized for their actions. + +## Culture + +[color=#a88b5e]The Typical Experience[/color] + +Most times, life is pretty normal. A Shadowkin can have a job, go to the job to work, then spend time off with friends. +The fact is most times of the day, the small abilities one might have are nice, but not overly useful. Sure, a Shadowkin could dim the nearby lights, but at the same time, the Shadowkin could also just flick the light switch. +However, it can sometimes happen that when a Shadowkin slept in and needs to get to work quickly, they might just teleport to work. +Some people might be overly wary of Shadowkin, some might be drawn towards Shadowkin. +Many Shadowkin are used to not wearing clothes, which can lead to some awkward situations, but those are generally the same situations any other furred species would have. + +[color=#a88b5e]Language[/color] + +The only recorded spoken language of the Shadowkin is an unusual language named "Mar", named after the fact that every single word in this language is the word "mar". +Spoken in different tones, with more or less emphasis on the various parts, or by drawing out parts of this word, a multitude of different "mar"s can be created, but they follow no apparent conventions. +Shadowkin can perfectly understand each other though and discuss complex topics using only this one word. +The Shadowkin can hear the Mar language from anywhere and understand it via Empathy, yet do not know who it is from unless they are close enough to see the sender. +Other humanoid species are incapable of understanding or learning Mar, as they are unable to accentuate their speech in the same way or hear some of the silent, Empathic tones they use. +Shadowkin tend to learn one or more languages of the Realspace beings. +The capability in such learned languages depends fully on each single Shadowkin, where some have only very broken capabilities, while others are fluent in several languages. + +[color=#a88b5e]Naming Conventions[/color] + +Shadowkin tend to name themselves with a singular word, ranging from states of being, such as Lone and Collected, to words that describe their memories connected to their supposed homeworld, like Dreamer. +Name schemes of the humans are usually frowned upon, as they do not reflect upon the Shadowkin, resulting in reactions ranging anywhere from an actual frown to being entirely ignored. +Shadowkin following another species naming scheme are often Blackeyes, not fitting in with other Shadowkin as well. +Names hold a great deal for Shadowkin because of how closely they are often tied to describing who they are. +Following life-changing events, Shadowkin often change their names to reflect the new person they have become. + +[color=#a88b5e]Rumors and Speculation[/color] + +Shadowkin are beings from another dimension, capable of performing feats that others could only describe as "magic", with no scientific explanation. +It is speculated that Shadowkin actually have a whole nation in their dimension, and those that come to Realspace just simply refuse to talk about it. +Sometimes Shadowkin mention a "Hub", acting as evidence for this theory. + +Some believe Shadowkin are the result of experimentation, though them being taken and experimented on is a large piece of evidence denying this theory. + +Some believe Shadowkin are the result of an expedition crew that disappeared hundreds of years ago, even though the first Shadowkin sightings were long before that. +Obviously, this expedition ship performed time travel. + +## OOC Notes + +Extra information, should be read if playing Shadowkin, if not you should try to learn this in gameplay. + +[color=#a88b5e]History[/color] + +Shadowkin used to live on a very lush forest planet, using primitive technology to work with metal, create tools, and build stone structures. +According to the dreams, Shadowkin back then had forged tools and blades, but had no electricity, presumably putting them at a medieval technology level. +In a sudden event, everyone and everything organic suddenly found themselves in an alternate dimension, sucked straight out of their previous home. +The Shadowkin being ripped from their homes happened in three total "dimensional ripples". + +Now stuck in this alternate dimension, Shadowkin changed a lot. +They stopped aging and with time developed the ability to use the energy of this dimension to power their unusual "magic". +And even later, they learned how to leave the dimension and travel to Realspace and back again. +However, as the eons passes, memories became shady of their home. +Many Shadowkin forgot more and more about the thousands of years they had lived, reducing memory to focus on the more important closer time. +However in dreams, Shadowkin, even those born in Realspace, often have visions of their home planet. +Some events can trigger certain memories to return like meeting someone they knew from the past makes them remember in great detail who they are. +As such, it can happen that two Shadowkin can randomly meet and remember that they met hundreds of years ago, often confusing nearby unknowing humanoids. + +[color=#a88b5e]Biology[/color] + +If a Shadowkin personality changes drastically, their eye color will change as an effect, reflecting upon their new personality. +Shadowkin, being ageless entities, can look older or younger, but that is merely a visual representation of how they feel about their age. +22 years after birth a Shadowkin stops aging, and in all of their history no instance of them dying of old age has been recorded. + +[color=#a88b5e]Shadowkin energy[/color] + +Shadowkin have an odd organ in them, their "Core". +This organ is the source and storage place for their power. +Without it, they would be unable to use their abilities. +The Core is very sensitive to physical trauma, yet is very resilient to electrical or magical damage. +The Core can get irreversibly destroyed from overloading it, using too much power too quickly, which is what happens to the Blackeyes. +The Core can not be replaced, using a new one would require a new body, and trying to use another Shadowkin Core will result in death. + +The Shadowkin's ability to fall into a deep sleep is a method to recharge their energy at a significantly higher rate than idling. +Though while in this deep sleep, it is difficult to wake up, and cannot be woken up by anything other than themself. + +Shadowkin can know exactly how much energy they have, and feel differently based on how much they have. +They can also Empathically sense the energy of others nearby and can estimate how much energy they have based on their feelings. + +[color=#a88b5e]Shadowkin Abilities[/color] + +Shadowkin have a few abilities. +They can teleport, requiring a small amount of energy, but they can do it quickly. +They can teleport to and from The Dark, requiring much more energy than teleportation. +They can immediately fall into a deep sleep at any time. + +[color=#a88b5e]The Ritual[/color] + +When a Shadowkin reaches adulthood, they undergo a "Ritual". +During this Ritual they intentionally overload their energy reserves, forcing their capacity to expand rapidly in order to gain enough energy to travel between dimensions. +Most Shadowkin pass the Ritual and that's the end of it, but some Shadowkin perish or become Blackeyes during the ritual. + +[color=#a88b5e]Important Terminology[/color] + +[color=#a88b5e]Shadowkin:[/color] +The name given for your race. +While your race doesn't have a name for itself, this is how most of the Galaxy refers to you, so it's how you refer to yourself too. + +[color=#a88b5e]The Dark:[/color] +The other dimension where you are from. +There are theories that The Dark and Bluespace are connected, but you don't know the details about that. +The Dark is a dimension where strange rules apply. +For outsiders who somehow enter it, whatever they imagine being in there, they see there, if not too complex. +If an outsider comes with a willing Shadowkin they may see what the Shadowkin sees, being anything they imagine, or a reflection of the station. + +[color=#a88b5e]Blackeyes:[/color] +A Shadowkin who has undergone and failed the Ritual, or lost their ability via other methods. +The Blackeyes have completely black eyes, no matter their actual personality. +They choose a new name, which follows a favorite species' naming scheme. +They are often ignored or left alone more by other Shadowkin. +[color=#a88b5e]Note:[/color] Blackeyes correlation with black eyes is done entirely via roleplay, the game will not handle this for you. + +[color=#a88b5e]Mar:[/color] +A word used to verbally communicate feelings, emotions, wishes, hopes, ideas, and whatever, in addition to your Empathy. diff --git a/Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.xml b/Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.xml new file mode 100644 index 0000000000..fe0ef45483 --- /dev/null +++ b/Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.xml @@ -0,0 +1,34 @@ + + # Shadowkin + + [color=#008000]Shadowkin are enabled for character creation.[/color] + + Fluffy lil' guys. + + ## Ability Differences + + - Need no air to survive + - Can teleport short distances + - Can travel to and from The Dark at will + - Dims nearby lights when in the The Dark + - When too low on energy, they may fall into a powerful sleep + - Can "speak" in the Empathy chat (~), which only other Shadowkin can understand + - Slightly less blunt damage + - A bit more slash damage + - Slightly more piercing damage + - Less cold damage + - Slightly more heat damage + - Near no cellular damage + - More bloodloss damage + - Slightly more shock damage + - More radiation damage + + ## Physical Differences + + - Very large and brightly colored eyes with no pupils + - Sees the world through their eyes' tint + - Very large ears + - Very fluffy + - Can be Male, Female, or Unisex + - Can be 18-300 years old + diff --git a/Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/darkswap.png b/Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/darkswap.png new file mode 100644 index 0000000000000000000000000000000000000000..3c2815e8c2466ef7dbdc0f585f2c55671b6f1aaa GIT binary patch literal 5595 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 JPDHLkV1j{j)Y||6 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/teleport.png b/Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/teleport.png new file mode 100644 index 0000000000000000000000000000000000000000..b0f1bd8dc8c5fafeba9540552a433b1a6e81ab7c GIT binary patch literal 4114 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 QHUIzs07*qoM6N<$g8C}qDF6Tf literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/meta.json b/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/meta.json new file mode 100644 index 0000000000..7dcfe2a004 --- /dev/null +++ b/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/meta.json @@ -0,0 +1,43 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "DSC@DEATHB4DEFEAT#4404 (801294818839756811)", + "states": [ + { + "name": "power0", + "delays": [[0.8, 0.8, 0.8, 0.8, 0.8, 0.8]] + }, + { + "name": "power1", + "delays": [[0.7, 0.7, 0.7, 0.7, 0.7, 0.7]] + }, + { + "name": "power2", + "delays": [[0.6, 0.6, 0.6, 0.6, 0.6, 0.6]] + }, + { + "name": "power3", + "delays": [[0.5, 0.5, 0.5, 0.5, 0.5, 0.5]] + }, + { + "name": "power4", + "delays": [[0.4, 0.4, 0.4, 0.4, 0.4, 0.4]] + }, + { + "name": "power5", + "delays": [[0.3, 0.3, 0.3, 0.3, 0.3, 0.3]] + }, + { + "name": "power6", + "delays": [[0.2, 0.2, 0.2, 0.2, 0.2, 0.2]] + }, + { + "name": "power7", + "delays": [[0.1, 0.1, 0.1, 0.1, 0.1, 0.1]] + } + ] +} diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power0.png b/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power0.png new file mode 100644 index 0000000000000000000000000000000000000000..ab370f753ed3a801484b81c74e044775d9038a62 GIT binary patch literal 853 zcmV-b1FHOqP)EX>4Tx04R}tkv&MmKp2MKrY$W}aj=7kLx$>PK~%(1s#pXIrLEAagUO|T(4-+r zad8w}3l9D)RvlcNb#-tR1i>E=R~IKm7b)?(q|hS9JC1vJ?|WbFz5|3-jj3i}0#G%} z$RrbDzOX8WUg1X=0h&RHnR+U_n1ko|x`&VNcX6KOUH9kcSBfSBd?N82(+!JwgLr1s z(mC%FM_ENuh|h_~4Z0xlBiCh@-#C{Y7Img}@eki-&FNJE5-2CAsRLY#Ju6cZUbPk8u;9ey9{yw(t_6gvB2ClTOzup37KS^(P zwb&6bunk;XcQttrxZDATo^;8O9LY~hD3yTsGy0|iFn9~}t+{>coa6KX$WgDBZ-9eC zV605p>mKh8_xA1Inoj?I0L{*FWpp6pMgRZ+24YJ`L;(K){{a7>y{D4^000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2j>F_1S_CX>@2HM@dakSAh-}0003jNkl+YMq9_y~gey>0JClu>%C5=`7$jj^d=5u~i zQD7KKrvL$Et6)c2*!C zFsJA5)wF!TA|D_h&`4iCz&D@s%cj6EluiKx%2vUqXgUS*0Vv4TSIYArsxKb^e^wX) zgO9`rNT&b+O^k?LVrK>N0dso(UQNpfEb;;J0gd$K1AOy2zibK&L+KPCpllUvil$Q_ fAAo{f{gLYfsQt*t#251+00000NkvXXu0mjfSYdHc literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power1.png b/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power1.png new file mode 100644 index 0000000000000000000000000000000000000000..d72965eeec8bd0b17a7e77d13550f41e43b06233 GIT binary patch literal 938 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/meta.json b/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/meta.json new file mode 100644 index 0000000000..f86e0e8585 --- /dev/null +++ b/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/meta.json @@ -0,0 +1,87 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from S.P.L.U.R.T ears.dmi at commit https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13/commit/8b4abffbe538fbded19b44b989ebc6808748f31f", + "states": [ + { + "name": "avali_inner", + "directions": 4 + }, + { + "name": "avali_outer", + "directions": 4 + }, + { + "name": "bunny", + "directions": 4 + }, + { + "name": "bunny2", + "directions": 4 + }, + { + "name": "chemlight_inner", + "directions": 4 + }, + { + "name": "chemlight_outer", + "directions": 4 + }, + { + "name": "dragonlong", + "directions": 4 + }, + { + "name": "easternd_ears", + "directions": 4 + }, + { + "name": "easternd_horns", + "directions": 4 + }, + { + "name": "jackal_inner", + "directions": 4 + }, + { + "name": "jackal_outer", + "directions": 4 + }, + { + "name": "magus_ears", + "directions": 4 + }, + { + "name": "magus_neck", + "directions": 4 + }, + { + "name": "mouse", + "directions": 4 + }, + { + "name": "shadowkin", + "directions": 4 + }, + { + "name": "shadowkin_stripes", + "directions": 4 + }, + { + "name": "sylveon_primary", + "directions": 4 + }, + { + "name": "sylveon_secondary", + "directions": 4 + }, + { + "name": "sylveon_tertiary", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/shadowkin.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/shadowkin.png new file mode 100644 index 0000000000000000000000000000000000000000..3aec926c5e273471968944a48d6306c1cbf5d59d GIT binary patch literal 9242 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 N@^tlcS?83{1OSASL8brz literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/axolotl.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/axolotl.png new file mode 100644 index 0000000000000000000000000000000000000000..c4156ca934af82d88fae13eb3b6c4152b3d7ba55 GIT binary patch literal 8532 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 Zea-W})|G50iy+km$9b+(vBToHe*+i??#}=K literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/datashark_ears_inner.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/datashark_ears_inner.png new file mode 100644 index 0000000000000000000000000000000000000000..1a9cb46d220188ec7b48197e3465975fa96f99ce GIT binary patch literal 5734 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�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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/datashark_taildata.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/datashark_taildata.png new file mode 100644 index 0000000000000000000000000000000000000000..b2842793281b92b8e51ac6d215f283b405a2db74 GIT binary patch literal 7294 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 X$|c19O*{}U)uWqjrTw~PZ}|TK#8*@2 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/easternd_primary.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/easternd_primary.png new file mode 100644 index 0000000000000000000000000000000000000000..07f146450d4ad546ca6af70a1a5fe44ae566d48f GIT binary patch literal 7539 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fennec.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fennec.png new file mode 100644 index 0000000000000000000000000000000000000000..f370548d05d251891f8dd16c0e63488010cf9ca0 GIT binary patch literal 8106 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 E0F(NBQUCw| literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fish_secondary.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fish_secondary.png new file mode 100644 index 0000000000000000000000000000000000000000..a2d941600d9eacfc1cbb62728821982d7142d5a0 GIT binary patch literal 7687 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 BCfEP~ literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fluffy.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fluffy.png new file mode 100644 index 0000000000000000000000000000000000000000..bb2bae364e66537291000ad75e2f713cd4304576 GIT binary patch literal 8939 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 aV&uB4Ny~kB2YcC%5DOD4<1)kD`~L?S$lbaC literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fox_primary.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fox_primary.png new file mode 100644 index 0000000000000000000000000000000000000000..ac40db1dbbffa91cfbbfbd812cc34b49acb03afa GIT binary patch literal 7850 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 L?=O1rdc{U1 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fox_secondary.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/fox_secondary.png new file mode 100644 index 0000000000000000000000000000000000000000..01c894116cf943a5c73b21867ffb02f2e9e30294 GIT binary patch literal 6682 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 T$90;fsF2-VyqpUhgEsyf?6C78 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/gecko_primary.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/gecko_primary.png new file mode 100644 index 0000000000000000000000000000000000000000..568bc0aab4cb6100f906f84feea1703ee3121155 GIT binary patch literal 8578 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/gecko_secondary.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/gecko_secondary.png new file mode 100644 index 0000000000000000000000000000000000000000..9794f382db1e2ce5456f86b3f4389ae683d92c38 GIT binary patch literal 6951 zcmeHMc|276`yVPHgcixI8A~N~%$zy1hmxH}wwooDGjq;pFpHUCCK4%ILVJ-)srX%K zBNZ*8x^CKwiU@VpjjT6{)b|Xnuiy9e`n`Jny7#YU=FFV)`8?12^E~fona`X_@o;z2 z)|{$|!{M}DobA1^&jrduT@8ExjUV2K!>MIO`S{7aU^zi75%Kt8C_%PLj1o`R$N?(&y&s4BfIgxxPY8tGc=RZoTb}ecYVr(rBKL*O5BWA>UFAb}^G5Xo;GQ~2w4KHXO*I~=uin!tEwI=^B3-%{52 ziJkMT_e)}X@Tbdsi&ghnzH50VyBPbhWA(c!+y5N+{mmcGQ})(-H{NMIYS3A~I09Kl ztK2YEKX6aFC*8Yt!T@y<>>WI|=I)F)4#}G$CTG(YJDG1RSfL%|2&XFQlO!_WA8~|v+D09zyXI3 zS4W?V7>3ue^C+Z9ZvU93pG*Xv@!>t5smdbo2#_qEPQ6^+>eXP*sQkgV0m^N zd*<$`c9)MGov3j`=M@1W=rK>=c2`UaO3>AtuTSRWJEj|7-F4vdFK$Otyq&>AW`8)J z&~y{)&q#6JVM3MaFk83HcpfMLe5M>UbhGf1%s#Z_y1(&Rj?5t`z=$f`@9@BD>yD-T zQ>Lq;!F*!bPd+wRM?4+w#TR=RfarYm7#Dmb3^T- zW^Ir#<#1m9`@}uDY5B(evCXY!R?UtVQ?sEL7g8QaKekyYnDXRx!o%eWt@l$;40Oe` zx}FU<87-IZi+R&A^)W0Zs`GiLeMY~yJxBO~3$<2kA0d453EpD3i;^2}~ zYv(v-vOLJ*$@U`buZg`#z+d$*$vm1hG^~cjq<0QM2lEJ0>G%tDg z#z8^j8Ux${Z9MM|*|_tP@KNnzrg^dYt0^t)Tzyeu`SJY)PxFK3x!_2hU(A-I8 zeIbsaQ`Ifa8HTgRS+G0>6wQk9OM*my&Kr+EAlT9(@95~9H?UjSmArh+Y;h<}p}OCG zDKs`eNrj)4uwyf)Id$^EB=PkCyRDfe*X!14kAp(f*j;CH2bvG?6#oUJrJ8pY z$7WUlhO{%U%wL}0nQ;4ZXsS{3yh(MxHCHAipBYP&-I66I$K+Hd63!NepJ|_dB(x^Z zdGT?}d(+^3MY$1$-8~bJoqqG7q9Nwg(~KOv?S~lK)b-<*yj`T>cEsiJ?2~|M4Sh#h zqvGay-G))O)>c+d@PEs&ZQa2>P-Fl4q}JLQSrqqh4&=7D>0W#%s%3U;FELC)y6ab) z-*a8WEU%Jux8KC2T7c)5&MrSgZr2K0)xIUD@y^SZ5Giszd#NwCIPd}Qc173IT~)=0 z*zI*k+F!O_Ib_op6@T(7*XrKUhjqt8(q6j#TI;_2;t5(w^PD1ltx&h|@ngek#k`6( zlJ13-T60y#HTc!LZZryAT3F<&#eKD`tz4L-ajCBCF}UJf4NB{`y7SgELAPljes2JD z&3)$!o{yp9pq;0xG2YM6EWQvhezHd|IofDzEk1xa>T$h#+`)^U*4br)=-A3pb%Agw zcha~f+|_cupoK>Kv}T^q`;F5gPk-q8`*I6it@DI|*Q@)JHeD|+J1Pk(^T&t0IJWI} z$1?4-sIK3J| z9|+k-d=|KbAqrno5K((!RxF&KQ;3{#4;`&B*EnUOeN}#Lyv1C5{sU)l^WolINwE*R z^QvZSEl_n#A9Fuvq2ygtY*%y%FFfiRTk}fXUW5AgQ^v%XEhvENpZs3Zz*2d4t9*NH z_k*nR$Fu%QOP|bCRV!JW+Lk`EQ)TD8^4nW24Y!!S00CXWZPIZ(b@}Cx$u=V z+Xm;KRnwy_7OQXEZXVt6wBdY%bntYZ^+o)a3Q2KyyzW^XPVWvM+cx;I7qPe^fhCNH zIH;vUAjY;8IGojdg&5|BqA~&p4dx52O*+dinh^MiwTUm4O=64f(3O1WC<*EvK_LheN?8hPlVMyIcCH*Inh=IXWTDn3erykdok)TbD3%mU z65ycVN0Lo!GznG`gvau-cl-!}U0Iu~l*z;_B2g}vTgo9zktCQ1GMP*wiA*Gu0Zamr zt`f>%1t64~Dj`NN>`^IK!WYZEFgZ`_A)Cb#r5xr2UC_=(T9U@Vo%=Bvrg!@@v93crCb_d}S z(J)kiiAu3m!Ecsya$$RX)=*Lq%om7s(RZ1vC3B@CEATDMIjRL~}g+>Dbm_{Q55C}qKE}4hW5%Mq;!eu#%Bmx)< zCtm;uqeQVVcz8ldILp?<#oB~yN%}J45eCb6m;zPM z$AtYf&i^mTKtWI{6{0f$sxo*Kgo^?&l|%t}WICC{By&NSH$u{9bg76Zlfx3!HW=d( z;|fdAVXg?~A44_!TWjPiQDq!RSoZ+27u^S>vM|=jG!x=K?;c8{GeDHi1$az^hLsDA z4ltQqCcuCY1O>68L1-gE`+@G!SrCl{k^T+$s9YWbQYmzRfg%)u!eB74Gn4^95QT=4 zsB{{G3w;}n|9AAT&_N^?NclJ1gUJxe;bD1+aBgQ5okBoJ#+J|rx3 zG!{tyH{9dVu`~q99Dq#YLI8zKqW}ylj75(`f*BMNmBXOXf24b#yD{Z+?O73(n~_hA z)Qb4OTJ4CySGyOiC5?<>yCQ6pMf|+W`q-H01P zzDxLLcKxL5yBPQ`;h)*{!|2lda-RkjVn43r*j<>J+FDHP4vref&B-43LHW!%pSKko z(GWZPOK~`z%gRG#`y3r3Y;dg1h3zo*xr)|klKHYn#!lE!j*Gpm5B9fFovqF~g6YylEK83kT7Ksq9V)WQZXKjk(J3ZjEp7W zViGCo_j_RxxsFpt3`C6$*FBSdUY-=*IP&Ly%iya#mDSnvetXRAH%v?5rNf6uxiBX_ zv#yDFZaQ-(BQw%7rkv5$090IgRQibf@<`Ax-6^??Rh84OXBLRNek*g_@l$f%FH7<#b)GR{Pc9k$?3X(`Og7>X#ht%wTbFFM ze6kumIc1YeU6d>ML_l8o^6A*8v(9cbWms}*gyTos9NjoCcbRqf^}2YB9M*cyiej2O zv1mo$pBkg*r1Rs$WHrJ(v`x2z;y1r^gpe{uVCxiOKWmn|-ppyF9sw`jf0&`b9(Oxi zu-;+crCY%_$84t23p4&mPt2Q;H#IUmoqu!WKDkqvYyQ}nvT;sF3W8Rd1G}F#GMa;8 z3VVKR(M%d{ALQlvlkeQ7U0&rYcQWq*3^aTH-)*-F2cP9I}V&bez{Bkby&jL%U45h9Nb@!*p4*=5vuEL`>td!!yH2Se!Iid zwj|cQyx*@Et=#&<$RHO%N!jK(w`|nK{wqZWwLuMfr%v0{s{M1rLmD|8d2V=YsjHLG ztZ(aM*Vr29J=qqLZPlVt+VnIGIJBy7&8_@tFJ+u%RRE>Ws$#VuqGb6WZg*F@tD;d) z>z5VJer#LYc68D6^4yEe0qA*{{BM=p80pf6V3iD3abk^ z+&AH5;b`o7=*000=VOhqZdP1I-aTA=LSt^%vA?Tn;WV_Gp>e>ukkJ(&+>c7G@ zR?G9EXnFYo^chZT>i!U~u_3Ps^IEENKRvR2w$l-_{quVx*Dbl!N-l0|RQn#tsw~|D z?lfo!6U~blFZ@+yc%rJ)I(=3xd5fSVcg<91@Y>_E9a*ANGp3xnU=?aH!pwFr6RMJ2 zIgLgd7wSu{!8heLft{qH_0u9YGFKilcvAa)9hMP2T741&dcE@J)@$T1p7Ivo_6VOk zt1I94ew@bbkVdqqL?$_4d^sb)q#cdQqMD*edjPAB{^khBI>1J#z>NqrD zwme^_{fsOvW_Z}c``*yC+Dfrz-`%DOt9%9Z=X;Ya}%8Z zwJ%umCws%uQM2HrrX~J*#Aox|?pe(=iHldtkKZ99B?s zoO$jqH{tGKi+1M}L>pHfUZoDSKX*1E=6kijfn|vfZ>zh3-}l3eyrvk>Pb%7jX7p!9 zTfQ1GrM1&2i}%wVTfq8pTBoX6_~xKGEFJBRzb3N`u$|$O-@&Y}B^`3F(Xg&q`20~& z)h(%#pATo)Rjh3^ZHW&u_GU%yE4w@!_QV@Jyv+&-Yxo@^|Fs; z9Vh6^kMv(~4; z2i9q#Qrm)ASLYW*CHD=456n7&rU%%SL{%YX($N#L8>C`Yc}s6X7s)#<-jTiEodc|&dMlsh@O-*R*f4liBRn>+b|PSNz* zU)MTK$hUog8=a;+T;hGBV7P&F>2Zcia!*n0LJHq-^|7f;W|&<#by3^Rw(2&;tBUQs z8teR%@`I1mqmPhCW|wf{${oh{$~IGMB*z`7#e|A?}kR$AVM*LqsVtA`VJ%buo5M;t~LHm=Yl;#l=b#+$0`l z5SL3FYlo>6@}P(^hDQnG3&C(ValRD+y18DK5rjXE`e726=kFg&@v&l!Z#A zj7z1eR4OMG%}FYcqCy-FhYG?}7zPLlK#?p_B1wQmVXK80!tlftA~`No;!+7&i-`!O z2}&M?Ld=uj*%v3{^WVcu6mMA|_@E{sGAiT*Qsd&NA8RO-UWo+ATZ8_mh9ZR608xW5 zg)~7f!n_hOiPH9C2vqc5UzQ+`9drj3QL$Joju2H4t3sbFIn$Rfc(0+QAPSF@4Qdf& zeG#UIG}#5V2BpgSKMLa4vT{Y3hm?}NgG6ra!al!_9x=J|T^DBAV8s8ocb+@V7h zL|`EU1H=f30(1xw0z$DE1TX~VFgPLxn+AzLg7TFpl!!!xX`u*kC!D}x3t6C;4zd6y z1k(UIQzQo1kPrlfm=L6~X&g2K1V4fZkmE#FBC#J^rG-KXD2^Bu(nN$IOge%PP)rCw zm`oU;K@bfV!D5t!!h=w#i0dtt$00;G@i-(3qsk;vgA-c9xo!eq9tCz9T6J(l5Q`|q zgaT0mxCE7|6d!~`@Hi}3iD>zRm@FEd!{$IRo5SKjAL)l;as`o#T2u&hq750L4GfoX zhoBbGW-0;j&QGp~97B{+d5BaR%cE#bAZs<>PxFa_LJ=k6i6}7w6ohG95aL2m2n=%R zY%UD~KsNUSZCt(-#l^}0m$bHg$j(DS_rVp!`pJVsLp2qQ#SfhgoyOvW#Y83#mIW6P z4Y{B|5;1hpP6BIaO0*D>L}5h#c$={A#_|7=40IG@Fla0`z|aPdj*2hME8J*7b^r}a0%96 zCWZR9fLPrC+5dEKU4}oczP)y_{CShTY`_?IR7->Na4p;i}y@q$|jL-wg!MZyV zh@mE5Pqz@_pPS!pMrMGcHJ#1X!`zT^!=hSwq+=0z&K$eKR?=@{Eto6DnuIe8UT<>e zTh*DLBI^*U#AAlHUt?!=UwrjQo3glwwddC=E_gjiZDk_kmseI?u)RGwEGFkrQ>;b& zk46>i)%WPF|GLq4i8Ic%deqNs-TBSy@eS>^HIA!(j;`J5INLX9e)EgPZ;=Ub*|vDg zn-dRgkeXb0vTNr~yXt3;=N@~M;9==52sDr0aHjv*^Fr0b?NNT6!!xQUsCL({zTff2 eUXx9dO$dm+EN@A0sJo~&($~x1bC3H1^?v{csS+Ll literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/kitsune_primary.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/kitsune_primary.png new file mode 100644 index 0000000000000000000000000000000000000000..54a1f7dd6ae1e0070d3b31d48c27e374f23494a5 GIT binary patch literal 8093 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/kitsune_secondary.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/kitsune_secondary.png new file mode 100644 index 0000000000000000000000000000000000000000..c7eceb053a40c0310d967fc6d8efca70cd417489 GIT binary patch literal 6736 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 RD>#}q*Lya5zvq(V{{i|#{=NVJ literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/maw.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/maw.png new file mode 100644 index 0000000000000000000000000000000000000000..d9eefadb2e34a99ce90c32349f0efb3157b95f31 GIT binary patch literal 9068 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 MuBlGB){)5n0iS(q-~a#s literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/meta.json b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/meta.json new file mode 100644 index 0000000000..358acdac05 --- /dev/null +++ b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/meta.json @@ -0,0 +1,119 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from S.P.L.U.R.T at commit https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13/commit/96703f76bccd8fe6a96b78524efb97a9af661767", + "states": [ + { + "name": "axolotl", + "directions": 4 + }, + { + "name": "datashark_ears_inner", + "directions": 4 + }, + { + "name": "datashark_ears", + "directions": 4 + }, + { + "name": "datashark_fin", + "directions": 4 + }, + { + "name": "datashark_tail", + "directions": 4 + }, + { + "name": "datashark_taildata", + "directions": 4 + }, + { + "name": "easternd_primary", + "directions": 4 + }, + { + "name": "easternd_secondary", + "directions": 4 + }, + { + "name": "fennec", + "directions": 4 + }, + { + "name": "fish_primary", + "directions": 4 + }, + { + "name": "fish_secondary", + "directions": 4 + }, + { + "name": "fluffy", + "directions": 4 + }, + { + "name": "fox_primary", + "directions": 4 + }, + { + "name": "fox_secondary", + "directions": 4 + }, + { + "name": "gecko_primary", + "directions": 4 + }, + { + "name": "gecko_secondary", + "directions": 4 + }, + { + "name": "gecko_tertiary", + "directions": 4 + }, + { + "name": "kitsune_primary", + "directions": 4 + }, + { + "name": "kitsune_secondary", + "directions": 4 + }, + { + "name": "maw", + "directions": 4 + }, + { + "name": "shark_fin", + "directions": 4 + }, + { + "name": "shark_tail", + "directions": 4 + }, + { + "name": "snake", + "directions": 4 + }, + { + "name": "succubus", + "directions": 4 + }, + { + "name": "tentacle", + "directions": 4 + }, + { + "name": "shadowkin_shorter", + "directions": 4 + }, + { + "name": "shadowkin_medium", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/shadowkin_medium.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/shadowkin_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..ca162bb1b05a50446fb54dbae2e84e4cea5876b5 GIT binary patch literal 807 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`0N3h)VWy>{)|yLa#2zI}V>(4p6_U%z_wYXAQImo8m;_Uzg1+qXAu+VuSS z^GA;!-MxEv`}XZmo;R0Bytse={)Gz{HgDd% zd-v{LyLLT({P^L+hnFv3K5*c``t|Gg?Afzp$Br{+&TQDQVcoiQYu2nec<|u9efu_U z+_-k_+VkhnKYjZ2i-&i-WB){j6Arsu!!~tre8~=DNMdc9)VxJiU7O9RGE)1FL#v>+ zMqPY=;X#$()AQc1sn#%f#PahD^O9IOUe(36Q{O)45|JomddzyrZvD2YUZG33OMQ_n zY%0&-UwQRv|M|avh3`2E^&b28Zpvns!U9I|fE^9o8ZjG`H?*iN5zgQeThe6WG*H+)pLa^n-8;}dtQPCDgsL3yp_ zvfsZFUaW8Lf5gvTWv_e5{hgrWG&z~3z*3WWGXK5{t?)UPQq}OnODUjh(e%0J{#5R0 z;B=2{DXup=Ta^^3$h7=%);FV|!dlkH?vYnFO6lgFeQV)jVA>QYGHLU4mc!}}%T^_t zaP?>kKIl~ORKNds8f&E4&(r=tx5sE4_`&U!qg}dtcB}(1vKTyF{an^LB{Ts52cyJN literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/shadowkin_shorter.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/shadowkin_shorter.png new file mode 100644 index 0000000000000000000000000000000000000000..979e4e6b26c4f0f65d39fb7b1789af3e7c6cc35a GIT binary patch literal 630 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 vvYh!_0ZL literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/snake.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/snake.png new file mode 100644 index 0000000000000000000000000000000000000000..8e20028e1e4f799f628102c7eb88d67cde2bc6ad GIT binary patch literal 9758 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 Sg?S_o0GJqB7?kLp3jKfd#^BNb literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/succubus.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/succubus.png new file mode 100644 index 0000000000000000000000000000000000000000..a02fad589e6e1ff22a38e9366e6610140e5e2018 GIT binary patch literal 8025 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 AWB>pF literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails64x32.rsi/meta.json b/Resources/Textures/SimpleStation14/Mobs/Customization/tails64x32.rsi/meta.json new file mode 100644 index 0000000000..2aea3b4201 --- /dev/null +++ b/Resources/Textures/SimpleStation14/Mobs/Customization/tails64x32.rsi/meta.json @@ -0,0 +1,23 @@ +{ + "version": 1, + "size": { + "x": 64, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13/commit/96703f76bccd8fe6a96b78524efb97a9af661767 Shadowkin big fluff made by DSC@Cabbage#9633 (561159087765848084)", + "states": [ + { + "name": "shadowkin", + "directions": 4 + }, + { + "name": "shadowkin_big", + "directions": 4 + }, + { + "name": "shadowkin_big_fluff", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails64x32.rsi/shadowkin.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails64x32.rsi/shadowkin.png new file mode 100644 index 0000000000000000000000000000000000000000..94ff21d9cbb92ec2898b31f6d08179bb4f27b1c8 GIT binary patch literal 4674 zcmZu!WmFViuwOa^K~zAR6%dq^lv29$PfEuUN=Yp#wIHpqg!BULBB=|~4U)^!u)vZF zNSAa7Z{LUa?VUR__uQF#=iE8>H*@C3>FcUdQ!-Hk003$Yb!9{R9FFHVXA4oN9Qa6p(5rDhBP zFRx!4(P$XZ^)$4deR39?sLcNeNH@=-ApM7VEpQWM%2pdQ=Xf$3yk_j27l;(aea>ui zcTW6sovs%olOaE>xl+Qucuseq*Y|oq=au11hD|aE)9`0~ev^%OcOd zF?q^Z=<}Wa6Kj)wg zelBqOh}&5sPWt|#d7^Bl{xNCfwishQY3A};cNF<|IWa4~T4?CPoec19btw~j zIOjU11{n_l@7H4wOW3!+^3*=wKCX*`U6>tX@YW}J)rPm8BmexFZx5BKrp^YTPudTD z&*ZOM)s^Zdl)Ff`HDkz4bGGWHKs*X=$$LiigLD7#Ir%0S!D&RLpZUOm=j+>=a_azp z=sg?%h7#C@v0+Mi6AhQSMDj+9sTa7vx*;p;WM_Uj{k7)8x?sE1-2gdttvSFmDHud81f5J?WYf#? z4I6)~l7Z$du}Y}_wFhcB$Jrt3E2it%qN+~Wm`o2Aj0Kh4y49q2m!mcxV8UQW>-2jJ zq^46c2enaDd!cSdD^K4{m>wb(^4crnKDtWmL5Ti;!D zYiQRwtyI)cPE;oc0QaG1-b_>ZG4VCwrQx9U+3aK4sdg>>=Yhxh&(>X#{*u{sRhJzI zPFBkh8Krl`^zT~8xlKs*<|r57*p+t(RreUsH@*@!aI&q}dA5E1v{-OWB=ysHmdftp ze#mKBczl+oYFb3@Cz3MqGcEGh_Rc1g5K-Ca6eY6f1FGL@QS*>OU=Blhl81xKX9}hO~8Ep%>~~ z*8*tMV?%zZI{#W7C7tAXqWi9M`EF9T(wIE8IijPZbJC%Rf$hIBB=hE3@$!G5XK&mzK5f|3MQQ<&r$hLhwaZ(CG&58T41uL#KOMcWuEm=^MGGyF<86Q zoJ0gk1+j^_a<^|XGjw9a&v4aPQ2pP4JbnG>;gRzX8ro+!xnei)nvXJDE!twAKf7O? zb}TL2vM-Pa(O7U>TJBZ(QR3vSlC%M;)W~L9$AgA!loC98b@l$^Xrf*a9LSw{X6NS< zRS@Ii1yxj=Z#>w)X9t{IW_bXtsO-0PFy~a4i2RRs5t{Q%$ZV6f2~IZWcdFG=mcBgI zymKsK@V;b@_p3K|%460Of37TwVTc1OF*D+Pg(+#@4AzJaW|Mfq=CY5B_KgPNlC#NP zCfFtL6zH?=aQqE&=~&H7x8nx4a3@+Hx30A=KAF95 z_nqy-YXoopY_Ah3k^Qu2{aUe3Mgo6Rx_XjVJ>+TV*muoJp}{5WsPR|Suq0L<0*%zP zN{sQAnBv&Fu{6etD^}`heo%_Dxb>qVwW^cm zvJO&v(g7n|G`VB+B$~C9M&C$}lOzJITh_4ecqz>|>`k?u5H6EKtzJoTYemCg=EY%+ z-rNGp5X1>T0j-wb@0lerzvg-5)r3hC@1h8hEPM)boULs*YH-$+Vj}-ekyZ?0AhFdk zOqp3%%jC*UBH`vJvFD2c67_wz-ptVuizRjh{p`J~?k+?-WdMa&FpvrLh?umGbl}@w zP}5x~Sr2P*K_}21Tx8NWBR8@vE`}ST7UXKJP|!cJ8W#U+5Y3(=uGS^I!I|3i(+b&0 z+VPB`@WbxF1Lm*l6=04py@83y>Sf1V2>D6GEN*MoMXv&3iu%THw-*`OG4

Bf?!# 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 uhn<6_LDDV~o{hlc|I z)E+@#OJ7q5e@^&IZx@&cgwr<=4&j6Zz+3=;fcfh8?tU9>G%>e`dsc*?cf_r1kGl{J z(IQVCOn${cE+0PH=4h62i@#fBY`$fG`wv5NyTWIsCtx1TTCMdQl99^KuW}PGx8Tzo zaQ*Edd#MJQ(r$XbnRxc4_p%K8VBMvLT;~GUcCLCfp^967|G2$i$9rbe>EG4wgrLj! z3b!G4B75h5D{s%+&yIf=L@(R9zG00?y>u?^N{m zge0CB@@(=RmZllzZa)l8R`SfUY=CUO|2uMIi!Bb^5H(55;MCG>vw{qyidp%|(bk|- zno6Kchx*NC(6#gyX?{{Y<->11mxH(eZhVV^RlW)aN?ZzCR0%_kG>!xk!e8E}0G+Yx zoKPHGUY^~LhrH{y<3Nv)LTzigEDWC1@vVXy;ZB>D&+lRbStEdw{t!vffT{<`%}vm4 zB$v)-cLUmRB=T`Xi_*0EqVAWiCd=UV90tv7fa+*P&p>qFXo6wIB`yQJ&ybVj>SN$o+VVfHT#1FHx z+X35y$42>#;XKFrij9JdCJ`1HE!@HzRVB`~d{rY1m+uCb{^G?GK|;iWBk9eU)#6$?CfD{8C0lRiKg+N#<`f zUm-k<1TA;TnAu3P*Lfj^y%4=$_Uu6d=8s30qE=KEY<$Y23#x7 z%@cb{sx;jGS?4!&?$Xkg`p2hQ+BHv2KmSOhooIn%!?BR7knMD*fc(jxtL>~NftDu0 zD;cYu(%Cz!{9es$=y!&Kei`j%A5xn*en)#J#I_g9O2XC|(+_uDjjgj^E+Y+fL#(kn z!ZzV=l{;4M!f@#r3lBM`yN?@8CKY7wk~&~t(Pa$I$nHEHMdl|09^{pI9~8>2JhO%4)L&6vDyLDek;+ zE#+<7_?vi%q4CIo*gl3|3Kez>#D~C(wxDc_pRGn{R@5i=`<|In{QYX$+`*MZU2QXq zxS;vJov*4ihq!*`(KNINo7qDEVY)E$BM!z{+vZV2XD19n|6V|?QU{8utVD_4+w`nX^Kjnwf_kQo|CPcHRD)RNJ@~TpLDni9; zYSEc0;$b4&ORVO$&rFe~Yi{$N<{C6RkkND@wk4>|%1X_53;88nkAMz}hx8iayObf{#Lu&09ui4@vw-`Pc}*6`E3)Kl4ZLV*K2o znFQ+g{BM%kpWEqKe<7M-Cp|Q%@inHf?ac$AbKd24@niO9I_0C<2XtqoxzxSMNKXQn z9)5d9#2PkCF56&Hn0g?Bkg~bw$i~g8WVH1UazB56mH_F_Iks6c{PEor*_#*!4tAr= zpVBGr2?mMwu)P6_tknG?T3K;xC5D0co-R4$7V7opkLdCE6e$UafsRS@y3V3RfGjon zzaU=ivn_8hCFrkTi9@{WGka{8az0l>{!`nOX5L?X_uT?;qnV9nqa>}eqS2Kgt|?ou zQtRb-N5(!V6v{vFL0#zBptV*O4lboQw)0^$P5|zFHx9Q(Vn~6etfZ?%VvMpD@&+s5 zTCxNp^*U{-qCQ8xNeHFaH$S@A*3++wi_2^1-R*KYY=JwrnyXOiqxH#2y2Ha+DAx={ zX!NV*v!1m@?nY}nvrY*r0`VY8>-;pvStsf^X=Bw(vD*|&$eD#{1e0W<5E2ZW zgO$*b59)F0HqOi7EWd%~(Mg5@l6(DObyk)*mdE8>N#nu-Y!naBovQ3#Tf%z`)Wt3a zi6^hmGdcd4*O4@edNEIJc69!Uj90BElcsdnwoSvb?U?wA*iM7IQ0T};_(x%;ILX^YNTZ7ii~ddq^<2qEf=9R-bU5*Ycem2GuJJ8&!=o z#Bd5dmw#L{_6R{MN}j;y$V9#_Sse6tZcjtKZ++af^^I4L26sRo(5;;98tAVae}tlG zUc-&PB82djP_4U*MLZSt(ySditJ#v)dHEeVmTMv@NrDx+4DE7) zMD3h)SBY=T!1@b~&X6Vw`c=Ef9P~QtT>^pY!=pqWn_aebvLMhXGJ0awc|S++5c@iy z^rT1^&f`JwC6;?^+WWnFy@LQ-asTvTnlJh@yFnlIy&%c^yx#0`OEZ_uwi<49=R=Bz zp)KJF5b0kUG_D$l^9f`w_T_eq1Cg89EGKlC&(m)1a-Jc#_urLrHuHte)%1Kw**$D- zu;fujQi2fjxa8N0$k7(z==*D}x)I+S_kZdxYe$O38#O#y2uQ96=KLy<2p!BXu!fv; zIR(1!MD26Du}?Rjtf#lm1)Hj!3dy?~D$V5=w2u)L??=PnvD;~&M*2{fY?j5c*Tf$= zij3ci!gQGMRYV?FeRDb%&tP4l-=Df~Nos%Iv|7W4 ziEOPsizvOFR1sJDL8YHL=io8O_E!u8Yq?=sS7X zfbr%P){Asb1@B(o-b=_r?(Gn#j?s5U@v-mjCJU4~uS>Y{D#!0C0Htu-eC7;8TX(hADZf)sdyu%+=$d z#wyk=1pL8n3;=8fm|>PD~W0&X$#uKZ^CwsTot_F0LwTpYGx#&VFCkmvGb_B=v}cm6J2tt82cN zkzp)mv->*%%zx}f?@5si06-80)6g&mX=wcK-htmXK7^(k2xywH^@VeA(=fVlS$!k1 zD2?G2rb#U>%`qXR+V7Cm7!EEy)0WHnWnpzbdu}~z`K77OT=zm?Zr+lXb^BsDry|Gs zPut=P%o3vQ%y#sSbQW&vI0CovXDh(65Hz&&O5Bw=;$a;1@85=f{cB*hLVs|@iCjs8 zP~jy)=HY!6s?WZw4#HS;%>5X$>6cc0?cHkbgHI_7Dg4`Cs;!bC^GL$XKa6}Sm5TOK zR^(=5n4W-mWYsrq%y(aRvx62=Lp)2nKz-N*+|Xz9Z)HIa_G3B8f_5%S>-rK}#O&$j zS%dF*cq@4lbik)Q_pUqx!!>P7Te9kVC4W)MX)mSxi(Xy~s_0x&H|3;mLUrCQQM_6> z=-9k`q0@OAN!hc zAc5$kQHf_;)h(z&m0o1!p!@8?>zYPq)UyEp&_M6o0>RTWBG*SRKh;3@J@CsQsiU5b zCgAqJQ`AwGj+aotpIRXRfIGea5kaQ#9ag-M%ok*!MTQ}y1~BoDrm4d5io76AHE_T@ z?hnd);uj;?!TxN)EGXC5oCGOztrq($ijPh>2Ix4*FL)_0Zfu<1 zO?gj1ox6k!bn(#wl!RjrMvK0?-okb8sntAR!d>jr34TSOokLtQoFahgK$u)sJxLPPB^FBMp-HQxQ+JXq^XoJ{Z1{cE4R9)U3Y^om?6hnmUh zlM+!?Z7tTZp1gYd4xFiRT7WUJ0!3Ic3|REKk2KvjZa7}vy1qP{ZxD%bc+=O{w@mt0 zlC(!+6z8YoO=@XlGqL%SIZ4toOY4)8sv6Xau_U9;lND9?p{v9b9H#i9T7IIFMd#6u^XmD}ft6a(M9< z6Z&FfvEBc2>GJ0KGF6y~<4IT*qLuAsE1Nt9|I9@Q$Ip}pKhMwQpMMYQ5Px_QWQQ0@ zXG(FV;f#sE1P(Y$!P&^FE%aVHoJ;?vj{0nK|VhfbRMP?VAym8L$1zE zeoB9aSk-wd#n%EIed#$1Q9XZ^;UlZ^cN(Wbhet+*3U2c_xr9FMD9#92u6@!E8H4ww zIe##o3vs4G@r9<81(-<5te~MJ8Tz6z*P;bn_bWRAWZJz*Q%VztRqRY{aB1`6;v!Er zAkLxdm7PqU!S3FkBiO_Qd zm~YxPDrc};CqXSf>)LLTdN@Yla^+HIXdZ*yoCjkKwp)Ta#(`XLv$G@mlWSmLPIXn) zmO#Sj{#p9HAG5Pe_zdH%$f}^Cv2Em0fc5qD17&X+D1I&-tVEuMKCx{0KL7DRa2dFNd&Vn#+r<7$i7x>0J@ zMT3QXpRKERVq;0jxmGS8yEV;s6|(Qt_NQ>Dj7v*P3ouZweE2lxy7H$Lv0F6%LxP%t zl0@IYV6``%{&)sW5OQ&()x6+&9Hb(EgdeW;g(odkKC3<6-4!Xxz!zwCe!e?X_!(*P zU*mkWVHbRV(!VJt#}|p;s6ex9V(h`=kgiy&`UpaSbo$Q+yg%|7kWv6s+}7D8K3fGCHQgLusyX*pugno6slzUK zK=k+br}5W3734x{ej4i<8qyz!(-RX!aX!t}#-siT*yHscO~_v~&BzCZ=m$^2RLKdr zh~+U72J}c%iY}DlDknKmi?$>KZ@qJWA4|g<+;=zP4J)iiLf?_KIU!S*kDM!QmQ*c5 zg8Bzj4;qag#jq(7WMySpB2C8<6BF^BXsV0Ho^3ghFwTJ&H{!F(B(AqM4Q(jQpu-C& z@W@}6uM=@M(qI3PVl!wk(Theu#Ou#~Px*vq?ljRCt{2oWW|_Oc2Nac0y2zaiP?KLZSE(d@w!qAr7B6|qZcSvTvT1&PRNnaXeeqeA^Ta{-1J3G7948Sl9!!QiP zFbu=IAsR(b;QM}bcXucM?smI{&&i}?+jd0nJDm<%tyUp>9~Zr#)oO)Kr-L8}&}=s4 z1+oyzh3wjDwGf6OPESvg_$Y}>|g zI4m4x3kv{l*Z2SNxLvWQ-*xo7 zUau#Yb@~g~4uF%B6TEx(4gjPrg%EHYr}S$oJwcmHCQ-NB1pxH>eNF(Mpy>Dc^Jj!% zh-Pzl?A_kp#+-k2bOZo08kD*ICrZr$fX6w?FbsV9^r`Gqzj{tiPUJqm&aYp;@c#XK z+~42Fj#DIc9H;d8AE&{n zGmTb3B?6#~RS1ErtE(uh^MP#1;%jBSUd#8C*{c~o2|@o1y|04GB7mB(1VJF@GZi&L zsMxk$)n&aHbWg79%GYMIk)!;>hY!+5M@L67F;tQK5v2=&cB#~?HEC5q$90y=B^HZC z*_ZX=EEWqam&=&AX@rv)2+I0_?WzhusXKr~B@saVUBGdi*iEP;DSNS4RC1#)jcJ+< z5;oa{UO;@1B-yQs1Q4ihBdDQ@fNto}+&&(UqdGdDFio@JdEU<4PtJaLc);Jkf2HG9 z=NpDmiCroYz-Tm*B2blkb8{2>oE{aby2*bD-7c!5Z*Fd4HloiNhS8{MgRF9ckH_N( z06u>F2mrB-jJl8bG%U-45JE;nvW*G}q-y*8Z^ln@Ha+<8mPrzW=XtfvgBXTk7=~dO zhG7_nVVD<0?ly6qf4xcTD{56p4{Od*5z5-GJT<2dO^7IvmJrBTj z{;!|BeFYNd_sL`uef|1XmLoNrP58bK-}e)1*qE0`uRA2?1COJBI-MpKm83oqq)r9E zww&oL)bG7kROb^E`qM}hz;HNBto7%H5C1m%dJ3eKl%+<1v|4|)l9l;)cy3RD)Y?F` z#!mdI;R#-|q}CHS`1d`w3)n$Ye5!NCbvqpxtiAHi-!Ou_39<89=OQ6qC-MKYt=% zw=WRcR<}8@8~TM1nYxK&>JZ|2o~&L`mlTF!?2Psx2vV0FmzS5(w{PEA1beu=yp(f# zk{$KPK=xJ>bsNI8K@ni452an0L)$j-W5X(^s$Z?(q&fLwOYTppfQ^RM^1(VHI7 zi=Cg1Lp=nN>|LanK;|4^G#bIOtcK@#vfMkZd7&DjNHlMu_P;Ei23yR|PsbA@D-gGH zp6&K$J4LVi*HN?3DjOWsl`K63fZ}}wa(#*F`PHV*G-v6{4t9EZ=wblkeFRj0aL)yX bVY2fd@2#J`H)&^900000NkvXXu0mjfPZv=2 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/eyes.png b/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/eyes.png new file mode 100644 index 0000000000000000000000000000000000000000..20fd326f17fa91b0b6c33b7fea29a3d693ec11c3 GIT binary patch literal 1643 zcmV-x29)`UP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-_bawI7X{O1&V1SBB@$3cK1_6B?WO{yQZ$Bvn? zcYh|rMR%)0tp_MYLfZfQ9qBJTOu3|@)@rXc<0-v#9(ZZ_<=J=HbB^;~@TI$so>r9J z{PB1rjF0pTDUfngKJ&>5B(EImQ_@Fz(jWBlOv7(x)E}4$%dKJ}D(!>-C zZ#GEg$#UtM7a>p-jZ|y zEihEba&xwI4}cOOw_-9RKpzEt<~z;i^If{~Wvi{e#-@!{+GXpm+jiT1k3g%1L|9%p%Xor0WmHF#O)w}hUSA=Zd3{%yA5uz;LpkQ zS%=RD+AfoHXDk6MTc+%_A`XE%+v+yaPQA*m6@R!VER@=;D^_hmBN}^b0#$oHeRupV z>Ijk8irSbPJWuf2wuyU`5!NELVw>kJ>$dPJv9j-pstOnw-XnT0-tEz&TRJdT`k4*iUOR4qd1@hG<0k)nPy*96vq`P z^4Bu`uHko}??B&y{+vLxs)0B`ykL>u48$7y;*tW|1!*2~NsL2j9?~_?V|g+ln})LC z0vl8^n-b0#P$z@E;?N?m;|$K4Gl8P+l625UN$^&9RDYu7`CSrd|DBl?FXuoPDoLzj%B3tt|B-f9FSKGH#i6>Z`cb zd{QR*qT_dtTaxIHS|0004mX+uL$Nkc;*aB^>EX>4Tx0C=2z zkv&MmP!xqvQ>7vm2Rn#3WT*~eK~%(1qF4kArLEAagUL((ph-iL;^HW{799LptU9+0Yt2!cN#t}afBE>hxsNufoI4=(THymt=w-3JJb3e&8v2|&|rGZmM_Y;IKyy+S}3 zpc<2zWhByz8ThWRdj$A?7vov}_x@acYTjZ%KqQ`HhG`RT5YKGd2Iqa^2rJ1d@j3Ch zNevP|a$WKGjdRgufoDd{OlqDuLM#?LSm|I^GBx69;;5?WlrLmGRyl8R)+#mD>XW}P zoYz;J85!}Oe8QU00006VoOIv0RI600RN!9r;`8x010qNS#tmY4#WTe4#WYKD-Ig~ z000McNliru=K>4>3_I#Q%W41s0Axu-K~#9!?b@*sfItWYz#l83^ec%@-o!*R4Sv+w zjTj;z<;DQuo+LBLyw+c|Jz2i0PQ9ucUp~TZ^Kh*J00000008*2)vxhaz2cM1?p``j pcfTu?u{s|hj{pDw0000yu>0fM{hqQTt>?(T~Pw*Wzd6Fj&*I4th65ZoPtyW6+#kMB(P z%$e>!-7|G>)vZ&}s>-q-(8ejF~W{-6>5VrH31Gg~dieDKS=8C7FoyDECoFUf&OMSr z9#tlzhUcIrsAu88y!`bV+$vrSENr|B2M8Fm*16?azsgRAR(s(S9$Nj9pUg0(>YAR6trMf2Ej2+zj@k72y?%hzX~uRYvByn6IOv#p~JtS82!ti{&}R3?$5PtSEAF=JuhHH~ta>7RQ1gE?aj948LA!h5K;F z*^28^yGy*uL`3nin_@H~T|8~GvJr#Y12#rv-;5VjjK^kNC2UV@G5*Ajx1CS*;2v*H zuyDEk!5C)E;}_jRuWoG`s%6*MmYrHia;RS0Zltv6M)PQ^=%zpn7Y~cHk6#0yf2luc zrNpN7BBW^{_8!l+KfOEg`h}zs_pSC%8G)Ba?WUzn2UMQi3K^(364aaIweJuV;j-;avhLc zQQ?Y@2AYD`cJE94Y<*5zBzBP_(d9iY8S+QCCk+#a z%IF|u?SNHYhr9n!69N5#7Gd@@LYBCdT?Fa1QnvO#MQiu*T)S%pk7@3C1g3HQ-50lg zY*I>ZXg`e_80+mS%e%JFt?z#OWFv*W4~Jjlk4FLO3X97rPy6`K>%hAZm>VMecg&CE z$=UxP{u*+-migZ6edb;LTy|~|X4!7qiuveFD@~l`y^gX@LJNS(%i%Kp1^m7(yZkL+ z;y@cE34NQ`pkpCEpuZoZZD7PVqiW62yjk|-TNg|3q1THpSJwUfi}z~nQwI6HgI`-jy^6L`mAODs(wEuMXeAjfYx@gMLEX_; ztba4KT>t9@Tt^@yM=iF4(jg*YA^d$^z~_4d_!INo%AQ^bx+XP0X@=DBq6?YCwMlmj zI#Mu#Ld&_ew@Ja5Z$t}hYpoW;jrJ?5U(PJ^Vp~4ue=r~coD{4g-|*W~j*g6kO}o7R z3>A)byyWG6z#&PYi{g-07+Uqp?3wg-MID}-{-6}hTbo@ll`L1!EcQ6ZPht|lt?Y(& zFcexjH_&d_o;CAs@E?ZNx@%}n7@qpLkkYTn^hgISkn zv9sUzB)Kpj7taLY$9yW4*oW2B^A}oG7f6c2KTrTXb@XuHBvJ+I-o~CWhKZEO zgTLzE{KC~#lcet$st%86mp*#6=y*Q+TF4h*@(M7W#lj!4^L<0Y>V1{;j*f5YZOp+T zO<>=ycrM%o**S){tM1deV%3e821lpNhpG;%;2C8KulLjSt_k;8D_wsyJzHm1aWy46 zW~tT~tlmj8#PYUPVhxy-Y;656zMcrFBV6lee?(5HdZAcGg*+*y1}nynNaH7bZ(U{- zmi?is@5X0pFO)3QBZ&_Q_CrN?aL^v+{nSUfxhcXdb} z9zTa+#gikCf}YNXMR1d3TZQH1IhUtuR3CdN7$3EhqDcSM13%#vA!?{`bT{b$407NJ zv1@sI#*@@aXzw%Pih|<~RF8@n$LZpPpI()}KdGh};|^BiI2Y}f^e?v<`qBYMfu7fI27E#1d-j6-Qow=^sAMW|CRMbXw|nl0tyt(i#Ty^FyzY0x z?gA5Qa9A}>{G?-3pK=j`>fPcmm!G9M_)E>A^r6lblVeki6Gu~BPAra z#>(P9Ne~gdFIjp;Zs*NPO)fX^8!Q0`h64QIp=;go(h}3r5Baoj;xX*>3Mc9~L)nr% zYZ`_|+HlJJ%qECm7`10BZX6;tj;2q=TJLeop>a{}=|WC+N~6q$Jkb)mj>bh0p4g_w zCQ{Tr$4AaOtXrJj_LSIDw^EsA?Y9o&B}c*wgZF$QX4fPTMo zcRe&xR4L>*%NS^TF~}3aQ($@tqhQ>VXwA!c#vV#y1y^D^19&fVMXe-CYVOfcYgrDg zUU5>0z3ev~KXiJGe2f}QC%ZihzJ`}`cIqOQ(BJfxde~CA03-|oJN579q5rhm#K$tP z&kf+u;!u1X4Y|zuc&2AfXfB4Qn|~4f?D%NI|DUxQznF=HApX!D{#86}EN^Mx{X`}~ z8p4*cNkyGaT|_8YphR&95=AgCok?!cvwKYH#qD4+V7ki?CYIIrUXJ2ote#AiN9k1b zJ(O#MRM$9mFLZxZY&J$70FgYp>d`EAi;>zL{iDaI${2Gae-@OYJ*@vmz>uH5()9N& ziMd89TRjfK3L!On(0i`P7BEUW>^F4P(&l*dL;6&iV)O*&ReNyiPR#faA)AV`tq{wno~Cdt@Q7Ziua6xdAnx|b%Z*PI6oQLM znDeNcD)O`he(H|xL28|yan~34t1!NP*m1~3jl<2QA`K6zzj<*pHEH@`*+;zqO6IiGbmla!45IDL;WytOJKW3|`?DEJ zpo!A*`8NdSJv`jT!Ni!)EC7R@`Hc70o{;#HS(4`jKB)xpB_)Vv6#KIq2?J$hovyqa0IJmFlp9?01X+z9$ypul(p=VNb``c|8~>)3 z3ehSGNSiXY%eEwO)+un2_(+EGbZ`S2yPJ1SPVKtbk=}d{)2=?oY@}b9=OPm^evkpfVL%oOY~7t zWNAZL9>UlF?)pJN=uc@C;Q6@Ca5S&)EJrj;621L9ouFbV<-LsJk5}S@c2QENOr$uE zs{q|%AUx9&wGEGI06kKnoi zg47Q=z~0Hr%zvqTRZG8PpqZ=`53hLR);nWuYh_;BA<1=q?f7ledINZGmfup!^3_Fe zlMqWc&S**T!Rp!1D(KHsW0F+?+Bi~G1L&q7OS40mKU@alBQS-56$3_$qrT0-XnuiA11ctnld$592z}SQ=9UcH`Uv{QK;%si{v-*xnj z^0~xr9j*=YXvIov<2iK`e5(DmgF8Y&EC$3|!2bNx!OzFuMo$Ewhf4yYu({cCws3r_4F zNW@8lb6Z&|tPmHlltTDd~$jCemtdWpmJ3lNr!tu>9Q@FbDc}dZO zmd+$Hk`wV$(0t`lMVi!3C2zI`7o$}i%|-j}Nu6xnl|j3HELmwf2Fn&@H;7xa8`j^0 za(Uv+X~A>kAS+k>e(DS*?*cPjd|GVh?91=nXJnS zr6z2nVqn(b>^iM}kBLb`F_&k3;hcV%d|XldED`d{#Q8vZyU2-Ep{i5sqBgfKh5!6N zupU$t`mtrXVQ%>-a3b~;BJc1tP@xE#Y3kqb9BLBFSMAe8zmqLYv&rs7moDBx7j`bylfEx+%yvf3i>{o>*il0QKby-$YgBzxCYVj0!RxMr1e zHvuMcujkwrY4hG{#PXb-nW=>8{$okisX>n)_uAimT@dgccOyr zoXk{|NK^Is1GOQZrtZw19jxUDtJgyhF7Ui+`s8aqGqbO-i80d1T~P=AKqNwk^q*5X zdafY;TXUr#vtX_+`N?InHqe;eV04^#r}Ne zp~2!$6ZG)8$qlsEM(b&o9ypc8$HFFLZ`JfDa3lcBeQ!nGB< z&LgvVrz#cm{JA)Fl(-7S99(0VJcu^m%I(s2{a+&PJVoH!Y(gSN#JqVl4P4nWTOTm{ zW;aS7zY6S@Ac7PES}yn&WY?CUokCkxQZzKN`c8H$ z$Z1B54P=IuMJnfba=UJZ)8*OEJ8u_rkEIBxAj52sbnx;)D7)8cT_sm{r^HQ1O!&uv zR*~geR=TJ?#wMzF@T{anF!0MMEyj}TZmlC2dZ!IS*MW!4V9T1H3 zZ$3hxG?|KL@2lZSmrIQZ_C*iGZRGQNTYthdfMFnkBP{OVSV`arnh#164&tFXh~YR5&$#iqV! zsgDl71q&(T7T1=O4lBdUZ;yuIniwvmc}=TfrGA+(sa|kN$OL**nxTP@c#DXoP*M$D zY_@tw_2Oi;ez9LUF*0$^Vas33CXPu&wUQ|gJ~uqZ~%@Iobej9`H? zjbBEuXOQ7RE$E`%fNgC))>{>aEVY2k8G3-N#&Dkb}$67yRH{dZolQ<%SUFKCrIvoV_X~*_PQ6(HZb> zT<*?4)tgWA?(RH8JxI*hz%B3NYg+`Y)QxQRRTczz|KIhyvosktg61Np=MDg1_5ZKK zrGCL8hYg~5$SX;s9Kd4&$OK3#s1gAH3n#i^%w@C^MWQI}8e5-)`4#TPsU#l)}y zEiPN|lpkI!0SuT?O%GNekx4 z2<8kP9WjYM{rd#?PAk8-xOm}tUoppYcX#(wkv{*p&5s5Ecz%BVNjnmRo1Kx7Pt0m4 z&OiVUy|!syVOPRGK0bbUxrPP=Az4{j{ab3VPL!i1fiRE#Z=cw;<%=3JC+UdFB7%xA%5rk4*$#57+db85X9EhG?+eF{y%*d7a+=zD-I^ITE!eY z56_+u8U_Xicd9~9J+p3FxGDpp8i87sw#XLMQ^f0QfE@{P?-sj-o=n4%g%A!Z;!io+ zZzRafW4#X#4|Vuk+p;vcuq|P2xc&!-CRm&rAc6Dy7(Db4c?FM6C0Zm54c+0V=YD;C zB>@8aySo9XAAees3PV4oDwx{Z9_n@m$5Nq(|F$KI6-yc^B9DZ@6V|sCe~CRXdw0j% z=ty2-8*<39FfapjM8MS512RI6bG42ZQg=`zjUvolt^Mlu)} z?0kGEdTFLByk~3e-pr-l12vjV|65$FE?R}_k-Hb&bW~gc}z^q-_6ax z0-&xyn4OuKnWqYw-b^mn7A6V54Y^J^@Zw@3i)?kJ03=a;a%J;Xzb$~&K>WbLk>t;p zZ_npDyCcb{;gYa+A`~tO2Lt41;YfE--+?b>i7n?E2PQ&^tt1Yj$^#qS?`aztV-yt? z*?Ad@H+?A!79k5<4wB)Ndo7a9ue5jkAsU#YG`l}0JsHH zH0qzqA+|gKU^9K6!+w{RqNJ$P;-SeUg~2G5kwI#wr!5QnyzYAD-D}^df+)AvAJfxn zMe2+;naH^ZaDXPqzItZZ>yIBlHV^WG1~)gUSHV4M;{oaZqS(@E?A+X8TU(~6A%H&i zZdYLD1igA0!PC>zlnu9PndVRELE?x7R`~m0oo`@pCPA$9%iW4|i|;l4H1~%B1{%r) zsWeN?3N4115F73o7ychGA2(=rN;G7Rgb`0sMTJTpv81$ga#cS0knNH5t}leb#va zGQ7OJQ%=pK5`p^sK;(~zO^)W~<_LNIS7;-9Znci&VK|_|>G=203uOjwK$KIjtV9@J zmKqD&I(0G_Vqgmj7${pP(Zi?g8W%JDKXp&^I;=$O@B;utuCVjl&)hju&{kp}&dM%A zHgMrIG&FV-#NJ>$7{_n{MtZf!eOAeRFvd>L%%lmI3`UY;g^<7a^c-|Bhry`gix#r^ zJbjP9fe#mkgZ#9;u~xs+e;)NcJRC`omls*#Fc=BY4U1%n$$4D}dB+4m01O;_pbp@b zzK884{s|tMD-!Cs!tiSh7Ucmj_%8lUe}ee~yXn=~o6}3s3Dq+dH}uWi(lQ)9q#GTN zn9ca4oX!7Y6OK?C7dX_@oBm1D@Dn9gyv&6QS9kbtzLpy6@Z7sZj z;m^WxZUh0AeG=^!%$xrm9!fYnv-#vk?(m<$)Mkl-?c%g~<1gQaKYkbvNkmWe`N_%V zU>rH5{4z(#``^^mR4@~6F@Z{+=s;;+;BpQe8X!FAtB8q+VW#TBV*$;ePC@zhoYxZX%g*pP7Z~B zndYAo+Z1($g@pwneOXy!mf}1R|=cAjBHyon4DFcDK7Wugfl4?(Aqk30;y@m5f-85Y1Igj4kmN1&k14wdH~InEz^{QX9W@)rtjnjSo63jS3Y>n7% zdFC9x8m(4i^ic)Tu+=S`03At_iSSQ3_?ujv0X-_brj|5JhGA-&`b9@>0oA3DV{_xR z?RcTayOY}O^~v+EyA#>QNM&%v-{hCl1@oEu9_K@Eh1h>4BeK&1-4h0jH8aos_N zDKVCoR;rfeYc7u8G%QtsPz%URoJcE%`0v F{{Xzh?l}Me literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/head_f.png b/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/head_f.png new file mode 100644 index 0000000000000000000000000000000000000000..9d99bd189030125d36e50c692b0627ca98a3ebb8 GIT binary patch literal 849 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fA0|PU& zr;B4q#hkaZ&U+g<${d@otJ|ybR)iyV*Oi0L6B@f7-gPedd_{AK{YvM0hyM-V1GECH zmu`4*vRPruioi_!=WiwN)xP|3?nz$zO!l@&(eFRcrKhKh&*MB;5XoQ=bBjSwU;pT# zLrih;@e|Lc$+E18{F%*IQC%%O`DBajv**vBJ}Z?Z{KUVhm|M_$9rF4G* zZ*T8U-}mmdy{|Ckbn46V2dl*!_H}o6Z&Ldgry(-s&s2sT>$E#BPjKaFcRupCkhAgl z+cN38ECY!J_unVy=KAu@`}Aw~ZtKYARZ|#bWMwUZen?7BcW;V_jh*_MVfllzXL-Gr zPFlac;raf(dwU~v)UL~)JCwJ*J8bpRr|b8y$;iuFFJHb~X{Jw7YAWmFj}m9ogw@s6 z8+DrQ|F!(QR0o(UJGx?*D7fE&VGu;baO^{kPwWztuPn zr!pP@2b&lJ&vaG>oZNS(@JHS z^Nz>$X8Ym9n-yoaCKMM7i;IgZ%|HK}sqy(TcJ|Y~g7w>vpLlk42}tEPm3@2m{L!EH zOzFssKMx-|W=}r!zw7zC5-X!=&+oDD+el|8<*o{1D<~*XSg*HS>Ak&F^{cN{8e-l1 z?lQHvx1am@bEk)j(2o84r{6EMeUQ6gc38GOTjhFlDc+qNPl|RPkZZip7`{66;nhXe y`{eg>ynXlX-z&Ms$cF9tO$IRp0+WH~x_n6G0s-Tto*uwF!rZ?Z{KUVhm|M_$9rF4G* zZ*T8U-}mmdy{|Ckbn46V2dl*!_H}o6Z&Ldgry(-s&s2sT>$E#BPjKaFcRupCkhAgl z+cN38ECY!J_unVy=KAu@`}Aw~ZtKYARZ|#bWMwUZen?7BcW;V_jh*_MVfllzXL-Gr zPFlac;raf(dwU~v)UL~)JCwJ*J8bpRr|b8y$;iuFFJHb~X{Jw7YAWmFj}m9ogw@s6 z8+DrQ|F!(QR0o(UJGx?*D7fE&VGu;baO^{kPwWztuPn zr!pP@2b&lJ&vaG>oZNS(@JHS z^Nz>$X8Ym9n-yoaCKMM7i;IgZ%|HK}sqy(TcJ|Y~g7w>vpLlk42}tEPm3@2m{L!EH zOzFssKMx-|W=}r!zw7zC5-X!=&+oDD+el|8<*o{1D<~*XSg*HS>Ak&F^{cN{8e-l1 z?lQHvx1am@bEk)j(2o84r{6EMeUQ6gc38GOTjhFlDc+qNPl|RPkZZip7`{66;nhXe y`{eg>ynXlX-z&Ms$cF9tO$IRp0+WH~x_n6G0s-Tto*uwF!rJPv-nPv#~t!+Ar0~E3ZvA-M{ngnKkhWeB2C$5eyxNnH*%q7#?k45OCkw z@U=?!(Z?OWrSIzYi%;}$sa#jYxG;cY@=2GJ&5@~R`;I3kZoj>d`6-j$bnZnLS6n(1 zq0{#IE0?T>=!KUhM}F40DF_@Wun_rK^Y8I$hi7}@^kw?pmG|Gx)85NFg=@mu(%rEW zPd}aDp)w`q)SSyNTV9rMU1iq~tm8J3;=P@;QQ-V@;pT%5B3!Ni^P;Yup0j`Fg@$R@ zAC&EOwVK;@_FLrnO>uUAQs(Jx;mFt;<)JotMTnOC(<@n~%IP~}oW!G8-jrEazH(g| z^6Q1r1WS9SBlB%^Gom?HW$n8EKHIv2Q@_;_>d|)A1`8dABZ-WdVQ}1t$!+n(55NC< zEDc&_w>aAAz{3Iopl{>Wi+}zZlVUWpe%gnxOlGrtKYGW_tKEJ(Hz(~!731ccJP!+Q zNSrFLkg2edTlQ*yoWstTZC|Tw1$o#Weyk|ieb?t|{a%L7%P&oq1+@rFxU7=4p@m`o z`SdsU-uo$F<^vNBgQu&X%Q~loCIEgx3!MM} literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_foot.png b/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_foot.png new file mode 100644 index 0000000000000000000000000000000000000000..30ad69dc3f0463bd7436d5c0dd40d2762822e7cf GIT binary patch literal 1867 zcmV-R2ekN!P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|ck|ZY#{O1%t0zycF;~+p0zJZVLr1~+lJ8gT{ z>+n|>(*vy*dL<-O+JF2W={G!uYDrbBX;;m7YOlQv3|jtp_Py^p#~D|A=q{tD7Nu`~ zc#H_`mAs&5^n4RO{qZrxpC;(Dr&n^4@8tY+Q@)9)Jq#7JPx4i=<s?W>_@S}bI09Y8Q&^l#qNN{AonQ)us{Fy8)C4z6HS$1A(l>LQ2_6F(TBl0iS`$3#VEf5Rgb&h_X~>1vsr7-!N2m9E`->%ETwrvsJ;W{)-?@Z#*%#nsK5cOMhWXVxiGr_DC|9BGxs zt1el(Y_-+b*tD^fcHOdd+itt>5m;)$QA0w*qD7DKMD0Q~eS_Io{UlpTO8m_FV=hbSmAIprA=ktOB^IA6XfleqiG3DK32tHKp=D3-h(E>!5!!* zD2|Wtx_!2dTh+M2f7z$oV7t$A*R+UMCxVJ&2AqG=U7e?25i4!gSj!!xMu=|3QU{xd zr>sl2@3}m7Ju0+t(aN-?A|2lQgr{&Ydp^eY>axu@?ktEmCQg%3++T3@s|a4;!6$O= z${^Td&>%V$-m!}Bj;g@9Ds-w{bw@d2cH2s4>#Y~8@E)j z$;{gDa=h6F)NwiNOJd@6FT5Q>I+TMO9EglTc70p$jc`C&%NxEqWZU}6*-{s|0?+x! zd)dRmkHrGHxd!a6)bYg+pV|=fyc~?Tt0JkX$e_h$1Ygg2)r&T;b160G@F(beH+IwO zI9e?C0}B-1n@u&m)1IGNb#S>rnL;ZJM86KLvOvnGl9vI;n=%R!X`BR${{>8-Wz;?W z33HeOX>Q;w_y7O_hG|1XP)S2WAaHVTW@&6?004NLeUUv#!%!53PgA8L6%jj#IAo|! z7DPn^mr}(dSSW3URvk=U`Ug!Kk`xz5!L{Jv&tlcV#aUMeS3wZ`0daM4Qgo3L?@J0T zV!ZHpALre3c<(+yXjGVLc1-}PW*Mn?Ow8t1#lR~B1mVK~<|Jn7iS%Lyp7nK4om6)b zp5@*5XZ0z0lL0=FILdUxBHkdL*|c=d`@|tuk`&@|;&Fp6Nc_lk+2uFRMTZ5R88R}d zdEyYUSnOcAgIUQ?iKmIfimFk*kabz%yv13q)L84D{Dr~1wvy&Ltr5hrganchA)|&e zDzFftT_eRriq2ym{$a-)kq~_kr8`?LJ#?;(srom*uNKFj{yP@U?yEx-U z|961*ps3190ssI2000000002|u4x*3KA$#@qj~S`$}aD{jpJyK$HSVY`AXN%rvWJ? z#TX??RaNP#A$aetswzp+aU4o1eI+;lG+^I%4a1yvZ(KS-S2nRb$vUN^#&W}e8YTy%ZdO1002ovPDHLk FV1g6-alrrp literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_hand.png b/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_hand.png new file mode 100644 index 0000000000000000000000000000000000000000..0cbc7371d14bd73a3bb5d33ed1f9e467fc12f881 GIT binary patch literal 450 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fA0|R4; zr;B4q#hkad7OrawU^w=%zxR=_1+$;@Tz3PD`v+1s%((N!lc#J`?;D;lxr1kKnn+z) z(6_UgUHa*}yz)Z_4}Aa2C35cE&%+8bF%yCraG~4Gd1lg=Uw^%jwe`Z=vbkExM+~N+cvVXJ=9!zL)}HzO_gK=#4gY?m zXH{~xC1&Jq3RV8+9?yu&acJTu2lBQX&wKu`z#_p!s&>ot4ATR3`_1>gzrJhc&)a3Y zP3QWtpMSpj%GWUFIp@=BZa*z@+$K6-^D}?rRfgt+4_24k8_V_2{aTgV_1S-Y{t@d1 mXAW`qas;$8HOzsbJNyn45~Pj< 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/meta.json b/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/meta.json new file mode 100644 index 0000000000..11752d5140 --- /dev/null +++ b/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/meta.json @@ -0,0 +1,67 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13/commit/5bc3ea02ce03a551c85017f1ddd411315a19a5ca#diff-519788fa2ca74299d1686a44d3ab2098b49ed5ab65d293ec742bead7d49f0b8d", + "states": [ + { + "name": "full", + "directions": 4 + }, + { + "name": "head_m", + "directions": 4 + }, + { + "name": "head_f", + "directions": 4 + }, + { + "name": "torso_m", + "directions": 4 + }, + { + "name": "torso_f", + "directions": 4 + }, + { + "name": "r_arm", + "directions": 4 + }, + { + "name": "l_arm", + "directions": 4 + }, + { + "name": "r_hand", + "directions": 4 + }, + { + "name": "l_hand", + "directions": 4 + }, + { + "name": "r_leg", + "directions": 4 + }, + { + "name": "r_foot", + "directions": 4 + }, + { + "name": "l_leg", + "directions": 4 + }, + { + "name": "l_foot", + "directions": 4 + }, + { + "name": "eyes", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_arm.png b/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_arm.png new file mode 100644 index 0000000000000000000000000000000000000000..c294120942cf5eed679cf4306018857a95c18f09 GIT binary patch literal 605 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fA0|OJk zr;B4q#hkadd|w*|N*w=q|B0WbbmD2Jh=>zWUY?)$_Apv|om#!&i<{1r6z{OER^Ej< zwoff57XLr5dAj<{oxkE~>t06(n;FM`o|!yr)=%a~h729Y85HE08!C7hK%8`mguQXx z`|q!RczU+qawVZoiFua=9M)eK=4)pTJMsGKqWkZ=Q;ae>4hlFJNE~@saA3Rn?6XHc zR=6k#80Jwhj8>61O3E>36vYsNO5e%chYvgKq7lXmFZFv0GlJZIN(f3Ukyv~$am zPxb20|IUn-m>DhZAon1>Su}fV)c)@>3C|@MjwCY(^fNlxurYkZ$~p7SK&to1%MvH8 zshh6sZmLh^O0baWs<2siPa@Y$`r+rFI{gV;2c8x^{92{Su#@ZA=bap_PSe~BSPS;w zzuGQT6umaANc6y~nM@PH|5fdMRAZOC{r18Djfh{bPWv#P(06SSc*V`L{4%F?3fF_O z-7Bjb&b%!<%r}$i#PiQlyYGrUERZ;wBv|%hzg&yfRIWFZGJ$p^EdCKFf$DB${tx0+ X*88+ucF0=;(+h*AtDnm{r-UW|r#lO; literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_foot.png b/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_foot.png new file mode 100644 index 0000000000000000000000000000000000000000..390e0a27ee3c31b36740b4d14c49fc5461cf57cb GIT binary patch literal 1876 zcmV-a2dnsrP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|cmMbR={AU$e0+JAdRw3JP`FfBhNh4?IkTQ&DTR*P8K^UOEqST7G}_P4=AQ^b0<8)6v6<(x)Hp zJwkh?XGnpRH|1kKIgaGRfclX1Oi%hnFOO;XQ$+3Vh|xai7iY^KpZ5NVSS_&TbgauL z75S;RMctQj^Bsr+iqCr9Xl9MJvEWFtu znJ3GoYhv7aN*0omq)4G)lP*h|uuR?}(DEY|y5{ZIbdwq;UIa@fI3tX>TDo`sZ+q$} zVxANcR)5bG;$l89(8;2l|F8le6!(3kSAy^D>jPlnq`>N=xnY4L`RQ?b&phlYw4Rjq2;wCku+OVwJd)pHhyi4{|;X4b6RXwpj4 zR-3ifdK;;87o1h?wOen!_c1W(faihHqYWsWUA(w@b@S%k$HexTW$LWcW}AJEw0OxX zOIKaC+Ujd;+Sp3FY~6L+ZoBUh*lHnBLZgO7iyq^F+J$QRgxPoG{uwp8p$5Rxg;{~o z9W|)U?k?!ii5|>=7#9NKb`ZdZ=7U*oR0<#D(!nfu#;H(7lzPBfbPxlAWfN=A1G{(R zzTuW|?*A)p{1Lfyp!*%jr32j)t;+Gw~kH;IH>;Mjr~Y)^|?aNhBKE6AsNSltmICL!4A*rocO1X>y4 zQX^2-bb-+{o0_wA75E8n#|fAzjs#amI2f<*XwxzNXme|*jXajbUY4ScKscB$Dt!j-ltVc>d}1Vr?<=A`>lSL@t;G(!%h3(cYdieeb+;I{hn|#U z-KHnm63wa2YHPTaI=o+bgdWt39N~+OmSsyF?90$;2n6LBa=7KTTP3Vlr*H*x_yl|Qx=^DXP62=RLp?hdJLRH@+i2}VtaKMee_Q5^QAG4Z+w%7!W-c&9x-wc@zC6vlKY*E#w{uDpEClgZ10<4qZf zh&0Xu*?$2O?o8x8{S6*e{0(5$8@&Jk0fuQqLr_UWLm+T+Z)Rz1WdHzpoPCi!NW)MR zg-=tZA{7xkh&W`ZP8LK(1ea39B3LMGg;pI*Uit@38j=(jN5Qq=;Ll>!!Nplu2UkH5 z`~h)waZ+@V67Ne2En>XzcpvB8b9nDQKxkB$YIaQks%9CfcudUZR>i<81O(y30OllS z>WTDX2A=hGPn}eE5uWAU_hE=c^y zb=l=N&P9g>o*6PSsd?fMu~_V2xr15BP>H9B!-}d=zL0fU;k?CJt<+fSp8SQuytb0& zI;|1Jv4jMY5Fw+6GAghTp$?=2#!SC6cg{et5 zDHsE~Uu^qh6bS4B&AM%WAKP~G1n@rtS6bU&Z2+^Mq}SV8_z39V1}?7Kn!E>G?f^qi zx@1U>4?5<5S>o`L`X0O?6YK~#9!?b@M^g+L62;d2)Z0*mLZcthq52*Kh}K!PDb z0Tw~ROw!dWA)6b-|LK`dr%hcY0000000000006*WbzR#uP1g6lm1Svf$f+z#8-~HA zX|lSmZ|C%L=ks}HY zbIv__KYntlD2k7B&W__yk|Z*-uP#ii>#8`8wQZZ)wpE&@DvILsB-StK1bo9B1R=!$ O0000XhvZ!BQeyxZ7OypHo7SH)?>RDJ^{CTqbMEwcD3^-838phL4FU|2&Kl8l!%Ii|@{5%t> znMoTtju#rt^tq5>5_ElzlmZ7+v5nls(@z7mrhedjWZ}21{V-#qL|UIeZ^7Igv)PLC z&nIub`9Szh+3u9HPm3gmG{eTzrD97t(MinkC7Pk&Njh9M(TR$#;COcD?{ww?SGihf0r>(WMP0t zf{onlsI}iNaa?|RrDERqEyed_6ZYRfyzOmD{qDPuu3mfnHTd~%YlqD@x3D!g{=9j- yJ9PEc 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/torso_m.png b/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/torso_m.png new file mode 100644 index 0000000000000000000000000000000000000000..dafc83b65eb84c863c1f67ff31c90ef59b130ced GIT binary patch literal 1432 zcmV;J1!ww+P)afqZvo(H z7%XPqX0uUhYAQd+&oD%aqE|@Zy_oIC$43@DI5-%d$NUiE{r#OVIja1A34oUt78cUO z!vhn82&#vLg)uP({`B<3f5+!M2)GD%FWfvNBm^$c*X!#m-=CkKIUF1g2Y=4P?e}~A z5&(noyjWCMSJTwg6vfBK)BXKD#~+ON`ubweXm4+q1_X5Q$oAXY+XVjU>1oQ(&u76g z^Wct-j;5276aFkdr?NWu9Rl)&`}_MMJw2Tc4-d(1x6{tf4te5^PESvH;412?as#`& zyCNeagFZh$IUHhRV|fzx_V&EO2iyaE5f>LnDJdzex+f`7QBe_x1l->U$gq_dRo)>hIRNWN`tZTz!mN621)$#6QI{A^@oMERY{A%JDB zzP_I3=H@v5;Q>ueP5fN%e~diKpiS;cundF0wzihJ|6eBc-3rV70PZCvB{VTHAv!xd znH0~-0LZ~MHa61W;2_P<&wD38%Mz^Y0lu>=2M@p~qafFNh#;YL0s?j*@*DpW2Lk`x ziO`?&jMn_~&j}D{SOSpAVF^Gcha~`+9F_oNa##Y8$zcgVCWj@!Prm%y{Q-fnL6ZP8 zGc%&6r-%L);G7T#w$07W`ko0&fXMB3i|+33Uu%#6z>TB0p`jrh)EajnvbMG+a&vQO zb#;}G$5FR;I2?wGu)e-7WMv8`)3B+cqC$TUfa)%ni%(%kM@P9do|cwIo12@WtgOrs z5x`YkT+Hj(BT}1!~xKNBm zQAQ3P6Vlh$N2R5uO7Bw^Ko%qc5W^6ZsL{NDBB|a0$Hm13p-%|hzQ^&tw)qQX0XjN5 zxHNWte$MfS;v{N>D3v>%PTfNQ9G+!Qpf(8Z;o)Ja0Ag%wYfFF-7pk=} zF){1~Mgd&lL`35mOyZ0;Aqw;C@4UmkT^R# zqw@0dz_!UrWM^l4yFz4Z9A*O9*N7EB0$kt(H*E0rM%btVB>^z&fXx1wiH3#-Ze2s8 zq)`ADyso9Cg%%eVz3p7nq!! zWC2v%A5cz$AXr#f@CH1{joJcB)Ya87pX?R^&?ls2AEId$kVJYkMXJEJF;n&lslqxD mB9p@sfJ_cc05UmDFTj5?`Q@6?Q zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|amgFc5{O1&N1SBDrvag+VynrC0UUv?kxqtiyW7rB># z>yFSqvNL)?FNg77Pb`o;O^A0-AK6KNvCF*-zaYw2AVzz#$KsQJzVhR@*2oJvJM#`T zMDP>Oq^?x<9UL2okv%PCn+){3rpuI0xREGXs=uLa-A|39t2M&1S8DY&0RO&Z65|& zs~bgx>@Ti>i`ir#V^QocydVgztB!ONe6?RM2#X*AUPg09g4MSpL{oaymbfjnz){hM zV{#g208oUr6<|o9fR7|fk$hrKMBp()p9Pk|0fy3avuW5M4+iqlT)A233ukG;7fsC5EUm#uRNY)+8w;O);gEQ%N;T4q0=| zDd${rb%l#yuWE@Um0U`x6^m9xu9#hOg`shi7Mix$Qp>Hh+EG3|bnUUHo_p!l4IVPW z&=E%(d6ZEnO_b6MQ)irM=2>Q4D77UkEM0M>l~-ByR&A^5UNn1G?)R$EsTu@xTeASC zOEs8NxE^KS|5P`AR?eApKcSp6={`{IUAGTZ8+N{T+lL+pn{7iQ)eE*C9A>VZ;lW?)-B&04 zV4yZe%yogr>;*5Vx-G7CGx)mwzR|n?>bR2D| z1&xiNxgo7mz|mMnTH-d%!zeVY*~qmy=5JW<0H4Uw(3!lhRFg0zuWsePeu`i9&OFIoj^pI=3ZYLjGf4#`@i( z*1+B{RtUC;w3jYiRQ*^H$nf0@k5=4;w4n5nyQe*C&5Qd8tbGBVQ2z2l~lC_+G^S``y1zy!^_1 z0z`8F00D(*LqkwWLqi~Na&Km7Y-Iodc$|HaJxIeq9K~N#OI2DN>>#3$p?0z$D&i2R|084ld5RI=Bjg;0K7Si<6>@l=#22&?3fz<9@um z_qclp2#pF;&7KKB)hr_wkBQmbs_1`(4?*-{6cLG;dLq4;f$R9Xhlj6sQJ&>~?#~fa z@+Jd3BJmv44U2e#cxKbmIqwsPSV>Zd&xywkx*+i**X0(!aV|P6@XU~rNzD_7h{a+T z%U#S$hDtn599C3~@`Y@R70z3n)k=-E@5x^n$ZIQUuG1Vr97{+b2@x`CD5C-kQCc-p zOr&T(=HefA{7G`j0V}O4bXx44}``EUd zCxG`ExY9cQY6F=4B)#6z!biZsHgIv>(d0egat9cC(j`N3Bri>&PypV~=$mrD;4RR< z*6OXjkJASrLtQQ300)Oaq)6H8F7NK`?(N?*?f!lMe1CGQE>iJB00006VoOIv0D1t+ z0Op>uefjf#Lmt%{@Z!BYdPfv`F?k^&gQcOgwl=>2)N#~GHMj(XX$K!FZBEY8?kmvbOOzTuG zgkU0KA%ru6p^@`-Ve&D0KA*_*yjT4Yq?7>g)tEm=Foh&Z008&002ovPDHLkV1j}+*XaNN literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Shaders/color_tint.swsl b/Resources/Textures/SimpleStation14/Shaders/color_tint.swsl new file mode 100644 index 0000000000..f95011cefa --- /dev/null +++ b/Resources/Textures/SimpleStation14/Shaders/color_tint.swsl @@ -0,0 +1,56 @@ +light_mode unshaded; + +uniform sampler2D SCREEN_TEXTURE; +uniform lowp vec3 tint_color; // RGB color between 0 and 1 +uniform lowp float tint_amount; // Number between 0 and 1 + +// Function to convert RGB to HSV. +highp vec3 rgb2hsv(highp vec3 c) +{ + highp vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + highp vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + highp vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + + highp float d = q.x - min(q.w, q.y); + /* float e = 1.0e-10; */ + highp float e = 0.0000000001; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +// Function to convert HSV to RGB. +highp vec3 hsv2rgb(highp vec3 c) +{ + highp vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + highp vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +void fragment() { + highp vec4 color = zTextureSpec(SCREEN_TEXTURE, FRAGCOORD.xy * SCREEN_PIXEL_SIZE); + + // Convert color to HSV. + highp vec3 hsvTint = rgb2hsv(tint_color); + highp vec3 hsvColor = rgb2hsv(color.rgb); + + // Set the original hue to the tint hue as long as it's not greyscale. + if (hsvTint.y > 0.05 && hsvTint.z != 0.0) + { + hsvColor.x = hsvTint.x; + } + // Modify saturation based on tint color saturation, + // Halving it if it's higher and capping it at the original. + hsvColor.y = (hsvColor.y < hsvTint.y) ? + mix(hsvColor.y, hsvTint.y, 0.75) : mix(hsvColor.y, hsvTint.y, 0.35); + + // Modify value based on tint color value, but only if it's darker. + hsvColor.z = (mix(hsvColor.z, hsvTint.z, 0.85) <= hsvColor.z) ? + mix(hsvColor.z, hsvTint.z, 0.85) : hsvColor.z; + + // Convert back to RGB. + highp vec3 rgbColorMod = hsv2rgb(hsvColor); + + // Mix the final RGB product with the original color to the intensity of the tint. + color.rgb = mix(color.rgb, rgbColorMod, tint_amount); + + COLOR = color; +} diff --git a/Resources/Textures/SimpleStation14/Shaders/ethereal.swsl b/Resources/Textures/SimpleStation14/Shaders/ethereal.swsl new file mode 100644 index 0000000000..45dcb9b6ac --- /dev/null +++ b/Resources/Textures/SimpleStation14/Shaders/ethereal.swsl @@ -0,0 +1,75 @@ +light_mode unshaded; + +uniform sampler2D SCREEN_TEXTURE; + +// Function to convert RGB to HSV. +highp vec3 rgb2hsv(highp vec3 c) +{ + highp vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + highp vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + highp vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + + highp float d = q.x - min(q.w, q.y); + /* float e = 1.0e-10; */ + highp float e = 0.0000000001; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +// Function to convert HSV to RGB. +highp vec3 hsv2rgb(highp vec3 c) +{ + highp vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + highp vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +// Random number function with potential negative values. +highp float rand(highp vec2 n) { + highp float r = 2.0 * (0.5 + 0.5 * fract (sin (dot (n.xy, vec2(12.9898, 78.233)))* 43758.5453)) - 1.0; + return r * (r < 0.0 ? 0.8 : 1.3); +} + +void fragment() { + highp vec4 color = zTextureSpec(SCREEN_TEXTURE, FRAGCOORD.xy * SCREEN_PIXEL_SIZE); + + // Increase the contrast of the image if the luminance is low enough. + highp float luminance = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722)); + if (luminance < 0.06) { + color.rgb *= 0.5; + } + + // Convert to HSV. + highp vec3 hsvColor = rgb2hsv(color.rgb); + + // Apply a breathing effect to the value of the image. + hsvColor.z *= mix(0.35, 0.7, (sin(TIME) * 0.65)); + + // Increase the saturation of the color, incorperating a random value, as long as the value is above 0.1. + if (hsvColor.z > 0.065) { + hsvColor.y *= (rand(FRAGCOORD.xy * (TIME * 0.15)) * 1.5) + 1.0; + } + + // Convert back to RGB. + color.rgb = hsv2rgb(hsvColor); + + + + // get distortion magnitude. hand crafted from a random jumble of trig functions + highp float w = sin(TIME + (FRAGCOORD.x + FRAGCOORD.y + 2.0*sin(TIME*0.3) * sin(TIME*0.3 + FRAGCOORD.x - FRAGCOORD.y)) ); + + // visualize distortion via: + // COLOR = vec4(w,w,w,1.0); + + w *= (3.0 + 1 * 2.0); + + highp vec4 background = zTextureSpec(SCREEN_TEXTURE, ( FRAGCOORD.xy + vec2(w) ) * SCREEN_PIXEL_SIZE ); + highp vec3 hsvBg = rgb2hsv(background.rgb); + hsvBg.x *= -1; + background.rgb = hsv2rgb(hsvBg); + + color.xyz = mix(background.xyz, color.xyz, 0.75); + + + + COLOR = color; +} From 487d34bc5a92e88d895e034a3bf9d1717ccae619 Mon Sep 17 00:00:00 2001 From: Finket Date: Mon, 6 Nov 2023 14:20:51 +0200 Subject: [PATCH 02/59] Port PR130 changes directly --- Content.Server/Magic/Events/ISpeakSpell.cs | 10 +++ .../Events/ShadowkinEvents.Powers.cs | 6 +- .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 69 ++++++++----------- .../ShadowkinDarkSwappedComponent.cs | 6 ++ .../Entites/Mobs/Player/shadowkin.yml | 2 +- .../Entites/Objects/Fun/toys.yml | 1 + 6 files changed, 48 insertions(+), 46 deletions(-) create mode 100644 Content.Server/Magic/Events/ISpeakSpell.cs diff --git a/Content.Server/Magic/Events/ISpeakSpell.cs b/Content.Server/Magic/Events/ISpeakSpell.cs new file mode 100644 index 0000000000..d7c7dbe250 --- /dev/null +++ b/Content.Server/Magic/Events/ISpeakSpell.cs @@ -0,0 +1,10 @@ +namespace Content.Server.Magic.Events; + +public interface ISpeakSpell // The speak n spell interface +{ + ///

+ /// Localized string spoken by the caster when casting this spell. + /// + public string? Speech { get; } +} + diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs index 5ea597fd64..2017fb47d4 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs @@ -7,7 +7,7 @@ namespace Content.Server.SimpleStation14.Species.Shadowkin.Events; /// /// Raised when the shadowkin teleport action is used. /// -public sealed class ShadowkinTeleportEvent : WorldTargetActionEvent, ISpeakSpell +public sealed partial class ShadowkinTeleportEvent : WorldTargetActionEvent, ISpeakSpell { [DataField("sound")] public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/SimpleStation14/Effects/Shadowkin/Powers/teleport.ogg"); @@ -30,7 +30,7 @@ public sealed class ShadowkinTeleportEvent : WorldTargetActionEvent, ISpeakSpell /// /// Raised when the shadowkin darkSwap action is used. /// -public sealed class ShadowkinDarkSwapEvent : InstantActionEvent, ISpeakSpell +public sealed partial class ShadowkinDarkSwapEvent : InstantActionEvent, ISpeakSpell { [DataField("soundOn")] public SoundSpecifier SoundOn = new SoundPathSpecifier("/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapon.ogg"); @@ -80,7 +80,7 @@ public sealed class ShadowkinDarkSwapAttemptEvent : CancellableEntityEventArgs } -public sealed class ShadowkinRestEvent: InstantActionEvent +public sealed partial class ShadowkinRestEvent: InstantActionEvent { } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 75b9c252f8..1214539a74 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -6,6 +6,7 @@ using Content.Shared.Actions; using Content.Shared.Actions.ActionTypes; using Content.Shared.CombatMode.Pacification; +using Content.Shared.Cuffs.Components; using Content.Shared.Damage.Systems; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; using Content.Shared.SimpleStation14.Species.Shadowkin.Events; @@ -14,9 +15,7 @@ using Robust.Server.GameObjects; using Robust.Shared.Audio; using Robust.Shared.Prototypes; - namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; - public sealed class ShadowkinDarkSwapSystem : EntitySystem { [Dependency] private readonly ShadowkinPowerSystem _power = default!; @@ -29,44 +28,38 @@ public sealed class ShadowkinDarkSwapSystem : EntitySystem [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly MagicSystem _magic = default!; - - private InstantAction _action = default!; - public override void Initialize() { base.Initialize(); - - _action = new InstantAction(_prototype.Index("ShadowkinDarkSwap")); - SubscribeLocalEvent(Startup); SubscribeLocalEvent(Shutdown); - SubscribeLocalEvent(DarkSwap); - SubscribeLocalEvent(OnInvisStartup); SubscribeLocalEvent(OnInvisShutdown); } - - private void Startup(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentStartup args) { - _actions.AddAction(uid, _action, uid); + _actions.AddAction(uid, new InstantAction(_prototype.Index("ShadowkinDarkSwap")), null); } - private void Shutdown(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentShutdown args) { - _actions.RemoveAction(uid, _action); + _actions.RemoveAction(uid, new InstantAction(_prototype.Index("ShadowkinDarkSwap"))); } - - private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ShadowkinDarkSwapEvent args) { + // Need power to drain power + if (!_entity.HasComponent(args.Performer)) + return; + // Don't activate abilities if handcuffed + // TODO: Something like the Psionic Headcage to disable powers for Shadowkin + if (_entity.HasComponent(args.Performer)) + return; var hasComp = _entity.HasComponent(args.Performer); - SetDarkened( args.Performer, !hasComp, !hasComp, + !hasComp, true, args.StaminaCostOn, args.PowerCostOn, @@ -75,19 +68,16 @@ private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, args.StaminaCostOff, args.PowerCostOff, args.SoundOff, - args.VolumeOff + args.VolumeOff, + args ); - - _magic.Speak(args); - - args.Handled = true; + _magic.Speak(args, false); } - - public void SetDarkened( EntityUid performer, bool addComp, bool invisible, + bool pacify, bool darken, float staminaCostOn, float powerCostOn, @@ -96,24 +86,23 @@ public void SetDarkened( float staminaCostOff, float powerCostOff, SoundSpecifier soundOff, - float volumeOff + float volumeOff, + ShadowkinDarkSwapEvent? args ) { - var ev = new ShadowkinDarkSwapAttemptEvent(); + var ev = new ShadowkinDarkSwapAttemptEvent(performer); RaiseLocalEvent(ev); if (ev.Cancelled) return; - if (addComp) { var comp = _entity.EnsureComponent(performer); comp.Invisible = invisible; + comp.Pacify = pacify; comp.Darken = darken; RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, true)); - _audio.PlayPvs(soundOn, performer, AudioParams.Default.WithVolume(volumeOn)); - _power.TryAddPowerLevel(performer, -powerCostOn); _stamina.TakeStaminaDamage(performer, staminaCostOn); } @@ -121,48 +110,44 @@ float volumeOff { _entity.RemoveComponent(performer); RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, false)); - _audio.PlayPvs(soundOff, performer, AudioParams.Default.WithVolume(volumeOff)); - _power.TryAddPowerLevel(performer, -powerCostOff); _stamina.TakeStaminaDamage(performer, staminaCostOff); } + if (args != null) + args.Handled = true; } - private void OnInvisStartup(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentStartup args) { EnsureComp(uid); + if (component.Pacify) + EnsureComp(uid); if (component.Invisible) SetCanSeeInvisibility(uid, true); } - private void OnInvisShutdown(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentShutdown args) { RemComp(uid); - if (component.Invisible) SetCanSeeInvisibility(uid, false); - component.Darken = false; - foreach (var light in component.DarkenedLights.ToArray()) { if (!_entity.TryGetComponent(light, out var pointLight) || !_entity.TryGetComponent(light, out var shadowkinLight)) continue; - _darken.ResetLight(pointLight, shadowkinLight); } - component.DarkenedLights.Clear(); } - public void SetCanSeeInvisibility(EntityUid uid, bool set) { var visibility = _entity.EnsureComponent(uid); + if (!TryComp(uid, out var visibility)) + return; if (set) { @@ -170,12 +155,12 @@ public void SetCanSeeInvisibility(EntityUid uid, bool set) { eye.VisibilityMask |= (uint) VisibilityFlags.DarkSwapInvisibility; } - _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); if (!_entity.TryGetComponent(uid, out var _)) + if (!_entity.TryGetComponent(uid, out _)) _stealth.SetVisibility(uid, 0.8f, _entity.EnsureComponent(uid)); } else @@ -184,12 +169,12 @@ public void SetCanSeeInvisibility(EntityUid uid, bool set) { eye.VisibilityMask &= ~(uint) VisibilityFlags.DarkSwapInvisibility; } - _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); if (!_entity.TryGetComponent(uid, out var _)) + if (!_entity.TryGetComponent(uid, out _)) _entity.RemoveComponent(uid); } } diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs index 7cfd9ba380..233236a8bd 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs @@ -11,6 +11,12 @@ public sealed partial class ShadowkinDarkSwappedComponent : Component [DataField("invisible")] public bool Invisible = true; + /// + /// If it should be pacified + /// + [DataField("pacify")] + public bool Pacify = true; + /// /// If it should dim nearby lights /// diff --git a/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml index 0ca063822b..a6ee613ba2 100644 --- a/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml @@ -96,7 +96,7 @@ sounds: Male: MaleSlime Female: FemaleSlime - Unsexed: UnisexSlime + Unsexed: MaleSlime - type: CombatMode canDisarm: true - type: MindContainer diff --git a/Resources/Prototypes/SimpleStation14/Entites/Objects/Fun/toys.yml b/Resources/Prototypes/SimpleStation14/Entites/Objects/Fun/toys.yml index a43c36b4e9..d3a9748354 100644 --- a/Resources/Prototypes/SimpleStation14/Entites/Objects/Fun/toys.yml +++ b/Resources/Prototypes/SimpleStation14/Entites/Objects/Fun/toys.yml @@ -6,6 +6,7 @@ components: - type: ShadowkinDarkSwapped invisible: false + pacify: false darken: true range: 4 - type: Sprite From b17ccf7f2d33600ef112dc55b51ca83b24a128aa Mon Sep 17 00:00:00 2001 From: Finket Date: Mon, 6 Nov 2023 15:24:16 +0200 Subject: [PATCH 03/59] Port PR146 changes directly --- .../Entites/Mobs/Customization/tails.yml | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Resources/Prototypes/SimpleStation14/Entites/Mobs/Customization/tails.yml diff --git a/Resources/Prototypes/SimpleStation14/Entites/Mobs/Customization/tails.yml b/Resources/Prototypes/SimpleStation14/Entites/Mobs/Customization/tails.yml new file mode 100644 index 0000000000..e421ab00dd --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entites/Mobs/Customization/tails.yml @@ -0,0 +1,25 @@ +- type: marking + id: TailShadowkin + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Shadowkin] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails64x32.rsi + state: shadowkin +- type: marking + id: TailShadowkinBig + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Shadowkin] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails64x32.rsi + state: shadowkin_big + +- type: marking + id: TailShadowkinBigFluff + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Shadowkin] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails64x32.rsi + state: shadowkin_big_fluff From 08ea21bbf378e15bd63ddfd703cbfd886dc07601 Mon Sep 17 00:00:00 2001 From: Finket Date: Mon, 6 Nov 2023 15:28:03 +0200 Subject: [PATCH 04/59] Port PR157 changes directly --- .../Entities/Mobs/Customization/tails.ftl | 16 +- .../Entites/Mobs/Customization/tails.yml | 153 +++++++++++++++++- 2 files changed, 167 insertions(+), 2 deletions(-) diff --git a/Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/tails.ftl b/Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/tails.ftl index ff08e8d864..78a775585d 100644 --- a/Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/tails.ftl +++ b/Resources/Locale/en-US/simplestation14/Prototypes/Entities/Mobs/Customization/tails.ftl @@ -1,4 +1,18 @@ -marking-TailShadowkin=Shadowkin +marking-TailAxolotl=Axolotl +marking-TailDatashark=Datashark +marking-TailEasternDragon=Eastern Dragon +marking-TailFennec=Fennec +marking-TailFish=Fish +marking-TailFluffy=Fluffy +marking-TailFox=Fox +marking-TailGecko=Gecko +marking-TailKitsune=Kitsune +marking-TailMaw=Maw +marking-TailShark=Shark +marking-TailSnake=Snake +marking-TailSuccubus=Pointy +marking-TailTentacle=Tentacles +marking-TailShadowkin=Shadowkin marking-TailShadowkinBig=Shadowkin (Big) marking-TailShadowkinShorter=Shadowkin (Short) marking-TailShadowkinMedium=Shadowkin (Medium) diff --git a/Resources/Prototypes/SimpleStation14/Entites/Mobs/Customization/tails.yml b/Resources/Prototypes/SimpleStation14/Entites/Mobs/Customization/tails.yml index e421ab00dd..415f4e55ce 100644 --- a/Resources/Prototypes/SimpleStation14/Entites/Mobs/Customization/tails.yml +++ b/Resources/Prototypes/SimpleStation14/Entites/Mobs/Customization/tails.yml @@ -1,4 +1,138 @@ - type: marking + id: TailAxolotl + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Reptilian] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: axolotl +- type: marking + id: TailDatashark + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Reptilian] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: datashark_ears_inner + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: datashark_ears + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: datashark_fin + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: datashark_tail + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: datashark_taildata +- type: marking + id: TailEasternDragon + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Reptilian] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: easternd_primary + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: easternd_secondary +- type: marking + id: TailFennec + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Felinid] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: fennec +- type: marking + id: TailFish + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Reptilian] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: fish_primary + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: fish_secondary +- type: marking + id: TailFluffy + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Felinid] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: fluffy +- type: marking + id: TailFox + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Felinid] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: fox_primary + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: fox_secondary +- type: marking + id: TailGecko + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Reptilian] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: gecko_primary + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: gecko_secondary + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: gecko_tertiary +- type: marking + id: TailKitsune + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Felinid] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: kitsune_primary + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: kitsune_secondary +- type: marking + id: TailMaw + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Reptilian, SlimePerson] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: maw +- type: marking + id: TailShark + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Reptilian] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: shark_fin + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: shark_tail +- type: marking + id: TailSnake + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Reptilian, SlimePerson] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: snake +- type: marking + id: TailSuccubus + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Moth, Felinid] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: succubus +- type: marking + id: TailTentacle + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [nHuman, Oni] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: tentacle +- type: marking id: TailShadowkin bodyPart: Tail markingCategory: Tail @@ -14,7 +148,6 @@ sprites: - sprite: SimpleStation14/Mobs/Customization/tails64x32.rsi state: shadowkin_big - - type: marking id: TailShadowkinBigFluff bodyPart: Tail @@ -23,3 +156,21 @@ sprites: - sprite: SimpleStation14/Mobs/Customization/tails64x32.rsi state: shadowkin_big_fluff + +- type: marking + id: TailShadowkinShorter + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Shadowkin] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: shadowkin_shorter + +- type: marking + id: TailShadowkinMedium + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Shadowkin] + sprites: + - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi + state: shadowkin_medium From dab0059d7892d42ce5553106c509dd2d28aaab25 Mon Sep 17 00:00:00 2001 From: Finket Date: Mon, 6 Nov 2023 15:39:53 +0200 Subject: [PATCH 05/59] Port PR188 changes directly --- Content.Server/Magic/MagicSystem.cs | 4 ++-- .../Shadowkin/Events/ShadowkinEvents.Powers.cs | 15 ++++++++++----- .../Systems/ShadowkinPowerSystem.Rest.cs | 4 ++-- .../Systems/ShadowkinPowerSystem.Teleport.cs | 4 ++-- .../Shadowkin/Systems/ShadowkinSystem.cs | 18 +++++------------- .../Shadowkin/Components/ShadowkinComponent.cs | 2 +- .../SimpleStation14/Magic/shadowkin.yml | 16 ++++++++-------- 7 files changed, 30 insertions(+), 33 deletions(-) diff --git a/Content.Server/Magic/MagicSystem.cs b/Content.Server/Magic/MagicSystem.cs index bbf884a05b..b0e643799a 100644 --- a/Content.Server/Magic/MagicSystem.cs +++ b/Content.Server/Magic/MagicSystem.cs @@ -396,12 +396,12 @@ private void SpawnSpellHelper(List entityEntries, EntityCoordi #endregion - public void Speak(BaseActionEvent args) + public void Speak(BaseActionEvent args, bool showInChat = true) { if (args is not ISpeakSpell speak || string.IsNullOrWhiteSpace(speak.Speech)) return; _chat.TrySendInGameICMessage(args.Performer, Loc.GetString(speak.Speech), - InGameICChatType.Speak, false); + InGameICChatType.Speak, !showInChat); } } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs index 2017fb47d4..b120bc1b45 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs @@ -17,10 +17,10 @@ public sealed partial class ShadowkinTeleportEvent : WorldTargetActionEvent, ISp [DataField("powerCost")] - public float PowerCost = 35f; + public float PowerCost = 40f; [DataField("staminaCost")] - public float StaminaCost = 30f; + public float StaminaCost = 20f; [DataField("speech")] @@ -49,13 +49,13 @@ public sealed partial class ShadowkinDarkSwapEvent : InstantActionEvent, ISpeakS /// How much stamina to drain when darkening. ///
[DataField("powerCostOn")] - public float PowerCostOn = 45f; + public float PowerCostOn = 60f; /// /// How much stamina to drain when lightening. /// [DataField("powerCostOff")] - public float PowerCostOff = 35f; + public float PowerCostOff = 45f; /// /// How much stamina to drain when darkening. @@ -71,12 +71,17 @@ public sealed partial class ShadowkinDarkSwapEvent : InstantActionEvent, ISpeakS [DataField("speech")] - public string? Speech { get; } + public string? Speech { get; set; } } public sealed class ShadowkinDarkSwapAttemptEvent : CancellableEntityEventArgs { + EntityUid Performer; + public ShadowkinDarkSwapAttemptEvent(EntityUid performer) + { + Performer = performer; + } } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index 076faae2c7..837d037ce9 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -56,7 +56,7 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki // No waking up normally (it would do nothing) _actions.RemoveAction(args.Performer, new InstantAction(_prototype.Index("Wake"))); - _power.TryAddMultiplier(args.Performer, 1f); + _power.TryAddMultiplier(args.Performer, 1.5f); // No action cooldown args.Handled = false; } @@ -66,7 +66,7 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki // Wake up _entity.RemoveComponent(args.Performer); _entity.RemoveComponent(args.Performer); - _power.TryAddMultiplier(args.Performer, -1f); + _power.TryAddMultiplier(args.Performer, -1.5f); // Action cooldown args.Handled = true; } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index 89dc1258a7..d4c17aa2ae 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -86,7 +86,7 @@ private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, pulledTransform.AttachToGridOrMap(); // Resume pulling - // TODO: This does nothing? + // TODO: This does nothing? // This does things sometimes, but the client never knows _pulling.TryStartPull(puller, pullable); } @@ -99,7 +99,7 @@ private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, _stamina.TakeStaminaDamage(args.Performer, args.StaminaCost); // Speak - _magic.Speak(args); + _magic.Speak(args, false); args.Handled = true; } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs index b6d862b693..bceabbb95b 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs @@ -179,32 +179,24 @@ public override void Update(float frameTime) private void ForceDarkSwap(EntityUid uid, ShadowkinComponent component) { - // Add/Remove DarkSwapped component, which will handle the rest + // Add/Remove the component, which should handle the rest if (_entity.HasComponent(uid)) - { - RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(uid, false)); _entity.RemoveComponent(uid); - } else - { - RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(uid, true)); - _entity.EnsureComponent(uid); - } + _entity.AddComponent(uid); } private void ForceTeleport(EntityUid uid, ShadowkinComponent component) { // Create the event we'll later raise, and set it to our Shadowkin. - var args = new ShadowkinTeleportEvent - { - Performer = uid - }; + var args = new ShadowkinTeleportEvent { Performer = uid }; // Pick a random location on the map until we find one that can be reached. var coords = Transform(uid).Coordinates; EntityCoordinates? target = null; - for (var i = 8; i != 0; i--) // It'll iterate up to 8 times, shrinking in distance each time, and if it doesn't find a valid location, it'll return. + // It'll iterate up to 8 times, shrinking in distance each time, and if it doesn't find a valid location, it'll return. + for (var i = 8; i != 0; i--) { var angle = Angle.FromDegrees(_random.Next(360)); var offset = new Vector2((float) (i * Math.Cos(angle)), (float) (i * Math.Sin(angle))); diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs index 103c8d2d07..2763d3ef2d 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs @@ -77,7 +77,7 @@ public float PowerLevel /// How much energy is gained per second. /// [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] - public float PowerLevelGain = 2f; + public float PowerLevelGain = 0.75f; /// /// Power gain multiplier diff --git a/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml index fc78d30a3f..2df3454d7a 100644 --- a/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml @@ -2,7 +2,7 @@ id: ShadowkinTeleport name: action-name-shadowkin-teleport description: action-description-shadowkin-teleport - useDelay: 2 + useDelay: 5 range: 32 itemIconStyle: NoItem checkCanAccess: true @@ -12,25 +12,25 @@ sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi state: teleport serverEvent: !type:ShadowkinTeleportEvent - powerCost: 35 - staminaCost: 15 + powerCost: 40 + staminaCost: 20 speech: action-description-shadowkin-teleport - type: instantAction id: ShadowkinDarkSwap name: action-name-shadowkin-darkswap description: action-description-shadowkin-darkswap - useDelay: 3 + useDelay: 15 itemIconStyle: NoItem priority: -21 icon: sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi state: darkswap serverEvent: !type:ShadowkinDarkSwapEvent - powerCostOn: 55 - powerCostOff: 40 - staminaCostOn: 0 - staminaCostOff: 0 + powerCostOn: 60 + powerCostOff: 45 + staminaCostOn: 25 + staminaCostOff: 25 speech: action-description-shadowkin-darkswap - type: instantAction From 45681f15d2958bfb8781dfdd9ddb8e75123c8e5f Mon Sep 17 00:00:00 2001 From: Finket Date: Mon, 6 Nov 2023 15:56:06 +0200 Subject: [PATCH 06/59] Port PR189 changes directly --- .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 31 +++++++++---------- .../Systems/ShadowkinPowerSystem.Darken.cs | 6 ++-- .../Systems/ShadowkinPowerSystem.Rest.cs | 15 +++++---- .../Systems/ShadowkinPowerSystem.Teleport.cs | 18 ++++++----- .../Shadowkin/Systems/ShadowkinSystem.cs | 23 +++++++++++--- .../Entities/Objects/Devices/pda.yml | 1 + .../Entities/Objects/Misc/fluff_lights.yml | 1 + .../Entities/Objects/Tools/flashlights.yml | 1 + .../Structures/Lighting/base_lighting.yml | 2 +- 9 files changed, 60 insertions(+), 38 deletions(-) diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 1214539a74..1eeab47d39 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -15,7 +15,9 @@ using Robust.Server.GameObjects; using Robust.Shared.Audio; using Robust.Shared.Prototypes; + namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; + public sealed class ShadowkinDarkSwapSystem : EntitySystem { [Dependency] private readonly ShadowkinPowerSystem _power = default!; @@ -28,38 +30,50 @@ public sealed class ShadowkinDarkSwapSystem : EntitySystem [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly MagicSystem _magic = default!; + public override void Initialize() { base.Initialize(); + SubscribeLocalEvent(Startup); SubscribeLocalEvent(Shutdown); + SubscribeLocalEvent(DarkSwap); + SubscribeLocalEvent(OnInvisStartup); SubscribeLocalEvent(OnInvisShutdown); } + + private void Startup(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentStartup args) { _actions.AddAction(uid, new InstantAction(_prototype.Index("ShadowkinDarkSwap")), null); } + private void Shutdown(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentShutdown args) { _actions.RemoveAction(uid, new InstantAction(_prototype.Index("ShadowkinDarkSwap"))); } + + private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ShadowkinDarkSwapEvent args) { // Need power to drain power if (!_entity.HasComponent(args.Performer)) return; + // Don't activate abilities if handcuffed // TODO: Something like the Psionic Headcage to disable powers for Shadowkin if (_entity.HasComponent(args.Performer)) return; + + var hasComp = _entity.HasComponent(args.Performer); + SetDarkened( args.Performer, !hasComp, !hasComp, - !hasComp, true, args.StaminaCostOn, args.PowerCostOn, @@ -77,7 +91,6 @@ public void SetDarkened( EntityUid performer, bool addComp, bool invisible, - bool pacify, bool darken, float staminaCostOn, float powerCostOn, @@ -98,9 +111,7 @@ public void SetDarkened( { var comp = _entity.EnsureComponent(performer); comp.Invisible = invisible; - comp.Pacify = pacify; comp.Darken = darken; - RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, true)); _audio.PlayPvs(soundOn, performer, AudioParams.Default.WithVolume(volumeOn)); _power.TryAddPowerLevel(performer, -powerCostOn); @@ -117,13 +128,9 @@ public void SetDarkened( if (args != null) args.Handled = true; } - private void OnInvisStartup(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentStartup args) { EnsureComp(uid); - if (component.Pacify) - EnsureComp(uid); - if (component.Invisible) SetCanSeeInvisibility(uid, true); } @@ -142,13 +149,9 @@ private void OnInvisShutdown(EntityUid uid, ShadowkinDarkSwappedComponent compon } component.DarkenedLights.Clear(); } - public void SetCanSeeInvisibility(EntityUid uid, bool set) { var visibility = _entity.EnsureComponent(uid); - if (!TryComp(uid, out var visibility)) - return; - if (set) { if (_entity.TryGetComponent(uid, out EyeComponent? eye)) @@ -158,9 +161,7 @@ public void SetCanSeeInvisibility(EntityUid uid, bool set) _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); - if (!_entity.TryGetComponent(uid, out var _)) - if (!_entity.TryGetComponent(uid, out _)) _stealth.SetVisibility(uid, 0.8f, _entity.EnsureComponent(uid)); } else @@ -172,9 +173,7 @@ public void SetCanSeeInvisibility(EntityUid uid, bool set) _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); - if (!_entity.TryGetComponent(uid, out var _)) - if (!_entity.TryGetComponent(uid, out _)) _entity.RemoveComponent(uid); } } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs index cfec6173d4..9f2ea18ede 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs @@ -78,7 +78,7 @@ public override void Update(float frameTime) if (!_entity.TryGetComponent(light, out ShadowkinLightComponent? shadowkinLight)) continue; // Not powered, undo changes - if (!_entity.TryGetComponent(light, out PoweredLightComponent? powered) || !powered.On) + if (_entity.TryGetComponent(light, out PoweredLightComponent? powered) && !powered.On) { ResetLight(pointLight, shadowkinLight); continue; @@ -98,10 +98,10 @@ public override void Update(float frameTime) shadowkin.DarkenedLights.Remove(light); continue; } - // 10% chance to remove the attached entity so it can become another Shadowkin's light + // 3% chance to remove the attached entity so it can become another Shadowkin's light if (shadowkinLight.AttachedEntity == uid) { - if (_random.Prob(0.1f)) + if (_random.Prob(0.03f)) shadowkinLight.AttachedEntity = EntityUid.Invalid; } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index 837d037ce9..d2ff89af3c 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -3,6 +3,7 @@ using Content.Shared.Actions; using Content.Shared.Actions.ActionTypes; using Content.Shared.Bed.Sleep; +using Content.Shared.Cuffs.Components; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; using Robust.Shared.Prototypes; @@ -15,14 +16,10 @@ public sealed class ShadowkinRestSystem : EntitySystem [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly ShadowkinPowerSystem _power = default!; - private InstantAction _action = default!; - public override void Initialize() { base.Initialize(); - _action = new InstantAction(_prototype.Index("ShadowkinRest")); - SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnShutdown); @@ -32,19 +29,25 @@ public override void Initialize() private void OnStartup(EntityUid uid, ShadowkinRestPowerComponent component, ComponentStartup args) { - _actions.AddAction(uid, _action, uid); + _actions.AddAction(uid, new InstantAction(_prototype.Index("ShadowkinRest")), null); } private void OnShutdown(EntityUid uid, ShadowkinRestPowerComponent component, ComponentShutdown args) { - _actions.RemoveAction(uid, _action); + _actions.RemoveAction(uid, new InstantAction(_prototype.Index("ShadowkinRest"))); } private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, ShadowkinRestEvent args) { + // Need power to modify power if (!_entity.HasComponent(args.Performer)) return; + // Rest is a funny ability, keep it :) + // // Don't activate abilities if handcuffed + // if (_entity.HasComponent(args.Performer)) + // return; + // Now doing what you weren't before component.IsResting = !component.IsResting; diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index d4c17aa2ae..094c2ab8f0 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -4,6 +4,7 @@ using Content.Server.SimpleStation14.Species.Shadowkin.Events; using Content.Shared.Actions; using Content.Shared.Actions.ActionTypes; +using Content.Shared.Cuffs.Components; using Content.Shared.Damage.Systems; using Content.Shared.Pulling.Components; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; @@ -24,14 +25,10 @@ public sealed class ShadowkinTeleportSystem : EntitySystem [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly MagicSystem _magic = default!; - private WorldTargetAction _action = default!; - public override void Initialize() { base.Initialize(); - _action = new WorldTargetAction(_prototype.Index("ShadowkinTeleport")); - SubscribeLocalEvent(Startup); SubscribeLocalEvent(Shutdown); @@ -41,19 +38,24 @@ public override void Initialize() private void Startup(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentStartup args) { - _actions.AddAction(uid, _action, uid); + _actions.AddAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport")), null); } private void Shutdown(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentShutdown args) { - _actions.RemoveAction(uid, _action); + _actions.RemoveAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport"))); } private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, ShadowkinTeleportEvent args) { - if (args.Handled || - !_entity.TryGetComponent(args.Performer, out var comp)) + // Need power to drain power + if (!_entity.TryGetComponent(args.Performer, out var comp)) + return; + + // Don't activate abilities if handcuffed + // TODO: Something like the Psionic Headcage to disable powers for Shadowkin + if (_entity.HasComponent(args.Performer)) return; diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs index bceabbb95b..12d89f6ab3 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs @@ -2,6 +2,8 @@ using Content.Server.Mind; using Content.Server.Mind.Components; using Content.Server.SimpleStation14.Species.Shadowkin.Events; +using Content.Shared.Bed.Sleep; +using Content.Shared.Cuffs.Components; using Content.Shared.Examine; using Content.Shared.IdentityManagement; using Content.Shared.Interaction; @@ -89,14 +91,20 @@ public override void Update(float frameTime) // Update power level for all shadowkin while (query.MoveNext(out var uid, out var shadowkin)) { - // Skip if the shadowkin is dead or catatonic + // Ensure dead or critical shadowkin aren't swapped, skip them if (_mobState.IsDead(uid) || - !_entity.System().TryGetMind(uid, out var mind) || + _mobState.IsCritical(uid)) + { + _entity.RemoveComponent(uid); + continue; + } + + // Don't update things for ssd shadowkin + if (!_entity.System().TryGetMind(uid, out var mind) || mind.Session == null) continue; var oldPowerLevel = _power.GetLevelName(shadowkin.PowerLevel); - _power.TryUpdatePowerLevel(uid, frameTime); if (oldPowerLevel != _power.GetLevelName(shadowkin.PowerLevel)) @@ -107,6 +115,11 @@ public override void Update(float frameTime) // I can't figure out how to get this to go to the 100% filled state in the above if statement 😢 _power.UpdateAlert(uid, true, shadowkin.PowerLevel); + // Don't randomly activate abilities if handcuffed + // TODO: Something like the Psionic Headcage to disable powers for Shadowkin + if (_entity.HasComponent(uid)) + continue; + #region MaxPower // Check if they're at max power if (shadowkin.PowerLevel >= ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Max]) @@ -149,7 +162,9 @@ public override void Update(float frameTime) ( ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Tired] + ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Okay] - ) / 2f + ) / 2f && + // Don't sleep if asleep + !_entity.HasComponent(uid) ) { // If so, start the timer diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index 5d384624c0..0e9360b76b 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -51,6 +51,7 @@ - idcard - Belt - type: UnpoweredFlashlight + - type: ShadowkinLight - type: PointLight enabled: false radius: 1.5 diff --git a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml index 77b321f951..34fd8913d3 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml @@ -40,6 +40,7 @@ sprite: Objects/Misc/Lights/lights.rsi size: 20 heldPrefix: off + - type: ShadowkinLight - type: PointLight enabled: false radius: 3 diff --git a/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml b/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml index c43ffc830c..8339d5c3f0 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml @@ -57,6 +57,7 @@ map: [ "light" ] - type: Item sprite: Objects/Tools/flashlight.rsi + - type: ShadowkinLight - type: PointLight enabled: false mask: /Textures/Effects/LightMasks/cone.png diff --git a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml index 2ac32ef54a..3472a810e1 100644 --- a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml +++ b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml @@ -29,6 +29,7 @@ - state: on map: ["enum.PoweredLightLayers.Base"] state: on + - type: ShadowkinLight - type: PointLight radius: 10 energy: 0.8 @@ -107,7 +108,6 @@ components: - type: Sprite state: off - - type: ShadowkinLight - type: PointLight enabled: true - type: PoweredLight From 20d8546676a24b0301b85140413f19a99cf871fe Mon Sep 17 00:00:00 2001 From: Finket Date: Mon, 6 Nov 2023 16:04:24 +0200 Subject: [PATCH 07/59] Port shadowkin visibility flags --- Content.Server/Visible/VisibilityFlags.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Content.Server/Visible/VisibilityFlags.cs diff --git a/Content.Server/Visible/VisibilityFlags.cs b/Content.Server/Visible/VisibilityFlags.cs new file mode 100644 index 0000000000..9cf76bcc47 --- /dev/null +++ b/Content.Server/Visible/VisibilityFlags.cs @@ -0,0 +1,13 @@ +namespace Content.Server.Visible +{ + [Flags] + public enum VisibilityFlags : uint + { + None = 0, + Normal = 1 << 0, + Ghost = 1 << 1, + PsionicInvisibility = 1 << 2, + DarkSwapInvisibility = 1 << 3, + AIEye = 1 << 4, + } +} From 279bda935fa21ba9c5ed7e2fdf0f166ce8f37ad8 Mon Sep 17 00:00:00 2001 From: Finket Date: Mon, 6 Nov 2023 17:11:28 +0200 Subject: [PATCH 08/59] Outline fixes and address some upstream refactor conflicts --- .../ShadowkinBlackeyeTraitComponent.cs | 2 +- .../ShadowkinDarkSwapPowerComponent.cs | 4 +- .../Components/ShadowkinLightComponent.cs | 2 +- .../Components/ShadowkinRestPowerComponent.cs | 4 +- .../ShadowkinTeleportPowerComponent.cs | 4 +- .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 23 +++-- .../Systems/ShadowkinPowerSystem.Rest.cs | 10 ++- .../Systems/ShadowkinPowerSystem.Teleport.cs | 8 +- .../Shadowkin/Systems/ShadowkinSystem.cs | 4 +- .../SimpleStation14/Magic/shadowkin.yml | 84 ++++++++++--------- 10 files changed, 82 insertions(+), 63 deletions(-) diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinBlackeyeTraitComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinBlackeyeTraitComponent.cs index 4946971df8..13a4010f9b 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinBlackeyeTraitComponent.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinBlackeyeTraitComponent.cs @@ -1,7 +1,7 @@ namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; [RegisterComponent] -public sealed class ShadowkinBlackeyeTraitComponent : Component +public sealed partial class ShadowkinBlackeyeTraitComponent : Component { } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs index 68333a32cd..6ede3ec25f 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs @@ -1,7 +1,7 @@ namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; [RegisterComponent] -public sealed class ShadowkinDarkSwapPowerComponent : Component +public sealed partial class ShadowkinDarkSwapPowerComponent : Component { - + public EntityUid? ActionShadowkinDarkSwap { get; set; } } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinLightComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinLightComponent.cs index 33ba441947..f96c48a018 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinLightComponent.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinLightComponent.cs @@ -1,7 +1,7 @@ namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; [RegisterComponent] -public sealed class ShadowkinLightComponent : Component +public sealed partial class ShadowkinLightComponent : Component { [ViewVariables(VVAccess.ReadOnly)] public EntityUid AttachedEntity = EntityUid.Invalid; diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinRestPowerComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinRestPowerComponent.cs index f485136b5e..e25640fb11 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinRestPowerComponent.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinRestPowerComponent.cs @@ -1,8 +1,10 @@ namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; [RegisterComponent] -public sealed class ShadowkinRestPowerComponent : Component +public sealed partial class ShadowkinRestPowerComponent : Component { [ViewVariables(VVAccess.ReadOnly)] public bool IsResting = false; + + public EntityUid? ActionShadowkinRest { get; set; } } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinTeleportPowerComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinTeleportPowerComponent.cs index 8643b4a401..eca292667a 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinTeleportPowerComponent.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinTeleportPowerComponent.cs @@ -3,7 +3,7 @@ namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; [RegisterComponent] -public sealed class ShadowkinTeleportPowerComponent : Component +public sealed partial class ShadowkinTeleportPowerComponent : Component { - + public EntityUid? ActionShadowkinTeleport { get; set; } } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 1eeab47d39..8e6fcee028 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -4,10 +4,10 @@ using Content.Server.SimpleStation14.Species.Shadowkin.Events; using Content.Server.Visible; using Content.Shared.Actions; -using Content.Shared.Actions.ActionTypes; using Content.Shared.CombatMode.Pacification; using Content.Shared.Cuffs.Components; using Content.Shared.Damage.Systems; +using Content.Shared.Ghost; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; using Content.Shared.SimpleStation14.Species.Shadowkin.Events; using Content.Shared.Stealth; @@ -47,12 +47,14 @@ public override void Initialize() private void Startup(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentStartup args) { - _actions.AddAction(uid, new InstantAction(_prototype.Index("ShadowkinDarkSwap")), null); + var componentActionShadowkinDarkSwap = component.ActionShadowkinDarkSwap; + _actions.AddAction(uid, ref componentActionShadowkinDarkSwap, "ActionShadowkinDarkSwap"); + // _actions.AddAction(uid, "ActionShadowkinDarkSwap"); } private void Shutdown(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentShutdown args) { - _actions.RemoveAction(uid, new InstantAction(_prototype.Index("ShadowkinDarkSwap"))); + _actions.RemoveAction(uid, component.ActionShadowkinDarkSwap); } @@ -87,6 +89,7 @@ private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ); _magic.Speak(args, false); } + public void SetDarkened( EntityUid performer, bool addComp, @@ -128,12 +131,14 @@ public void SetDarkened( if (args != null) args.Handled = true; } + private void OnInvisStartup(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentStartup args) { EnsureComp(uid); if (component.Invisible) SetCanSeeInvisibility(uid, true); } + private void OnInvisShutdown(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentShutdown args) { RemComp(uid); @@ -149,15 +154,17 @@ private void OnInvisShutdown(EntityUid uid, ShadowkinDarkSwappedComponent compon } component.DarkenedLights.Clear(); } + + // Commented out eye and ghost stuff until ported public void SetCanSeeInvisibility(EntityUid uid, bool set) { var visibility = _entity.EnsureComponent(uid); if (set) { - if (_entity.TryGetComponent(uid, out EyeComponent? eye)) + /*if (_entity.TryGetComponent(uid, out EyeComponent? eye)) { eye.VisibilityMask |= (uint) VisibilityFlags.DarkSwapInvisibility; - } + }*/ _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); @@ -166,10 +173,10 @@ public void SetCanSeeInvisibility(EntityUid uid, bool set) } else { - if (_entity.TryGetComponent(uid, out EyeComponent? eye)) + /*if (_entity.TryGetComponent(uid, out EyeComponent? eye)) { - eye.VisibilityMask &= ~(uint) VisibilityFlags.DarkSwapInvisibility; - } + // eye.VisibilityMask &= ~(uint) VisibilityFlags.DarkSwapInvisibility; + }*/ _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index d2ff89af3c..edc26f42eb 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -1,7 +1,6 @@ using Content.Server.SimpleStation14.Species.Shadowkin.Components; using Content.Server.SimpleStation14.Species.Shadowkin.Events; using Content.Shared.Actions; -using Content.Shared.Actions.ActionTypes; using Content.Shared.Bed.Sleep; using Content.Shared.Cuffs.Components; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; @@ -29,12 +28,13 @@ public override void Initialize() private void OnStartup(EntityUid uid, ShadowkinRestPowerComponent component, ComponentStartup args) { - _actions.AddAction(uid, new InstantAction(_prototype.Index("ShadowkinRest")), null); + var componentActionShadowkinRest = component.ActionShadowkinRest; + _actions.AddAction(uid, ref componentActionShadowkinRest, "ActionShadowkinRest"); } private void OnShutdown(EntityUid uid, ShadowkinRestPowerComponent component, ComponentShutdown args) { - _actions.RemoveAction(uid, new InstantAction(_prototype.Index("ShadowkinRest"))); + _actions.RemoveAction(uid, component.ActionShadowkinRest); } private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, ShadowkinRestEvent args) @@ -57,7 +57,9 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki // Sleepy time _entity.EnsureComponent(args.Performer); // No waking up normally (it would do nothing) - _actions.RemoveAction(args.Performer, new InstantAction(_prototype.Index("Wake"))); + // Not sure what needs to be done here with the refactor + // _actions.RemoveAction(args.Performer, component.WakeAction); // ?? + // _actions.RemoveAction(args.Performer, new InstantAction(_prototype.Index("Wake"))); _power.TryAddMultiplier(args.Performer, 1.5f); // No action cooldown diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index 094c2ab8f0..a5d260aae1 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -3,7 +3,6 @@ using Content.Server.SimpleStation14.Species.Shadowkin.Components; using Content.Server.SimpleStation14.Species.Shadowkin.Events; using Content.Shared.Actions; -using Content.Shared.Actions.ActionTypes; using Content.Shared.Cuffs.Components; using Content.Shared.Damage.Systems; using Content.Shared.Pulling.Components; @@ -38,12 +37,15 @@ public override void Initialize() private void Startup(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentStartup args) { - _actions.AddAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport")), null); + var componentActionShadowkinTeleport = component.ActionShadowkinTeleport; + _actions.AddAction(uid, ref componentActionShadowkinTeleport, "ActionShadowkinTeleport"); + // _actions.AddAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport")), null); } private void Shutdown(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentShutdown args) { - _actions.RemoveAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport"))); + _actions.RemoveAction(uid, component.ActionShadowkinTeleport); + // _actions.RemoveAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport"))); } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs index 12d89f6ab3..288b03c1e7 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs @@ -1,6 +1,6 @@ using System.Numerics; using Content.Server.Mind; -using Content.Server.Mind.Components; +using Content.Shared.Mind.Components; using Content.Server.SimpleStation14.Species.Shadowkin.Events; using Content.Shared.Bed.Sleep; using Content.Shared.Cuffs.Components; @@ -100,7 +100,7 @@ public override void Update(float frameTime) } // Don't update things for ssd shadowkin - if (!_entity.System().TryGetMind(uid, out var mind) || + if (!_entity.System().TryGetMind(uid, out var mindId, out var mind) || mind.Session == null) continue; diff --git a/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml index 2df3454d7a..07ff9babb2 100644 --- a/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml @@ -1,47 +1,53 @@ -- type: worldTargetAction - id: ShadowkinTeleport +- type: entity + id: ActionShadowkinTeleport name: action-name-shadowkin-teleport description: action-description-shadowkin-teleport - useDelay: 5 - range: 32 - itemIconStyle: NoItem - checkCanAccess: true - repeat: true - priority: -20 - icon: - sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi - state: teleport - serverEvent: !type:ShadowkinTeleportEvent - powerCost: 40 - staminaCost: 20 - speech: action-description-shadowkin-teleport + components: + - type: WorldTargetAction + useDelay: 5 + range: 32 + itemIconStyle: NoItem + checkCanAccess: true + repeat: true + priority: -20 + icon: + sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi + state: teleport + serverEvent: !type:ShadowkinTeleportEvent + powerCost: 40 + staminaCost: 20 + speech: action-description-shadowkin-teleport -- type: instantAction - id: ShadowkinDarkSwap +- type: entity + id: ActionShadowkinDarkSwap name: action-name-shadowkin-darkswap description: action-description-shadowkin-darkswap - useDelay: 15 - itemIconStyle: NoItem - priority: -21 - icon: - sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi - state: darkswap - serverEvent: !type:ShadowkinDarkSwapEvent - powerCostOn: 60 - powerCostOff: 45 - staminaCostOn: 25 - staminaCostOff: 25 - speech: action-description-shadowkin-darkswap + components: + - type: InstantAction + useDelay: 15 + itemIconStyle: NoItem + priority: -21 + icon: + sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi + state: darkswap + serverEvent: !type:ShadowkinDarkSwapEvent + powerCostOn: 60 + powerCostOff: 45 + staminaCostOn: 25 + staminaCostOff: 25 + speech: action-description-shadowkin-darkswap -- type: instantAction - id: ShadowkinRest +- type: entity + id: ActionShadowkinRest name: action-name-shadowkin-rest description: action-description-shadowkin-rest - useDelay: 60 - itemIconStyle: NoItem - priority: -22 - icon: - sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi - state: rest - checkCanInteract: false - serverEvent: !type:ShadowkinRestEvent + components: + - type: InstantAction + useDelay: 60 + itemIconStyle: NoItem + priority: -22 + icon: + sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi + state: rest + checkCanInteract: false + serverEvent: !type:ShadowkinRestEvent From 4577f388ae2e03021e95403433dcf0a837e4b4bc Mon Sep 17 00:00:00 2001 From: Finket Date: Mon, 6 Nov 2023 17:42:26 +0200 Subject: [PATCH 09/59] Fix other old refactor conflicts --- Content.Server/SimpleStation14/Chat/ESayCommand.cs | 2 +- .../Shadowkin/Events/ShadowkinEvents.Powers.cs | 2 +- .../Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs | 4 ++-- .../Shadowkin/Systems/ShadowkinSystem.Blackeye.cs | 12 +++--------- .../Speech/Components/ShadowkinAccentComponent.cs | 2 +- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/Content.Server/SimpleStation14/Chat/ESayCommand.cs b/Content.Server/SimpleStation14/Chat/ESayCommand.cs index 4e125bc581..e3f81360a8 100644 --- a/Content.Server/SimpleStation14/Chat/ESayCommand.cs +++ b/Content.Server/SimpleStation14/Chat/ESayCommand.cs @@ -37,7 +37,7 @@ public void Execute(IConsoleShell shell, string argStr, string[] args) if (string.IsNullOrEmpty(message)) return; - EntitySystem.Get().TrySendInGameICMessage(playerEntity, message, InGameICChatType.Empathy, false, shell, player, checkRadioPrefix: false); + EntitySystem.Get().TrySendInGameICMessage(playerEntity, message, InGameICChatType.Empathy, false, false, shell, player, checkRadioPrefix: false); } } } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs index b120bc1b45..5008e8992f 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs @@ -24,7 +24,7 @@ public sealed partial class ShadowkinTeleportEvent : WorldTargetActionEvent, ISp [DataField("speech")] - public string? Speech { get; } + public string? Speech { get; set; } } /// diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs index 9f2ea18ede..c7e2769e34 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs @@ -24,7 +24,7 @@ public void ResetLight(PointLightComponent light, ShadowkinLightComponent sLight sLight.OldRadiusEdited = false; if (sLight.OldEnergyEdited) - light.Energy = sLight.OldEnergy; + _light.SetEnergy(light.Owner, sLight.OldEnergy); sLight.OldEnergyEdited = false; } @@ -136,7 +136,7 @@ public override void Update(float frameTime) // Put changes into effect _light.SetRadius(pointLight.Owner, radius); - pointLight.Energy = energy; + _light.SetEnergy(pointLight.Owner, energy); } } } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs index 1e20a215aa..908a77317c 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs @@ -80,15 +80,9 @@ private void OnBlackeye(ShadowkinBlackeyeEvent ev) var minus = damageable.TotalDamage; - _damageable.TryChangeDamage( - ev.Uid, - new DamageSpecifier(_prototype.Index("Cellular"), + _damageable.TryChangeDamage(ev.Uid, new DamageSpecifier(_prototype.Index("Cellular"), Math.Max((double) (key.Value - minus - 5), 0)), - true, - true, - null, - null, - false - ); + true, + true, null, null); } } diff --git a/Content.Server/SimpleStation14/Speech/Components/ShadowkinAccentComponent.cs b/Content.Server/SimpleStation14/Speech/Components/ShadowkinAccentComponent.cs index 20ab1723a7..5e613d5c76 100644 --- a/Content.Server/SimpleStation14/Speech/Components/ShadowkinAccentComponent.cs +++ b/Content.Server/SimpleStation14/Speech/Components/ShadowkinAccentComponent.cs @@ -1,4 +1,4 @@ namespace Content.Server.Speech.Components; [RegisterComponent] -public sealed class ShadowkinAccentComponent : Component {} +public sealed partial class ShadowkinAccentComponent : Component {} From a9c37e6b7a56928620a2c06e2088dbb0f0abc75f Mon Sep 17 00:00:00 2001 From: Finket Date: Tue, 7 Nov 2023 12:56:06 +0200 Subject: [PATCH 10/59] Add some shadowkin improvements progress --- .../ShadowkinDarkSwapPowerComponent.cs | 46 +++- .../Components/ShadowkinSightComponent.cs | 7 + .../Events/ShadowkinEvents.Powers.cs | 2 +- .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 218 ++++++++++++++---- .../Systems/ShadowkinPowerSystem.Rest.cs | 6 +- 5 files changed, 224 insertions(+), 55 deletions(-) create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinSightComponent.cs diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs index 6ede3ec25f..245d7d5a98 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs @@ -1,7 +1,51 @@ -namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; +using Content.Server.NPC.Components; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; + +namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; [RegisterComponent] public sealed partial class ShadowkinDarkSwapPowerComponent : Component { public EntityUid? ActionShadowkinDarkSwap { get; set; } + + /// + /// Factions temporarily deleted from the entity while swapped + /// + public List SuppressedFactions = new(); + /// + /// Factions temporarily added to the entity while swapped + /// + [DataField("factions", customTypeSerializer: typeof(PrototypeIdListSerializer))] + public List AddedFactions = new() { "ShadowkinDarkFriendly" }; + + /// + /// If the entity should be sent to the dark + /// + [DataField("invisible")] + public bool Invisible = true; + + /// + /// If it should be pacified + /// + [DataField("pacify")] + public bool Pacify = true; + + /// + /// If the entity should dim nearby lights when swapped + /// + [DataField("darken"), ViewVariables(VVAccess.ReadWrite)] + public bool Darken = true; + + /// + /// How far to dim nearby lights + /// + [DataField("range"), ViewVariables(VVAccess.ReadWrite)] + public float DarkenRange = 5f; + + /// + /// How fast to refresh nearby light dimming in seconds + /// Without this performance would be significantly worse + /// + [ViewVariables(VVAccess.ReadWrite)] + public float DarkenRate = 0.084f; // 1/12th of a second } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinSightComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinSightComponent.cs new file mode 100644 index 0000000000..f66ea62e9b --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinSightComponent.cs @@ -0,0 +1,7 @@ +namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; + +[RegisterComponent] +public sealed class ShadowkinSightComponent : Component +{ + +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs index 5008e8992f..aced4dc646 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs @@ -76,7 +76,7 @@ public sealed partial class ShadowkinDarkSwapEvent : InstantActionEvent, ISpeakS public sealed class ShadowkinDarkSwapAttemptEvent : CancellableEntityEventArgs { - EntityUid Performer; + public EntityUid Performer; public ShadowkinDarkSwapAttemptEvent(EntityUid performer) { diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 8e6fcee028..8a9e490b4e 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -1,8 +1,11 @@ -using Content.Server.Ghost.Components; +using System.Linq; +using Content.Server.Ghost.Components; using Content.Server.Magic; using Content.Server.SimpleStation14.Species.Shadowkin.Components; using Content.Server.SimpleStation14.Species.Shadowkin.Events; using Content.Server.Visible; +using Content.Server.NPC.Systems; +using Content.Server.NPC.Components; using Content.Shared.Actions; using Content.Shared.CombatMode.Pacification; using Content.Shared.Cuffs.Components; @@ -16,6 +19,7 @@ using Robust.Shared.Audio; using Robust.Shared.Prototypes; + namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; public sealed class ShadowkinDarkSwapSystem : EntitySystem @@ -30,6 +34,7 @@ public sealed class ShadowkinDarkSwapSystem : EntitySystem [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly MagicSystem _magic = default!; + [Dependency] private readonly NpcFactionSystem _factions = default!; public override void Initialize() { @@ -44,12 +49,10 @@ public override void Initialize() SubscribeLocalEvent(OnInvisShutdown); } - private void Startup(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentStartup args) { var componentActionShadowkinDarkSwap = component.ActionShadowkinDarkSwap; _actions.AddAction(uid, ref componentActionShadowkinDarkSwap, "ActionShadowkinDarkSwap"); - // _actions.AddAction(uid, "ActionShadowkinDarkSwap"); } private void Shutdown(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentShutdown args) @@ -64,124 +67,239 @@ private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, if (!_entity.HasComponent(args.Performer)) return; - // Don't activate abilities if handcuffed - // TODO: Something like the Psionic Headcage to disable powers for Shadowkin - if (_entity.HasComponent(args.Performer)) + // Don't activate abilities if specially handcuffed + if (_entity.TryGetComponent(args.Performer, out var cuffs) && cuffs.AntiShadowkin) return; - var hasComp = _entity.HasComponent(args.Performer); - SetDarkened( args.Performer, - !hasComp, - !hasComp, - true, - args.StaminaCostOn, - args.PowerCostOn, + !_entity.HasComponent(args.Performer), args.SoundOn, args.VolumeOn, - args.StaminaCostOff, - args.PowerCostOff, args.SoundOff, args.VolumeOff, - args + args, + args.StaminaCostOn, + args.PowerCostOn, + args.StaminaCostOff, + args.PowerCostOff ); + _magic.Speak(args, false); } + + /// + /// Handles the effects of darkswapping + /// + /// The entity being modified + /// Is the entity swapping in to or out of The Dark? + /// Sound for the darkswapping + /// Volume for the on sound + /// Sound for the un swapping + /// Volume for the off sound + /// Stamina cost for darkswapping + /// Power cost for darkswapping + /// Stamina cost for un swapping + /// Power cost for un swapping + /// If from an event, handle it public void SetDarkened( EntityUid performer, bool addComp, - bool invisible, - bool darken, - float staminaCostOn, - float powerCostOn, - SoundSpecifier soundOn, - float volumeOn, - float staminaCostOff, - float powerCostOff, - SoundSpecifier soundOff, - float volumeOff, - ShadowkinDarkSwapEvent? args + SoundSpecifier? soundOn, + float? volumeOn, + SoundSpecifier? soundOff, + float? volumeOff, + ShadowkinDarkSwapEvent? args, + float staminaCostOn = 0, + float powerCostOn = 0, + float staminaCostOff = 0, + float powerCostOff = 0 ) { + // Ask other systems if we can DarkSwap var ev = new ShadowkinDarkSwapAttemptEvent(performer); RaiseLocalEvent(ev); if (ev.Cancelled) return; - if (addComp) + + // We require the power component to DarkSwap + if (!_entity.TryGetComponent(performer, out var power)) + return; + + if (addComp) // Into The Dark { + // Add the DarkSwapped component and set variables to match the power component var comp = _entity.EnsureComponent(performer); - comp.Invisible = invisible; - comp.Darken = darken; + comp.Invisible = power.Invisible; + comp.Pacify = power.Pacify; + comp.Darken = power.Darken; + comp.DarkenRange = power.DarkenRange; + comp.DarkenRate = power.DarkenRate; + + // Tell other systems we've DarkSwapped RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, true)); - _audio.PlayPvs(soundOn, performer, AudioParams.Default.WithVolume(volumeOn)); + + // Play a sound if we have one + if (soundOn != null) + _audio.PlayPvs(soundOn, performer, AudioParams.Default.WithVolume(volumeOn ?? 5f)); + + // Drain power and stamina if we have a cost _power.TryAddPowerLevel(performer, -powerCostOn); _stamina.TakeStaminaDamage(performer, staminaCostOn); } - else + else // Out of The Dark { + // Remove the DarkSwapped component, the rest is handled in the shutdown event _entity.RemoveComponent(performer); + + // Tell other systems we've un DarkSwapped RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, false)); - _audio.PlayPvs(soundOff, performer, AudioParams.Default.WithVolume(volumeOff)); + + // Play a sound if we have one + if (soundOff != null) + _audio.PlayPvs(soundOff, performer, AudioParams.Default.WithVolume(volumeOff ?? 5f)); + + // Drain power and stamina if we have a cost _power.TryAddPowerLevel(performer, -powerCostOff); _stamina.TakeStaminaDamage(performer, staminaCostOff); } + + // If we have an event, mark it as handled if (args != null) args.Handled = true; } + private void OnInvisStartup(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentStartup args) { - EnsureComp(uid); + if (component.Pacify) + EnsureComp(uid); + if (component.Invisible) - SetCanSeeInvisibility(uid, true); + { + SetVisibility(uid, true, true, true); + SuppressFactions(uid, true); + } } private void OnInvisShutdown(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentShutdown args) { RemComp(uid); + if (component.Invisible) - SetCanSeeInvisibility(uid, false); + { + SetVisibility(uid, false, false, false); + SuppressFactions(uid, false); + } + + // Prevent more updates while we're cleaning up component.Darken = false; + + // In case more updates occur for some reason, create a copy of the list to prevent error foreach (var light in component.DarkenedLights.ToArray()) { if (!_entity.TryGetComponent(light, out var pointLight) || !_entity.TryGetComponent(light, out var shadowkinLight)) continue; + _darken.ResetLight(pointLight, shadowkinLight); } + + // Clear the original array component.DarkenedLights.Clear(); } // Commented out eye and ghost stuff until ported - public void SetCanSeeInvisibility(EntityUid uid, bool set) + /// + /// Makes the specified entity able to see Shadowkin invisibility. + /// + /// Entity to modify + /// Whether the entity can see invisibility + /// Should the entity be moved to another visibility layer? + /// (Only gets considered if set is true) Adds stealth to the entity + public void SetVisibility(EntityUid uid, bool set, bool invisibility, bool stealth) { + // We require the visibility component for this to work var visibility = _entity.EnsureComponent(uid); - if (set) + + if (set) // Invisible { + // Allow the entity to see DarkSwapped entities /*if (_entity.TryGetComponent(uid, out EyeComponent? eye)) + eye.VisibilityMask |= (uint) VisibilityFlags.DarkSwapInvisibility;*/ + + // Make other entities unable to see the entity unless also DarkSwapped + if (invisibility) { - eye.VisibilityMask |= (uint) VisibilityFlags.DarkSwapInvisibility; - }*/ - _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); - _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); + _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + } _visibility.RefreshVisibility(uid); - if (!_entity.TryGetComponent(uid, out var _)) + + // If not a ghost, add a stealth shader to the entity + if (!_entity.TryGetComponent(uid, out _) && stealth) _stealth.SetVisibility(uid, 0.8f, _entity.EnsureComponent(uid)); } - else + else // Visible { + // Remove the ability to see DarkSwapped entities /*if (_entity.TryGetComponent(uid, out EyeComponent? eye)) + eye.VisibilityMask &= ~(uint) VisibilityFlags.DarkSwapInvisibility;*/ + + // Make other entities able to see the entity again + if (invisibility) { - // eye.VisibilityMask &= ~(uint) VisibilityFlags.DarkSwapInvisibility; - }*/ - _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); - _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); + _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + } _visibility.RefreshVisibility(uid); - if (!_entity.TryGetComponent(uid, out var _)) - _entity.RemoveComponent(uid); + + // Remove the stealth shader from the entity + if (!_entity.TryGetComponent(uid, out _)) + _stealth.SetEnabled(uid, false); + } + } + + /// + /// Remove existing factions on the entity and move them to the power component to add back when removed from The Dark + /// + /// Entity to modify factions for + /// Add or remove the factions + public void SuppressFactions(EntityUid uid, bool set) + { + // We require the power component to keep track of the factions + if (!_entity.TryGetComponent(uid, out var component)) + return; + + if (set) + { + if (!_entity.TryGetComponent(uid, out var factions)) + return; + + // Copy the suppressed factions to the power component + component.SuppressedFactions = factions.Factions.ToList(); + + // Remove the factions from the entity + foreach (var faction in factions.Factions) + _factions.RemoveFaction(uid, faction); + + // Add status factions for The Dark to the entity + foreach (var faction in component.AddedFactions) + _factions.AddFaction(uid, faction); + } + else + { + // Remove the status factions from the entity + foreach (var faction in component.AddedFactions) + _factions.RemoveFaction(uid, faction); + + // Add the factions back to the entity + foreach (var faction in component.SuppressedFactions) + _factions.AddFaction(uid, faction); + + component.SuppressedFactions.Clear(); } } } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index edc26f42eb..7c0fba7ff2 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -8,6 +8,7 @@ namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; + public sealed class ShadowkinRestSystem : EntitySystem { [Dependency] private readonly IEntityManager _entity = default!; @@ -25,7 +26,6 @@ public override void Initialize() SubscribeLocalEvent(Rest); } - private void OnStartup(EntityUid uid, ShadowkinRestPowerComponent component, ComponentStartup args) { var componentActionShadowkinRest = component.ActionShadowkinRest; @@ -44,8 +44,8 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki return; // Rest is a funny ability, keep it :) - // // Don't activate abilities if handcuffed - // if (_entity.HasComponent(args.Performer)) + // // Don't activate abilities if specially handcuffed + // if (_entity.TryGetComponent(args.Performer, out var cuffs) && cuffs.AntiShadowkin) // return; // Now doing what you weren't before From 145381aa8dc6163a9a6d706adf63965317f351ad Mon Sep 17 00:00:00 2001 From: Finket Date: Tue, 7 Nov 2023 14:10:00 +0200 Subject: [PATCH 11/59] Add more of the shadowkin improvements --- .../Systems/ShadowkinPowerSystem.Rest.cs | 6 +- .../Systems/ShadowkinPowerSystem.Teleport.cs | 25 ++-- .../Shadowkin/Systems/ShadowkinPowerSystem.cs | 15 +- .../Shadowkin/Systems/ShadowkinSightSystem.cs | 29 ++++ .../Systems/ShadowkinSystem.Blackeye.cs | 38 ++++- .../Traits/Events/CloningEvents.cs | 36 +++++ .../Cuffs/Components/HandcuffComponent.cs | 6 + .../Components/ShadowkinComponent.cs | 6 +- .../ShadowkinDarkSwappedComponent.cs | 17 ++- .../Events/ShadowkinEvents.Blackeye.cs | 4 +- .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 12 +- Resources/Prototypes/Reagents/toxins.yml | 12 +- .../SimpleStation14/Actions/types.yml | 12 ++ .../SimpleStation14/Body/Organs/shadowkin.yml | 138 ++++++++++++++++++ .../Chemistry/metabolizer_types.yml | 3 + .../Entites/Body/Parts/shadowkin.yml | 4 +- .../Entites/Body/Prototypes/shadowkin.yml | 16 +- .../Entites/Clothing/Eyes/glasses.yml | 14 ++ .../Clothing/Head/hardsuit-helmets.yml | 27 ++++ .../Clothing/OuterClothing/hardsuits.yml | 30 ++++ .../Entites/Mobs/Player/shadowkin.yml | 60 +++++++- .../Entites/Objects/Misc/handcuffs.yml | 21 +++ .../SimpleStation14/Species/shadowkin.yml | 30 ++-- 23 files changed, 488 insertions(+), 73 deletions(-) create mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSightSystem.cs create mode 100644 Content.Server/SimpleStation14/Traits/Events/CloningEvents.cs create mode 100644 Resources/Prototypes/SimpleStation14/Actions/types.yml create mode 100644 Resources/Prototypes/SimpleStation14/Body/Organs/shadowkin.yml create mode 100644 Resources/Prototypes/SimpleStation14/Chemistry/metabolizer_types.yml create mode 100644 Resources/Prototypes/SimpleStation14/Entites/Clothing/Eyes/glasses.yml create mode 100644 Resources/Prototypes/SimpleStation14/Entites/Objects/Misc/handcuffs.yml diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index 7c0fba7ff2..20b1dba2ce 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -22,7 +22,6 @@ public override void Initialize() SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnShutdown); - SubscribeLocalEvent(Rest); } @@ -57,8 +56,7 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki // Sleepy time _entity.EnsureComponent(args.Performer); // No waking up normally (it would do nothing) - // Not sure what needs to be done here with the refactor - // _actions.RemoveAction(args.Performer, component.WakeAction); // ?? + // _actions.RemoveAction(args.Performer, uid....Wake); // ?? // _actions.RemoveAction(args.Performer, new InstantAction(_prototype.Index("Wake"))); _power.TryAddMultiplier(args.Performer, 1.5f); @@ -71,7 +69,7 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki // Wake up _entity.RemoveComponent(args.Performer); _entity.RemoveComponent(args.Performer); - _power.TryAddMultiplier(args.Performer, -1.5f); + _power.TryAddMultiplier(args.Performer, -2f); // Action cooldown args.Handled = true; } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index a5d260aae1..053575866f 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -7,9 +7,11 @@ using Content.Shared.Damage.Systems; using Content.Shared.Pulling.Components; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.Storage.Components; using Robust.Shared.Audio; using Robust.Shared.Prototypes; + namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; public sealed class ShadowkinTeleportSystem : EntitySystem @@ -34,34 +36,29 @@ public override void Initialize() SubscribeLocalEvent(Teleport); } - private void Startup(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentStartup args) { var componentActionShadowkinTeleport = component.ActionShadowkinTeleport; _actions.AddAction(uid, ref componentActionShadowkinTeleport, "ActionShadowkinTeleport"); - // _actions.AddAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport")), null); } private void Shutdown(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentShutdown args) { _actions.RemoveAction(uid, component.ActionShadowkinTeleport); - // _actions.RemoveAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport"))); } private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, ShadowkinTeleportEvent args) { - // Need power to drain power - if (!_entity.TryGetComponent(args.Performer, out var comp)) - return; - - // Don't activate abilities if handcuffed - // TODO: Something like the Psionic Headcage to disable powers for Shadowkin - if (_entity.HasComponent(args.Performer)) + // Don't activate abilities if... + if (!_entity.TryGetComponent(args.Performer, out var comp) || // Not a Shadowkin + _entity.TryGetComponent(args.Performer, out var cuffs) && cuffs.AntiShadowkin || // Specially handcuffed + _entity.HasComponent(args.Performer)) // Inside an entity storage return; var transform = Transform(args.Performer); + // Must be on the same map if (transform.MapID != args.Target.GetMapId(EntityManager)) return; @@ -70,14 +67,12 @@ private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, puller.Pulling != null && _entity.TryGetComponent(puller.Pulling, out pullable) && pullable.BeingPulled) - { - // Temporarily stop pulling to avoid not teleporting to the target + // Temporarily stop pulling to avoid not teleporting fully to the target _pulling.TryStopPull(pullable); - } // Teleport the performer to the target _transform.SetCoordinates(args.Performer, args.Target); - transform.AttachToGridOrMap(); + _transform.AttachToGridOrMap(args.Performer, transform); if (pullable != null && puller != null) { @@ -87,7 +82,7 @@ private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, // Teleport the pulled entity to the target // TODO: Relative position to the performer _transform.SetCoordinates(pullable.Owner, args.Target); - pulledTransform.AttachToGridOrMap(); + _transform.AttachToGridOrMap(args.Performer, transform); // Resume pulling // TODO: This does nothing? // This does things sometimes, but the client never knows diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs index 81ded05b26..f164138a1a 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs @@ -196,22 +196,25 @@ public void SetPowerLevel(EntityUid uid, float newPowerLevel) /// /// Tries to blackeye a shadowkin. /// - public bool TryBlackeye(EntityUid uid) + public bool TryBlackeye(EntityUid uid, bool damage = true, bool checkPower = true) { + if (!_entity.HasComponent(uid)) + return false; + // Raise an attempted blackeye event - var ev = new ShadowkinBlackeyeAttemptEvent(uid); + var ev = new ShadowkinBlackeyeAttemptEvent(uid, checkPower); RaiseLocalEvent(ev); if (ev.Cancelled) return false; - Blackeye(uid); + Blackeye(uid, damage); return true; } /// /// Blackeyes a shadowkin. /// - public void Blackeye(EntityUid uid) + public void Blackeye(EntityUid uid, bool damage = true) { // Get shadowkin component if (!_entity.TryGetComponent(uid, out var component)) @@ -221,8 +224,8 @@ public void Blackeye(EntityUid uid) } component.Blackeye = true; - RaiseNetworkEvent(new ShadowkinBlackeyeEvent(uid)); - RaiseLocalEvent(new ShadowkinBlackeyeEvent(uid)); + RaiseNetworkEvent(new ShadowkinBlackeyeEvent(uid, damage)); + RaiseLocalEvent(new ShadowkinBlackeyeEvent(uid, damage)); } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSightSystem.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSightSystem.cs new file mode 100644 index 0000000000..b1a56999f1 --- /dev/null +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSightSystem.cs @@ -0,0 +1,29 @@ +using Content.Server.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.Inventory.Events; + +namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; + +public sealed class ShadowkinSightSystem : EntitySystem +{ + [Dependency] private readonly ShadowkinDarkSwapSystem _darkSwap = default!; + + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnEquipped); + SubscribeLocalEvent(OnUnEquipped); + } + + + private void OnEquipped(EntityUid uid, ShadowkinSightComponent component, GotEquippedEvent args) + { + _darkSwap.SetVisibility(args.Equipee, true, false, false); + } + + private void OnUnEquipped(EntityUid uid, ShadowkinSightComponent component, GotUnequippedEvent args) + { + _darkSwap.SetVisibility(args.Equipee, false, false, false); + } +} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs index 908a77317c..bc02c27b2d 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs @@ -1,4 +1,6 @@ -using Content.Server.SimpleStation14.Species.Shadowkin.Components; +using Content.Server.Cloning; +using Content.Server.SimpleStation14.Species.Shadowkin.Components; +using Content.Server.SimpleStation14.Traits.Events; using Content.Shared.SimpleStation14.Species.Shadowkin.Events; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; using Content.Shared.Damage.Systems; @@ -28,14 +30,20 @@ public override void Initialize() SubscribeLocalEvent(OnBlackeyeAttempt); SubscribeAllEvent(OnBlackeye); + + SubscribeLocalEvent(OnCloned); } private void OnBlackeyeAttempt(ShadowkinBlackeyeAttemptEvent ev) { + // Cancel if one of the following is true: + // - The entity is not a shadowkin + // - The entity is already blackeyed + // - The entity has more than 5 power and ev.CheckPower is true if (!_entity.TryGetComponent(ev.Uid, out var component) || component.Blackeye || - !(component.PowerLevel <= ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Min] + 5)) + (ev.CheckPower && component.PowerLevel > ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Min] + 5)) ev.Cancel(); } @@ -58,7 +66,7 @@ private void OnBlackeye(ShadowkinBlackeyeEvent ev) _entity.RemoveComponent(ev.Uid); _entity.RemoveComponent(ev.Uid); _entity.RemoveComponent(ev.Uid); - + _entity.RemoveComponent(ev.Uid); if (!ev.Damage) return; @@ -80,9 +88,29 @@ private void OnBlackeye(ShadowkinBlackeyeEvent ev) var minus = damageable.TotalDamage; - _damageable.TryChangeDamage(ev.Uid, new DamageSpecifier(_prototype.Index("Cellular"), + _damageable.TryChangeDamage( + ev.Uid, + new DamageSpecifier(_prototype.Index("Cellular"), Math.Max((double) (key.Value - minus - 5), 0)), true, - true, null, null); + true, + null, + null + ); + + } + + + private void OnCloned(BeenClonedEvent ev) + { + // Don't give blackeyed Shadowkin their abilities back when they're cloned. + if (_entity.TryGetComponent(ev.OriginalMob, out var shadowkin) && + shadowkin.Blackeye) + _power.TryBlackeye(ev.Mob, false, false); + + // Blackeye the Shadowkin that come from the metempsychosis machine + if (_entity.HasComponent(ev.Cloner) && + _entity.HasComponent(ev.Mob)) + _power.TryBlackeye(ev.Mob, false, false); } } diff --git a/Content.Server/SimpleStation14/Traits/Events/CloningEvents.cs b/Content.Server/SimpleStation14/Traits/Events/CloningEvents.cs new file mode 100644 index 0000000000..4f744d3de3 --- /dev/null +++ b/Content.Server/SimpleStation14/Traits/Events/CloningEvents.cs @@ -0,0 +1,36 @@ +using Content.Shared.Preferences; + +namespace Content.Server.SimpleStation14.Traits.Events +{ + public sealed class BeingClonedEvent : CancellableEntityEventArgs + { + public HumanoidCharacterProfile Profile { get; set; } + public Mind.MindSystem Mind { get; set; } + public EntityUid Cloner { get; set; } + + public BeingClonedEvent(HumanoidCharacterProfile profile, Mind.MindSystem mind, EntityUid cloner) + { + Profile = profile; + Mind = mind; + Cloner = cloner; + } + } + + public sealed class BeenClonedEvent : EntityEventArgs + { + public HumanoidCharacterProfile Profile { get; set; } + public Mind.MindSystem Mind { get; set; } + public EntityUid Mob { get; set; } + public EntityUid OriginalMob { get; set; } + public EntityUid Cloner { get; set; } + + public BeenClonedEvent(HumanoidCharacterProfile profile, Mind.MindSystem mind, EntityUid mob, EntityUid originalMob, EntityUid cloner) + { + Profile = profile; + Mind = mind; + Mob = mob; + OriginalMob = originalMob; + Cloner = cloner; + } + } +} diff --git a/Content.Shared/Cuffs/Components/HandcuffComponent.cs b/Content.Shared/Cuffs/Components/HandcuffComponent.cs index b43bf18bf8..7f2006b804 100644 --- a/Content.Shared/Cuffs/Components/HandcuffComponent.cs +++ b/Content.Shared/Cuffs/Components/HandcuffComponent.cs @@ -86,6 +86,12 @@ public sealed partial class HandcuffComponent : Component [DataField, ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier EndUncuffSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_takeoff_end.ogg"); + + + // Parkstation-Shadowkin Start + [DataField("antiShadowkin")] + public bool AntiShadowkin = false; + // Parkstation-Shadowkin End } /// diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs index 2763d3ef2d..1ba47df844 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs @@ -14,10 +14,10 @@ public sealed partial class ShadowkinComponent : Component public float MaxedPowerRoof = 0f; [ViewVariables(VVAccess.ReadWrite)] - public float MaxedPowerRateMin = 45f; + public float MaxedPowerRateMin = 90f; [ViewVariables(VVAccess.ReadWrite)] - public float MaxedPowerRateMax = 150f; + public float MaxedPowerRateMax = 200f; [ViewVariables(VVAccess.ReadWrite)] @@ -77,7 +77,7 @@ public float PowerLevel /// How much energy is gained per second. /// [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] - public float PowerLevelGain = 0.75f; + public float PowerLevelGain = 0.5f; /// /// Power gain multiplier diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs index 233236a8bd..c61e93808c 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs @@ -6,32 +6,43 @@ namespace Content.Shared.SimpleStation14.Species.Shadowkin.Components; public sealed partial class ShadowkinDarkSwappedComponent : Component { /// - /// If it should be sent to the dark + /// If the entity should be sent to the dark /// - [DataField("invisible")] + /// + /// This is also defined in the power component, this is if you want to use only some effects of the swap without a toggle + /// + [DataField("invisible"), ViewVariables(VVAccess.ReadWrite)] public bool Invisible = true; /// /// If it should be pacified /// + /// [DataField("pacify")] public bool Pacify = true; /// - /// If it should dim nearby lights + /// If the entity should dim nearby lights when swapped /// + /// [DataField("darken"), ViewVariables(VVAccess.ReadWrite)] public bool Darken = true; /// /// How far to dim nearby lights /// + /// [DataField("range"), ViewVariables(VVAccess.ReadWrite)] public float DarkenRange = 5f; [ViewVariables(VVAccess.ReadOnly)] public List DarkenedLights = new(); + /// + /// How fast to refresh nearby light dimming in seconds + /// Without this performance would be significantly worse + /// + /// [ViewVariables(VVAccess.ReadWrite)] public float DarkenRate = 0.084f; // 1/12th of a second diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs index 353313b2b3..01d3c49df0 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs @@ -8,10 +8,12 @@ namespace Content.Shared.SimpleStation14.Species.Shadowkin.Events; public sealed class ShadowkinBlackeyeAttemptEvent : CancellableEntityEventArgs { public readonly EntityUid Uid; + public readonly bool CheckPower; - public ShadowkinBlackeyeAttemptEvent(EntityUid uid) + public ShadowkinBlackeyeAttemptEvent(EntityUid uid, bool checkPower = true) { Uid = uid; + CheckPower = checkPower; } } diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 9cb201bc97..123de10a13 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -1,4 +1,5 @@ using Content.Shared.Interaction.Events; +using Content.Shared.Item; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; using Content.Shared.Popups; using Robust.Shared.Timing; @@ -21,14 +22,13 @@ public override void Initialize() private void OnInteractionAttempt(EntityUid uid, ShadowkinDarkSwappedComponent component, InteractionAttemptEvent args) { - if (args.Target == null || !_entity.TryGetComponent(args.Target, out var __) || - _entity.TryGetComponent(args.Target, out _)) + if (args.Target == null || + !_entity.HasComponent(args.Target) || + _entity.HasComponent(args.Target)) return; args.Cancel(); - if (_gameTiming.InPrediction) - return; - - _popup.PopupEntity(Loc.GetString("ethereal-pickup-fail"), args.Target.Value, uid); + if (_gameTiming.InPrediction && _gameTiming.IsFirstTimePredicted) + _popup.PopupEntity(Loc.GetString("ethereal-pickup-fail"), args.Target.Value, uid); } } diff --git a/Resources/Prototypes/Reagents/toxins.yml b/Resources/Prototypes/Reagents/toxins.yml index 41e83a7c71..f31d24e2d4 100644 --- a/Resources/Prototypes/Reagents/toxins.yml +++ b/Resources/Prototypes/Reagents/toxins.yml @@ -324,7 +324,7 @@ damage: groups: Toxin: 2 - - !type:ChemRemovePsionic #Nyano - Summary: removes psionics from the user at 20u. + - !type:ChemRemovePsionic #Nyano - Summary: removes psionics from the user at 20u. conditions: - !type:ReagentThreshold reagent: MindbreakerToxin @@ -469,6 +469,14 @@ type: Animal reagent: Protein amount: 0.5 + # Parkstation-Shadowkin Start + - !type:AdjustReagent + conditions: + - !type:OrganType + type: Shadowkin + reagent: Protein + amount: 0.5 + # Parkstation-Shadowkin End - type: reagent id: Allicin @@ -533,7 +541,7 @@ damage: types: Poison: 0.06 - + - type: reagent id: Lead diff --git a/Resources/Prototypes/SimpleStation14/Actions/types.yml b/Resources/Prototypes/SimpleStation14/Actions/types.yml new file mode 100644 index 0000000000..0224af6abb --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Actions/types.yml @@ -0,0 +1,12 @@ + +- type: entity + id: ShadowkinDarkSwapHardsuitToggle + name: action-darkswap-hardsuit-name + components: + - type: InstantAction + useDelay: 15 + icon: + sprite: SimpleStation14/Clothing/Head/Hardsuits/darkened.rsi + state: icon + itemIconStyle: NoItem + event: !type:ToggleClothingEvent diff --git a/Resources/Prototypes/SimpleStation14/Body/Organs/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Body/Organs/shadowkin.yml new file mode 100644 index 0000000000..6485660b13 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Body/Organs/shadowkin.yml @@ -0,0 +1,138 @@ +- type: entity + id: BaseShadowkinOrgan + parent: BaseItem + abstract: true + components: + - type: Organ + - type: Sprite + sprite: SimpleStation14/Mobs/Species/Shadowkin/organs.rsi + - type: DynamicPrice + price: 70 + + +- type: entity + id: OrganShadowkinBrain + parent: BaseShadowkinOrgan + name: brain + description: The source of incredible, unending intelligence. + components: + - type: Sprite + state: brain + - type: Organ + - type: Input + context: ghost + - type: InputMover + - type: MovementSpeedModifier # How the hell does it walk? + baseWalkSpeed: 0 + baseSprintSpeed: 0 + - type: Brain + +- type: entity + id: OrganShadowkinEyes + parent: BaseShadowkinOrgan + name: eyes + description: I see beyond anything you ever will! + components: + - type: Sprite + state: eyes + - type: Organ + +- type: entity + id: OrganShadowkinEars + parent: BaseShadowkinOrgan + name: ears + description: Hey, listen! + components: + - type: Sprite + state: ears + - type: Organ + +- type: entity + id: OrganShadowkinTongue + parent: BaseShadowkinOrgan + name: tongue + description: A fleshy muscle mostly used for lying. + components: + - type: Sprite + state: tongue + - type: Organ + + +- type: entity + id: OrganShadowkinAppendix + parent: BaseShadowkinOrgan + name: appendix + description: What does this do? + components: + - type: Sprite + state: appendix + - type: Organ + + +- type: entity + id: OrganShadowkinHeart + parent: BaseShadowkinOrgan + name: heart + description: I feel bad for the heartless bastard who lost this. + components: + - type: Sprite + state: heart + - type: Organ + - type: Metabolizer + maxReagents: 2 + metabolizerTypes: [Shadowkin] + groups: + - id: Medicine + - id: Poison + - id: Narcotic + +- type: entity + id: OrganShadowkinStomach + parent: BaseShadowkinOrgan + name: stomach + description: '"Yummy!", says the stomach, although you are unable to hear it.' + components: + - type: Sprite + state: stomach + - type: Organ + - type: SolutionContainerManager + solutions: + stomach: + maxVol: 40 + - type: Stomach + - type: Metabolizer + maxReagents: 3 + metabolizerTypes: [Shadowkin] + groups: + - id: Food + - id: Drink + +- type: entity + id: OrganShadowkinLiver + parent: BaseShadowkinOrgan + name: liver + description: "Live 'er? I hardly know 'er!" + components: + - type: Sprite + state: liver + - type: Organ + - type: Metabolizer + maxReagents: 1 + metabolizerTypes: [Shadowkin] + groups: + - id: Alcohol + rateModifier: 0.1 + +- type: entity + id: OrganShadowkinKidneys + parent: BaseShadowkinOrgan + name: kidneys + description: Give the kid their knees back, please, this is the third time this week. + components: + - type: Sprite + state: kidneys + - type: Organ + - type: Metabolizer + maxReagents: 5 + metabolizerTypes: [Shadowkin] + removeEmpty: true diff --git a/Resources/Prototypes/SimpleStation14/Chemistry/metabolizer_types.yml b/Resources/Prototypes/SimpleStation14/Chemistry/metabolizer_types.yml new file mode 100644 index 0000000000..98c7b42b10 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Chemistry/metabolizer_types.yml @@ -0,0 +1,3 @@ +- type: metabolizerType + id: Shadowkin + name: shadowkin diff --git a/Resources/Prototypes/SimpleStation14/Entites/Body/Parts/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entites/Body/Parts/shadowkin.yml index 67762764e0..3981906b15 100644 --- a/Resources/Prototypes/SimpleStation14/Entites/Body/Parts/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Entites/Body/Parts/shadowkin.yml @@ -6,9 +6,9 @@ components: - type: Sprite netsync: false - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi - type: Icon - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi - type: Damageable damageContainer: Biological - type: BodyPart diff --git a/Resources/Prototypes/SimpleStation14/Entites/Body/Prototypes/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entites/Body/Prototypes/shadowkin.yml index 2cbe244983..479cfe1c12 100644 --- a/Resources/Prototypes/SimpleStation14/Entites/Body/Prototypes/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Entites/Body/Prototypes/shadowkin.yml @@ -8,8 +8,8 @@ connections: - torso organs: - brain: OrganHumanBrain - eyes: OrganHumanEyes + brain: OrganShadowkinBrain + eyes: OrganShadowkinEyes torso: part: TorsoShadowkin connections: @@ -17,12 +17,12 @@ - right arm - left leg - right leg - organs: # placeholders - heart: OrganHumanHeart - # lungs: OrganLungs - stomach: OrganHumanStomach - liver: OrganHumanLiver - kidneys: OrganHumanKidneys + organs: + heart: OrganShadowkinHeart + # lungs: OrganHumanLungs + stomach: OrganShadowkinStomach + liver: OrganShadowkinLiver + kidneys: OrganShadowkinKidneys right arm: part: RightArmShadowkin connections: diff --git a/Resources/Prototypes/SimpleStation14/Entites/Clothing/Eyes/glasses.yml b/Resources/Prototypes/SimpleStation14/Entites/Clothing/Eyes/glasses.yml new file mode 100644 index 0000000000..b7ad451de6 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entites/Clothing/Eyes/glasses.yml @@ -0,0 +1,14 @@ +- type: entity + parent: ClothingEyesBase + id: ClothingEyesGlassesShadowkinDarkWindow + name: darkened goggles + description: An unusual pair of goggles developed during a time of inhumane experimentation involving Shadowkin. They are designed to allow the wearer to peer into The Dark. + components: + - type: Sprite + sprite: SimpleStation14/Clothing/Eyes/Glasses/darkened.rsi + - type: Clothing + sprite: SimpleStation14/Clothing/Eyes/Glasses/darkened.rsi + - type: EyeProtection + - type: DropOnSlip + chance: 20 + - type: ShadowkinSight diff --git a/Resources/Prototypes/SimpleStation14/Entites/Clothing/Head/hardsuit-helmets.yml b/Resources/Prototypes/SimpleStation14/Entites/Clothing/Head/hardsuit-helmets.yml index 842796607b..c9ea02f6f0 100644 --- a/Resources/Prototypes/SimpleStation14/Entites/Clothing/Head/hardsuit-helmets.yml +++ b/Resources/Prototypes/SimpleStation14/Entites/Clothing/Head/hardsuit-helmets.yml @@ -39,3 +39,30 @@ Piercing: 0.95 Heat: 0.9 Radiation: 0.6 + +- type: entity + parent: ClothingHeadHardsuitBase + id: ClothingHeadHelmetHardsuitShadowkinDarkswap + noSpawn: true + name: darkened softsuit helmet + components: + - type: Sprite + sprite: SimpleStation14/Clothing/Head/Hardsuits/darkened.rsi + - type: Clothing + sprite: SimpleStation14/Clothing/Head/Hardsuits/darkened.rsi + - type: PointLight + color: "#d6adff" + - type: Armor + modifiers: + coefficients: + Blunt: 1.4 + Slash: 1.3 + Piercing: 1.2 + Radiation: 0.4 + - type: ClothingSpeedModifier + walkModifier: 0.5 + sprintModifier: 0.5 + - type: ClothingGrantComponent + component: + - type: ShadowkinDarkSwapped + darken: false diff --git a/Resources/Prototypes/SimpleStation14/Entites/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/SimpleStation14/Entites/Clothing/OuterClothing/hardsuits.yml index 7f26eeb1f3..bc03bd6298 100644 --- a/Resources/Prototypes/SimpleStation14/Entites/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/SimpleStation14/Entites/Clothing/OuterClothing/hardsuits.yml @@ -26,3 +26,33 @@ damageCoefficient: 0.8 - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitHoP + +- type: entity + parent: ClothingOuterHardsuitBase + id: ClothingOuterHardsuitShadowkinDarkswap + name: darkened softsuit + description: Originally created while several research facilities were experimenting on Shadowkin, this hardsuit allows the wearer to jump the gap between the "normal" dimension and The Dark. + components: + - type: Sprite + sprite: SimpleStation14/Clothing/OuterClothing/Hardsuits/darkened.rsi + - type: Clothing + sprite: SimpleStation14/Clothing/OuterClothing/Hardsuits/darkened.rsi + - type: Armor + modifiers: + coefficients: + Blunt: 0.9 + Slash: 0.8 + Piercing: 0.9 + Radiation: 0.3 + - type: ClothingSpeedModifier + walkModifier: 0.9 + sprintModifier: 0.9 + - type: Item + size: 65 + - type: Tag + tags: + - FullBodyOuter + - Hardsuit + - type: ToggleableClothing + clothingPrototype: ClothingHeadHelmetHardsuitShadowkinDarkswap + actionId: ShadowkinDarkSwapHardsuitToggle diff --git a/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml index a6ee613ba2..b163e908b1 100644 --- a/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml @@ -9,7 +9,7 @@ - type: Hunger - type: Thirst - type: Icon - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: full - type: Body prototype: Shadowkin @@ -75,9 +75,63 @@ layer: - MobLayer - type: Sprite + netsync: false + noRot: true + drawdepth: Mobs scale: 0.85, 0.85 # Small + layers: + - map: [ "enum.HumanoidVisualLayers.Chest" ] + - map: [ "enum.HumanoidVisualLayers.Head" ] + - map: [ "enum.HumanoidVisualLayers.Snout" ] + - map: [ "enum.HumanoidVisualLayers.Eyes" ] + - map: [ "enum.HumanoidVisualLayers.RArm" ] + - map: [ "enum.HumanoidVisualLayers.LArm" ] + - map: [ "enum.HumanoidVisualLayers.RLeg" ] + - map: [ "enum.HumanoidVisualLayers.LLeg" ] + - shader: StencilClear + sprite: Mobs/Species/Human/parts.rsi + state: l_leg + - shader: StencilMask + map: [ "enum.HumanoidVisualLayers.StencilMask" ] + sprite: Mobs/Customization/masking_helpers.rsi + state: full + visible: false + - map: [ "enum.HumanoidVisualLayers.LFoot" ] + - map: [ "enum.HumanoidVisualLayers.RFoot" ] + - map: [ "socks" ] + - map: [ "underpants" ] + - map: [ "undershirt" ] + - map: [ "jumpsuit" ] + - map: [ "enum.HumanoidVisualLayers.LHand" ] + - map: [ "enum.HumanoidVisualLayers.RHand" ] + - map: [ "enum.HumanoidVisualLayers.Handcuffs" ] + color: "#ffffff" + sprite: Objects/Misc/handcuffs.rsi + state: body-overlay-2 + visible: false + - map: [ "id" ] + - map: [ "gloves" ] + - map: [ "shoes" ] + - map: [ "ears" ] + - map: [ "outerClothing" ] + - map: [ "eyes" ] + - map: [ "belt" ] + - map: [ "neck" ] + - map: [ "back" ] + - map: [ "enum.HumanoidVisualLayers.FacialHair" ] + - map: [ "enum.HumanoidVisualLayers.Hair" ] + - map: [ "enum.HumanoidVisualLayers.HeadSide" ] + - map: [ "enum.HumanoidVisualLayers.HeadTop" ] + - map: [ "mask" ] + - map: [ "head" ] + - map: [ "pocket1" ] + - map: [ "pocket2" ] + - map: [ "enum.HumanoidVisualLayers.Tail" ] + - map: [ "enum.HumanoidVisualLayers.Wings" ] - type: Eye - zoom: "0.85, 0.85" + zoom: 0.85, 0.85 + targetZoom: 0.85, 0.85 + maxZoom: 0.85, 0.85 - type: MeleeWeapon soundHit: collection: Punch @@ -135,7 +189,7 @@ components: - type: HumanoidAppearance species: Shadowkin - - type: Sprite # sprite again because we want different layer ordering + - type: Sprite netsync: false noRot: true drawdepth: Mobs diff --git a/Resources/Prototypes/SimpleStation14/Entites/Objects/Misc/handcuffs.yml b/Resources/Prototypes/SimpleStation14/Entites/Objects/Misc/handcuffs.yml new file mode 100644 index 0000000000..155ad20c84 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entites/Objects/Misc/handcuffs.yml @@ -0,0 +1,21 @@ +- type: entity + parent: Handcuffs + id: HandcuffsShadowkin + name: shadowkin restraints + description: One of the first creations after finding Shadowkin, these were used to contain the Shadowkin during research so they didn't teleport away. + components: + - type: Item + size: 20 + - type: Handcuff + cuffedRSI: SimpleStation14/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi + breakoutTime: 40 + damageOnResist: + types: + Blunt: 2 + cuffTime: 4 + uncuffTime: 5 + stunBonus: 4 + antiShadowkin: true + - type: Sprite + sprite: SimpleStation14/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi + state: icon diff --git a/Resources/Prototypes/SimpleStation14/Species/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Species/shadowkin.yml index 225eb532a1..09049f051a 100644 --- a/Resources/Prototypes/SimpleStation14/Species/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Species/shadowkin.yml @@ -71,89 +71,89 @@ - type: humanoidBaseSprite id: MobShadowkinHead baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: head_m - type: humanoidBaseSprite id: MobShadowkinHeadMale baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: head_m - type: humanoidBaseSprite id: MobShadowkinHeadFemale baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: head_f - type: humanoidBaseSprite id: MobShadowkinTorso baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: torso_m - type: humanoidBaseSprite id: MobShadowkinTorsoMale baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: torso_m - type: humanoidBaseSprite id: MobShadowkinTorsoFemale baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: torso_f - type: humanoidBaseSprite id: MobShadowkinLLeg baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: l_leg - type: humanoidBaseSprite id: MobShadowkinLHand baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: l_hand - type: humanoidBaseSprite id: MobShadowkinEyes baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: eyes - type: humanoidBaseSprite id: MobShadowkinLArm baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: l_arm - type: humanoidBaseSprite id: MobShadowkinLFoot baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: l_foot - type: humanoidBaseSprite id: MobShadowkinRLeg baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: r_leg - type: humanoidBaseSprite id: MobShadowkinRHand baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: r_hand - type: humanoidBaseSprite id: MobShadowkinRArm baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: r_arm - type: humanoidBaseSprite id: MobShadowkinRFoot baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi state: r_foot From ad29f044a0727eefec7134dbfcd390a651900a83 Mon Sep 17 00:00:00 2001 From: Finket Date: Tue, 7 Nov 2023 14:11:36 +0200 Subject: [PATCH 12/59] Revert shadowkin improvements as PR209 is a draft This reverts commit 145381aa8dc6163a9a6d706adf63965317f351ad. --- .../Systems/ShadowkinPowerSystem.Rest.cs | 6 +- .../Systems/ShadowkinPowerSystem.Teleport.cs | 25 ++-- .../Shadowkin/Systems/ShadowkinPowerSystem.cs | 15 +- .../Shadowkin/Systems/ShadowkinSightSystem.cs | 29 ---- .../Systems/ShadowkinSystem.Blackeye.cs | 38 +---- .../Traits/Events/CloningEvents.cs | 36 ----- .../Cuffs/Components/HandcuffComponent.cs | 6 - .../Components/ShadowkinComponent.cs | 6 +- .../ShadowkinDarkSwappedComponent.cs | 17 +-- .../Events/ShadowkinEvents.Blackeye.cs | 4 +- .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 12 +- Resources/Prototypes/Reagents/toxins.yml | 12 +- .../SimpleStation14/Actions/types.yml | 12 -- .../SimpleStation14/Body/Organs/shadowkin.yml | 138 ------------------ .../Chemistry/metabolizer_types.yml | 3 - .../Entites/Body/Parts/shadowkin.yml | 4 +- .../Entites/Body/Prototypes/shadowkin.yml | 16 +- .../Entites/Clothing/Eyes/glasses.yml | 14 -- .../Clothing/Head/hardsuit-helmets.yml | 27 ---- .../Clothing/OuterClothing/hardsuits.yml | 30 ---- .../Entites/Mobs/Player/shadowkin.yml | 60 +------- .../Entites/Objects/Misc/handcuffs.yml | 21 --- .../SimpleStation14/Species/shadowkin.yml | 30 ++-- 23 files changed, 73 insertions(+), 488 deletions(-) delete mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSightSystem.cs delete mode 100644 Content.Server/SimpleStation14/Traits/Events/CloningEvents.cs delete mode 100644 Resources/Prototypes/SimpleStation14/Actions/types.yml delete mode 100644 Resources/Prototypes/SimpleStation14/Body/Organs/shadowkin.yml delete mode 100644 Resources/Prototypes/SimpleStation14/Chemistry/metabolizer_types.yml delete mode 100644 Resources/Prototypes/SimpleStation14/Entites/Clothing/Eyes/glasses.yml delete mode 100644 Resources/Prototypes/SimpleStation14/Entites/Objects/Misc/handcuffs.yml diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index 20b1dba2ce..7c0fba7ff2 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -22,6 +22,7 @@ public override void Initialize() SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnShutdown); + SubscribeLocalEvent(Rest); } @@ -56,7 +57,8 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki // Sleepy time _entity.EnsureComponent(args.Performer); // No waking up normally (it would do nothing) - // _actions.RemoveAction(args.Performer, uid....Wake); // ?? + // Not sure what needs to be done here with the refactor + // _actions.RemoveAction(args.Performer, component.WakeAction); // ?? // _actions.RemoveAction(args.Performer, new InstantAction(_prototype.Index("Wake"))); _power.TryAddMultiplier(args.Performer, 1.5f); @@ -69,7 +71,7 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki // Wake up _entity.RemoveComponent(args.Performer); _entity.RemoveComponent(args.Performer); - _power.TryAddMultiplier(args.Performer, -2f); + _power.TryAddMultiplier(args.Performer, -1.5f); // Action cooldown args.Handled = true; } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index 053575866f..a5d260aae1 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -7,11 +7,9 @@ using Content.Shared.Damage.Systems; using Content.Shared.Pulling.Components; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; -using Content.Shared.Storage.Components; using Robust.Shared.Audio; using Robust.Shared.Prototypes; - namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; public sealed class ShadowkinTeleportSystem : EntitySystem @@ -36,29 +34,34 @@ public override void Initialize() SubscribeLocalEvent(Teleport); } + private void Startup(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentStartup args) { var componentActionShadowkinTeleport = component.ActionShadowkinTeleport; _actions.AddAction(uid, ref componentActionShadowkinTeleport, "ActionShadowkinTeleport"); + // _actions.AddAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport")), null); } private void Shutdown(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentShutdown args) { _actions.RemoveAction(uid, component.ActionShadowkinTeleport); + // _actions.RemoveAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport"))); } private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, ShadowkinTeleportEvent args) { - // Don't activate abilities if... - if (!_entity.TryGetComponent(args.Performer, out var comp) || // Not a Shadowkin - _entity.TryGetComponent(args.Performer, out var cuffs) && cuffs.AntiShadowkin || // Specially handcuffed - _entity.HasComponent(args.Performer)) // Inside an entity storage + // Need power to drain power + if (!_entity.TryGetComponent(args.Performer, out var comp)) + return; + + // Don't activate abilities if handcuffed + // TODO: Something like the Psionic Headcage to disable powers for Shadowkin + if (_entity.HasComponent(args.Performer)) return; var transform = Transform(args.Performer); - // Must be on the same map if (transform.MapID != args.Target.GetMapId(EntityManager)) return; @@ -67,12 +70,14 @@ private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, puller.Pulling != null && _entity.TryGetComponent(puller.Pulling, out pullable) && pullable.BeingPulled) - // Temporarily stop pulling to avoid not teleporting fully to the target + { + // Temporarily stop pulling to avoid not teleporting to the target _pulling.TryStopPull(pullable); + } // Teleport the performer to the target _transform.SetCoordinates(args.Performer, args.Target); - _transform.AttachToGridOrMap(args.Performer, transform); + transform.AttachToGridOrMap(); if (pullable != null && puller != null) { @@ -82,7 +87,7 @@ private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, // Teleport the pulled entity to the target // TODO: Relative position to the performer _transform.SetCoordinates(pullable.Owner, args.Target); - _transform.AttachToGridOrMap(args.Performer, transform); + pulledTransform.AttachToGridOrMap(); // Resume pulling // TODO: This does nothing? // This does things sometimes, but the client never knows diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs index f164138a1a..81ded05b26 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs @@ -196,25 +196,22 @@ public void SetPowerLevel(EntityUid uid, float newPowerLevel) /// /// Tries to blackeye a shadowkin. /// - public bool TryBlackeye(EntityUid uid, bool damage = true, bool checkPower = true) + public bool TryBlackeye(EntityUid uid) { - if (!_entity.HasComponent(uid)) - return false; - // Raise an attempted blackeye event - var ev = new ShadowkinBlackeyeAttemptEvent(uid, checkPower); + var ev = new ShadowkinBlackeyeAttemptEvent(uid); RaiseLocalEvent(ev); if (ev.Cancelled) return false; - Blackeye(uid, damage); + Blackeye(uid); return true; } /// /// Blackeyes a shadowkin. /// - public void Blackeye(EntityUid uid, bool damage = true) + public void Blackeye(EntityUid uid) { // Get shadowkin component if (!_entity.TryGetComponent(uid, out var component)) @@ -224,8 +221,8 @@ public void Blackeye(EntityUid uid, bool damage = true) } component.Blackeye = true; - RaiseNetworkEvent(new ShadowkinBlackeyeEvent(uid, damage)); - RaiseLocalEvent(new ShadowkinBlackeyeEvent(uid, damage)); + RaiseNetworkEvent(new ShadowkinBlackeyeEvent(uid)); + RaiseLocalEvent(new ShadowkinBlackeyeEvent(uid)); } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSightSystem.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSightSystem.cs deleted file mode 100644 index b1a56999f1..0000000000 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSightSystem.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Content.Server.SimpleStation14.Species.Shadowkin.Components; -using Content.Shared.Inventory.Events; - -namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; - -public sealed class ShadowkinSightSystem : EntitySystem -{ - [Dependency] private readonly ShadowkinDarkSwapSystem _darkSwap = default!; - - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnEquipped); - SubscribeLocalEvent(OnUnEquipped); - } - - - private void OnEquipped(EntityUid uid, ShadowkinSightComponent component, GotEquippedEvent args) - { - _darkSwap.SetVisibility(args.Equipee, true, false, false); - } - - private void OnUnEquipped(EntityUid uid, ShadowkinSightComponent component, GotUnequippedEvent args) - { - _darkSwap.SetVisibility(args.Equipee, false, false, false); - } -} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs index bc02c27b2d..908a77317c 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs @@ -1,6 +1,4 @@ -using Content.Server.Cloning; -using Content.Server.SimpleStation14.Species.Shadowkin.Components; -using Content.Server.SimpleStation14.Traits.Events; +using Content.Server.SimpleStation14.Species.Shadowkin.Components; using Content.Shared.SimpleStation14.Species.Shadowkin.Events; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; using Content.Shared.Damage.Systems; @@ -30,20 +28,14 @@ public override void Initialize() SubscribeLocalEvent(OnBlackeyeAttempt); SubscribeAllEvent(OnBlackeye); - - SubscribeLocalEvent(OnCloned); } private void OnBlackeyeAttempt(ShadowkinBlackeyeAttemptEvent ev) { - // Cancel if one of the following is true: - // - The entity is not a shadowkin - // - The entity is already blackeyed - // - The entity has more than 5 power and ev.CheckPower is true if (!_entity.TryGetComponent(ev.Uid, out var component) || component.Blackeye || - (ev.CheckPower && component.PowerLevel > ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Min] + 5)) + !(component.PowerLevel <= ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Min] + 5)) ev.Cancel(); } @@ -66,7 +58,7 @@ private void OnBlackeye(ShadowkinBlackeyeEvent ev) _entity.RemoveComponent(ev.Uid); _entity.RemoveComponent(ev.Uid); _entity.RemoveComponent(ev.Uid); - _entity.RemoveComponent(ev.Uid); + if (!ev.Damage) return; @@ -88,29 +80,9 @@ private void OnBlackeye(ShadowkinBlackeyeEvent ev) var minus = damageable.TotalDamage; - _damageable.TryChangeDamage( - ev.Uid, - new DamageSpecifier(_prototype.Index("Cellular"), + _damageable.TryChangeDamage(ev.Uid, new DamageSpecifier(_prototype.Index("Cellular"), Math.Max((double) (key.Value - minus - 5), 0)), true, - true, - null, - null - ); - - } - - - private void OnCloned(BeenClonedEvent ev) - { - // Don't give blackeyed Shadowkin their abilities back when they're cloned. - if (_entity.TryGetComponent(ev.OriginalMob, out var shadowkin) && - shadowkin.Blackeye) - _power.TryBlackeye(ev.Mob, false, false); - - // Blackeye the Shadowkin that come from the metempsychosis machine - if (_entity.HasComponent(ev.Cloner) && - _entity.HasComponent(ev.Mob)) - _power.TryBlackeye(ev.Mob, false, false); + true, null, null); } } diff --git a/Content.Server/SimpleStation14/Traits/Events/CloningEvents.cs b/Content.Server/SimpleStation14/Traits/Events/CloningEvents.cs deleted file mode 100644 index 4f744d3de3..0000000000 --- a/Content.Server/SimpleStation14/Traits/Events/CloningEvents.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Content.Shared.Preferences; - -namespace Content.Server.SimpleStation14.Traits.Events -{ - public sealed class BeingClonedEvent : CancellableEntityEventArgs - { - public HumanoidCharacterProfile Profile { get; set; } - public Mind.MindSystem Mind { get; set; } - public EntityUid Cloner { get; set; } - - public BeingClonedEvent(HumanoidCharacterProfile profile, Mind.MindSystem mind, EntityUid cloner) - { - Profile = profile; - Mind = mind; - Cloner = cloner; - } - } - - public sealed class BeenClonedEvent : EntityEventArgs - { - public HumanoidCharacterProfile Profile { get; set; } - public Mind.MindSystem Mind { get; set; } - public EntityUid Mob { get; set; } - public EntityUid OriginalMob { get; set; } - public EntityUid Cloner { get; set; } - - public BeenClonedEvent(HumanoidCharacterProfile profile, Mind.MindSystem mind, EntityUid mob, EntityUid originalMob, EntityUid cloner) - { - Profile = profile; - Mind = mind; - Mob = mob; - OriginalMob = originalMob; - Cloner = cloner; - } - } -} diff --git a/Content.Shared/Cuffs/Components/HandcuffComponent.cs b/Content.Shared/Cuffs/Components/HandcuffComponent.cs index 7f2006b804..b43bf18bf8 100644 --- a/Content.Shared/Cuffs/Components/HandcuffComponent.cs +++ b/Content.Shared/Cuffs/Components/HandcuffComponent.cs @@ -86,12 +86,6 @@ public sealed partial class HandcuffComponent : Component [DataField, ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier EndUncuffSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_takeoff_end.ogg"); - - - // Parkstation-Shadowkin Start - [DataField("antiShadowkin")] - public bool AntiShadowkin = false; - // Parkstation-Shadowkin End } /// diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs index 1ba47df844..2763d3ef2d 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs @@ -14,10 +14,10 @@ public sealed partial class ShadowkinComponent : Component public float MaxedPowerRoof = 0f; [ViewVariables(VVAccess.ReadWrite)] - public float MaxedPowerRateMin = 90f; + public float MaxedPowerRateMin = 45f; [ViewVariables(VVAccess.ReadWrite)] - public float MaxedPowerRateMax = 200f; + public float MaxedPowerRateMax = 150f; [ViewVariables(VVAccess.ReadWrite)] @@ -77,7 +77,7 @@ public float PowerLevel /// How much energy is gained per second. /// [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] - public float PowerLevelGain = 0.5f; + public float PowerLevelGain = 0.75f; /// /// Power gain multiplier diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs index c61e93808c..233236a8bd 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs @@ -6,43 +6,32 @@ namespace Content.Shared.SimpleStation14.Species.Shadowkin.Components; public sealed partial class ShadowkinDarkSwappedComponent : Component { /// - /// If the entity should be sent to the dark + /// If it should be sent to the dark /// - /// - /// This is also defined in the power component, this is if you want to use only some effects of the swap without a toggle - /// - [DataField("invisible"), ViewVariables(VVAccess.ReadWrite)] + [DataField("invisible")] public bool Invisible = true; /// /// If it should be pacified /// - /// [DataField("pacify")] public bool Pacify = true; /// - /// If the entity should dim nearby lights when swapped + /// If it should dim nearby lights /// - /// [DataField("darken"), ViewVariables(VVAccess.ReadWrite)] public bool Darken = true; /// /// How far to dim nearby lights /// - /// [DataField("range"), ViewVariables(VVAccess.ReadWrite)] public float DarkenRange = 5f; [ViewVariables(VVAccess.ReadOnly)] public List DarkenedLights = new(); - /// - /// How fast to refresh nearby light dimming in seconds - /// Without this performance would be significantly worse - /// - /// [ViewVariables(VVAccess.ReadWrite)] public float DarkenRate = 0.084f; // 1/12th of a second diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs index 01d3c49df0..353313b2b3 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs @@ -8,12 +8,10 @@ namespace Content.Shared.SimpleStation14.Species.Shadowkin.Events; public sealed class ShadowkinBlackeyeAttemptEvent : CancellableEntityEventArgs { public readonly EntityUid Uid; - public readonly bool CheckPower; - public ShadowkinBlackeyeAttemptEvent(EntityUid uid, bool checkPower = true) + public ShadowkinBlackeyeAttemptEvent(EntityUid uid) { Uid = uid; - CheckPower = checkPower; } } diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 123de10a13..9cb201bc97 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -1,5 +1,4 @@ using Content.Shared.Interaction.Events; -using Content.Shared.Item; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; using Content.Shared.Popups; using Robust.Shared.Timing; @@ -22,13 +21,14 @@ public override void Initialize() private void OnInteractionAttempt(EntityUid uid, ShadowkinDarkSwappedComponent component, InteractionAttemptEvent args) { - if (args.Target == null || - !_entity.HasComponent(args.Target) || - _entity.HasComponent(args.Target)) + if (args.Target == null || !_entity.TryGetComponent(args.Target, out var __) || + _entity.TryGetComponent(args.Target, out _)) return; args.Cancel(); - if (_gameTiming.InPrediction && _gameTiming.IsFirstTimePredicted) - _popup.PopupEntity(Loc.GetString("ethereal-pickup-fail"), args.Target.Value, uid); + if (_gameTiming.InPrediction) + return; + + _popup.PopupEntity(Loc.GetString("ethereal-pickup-fail"), args.Target.Value, uid); } } diff --git a/Resources/Prototypes/Reagents/toxins.yml b/Resources/Prototypes/Reagents/toxins.yml index f31d24e2d4..41e83a7c71 100644 --- a/Resources/Prototypes/Reagents/toxins.yml +++ b/Resources/Prototypes/Reagents/toxins.yml @@ -324,7 +324,7 @@ damage: groups: Toxin: 2 - - !type:ChemRemovePsionic #Nyano - Summary: removes psionics from the user at 20u. + - !type:ChemRemovePsionic #Nyano - Summary: removes psionics from the user at 20u. conditions: - !type:ReagentThreshold reagent: MindbreakerToxin @@ -469,14 +469,6 @@ type: Animal reagent: Protein amount: 0.5 - # Parkstation-Shadowkin Start - - !type:AdjustReagent - conditions: - - !type:OrganType - type: Shadowkin - reagent: Protein - amount: 0.5 - # Parkstation-Shadowkin End - type: reagent id: Allicin @@ -541,7 +533,7 @@ damage: types: Poison: 0.06 - + - type: reagent id: Lead diff --git a/Resources/Prototypes/SimpleStation14/Actions/types.yml b/Resources/Prototypes/SimpleStation14/Actions/types.yml deleted file mode 100644 index 0224af6abb..0000000000 --- a/Resources/Prototypes/SimpleStation14/Actions/types.yml +++ /dev/null @@ -1,12 +0,0 @@ - -- type: entity - id: ShadowkinDarkSwapHardsuitToggle - name: action-darkswap-hardsuit-name - components: - - type: InstantAction - useDelay: 15 - icon: - sprite: SimpleStation14/Clothing/Head/Hardsuits/darkened.rsi - state: icon - itemIconStyle: NoItem - event: !type:ToggleClothingEvent diff --git a/Resources/Prototypes/SimpleStation14/Body/Organs/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Body/Organs/shadowkin.yml deleted file mode 100644 index 6485660b13..0000000000 --- a/Resources/Prototypes/SimpleStation14/Body/Organs/shadowkin.yml +++ /dev/null @@ -1,138 +0,0 @@ -- type: entity - id: BaseShadowkinOrgan - parent: BaseItem - abstract: true - components: - - type: Organ - - type: Sprite - sprite: SimpleStation14/Mobs/Species/Shadowkin/organs.rsi - - type: DynamicPrice - price: 70 - - -- type: entity - id: OrganShadowkinBrain - parent: BaseShadowkinOrgan - name: brain - description: The source of incredible, unending intelligence. - components: - - type: Sprite - state: brain - - type: Organ - - type: Input - context: ghost - - type: InputMover - - type: MovementSpeedModifier # How the hell does it walk? - baseWalkSpeed: 0 - baseSprintSpeed: 0 - - type: Brain - -- type: entity - id: OrganShadowkinEyes - parent: BaseShadowkinOrgan - name: eyes - description: I see beyond anything you ever will! - components: - - type: Sprite - state: eyes - - type: Organ - -- type: entity - id: OrganShadowkinEars - parent: BaseShadowkinOrgan - name: ears - description: Hey, listen! - components: - - type: Sprite - state: ears - - type: Organ - -- type: entity - id: OrganShadowkinTongue - parent: BaseShadowkinOrgan - name: tongue - description: A fleshy muscle mostly used for lying. - components: - - type: Sprite - state: tongue - - type: Organ - - -- type: entity - id: OrganShadowkinAppendix - parent: BaseShadowkinOrgan - name: appendix - description: What does this do? - components: - - type: Sprite - state: appendix - - type: Organ - - -- type: entity - id: OrganShadowkinHeart - parent: BaseShadowkinOrgan - name: heart - description: I feel bad for the heartless bastard who lost this. - components: - - type: Sprite - state: heart - - type: Organ - - type: Metabolizer - maxReagents: 2 - metabolizerTypes: [Shadowkin] - groups: - - id: Medicine - - id: Poison - - id: Narcotic - -- type: entity - id: OrganShadowkinStomach - parent: BaseShadowkinOrgan - name: stomach - description: '"Yummy!", says the stomach, although you are unable to hear it.' - components: - - type: Sprite - state: stomach - - type: Organ - - type: SolutionContainerManager - solutions: - stomach: - maxVol: 40 - - type: Stomach - - type: Metabolizer - maxReagents: 3 - metabolizerTypes: [Shadowkin] - groups: - - id: Food - - id: Drink - -- type: entity - id: OrganShadowkinLiver - parent: BaseShadowkinOrgan - name: liver - description: "Live 'er? I hardly know 'er!" - components: - - type: Sprite - state: liver - - type: Organ - - type: Metabolizer - maxReagents: 1 - metabolizerTypes: [Shadowkin] - groups: - - id: Alcohol - rateModifier: 0.1 - -- type: entity - id: OrganShadowkinKidneys - parent: BaseShadowkinOrgan - name: kidneys - description: Give the kid their knees back, please, this is the third time this week. - components: - - type: Sprite - state: kidneys - - type: Organ - - type: Metabolizer - maxReagents: 5 - metabolizerTypes: [Shadowkin] - removeEmpty: true diff --git a/Resources/Prototypes/SimpleStation14/Chemistry/metabolizer_types.yml b/Resources/Prototypes/SimpleStation14/Chemistry/metabolizer_types.yml deleted file mode 100644 index 98c7b42b10..0000000000 --- a/Resources/Prototypes/SimpleStation14/Chemistry/metabolizer_types.yml +++ /dev/null @@ -1,3 +0,0 @@ -- type: metabolizerType - id: Shadowkin - name: shadowkin diff --git a/Resources/Prototypes/SimpleStation14/Entites/Body/Parts/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entites/Body/Parts/shadowkin.yml index 3981906b15..67762764e0 100644 --- a/Resources/Prototypes/SimpleStation14/Entites/Body/Parts/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Entites/Body/Parts/shadowkin.yml @@ -6,9 +6,9 @@ components: - type: Sprite netsync: false - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi - type: Icon - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi - type: Damageable damageContainer: Biological - type: BodyPart diff --git a/Resources/Prototypes/SimpleStation14/Entites/Body/Prototypes/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entites/Body/Prototypes/shadowkin.yml index 479cfe1c12..2cbe244983 100644 --- a/Resources/Prototypes/SimpleStation14/Entites/Body/Prototypes/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Entites/Body/Prototypes/shadowkin.yml @@ -8,8 +8,8 @@ connections: - torso organs: - brain: OrganShadowkinBrain - eyes: OrganShadowkinEyes + brain: OrganHumanBrain + eyes: OrganHumanEyes torso: part: TorsoShadowkin connections: @@ -17,12 +17,12 @@ - right arm - left leg - right leg - organs: - heart: OrganShadowkinHeart - # lungs: OrganHumanLungs - stomach: OrganShadowkinStomach - liver: OrganShadowkinLiver - kidneys: OrganShadowkinKidneys + organs: # placeholders + heart: OrganHumanHeart + # lungs: OrganLungs + stomach: OrganHumanStomach + liver: OrganHumanLiver + kidneys: OrganHumanKidneys right arm: part: RightArmShadowkin connections: diff --git a/Resources/Prototypes/SimpleStation14/Entites/Clothing/Eyes/glasses.yml b/Resources/Prototypes/SimpleStation14/Entites/Clothing/Eyes/glasses.yml deleted file mode 100644 index b7ad451de6..0000000000 --- a/Resources/Prototypes/SimpleStation14/Entites/Clothing/Eyes/glasses.yml +++ /dev/null @@ -1,14 +0,0 @@ -- type: entity - parent: ClothingEyesBase - id: ClothingEyesGlassesShadowkinDarkWindow - name: darkened goggles - description: An unusual pair of goggles developed during a time of inhumane experimentation involving Shadowkin. They are designed to allow the wearer to peer into The Dark. - components: - - type: Sprite - sprite: SimpleStation14/Clothing/Eyes/Glasses/darkened.rsi - - type: Clothing - sprite: SimpleStation14/Clothing/Eyes/Glasses/darkened.rsi - - type: EyeProtection - - type: DropOnSlip - chance: 20 - - type: ShadowkinSight diff --git a/Resources/Prototypes/SimpleStation14/Entites/Clothing/Head/hardsuit-helmets.yml b/Resources/Prototypes/SimpleStation14/Entites/Clothing/Head/hardsuit-helmets.yml index c9ea02f6f0..842796607b 100644 --- a/Resources/Prototypes/SimpleStation14/Entites/Clothing/Head/hardsuit-helmets.yml +++ b/Resources/Prototypes/SimpleStation14/Entites/Clothing/Head/hardsuit-helmets.yml @@ -39,30 +39,3 @@ Piercing: 0.95 Heat: 0.9 Radiation: 0.6 - -- type: entity - parent: ClothingHeadHardsuitBase - id: ClothingHeadHelmetHardsuitShadowkinDarkswap - noSpawn: true - name: darkened softsuit helmet - components: - - type: Sprite - sprite: SimpleStation14/Clothing/Head/Hardsuits/darkened.rsi - - type: Clothing - sprite: SimpleStation14/Clothing/Head/Hardsuits/darkened.rsi - - type: PointLight - color: "#d6adff" - - type: Armor - modifiers: - coefficients: - Blunt: 1.4 - Slash: 1.3 - Piercing: 1.2 - Radiation: 0.4 - - type: ClothingSpeedModifier - walkModifier: 0.5 - sprintModifier: 0.5 - - type: ClothingGrantComponent - component: - - type: ShadowkinDarkSwapped - darken: false diff --git a/Resources/Prototypes/SimpleStation14/Entites/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/SimpleStation14/Entites/Clothing/OuterClothing/hardsuits.yml index bc03bd6298..7f26eeb1f3 100644 --- a/Resources/Prototypes/SimpleStation14/Entites/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/SimpleStation14/Entites/Clothing/OuterClothing/hardsuits.yml @@ -26,33 +26,3 @@ damageCoefficient: 0.8 - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitHoP - -- type: entity - parent: ClothingOuterHardsuitBase - id: ClothingOuterHardsuitShadowkinDarkswap - name: darkened softsuit - description: Originally created while several research facilities were experimenting on Shadowkin, this hardsuit allows the wearer to jump the gap between the "normal" dimension and The Dark. - components: - - type: Sprite - sprite: SimpleStation14/Clothing/OuterClothing/Hardsuits/darkened.rsi - - type: Clothing - sprite: SimpleStation14/Clothing/OuterClothing/Hardsuits/darkened.rsi - - type: Armor - modifiers: - coefficients: - Blunt: 0.9 - Slash: 0.8 - Piercing: 0.9 - Radiation: 0.3 - - type: ClothingSpeedModifier - walkModifier: 0.9 - sprintModifier: 0.9 - - type: Item - size: 65 - - type: Tag - tags: - - FullBodyOuter - - Hardsuit - - type: ToggleableClothing - clothingPrototype: ClothingHeadHelmetHardsuitShadowkinDarkswap - actionId: ShadowkinDarkSwapHardsuitToggle diff --git a/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml index b163e908b1..a6ee613ba2 100644 --- a/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml @@ -9,7 +9,7 @@ - type: Hunger - type: Thirst - type: Icon - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: full - type: Body prototype: Shadowkin @@ -75,63 +75,9 @@ layer: - MobLayer - type: Sprite - netsync: false - noRot: true - drawdepth: Mobs scale: 0.85, 0.85 # Small - layers: - - map: [ "enum.HumanoidVisualLayers.Chest" ] - - map: [ "enum.HumanoidVisualLayers.Head" ] - - map: [ "enum.HumanoidVisualLayers.Snout" ] - - map: [ "enum.HumanoidVisualLayers.Eyes" ] - - map: [ "enum.HumanoidVisualLayers.RArm" ] - - map: [ "enum.HumanoidVisualLayers.LArm" ] - - map: [ "enum.HumanoidVisualLayers.RLeg" ] - - map: [ "enum.HumanoidVisualLayers.LLeg" ] - - shader: StencilClear - sprite: Mobs/Species/Human/parts.rsi - state: l_leg - - shader: StencilMask - map: [ "enum.HumanoidVisualLayers.StencilMask" ] - sprite: Mobs/Customization/masking_helpers.rsi - state: full - visible: false - - map: [ "enum.HumanoidVisualLayers.LFoot" ] - - map: [ "enum.HumanoidVisualLayers.RFoot" ] - - map: [ "socks" ] - - map: [ "underpants" ] - - map: [ "undershirt" ] - - map: [ "jumpsuit" ] - - map: [ "enum.HumanoidVisualLayers.LHand" ] - - map: [ "enum.HumanoidVisualLayers.RHand" ] - - map: [ "enum.HumanoidVisualLayers.Handcuffs" ] - color: "#ffffff" - sprite: Objects/Misc/handcuffs.rsi - state: body-overlay-2 - visible: false - - map: [ "id" ] - - map: [ "gloves" ] - - map: [ "shoes" ] - - map: [ "ears" ] - - map: [ "outerClothing" ] - - map: [ "eyes" ] - - map: [ "belt" ] - - map: [ "neck" ] - - map: [ "back" ] - - map: [ "enum.HumanoidVisualLayers.FacialHair" ] - - map: [ "enum.HumanoidVisualLayers.Hair" ] - - map: [ "enum.HumanoidVisualLayers.HeadSide" ] - - map: [ "enum.HumanoidVisualLayers.HeadTop" ] - - map: [ "mask" ] - - map: [ "head" ] - - map: [ "pocket1" ] - - map: [ "pocket2" ] - - map: [ "enum.HumanoidVisualLayers.Tail" ] - - map: [ "enum.HumanoidVisualLayers.Wings" ] - type: Eye - zoom: 0.85, 0.85 - targetZoom: 0.85, 0.85 - maxZoom: 0.85, 0.85 + zoom: "0.85, 0.85" - type: MeleeWeapon soundHit: collection: Punch @@ -189,7 +135,7 @@ components: - type: HumanoidAppearance species: Shadowkin - - type: Sprite + - type: Sprite # sprite again because we want different layer ordering netsync: false noRot: true drawdepth: Mobs diff --git a/Resources/Prototypes/SimpleStation14/Entites/Objects/Misc/handcuffs.yml b/Resources/Prototypes/SimpleStation14/Entites/Objects/Misc/handcuffs.yml deleted file mode 100644 index 155ad20c84..0000000000 --- a/Resources/Prototypes/SimpleStation14/Entites/Objects/Misc/handcuffs.yml +++ /dev/null @@ -1,21 +0,0 @@ -- type: entity - parent: Handcuffs - id: HandcuffsShadowkin - name: shadowkin restraints - description: One of the first creations after finding Shadowkin, these were used to contain the Shadowkin during research so they didn't teleport away. - components: - - type: Item - size: 20 - - type: Handcuff - cuffedRSI: SimpleStation14/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi - breakoutTime: 40 - damageOnResist: - types: - Blunt: 2 - cuffTime: 4 - uncuffTime: 5 - stunBonus: 4 - antiShadowkin: true - - type: Sprite - sprite: SimpleStation14/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi - state: icon diff --git a/Resources/Prototypes/SimpleStation14/Species/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Species/shadowkin.yml index 09049f051a..225eb532a1 100644 --- a/Resources/Prototypes/SimpleStation14/Species/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Species/shadowkin.yml @@ -71,89 +71,89 @@ - type: humanoidBaseSprite id: MobShadowkinHead baseSprite: - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: head_m - type: humanoidBaseSprite id: MobShadowkinHeadMale baseSprite: - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: head_m - type: humanoidBaseSprite id: MobShadowkinHeadFemale baseSprite: - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: head_f - type: humanoidBaseSprite id: MobShadowkinTorso baseSprite: - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: torso_m - type: humanoidBaseSprite id: MobShadowkinTorsoMale baseSprite: - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: torso_m - type: humanoidBaseSprite id: MobShadowkinTorsoFemale baseSprite: - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: torso_f - type: humanoidBaseSprite id: MobShadowkinLLeg baseSprite: - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: l_leg - type: humanoidBaseSprite id: MobShadowkinLHand baseSprite: - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: l_hand - type: humanoidBaseSprite id: MobShadowkinEyes baseSprite: - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: eyes - type: humanoidBaseSprite id: MobShadowkinLArm baseSprite: - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: l_arm - type: humanoidBaseSprite id: MobShadowkinLFoot baseSprite: - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: l_foot - type: humanoidBaseSprite id: MobShadowkinRLeg baseSprite: - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: r_leg - type: humanoidBaseSprite id: MobShadowkinRHand baseSprite: - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: r_hand - type: humanoidBaseSprite id: MobShadowkinRArm baseSprite: - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: r_arm - type: humanoidBaseSprite id: MobShadowkinRFoot baseSprite: - sprite: SimpleStation14/Mobs/Species/Shadowkin/parts.rsi + sprite: SimpleStation14/Mobs/Species/shadowkin.rsi state: r_foot From 3da460f75d2a253b5aa19e1640555bfbfa2f3583 Mon Sep 17 00:00:00 2001 From: Finket Date: Tue, 7 Nov 2023 14:12:16 +0200 Subject: [PATCH 13/59] Revert "Add some shadowkin improvements progress" This reverts commit a9c37e6b7a56928620a2c06e2088dbb0f0abc75f. --- .../ShadowkinDarkSwapPowerComponent.cs | 46 +--- .../Components/ShadowkinSightComponent.cs | 7 - .../Events/ShadowkinEvents.Powers.cs | 2 +- .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 218 ++++-------------- .../Systems/ShadowkinPowerSystem.Rest.cs | 6 +- 5 files changed, 55 insertions(+), 224 deletions(-) delete mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinSightComponent.cs diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs index 245d7d5a98..6ede3ec25f 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs @@ -1,51 +1,7 @@ -using Content.Server.NPC.Components; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; - -namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; +namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; [RegisterComponent] public sealed partial class ShadowkinDarkSwapPowerComponent : Component { public EntityUid? ActionShadowkinDarkSwap { get; set; } - - /// - /// Factions temporarily deleted from the entity while swapped - /// - public List SuppressedFactions = new(); - /// - /// Factions temporarily added to the entity while swapped - /// - [DataField("factions", customTypeSerializer: typeof(PrototypeIdListSerializer))] - public List AddedFactions = new() { "ShadowkinDarkFriendly" }; - - /// - /// If the entity should be sent to the dark - /// - [DataField("invisible")] - public bool Invisible = true; - - /// - /// If it should be pacified - /// - [DataField("pacify")] - public bool Pacify = true; - - /// - /// If the entity should dim nearby lights when swapped - /// - [DataField("darken"), ViewVariables(VVAccess.ReadWrite)] - public bool Darken = true; - - /// - /// How far to dim nearby lights - /// - [DataField("range"), ViewVariables(VVAccess.ReadWrite)] - public float DarkenRange = 5f; - - /// - /// How fast to refresh nearby light dimming in seconds - /// Without this performance would be significantly worse - /// - [ViewVariables(VVAccess.ReadWrite)] - public float DarkenRate = 0.084f; // 1/12th of a second } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinSightComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinSightComponent.cs deleted file mode 100644 index f66ea62e9b..0000000000 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinSightComponent.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; - -[RegisterComponent] -public sealed class ShadowkinSightComponent : Component -{ - -} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs index aced4dc646..5008e8992f 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs @@ -76,7 +76,7 @@ public sealed partial class ShadowkinDarkSwapEvent : InstantActionEvent, ISpeakS public sealed class ShadowkinDarkSwapAttemptEvent : CancellableEntityEventArgs { - public EntityUid Performer; + EntityUid Performer; public ShadowkinDarkSwapAttemptEvent(EntityUid performer) { diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 8a9e490b4e..8e6fcee028 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -1,11 +1,8 @@ -using System.Linq; -using Content.Server.Ghost.Components; +using Content.Server.Ghost.Components; using Content.Server.Magic; using Content.Server.SimpleStation14.Species.Shadowkin.Components; using Content.Server.SimpleStation14.Species.Shadowkin.Events; using Content.Server.Visible; -using Content.Server.NPC.Systems; -using Content.Server.NPC.Components; using Content.Shared.Actions; using Content.Shared.CombatMode.Pacification; using Content.Shared.Cuffs.Components; @@ -19,7 +16,6 @@ using Robust.Shared.Audio; using Robust.Shared.Prototypes; - namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; public sealed class ShadowkinDarkSwapSystem : EntitySystem @@ -34,7 +30,6 @@ public sealed class ShadowkinDarkSwapSystem : EntitySystem [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly MagicSystem _magic = default!; - [Dependency] private readonly NpcFactionSystem _factions = default!; public override void Initialize() { @@ -49,10 +44,12 @@ public override void Initialize() SubscribeLocalEvent(OnInvisShutdown); } + private void Startup(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentStartup args) { var componentActionShadowkinDarkSwap = component.ActionShadowkinDarkSwap; _actions.AddAction(uid, ref componentActionShadowkinDarkSwap, "ActionShadowkinDarkSwap"); + // _actions.AddAction(uid, "ActionShadowkinDarkSwap"); } private void Shutdown(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentShutdown args) @@ -67,239 +64,124 @@ private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, if (!_entity.HasComponent(args.Performer)) return; - // Don't activate abilities if specially handcuffed - if (_entity.TryGetComponent(args.Performer, out var cuffs) && cuffs.AntiShadowkin) + // Don't activate abilities if handcuffed + // TODO: Something like the Psionic Headcage to disable powers for Shadowkin + if (_entity.HasComponent(args.Performer)) return; + var hasComp = _entity.HasComponent(args.Performer); + SetDarkened( args.Performer, - !_entity.HasComponent(args.Performer), + !hasComp, + !hasComp, + true, + args.StaminaCostOn, + args.PowerCostOn, args.SoundOn, args.VolumeOn, + args.StaminaCostOff, + args.PowerCostOff, args.SoundOff, args.VolumeOff, - args, - args.StaminaCostOn, - args.PowerCostOn, - args.StaminaCostOff, - args.PowerCostOff + args ); - _magic.Speak(args, false); } - - /// - /// Handles the effects of darkswapping - /// - /// The entity being modified - /// Is the entity swapping in to or out of The Dark? - /// Sound for the darkswapping - /// Volume for the on sound - /// Sound for the un swapping - /// Volume for the off sound - /// Stamina cost for darkswapping - /// Power cost for darkswapping - /// Stamina cost for un swapping - /// Power cost for un swapping - /// If from an event, handle it public void SetDarkened( EntityUid performer, bool addComp, - SoundSpecifier? soundOn, - float? volumeOn, - SoundSpecifier? soundOff, - float? volumeOff, - ShadowkinDarkSwapEvent? args, - float staminaCostOn = 0, - float powerCostOn = 0, - float staminaCostOff = 0, - float powerCostOff = 0 + bool invisible, + bool darken, + float staminaCostOn, + float powerCostOn, + SoundSpecifier soundOn, + float volumeOn, + float staminaCostOff, + float powerCostOff, + SoundSpecifier soundOff, + float volumeOff, + ShadowkinDarkSwapEvent? args ) { - // Ask other systems if we can DarkSwap var ev = new ShadowkinDarkSwapAttemptEvent(performer); RaiseLocalEvent(ev); if (ev.Cancelled) return; - - // We require the power component to DarkSwap - if (!_entity.TryGetComponent(performer, out var power)) - return; - - if (addComp) // Into The Dark + if (addComp) { - // Add the DarkSwapped component and set variables to match the power component var comp = _entity.EnsureComponent(performer); - comp.Invisible = power.Invisible; - comp.Pacify = power.Pacify; - comp.Darken = power.Darken; - comp.DarkenRange = power.DarkenRange; - comp.DarkenRate = power.DarkenRate; - - // Tell other systems we've DarkSwapped + comp.Invisible = invisible; + comp.Darken = darken; RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, true)); - - // Play a sound if we have one - if (soundOn != null) - _audio.PlayPvs(soundOn, performer, AudioParams.Default.WithVolume(volumeOn ?? 5f)); - - // Drain power and stamina if we have a cost + _audio.PlayPvs(soundOn, performer, AudioParams.Default.WithVolume(volumeOn)); _power.TryAddPowerLevel(performer, -powerCostOn); _stamina.TakeStaminaDamage(performer, staminaCostOn); } - else // Out of The Dark + else { - // Remove the DarkSwapped component, the rest is handled in the shutdown event _entity.RemoveComponent(performer); - - // Tell other systems we've un DarkSwapped RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, false)); - - // Play a sound if we have one - if (soundOff != null) - _audio.PlayPvs(soundOff, performer, AudioParams.Default.WithVolume(volumeOff ?? 5f)); - - // Drain power and stamina if we have a cost + _audio.PlayPvs(soundOff, performer, AudioParams.Default.WithVolume(volumeOff)); _power.TryAddPowerLevel(performer, -powerCostOff); _stamina.TakeStaminaDamage(performer, staminaCostOff); } - - // If we have an event, mark it as handled if (args != null) args.Handled = true; } - private void OnInvisStartup(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentStartup args) { - if (component.Pacify) - EnsureComp(uid); - + EnsureComp(uid); if (component.Invisible) - { - SetVisibility(uid, true, true, true); - SuppressFactions(uid, true); - } + SetCanSeeInvisibility(uid, true); } private void OnInvisShutdown(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentShutdown args) { RemComp(uid); - if (component.Invisible) - { - SetVisibility(uid, false, false, false); - SuppressFactions(uid, false); - } - - // Prevent more updates while we're cleaning up + SetCanSeeInvisibility(uid, false); component.Darken = false; - - // In case more updates occur for some reason, create a copy of the list to prevent error foreach (var light in component.DarkenedLights.ToArray()) { if (!_entity.TryGetComponent(light, out var pointLight) || !_entity.TryGetComponent(light, out var shadowkinLight)) continue; - _darken.ResetLight(pointLight, shadowkinLight); } - - // Clear the original array component.DarkenedLights.Clear(); } // Commented out eye and ghost stuff until ported - /// - /// Makes the specified entity able to see Shadowkin invisibility. - /// - /// Entity to modify - /// Whether the entity can see invisibility - /// Should the entity be moved to another visibility layer? - /// (Only gets considered if set is true) Adds stealth to the entity - public void SetVisibility(EntityUid uid, bool set, bool invisibility, bool stealth) + public void SetCanSeeInvisibility(EntityUid uid, bool set) { - // We require the visibility component for this to work var visibility = _entity.EnsureComponent(uid); - - if (set) // Invisible + if (set) { - // Allow the entity to see DarkSwapped entities /*if (_entity.TryGetComponent(uid, out EyeComponent? eye)) - eye.VisibilityMask |= (uint) VisibilityFlags.DarkSwapInvisibility;*/ - - // Make other entities unable to see the entity unless also DarkSwapped - if (invisibility) { - _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); - _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); - } + eye.VisibilityMask |= (uint) VisibilityFlags.DarkSwapInvisibility; + }*/ + _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); + _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); - - // If not a ghost, add a stealth shader to the entity - if (!_entity.TryGetComponent(uid, out _) && stealth) + if (!_entity.TryGetComponent(uid, out var _)) _stealth.SetVisibility(uid, 0.8f, _entity.EnsureComponent(uid)); } - else // Visible + else { - // Remove the ability to see DarkSwapped entities /*if (_entity.TryGetComponent(uid, out EyeComponent? eye)) - eye.VisibilityMask &= ~(uint) VisibilityFlags.DarkSwapInvisibility;*/ - - // Make other entities able to see the entity again - if (invisibility) { - _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); - _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); - } + // eye.VisibilityMask &= ~(uint) VisibilityFlags.DarkSwapInvisibility; + }*/ + _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); + _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); - - // Remove the stealth shader from the entity - if (!_entity.TryGetComponent(uid, out _)) - _stealth.SetEnabled(uid, false); - } - } - - /// - /// Remove existing factions on the entity and move them to the power component to add back when removed from The Dark - /// - /// Entity to modify factions for - /// Add or remove the factions - public void SuppressFactions(EntityUid uid, bool set) - { - // We require the power component to keep track of the factions - if (!_entity.TryGetComponent(uid, out var component)) - return; - - if (set) - { - if (!_entity.TryGetComponent(uid, out var factions)) - return; - - // Copy the suppressed factions to the power component - component.SuppressedFactions = factions.Factions.ToList(); - - // Remove the factions from the entity - foreach (var faction in factions.Factions) - _factions.RemoveFaction(uid, faction); - - // Add status factions for The Dark to the entity - foreach (var faction in component.AddedFactions) - _factions.AddFaction(uid, faction); - } - else - { - // Remove the status factions from the entity - foreach (var faction in component.AddedFactions) - _factions.RemoveFaction(uid, faction); - - // Add the factions back to the entity - foreach (var faction in component.SuppressedFactions) - _factions.AddFaction(uid, faction); - - component.SuppressedFactions.Clear(); + if (!_entity.TryGetComponent(uid, out var _)) + _entity.RemoveComponent(uid); } } } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index 7c0fba7ff2..edc26f42eb 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -8,7 +8,6 @@ namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; - public sealed class ShadowkinRestSystem : EntitySystem { [Dependency] private readonly IEntityManager _entity = default!; @@ -26,6 +25,7 @@ public override void Initialize() SubscribeLocalEvent(Rest); } + private void OnStartup(EntityUid uid, ShadowkinRestPowerComponent component, ComponentStartup args) { var componentActionShadowkinRest = component.ActionShadowkinRest; @@ -44,8 +44,8 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki return; // Rest is a funny ability, keep it :) - // // Don't activate abilities if specially handcuffed - // if (_entity.TryGetComponent(args.Performer, out var cuffs) && cuffs.AntiShadowkin) + // // Don't activate abilities if handcuffed + // if (_entity.HasComponent(args.Performer)) // return; // Now doing what you weren't before From d276fb21ead4b11539c94950a8b252ceb270b728 Mon Sep 17 00:00:00 2001 From: Finket Date: Tue, 7 Nov 2023 14:25:14 +0200 Subject: [PATCH 14/59] Port over PR218 changes --- .../ShadowkinDarkSwapPowerComponent.cs | 16 ++- .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 113 +++++++++++++++--- .../Prototypes/SimpleStation14/factions.yml | 9 ++ 3 files changed, 119 insertions(+), 19 deletions(-) create mode 100644 Resources/Prototypes/SimpleStation14/factions.yml diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs index 6ede3ec25f..8dd132d791 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs @@ -1,7 +1,21 @@ -namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; +using Content.Server.NPC.Components; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; + +namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; [RegisterComponent] public sealed partial class ShadowkinDarkSwapPowerComponent : Component { + /// + /// Factions temporarily deleted from the entity while swapped + /// + public List SuppressedFactions = new(); + + /// + /// Factions temporarily added to the entity while swapped + /// + [DataField("factions", customTypeSerializer: typeof(PrototypeIdListSerializer))] + public List AddedFactions = new() { "ShadowkinDarkFriendly" }; + public EntityUid? ActionShadowkinDarkSwap { get; set; } } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 8e6fcee028..0f38d6b8e6 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -1,5 +1,7 @@ -using Content.Server.Ghost.Components; +using System.Linq; using Content.Server.Magic; +using Content.Server.NPC.Components; +using Content.Server.NPC.Systems; using Content.Server.SimpleStation14.Species.Shadowkin.Components; using Content.Server.SimpleStation14.Species.Shadowkin.Events; using Content.Server.Visible; @@ -16,6 +18,7 @@ using Robust.Shared.Audio; using Robust.Shared.Prototypes; + namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; public sealed class ShadowkinDarkSwapSystem : EntitySystem @@ -30,6 +33,7 @@ public sealed class ShadowkinDarkSwapSystem : EntitySystem [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly MagicSystem _magic = default!; + [Dependency] private readonly NpcFactionSystem _factions = default!; public override void Initialize() { @@ -44,12 +48,10 @@ public override void Initialize() SubscribeLocalEvent(OnInvisShutdown); } - private void Startup(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentStartup args) { var componentActionShadowkinDarkSwap = component.ActionShadowkinDarkSwap; _actions.AddAction(uid, ref componentActionShadowkinDarkSwap, "ActionShadowkinDarkSwap"); - // _actions.AddAction(uid, "ActionShadowkinDarkSwap"); } private void Shutdown(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentShutdown args) @@ -76,6 +78,7 @@ private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, args.Performer, !hasComp, !hasComp, + !hasComp, true, args.StaminaCostOn, args.PowerCostOn, @@ -87,13 +90,16 @@ private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, args.VolumeOff, args ); + _magic.Speak(args, false); } + public void SetDarkened( EntityUid performer, bool addComp, bool invisible, + bool pacify, bool darken, float staminaCostOn, float powerCostOn, @@ -110,13 +116,18 @@ public void SetDarkened( RaiseLocalEvent(ev); if (ev.Cancelled) return; + if (addComp) { var comp = _entity.EnsureComponent(performer); comp.Invisible = invisible; + comp.Pacify = pacify; comp.Darken = darken; + RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, true)); + _audio.PlayPvs(soundOn, performer, AudioParams.Default.WithVolume(volumeOn)); + _power.TryAddPowerLevel(performer, -powerCostOn); _stamina.TakeStaminaDamage(performer, staminaCostOn); } @@ -124,64 +135,130 @@ public void SetDarkened( { _entity.RemoveComponent(performer); RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, false)); + _audio.PlayPvs(soundOff, performer, AudioParams.Default.WithVolume(volumeOff)); + _power.TryAddPowerLevel(performer, -powerCostOff); _stamina.TakeStaminaDamage(performer, staminaCostOff); } + if (args != null) args.Handled = true; } + private void OnInvisStartup(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentStartup args) { - EnsureComp(uid); + if (component.Pacify) + EnsureComp(uid); + if (component.Invisible) - SetCanSeeInvisibility(uid, true); + { + SetVisibility(uid, true); + SuppressFactions(uid, true); + } } private void OnInvisShutdown(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentShutdown args) { RemComp(uid); + if (component.Invisible) - SetCanSeeInvisibility(uid, false); + { + SetVisibility(uid, false); + SuppressFactions(uid, false); + } + component.Darken = false; + foreach (var light in component.DarkenedLights.ToArray()) { if (!_entity.TryGetComponent(light, out var pointLight) || !_entity.TryGetComponent(light, out var shadowkinLight)) continue; + _darken.ResetLight(pointLight, shadowkinLight); } + component.DarkenedLights.Clear(); } // Commented out eye and ghost stuff until ported - public void SetCanSeeInvisibility(EntityUid uid, bool set) + public void SetVisibility(EntityUid uid, bool set) { - var visibility = _entity.EnsureComponent(uid); - if (set) + // We require the visibility component for this to work + var visibility = EnsureComp(uid); + + if (set) // Invisible { + // Allow the entity to see DarkSwapped entities /*if (_entity.TryGetComponent(uid, out EyeComponent? eye)) - { - eye.VisibilityMask |= (uint) VisibilityFlags.DarkSwapInvisibility; - }*/ + eye.VisibilityMask |= (uint) VisibilityFlags.DarkSwapInvisibility;*/ + + // Make other entities unable to see the entity unless also DarkSwapped _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); + + // If not a ghost, add a stealth shader to the entity if (!_entity.TryGetComponent(uid, out var _)) _stealth.SetVisibility(uid, 0.8f, _entity.EnsureComponent(uid)); } - else + else // Visible { + // Remove the ability to see DarkSwapped entities /*if (_entity.TryGetComponent(uid, out EyeComponent? eye)) - { - // eye.VisibilityMask &= ~(uint) VisibilityFlags.DarkSwapInvisibility; - }*/ + eye.VisibilityMask &= ~(uint) VisibilityFlags.DarkSwapInvisibility;*/ + + // Make other entities able to see the entity again _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); - if (!_entity.TryGetComponent(uid, out var _)) - _entity.RemoveComponent(uid); + + // Remove the stealth shader from the entity + if (!_entity.TryGetComponent(uid, out _)) + _stealth.SetVisibility(uid, 1f, _entity.EnsureComponent(uid)); + } + } + + /// + /// Remove existing factions on the entity and move them to the power component to add back when removed from The Dark + /// + /// Entity to modify factions for + /// Add or remove the factions + public void SuppressFactions(EntityUid uid, bool set) + { + // We require the power component to keep track of the factions + if (!_entity.TryGetComponent(uid, out var component)) + return; + + if (set) + { + if (!_entity.TryGetComponent(uid, out var factions)) + return; + + // Copy the suppressed factions to the power component + component.SuppressedFactions = factions.Factions.ToList(); + + // Remove the factions from the entity + foreach (var faction in factions.Factions) + _factions.RemoveFaction(uid, faction); + + // Add status factions for The Dark to the entity + foreach (var faction in component.AddedFactions) + _factions.AddFaction(uid, faction); + } + else + { + // Remove the status factions from the entity + foreach (var faction in component.AddedFactions) + _factions.RemoveFaction(uid, faction); + + // Add the factions back to the entity + foreach (var faction in component.SuppressedFactions) + _factions.AddFaction(uid, faction); + + component.SuppressedFactions.Clear(); } } } diff --git a/Resources/Prototypes/SimpleStation14/factions.yml b/Resources/Prototypes/SimpleStation14/factions.yml new file mode 100644 index 0000000000..340a8ed8da --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/factions.yml @@ -0,0 +1,9 @@ +- type: npcFaction + id: ShadowkinDarkHostile + hostile: + - ShadowkinDarkFriendly + +- type: npcFaction + id: ShadowkinDarkFriendly + hostile: + - ShadowkinDarkHostile From 1f13d93c697632dd8e50d45a7b2f7cc6339f73d7 Mon Sep 17 00:00:00 2001 From: Finket Date: Wed, 8 Nov 2023 10:52:55 +0200 Subject: [PATCH 15/59] Fix directory name entities typo --- .../{Entites => Entities}/Body/Parts/shadowkin.yml | 0 .../{Entites => Entities}/Body/Prototypes/shadowkin.yml | 0 .../{Entites => Entities}/Clothing/Hands/gloves.yml | 0 .../{Entites => Entities}/Clothing/Head/hardsuit-helmets.yml | 0 .../{Entites => Entities}/Clothing/OuterClothing/hardsuits.yml | 0 .../{Entites => Entities}/Mobs/Customization/tails.yml | 0 .../{Entites => Entities}/Mobs/Player/shadowkin.yml | 0 .../SimpleStation14/{Entites => Entities}/Objects/Fun/toys.yml | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename Resources/Prototypes/SimpleStation14/{Entites => Entities}/Body/Parts/shadowkin.yml (100%) rename Resources/Prototypes/SimpleStation14/{Entites => Entities}/Body/Prototypes/shadowkin.yml (100%) rename Resources/Prototypes/SimpleStation14/{Entites => Entities}/Clothing/Hands/gloves.yml (100%) rename Resources/Prototypes/SimpleStation14/{Entites => Entities}/Clothing/Head/hardsuit-helmets.yml (100%) rename Resources/Prototypes/SimpleStation14/{Entites => Entities}/Clothing/OuterClothing/hardsuits.yml (100%) rename Resources/Prototypes/SimpleStation14/{Entites => Entities}/Mobs/Customization/tails.yml (100%) rename Resources/Prototypes/SimpleStation14/{Entites => Entities}/Mobs/Player/shadowkin.yml (100%) rename Resources/Prototypes/SimpleStation14/{Entites => Entities}/Objects/Fun/toys.yml (100%) diff --git a/Resources/Prototypes/SimpleStation14/Entites/Body/Parts/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entities/Body/Parts/shadowkin.yml similarity index 100% rename from Resources/Prototypes/SimpleStation14/Entites/Body/Parts/shadowkin.yml rename to Resources/Prototypes/SimpleStation14/Entities/Body/Parts/shadowkin.yml diff --git a/Resources/Prototypes/SimpleStation14/Entites/Body/Prototypes/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entities/Body/Prototypes/shadowkin.yml similarity index 100% rename from Resources/Prototypes/SimpleStation14/Entites/Body/Prototypes/shadowkin.yml rename to Resources/Prototypes/SimpleStation14/Entities/Body/Prototypes/shadowkin.yml diff --git a/Resources/Prototypes/SimpleStation14/Entites/Clothing/Hands/gloves.yml b/Resources/Prototypes/SimpleStation14/Entities/Clothing/Hands/gloves.yml similarity index 100% rename from Resources/Prototypes/SimpleStation14/Entites/Clothing/Hands/gloves.yml rename to Resources/Prototypes/SimpleStation14/Entities/Clothing/Hands/gloves.yml diff --git a/Resources/Prototypes/SimpleStation14/Entites/Clothing/Head/hardsuit-helmets.yml b/Resources/Prototypes/SimpleStation14/Entities/Clothing/Head/hardsuit-helmets.yml similarity index 100% rename from Resources/Prototypes/SimpleStation14/Entites/Clothing/Head/hardsuit-helmets.yml rename to Resources/Prototypes/SimpleStation14/Entities/Clothing/Head/hardsuit-helmets.yml diff --git a/Resources/Prototypes/SimpleStation14/Entites/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/SimpleStation14/Entities/Clothing/OuterClothing/hardsuits.yml similarity index 100% rename from Resources/Prototypes/SimpleStation14/Entites/Clothing/OuterClothing/hardsuits.yml rename to Resources/Prototypes/SimpleStation14/Entities/Clothing/OuterClothing/hardsuits.yml diff --git a/Resources/Prototypes/SimpleStation14/Entites/Mobs/Customization/tails.yml b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/tails.yml similarity index 100% rename from Resources/Prototypes/SimpleStation14/Entites/Mobs/Customization/tails.yml rename to Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/tails.yml diff --git a/Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml similarity index 100% rename from Resources/Prototypes/SimpleStation14/Entites/Mobs/Player/shadowkin.yml rename to Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml diff --git a/Resources/Prototypes/SimpleStation14/Entites/Objects/Fun/toys.yml b/Resources/Prototypes/SimpleStation14/Entities/Objects/Fun/toys.yml similarity index 100% rename from Resources/Prototypes/SimpleStation14/Entites/Objects/Fun/toys.yml rename to Resources/Prototypes/SimpleStation14/Entities/Objects/Fun/toys.yml From 937204e4d140a05cd79360a6b60102919ad652a0 Mon Sep 17 00:00:00 2001 From: Finket Date: Wed, 8 Nov 2023 10:57:26 +0200 Subject: [PATCH 16/59] Add shadowkin ears yml --- .../Entities/Mobs/Customization/ears.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/ears.yml diff --git a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/ears.yml b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/ears.yml new file mode 100644 index 0000000000..5f8680fdb3 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/ears.yml @@ -0,0 +1,19 @@ +- type: marking + id: EarsShadowkin + bodyPart: HeadTop + markingCategory: HeadTop + speciesRestriction: [Shadowkin] + sprites: + - sprite: SimpleStation14/Mobs/Customization/ears.rsi + state: shadowkin + +- type: marking + id: EarsShadowkinStriped + bodyPart: HeadTop + markingCategory: HeadTop + speciesRestriction: [Shadowkin] + sprites: + - sprite: SimpleStation14/Mobs/Customization/ears.rsi + state: shadowkin + - sprite: SimpleStation14/Mobs/Customization/ears.rsi + state: shadowkin_stripes From 8301021ded383099eeff158d6b6fbdd99acc9c03 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Wed, 8 Nov 2023 15:01:23 -0800 Subject: [PATCH 17/59] reformatting and codebase change markers I didn't want to do a review... --- Content.Client/Chat/Managers/ChatManager.cs | 2 +- .../Chat/ShadowkinChatUpdateSystem.cs | 2 + .../Overlays/Shaders/ColorTintOverlay.cs | 2 + .../Overlays/Shaders/EtherealOverlay.cs | 2 + .../IgnoreHumanoidWithComponentOverlay.cs | 11 ++ .../ShadowkinPowerSystem.DarkSwapped.cs | 1 + .../Systems/ShadowkinSystem.Blackeye.cs | 3 + .../Shadowkin/Systems/ShadowkinSystem.Tint.cs | 10 +- .../Systems/Chat/ChatUIController.cs | 13 +- .../Chat/Controls/ChannelFilterPopup.xaml.cs | 2 +- .../Chat/Controls/ChannelSelectorButton.cs | 2 +- .../Chat/Controls/ChannelSelectorPopup.cs | 2 +- Content.Server/Chat/Systems/ChatSystem.cs | 6 +- Content.Server/Magic/Events/ISpeakSpell.cs | 10 - Content.Server/Magic/MagicSystem.cs | 4 +- .../SimpleStation14/Chat/ESayCommand.cs | 56 +++--- .../Chat/SimpleStationChatSystem.cs | 2 +- .../ShadowkinDarkSwapPowerComponent.cs | 2 +- .../Events/ShadowkinEvents.Powers.cs | 4 +- .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 2 + .../Systems/ShadowkinPowerSystem.Darken.cs | 1 + .../Systems/ShadowkinPowerSystem.Rest.cs | 1 + .../Systems/ShadowkinPowerSystem.Teleport.cs | 3 +- .../Shadowkin/Systems/ShadowkinPowerSystem.cs | 4 +- .../Systems/ShadowkinSystem.Blackeye.Trait.cs | 1 + .../Systems/ShadowkinSystem.Blackeye.cs | 10 +- .../Shadowkin/Systems/ShadowkinSystem.cs | 1 + .../Components/ShadowkinAccentComponent.cs | 5 +- .../EntitySystems/ShadowkinAccentSystem.cs | 2 + Content.Server/Visible/VisibilityFlags.cs | 13 -- Content.Shared/Alert/AlertCategory.cs | 2 +- Content.Shared/Alert/AlertType.cs | 2 +- Content.Shared/Chat/ChatChannel.cs | 5 +- Content.Shared/Chat/ChatSelectChannel.cs | 2 +- Content.Shared/Chat/SharedChatSystem.cs | 2 +- Content.Shared/Eye/VisibilityFlags.cs | 2 + Content.Shared/Humanoid/NamingSystem.cs | 2 +- .../Components/ShadowkinComponent.cs | 1 + .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 2 + .../en-US/chat/managers/chat-manager.ftl | 2 + Resources/Locale/en-US/chat/ui/chat-box.ftl | 2 + .../Prototypes/Alerts/shadowkin.ftl | 2 +- .../Prototypes/Guidebook/species.ftl | 1 - Resources/Locale/en-US/species/namepreset.ftl | 3 +- Resources/Prototypes/Alerts/alerts.yml | 2 +- .../Prototypes/Catalog/Fills/Crates/fun.yml | 4 +- .../Entities/Objects/Devices/pda.yml | 2 +- .../Entities/Objects/Misc/fluff_lights.yml | 2 +- .../Entities/Objects/Tools/flashlights.yml | 2 +- .../Structures/Lighting/base_lighting.yml | 2 +- .../Entities/Body/Parts/shadowkin.yml | 62 +++--- .../Entities/Mobs/Customization/tails.yml | 16 ++ .../SimpleStationSpecies/Shadowkin.Lore.txt | 178 ------------------ .../SimpleStationSpecies/Shadowkin.xml | 34 ---- 54 files changed, 171 insertions(+), 342 deletions(-) delete mode 100644 Content.Server/Magic/Events/ISpeakSpell.cs delete mode 100644 Content.Server/Visible/VisibilityFlags.cs delete mode 100644 Resources/Locale/en-US/simplestation14/Prototypes/Guidebook/species.ftl delete mode 100644 Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.Lore.txt delete mode 100644 Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.xml diff --git a/Content.Client/Chat/Managers/ChatManager.cs b/Content.Client/Chat/Managers/ChatManager.cs index 44ef7dc0ae..b5d07551cc 100644 --- a/Content.Client/Chat/Managers/ChatManager.cs +++ b/Content.Client/Chat/Managers/ChatManager.cs @@ -72,7 +72,7 @@ public void SendMessage(string text, ChatSelectChannel channel) _consoleHost.ExecuteCommand($"tsay \"{CommandParsing.Escape(str)}\""); break; - // Parkstation - Shadowkin chat + // Parkstation-EmpathyChat case ChatSelectChannel.Empathy: _consoleHost.ExecuteCommand($"esay \"{CommandParsing.Escape(str)}\""); break; diff --git a/Content.Client/SimpleStation14/Chat/ShadowkinChatUpdateSystem.cs b/Content.Client/SimpleStation14/Chat/ShadowkinChatUpdateSystem.cs index 549e3aff27..99c87e7f3d 100644 --- a/Content.Client/SimpleStation14/Chat/ShadowkinChatUpdateSystem.cs +++ b/Content.Client/SimpleStation14/Chat/ShadowkinChatUpdateSystem.cs @@ -9,6 +9,7 @@ public sealed class ShadowkinChatUpdateSystem : EntitySystem [Dependency] private readonly IChatManager _chatManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; + public override void Initialize() { base.Initialize(); @@ -17,6 +18,7 @@ public override void Initialize() SubscribeLocalEvent(OnRemove); } + public EmpathyChatComponent? Player => CompOrNull(_playerManager.LocalPlayer?.ControlledEntity); public bool IsShadowkin => Player != null; diff --git a/Content.Client/SimpleStation14/Overlays/Shaders/ColorTintOverlay.cs b/Content.Client/SimpleStation14/Overlays/Shaders/ColorTintOverlay.cs index 1dd4e9bfe6..f4d7ac4366 100644 --- a/Content.Client/SimpleStation14/Overlays/Shaders/ColorTintOverlay.cs +++ b/Content.Client/SimpleStation14/Overlays/Shaders/ColorTintOverlay.cs @@ -31,6 +31,7 @@ public sealed class ColorTintOverlay : Overlay /// public Component? Comp = null; + public ColorTintOverlay() { IoCManager.InjectDependencies(this); @@ -38,6 +39,7 @@ public ColorTintOverlay() _shader = _prototype.Index("ColorTint").InstanceUnique(); } + protected override void Draw(in OverlayDrawArgs args) { if (ScreenTexture == null || diff --git a/Content.Client/SimpleStation14/Overlays/Shaders/EtherealOverlay.cs b/Content.Client/SimpleStation14/Overlays/Shaders/EtherealOverlay.cs index d1aa0a7152..d87bb06d4a 100644 --- a/Content.Client/SimpleStation14/Overlays/Shaders/EtherealOverlay.cs +++ b/Content.Client/SimpleStation14/Overlays/Shaders/EtherealOverlay.cs @@ -14,12 +14,14 @@ public sealed class EtherealOverlay : Overlay public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowFOV; private readonly ShaderInstance _shader; + public EtherealOverlay() { IoCManager.InjectDependencies(this); _shader = _prototype.Index("Ethereal").InstanceUnique(); } + protected override void Draw(in OverlayDrawArgs args) { if (ScreenTexture == null) return; diff --git a/Content.Client/SimpleStation14/Overlays/Shaders/IgnoreHumanoidWithComponentOverlay.cs b/Content.Client/SimpleStation14/Overlays/Shaders/IgnoreHumanoidWithComponentOverlay.cs index c0cc302d66..10a92b0d71 100644 --- a/Content.Client/SimpleStation14/Overlays/Shaders/IgnoreHumanoidWithComponentOverlay.cs +++ b/Content.Client/SimpleStation14/Overlays/Shaders/IgnoreHumanoidWithComponentOverlay.cs @@ -5,6 +5,9 @@ namespace Content.Client.SimpleStation14.Overlays.Shaders; +/// +/// Not really an overlay to be honest +/// public sealed class IgnoreHumanoidWithComponentOverlay : Overlay { [Dependency] private readonly IPlayerManager _playerManager = default!; @@ -14,11 +17,13 @@ public sealed class IgnoreHumanoidWithComponentOverlay : Overlay public List AllowAnywayComponents = new(); private readonly List _nonVisibleList = new(); + public IgnoreHumanoidWithComponentOverlay() { IoCManager.InjectDependencies(this); } + protected override void Draw(in OverlayDrawArgs args) { var spriteQuery = _entityManager.GetEntityQuery(); @@ -72,6 +77,9 @@ protected override void Draw(in OverlayDrawArgs args) } + /// + /// Resets the overlay, making all entities visible again + /// public void Reset() { foreach (var humanoid in _nonVisibleList.ToArray()) @@ -83,6 +91,9 @@ public void Reset() } } + /// + /// Resets the overlay for a specific entity, making it visible again + /// public void Reset(EntityUid entity) { if (!_nonVisibleList.Contains(entity)) diff --git a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs index f527c4e6d1..0c038c0ba1 100644 --- a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs +++ b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs @@ -16,6 +16,7 @@ public sealed class ShadowkinDarkSwappedSystem : EntitySystem private IgnoreHumanoidWithComponentOverlay _ignoreOverlay = default!; private EtherealOverlay _etherealOverlay = default!; + public override void Initialize() { base.Initialize(); diff --git a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs index 4c33438806..9af16385e5 100644 --- a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs +++ b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs @@ -9,6 +9,7 @@ public sealed class ShadowkinBlackeyeSystem : EntitySystem { [Dependency] private readonly IEntityManager _entity = default!; + public override void Initialize() { base.Initialize(); @@ -18,6 +19,7 @@ public override void Initialize() SubscribeLocalEvent(OnInit); } + private void OnBlackeye(ShadowkinBlackeyeEvent ev) { SetColor(ev.Uid, Color.Black); @@ -34,6 +36,7 @@ private void OnInit(EntityUid uid, ShadowkinComponent component, ComponentInit a // Blackeye if none of the RGB values are greater than 75 if (layer.Color.R * 255 < 75 && layer.Color.G * 255 < 75 && layer.Color.B * 255 < 75) { + // TODO Need to move this to server somehow, can't trust the client with this RaiseNetworkEvent(new ShadowkinBlackeyeEvent(uid, false)); } } diff --git a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs index 482203dde6..1e97a501c6 100644 --- a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs +++ b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs @@ -17,6 +17,7 @@ public sealed class ShadowkinTintSystem : EntitySystem private ColorTintOverlay _tintOverlay = default!; + public override void Initialize() { base.Initialize(); @@ -35,6 +36,7 @@ public override void Initialize() SubscribeLocalEvent(OnRoundRestart); } + private void OnStartup(EntityUid uid, ShadowkinComponent component, ComponentStartup args) { if (_player.LocalPlayer?.ControlledEntity != uid) @@ -82,13 +84,13 @@ public override void Update(float frameTime) // Eye color comp.TintColor = new Vector3(layer.Color.R, layer.Color.G, layer.Color.B); - // 1/3 = 0.333... // intensity = min + (power / max) - // intensity = intensity / 0.333 + // intensity = intensity / 3 // intensity = clamp intensity min, max const float min = 0.45f; const float max = 0.75f; - comp.TintIntensity = Math.Clamp(min + (comp.PowerLevel / comp.PowerLevelMax) * 0.333f, min, max); + // TODO This math doesn't match the comments, figure out which is correct + comp.TintIntensity = Math.Clamp(min + (comp.PowerLevel / comp.PowerLevelMax) / 3, min, max); UpdateShader(comp.TintColor, comp.TintIntensity); } @@ -97,9 +99,7 @@ public override void Update(float frameTime) private void UpdateShader(Vector3? color, float? intensity) { while (_overlay.HasOverlay()) - { _overlay.RemoveOverlay(_tintOverlay); - } if (color != null) _tintOverlay.TintColor = color; diff --git a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs index d8fc24243b..11045a67b1 100644 --- a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs +++ b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs @@ -57,7 +57,7 @@ public sealed class ChatUIController : UIController [UISystemDependency] private readonly TypingIndicatorSystem? _typingIndicator = default; [UISystemDependency] private readonly ChatSystem? _chatSys = default; [UISystemDependency] private readonly PsionicChatUpdateSystem? _psionic = default!; //Nyano - Summary: makes the psionic chat available. - [UISystemDependency] private readonly ShadowkinChatUpdateSystem? _shadowkin = default!; + [UISystemDependency] private readonly ShadowkinChatUpdateSystem? _shadowkin = default!; // Parkstation-EmpathyChat private ISawmill _sawmill = default!; @@ -74,8 +74,7 @@ public sealed class ChatUIController : UIController {SharedChatSystem.RadioCommonPrefix, ChatSelectChannel.Radio}, {SharedChatSystem.DeadPrefix, ChatSelectChannel.Dead}, {SharedChatSystem.TelepathicPrefix, ChatSelectChannel.Telepathic}, //Nyano - Summary: adds the telepathic prefix =. - {SharedChatSystem.TelepathicPrefix, ChatSelectChannel.Telepathic}, - {SharedChatSystem.EmpathyPrefix, ChatSelectChannel.Empathy} + {SharedChatSystem.EmpathyPrefix, ChatSelectChannel.Empathy}, // Parkstation-EmpathyChat }; public static readonly Dictionary ChannelPrefixes = new() @@ -90,8 +89,7 @@ public sealed class ChatUIController : UIController {ChatSelectChannel.Radio, SharedChatSystem.RadioCommonPrefix}, {ChatSelectChannel.Dead, SharedChatSystem.DeadPrefix}, {ChatSelectChannel.Telepathic, SharedChatSystem.TelepathicPrefix }, //Nyano - Summary: associates telepathic with =. - {ChatSelectChannel.Telepathic, SharedChatSystem.TelepathicPrefix}, - {ChatSelectChannel.Empathy, SharedChatSystem.EmpathyPrefix} + {ChatSelectChannel.Empathy, SharedChatSystem.EmpathyPrefix}, // Parkstation-EmpathyChat }; /// @@ -536,7 +534,7 @@ private void UpdateChannelPermissions() FilterableChannels |= ChatChannel.AdminChat; CanSendChannels |= ChatSelectChannel.Admin; FilterableChannels |= ChatChannel.Telepathic; //Nyano - Summary: makes admins able to see psionic chat. - FilterableChannels |= ChatChannel.Empathy; + FilterableChannels |= ChatChannel.Empathy; // Parkstation-EmpathyChat } // Nyano - Summary: - Begin modified code block to add telepathic as a channel for a psionic user. @@ -547,12 +545,13 @@ private void UpdateChannelPermissions() } // /Nyano - End modified code block - // Shadowkin + // Parkstation-EmpathyChat-Start if (_shadowkin != null && _shadowkin.IsShadowkin) { FilterableChannels |= ChatChannel.Empathy; CanSendChannels |= ChatSelectChannel.Empathy; } + // Parkstation-EmpathyChat-End SelectableChannels = CanSendChannels; diff --git a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelFilterPopup.xaml.cs b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelFilterPopup.xaml.cs index 23114f8cfa..36c4c5b946 100644 --- a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelFilterPopup.xaml.cs +++ b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelFilterPopup.xaml.cs @@ -17,7 +17,7 @@ public sealed partial class ChannelFilterPopup : Popup ChatChannel.Emotes, ChatChannel.Radio, ChatChannel.Telepathic, //Nyano - Summary: adds telepathic chat to where it belongs in order in the chat. - ChatChannel.Empathy, + ChatChannel.Empathy, // Parkstation-EmpathyChat ChatChannel.LOOC, ChatChannel.OOC, ChatChannel.Dead, diff --git a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorButton.cs b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorButton.cs index 66f6c62ecc..7f1ee391e9 100644 --- a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorButton.cs +++ b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorButton.cs @@ -83,7 +83,7 @@ public Color ChannelSelectColor(ChatSelectChannel channel) ChatSelectChannel.Dead => Color.MediumPurple, ChatSelectChannel.Admin => Color.HotPink, ChatSelectChannel.Telepathic => Color.PaleVioletRed, //Nyano - Summary: determines the color for the chat. - ChatSelectChannel.Empathy => Color.PaleVioletRed, + ChatSelectChannel.Empathy => Color.PaleVioletRed, // Parkstation-EmpathyChat _ => Color.DarkGray }; } diff --git a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorPopup.cs b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorPopup.cs index 9999a50360..cb8d5e45ab 100644 --- a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorPopup.cs +++ b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorPopup.cs @@ -14,7 +14,7 @@ public sealed class ChannelSelectorPopup : Popup ChatSelectChannel.Emotes, ChatSelectChannel.Radio, ChatSelectChannel.Telepathic, //Nyano - Summary: determines the order in which telepathic shows. - ChatSelectChannel.Empathy, + ChatSelectChannel.Empathy, // Parkstation-EmpathyChat ChatSelectChannel.LOOC, ChatSelectChannel.OOC, ChatSelectChannel.Dead, diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 7d41098adc..52f441a597 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -55,7 +55,7 @@ public sealed partial class ChatSystem : SharedChatSystem [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!; [Dependency] private readonly StationSystem _stationSystem = default!; [Dependency] private readonly MobStateSystem _mobStateSystem = default!; - [Dependency] private readonly SimpleStationChatSystem _simpleStationChatSystem = default!; + [Dependency] private readonly SimpleStationChatSystem _simpleStationChatSystem = default!; // Parkstation-EmpathyChat [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly ReplacementAccentSystem _wordreplacement = default!; @@ -254,7 +254,7 @@ public void TrySendInGameICMessage( case InGameICChatType.Telepathic: _nyanoChatSystem.SendTelepathicChat(source, message, range == ChatTransmitRange.HideChat); break; - // Shadowkin + // Parkstation-EmpathyChat case InGameICChatType.Empathy: _simpleStationChatSystem.SendEmpathyChat(source, message, range == ChatTransmitRange.HideChat); break; @@ -908,7 +908,7 @@ public enum InGameICChatType : byte Emote, Whisper, Telepathic, //Nyano - Summary: adds telepathic as a type of message users can receive. - Empathy // Shadowkin + Empathy, // Parkstation-EmpathyChat } /// diff --git a/Content.Server/Magic/Events/ISpeakSpell.cs b/Content.Server/Magic/Events/ISpeakSpell.cs deleted file mode 100644 index d7c7dbe250..0000000000 --- a/Content.Server/Magic/Events/ISpeakSpell.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Content.Server.Magic.Events; - -public interface ISpeakSpell // The speak n spell interface -{ - /// - /// Localized string spoken by the caster when casting this spell. - /// - public string? Speech { get; } -} - diff --git a/Content.Server/Magic/MagicSystem.cs b/Content.Server/Magic/MagicSystem.cs index b0e643799a..bbbed36817 100644 --- a/Content.Server/Magic/MagicSystem.cs +++ b/Content.Server/Magic/MagicSystem.cs @@ -396,12 +396,12 @@ private void SpawnSpellHelper(List entityEntries, EntityCoordi #endregion - public void Speak(BaseActionEvent args, bool showInChat = true) + public void Speak(BaseActionEvent args, bool showInChat = true) // Parkstation-Shadowkin // Make Spell Speak function public and add showInChat { if (args is not ISpeakSpell speak || string.IsNullOrWhiteSpace(speak.Speech)) return; _chat.TrySendInGameICMessage(args.Performer, Loc.GetString(speak.Speech), - InGameICChatType.Speak, !showInChat); + InGameICChatType.Speak, !showInChat); // Parkstation-Shadowkin } } diff --git a/Content.Server/SimpleStation14/Chat/ESayCommand.cs b/Content.Server/SimpleStation14/Chat/ESayCommand.cs index e3f81360a8..d8c3eb3fcc 100644 --- a/Content.Server/SimpleStation14/Chat/ESayCommand.cs +++ b/Content.Server/SimpleStation14/Chat/ESayCommand.cs @@ -4,40 +4,42 @@ using Robust.Shared.Console; using Robust.Shared.Enums; -namespace Content.Server.SimpleStation14.Chat.Commands +namespace Content.Server.SimpleStation14.Chat.Commands; + +[AnyCommand] +/// +/// Chat commands are stupid +/// +internal sealed class ESayCommand : IConsoleCommand { - [AnyCommand] - internal sealed class ESayCommand : IConsoleCommand - { - public string Command => "esay"; - public string Description => "Send chat messages to Shadowkin."; - public string Help => $"{Command} "; + public string Command => "esay"; + public string Description => "Send chat messages to Shadowkin."; + public string Help => $"{Command} "; - public void Execute(IConsoleShell shell, string argStr, string[] args) + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (shell.Player is not IPlayerSession player) { - if (shell.Player is not IPlayerSession player) - { - shell.WriteError("This command cannot be run from the server."); - return; - } + shell.WriteError("This command cannot be run from the server."); + return; + } - if (player.Status != SessionStatus.InGame) - return; + if (player.Status != SessionStatus.InGame) + return; - if (player.AttachedEntity is not {} playerEntity) - { - shell.WriteError("You don't have an entity!"); - return; - } + if (player.AttachedEntity is not {} playerEntity) + { + shell.WriteError("You don't have an entity!"); + return; + } - if (args.Length < 1) - return; + if (args.Length < 1) + return; - var message = string.Join(" ", args).Trim(); - if (string.IsNullOrEmpty(message)) - return; + var message = string.Join(" ", args).Trim(); + if (string.IsNullOrEmpty(message)) + return; - EntitySystem.Get().TrySendInGameICMessage(playerEntity, message, InGameICChatType.Empathy, false, false, shell, player, checkRadioPrefix: false); - } + EntitySystem.Get().TrySendInGameICMessage(playerEntity, message, InGameICChatType.Empathy, false, false, shell, player, checkRadioPrefix: false); } } diff --git a/Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs b/Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs index e02dd47229..327c695cfd 100644 --- a/Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs +++ b/Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs @@ -16,7 +16,7 @@ namespace Content.Server.SimpleStation14.Chat { /// - /// Extensions for parkstation's chat stuff + /// qExtensions for Parkstation's chat stuff /// public sealed class SimpleStationChatSystem : EntitySystem { diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs index 8dd132d791..00789ab7d1 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs @@ -7,7 +7,7 @@ namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; public sealed partial class ShadowkinDarkSwapPowerComponent : Component { /// - /// Factions temporarily deleted from the entity while swapped + /// Factions temporarily removed from the entity while swapped /// public List SuppressedFactions = new(); diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs index 5008e8992f..ea28c1915d 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs @@ -1,5 +1,5 @@ -using Content.Server.Magic.Events; -using Content.Shared.Actions; +using Content.Shared.Actions; +using Content.Shared.Magic; using Robust.Shared.Audio; namespace Content.Server.SimpleStation14.Species.Shadowkin.Events; diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 0f38d6b8e6..e9488978a1 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -35,6 +35,7 @@ public sealed class ShadowkinDarkSwapSystem : EntitySystem [Dependency] private readonly MagicSystem _magic = default!; [Dependency] private readonly NpcFactionSystem _factions = default!; + public override void Initialize() { base.Initialize(); @@ -48,6 +49,7 @@ public override void Initialize() SubscribeLocalEvent(OnInvisShutdown); } + private void Startup(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentStartup args) { var componentActionShadowkinDarkSwap = component.ActionShadowkinDarkSwap; diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs index c7e2769e34..bb5bc01c9d 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs @@ -33,6 +33,7 @@ public override void Update(float frameTime) { base.Update(frameTime); + // TODO Use a cached query, and update it on ShadowkinDarkSwappedComponent.Initialize var shadowkins = _entity.EntityQueryEnumerator(); while (shadowkins.MoveNext(out var uid, out var shadowkin)) diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index edc26f42eb..6f57ab90bc 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -15,6 +15,7 @@ public sealed class ShadowkinRestSystem : EntitySystem [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly ShadowkinPowerSystem _power = default!; + public override void Initialize() { base.Initialize(); diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index a5d260aae1..593d451dda 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -24,6 +24,7 @@ public sealed class ShadowkinTeleportSystem : EntitySystem [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly MagicSystem _magic = default!; + public override void Initialize() { base.Initialize(); @@ -90,7 +91,7 @@ private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, pulledTransform.AttachToGridOrMap(); // Resume pulling - // TODO: This does nothing? // This does things sometimes, but the client never knows + // TODO: This does nothing? // This does things sometimes, but the client never knows // This does nothing?? _pulling.TryStartPull(puller, pullable); } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs index 81ded05b26..3613b7d1d5 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs @@ -12,9 +12,10 @@ public sealed class ShadowkinPowerSystem : EntitySystem private readonly Dictionary _powerDictionary; + public ShadowkinPowerSystem() { - var Locale = IoCManager.Resolve(); // Whyyyy + var Locale = IoCManager.Resolve(); // Whyyyy // Dependencies aren't resolved yet, must resolve manually to get locale for the _powerDictionary _powerDictionary = new Dictionary { @@ -27,6 +28,7 @@ public ShadowkinPowerSystem() }; } + /// The current power level. /// The name of the power level. public string GetLevelName(float powerLevel) diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.Trait.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.Trait.cs index a98bf50134..dff2aece9b 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.Trait.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.Trait.cs @@ -12,6 +12,7 @@ public override void Initialize() SubscribeLocalEvent(OnStartup); } + private void OnStartup(EntityUid uid, ShadowkinBlackeyeTraitComponent _, ComponentStartup args) { RaiseLocalEvent(uid, new ShadowkinBlackeyeEvent(uid, false)); diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs index 908a77317c..79de5f4d7a 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs @@ -22,6 +22,7 @@ public sealed class ShadowkinBlackeyeSystem : EntitySystem [Dependency] private readonly MobThresholdSystem _mobThreshold = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; + public override void Initialize() { base.Initialize(); @@ -80,9 +81,12 @@ private void OnBlackeye(ShadowkinBlackeyeEvent ev) var minus = damageable.TotalDamage; - _damageable.TryChangeDamage(ev.Uid, new DamageSpecifier(_prototype.Index("Cellular"), + _damageable.TryChangeDamage(ev.Uid, + new DamageSpecifier(_prototype.Index("Cellular"), Math.Max((double) (key.Value - minus - 5), 0)), - true, - true, null, null); + true, + true, + null, + null); } } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs index 288b03c1e7..7963331c1b 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs @@ -24,6 +24,7 @@ public sealed class ShadowkinSystem : EntitySystem [Dependency] private readonly SharedInteractionSystem _interaction = default!; [Dependency] private readonly MobStateSystem _mobState = default!; + public override void Initialize() { base.Initialize(); diff --git a/Content.Server/SimpleStation14/Speech/Components/ShadowkinAccentComponent.cs b/Content.Server/SimpleStation14/Speech/Components/ShadowkinAccentComponent.cs index 5e613d5c76..ccc96654ea 100644 --- a/Content.Server/SimpleStation14/Speech/Components/ShadowkinAccentComponent.cs +++ b/Content.Server/SimpleStation14/Speech/Components/ShadowkinAccentComponent.cs @@ -1,4 +1,7 @@ namespace Content.Server.Speech.Components; [RegisterComponent] -public sealed partial class ShadowkinAccentComponent : Component {} +public sealed partial class ShadowkinAccentComponent : Component +{ + +} diff --git a/Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs b/Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs index 97c036f679..f8d44253cc 100644 --- a/Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs +++ b/Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs @@ -13,11 +13,13 @@ public sealed class ShadowkinAccentSystem : EntitySystem private static readonly Regex aRegex = new(@"[behknqtwy]", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex rRegex = new(@"[cfiloruxz]", RegexOptions.Compiled | RegexOptions.IgnoreCase); + public override void Initialize() { SubscribeLocalEvent(OnAccent); } + public string Accentuate(string message) { message = message.Trim(); diff --git a/Content.Server/Visible/VisibilityFlags.cs b/Content.Server/Visible/VisibilityFlags.cs deleted file mode 100644 index 9cf76bcc47..0000000000 --- a/Content.Server/Visible/VisibilityFlags.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Content.Server.Visible -{ - [Flags] - public enum VisibilityFlags : uint - { - None = 0, - Normal = 1 << 0, - Ghost = 1 << 1, - PsionicInvisibility = 1 << 2, - DarkSwapInvisibility = 1 << 3, - AIEye = 1 << 4, - } -} diff --git a/Content.Shared/Alert/AlertCategory.cs b/Content.Shared/Alert/AlertCategory.cs index bba215c474..af7ded643d 100644 --- a/Content.Shared/Alert/AlertCategory.cs +++ b/Content.Shared/Alert/AlertCategory.cs @@ -12,7 +12,7 @@ public enum AlertCategory Health, Internals, Stamina, - ShadowkinPower, + ShadowkinPower, // Parkstation-Shadowkin Piloting, Hunger, Thirst, diff --git a/Content.Shared/Alert/AlertType.cs b/Content.Shared/Alert/AlertType.cs index 237e13a924..1bbf5e4989 100644 --- a/Content.Shared/Alert/AlertType.cs +++ b/Content.Shared/Alert/AlertType.cs @@ -30,7 +30,7 @@ public enum AlertType : byte Thirsty, Parched, Stamina, - ShadowkinPower, + ShadowkinPower, // Parkstation-Shadowkin Pulled, Pulling, Magboots, diff --git a/Content.Shared/Chat/ChatChannel.cs b/Content.Shared/Chat/ChatChannel.cs index 7e34545809..3c374c1e6d 100644 --- a/Content.Shared/Chat/ChatChannel.cs +++ b/Content.Shared/Chat/ChatChannel.cs @@ -87,12 +87,13 @@ public enum ChatChannel : ushort /// /// Empathy channel for Shadowkin. /// - Empathy = 1 << 15, + Empathy = 1 << 15, // Parkstation-EmpathyChat /// /// Channels considered to be IC. /// - //Nyano - Summary: Adds telepathic as an 'IC' labelled chat.. Shadowkin: Adds empathy likewise + //Nyano - Summary: Adds telepathic as an 'IC' labelled chat.. + // Parkstation-EmpathyChat IC = Local | Whisper | Radio | Dead | Emotes | Damage | Visual | Telepathic | Empathy, AdminRelated = Admin | AdminAlert | AdminChat, diff --git a/Content.Shared/Chat/ChatSelectChannel.cs b/Content.Shared/Chat/ChatSelectChannel.cs index d9b4dbb43f..5b442c76ac 100644 --- a/Content.Shared/Chat/ChatSelectChannel.cs +++ b/Content.Shared/Chat/ChatSelectChannel.cs @@ -59,7 +59,7 @@ public enum ChatSelectChannel : ushort /// /// Shadowkin empathy channel /// - Empathy = ChatChannel.Empathy, + Empathy = ChatChannel.Empathy, // Parkstation-EmpathyChat Console = ChatChannel.Unspecified } diff --git a/Content.Shared/Chat/SharedChatSystem.cs b/Content.Shared/Chat/SharedChatSystem.cs index f8317df86f..c7cafa2e9b 100644 --- a/Content.Shared/Chat/SharedChatSystem.cs +++ b/Content.Shared/Chat/SharedChatSystem.cs @@ -21,7 +21,7 @@ public abstract class SharedChatSystem : EntitySystem public const char AdminPrefix = ']'; public const char WhisperPrefix = ','; public const char TelepathicPrefix = '='; //Nyano - Summary: Adds the telepathic channel's prefix. - public const char EmpathyPrefix = '~'; //Shadowkin + public const char EmpathyPrefix = '~'; // Parkstation-EmpathyChat public const char DefaultChannelKey = 'h'; [ValidatePrototypeId] diff --git a/Content.Shared/Eye/VisibilityFlags.cs b/Content.Shared/Eye/VisibilityFlags.cs index 7e2dd33d7d..d1b2d13c7e 100644 --- a/Content.Shared/Eye/VisibilityFlags.cs +++ b/Content.Shared/Eye/VisibilityFlags.cs @@ -10,6 +10,8 @@ public enum VisibilityFlags : int Normal = 1 << 0, Ghost = 1 << 1, PsionicInvisibility = 1 << 2, //Nyano - Summary: adds Psionic Invisibility as a visibility layer. Currently does nothing. + DarkSwapInvisibility = 1 << 3, // Parkstation-Shadowkin + AIEye = 1 << 4, // Parkstation-SAI TelegnosticProjection = 5, } } diff --git a/Content.Shared/Humanoid/NamingSystem.cs b/Content.Shared/Humanoid/NamingSystem.cs index ae5dbd73ed..d4f35463d0 100644 --- a/Content.Shared/Humanoid/NamingSystem.cs +++ b/Content.Shared/Humanoid/NamingSystem.cs @@ -37,7 +37,7 @@ public string GetName(string species, Gender? gender = null) case SpeciesNaming.FirstDashFirst: return Loc.GetString("namepreset-firstdashfirst", ("first1", GetFirstName(speciesProto, gender)), ("first2", GetFirstName(speciesProto, gender))); - case SpeciesNaming.First: + case SpeciesNaming.First: // Parkstation-Shadowkin return Loc.GetString("namepreset-first", ("first", GetFirstName(speciesProto, gender))); case SpeciesNaming.FirstLast: diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs index 2763d3ef2d..eaad9d3870 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs @@ -98,6 +98,7 @@ public float PowerLevel public bool Blackeye = false; + // TODO This sucks, make this not hardcoded so we can do some fun things with it public static readonly Dictionary PowerThresholds = new() { { ShadowkinPowerThreshold.Max, 250.0f }, diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 9cb201bc97..2220764c3e 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -11,6 +11,7 @@ public sealed class ShadowkinDarken : EntitySystem [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; + public override void Initialize() { base.Initialize(); @@ -29,6 +30,7 @@ private void OnInteractionAttempt(EntityUid uid, ShadowkinDarkSwappedComponent c if (_gameTiming.InPrediction) return; + // TODO This appears on way too many things _popup.PopupEntity(Loc.GetString("ethereal-pickup-fail"), args.Target.Value, uid); } } diff --git a/Resources/Locale/en-US/chat/managers/chat-manager.ftl b/Resources/Locale/en-US/chat/managers/chat-manager.ftl index 29aec8350f..9527c23a61 100644 --- a/Resources/Locale/en-US/chat/managers/chat-manager.ftl +++ b/Resources/Locale/en-US/chat/managers/chat-manager.ftl @@ -47,9 +47,11 @@ chat-manager-send-hook-ooc-wrap-message = OOC: (D){$senderName}: {$message} chat-manager-dead-channel-name = DEAD chat-manager-admin-channel-name = ADMIN +## Parkstation-EmpathyChat-Start chat-manager-send-empathy-chat-wrap-message = {$empathyChannelName}: {$message} chat-manager-send-empathy-chat-wrap-message-admin = {$empathyChannelName} - {$source}: {$message} chat-manager-empathy-channel-name = EMPATHY +## Parkstation-EmpathyChat-End ## Speech verbs for chat diff --git a/Resources/Locale/en-US/chat/ui/chat-box.ftl b/Resources/Locale/en-US/chat/ui/chat-box.ftl index 45ef7ac092..ef6b518b3f 100644 --- a/Resources/Locale/en-US/chat/ui/chat-box.ftl +++ b/Resources/Locale/en-US/chat/ui/chat-box.ftl @@ -12,6 +12,7 @@ hud-chatbox-select-channel-OOC = OOC hud-chatbox-select-channel-Damage = Damage hud-chatbox-select-channel-Visual = Actions hud-chatbox-select-channel-Radio = Radio +## Parkstation-EmpathyChat hud-chatbox-select-channel-Empathy = Empathy hud-chatbox-channel-Admin = Admin Misc @@ -25,6 +26,7 @@ hud-chatbox-channel-LOOC = LOOC hud-chatbox-channel-OOC = OOC hud-chatbox-channel-Radio = Radio hud-chatbox-channel-Server = Server +## Parkstation-EmpathyChat hud-chatbox-channel-Empathy = Empathy hud-chatbox-channel-Visual = Actions hud-chatbox-channel-Damage = Damage diff --git a/Resources/Locale/en-US/simplestation14/Prototypes/Alerts/shadowkin.ftl b/Resources/Locale/en-US/simplestation14/Prototypes/Alerts/shadowkin.ftl index b45ae82583..32653a424e 100644 --- a/Resources/Locale/en-US/simplestation14/Prototypes/Alerts/shadowkin.ftl +++ b/Resources/Locale/en-US/simplestation14/Prototypes/Alerts/shadowkin.ftl @@ -1,2 +1,2 @@ alerts-shadowkin-power-name = Power Level -alerts-shadowkin-power-desc = How much energy you have to expend via your abilities. +alerts-shadowkin-power-desc = How much energy you can expend via your abilities. diff --git a/Resources/Locale/en-US/simplestation14/Prototypes/Guidebook/species.ftl b/Resources/Locale/en-US/simplestation14/Prototypes/Guidebook/species.ftl deleted file mode 100644 index 14fb0e899b..0000000000 --- a/Resources/Locale/en-US/simplestation14/Prototypes/Guidebook/species.ftl +++ /dev/null @@ -1 +0,0 @@ -guide-entry-shadowkin = Shadowkin diff --git a/Resources/Locale/en-US/species/namepreset.ftl b/Resources/Locale/en-US/species/namepreset.ftl index 2f37b5f8a3..a6eb79c873 100644 --- a/Resources/Locale/en-US/species/namepreset.ftl +++ b/Resources/Locale/en-US/species/namepreset.ftl @@ -1,6 +1,5 @@ namepreset-firstlast = {$first} {$last} namepreset-firstdashfirst = {$first1}-{$first2} namepreset-thefirstoflast = The {$first} of {$last} - -## Parkstation +## Parkstation-Shadowkin namepreset-first = {$first} diff --git a/Resources/Prototypes/Alerts/alerts.yml b/Resources/Prototypes/Alerts/alerts.yml index d5bcea53f0..f7cd3d21f8 100644 --- a/Resources/Prototypes/Alerts/alerts.yml +++ b/Resources/Prototypes/Alerts/alerts.yml @@ -6,7 +6,7 @@ order: - category: Health - category: Stamina - - category: ShadowkinPower + - category: ShadowkinPower # Parkstation-Shadowkin - alertType: SuitPower - category: Internals - alertType: Fire diff --git a/Resources/Prototypes/Catalog/Fills/Crates/fun.yml b/Resources/Prototypes/Catalog/Fills/Crates/fun.yml index 38a8ca58b4..9119784f20 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/fun.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/fun.yml @@ -20,7 +20,7 @@ - id: PlushieSharkGrey orGroup: PlushieShark - id: PlushieAtmosian - - id: PlushieShadowkin + - id: PlushieShadowkin # Parkstation-Shadowkin - id: PlushieDiona - id: PlushieXeno - id: PlushieHampter @@ -309,4 +309,4 @@ - id: BoxDarts amount: 1 prob: 0.05 - + diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index 0e9360b76b..1c53e3697d 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -51,7 +51,7 @@ - idcard - Belt - type: UnpoweredFlashlight - - type: ShadowkinLight + - type: ShadowkinLight # Parkstation-Shadowkin - type: PointLight enabled: false radius: 1.5 diff --git a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml index 34fd8913d3..2c359103c7 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml @@ -40,7 +40,7 @@ sprite: Objects/Misc/Lights/lights.rsi size: 20 heldPrefix: off - - type: ShadowkinLight + - type: ShadowkinLight # Parkstation-Shadowkin - type: PointLight enabled: false radius: 3 diff --git a/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml b/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml index 8339d5c3f0..c454787fc2 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml @@ -57,7 +57,7 @@ map: [ "light" ] - type: Item sprite: Objects/Tools/flashlight.rsi - - type: ShadowkinLight + - type: ShadowkinLight # Parkstation-Shadowkin - type: PointLight enabled: false mask: /Textures/Effects/LightMasks/cone.png diff --git a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml index 3472a810e1..a7365a6aff 100644 --- a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml +++ b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml @@ -29,7 +29,7 @@ - state: on map: ["enum.PoweredLightLayers.Base"] state: on - - type: ShadowkinLight + - type: ShadowkinLight # Parkstation-Shadowkin - type: PointLight radius: 10 energy: 0.8 diff --git a/Resources/Prototypes/SimpleStation14/Entities/Body/Parts/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entities/Body/Parts/shadowkin.yml index 67762764e0..a28ca19701 100644 --- a/Resources/Prototypes/SimpleStation14/Entities/Body/Parts/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Entities/Body/Parts/shadowkin.yml @@ -1,7 +1,7 @@ - type: entity id: PartShadowkin parent: BaseItem - name: "Shadowkin body part" + name: Shadowkin body part abstract: true components: - type: Sprite @@ -19,25 +19,25 @@ - type: entity id: TorsoShadowkin - name: "Shadowkin torso" + name: Shadowkin torso parent: PartShadowkin components: - type: Sprite - state: "torso_m" + state: torso_m - type: Icon - state: "torso_m" + state: torso_m - type: BodyPart partType: Torso - type: entity id: HeadShadowkin - name: "Shadowkin head" + name: Shadowkin head parent: PartShadowkin components: - type: Sprite - state: "head_m" + state: head_m - type: Icon - state: "head_m" + state: head_m - type: BodyPart partType: Head - type: Input @@ -50,65 +50,65 @@ - type: entity id: LeftArmShadowkin - name: "left Shadowkin arm" + name: left Shadowkin arm parent: PartShadowkin components: - type: Sprite - state: "l_arm" + state: l_arm - type: Icon - state: "l_arm" + state: l_arm - type: BodyPart partType: Arm symmetry: Left - type: entity id: RightArmShadowkin - name: "right Shadowkin arm" + name: right Shadowkin arm parent: PartShadowkin components: - type: Sprite - state: "r_arm" + state: r_arm - type: Icon - state: "r_arm" + state: r_arm - type: BodyPart partType: Arm symmetry: Right - type: entity id: LeftHandShadowkin - name: "left Shadowkin hand" + name: left Shadowkin hand parent: PartShadowkin components: - type: Sprite - state: "l_hand" + state: l_hand - type: Icon - state: "l_hand" + state: l_hand - type: BodyPart partType: Hand symmetry: Left - type: entity id: RightHandShadowkin - name: "right Shadowkin hand" + name: right Shadowkin hand parent: PartShadowkin components: - type: Sprite - state: "r_hand" + state: r_hand - type: Icon - state: "r_hand" + state: r_hand - type: BodyPart partType: Hand symmetry: Right - type: entity id: LeftLegShadowkin - name: "left Shadowkin leg" + name: left Shadowkin leg parent: PartShadowkin components: - type: Sprite - state: "l_leg" + state: l_leg - type: Icon - state: "l_leg" + state: l_leg - type: BodyPart partType: Leg symmetry: Left @@ -116,13 +116,13 @@ - type: entity id: RightLegShadowkin - name: "right Shadowkin leg" + name: right Shadowkin leg parent: PartShadowkin components: - type: Sprite - state: "r_leg" + state: r_leg - type: Icon - state: "r_leg" + state: r_leg - type: BodyPart partType: Leg symmetry: Right @@ -130,26 +130,26 @@ - type: entity id: LeftFootShadowkin - name: "left Shadowkin foot" + name: left Shadowkin foot parent: PartShadowkin components: - type: Sprite - state: "l_foot" + state: l_foot - type: Icon - state: "l_foot" + state: l_foot - type: BodyPart partType: Foot symmetry: Left - type: entity id: RightFootShadowkin - name: "right Shadowkin foot" + name: right Shadowkin foot parent: PartShadowkin components: - type: Sprite - state: "r_foot" + state: r_foot - type: Icon - state: "r_foot" + state: r_foot - type: BodyPart partType: Foot symmetry: Right diff --git a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/tails.yml b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/tails.yml index 415f4e55ce..e3de225126 100644 --- a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/tails.yml +++ b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/tails.yml @@ -6,6 +6,7 @@ sprites: - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi state: axolotl + - type: marking id: TailDatashark bodyPart: Tail @@ -22,6 +23,7 @@ state: datashark_tail - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi state: datashark_taildata + - type: marking id: TailEasternDragon bodyPart: Tail @@ -32,6 +34,7 @@ state: easternd_primary - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi state: easternd_secondary + - type: marking id: TailFennec bodyPart: Tail @@ -40,6 +43,7 @@ sprites: - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi state: fennec + - type: marking id: TailFish bodyPart: Tail @@ -50,6 +54,7 @@ state: fish_primary - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi state: fish_secondary + - type: marking id: TailFluffy bodyPart: Tail @@ -58,6 +63,7 @@ sprites: - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi state: fluffy + - type: marking id: TailFox bodyPart: Tail @@ -68,6 +74,7 @@ state: fox_primary - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi state: fox_secondary + - type: marking id: TailGecko bodyPart: Tail @@ -80,6 +87,7 @@ state: gecko_secondary - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi state: gecko_tertiary + - type: marking id: TailKitsune bodyPart: Tail @@ -90,6 +98,7 @@ state: kitsune_primary - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi state: kitsune_secondary + - type: marking id: TailMaw bodyPart: Tail @@ -98,6 +107,7 @@ sprites: - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi state: maw + - type: marking id: TailShark bodyPart: Tail @@ -108,6 +118,7 @@ state: shark_fin - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi state: shark_tail + - type: marking id: TailSnake bodyPart: Tail @@ -116,6 +127,7 @@ sprites: - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi state: snake + - type: marking id: TailSuccubus bodyPart: Tail @@ -124,6 +136,7 @@ sprites: - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi state: succubus + - type: marking id: TailTentacle bodyPart: Tail @@ -132,6 +145,7 @@ sprites: - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi state: tentacle + - type: marking id: TailShadowkin bodyPart: Tail @@ -140,6 +154,7 @@ sprites: - sprite: SimpleStation14/Mobs/Customization/tails64x32.rsi state: shadowkin + - type: marking id: TailShadowkinBig bodyPart: Tail @@ -148,6 +163,7 @@ sprites: - sprite: SimpleStation14/Mobs/Customization/tails64x32.rsi state: shadowkin_big + - type: marking id: TailShadowkinBigFluff bodyPart: Tail diff --git a/Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.Lore.txt b/Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.Lore.txt deleted file mode 100644 index da40d40b2a..0000000000 --- a/Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.Lore.txt +++ /dev/null @@ -1,178 +0,0 @@ -# Lore - -## Biology - -[color=#a88b5e]Physicality[/color] - -Shadowkin seem very similar to canine species when looked at. -While mammalian in nature, it is nearly impossible to find any sexual dimorphism between genders, if they even have any. -They seem to all share the same body shape and often voices. - -The head consists of a snout with a nose, sharp teeth in the mouth, and two big ears on top of the head. -In addition to the two big ears, Shadowkin have two smaller ears lower down, giving them an exceptionally good ability to detect where exactly sounds come from. - -Shadowkin eyes are usually very large and fully mono-colored; they have no discernible pupils, irises, or similar. -The eye of a Shadowkin is a solid orb of color and, perhaps, their most defining trait. - -All observations show Shadowkin do not seem to age after a certain point. -Some may look older or younger than others, but the aging process seems to stop when the Shadowkin is chronologically in their 20s. - -Unusually, compiled medical data on Shadowkin shows that they have no lungs, thus not needing to breathe. -The compiled medical data also shows that they have a large, more circular shape where their lungs would be. - -[color=#a88b5e]Mentality[/color] - -Shadowkin core personalities are mirrored by their eye color. -Some common colors and their meanings are: - -- Red: Determined to reach a goal, even if it means sacrificing others. -- Green: Eager to learn and fit in with others. -- Blue: Very calm and collected, or shy. - -Other colors also exist in addition to these but are not as common. -The other colors are just mixes of the three main colors. -For example, here are a couple of mixes: - -- Purple: Determined, yet probably won't harm, in some cases shy. -- Yellow: Quite eager to be number one, especially if related to knowledge. -- Orange: Shy and calm, yet will fight if provoked. -- White: Very robust, exceeds expectations in most things they do, but is quite boring to interact with generally. - -There are rumors other colors exist as well. -Shadowkin that lose their ability to travel between dimensions have [color=#000000]black eyes[/color] no matter their core personality. -These black-eyed Shadowkin make up the largest number of them living in Realspace. - -## History - -Shadowkin are creatures native to their so-called Pocket Dimension, a part of space that is unable to be accurately pinpointed and/or visited by most people. -From there, Shadowkin visit our worlds, and sometimes a large number of them are forced into our world in mass migrations and then live among us. -What exactly causes these mass migrations is unknown, but may be related to them losing their ability to travel between dimensions. - -[color=#a88b5e]Homeworld[/color] - -While no home system or world has been found, some Shadowkin talk about dreaming of their homeworld, describing a lush and green land with abundant resources. - -[color=#a88b5e]Racial/Government Status[/color] - -There currently exists no Shadowkin government, and with Shadowkin being as rare as they are, they tend to fit into currently established societies and civilizations, with varying degrees of success in the past. -In recent years, however, many cultures have taken to accepting Shadowkin as another galactic constant, going as far as allowing them lives similar to those that any of the other species would lead. - -Some systems early on took and experimented on Shadowkin, in an attempt to utilize their powers in various technology, and even recreating them with very experimental technology. -The tests failed and this was met with a lot of resistance from Shadowkin, many of them being killed or becoming Blackeyes in the process. -After this, those systems realized that Shadowkin were a sentient species, and deeply apologized for their actions. - -## Culture - -[color=#a88b5e]The Typical Experience[/color] - -Most times, life is pretty normal. A Shadowkin can have a job, go to the job to work, then spend time off with friends. -The fact is most times of the day, the small abilities one might have are nice, but not overly useful. Sure, a Shadowkin could dim the nearby lights, but at the same time, the Shadowkin could also just flick the light switch. -However, it can sometimes happen that when a Shadowkin slept in and needs to get to work quickly, they might just teleport to work. -Some people might be overly wary of Shadowkin, some might be drawn towards Shadowkin. -Many Shadowkin are used to not wearing clothes, which can lead to some awkward situations, but those are generally the same situations any other furred species would have. - -[color=#a88b5e]Language[/color] - -The only recorded spoken language of the Shadowkin is an unusual language named "Mar", named after the fact that every single word in this language is the word "mar". -Spoken in different tones, with more or less emphasis on the various parts, or by drawing out parts of this word, a multitude of different "mar"s can be created, but they follow no apparent conventions. -Shadowkin can perfectly understand each other though and discuss complex topics using only this one word. -The Shadowkin can hear the Mar language from anywhere and understand it via Empathy, yet do not know who it is from unless they are close enough to see the sender. -Other humanoid species are incapable of understanding or learning Mar, as they are unable to accentuate their speech in the same way or hear some of the silent, Empathic tones they use. -Shadowkin tend to learn one or more languages of the Realspace beings. -The capability in such learned languages depends fully on each single Shadowkin, where some have only very broken capabilities, while others are fluent in several languages. - -[color=#a88b5e]Naming Conventions[/color] - -Shadowkin tend to name themselves with a singular word, ranging from states of being, such as Lone and Collected, to words that describe their memories connected to their supposed homeworld, like Dreamer. -Name schemes of the humans are usually frowned upon, as they do not reflect upon the Shadowkin, resulting in reactions ranging anywhere from an actual frown to being entirely ignored. -Shadowkin following another species naming scheme are often Blackeyes, not fitting in with other Shadowkin as well. -Names hold a great deal for Shadowkin because of how closely they are often tied to describing who they are. -Following life-changing events, Shadowkin often change their names to reflect the new person they have become. - -[color=#a88b5e]Rumors and Speculation[/color] - -Shadowkin are beings from another dimension, capable of performing feats that others could only describe as "magic", with no scientific explanation. -It is speculated that Shadowkin actually have a whole nation in their dimension, and those that come to Realspace just simply refuse to talk about it. -Sometimes Shadowkin mention a "Hub", acting as evidence for this theory. - -Some believe Shadowkin are the result of experimentation, though them being taken and experimented on is a large piece of evidence denying this theory. - -Some believe Shadowkin are the result of an expedition crew that disappeared hundreds of years ago, even though the first Shadowkin sightings were long before that. -Obviously, this expedition ship performed time travel. - -## OOC Notes - -Extra information, should be read if playing Shadowkin, if not you should try to learn this in gameplay. - -[color=#a88b5e]History[/color] - -Shadowkin used to live on a very lush forest planet, using primitive technology to work with metal, create tools, and build stone structures. -According to the dreams, Shadowkin back then had forged tools and blades, but had no electricity, presumably putting them at a medieval technology level. -In a sudden event, everyone and everything organic suddenly found themselves in an alternate dimension, sucked straight out of their previous home. -The Shadowkin being ripped from their homes happened in three total "dimensional ripples". - -Now stuck in this alternate dimension, Shadowkin changed a lot. -They stopped aging and with time developed the ability to use the energy of this dimension to power their unusual "magic". -And even later, they learned how to leave the dimension and travel to Realspace and back again. -However, as the eons passes, memories became shady of their home. -Many Shadowkin forgot more and more about the thousands of years they had lived, reducing memory to focus on the more important closer time. -However in dreams, Shadowkin, even those born in Realspace, often have visions of their home planet. -Some events can trigger certain memories to return like meeting someone they knew from the past makes them remember in great detail who they are. -As such, it can happen that two Shadowkin can randomly meet and remember that they met hundreds of years ago, often confusing nearby unknowing humanoids. - -[color=#a88b5e]Biology[/color] - -If a Shadowkin personality changes drastically, their eye color will change as an effect, reflecting upon their new personality. -Shadowkin, being ageless entities, can look older or younger, but that is merely a visual representation of how they feel about their age. -22 years after birth a Shadowkin stops aging, and in all of their history no instance of them dying of old age has been recorded. - -[color=#a88b5e]Shadowkin energy[/color] - -Shadowkin have an odd organ in them, their "Core". -This organ is the source and storage place for their power. -Without it, they would be unable to use their abilities. -The Core is very sensitive to physical trauma, yet is very resilient to electrical or magical damage. -The Core can get irreversibly destroyed from overloading it, using too much power too quickly, which is what happens to the Blackeyes. -The Core can not be replaced, using a new one would require a new body, and trying to use another Shadowkin Core will result in death. - -The Shadowkin's ability to fall into a deep sleep is a method to recharge their energy at a significantly higher rate than idling. -Though while in this deep sleep, it is difficult to wake up, and cannot be woken up by anything other than themself. - -Shadowkin can know exactly how much energy they have, and feel differently based on how much they have. -They can also Empathically sense the energy of others nearby and can estimate how much energy they have based on their feelings. - -[color=#a88b5e]Shadowkin Abilities[/color] - -Shadowkin have a few abilities. -They can teleport, requiring a small amount of energy, but they can do it quickly. -They can teleport to and from The Dark, requiring much more energy than teleportation. -They can immediately fall into a deep sleep at any time. - -[color=#a88b5e]The Ritual[/color] - -When a Shadowkin reaches adulthood, they undergo a "Ritual". -During this Ritual they intentionally overload their energy reserves, forcing their capacity to expand rapidly in order to gain enough energy to travel between dimensions. -Most Shadowkin pass the Ritual and that's the end of it, but some Shadowkin perish or become Blackeyes during the ritual. - -[color=#a88b5e]Important Terminology[/color] - -[color=#a88b5e]Shadowkin:[/color] -The name given for your race. -While your race doesn't have a name for itself, this is how most of the Galaxy refers to you, so it's how you refer to yourself too. - -[color=#a88b5e]The Dark:[/color] -The other dimension where you are from. -There are theories that The Dark and Bluespace are connected, but you don't know the details about that. -The Dark is a dimension where strange rules apply. -For outsiders who somehow enter it, whatever they imagine being in there, they see there, if not too complex. -If an outsider comes with a willing Shadowkin they may see what the Shadowkin sees, being anything they imagine, or a reflection of the station. - -[color=#a88b5e]Blackeyes:[/color] -A Shadowkin who has undergone and failed the Ritual, or lost their ability via other methods. -The Blackeyes have completely black eyes, no matter their actual personality. -They choose a new name, which follows a favorite species' naming scheme. -They are often ignored or left alone more by other Shadowkin. -[color=#a88b5e]Note:[/color] Blackeyes correlation with black eyes is done entirely via roleplay, the game will not handle this for you. - -[color=#a88b5e]Mar:[/color] -A word used to verbally communicate feelings, emotions, wishes, hopes, ideas, and whatever, in addition to your Empathy. diff --git a/Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.xml b/Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.xml deleted file mode 100644 index fe0ef45483..0000000000 --- a/Resources/ServerInfo/SimpleStation14/Guidebook/Species/SimpleStationSpecies/Shadowkin.xml +++ /dev/null @@ -1,34 +0,0 @@ - - # Shadowkin - - [color=#008000]Shadowkin are enabled for character creation.[/color] - - Fluffy lil' guys. - - ## Ability Differences - - - Need no air to survive - - Can teleport short distances - - Can travel to and from The Dark at will - - Dims nearby lights when in the The Dark - - When too low on energy, they may fall into a powerful sleep - - Can "speak" in the Empathy chat (~), which only other Shadowkin can understand - - Slightly less blunt damage - - A bit more slash damage - - Slightly more piercing damage - - Less cold damage - - Slightly more heat damage - - Near no cellular damage - - More bloodloss damage - - Slightly more shock damage - - More radiation damage - - ## Physical Differences - - - Very large and brightly colored eyes with no pupils - - Sees the world through their eyes' tint - - Very large ears - - Very fluffy - - Can be Male, Female, or Unisex - - Can be 18-300 years old - From 63b830aae8983b6b5387a01d90bb1600b536224a Mon Sep 17 00:00:00 2001 From: Finket Date: Tue, 14 Nov 2023 11:16:48 +0200 Subject: [PATCH 18/59] Move over to NetEntity --- .../ShadowkinPowerSystem.DarkSwapped.cs | 4 +-- .../Systems/ShadowkinSystem.Blackeye.cs | 8 +++-- .../Shadowkin/Systems/ShadowkinSystem.Tint.cs | 4 +-- .../SimpleStation14/Chat/ESayCommand.cs | 6 ++-- .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 35 ++++++++++--------- .../Systems/ShadowkinPowerSystem.Teleport.cs | 4 +-- .../Shadowkin/Systems/ShadowkinPowerSystem.cs | 9 +++-- .../Systems/ShadowkinSystem.Blackeye.Trait.cs | 7 ++-- .../Systems/ShadowkinSystem.Blackeye.cs | 29 ++++++++------- .../Events/ShadowkinEvents.Blackeye.cs | 12 +++---- .../Events/ShadowkinEvents.Powers.cs | 4 +-- 11 files changed, 68 insertions(+), 54 deletions(-) diff --git a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs index 0c038c0ba1..9544b3a4b2 100644 --- a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs +++ b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs @@ -49,12 +49,12 @@ private void OnShutdown(EntityUid uid, ShadowkinDarkSwappedComponent component, RemoveOverlay(); } - private void OnPlayerAttached(EntityUid uid, ShadowkinDarkSwappedComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, ShadowkinDarkSwappedComponent component)//, PlayerAttachedEvent args) { AddOverlay(); } - private void OnPlayerDetached(EntityUid uid, ShadowkinDarkSwappedComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, ShadowkinDarkSwappedComponent component)//, PlayerDetachedEvent args) { RemoveOverlay(); } diff --git a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs index 9af16385e5..5a4db8f392 100644 --- a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs +++ b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs @@ -22,7 +22,8 @@ public override void Initialize() private void OnBlackeye(ShadowkinBlackeyeEvent ev) { - SetColor(ev.Uid, Color.Black); + var uid = _entity.GetEntity(ev.Ent); + SetColor(uid, Color.Black); } @@ -36,8 +37,9 @@ private void OnInit(EntityUid uid, ShadowkinComponent component, ComponentInit a // Blackeye if none of the RGB values are greater than 75 if (layer.Color.R * 255 < 75 && layer.Color.G * 255 < 75 && layer.Color.B * 255 < 75) { - // TODO Need to move this to server somehow, can't trust the client with this - RaiseNetworkEvent(new ShadowkinBlackeyeEvent(uid, false)); + // TODO Need to move this to server somehow, can't trust the client with this + var ent = _entity.GetNetEntity(uid); + RaiseNetworkEvent(new ShadowkinBlackeyeEvent(ent, false)); } } diff --git a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs index 1e97a501c6..74613d28bf 100644 --- a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs +++ b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs @@ -53,12 +53,12 @@ private void OnShutdown(EntityUid uid, ShadowkinComponent component, ComponentSh _overlay.RemoveOverlay(_tintOverlay); } - private void OnPlayerAttached(EntityUid uid, ShadowkinComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, ShadowkinComponent component)// , PlayerAttachedEvent args) { _overlay.AddOverlay(_tintOverlay); } - private void OnPlayerDetached(EntityUid uid, ShadowkinComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, ShadowkinComponent component)// , PlayerDetachedEvent args) { _overlay.RemoveOverlay(_tintOverlay); } diff --git a/Content.Server/SimpleStation14/Chat/ESayCommand.cs b/Content.Server/SimpleStation14/Chat/ESayCommand.cs index d8c3eb3fcc..b9743c622a 100644 --- a/Content.Server/SimpleStation14/Chat/ESayCommand.cs +++ b/Content.Server/SimpleStation14/Chat/ESayCommand.cs @@ -18,7 +18,7 @@ internal sealed class ESayCommand : IConsoleCommand public void Execute(IConsoleShell shell, string argStr, string[] args) { - if (shell.Player is not IPlayerSession player) + /*if (shell.Player is not IPlayerSession player) { shell.WriteError("This command cannot be run from the server."); return; @@ -31,7 +31,7 @@ public void Execute(IConsoleShell shell, string argStr, string[] args) { shell.WriteError("You don't have an entity!"); return; - } + }*/ if (args.Length < 1) return; @@ -40,6 +40,6 @@ public void Execute(IConsoleShell shell, string argStr, string[] args) if (string.IsNullOrEmpty(message)) return; - EntitySystem.Get().TrySendInGameICMessage(playerEntity, message, InGameICChatType.Empathy, false, false, shell, player, checkRadioPrefix: false); + // EntitySystem.Get().TrySendInGameICMessage(playerEntity, message, InGameICChatType.Empathy, false, false, shell, player, checkRadioPrefix: false); } } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index e9488978a1..8522a1bfec 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -4,7 +4,6 @@ using Content.Server.NPC.Systems; using Content.Server.SimpleStation14.Species.Shadowkin.Components; using Content.Server.SimpleStation14.Species.Shadowkin.Events; -using Content.Server.Visible; using Content.Shared.Actions; using Content.Shared.CombatMode.Pacification; using Content.Shared.Cuffs.Components; @@ -64,6 +63,8 @@ private void Shutdown(EntityUid uid, ShadowkinDarkSwapPowerComponent component, private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ShadowkinDarkSwapEvent args) { + var performer = _entity.GetNetEntity(args.Performer); + // Need power to drain power if (!_entity.HasComponent(args.Performer)) return; @@ -77,7 +78,7 @@ private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, var hasComp = _entity.HasComponent(args.Performer); SetDarkened( - args.Performer, + performer, !hasComp, !hasComp, !hasComp, @@ -98,7 +99,7 @@ private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, public void SetDarkened( - EntityUid performer, + NetEntity performer, bool addComp, bool invisible, bool pacify, @@ -114,34 +115,36 @@ public void SetDarkened( ShadowkinDarkSwapEvent? args ) { - var ev = new ShadowkinDarkSwapAttemptEvent(performer); + var performerUid = _entity.GetEntity(performer); + + var ev = new ShadowkinDarkSwapAttemptEvent(performerUid); RaiseLocalEvent(ev); if (ev.Cancelled) return; if (addComp) { - var comp = _entity.EnsureComponent(performer); + var comp = _entity.EnsureComponent(performerUid); comp.Invisible = invisible; comp.Pacify = pacify; comp.Darken = darken; RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, true)); - _audio.PlayPvs(soundOn, performer, AudioParams.Default.WithVolume(volumeOn)); + _audio.PlayPvs(soundOn, performerUid, AudioParams.Default.WithVolume(volumeOn)); - _power.TryAddPowerLevel(performer, -powerCostOn); - _stamina.TakeStaminaDamage(performer, staminaCostOn); + _power.TryAddPowerLevel(performerUid, -powerCostOn); + _stamina.TakeStaminaDamage(performerUid, staminaCostOn); } else { - _entity.RemoveComponent(performer); + _entity.RemoveComponent(performerUid); RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, false)); - _audio.PlayPvs(soundOff, performer, AudioParams.Default.WithVolume(volumeOff)); + _audio.PlayPvs(soundOff, performerUid, AudioParams.Default.WithVolume(volumeOff)); - _power.TryAddPowerLevel(performer, -powerCostOff); - _stamina.TakeStaminaDamage(performer, staminaCostOff); + _power.TryAddPowerLevel(performerUid, -powerCostOff); + _stamina.TakeStaminaDamage(performerUid, staminaCostOff); } if (args != null) @@ -198,8 +201,8 @@ public void SetVisibility(EntityUid uid, bool set) eye.VisibilityMask |= (uint) VisibilityFlags.DarkSwapInvisibility;*/ // Make other entities unable to see the entity unless also DarkSwapped - _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); - _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + // _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); + // _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); // If not a ghost, add a stealth shader to the entity @@ -213,8 +216,8 @@ public void SetVisibility(EntityUid uid, bool set) eye.VisibilityMask &= ~(uint) VisibilityFlags.DarkSwapInvisibility;*/ // Make other entities able to see the entity again - _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); - _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + // _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); + // _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); // Remove the stealth shader from the entity diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index 593d451dda..60d59e4528 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -40,13 +40,13 @@ private void Startup(EntityUid uid, ShadowkinTeleportPowerComponent component, C { var componentActionShadowkinTeleport = component.ActionShadowkinTeleport; _actions.AddAction(uid, ref componentActionShadowkinTeleport, "ActionShadowkinTeleport"); - // _actions.AddAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport")), null); + // // _actions.AddAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport")), null); } private void Shutdown(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentShutdown args) { _actions.RemoveAction(uid, component.ActionShadowkinTeleport); - // _actions.RemoveAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport"))); + // // _actions.RemoveAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport"))); } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs index 3613b7d1d5..e5218a030e 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs @@ -200,8 +200,9 @@ public void SetPowerLevel(EntityUid uid, float newPowerLevel) /// public bool TryBlackeye(EntityUid uid) { + var ent = _entity.GetNetEntity(uid); // Raise an attempted blackeye event - var ev = new ShadowkinBlackeyeAttemptEvent(uid); + var ev = new ShadowkinBlackeyeAttemptEvent(ent); RaiseLocalEvent(ev); if (ev.Cancelled) return false; @@ -215,6 +216,8 @@ public bool TryBlackeye(EntityUid uid) /// public void Blackeye(EntityUid uid) { + var ent = _entity.GetNetEntity(uid); + // Get shadowkin component if (!_entity.TryGetComponent(uid, out var component)) { @@ -223,8 +226,8 @@ public void Blackeye(EntityUid uid) } component.Blackeye = true; - RaiseNetworkEvent(new ShadowkinBlackeyeEvent(uid)); - RaiseLocalEvent(new ShadowkinBlackeyeEvent(uid)); + RaiseNetworkEvent(new ShadowkinBlackeyeEvent(ent)); + RaiseLocalEvent(new ShadowkinBlackeyeEvent(ent)); } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.Trait.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.Trait.cs index dff2aece9b..ca14d1e2d1 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.Trait.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.Trait.cs @@ -5,6 +5,8 @@ namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; public sealed class ShadowkinBlackeyeTraitSystem : EntitySystem { + [Dependency] private readonly IEntityManager _entity = default!; + public override void Initialize() { base.Initialize(); @@ -15,7 +17,8 @@ public override void Initialize() private void OnStartup(EntityUid uid, ShadowkinBlackeyeTraitComponent _, ComponentStartup args) { - RaiseLocalEvent(uid, new ShadowkinBlackeyeEvent(uid, false)); - RaiseNetworkEvent(new ShadowkinBlackeyeEvent(uid, false)); + var ent = _entity.GetNetEntity(uid); + RaiseLocalEvent(uid, new ShadowkinBlackeyeEvent(ent, false)); + RaiseNetworkEvent(new ShadowkinBlackeyeEvent(ent, false)); } } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs index 79de5f4d7a..01fe6cbc63 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs @@ -34,7 +34,8 @@ public override void Initialize() private void OnBlackeyeAttempt(ShadowkinBlackeyeAttemptEvent ev) { - if (!_entity.TryGetComponent(ev.Uid, out var component) || + var uid = _entity.GetEntity(ev.Ent); + if (!_entity.TryGetComponent(uid, out var component) || component.Blackeye || !(component.PowerLevel <= ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Min] + 5)) ev.Cancel(); @@ -42,46 +43,48 @@ private void OnBlackeyeAttempt(ShadowkinBlackeyeAttemptEvent ev) private void OnBlackeye(ShadowkinBlackeyeEvent ev) { + var uid = _entity.GetEntity(ev.Ent); + // Check if the entity is a shadowkin - if (!_entity.TryGetComponent(ev.Uid, out var component)) + if (!_entity.TryGetComponent(uid, out var component)) return; // Stop gaining power component.Blackeye = true; component.PowerLevelGainEnabled = false; - _power.SetPowerLevel(ev.Uid, ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Min]); + _power.SetPowerLevel(uid, ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Min]); // Update client state Dirty(component); // Remove powers - _entity.RemoveComponent(ev.Uid); - _entity.RemoveComponent(ev.Uid); - _entity.RemoveComponent(ev.Uid); - _entity.RemoveComponent(ev.Uid); + _entity.RemoveComponent(uid); + _entity.RemoveComponent(uid); + _entity.RemoveComponent(uid); + _entity.RemoveComponent(uid); if (!ev.Damage) return; // Popup - _popup.PopupEntity(Loc.GetString("shadowkin-blackeye"), ev.Uid, ev.Uid, PopupType.Large); + _popup.PopupEntity(Loc.GetString("shadowkin-blackeye"), uid, uid, PopupType.Large); // Stamina crit - if (_entity.TryGetComponent(ev.Uid, out var stamina)) + if (_entity.TryGetComponent(uid, out var stamina)) { - _stamina.TakeStaminaDamage(ev.Uid, stamina.CritThreshold, null, ev.Uid); + _stamina.TakeStaminaDamage(uid, stamina.CritThreshold, null, uid); } // Nearly crit with cellular damage // If already 5 damage off of crit, don't do anything - if (!_entity.TryGetComponent(ev.Uid, out var damageable) || - !_mobThreshold.TryGetThresholdForState(ev.Uid, MobState.Critical, out var key)) + if (!_entity.TryGetComponent(uid, out var damageable) || + !_mobThreshold.TryGetThresholdForState(uid, MobState.Critical, out var key)) return; var minus = damageable.TotalDamage; - _damageable.TryChangeDamage(ev.Uid, + _damageable.TryChangeDamage(uid, new DamageSpecifier(_prototype.Index("Cellular"), Math.Max((double) (key.Value - minus - 5), 0)), true, diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs index 353313b2b3..b7109bd7af 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs @@ -7,11 +7,11 @@ namespace Content.Shared.SimpleStation14.Species.Shadowkin.Events; /// public sealed class ShadowkinBlackeyeAttemptEvent : CancellableEntityEventArgs { - public readonly EntityUid Uid; + public readonly NetEntity Ent; - public ShadowkinBlackeyeAttemptEvent(EntityUid uid) + public ShadowkinBlackeyeAttemptEvent(NetEntity ent) { - Uid = uid; + Ent = ent; } } @@ -21,12 +21,12 @@ public ShadowkinBlackeyeAttemptEvent(EntityUid uid) [Serializable, NetSerializable] public sealed class ShadowkinBlackeyeEvent : EntityEventArgs { - public readonly EntityUid Uid; + public readonly NetEntity Ent; public readonly bool Damage; - public ShadowkinBlackeyeEvent(EntityUid uid, bool damage = true) + public ShadowkinBlackeyeEvent(NetEntity ent, bool damage = true) { - Uid = uid; + Ent = ent; Damage = damage; } } diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs index d0d3c67ddf..83385e205e 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs @@ -8,10 +8,10 @@ namespace Content.Shared.SimpleStation14.Species.Shadowkin.Events; [Serializable, NetSerializable] public sealed class ShadowkinDarkSwappedEvent : EntityEventArgs { - public EntityUid Performer { get; } + public NetEntity Performer { get; } public bool DarkSwapped { get; } - public ShadowkinDarkSwappedEvent(EntityUid performer, bool darkSwapped) + public ShadowkinDarkSwappedEvent(NetEntity performer, bool darkSwapped) { Performer = performer; DarkSwapped = darkSwapped; From 024392c945b91454dea6ebb755c9940c147bb21a Mon Sep 17 00:00:00 2001 From: Finket Date: Thu, 4 Jan 2024 06:05:02 +0200 Subject: [PATCH 19/59] Move more sprites over --- .../ShadowkinPowerSystem.DarkSwapped.cs | 8 +-- .../Shadowkin/Systems/ShadowkinSystem.Tint.cs | 8 +-- .../Entities/Mobs/Player/shadowkin.yml | 4 +- .../Customization/ears.rsi/avali_inner.png | Bin 0 -> 7734 bytes .../Customization/ears.rsi/avali_outer.png | Bin 0 -> 7497 bytes .../Mobs/Customization/ears.rsi/bunny.png | Bin 0 -> 8130 bytes .../Mobs/Customization/ears.rsi/bunny2.png | Bin 0 -> 7187 bytes .../ears.rsi/chemlight_inner.png | Bin 0 -> 6512 bytes .../ears.rsi/chemlight_outer.png | Bin 0 -> 6919 bytes .../Customization/ears.rsi/dragonlong.png | Bin 0 -> 7244 bytes .../Customization/ears.rsi/easternd_ears.png | Bin 0 -> 6634 bytes .../Customization/ears.rsi/easternd_horns.png | Bin 0 -> 6680 bytes .../Customization/ears.rsi/jackal_inner.png | Bin 0 -> 6188 bytes .../Customization/ears.rsi/jackal_outer.png | Bin 0 -> 6875 bytes .../Customization/ears.rsi/magus_ears.png | Bin 0 -> 7434 bytes .../Customization/ears.rsi/magus_neck.png | Bin 0 -> 6605 bytes .../Mobs/Customization/ears.rsi/mouse.png | Bin 0 -> 7084 bytes .../ears.rsi/sylveon_primary.png | Bin 0 -> 7536 bytes .../ears.rsi/sylveon_secondary.png | Bin 0 -> 6906 bytes .../ears.rsi/sylveon_tertiary.png | Bin 0 -> 6253 bytes .../Customization/wings64x32.rsi/harpy.png | Bin 0 -> 9638 bytes .../Customization/wings64x32.rsi/meta.json | 15 +++++ .../Customization/wings96x34.rsi/dragon.png | Bin 0 -> 8414 bytes .../wings96x34.rsi/dragon_open.png | Bin 0 -> 10926 bytes .../Mobs/Customization/wings96x34.rsi/fly.png | Bin 0 -> 16694 bytes .../Customization/wings96x34.rsi/fly_open.png | Bin 0 -> 21757 bytes .../Customization/wings96x34.rsi/megamoth.png | Bin 0 -> 14130 bytes .../wings96x34.rsi/megamoth_open.png | Bin 0 -> 15775 bytes .../Customization/wings96x34.rsi/meta.json | 52 ++++++++++++++++++ .../Customization/wings96x34.rsi/mothra.png | Bin 0 -> 9374 bytes .../wings96x34.rsi/mothra_open.png | Bin 0 -> 14824 bytes .../Customization/wings96x34.rsi/robotic.png | Bin 0 -> 13347 bytes .../Customization/wings96x34.rsi/skeleton.png | Bin 0 -> 8551 bytes .../wings96x34.rsi/skeleton_open.png | Bin 0 -> 10255 bytes 34 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/avali_inner.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/avali_outer.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/bunny.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/bunny2.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/chemlight_inner.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/chemlight_outer.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/dragonlong.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/easternd_ears.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/easternd_horns.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/jackal_inner.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/jackal_outer.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/magus_ears.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/magus_neck.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/mouse.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/sylveon_primary.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/sylveon_secondary.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/sylveon_tertiary.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings64x32.rsi/harpy.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings64x32.rsi/meta.json create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/dragon.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/dragon_open.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/fly.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/fly_open.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/megamoth.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/megamoth_open.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/meta.json create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/mothra.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/mothra_open.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/robotic.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/skeleton.png create mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/skeleton_open.png diff --git a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs index 9544b3a4b2..67ea8f91fb 100644 --- a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs +++ b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs @@ -28,8 +28,8 @@ public override void Initialize() SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnShutdown); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); } @@ -49,12 +49,12 @@ private void OnShutdown(EntityUid uid, ShadowkinDarkSwappedComponent component, RemoveOverlay(); } - private void OnPlayerAttached(EntityUid uid, ShadowkinDarkSwappedComponent component)//, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, ShadowkinDarkSwappedComponent component, LocalPlayerAttachedEvent args) { AddOverlay(); } - private void OnPlayerDetached(EntityUid uid, ShadowkinDarkSwappedComponent component)//, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, ShadowkinDarkSwappedComponent component, LocalPlayerDetachedEvent args) { RemoveOverlay(); } diff --git a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs index 74613d28bf..20d92ae4e6 100644 --- a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs +++ b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs @@ -31,8 +31,8 @@ public override void Initialize() SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnShutdown); - SubscribeLocalEvent(OnPlayerAttached); - SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnRoundRestart); } @@ -53,12 +53,12 @@ private void OnShutdown(EntityUid uid, ShadowkinComponent component, ComponentSh _overlay.RemoveOverlay(_tintOverlay); } - private void OnPlayerAttached(EntityUid uid, ShadowkinComponent component)// , PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, ShadowkinComponent component, LocalPlayerAttachedEvent args) { _overlay.AddOverlay(_tintOverlay); } - private void OnPlayerDetached(EntityUid uid, ShadowkinComponent component)// , PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, ShadowkinComponent component, LocalPlayerDetachedEvent args) { _overlay.RemoveOverlay(_tintOverlay); } diff --git a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml index a6ee613ba2..e96e67a191 100644 --- a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml @@ -14,8 +14,8 @@ - type: Body prototype: Shadowkin requiredLegs: 2 - - type: DiseaseCarrier - diseaseResist: 0.1 + # - type: DiseaseCarrier + # diseaseResist: 0.1 - type: Flammable damage: types: diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/avali_inner.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/avali_inner.png new file mode 100644 index 0000000000000000000000000000000000000000..5a2c14b8a1d0e3c0dfffca2a581d50463fa1d2be GIT binary patch literal 7734 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/bunny.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/bunny.png new file mode 100644 index 0000000000000000000000000000000000000000..bb7b6c58278a9df8aa80ff7f12fe5384104c89a8 GIT binary patch literal 8130 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/chemlight_outer.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/chemlight_outer.png new file mode 100644 index 0000000000000000000000000000000000000000..5e0d710521695b3ee48ab7c74c0456c3c100247e GIT binary patch literal 6919 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 U_0rW1%T;5p&hFeY$HmG20ZWKGEdT%j literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/dragonlong.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/dragonlong.png new file mode 100644 index 0000000000000000000000000000000000000000..4fd9e394695bb8e47ca22b94dadba176a9a0c5d4 GIT binary patch literal 7244 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 WIdUGkKc$MtEKRqYTsGQ!;C}!ni77Au literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/easternd_ears.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/easternd_ears.png new file mode 100644 index 0000000000000000000000000000000000000000..fff95197c2702dd4aacf06f7418316450e918f33 GIT binary patch literal 6634 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/easternd_horns.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/easternd_horns.png new file mode 100644 index 0000000000000000000000000000000000000000..dd01985e81bbe4a24988a8cf999d1449b1758141 GIT binary patch literal 6680 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/jackal_inner.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/jackal_inner.png new file mode 100644 index 0000000000000000000000000000000000000000..23979301e85cacd05742367ad8b89eac34c88eaa GIT binary patch literal 6188 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/jackal_outer.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/jackal_outer.png new file mode 100644 index 0000000000000000000000000000000000000000..1446c495a5829b9c99b3ee1258bd50482450f305 GIT binary patch literal 6875 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 K=YxyF*ZmK0a{i70 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/magus_neck.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/magus_neck.png new file mode 100644 index 0000000000000000000000000000000000000000..6139c5d1724e378b7af1f3f93681a099e31bc1fa GIT binary patch literal 6605 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 LQ-s^cC*}PY=&+RZ literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/mouse.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/mouse.png new file mode 100644 index 0000000000000000000000000000000000000000..ea1a2b081520d6594ca11e9adf9c80003378eae7 GIT binary patch literal 7084 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 GnEwIx9lvn^ literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/sylveon_primary.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/sylveon_primary.png new file mode 100644 index 0000000000000000000000000000000000000000..fedb41a80034e9d9e9398a23bd17a48e169a3f02 GIT binary patch literal 7536 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 JTVb~*?%znwGpqmr literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/sylveon_tertiary.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ears.rsi/sylveon_tertiary.png new file mode 100644 index 0000000000000000000000000000000000000000..a9d62b5ed1b4f7ae995fa125da87ca9708983197 GIT binary patch literal 6253 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 IvD0S#1#i6Yb^rhX literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/wings64x32.rsi/harpy.png b/Resources/Textures/SimpleStation14/Mobs/Customization/wings64x32.rsi/harpy.png new file mode 100644 index 0000000000000000000000000000000000000000..be6423a49a8519c3dfd7eca79b36ca1a21688ad8 GIT binary patch literal 9638 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/dragon_open.png b/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/dragon_open.png new file mode 100644 index 0000000000000000000000000000000000000000..76eefc0af65ce61284fb937b0fcc90e9ec377141 GIT binary patch literal 10926 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/fly.png b/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/fly.png new file mode 100644 index 0000000000000000000000000000000000000000..261b3eb75df292a9a435ed5731224a821bfc9797 GIT binary patch literal 16694 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/fly_open.png b/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/fly_open.png new file mode 100644 index 0000000000000000000000000000000000000000..e98fd41bc01408e31c76c489fc27ba4d9445bbba GIT binary patch literal 21757 zcmeFZbx@p7(>A)e2X}V~wzxY4cMpLqu(-Pfm*5Tof(1!%3GVJLf#B}$4&UbYc%856 z)LZAg|2@>oy)!-6bYI;wb5GA*gsUpQLqjG)1^@tPaa%`9!e6fT|)U<$B@r5OO=u~3k%=R_i$5WISc;|yzq35W^$Wn;(Q zpFLhJTic^8`ox(Zuf=2rrlS)2B)-r8dbxUg&(uIc82&TC-K)lc((J3PPV%Y8<^!=e1oKXQM&U;865=n~Ka7kr1)G|FUCaf&>0i;1;a4OYvk0E-kJ z-Zc3!WqbXp0#AkL({F=VY@#i1(k79Hv);CXhAgxh;eD+vKU(P48JpStN_QpBYHeur zc8%XCY)tu~f30s_(i)TU-g36(*Q~yM-j6IwrNb3#`_@}v!_L}BkURPt0+a7)=4m&I z*{*f-ySg3b$>3p~54P9bZVR5>&+$_n7kf-k!*1#}qriRD=b9M8+;;YD`W2ya~TWC??i3U1Q5fq5L_x z_VR;p@}jfpJU()>LFG0|68UhE7h_3xd7AW=q`R3rO&Psc<+$ZCOfO4F!AK@uLEzbr zt?!cl&$@_H`Wu|ZD1=7AZy)Sj^BhvN(bqr`F!~0YfIn&-;z_y~PBdx{i zp+T3Ci*m;7d2NzWW*%JLZ2A69F`~HBsbq^eI8B3+0?fw`C69K!UDfU<-b%adW5Lzm zxQDHUNRdlR6BjGuBNs=^H8QOy;jPOZT!{0gTn^)2tCsZ$c8mR6cBU{sCl*a>M(XS4 zzBmbApdhVwRD(JsYSJxs_XiP(xgi zqF=oxEn|R93uzs7Ok%4`zZ9Wc)h=bXznn=J^_7{AP9hhGEfHYAe-t6<);L=y+%>6Z z?@gEmoQ(bMXQV)p+0?7jI@m6=&&k+D?D9N7`v86rjjPvdI6mf#X>6gFF&IlqTddww zRFxYy*yY1sr@GfWLCxr;i=3F6657rBeIj48Udr*-UFVcFu@j^z=3yqoU@y5ndA~F_ z7zHjkv*aZF9f%+j8MU46K9%G$-Gp=m&6ty2#OyG3IOdibJ#9a!IF=H7Ds+>ZRb7&Y zem8hL(a@m0%n_j72gp;_Ac}#>0Is=1?eJO2HEW9oOpU|4L)}aVJQqCQr_=^qKt&{m zM=PyyhLvO|2jI6H@Y=>9ZHI)%o-odU>QV*i9BiE9GS!qBY@B^&VLvG}blOBzA&0HR z!-*OC@CTcLJOi#hCNcTRC5vlD;P2E_}jo926~kmXbW z-t2Ky6QS*V#y@+7K&4W38JK89F`+Y>GZsok}K zD2ElOEB^!OJ2J1r((78zxWoCSo9fJO+usp7~%Rzpo`OvCy1ZQYqZ~l)F%rlJt;mmA%OQi2$O`Z=&rXJ$p`hXUFvNxazQI+y-9)k z3I`4N8Kl!FVpooDnr&Fbl;NiBqJ)>&K*EZ6qA0Yv@2P1Tk_NBY0yp^)=iE#eg~$;e z)^G}jT$}r|I5YtUZ#&_By5n^V)Q=?psVH|UCJG;01W`eY!C`&bJ#2GB)Z_R)Z@+iIxX~rfOTyI=8r6nVG zIxDRv^yf~g7O!d>HI1B!}a^wGby_0SO-9uJ&G&zXhUG3MV1y%<+P9 zoUsa#a1w<_KWED#Lv0sTL46eW(IYYuws3ZG`8=B!#V(k!Nz>P-jxwV63R&Ou z#qF=dP}$r2YcH^8nX%Y_&g+15*&t8yBnml2@V07JN+C<;maz;mfg$~}#NsqCU&w1YWW1J)NfCKG ze!B8KJX~!1o zo{L9PtZZqIROO3cmOB|5aRf>;Tr&^m^^}RBOb_g3;V02Yapy`>2M=a{6oN`aGe;|! zV)wG|?k)8K_0PFPr5`)ghwOG39WaPCV;Z*d8f@hL*hIVx;PIc=Kb{Nt`HtJ%BX%lPVtUg%xKE2mKfo&3bb~ zw8)2P>m?lc;vtKK8>Rrih&SP~1ihc%b|ov$9Z$J0p_znA%oE1waS9Q!+E9r*c3*-t z;A1G#!J)r-SHRTE_W_b;7Eu-a<%n!mbCk4abXC+T_2#x}V!Icwy7xgXoj>>Ae1?j$ zU__BD1RleY)!_2eYiX3BOy|rKKOE}XCA~31#-JLo1asp`$9*CGim2v~ zn?-jNDC&{`*ji(cFY!*ehyC3^CtYJLof7nOtudmTX9A-y6;_US4N1xtAkl?;8;Q^Z zbsgH1Eyl*JE$5a+6XHA)c)Kzf+d{dHH2!4Jhv}nYDy1qu^-*yW?b?kj5K+}8|Dc8t zsOrd#1=`_d#ZZHXGWs-42FCvVM0O+^uRae0;(^mYfeIi6BCwe{P*?JJb2Gf9;>-Lp z{&k(!&ja){ocDYmhDW_7Q_;W*QlD?Sk5fxi_=#Nztr)iQ@wrldPVd0Ae5x7SWwE8W z(UovIieE1d0$pJIDkTs|iKnS&^k)?Xn}f!1MO(2i+0p!X}?Rgc!s_i-CzRSi-<)_^-jom}XY` zpEpzYn#N(a#ZO?P%Qr2yLbNa%%Q4!SV9f|HTk_XA#Gj!wngpF3m(pOBqbgP3(sljf z0LY6~x1O&?DdTKvvu#5dZE1 z8ozFWEl>6wH1GyBJenE(vmQ`?W^Ebg+j3FIH`Tb`>npM+Xk>HK?~ z98*SMJIa-gkp0`IaY@F+-u?VIb;8xy;`E-6qo)Mn*yY<5TB$*j+tr#P3}twehU5i* zC=QQF0ApI0rN&WTy)!+Hv8+Yl1oc+&&CS#IM-eR4Gg;D@3d^{GKBmN0)2x$#*Zq-7@Q~? zG!7JA`t`cvVE0f?Dl3t?dD(fA;Xa~#+zC#cM~-NcbkXxoyQ|XqaYnElhP~~u(dQ$^ zmv<#cw@#Dov=x9vt!_$JZ#>Y8o}b&}=uk3kZt-MetCh3#I~nSJ)wx79@NkpKr1O`m zW)9u}HYJ(U=eJt<3KYQsM0D~#pLc3E2YeJIgUE;qqnT?=hCgkpW11dEur#E8l-L0! z1#LDu`te>zPB%z?Wx@8}JC%yukInJV>$b^n+Daf0LTrq4;!Gju_CDtHyLX%P^ZV50 zC)80xD%w+PKIv?Vr6L1!NKD+6kueHD&)q2#MIGG_j*nVFG<?M5nh91=GQZ`-qAe9H71Q(`_a~(%QDo&-g zJZPb!j=&TaF3XP~aB&hIzIr}|joLi{OGg*YNa!YOwm{f=`q|TgKq*+Ls)HTJJQMvK zV>+CLJ{pAp(JKjU&jp35gmF z1NVUq@h;xH*ZUs+IU))<$#+(=nnElzt@xu`+=g&Kc7iuUgY;3~ z2!Ykp+pKpYghgu%B;<)go=Dxnyn!-5DL?&e{;5=NM4>zwmYtZqt`CTCGxVBSu5phr z?IDRq2L!)8a+7_BHyC1%MS15`AB8wiEJPSgxm|(aS<2yzJ+NuC(5IiiGlmgC)B1*C za`P(yZ^6DzG!f3WEVWm*wcGyPT@*i0ns1=B#5yDkz{w}>a{_ND@Z!P*h{&dj+jbPgMnDKaeu(vx``hu9h0*B$wp?B?M zSyQk%y0hHCm{X#>p9MRU6WZSz2;^)qxm}3&E!Hf=Egp0*xE{Am_EY`H70jFYf*7z) zClp9Bu)v+k?SMx|Bu*Zb^JOKIsibSP@u3|G7gX`Ehs-2IM^0e;iM>TUpGq8>wJ|c9 zxFt-6DV>W8i3jYDp=eOi>WGstz}JT&YQZ{L`niD2=b|HgJ^d|Co z!9!&q8*7C%e)`7VWor<1C-nx^qa+5^r&yM+p|r(stA_$YZh;hE3gyzT3#gn#;a%yN zgX=yZIc|}zAm`Oys3ruU^%6-sPrS(p28z2>FJP#ViVoe%f3j0)eyH@?ZObV_$% z=23H9K@oKvjP6I8)@(t6^j$r?5V5jXmTsv%YGOi#JBIkk8U>en674cV2Tj{Pla<=W z5H9=K5_F&mJUJo{{j3uwj)zF|57>au#vr%>kAe+hMj?@Fi^omaPi&s?*YOt9?pvm2 zv-ZS{?PS^6Y){vY5;Q1m<)Q01lT1Etc`DaT4k-CC&tf%DQJVq}*52n!1Y&mzp0%cQ zTo&X4Z)~e%DlMLj9;ILmgO4&Xk-d0_c<_H-7r6A*ssh#{my`N%J$V;5S-9SM^S*D4;v zP6RVL)e*0rv=76{?|KN+MR{fN-_>bp2ZLf^VrLlH)~R+X?_c z1zSo=s>(@9{v)voNoQvG#0$%Ii;?siY1C5TigSkXnHDPJNlB9wL`YYvE+Cf)q#8U> za#_l%8<4=w1qP8vY9Zj8e;_r06F-CLnH-dxl$L)oQn$d|>~s`eS@vFPg$edbv()bA z%h|6>i|Eg{v6Dt_rHb+mrpQ$=ONp0dGhGvGJHcE#{E%dRpZ(~3RqPoF1r_d*Lik;& zMOmoTk~rfwTv|IpYr}a1n8+&oG~n91$vY+wuRmg#8<)gqfyzJz>%3MfQE*l&=>~%J8Y^r(U?;D5lH?Tcc_w} zKsg6bz`vsw06%{n^xAo9SJt%^`~@clDw8ed5(pja79ca~*cMCr!x0)bJK$~WcEwCU zn#znbSolO@*m+xRuzI93;UOma<+>U=1&2O%pF` z6Mj=FQ4wSz4*>{(E!YJ_;bCiI=PckMO!XJ80Oa~lF&h=dUm`Bn!c@9SsuYs;PGAZy zRxVa{7HJPlHx4QhWC|fCQ!@c|DVe`RKz<2RS-7}32(YoaySuZxbF$hynX>`;`T5z{ zIoLQjSRfKC&YpHIAP*KhXX-x?f5VUhJDWIJI=EQc+fn?%1R2}Ax(HKILFy^~p`WdT zlF~on?VSJ40)!7X50C>Jkd>Xy)|TzxTR6K&yFozyuF(Irg|j9kU(covcD8qQG674w zf$dzV{~f~Auis;pPLefVlYiSh#qB+${X;9PBJ0ZVnTE6Fv?u4ql#rgOamzb^+O$fd4>2 zz*#LJIDDp@9H!i+CM;ZLoRAM7Hx~1IiTS0+Ir`fFYpl92^2b$ctB#gHwQ;UjPVXVdoQI z|2KJiQ%f_?|2OGB!-qoXZ%&uBbcXcr`B%~3#*_xw@o&HW_S44lufaq?@z<~r0Ga&F z1ZR*N*z_+wAy|K_GO+;JnS&wo$KM0?ALW++mtZjC;Nmj_b8@io0gZtyT$~^v3kVVo zELDd<1d z{r_y<-y`Cm<_WR=nGpZsOd+=ahr9nK@NY9HgqFXRL1t#iM9=omnf~v5{h3q$7yteq zX8(&lK%oEI$^VGo|I+ney8cHD{EvkH8(sgU>wm<+|48`1(e?iuUC961D}wDHH+b%l zogkJR@^{EC65d$hofP2p&xVqd{?jGo3&}xN&l$4y?D_MCN`Cu>7*dGfBBvycu!D+) zAczWMoZJEcPypnl#5Fw@j(yzylY6gkoX1AIPk%O7R$jfC@Je&p!#xYwIcD~tt z#eIi=d?bU@`HgA_ljb*MtwIUh;f~bu^g zl4QmWG_*OH=zbLXy0mTwH905D9vNP>4z%E%E|r>=v#^BF4q|^ zhxLbY@HK?O4ni72<~|6?F@{|$;vH{j(>9}HLRYoYUl8{^Cu{Y#+~xsLh_a!Z*poV< z!$2FWgeHp_iswQXCF^Mb5CM8M9%+zgJG_V1#U4r*t50aC=%`NS^Qsx~De!PPZLc!F zkaa;{5ny}s$PB>^loS^ho31ALbW_>`^yIOWQt@I;6Q|dplATi$kDg_ z;$lK>>%A`NVXnvTN0y&C?)z8bUEfz^eefiQ;@F1nIS6@+G!gRIA0VtJ=N~Ml&MM|h z4wX>EYZfasgZ5GL)bK;q4+r#W5SEtqdHxEqnmvFD7YG=c8*c}82-?5Tx-A)>6MpCd zzB6#T`B6+kweh}h$y2(wx^@9jd<4F+ zwwg!TmEC7PApjM0H6<2Y7~ncLR{|g|4e;k_z0%e>%@E$mnEq1k{Zt@Q#!Aw3w{x^U z{sm>io~dUOfIJboJxn<2xlv$f%SQI#Ip%Ed!a3W7C#j-`T8LPUAf-Ey2!y5r(P38T zue^HY2p$25{bgv>aHZs7{O2R{;D3;}BO+gpekH%L@EEFkE6wFa+^vkeu(44s3jJ|b z_-+R2z<_-x<&Z2CONrQLeEYQ+Q!~zQD`OygesueKY|IWn8{E)!rpAm?g!KN^TGad zOek)_!z9|`wd?WL$-^*|u?OSjO|~12-N3qb(c4J1>CkqM;nZedX8_!uw3zF1-uMl* zb@wbj+ViJpXL~nm&l@&;9~FPIF)NjxwtdTf7M=5~RB4>t?Ne7>o52220(X;fvP_2d zkLUpI17XG@weu}4wD9!f(~*;vwH}kUg@=d7R-#NEQ${fvC^I}d|FmSCke$h{!y|=HNY%(GEPyoC1PrcOn#cxkPJ#D?|X3Juf$n_7a#Gvqhu(kJ{C>vx` z(XH8Bo+l;FavAwDw1pN=&m%9N6{Y6?sVtql(qm9Qlf!t3^z+S*`$+yuYm*vCoH8sN z3VhyWn4!iX394&-cKi`aPu8j|6%D;}sIzh~c{E2~F>xW>{UG{!&EN={IA1{7kqC!O zV!NgKX=!)7aC_jmA)Q-cSDZx(o9oBbQ8)_Nft~i&<;MH8AIy{;oQbP1C-k;NnL-}4 zh*@IBzrA>v0pStyGNY)Fp`%%CpYA5s>i8)KL0k%!qJjy!klr{T0U;hsDp@K#dhurL zNEuCq_$Q(&Z5Vs_)AhHxayU(C%|-NPhn-N0v!L-RwQa=XPLm6m^d84%&HDZh;gr^d`qeISwNR@_1&b+GyKX6oXX|b5MsK{C zB!!eqq0S&Zj>h7Lelh7yx-igYxe(l|pe-viN^~IIijRwliQ!r3rFM?y2Xxr3yA`p6 zDg4Cgto>+ao>2pf93YV@wP@%&))F(9A!@$8tb%HcHQIFD^hF^e^3THX{LaV76LrDW zqJp-!ci>M&nv~AUb5G76`5(vIyCWu8Wfmp#g!C-;W;>-f{zHGdm_EaY(TRxoT#O+7 zd@S7?`4E-P?Q))g>y$I-H?aXoJW1ngQOkSik%DC?VT$xx;Xj;KX0oy(pYzK^Jj&zD zBGZ_s)mf+HW6hk6a1ICsDQ4EMG>T=SpBOb(^~KiuDE&zB9!Q_iB~IXu38WaD4JF63 zT=Z$h065HtUH$-eAHO*G5*uG!$B;K93?gD8iBT0d*}gAVZt&gs@HrgCd2 zm->hpRmi@k*F&g=<|LZBy5e1R9ZTLorb^d=5x`rv=%hAWr}To%fX!IeaCyEtWVRi^bt;qb*Lrd1IOrK#Dpd!MI3IKc;W_Q(HZmK0L z&d1O$#B|(QU(6mWzf<%zB$HVdyk?_{X+__U!JNm377IZ@1e6nbo=Cp^F3fecQgC>1 zWWPA)YF%A&nflhq>#WYaqI3xlu*64wC}#oS`5PtP`TVxTcue-0;Eu#2i!YBCD<-H0oNbG5oqC^ zRjF;~(G^Lx>)lxJ5O=qCxNEC$>?YbsX@`dfN_cbS4??6#OM+F&ImE-{_UgW#v>|qg zYGyo#Gtpro0Xha2KMPY16@R3~Msx(wy*1TMl|>^YSCE?|EtxA+NRcyp9$`UEv3K89 zm<7qa$U}40*)1=?YH1_FShb)Z{|qUygGZ#0NL9?4%UQ9;9mS}b!!^FW<8tecSn!ptN>}$BSZ~{f-ww;l6{MTmN z)z_g9v2VpSDf}m+W80VJdNwKhH@=1UCeR@oY;r1p5FZ&*Oh`yz3XQfgY}4%JCv|=f zR^y9`f9{y6!i7#^R?0v&W*wc^)X3P3%KC645dyWnguXkIVmg4PB2=uJ9F}wSD}kFO z4GDZYF1|3>->Hv6MRB^{4pPd)1NgIi<;}CKHj7`gSqvVz^h49?;Qzc)FDf;J6hx7` z_d9P{297cQ;KqH|%z-)Xp&xAlEzVyT8K13UY*xN@mIXP7s>8~=YukFm6eb)z%Urr#VJ?Ch3Dh1M!ctGlrr(gRE+-Z} z`*=Gp&gp+dxcPJ8N)(w^nwG+2;eN0sg(*u)DDt*$cJjIHhD=6NR$9>%)|fBC{j3im zTVVY}FT3_tCEMip`MYvE&tGt-Ff`EcKySK)Jr!+}wM)_a7JlMQDj0VC(>*9+Tp5jN zjVikr1Jmf#1Rq`2APDhg2L6RL`ANubpEzZ|Dc*;q3yvjQ}0+)VO*{^X$38ru79)xV>(%Jt!DQeCt3@$C&vYs_(|84Hm; z5{{hxq7yNIWu>9<4W@#ARJ~YdQwr8U}!>0vp@o{8Jx$k$vElo2x$A%+EGej zxdyZuOLWwhZL;Gqyvg>)!fT(OoUjrj9z$BD16D;|-Tcg7D>ND-o`{F3n5b9no0N+# zS@>8M&`#pe_Zb@(y2g6!39s0<)nhz8O^sTcm(wU&(NZrE(FzBaVSuZ&JqXdD(o9kk z6BK4)c3M7eZ_xM>*!tD^t3L5Zb30Z51!R4{b+?AGSmsyXW%U(-a z*eqoxMXA0-VhHP7AO-9-@`Yx}EGyMDcy&kXhZg_gJi&bJ$sznT{Pk)+`$ChEpXoRO zFQs))lHBJ^s6r|=vadAI(spK4V!s^j)hyAIn%9zWOx;_a%tYmAHpq8Qj_)O*%1fGR zR?gQhGT>heNB_Exul{SxW|LvQOD_O}^t3UrbL%9OWx;oKH6FeeCL2CLOhrkhf;rzR zA^wpuR&Vkm))2Y(}vpn?cH&`dY9|u zRo3Cgju0dQs*#7q($fK>b8{iGeqxpJp7VAQGDF3?oE)XO8+4!Nf$1P*JQf9> z=B*4B1}qAdo~*Rsa3M^&YXR41KL!7z&POZPZTK7t41h5PQfE9?P&j{t%*DyAnfv*m z>5!mx-Ak^MVh(h_R{f!DPgmMnw#;=DQf%y{4A{;3CY-IM9w`WF?JDi`6j-IJ*P0mn z-tfeUDLa7@b?UV1WKs@I05wMRr~)93u%(%nmp7FR7lv!<*1}O8OM`Vz6?-yMO+U-5 z_Y0V&NQKBu5ph;_>qa_iOl;&m={&x2d8CDFo9X@Bi0N?^QDC202BY98!Hg?|j8}V|S=JA&ukce8~a-skskIqq0QR|BUR!a>c zN-;HFKBck-lv_`~G9(=_s>flirQu*)$K$_|pfYYLp1&V^m+8YnxLQ?mrfB&KYb=Dq z%w=y8tT&i`J-Q}r@8_*enNc5IA#l2Vt`pO2w|YY-%C)^>PxfhtS$C5t>(eLrsQ4MT zGMI{bFf0H;K*IM~*&i3ezgrPX zvhO~=k(do*^jm3iDq5^^E6|{T#lWI8b&wUaNF~J#;kVZLCG5TRt6pEyisjy44mz}2 z(f2pf^DdOwrl`T$(o2orc_WDaD%(8mQ-=doqOQUU(Ny(2Lm%t01ufTb1}pOIammR` zMvN2P<|*3`jWeX>TWqI~-gBeb#Ly0a5Ljg-%=s4+8fO|Lntigt;Zp_XI#D;|mKnqIK?6Fy{Yn2`iW$B@n2V5hQ51sI? z90##;xsD6$Yf!=eJ{a9yJDN4gGc1@#{E07+RUyIq1#vOU*4B@7)y$K%Lf*XKq;h?Y>^BmRReJp)? z#pU!jbxM}_0ZAh}lxvKpu*8=;=G%}onDrK0m-Pws4;)3Ctm8!Iu?y)JvNx#2k&|`w zMgnhU8y?KFA1ps^zQZDntF;Q^8_-w6!!3TjD4~ViqSp}lv-{!SYsF2HTI+PulJ>p8 zLYw*(2i(2OCvrax-oH+-jc3;@?yJNZNuPehI(Y5NZ7Kru^D_B1rdaT*M&$!ll~IX! zwyYO%>~#5;6_Vc{_Xe{OJK)I2j-iPY)BDj4B@Y@5t9gF<3^(Cvlz-(SdfhCfn9M%O z_L6G^IAXv;5;7T+?Q=TbkqS*+-X8c)d#*q!)4BKLF4OEslXvdz=^rS?dS0?)psLPo zn7JD*_7I8#mvmMSCB;?scayMFy53@k2(!c&GH^WHJ}~KN@8oq)tRlq)gXN-{+`5c> zIm|o#oE_+v1VLWU+L^R^+Qo2}yS!SvTzN*fX!qnk3w1k_J~{!i;kwDCbPAEchlF@h zFJkKlBRgW;k`#FLcf}H_1%WDUd#Z=O1FTU*UoQ}UrdZvaw$rAlM?1|`tjUSOP~Vvo zK-hZKX|^OrN-UsSvFz;6uA5;WtcAbT8};96yAeP2Y8L?qDA1UWfO%gnOg}B;)vp+D zI{)!8Mc6jMWS#8nRW4*CsY17L7 z2tO>qJlKCUBPTd4tGaNedkyxce`*gc6F`y5_c;F<+8ghSq^N_BIi0ZwD@Ujh^}!Uy@JT?l(kN zw6)`Qqm|C-WY5!r5Gq&{-zDB z9I{a~%zIymJEyz7sAS~nZ+gUy{j$l)r*WFi1*KZPn41R`7M_|mfPwkrdqG--4l8?J z`B2k|xg`K__T%%<{5mmfgyu>El&==Q#r_CM!=k;8iWJJfJaG1BlMS^=22>jO_mQ~dc{?1`I6)!5 zcz|c4wWuLEbCMxWu^;6h+Un)PdyQ8gJvq{PhQPzG`?sh9W|erjxLO6o6}p&4LQ3j=fClSJ&%y@Pw#O8}okSo_MB zJQD#oT(pES_9zH5kS?-QRPNJ+1z=ffeW!^F8x|3$NqLZGq{=`DL#wVu8*!0>)iK$M zFX6KK_JI)!8jG?J1BT1n zG3BJilvHZrCyC;N;=KtWSQrG64APY1j6;6<)ynWGepOLFtG^p5ntYG;Ew#=rS3f&8 zq(9J<%9RqJV#bt}VwAr_ zuz3IU63CAy4@;|dHWTiitpi3BHQ7)hxj}s=r}rzsWjZ^XNQ%dS1eUTlkOunjH#}%G zG3G;&ggnz(oJCq5&UQy=pk_GEnJTS+SneU+NGXYUD!~XUodWlvcKt9Ov&nFdsninA^L|5#!yU6b)9hUyoxy8{1}$!Z z61uP_vmQ22%T-G(#xk6?ni~DY6S|qZEM2BYa-l(NVFWUbygr3>Uwrxll<%|BcsQ&VvO+V96z(5+nN@5uw#Xg9u}cs(DV z)G7-)#wTS@|GwNex1EN+(#zX^o3r7GvLI6+l2hd4RSqMbmIJF!rEaX=jcOL;A6*F) zL9|H)IUaj|v5&|xg#*NmAze&kaE5sA_4&bw#Qh4_=s6 zk!AAA^m55cQHBnFE^#LM?qc)E9h7(74zizTsE((oG)@(>@l^5kWnT|PqGkcW&LU%b zf;RO+s9s|^q~=SI5w(+3QzgG&L|qj31b4i3EPc0Yi(ETa!ss3%UxN#uB!pdc^1Qam zO8A4MUIH@Ux6^#qTQTYDZtRtxo%*LMu53NlCqm*MBN%p9`eQ}#h|-0d_h6K(l5uHU zml%qp)+eZi0XVq0lx%FL&8{yPjLunl&L=)kdwn_?qDDiU&o-VS(A>|GdnfJzF zIO`UIO#h`hle!}JVKH#&nY_eu2yu4wuIJ;oBPpwMp>Wfpj zMBV^g7@Bw)x9@OkEczSG{SV4OhE*DKGqcB*AQg`rhb24xcst)ULecT* zVJE`~vhc6#>}Ec|ztg(PpY)W(Kk_)}^*s>wK2_RO@NMqE*xy0OBC-g(D%r8MnRWup z(Iql4F+DVoIBMOU=3S)D42?*6c?q;ZD>jevukRqd8A3k<0MKjxJPVLT^!ut9a!8fj zc0YXS69vqQikHEE+Hvm2fchxrahR6YuBf8Y-!UEQ+xoBu^;HVCn24dxxdVWE4kgy% zfQs?fGPRnK(_-35VGD~^6(>`R@;a9(MRqum{4%TS>9pt4n@QmLWq)&O%34-VuSg~I zo1=&+roAResyEcyDZM+D!eZG;MQ^OHZ{;y*Eo{ddcZjKy!eKCi+Z8GV%6|`ke>%hV z1LRn!T_=4n+m*t<{qZQPOTy!HvPQ4Em~agv3#!g$1=R%A%GC5pVYB(vTw{8Qz0x%g zoFyk7eBq2Jd%Se=o*|eZMhwgDuBi$5ow>ku*uEU8rAyCB`isfP*Wik!-c1(86VI zB8gjDtag1{^TxIfY-S(bDLCHhDzW{gLbmY1q%b)xJfdqzOq2Gz;qwE;DH6G*sI;`S zzq1u5weI#OHo{WU)6*k7i)5Z@o9aq^I0`NGm3n6e4@giqCKvV>}f+rKI}q z@vEunTsR3abpR3s^4@R%h5-F&$DX^ZQ@<^ip=W^s{xapCuH3xfaxz;Jw!*3fKu1-JYBgWaS4)7c=k z;h@iE=4^suI-YrEo4jV#&Nuo8GRJw(NQrYPDfW*Zk^^aOx93kE&SeX9u=L9yPfuWh z!C^o0HH%&;g-|r3)F5X@V^JDK9E_>bVKvvOpz0_c4@6B|DB|U_J{IM5hxX(ajMb^QgS0I{oyiI<2-a^YEqYm|Qf6!0?FhhTw38L5DQjMD|&} zVVOV*x`0})jVaLdjn5AG2x`5%{Wm3r3Q8(P!w@I}T<%;esbBInJG{sQ5#_fS*z4Ey zFK&w4r-VSq-wIv%_t_)%39pkGeM){l2Ue%JhQjur4nj_BqC&?AwV=Y*We-2J?Y7IbeK0=3)bNM56 z_o-w#>~6`4C^|9MrmI;1D85e+`1=Eh`Ms#fUx`&(1R6Hn*_!W*(-;Hf;KfJu=os&8 zK$3N{bNuD6bH(x$;ByJ%vKisS8Sq$0DL_&42TC6idGX$Rx$>B;*HJ3SIe~dkoCh}> zo1t{IB=)_h=Oh6w)+%vceaEl&MTJ#;B~0Ono|se~GtbKvUyi+wm))o&Ow%+euayZ} z9OvjSzb1WZYw#VV_O>S%*$>6;Y`yTkvC74tm3@Ed zo!QfN>5#Yow7M;(X5;f6u-cAXc>AjO`t@5gdV}Rd1FyD9mYY!6)+p8&Lr-*v`!EGV zL%&y(cSXRdy{=W}o8lftd7B=1NBqbFk6{P@Lal)lxJV*QU~n3Tm)kO-mp%5N=|r*C zBMspBp!(iW^O@|FGbxT{iY8z<3Mki2QY`Cq5GF_cGSB&y+`C9+<@s(oKob5%z=bso z;k<*$TBG$S8k@EWm2c=SDd{Rxuue7CA{JJB&3KkBTz07LxKO)VXU={DjR?m}D}X`b zl))t{Q=!tUepbb7~fa%#BOBlFFh-f5BV z`n6Ry+OK#F6SK9f)J0f*rbE6!p}XE&+fe*2Y&`26!cTAP7>yR&|ahqRiWm7XOd z-q?pF$G81c2p?Qe5Z)Vkv|2lkg^twBmbt0*&hyf$U3Vd~6^j&rg1VCE&~B1!SJP4! z8rBW1qj>u)96@BqOPRzo7QbnHrJ8RB16kfjZ04v(^lpTrC4d4Ehvs>e8*lov?v2!^ z-kT}<_VD*-#u9x*hWrns`S+^-Cn*Wm_6TdEz%Yp_ppw6AWgS(L)Xr_U!+G%n{^h@$zxjbDkFI^u z+4H9kn|N9k%?^Exy?f%DyPtTWf3vGE{3Q30zxFrQ_|{in`thyfW}I8$;kj(&WiRi1 z>w^vy1iscW1J)xVcW9YIfV^RNfMJLf)^N#+wGD}sYjy3k3m{gGiYPe;s$Me#8P#i) zt(ZH{TWe+1i1C;2@3Zc=0gRkH@~JNU`caMa^l(@1&M2{kDv3Jwq7a`%;nEeEUPMwm zb==`SL?s~-ReWNoH>zp{6cjC5+FYHtHTrem8koR8di$fl1%R8zUGuo8Qo=d2>9J=A z);;gc1)-1yF}t!dnmla$ud3*E=wtldlV7tbDGC({SlzeJywaz|rRRPcx7IU}-ah62 zivi%Wn=X4k^r6}F`Ik+|8kgRy+t&;YiO7MBCsJWzB95~$;F6VJH89Ma(XDeHn-~le zn5=+ERTOpV*V8>kMZxmVKiAvF-*&+PHGr(_(T{f@c$5|u?(tDPTPW{~g-tw(I1hLg z@y=;V`!?H(SFWy`(xJ^as_I2N5?`%p2&h$1K+qtqOZ%N5CQGc3-SOCk05E*qwGXKZ zLg&nuzrHe{=2@pKa-J*z>%)+zTt9wj6}1i@jJs#@OC|^efU`zj!OL&;YWlk~=LOb! zBF0@)?z<8IF1_*6C!GpGMT?iOuBV`oqDnR{-m%?wW&LDO0aCPQuV)Uts#5@{ z-m}N1L^4SQixxKuI<(tPJ}F5ThNex+%|*+f3!_O=;+ngo(A@c(7?Vg#l`qnsg$WoU~nkmD^Us1)V!wXZc%lh58yC*-)vB2+{`9ZfD zr=9p|V2sOs_oI$=PCRCr0VA-6hEE)J$6XWez7YU^d-8zi44b6$>J;j1ht`|Q^Ea~> zZ=);d?1aTcobySIPKknGq8g+i!_3y2{S(doGXQJDsD_gX0q;Q~#H=g~CPU;UWad(4 z5(S6wBBJD(phN+fVf>n$`oe~ve|z3J7hV3_>{`v5s1Yv-7i!+zFOG1bGt~wky}*lO zRhW!Zhs-H?Z+73*;|DLRqSN6CV{B>3d$YS{oH}HVsCqBzs|`MSLEa}{w6=lunFIT7 zhzBtmKIO)#`J1=W6OTNfbsm|=M7-E`t+$GBg#(e8)Ujb^rhu85yo5}qwET!O5Rsn& zV~9wt-M`uc`(-5`zWdS4Zaq33-=t-8pD1&#yrQ22j3ZK4nzO!Eta;-d0EbKzGO;&o zys=h{F&Ya3rM$v)G;FZ-j4Ljj9ZyO13Lh4HvAALJmhIJpp54|Zw{A~IgL>bpiX*U( z1u@~KjlY?6UDh9~sC0N@_FJ>w8FI~~ZDO%_QbZG~l2k<~J9eg5>(^^-$&%$w!W}!) zQkpi(tDad`hy3QW*#&#|7TS`sv{-|B1w<^&MhvkSW5inPjS0N9?EKeTGi$VIooh_Y zF_R~X_7*j2reoFOB{F9C*y|723;+N@U>yLbsxB%zOCBr&YfyK{vCETT5|%~07*+Ku z5~XKhCRl64HLSm-O`pCf$;(#&QoLwIqiQ|7=O7WPb50ags;VUbv$d9O5VLSTsG`x~ zjhGEeZ4e7Z)j8)xRYgIiA}EV>@3yvDJfPx5E1G5W>9s9Uu$SBP?MFEazSt6vr>JpW zCAxbn%<72@8Me+C=ITR^U2d&`VFeR20Y+5?fCPcvZ(i^B=JLHa-~XWRk=>6jE862q z_7=F*>NOmI@(SM&V~n@PdS;_c3^s-hGoYR%=?E@F?Ium7VBUfTiS66dQo48j+Ievz z5{gJtw(m%@jT-CTv)bjMPr}4yL$E3E%y{|-%i99k$47btR-s#jRkRu$6`LZ+8AAOA!Z>W z-Mwv#mKE*M{GB^-^ks{9-(Ft_CeDF1HXe&vYi$sVr36ecHa*3xU+@Ku9zG%aw#V+w z@?q#RGV2I4i)B`TgqW~<#|{{4p`v`_D72obl*g!{MC~QT8eKoH#eBS4 zswFTEif0H)tRJ&T#0A(m*tWBtf0 zZ@TM0_SXJX9dOIt+2dPu?3@s#q>7d~=aLE+ih8HQ0*LPZ;KL)*2MpM9^|_ZmT}7Gy zJv{L2W9Jvmo7c4VkmEK09PM$*Sb`0#wJ~B!Vba*9uU5oI4f|=T_xz-%DsR7M+UO=7 zx+GM6srQmpkx&7bw{x3V6Q^r0yz<#9n*8tMz9%0#*ZG8I)@u}%OJWX;;TVyrwsqC= z_)XW3nf_Bf%TIo+c*cFV+@yxfjNyb00w-+z^%q_HWECxbez@m}`z~bh#)YBvUgG2> hWyH0kep1KB{|Ab?iFf`Ym8bv!002ovPDHLkV1gM)d*T29 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/megamoth.png b/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/megamoth.png new file mode 100644 index 0000000000000000000000000000000000000000..c46815be6daf4c61265301b7924806ae0b6dd96c GIT binary patch literal 14130 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/megamoth_open.png b/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/megamoth_open.png new file mode 100644 index 0000000000000000000000000000000000000000..76cfd53168403567647dcc5c33ecc9f66579686e GIT binary patch literal 15775 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/robotic.png b/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/robotic.png new file mode 100644 index 0000000000000000000000000000000000000000..073c1f5c4a0ed6f53692362ce4d6e12a126f8aa8 GIT binary patch literal 13347 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/skeleton_open.png b/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/skeleton_open.png new file mode 100644 index 0000000000000000000000000000000000000000..58357ab51de7ade59362da8452f096fa74dc7634 GIT binary patch literal 10255 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 Date: Sat, 6 Jan 2024 00:23:00 +0200 Subject: [PATCH 20/59] Fix Wings sprite bug --- Content.Shared/Humanoid/HumanoidVisualLayers.cs | 1 + Content.Shared/Humanoid/HumanoidVisualLayersExtension.cs | 3 +++ Content.Shared/Humanoid/Markings/MarkingCategories.cs | 2 ++ Resources/Prototypes/Species/human.yml | 4 ++++ 4 files changed, 10 insertions(+) diff --git a/Content.Shared/Humanoid/HumanoidVisualLayers.cs b/Content.Shared/Humanoid/HumanoidVisualLayers.cs index 938b789f7a..ae8839e59e 100644 --- a/Content.Shared/Humanoid/HumanoidVisualLayers.cs +++ b/Content.Shared/Humanoid/HumanoidVisualLayers.cs @@ -6,6 +6,7 @@ namespace Content.Shared.Humanoid [Serializable, NetSerializable] public enum HumanoidVisualLayers : byte { + Wings, Tail, Hair, FacialHair, diff --git a/Content.Shared/Humanoid/HumanoidVisualLayersExtension.cs b/Content.Shared/Humanoid/HumanoidVisualLayersExtension.cs index 0f8b940bd6..cc0a06f32a 100644 --- a/Content.Shared/Humanoid/HumanoidVisualLayersExtension.cs +++ b/Content.Shared/Humanoid/HumanoidVisualLayersExtension.cs @@ -61,6 +61,7 @@ public static IEnumerable Sublayers(HumanoidVisualLayers l break; case HumanoidVisualLayers.Chest: yield return HumanoidVisualLayers.Chest; + yield return HumanoidVisualLayers.Wings; yield return HumanoidVisualLayers.Tail; break; default: @@ -78,6 +79,8 @@ public static IEnumerable Sublayers(HumanoidVisualLayers l return HumanoidVisualLayers.Chest; case BodyPartType.Tail: return HumanoidVisualLayers.Tail; + // case BodyPartType.Wings: + // return HumanoidVisualLayers.Wings; case BodyPartType.Head: // use the Sublayers method to hide the rest of the parts, // if that's what you're looking for diff --git a/Content.Shared/Humanoid/Markings/MarkingCategories.cs b/Content.Shared/Humanoid/Markings/MarkingCategories.cs index 5d407063c2..285fb428cf 100644 --- a/Content.Shared/Humanoid/Markings/MarkingCategories.cs +++ b/Content.Shared/Humanoid/Markings/MarkingCategories.cs @@ -14,6 +14,7 @@ public enum MarkingCategories : byte Chest, Arms, Legs, + Wings, Tail, Overlay } @@ -39,6 +40,7 @@ public static MarkingCategories FromHumanoidVisualLayers(HumanoidVisualLayers la HumanoidVisualLayers.RLeg => MarkingCategories.Legs, HumanoidVisualLayers.LFoot => MarkingCategories.Legs, HumanoidVisualLayers.RFoot => MarkingCategories.Legs, + HumanoidVisualLayers.Wings => MarkingCategories.Wings, HumanoidVisualLayers.Tail => MarkingCategories.Tail, _ => MarkingCategories.Overlay }; diff --git a/Resources/Prototypes/Species/human.yml b/Resources/Prototypes/Species/human.yml index 956c0d1946..c4115aaa97 100644 --- a/Resources/Prototypes/Species/human.yml +++ b/Resources/Prototypes/Species/human.yml @@ -30,6 +30,7 @@ RLeg: MobHumanRLeg LFoot: MobHumanLFoot RFoot: MobHumanRFoot + Wings: MobHumanoidAnyMarking Tail: MobHumanoidAnyMarking # Nyanotrasen - Felinid HeadTop: MobHumanoidAnyMarking # Nyanotrasen - Felinid & Oni @@ -57,6 +58,9 @@ Arms: points: 2 required: false + Wings: + points: 1 + required: false - type: humanoidBaseSprite id: MobHumanoidEyes From f4bc63e5a382d5fed765ccf1dd373c493881565c Mon Sep 17 00:00:00 2001 From: Finket Date: Wed, 21 Feb 2024 15:25:16 +0200 Subject: [PATCH 21/59] Fix duplicate wings declaration --- Resources/Prototypes/Species/human.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/Resources/Prototypes/Species/human.yml b/Resources/Prototypes/Species/human.yml index a3d2fc7a7f..df431bed53 100644 --- a/Resources/Prototypes/Species/human.yml +++ b/Resources/Prototypes/Species/human.yml @@ -30,7 +30,6 @@ RLeg: MobHumanRLeg LFoot: MobHumanLFoot RFoot: MobHumanRFoot - Wings: MobHumanoidAnyMarking Tail: MobHumanoidAnyMarking # Nyanotrasen - Felinid Wings: MobHumanoidAnyMarking # Parkstation-Wings HeadTop: MobHumanoidAnyMarking # Nyanotrasen - Felinid & Oni From 3bf3545f64da2fc8a39a4b58414c83b219e73a11 Mon Sep 17 00:00:00 2001 From: Finket Date: Wed, 21 Feb 2024 15:25:33 +0200 Subject: [PATCH 22/59] Fix missing imports --- .../Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs | 3 +-- .../Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs | 2 +- .../Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs | 3 +-- .../Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs | 1 + 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs index 67ea8f91fb..00cdbb07ce 100644 --- a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs +++ b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs @@ -1,10 +1,9 @@ using Robust.Client.Graphics; using Robust.Client.Player; -using Content.Client.SimpleStation14.Overlays; using Content.Client.SimpleStation14.Overlays.Shaders; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; -using Robust.Client.GameObjects; using Content.Shared.Humanoid; +using Robust.Shared.Player; namespace Content.Client.SimpleStation14.Species.Shadowkin.Systems; diff --git a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs index 20d92ae4e6..57b0b93190 100644 --- a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs +++ b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs @@ -1,11 +1,11 @@ using Robust.Client.Graphics; using Robust.Client.Player; -using Content.Client.SimpleStation14.Overlays; using Content.Client.SimpleStation14.Overlays.Shaders; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; using Robust.Client.GameObjects; using Content.Shared.GameTicking; using Content.Shared.Humanoid; +using Robust.Shared.Player; namespace Content.Client.SimpleStation14.Species.Shadowkin.Systems; diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 8522a1bfec..83747fe12f 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -15,7 +15,7 @@ using Content.Shared.Stealth.Components; using Robust.Server.GameObjects; using Robust.Shared.Audio; -using Robust.Shared.Prototypes; +using Robust.Shared.Audio.Systems; namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; @@ -30,7 +30,6 @@ public sealed class ShadowkinDarkSwapSystem : EntitySystem [Dependency] private readonly SharedStealthSystem _stealth = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedActionsSystem _actions = default!; - [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly MagicSystem _magic = default!; [Dependency] private readonly NpcFactionSystem _factions = default!; diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index 60d59e4528..83e38ef11e 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -8,6 +8,7 @@ using Content.Shared.Pulling.Components; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; using Robust.Shared.Audio; +using Robust.Shared.Audio.Systems; using Robust.Shared.Prototypes; namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; From d5b22e87c2fd711ce501694b972676ff1f8e7957 Mon Sep 17 00:00:00 2001 From: Finket Date: Wed, 21 Feb 2024 15:34:08 +0200 Subject: [PATCH 23/59] Fix missing merge --- .../Mobs/Customization/tails32x32.rsi/meta.json | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/meta.json b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/meta.json index 49ca216dbc..54066dec47 100644 --- a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/meta.json +++ b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/meta.json @@ -88,8 +88,6 @@ "directions": 4 }, { -<<<<<<< HEAD -======= "name": "shadowkin_shorter", "directions": 4 }, @@ -98,7 +96,6 @@ "directions": 4 }, { ->>>>>>> master "name": "shark_fin", "directions": 4 }, @@ -113,21 +110,10 @@ { "name": "succubus", "directions": 4 -<<<<<<< HEAD }, { "name": "tentacle", "directions": 4 - }, - { - "name": "shadowkin_shorter", - "directions": 4 - }, - { - "name": "shadowkin_medium", - "directions": 4 -======= ->>>>>>> master } ] } From 29028868e02b0e5afef0a1ada9193084ff8ae27e Mon Sep 17 00:00:00 2001 From: Finket Date: Wed, 21 Feb 2024 17:05:57 +0200 Subject: [PATCH 24/59] Fix shadowkin actions! --- .../Events/ShadowkinEvents.Powers.cs | 91 ------------------ .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 1 - .../Systems/ShadowkinPowerSystem.Rest.cs | 2 +- .../Systems/ShadowkinPowerSystem.Teleport.cs | 4 +- .../Shadowkin/Systems/ShadowkinSystem.cs | 2 - .../Events/ShadowkinEvents.Powers.cs | 93 ++++++++++++++++++- .../Entities/Mobs/Player/shadowkin.yml | 1 - .../SimpleStation14/Magic/shadowkin.yml | 12 +-- 8 files changed, 101 insertions(+), 105 deletions(-) delete mode 100644 Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs deleted file mode 100644 index ea28c1915d..0000000000 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs +++ /dev/null @@ -1,91 +0,0 @@ -using Content.Shared.Actions; -using Content.Shared.Magic; -using Robust.Shared.Audio; - -namespace Content.Server.SimpleStation14.Species.Shadowkin.Events; - -///

-/// Raised when the shadowkin teleport action is used. -/// -public sealed partial class ShadowkinTeleportEvent : WorldTargetActionEvent, ISpeakSpell -{ - [DataField("sound")] - public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/SimpleStation14/Effects/Shadowkin/Powers/teleport.ogg"); - - [DataField("volume")] - public float Volume = 5f; - - - [DataField("powerCost")] - public float PowerCost = 40f; - - [DataField("staminaCost")] - public float StaminaCost = 20f; - - - [DataField("speech")] - public string? Speech { get; set; } -} - -/// -/// Raised when the shadowkin darkSwap action is used. -/// -public sealed partial class ShadowkinDarkSwapEvent : InstantActionEvent, ISpeakSpell -{ - [DataField("soundOn")] - public SoundSpecifier SoundOn = new SoundPathSpecifier("/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapon.ogg"); - - [DataField("volumeOn")] - public float VolumeOn = 5f; - - [DataField("soundOff")] - public SoundSpecifier SoundOff = new SoundPathSpecifier("/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapoff.ogg"); - - [DataField("volumeOff")] - public float VolumeOff = 5f; - - - /// - /// How much stamina to drain when darkening. - /// - [DataField("powerCostOn")] - public float PowerCostOn = 60f; - - /// - /// How much stamina to drain when lightening. - /// - [DataField("powerCostOff")] - public float PowerCostOff = 45f; - - /// - /// How much stamina to drain when darkening. - /// - [DataField("staminaCostOn")] - public float StaminaCostOn; - - /// - /// How much stamina to drain when lightening. - /// - [DataField("staminaCostOff")] - public float StaminaCostOff; - - - [DataField("speech")] - public string? Speech { get; set; } -} - -public sealed class ShadowkinDarkSwapAttemptEvent : CancellableEntityEventArgs -{ - EntityUid Performer; - - public ShadowkinDarkSwapAttemptEvent(EntityUid performer) - { - Performer = performer; - } -} - - -public sealed partial class ShadowkinRestEvent: InstantActionEvent -{ - -} diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 83747fe12f..a34980f2fa 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -3,7 +3,6 @@ using Content.Server.NPC.Components; using Content.Server.NPC.Systems; using Content.Server.SimpleStation14.Species.Shadowkin.Components; -using Content.Server.SimpleStation14.Species.Shadowkin.Events; using Content.Shared.Actions; using Content.Shared.CombatMode.Pacification; using Content.Shared.Cuffs.Components; diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index 6f57ab90bc..af4f80d9c8 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -1,9 +1,9 @@ using Content.Server.SimpleStation14.Species.Shadowkin.Components; -using Content.Server.SimpleStation14.Species.Shadowkin.Events; using Content.Shared.Actions; using Content.Shared.Bed.Sleep; using Content.Shared.Cuffs.Components; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.SimpleStation14.Species.Shadowkin.Events; using Robust.Shared.Prototypes; namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index 83e38ef11e..6fa7b03184 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -1,12 +1,12 @@ using Content.Server.Magic; using Content.Server.Pulling; using Content.Server.SimpleStation14.Species.Shadowkin.Components; -using Content.Server.SimpleStation14.Species.Shadowkin.Events; using Content.Shared.Actions; using Content.Shared.Cuffs.Components; using Content.Shared.Damage.Systems; using Content.Shared.Pulling.Components; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.SimpleStation14.Species.Shadowkin.Events; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Prototypes; @@ -66,7 +66,7 @@ private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, var transform = Transform(args.Performer); if (transform.MapID != args.Target.GetMapId(EntityManager)) return; - + SharedPullableComponent? pullable = null; // To avoid "might not be initialized when accessed" warning if (_entity.TryGetComponent(args.Performer, out var puller) && puller.Pulling != null && diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs index 7963331c1b..d33a11f68c 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.cs @@ -1,7 +1,5 @@ using System.Numerics; using Content.Server.Mind; -using Content.Shared.Mind.Components; -using Content.Server.SimpleStation14.Species.Shadowkin.Events; using Content.Shared.Bed.Sleep; using Content.Shared.Cuffs.Components; using Content.Shared.Examine; diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs index 83385e205e..c3a1b118be 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs @@ -1,7 +1,98 @@ -using Robust.Shared.Serialization; +using Content.Shared.Actions; +using Content.Shared.Magic; +using Robust.Shared.Audio; +using Robust.Shared.Serialization; namespace Content.Shared.SimpleStation14.Species.Shadowkin.Events; + +/// +/// Raised when the shadowkin teleport action is used. +/// +public sealed partial class ShadowkinTeleportEvent : WorldTargetActionEvent, ISpeakSpell +{ + [DataField("sound")] + public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/SimpleStation14/Effects/Shadowkin/Powers/teleport.ogg"); + + [DataField("volume")] + public float Volume = 5f; + + + [DataField("powerCost")] + public float PowerCost = 40f; + + [DataField("staminaCost")] + public float StaminaCost = 20f; + + + [DataField("speech")] + public string? Speech { get; set; } +} + +/// +/// Raised when the shadowkin darkSwap action is used. +/// +public sealed partial class ShadowkinDarkSwapEvent : InstantActionEvent, ISpeakSpell +{ + [DataField("soundOn")] + public SoundSpecifier SoundOn = new SoundPathSpecifier("/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapon.ogg"); + + [DataField("volumeOn")] + public float VolumeOn = 5f; + + [DataField("soundOff")] + public SoundSpecifier SoundOff = new SoundPathSpecifier("/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapoff.ogg"); + + [DataField("volumeOff")] + public float VolumeOff = 5f; + + + /// + /// How much stamina to drain when darkening. + /// + [DataField("powerCostOn")] + public float PowerCostOn = 60f; + + /// + /// How much stamina to drain when lightening. + /// + [DataField("powerCostOff")] + public float PowerCostOff = 45f; + + /// + /// How much stamina to drain when darkening. + /// + [DataField("staminaCostOn")] + public float StaminaCostOn; + + /// + /// How much stamina to drain when lightening. + /// + [DataField("staminaCostOff")] + public float StaminaCostOff; + + + [DataField("speech")] + public string? Speech { get; set; } +} + +public sealed class ShadowkinDarkSwapAttemptEvent : CancellableEntityEventArgs +{ + EntityUid Performer; + + public ShadowkinDarkSwapAttemptEvent(EntityUid performer) + { + Performer = performer; + } +} + + +public sealed partial class ShadowkinRestEvent: InstantActionEvent +{ + +} + + /// /// Raised over network to notify the client that they're going in/out of The Dark. /// diff --git a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml index e96e67a191..b71a8cd139 100644 --- a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml @@ -113,7 +113,6 @@ - type: NpcFactionMember factions: - NanoTrasen - - type: MailReceiver - type: InteractionPopup successChance: 0.75 interactFailureString: petting-failure-generic diff --git a/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml index 07ff9babb2..a029e421b1 100644 --- a/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml @@ -7,13 +7,13 @@ useDelay: 5 range: 32 itemIconStyle: NoItem - checkCanAccess: true - repeat: true - priority: -20 icon: sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi state: teleport - serverEvent: !type:ShadowkinTeleportEvent + checkCanAccess: true + repeat: true + priority: -20 + event: !type:ShadowkinTeleportEvent powerCost: 40 staminaCost: 20 speech: action-description-shadowkin-teleport @@ -30,7 +30,7 @@ icon: sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi state: darkswap - serverEvent: !type:ShadowkinDarkSwapEvent + event: !type:ShadowkinDarkSwapEvent powerCostOn: 60 powerCostOff: 45 staminaCostOn: 25 @@ -50,4 +50,4 @@ sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi state: rest checkCanInteract: false - serverEvent: !type:ShadowkinRestEvent + event: !type:ShadowkinRestEvent From 19c1a4b9f078b40e1385026011b9336f77c94316 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Wed, 21 Feb 2024 17:33:28 -0800 Subject: [PATCH 25/59] fix sprite layers --- .../DeltaV/Entities/Mobs/Species/harpy.yml | 2 + .../Entities/Mobs/Species/vulpkanin.yml | 1 + .../Entities/Mobs/Species/arachnid.yml | 1 + .../Prototypes/Entities/Mobs/Species/base.yml | 16 +++++- .../Prototypes/Entities/Mobs/Species/moth.yml | 3 +- .../Entities/Mobs/Player/shadowkin.yml | 54 ------------------- 6 files changed, 20 insertions(+), 57 deletions(-) diff --git a/Resources/Prototypes/DeltaV/Entities/Mobs/Species/harpy.yml b/Resources/Prototypes/DeltaV/Entities/Mobs/Species/harpy.yml index 3b7ae72618..76c5e02622 100644 --- a/Resources/Prototypes/DeltaV/Entities/Mobs/Species/harpy.yml +++ b/Resources/Prototypes/DeltaV/Entities/Mobs/Species/harpy.yml @@ -64,6 +64,7 @@ - map: [ "enum.HumanoidVisualLayers.FacialHair" ] - map: [ "enum.HumanoidVisualLayers.HeadSide" ] - map: [ "enum.HumanoidVisualLayers.Tail" ] + - map: [ "enum.HumanoidVisualLayers.Wings" ] # Parkstation-Wings - map: [ "pocket1" ] - map: [ "pocket2" ] - map: [ "clownedon" ] # Dynamically generated @@ -171,6 +172,7 @@ - map: [ "enum.HumanoidVisualLayers.HeadSide" ] - map: [ "enum.HumanoidVisualLayers.HeadTop" ] - map: [ "enum.HumanoidVisualLayers.Tail" ] + - map: [ "enum.HumanoidVisualLayers.Wings" ] # Parkstation-Wings - map: [ "pocket1" ] - map: [ "pocket2" ] - map: [ "clownedon" ] # Dynamically generated diff --git a/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml b/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml index 4a187d51b3..890b337dbf 100644 --- a/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml +++ b/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml @@ -68,6 +68,7 @@ - map: [ "enum.HumanoidVisualLayers.HeadSide" ] - map: [ "enum.HumanoidVisualLayers.HeadTop" ] - map: [ "enum.HumanoidVisualLayers.Tail" ] + - map: [ "enum.HumanoidVisualLayers.Wings" ] # Parkstation-Wings - map: [ "mask" ] - map: [ "head" ] - map: [ "pocket1" ] diff --git a/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml b/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml index 6a92a6cc6b..a57455af7d 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml @@ -100,6 +100,7 @@ - map: [ "belt" ] - map: [ "id" ] - map: [ "enum.HumanoidVisualLayers.Tail" ] # Mentioned in moth code: This needs renaming lol. + - map: [ "enum.HumanoidVisualLayers.Wings" ] # Parkstation-Wings - map: [ "neck" ] - map: [ "back" ] - map: [ "enum.HumanoidVisualLayers.FacialHair" ] diff --git a/Resources/Prototypes/Entities/Mobs/Species/base.yml b/Resources/Prototypes/Entities/Mobs/Species/base.yml index e8c475907e..d4edb6bd73 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/base.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/base.yml @@ -27,9 +27,14 @@ sprite: Mobs/Customization/masking_helpers.rsi state: unisex_full visible: false - - map: ["jumpsuit"] - map: ["enum.HumanoidVisualLayers.LFoot"] - map: ["enum.HumanoidVisualLayers.RFoot"] + # Parkstation-Underwear Start + # - map: ["socks"] + # - map: ["underpants"] + # - map: ["undershirt"] + - map: ["jumpsuit"] + # Parkstation-Underwear End - map: ["enum.HumanoidVisualLayers.LHand"] - map: ["enum.HumanoidVisualLayers.RHand"] - map: [ "gloves" ] @@ -46,6 +51,7 @@ - map: [ "enum.HumanoidVisualLayers.HeadSide" ] - map: [ "enum.HumanoidVisualLayers.HeadTop" ] - map: [ "enum.HumanoidVisualLayers.Tail" ] + - map: [ "enum.HumanoidVisualLayers.Wings" ] # Parkstation-Wings - map: [ "mask" ] - map: [ "head" ] - map: [ "pocket1" ] @@ -338,9 +344,14 @@ sprite: Mobs/Customization/masking_helpers.rsi state: unisex_full visible: false - - map: ["jumpsuit"] - map: ["enum.HumanoidVisualLayers.LFoot"] - map: ["enum.HumanoidVisualLayers.RFoot"] + # Parkstation-Underwear Start + # - map: ["socks"] + # - map: ["underpants"] + # - map: ["undershirt"] + - map: ["jumpsuit"] + # Parkstation-Underwear End - map: ["enum.HumanoidVisualLayers.LHand"] - map: ["enum.HumanoidVisualLayers.RHand"] - map: ["enum.HumanoidVisualLayers.Handcuffs"] @@ -362,6 +373,7 @@ - map: [ "enum.HumanoidVisualLayers.HeadSide" ] - map: [ "enum.HumanoidVisualLayers.HeadTop" ] - map: [ "enum.HumanoidVisualLayers.Tail" ] + - map: [ "enum.HumanoidVisualLayers.Wings" ] # Parkstation-Wings - map: [ "mask" ] - map: [ "head" ] - map: [ "pocket1" ] diff --git a/Resources/Prototypes/Entities/Mobs/Species/moth.yml b/Resources/Prototypes/Entities/Mobs/Species/moth.yml index c977138355..6ea1a5a38b 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/moth.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/moth.yml @@ -99,7 +99,8 @@ - map: [ "eyes" ] - map: [ "belt" ] - map: [ "id" ] - - map: [ "enum.HumanoidVisualLayers.Tail" ] #in the utopian future we should probably have a wings enum inserted here so everyhting doesn't break + - map: [ "enum.HumanoidVisualLayers.Tail" ] + - map: [ "enum.HumanoidVisualLayers.Wings" ] # Parkstation-Wings - map: [ "neck" ] - map: [ "back" ] - map: [ "enum.HumanoidVisualLayers.FacialHair" ] diff --git a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml index b71a8cd139..4fe8a05e00 100644 --- a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml @@ -134,57 +134,3 @@ components: - type: HumanoidAppearance species: Shadowkin - - type: Sprite # sprite again because we want different layer ordering - netsync: false - noRot: true - drawdepth: Mobs - scale: 0.85, 0.85 # Small - layers: - - map: ["enum.HumanoidVisualLayers.Chest"] - - map: ["enum.HumanoidVisualLayers.Head"] - - map: ["enum.HumanoidVisualLayers.Snout"] - - map: ["enum.HumanoidVisualLayers.Eyes"] - - map: ["enum.HumanoidVisualLayers.RArm"] - - map: ["enum.HumanoidVisualLayers.LArm"] - - map: ["enum.HumanoidVisualLayers.RLeg"] - - map: ["enum.HumanoidVisualLayers.LLeg"] - - shader: StencilClear - sprite: Mobs/Species/Human/parts.rsi - state: l_leg - - shader: StencilMask - map: ["enum.HumanoidVisualLayers.StencilMask"] - sprite: Mobs/Customization/masking_helpers.rsi - state: full - visible: false - - map: ["enum.HumanoidVisualLayers.LFoot"] - - map: ["enum.HumanoidVisualLayers.RFoot"] - - map: ["socks"] - - map: ["underpants"] - - map: ["undershirt"] - - map: ["jumpsuit"] - - map: ["enum.HumanoidVisualLayers.LHand"] - - map: ["enum.HumanoidVisualLayers.RHand"] - - map: ["enum.HumanoidVisualLayers.Handcuffs"] - color: "#ffffff" - sprite: Objects/Misc/handcuffs.rsi - state: body-overlay-2 - visible: false - - map: ["id"] - - map: ["gloves"] - - map: ["shoes"] - - map: ["ears"] - - map: ["outerClothing"] - - map: ["eyes"] - - map: ["belt"] - - map: ["neck"] - - map: ["back"] - - map: ["enum.HumanoidVisualLayers.FacialHair"] - - map: ["enum.HumanoidVisualLayers.Hair"] - - map: ["enum.HumanoidVisualLayers.HeadSide"] - - map: ["enum.HumanoidVisualLayers.HeadTop"] - - map: ["mask"] - - map: ["head"] - - map: ["pocket1"] - - map: ["pocket2"] - - map: ["enum.HumanoidVisualLayers.Tail"] - - map: ["enum.HumanoidVisualLayers.Wings"] From 6f6a62e336888ff1fd903a346e07a9704db2273a Mon Sep 17 00:00:00 2001 From: Finket Date: Thu, 22 Feb 2024 09:06:15 +0200 Subject: [PATCH 26/59] Accept resources suggestions from review --- .../Entities/Mobs/Customization/tails.yml | 9 --------- .../SimpleStation14/Species/shadowkin.yml | 12 +++++++----- Resources/Prototypes/Species/human.yml | 3 --- .../Mobs/Customization/tails32x32.rsi/meta.json | 4 ---- .../Customization/tails32x32.rsi/tentacle.png | Bin 10386 -> 0 bytes .../Mobs/Customization/wings64x32.rsi/harpy.png | Bin 9638 -> 0 bytes .../Mobs/Customization/wings64x32.rsi/meta.json | 15 --------------- 7 files changed, 7 insertions(+), 36 deletions(-) delete mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/tentacle.png delete mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings64x32.rsi/harpy.png delete mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings64x32.rsi/meta.json diff --git a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/tails.yml b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/tails.yml index a3d8ccaa36..b7e73b9f90 100644 --- a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/tails.yml +++ b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/tails.yml @@ -137,15 +137,6 @@ - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi state: succubus -- type: marking - id: TailTentacle - bodyPart: Tail - markingCategory: Tail - speciesRestriction: [nHuman, Oni] - sprites: - - sprite: SimpleStation14/Mobs/Customization/tails32x32.rsi - state: tentacle - - type: marking id: TailShadowkin bodyPart: Tail diff --git a/Resources/Prototypes/SimpleStation14/Species/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Species/shadowkin.yml index 225eb532a1..269ea2e4be 100644 --- a/Resources/Prototypes/SimpleStation14/Species/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Species/shadowkin.yml @@ -24,11 +24,13 @@ id: MobShadowkinSprites sprites: Head: MobShadowkinHead - Snout: MobShadowkinAnyMarkingFollowSkin - HeadTop: MobShadowkinAnyMarkingFollowSkin - HeadSide: MobShadowkinAnyMarkingFollowSkin - Wings: MobShadowkinAnyMarkingFollowSkin - Tail: MobShadowkinAnyMarkingFollowSkin + Hair: MobShadowkinAnyMarking + FacialHair: MobShadowkinAnyMarking + Snout: MobShadowkinAnyMarking + HeadTop: MobShadowkinAnyMarking + HeadSide: MobShadowkinAnyMarking + Wings: MobShadowkinAnyMarking + Tail: MobShadowkinAnyMarking Chest: MobShadowkinTorso Eyes: MobShadowkinEyes LArm: MobShadowkinLArm diff --git a/Resources/Prototypes/Species/human.yml b/Resources/Prototypes/Species/human.yml index df431bed53..ad115c07c0 100644 --- a/Resources/Prototypes/Species/human.yml +++ b/Resources/Prototypes/Species/human.yml @@ -58,9 +58,6 @@ Arms: points: 4 # Parkstation-WideUseMarkings required: false - Wings: - points: 1 - required: false - type: humanoidBaseSprite id: MobHumanoidEyes diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/meta.json b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/meta.json index 54066dec47..aac828f74b 100644 --- a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/meta.json +++ b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/meta.json @@ -110,10 +110,6 @@ { "name": "succubus", "directions": 4 - }, - { - "name": "tentacle", - "directions": 4 } ] } diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/tentacle.png b/Resources/Textures/SimpleStation14/Mobs/Customization/tails32x32.rsi/tentacle.png deleted file mode 100644 index a4c637d172b90fcf1abb29a8b2670d1365766afe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10386 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 AWB>pF diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/wings64x32.rsi/harpy.png b/Resources/Textures/SimpleStation14/Mobs/Customization/wings64x32.rsi/harpy.png deleted file mode 100644 index be6423a49a8519c3dfd7eca79b36ca1a21688ad8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9638 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 Date: Thu, 22 Feb 2024 09:12:17 +0200 Subject: [PATCH 27/59] Undo larger wings sprite additions --- .../Customization/wings96x34.rsi/dragon.png | Bin 8414 -> 0 bytes .../Mobs/Customization/wings96x34.rsi/fly.png | Bin 16694 -> 0 bytes .../Mobs/Customization/wings96x34.rsi/meta.json | 16 ---------------- .../Customization/wings96x34.rsi/robotic.png | Bin 13347 -> 0 bytes .../Customization/wings96x34.rsi/skeleton.png | Bin 8551 -> 0 bytes 5 files changed, 16 deletions(-) delete mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/dragon.png delete mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/fly.png delete mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/robotic.png delete mode 100644 Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/skeleton.png diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/dragon.png b/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/dragon.png deleted file mode 100644 index ddfa6613a86372e52b43edee66ba4065294fb4e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8414 zcmeHKc{tST+b3B|*|J0oDa05vW6T)FK6bK)RL0DA#uyA^>}4miRI;>KS}1Epi(RtQ zi9%$}5-Q=yR)lw`b57@a-|Kp>bG`5Hzw^Dm>+{_A=f3aHeLv6jz2hv*4Y;`uaxpP6 zaT^)xSuvhV^6oj`GdS@R3h0O0MP@z01yyBCNePv4CG#= z_#Lj|j@t4$;IPYxN4i8zqqA*a>G!j)Z5;^@=1q@U4!Y&P8E3JT6%gonwi(!<8DMCN z5b&sREWT_|;u84#?Up{gdZ%34^tZsGRfFoSk3q7N8`@LJUTJ-Ur{ArHIvvkusWy*1 zvDToqfx%wa40WF8q;0`o1xqa)08W2i)mjlZ{4x`{B<@`O^g!YA%7oxlVCHIz;QEZ_ z*Y5A-1@kwaRYMX#cmU#U-wcym9~p*#wZ3bzi=4fbJw1h_HSnZvs)sg4g`E|;*Ll9= z_KXSm-N+LEvFr!6H*@ECq8_-Wey_#W?yd;QdR8Nz9CERpe@%j@xUq3;>ugPbyoY2+ zT#O^w#Kl#1=dCy8PlTKq#yGwEyQ{Iu+HrDQ{Whop4_M6YU9;K*j zgYu_dO8M~SJ9j@i{_=!lkmt+m6=LN{SHq)>Q`uCGvOF}l{Mv1NURM_zUts4k@P=-a zpX*lq#8#;3bx!K5$8UNaslEE?rz=+mPR$7EwH8ZzI5L^C6=K6b!9XLO3Z@2 z=uw(+e{}o?UOU@1?SAFJrx(3%17GNC`VD)mdIV?CZ+6KU9LLNq;Ym(;en*CA%e{l1 z&-_|s+^F_jwC~Jr9}^uzE`1RllyP(Nn8nAwr`=8x37fRwi$$Ji(jm1dtk@X)y%&4r zdf)fDLk^m#rs@K+H*XK>X7`hP#^d{b6EdVDuQ`^sb>e-5?&|s0jRR%#7K0OV_r8GM zJABYi)LB{h_VMuQSks*5w1Z-4s*Xo`-tl7po>Ur{EOmk1HYMY6BY{0*F3IDdjzOc) znM@x|=8PzuE4Z@3vGH6}A>JMMjGt{RHF~VVnf^gcW9pLW*&ykzO8bwg!)xeVmHs{J zH*Y057@R)wA_J34(4ssobQfn$iapeP-1{P?*Mpz6xNMG)Mmb5M3`{m29AF(R8a7u} zdv!12&AQbS8YL}jF@qNDp}RUHq(B`EesjlmZLW2PQdUt&k#;b)2c0}gs7gWQJ2pD&8iA4pTI)BDVVlYAn`ROCuG&vLOZ zPdI&iWTEJ!yPt~slh58WT~@u-fsWqY+AC=+C#WJq&-jdIM2YJop80KLB1zkOS9%d7 zUl131v{O4QI($7|{vP!y!UWr&#A@lXFC#dms_eM@I&+VeroZmc(}LlE%W20dlJNrz z(H~6SSXW|c9}}8;$HQXImV5es5;tqw8miuy`t3G{33z%$pm|_fz=Sg*IhT_%&HjW( z)XQ+Wg5!m`&S(IOQ8NZOl!ttwja_3g=6td=tWS~gwIIVK_xZL-q9`UJHn&8_Bq*K- zg&aTes(i6p`VgfTU3B5*Q5Hj?cb(*H50Z za9n^UWllNKPbKu$(c#7J#;yy%$jl*1YX;#~NaO3+mOnDiU>;h_G1Of7(NYbM&VCMd%cNvgMAj>RRa!Y_9Ii!{Rb*QT z+QqM|e!+P>9iQgkO z=4SJ;@6GyP(<(gbCtMp??-X^3tqBkAf^?tt7ny+li(eaPQ9dErgiHFGN?_ zLr3^K(&WN0vQez5)sb1u$(as<^@#k3u0eWu&rB?<>C<9k2f$(Ud|`BS%K@<(ml79g zS*Mz;gNL;*_moH}w08UN$(*7rdrcofy(M&vO*EB}1d6M~JN8u>ai^qwilN9p5+Cgf z3VJ?}7SixZrT0q#i2pSk^k{la)&w}FCoSDp@>oxJ@+a-&enW9xliMY&#pVINcCylj zkyG8m$=0H`nXbQ#Z7Bcz-@#5FILb9Grv3$lHOh+tN`mktc}52oTUB6 zv6PT~noWY|nX8!72l_ARrTC9E|9*Ic4roZWmR)jtYx7BJEkY%jQ;qqVA1wrSQ83~| zPK*Z)ZlKRYZaS&|IB%>QO|Gz2U$76lKoaY6EAzoduD*XvNtob^Uo33Bc%=->dmD5S zp?0T!Vm6wYxBrl;hb_jb1bIKvIQKx2K>H~vU+&4uoSw!v9KHU>1pUW&USmXF-dFHn zF zZ`v4pS#YGgI96J;O{Y0yY-n%a9INQ9qxwxX4y2c0`Io}W)ZPybTB^P$idq$C8apib z?mi#U!sf(fzfr0}0gaCvmjfo`74feM-g<9MK3$rBdGc#b)#Bs&XT-W_roE@z$4Kr;NR0Y^2?h$>%C*RIv zl23f>%OYLCQSj#E-2sE-`?)?B)YujFGxrN{yM2gi&RoeY338+2DJjHKHlxfI{vlU@ zgAIFi>PoE~eDkidqE*DF$PMiy`G+&t6MxgJ=&7|#d-cergSt{~CCn6kUrjPO-V_?q z{>40e!Yj6-Reip&HMGm1=OL#oI1A=}%cLr5d~^yLc{)(&QGLC7h|r`&$5_>V^#f{C zP9@D@VHXt+Y{hzX8)Z+GPS;p0Nc2nH6&|n;leCd`O|(3sNoFygQyz#4ulr)~x_3g; zT=sSL<92@frE8DW4M8p78tZkVt2O954?6BL^}#mf?tIKEABr5B65;L`m*_N|V|7Y_ z#N3OQ9I$_b*>#QBa=N&o>9IU?&Zd57&${*&O(EU=_cN$8ikttPIdJ0s^tXbD8zE_e zIwBn4TZn>aMN!C?(pHY!U3VP&p7DdQ27u3Uw4zj zMqhPWlT;=fS~-ca_C-WW#M`n9kxm_QV%7egrSWx}(QB;n_cKj&3B>%CYYq+Jz}RO?`PT zLxV}=liNo&6l%AAd`ivK;@sTI$R?)y^E^A4mlmIY?^8Py(>_}=qw%pfGezU69*Q^u z)df%t@bF?ZModiVngL!oJO!YGTmTZ;6C*WW^-KyxCSasaAk37^ymSFqvSAPnunsb} z!3R=Woo#|3~reGYF!{J_uyeDE}~7oAM?1Z`vDT&TWujFc2(9`uKQ9$scHY*RoYdwA_=G06U#B%MtBi>$x-wmq{G z&aaLz)c?f&oAe*C?+7!b%*@bwRJ`xDdq#Q~scrjc0u@gtpm$!82o+^K0)+$PlvPn+ zWh4{_8FlXniWp1II`w*#k!cAYPuNor!J2(b^V97%7;d(qAJM?l?M; zp}<%JWKROs-{-F>8?pyrO~-BX2~|Nt;Rq!-9Lk6qs{D(-9YFJ8)Z#WOR7nvI+fm<6 z44M%RgIe5nr7{3^#u?F|b!h;OPNmsUsqPr5ZKpunntx84F%}d7N5|>m=l}y$2?j$$ z87I;P21g@MXoM12358brMV?9^69fM@>FwnMQvZ>3L$VLUe&Ei~k2Pftc>nnN@##+9 zSxg|%&ayz`@IONE!TAA%9X}aZKc?`mI8PG5*gt+2>>uOg|EU;Y$|xcLhk;R07bsX6 zj)Q`6IJh!c8K#O*Qc)%HatxpiN@%$l!`mpgUZFWPheg?(g#cuE2I4 z7?gpbj1y@CWl#n~Gjam?&xeO}QG(%7Pymcj-CizmWjNS{h=7A}DoR8c(nSRUBf$Ue z?*BQwpA`Z9BRqA;_J;UJGSwmfE!{r^e%V18wEP%j?97af9`ff-|C6unJ@r3${4BHo zpall>zefHMzyH$pFJ1qLfqx|YZ*~1k*FR$59|`|kUH@-%asAaR0-lT?Jby+fxRF5^ zXLONlE+z(gOk3LxC0yq0BICj7W$56;XgwRZFXmMFeWHv(cDj)nmVIh3A3GXeBoSA~ z#Kg*Lq^E5YFff~GmUKs*Cnnx?->ZnCAdwt}vtfpp&+d|*tCKAK!fZduQ^9f~wvpRj zkITf4Tu7}e`+8Tn;rI0HUV-8HM@GoEc2-Xd+f~Mo>|&VNIl}fPK%YSGZhk^Dtq2Ws zo^cTW?zFzOrl>Dbn0+_@JZ|s$>X?yAZEt0TpGG!Gq)XV^e+I`_x2anseQ?VQrQH0e zSEDEC$y4a&n3t9#{rtui>A-x(jh7N?$zSJqlArg`MFZpHsATC|w`IlM3S}?cO`KSG z>n5?}Q{m($b-Vkcp0}8_Sj+ML>_JqfdGQLAnGGd=v2i3@O^0%>OsKRsxwjIkZor(y zaWk7C{COiTwp1awebXTg(U&YuUS>a97q^ROzC%07|}uBTWo7`Bhb4rWlcUC+1z6+ z*X4*@9g?k^g+q}?7jueyVaAE zYoD{FjpV`gyM>)=P9tN^($^Da$i?KE)A*=&+C009wL3!70VBX+rPq7jcZN+Hv{H6I zC#1x{I{Sg!^u6bP6UuoCCItl-RBmu%EqiFjmI8q{Ud9v@+%8qPu|(or5enw39-MWp z8rJX);KN>)@t*PEjKUfA&7^8*YUURllajJBMg*^)>X?Sh<>tw9F`!1?z56&jn^>kSVK-XG%Gi{gKs$anxOdwtBb9UKas_N{u~^H; zT@vIy&aZiILLlb=Ri&4&oU{2cIl&>`ymiC3J}&n7bl<9_%?VQ8ne)5Ozp5Uvt~yzC zPR;BpQ)W`YvK_D*#h(y-E{mg6-}-(hi8+?Z`SOq&Z(2&s1vSno?98km1@lzNAK3yX z6&J4$ur`pn_K)0Bc766Pc-1L;Q1L6qIT5-%Nh51~TN@$;43&DSHD5j0$!w;!A8(pD z9k|%m2T3=wv70z0`>>kbrx+781nG+8bNsG)Ls2A1} zPi``{)7iTO!|es_Z*w^!b+j%;iS71tSdB)gv7o#Ir&3RzQcQ1U9NSxN$Byx`L4U>M zM&r$Ig}nEopaGIVG1l=hPm0z1^^hy8CW7+crg@!Bg(F>^t}?gc@7u=+l<-+TzN)HO7J4)kMY1ur6pj(t%^Zz0Bwu%l0*9fJZfI1Uevo)L{&rqjXXy9c zA0kd%3*8?9x(VXY3kreCy<$Z3_4KyQM{HiJ=Orm?8>1SjN9{@-BVN~iVb`#_8FvYF z#F=@a3YgsNTw1<(=eTerE4b*1Z`L$VnZ11|Ejw`;ETz=~FV7)=8kSFBem}Ne+vgv` yGXL(@jO0)-&k1|+VU3w9wSR6`KeF@Hc#{QxNa@z^E{7j&j~HRi_3rC9NBkH0UDbF1 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/fly.png b/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/fly.png deleted file mode 100644 index 261b3eb75df292a9a435ed5731224a821bfc9797..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16694 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 diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/meta.json b/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/meta.json index e41d615328..2dc5eca011 100644 --- a/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/meta.json +++ b/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/meta.json @@ -8,18 +8,10 @@ "name": "dragon_open", "directions": 4 }, - { - "name": "dragon", - "directions": 4 - }, { "name": "fly_open", "directions": 4 }, - { - "name": "fly", - "directions": 4 - }, { "name": "megamoth_open", "directions": 4 @@ -36,17 +28,9 @@ "name": "mothra", "directions": 4 }, - { - "name": "robotic", - "directions": 4 - }, { "name": "skeleton_open", "directions": 4 - }, - { - "name": "skeleton", - "directions": 4 } ] } diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/robotic.png b/Resources/Textures/SimpleStation14/Mobs/Customization/wings96x34.rsi/robotic.png deleted file mode 100644 index 073c1f5c4a0ed6f53692362ce4d6e12a126f8aa8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13347 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 From 7968e08753423afe5e8d977761e96b338941c200 Mon Sep 17 00:00:00 2001 From: Finket Date: Thu, 22 Feb 2024 09:23:54 +0200 Subject: [PATCH 28/59] Clean up code comments a bit --- Content.Client/Chat/Managers/ChatManager.cs | 6 +- .../Shadowkin/Systems/ShadowkinSystem.Tint.cs | 3 - .../Systems/ShadowkinPowerSystem.Teleport.cs | 4 +- .../Shadowkin/Systems/ShadowkinPowerSystem.cs | 63 +++++++++---------- 4 files changed, 34 insertions(+), 42 deletions(-) diff --git a/Content.Client/Chat/Managers/ChatManager.cs b/Content.Client/Chat/Managers/ChatManager.cs index b5d07551cc..70336fe99c 100644 --- a/Content.Client/Chat/Managers/ChatManager.cs +++ b/Content.Client/Chat/Managers/ChatManager.cs @@ -14,7 +14,7 @@ internal sealed class ChatManager : IChatManager [Dependency] private readonly IEntitySystemManager _systems = default!; private ISawmill _sawmill = default!; - public event Action? PermissionsUpdated; //Nyano - Summary: need to be able to update perms for new psionics. + public event Action? PermissionsUpdated; //Nyano - Summary: need to be able to update perms for new psionics public void Initialize() { _sawmill = Logger.GetSawmill("chat"); @@ -67,7 +67,7 @@ public void SendMessage(string text, ChatSelectChannel channel) _consoleHost.ExecuteCommand($"whisper \"{CommandParsing.Escape(str)}\""); break; - //Nyano - Summary: sends the command for telepath communication. + //Nyano - Summary: sends the command for telepath communication case ChatSelectChannel.Telepathic: _consoleHost.ExecuteCommand($"tsay \"{CommandParsing.Escape(str)}\""); break; @@ -81,7 +81,7 @@ public void SendMessage(string text, ChatSelectChannel channel) throw new ArgumentOutOfRangeException(nameof(channel), channel, null); } } - //Nyano - Summary: fires off the update permissions script. + //Nyano - Summary: fires off the update permissions script public void UpdatePermissions() { PermissionsUpdated?.Invoke(); diff --git a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs index 57b0b93190..7f8e49b382 100644 --- a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs +++ b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs @@ -84,9 +84,6 @@ public override void Update(float frameTime) // Eye color comp.TintColor = new Vector3(layer.Color.R, layer.Color.G, layer.Color.B); - // intensity = min + (power / max) - // intensity = intensity / 3 - // intensity = clamp intensity min, max const float min = 0.45f; const float max = 0.75f; // TODO This math doesn't match the comments, figure out which is correct diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index 6fa7b03184..c15b68d45c 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -41,13 +41,11 @@ private void Startup(EntityUid uid, ShadowkinTeleportPowerComponent component, C { var componentActionShadowkinTeleport = component.ActionShadowkinTeleport; _actions.AddAction(uid, ref componentActionShadowkinTeleport, "ActionShadowkinTeleport"); - // // _actions.AddAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport")), null); } private void Shutdown(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentShutdown args) { _actions.RemoveAction(uid, component.ActionShadowkinTeleport); - // // _actions.RemoveAction(uid, new WorldTargetAction(_prototype.Index("ShadowkinTeleport"))); } @@ -66,7 +64,7 @@ private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, var transform = Transform(args.Performer); if (transform.MapID != args.Target.GetMapId(EntityManager)) return; - + SharedPullableComponent? pullable = null; // To avoid "might not be initialized when accessed" warning if (_entity.TryGetComponent(args.Performer, out var puller) && puller.Pulling != null && diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs index e5218a030e..26d33ed214 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs @@ -29,8 +29,8 @@ public ShadowkinPowerSystem() } - /// The current power level. - /// The name of the power level. + /// The current power level + /// The name of the power level public string GetLevelName(float powerLevel) { // Placeholders @@ -55,11 +55,11 @@ public string GetLevelName(float powerLevel) } /// - /// Sets the alert level of a shadowkin. + /// Sets the alert level of a shadowkin /// - /// The entity uid. + /// The entity uid /// Enable the alert or not - /// The current power level. + /// The current power level public void UpdateAlert(EntityUid uid, bool enabled, float? powerLevel = null) { if (!enabled || powerLevel == null) @@ -86,10 +86,10 @@ public void UpdateAlert(EntityUid uid, bool enabled, float? powerLevel = null) /// - /// Tries to update the power level of a shadowkin based on an amount of seconds. + /// Tries to update the power level of a shadowkin based on an amount of seconds /// - /// The entity uid. - /// The time since the last update in seconds. + /// The entity uid + /// The time since the last update in seconds public bool TryUpdatePowerLevel(EntityUid uid, float frameTime) { // Check if the entity has a shadowkin component @@ -107,10 +107,10 @@ public bool TryUpdatePowerLevel(EntityUid uid, float frameTime) } /// - /// Updates the power level of a shadowkin based on an amount of seconds. + /// Updates the power level of a shadowkin based on an amount of seconds /// - /// The entity uid. - /// The time since the last update in seconds. + /// The entity uid + /// The time since the last update in seconds public void UpdatePowerLevel(EntityUid uid, float frameTime) { // Get shadowkin component @@ -123,7 +123,6 @@ public void UpdatePowerLevel(EntityUid uid, float frameTime) // Calculate new power level (P = P + t * G * M) var newPowerLevel = component.PowerLevel + frameTime * component.PowerLevelGain * component.PowerLevelGainMultiplier; - // Clamp power level using clamp function newPowerLevel = Math.Clamp(newPowerLevel, component.PowerLevelMin, component.PowerLevelMax); // Set the new power level @@ -132,10 +131,10 @@ public void UpdatePowerLevel(EntityUid uid, float frameTime) /// - /// Tries to add to the power level of a shadowkin. + /// Tries to add to the power level of a shadowkin /// - /// The entity uid. - /// The amount to add to the power level. + /// The entity uid + /// The amount to add to the power level public bool TryAddPowerLevel(EntityUid uid, float amount) { // Check if the entity has a shadowkin component @@ -149,10 +148,10 @@ public bool TryAddPowerLevel(EntityUid uid, float amount) } /// - /// Adds to the power level of a shadowkin. + /// Adds to the power level of a shadowkin /// - /// The entity uid. - /// The amount to add to the power level. + /// The entity uid + /// The amount to add to the power level public void AddPowerLevel(EntityUid uid, float amount) { // Get shadowkin component @@ -165,7 +164,6 @@ public void AddPowerLevel(EntityUid uid, float amount) // Get new power level var newPowerLevel = component.PowerLevel + amount; - // Clamp power level using clamp function newPowerLevel = Math.Clamp(newPowerLevel, component.PowerLevelMin, component.PowerLevelMax); // Set the new power level @@ -174,10 +172,10 @@ public void AddPowerLevel(EntityUid uid, float amount) /// - /// Sets the power level of a shadowkin. + /// Sets the power level of a shadowkin /// - /// The entity uid. - /// The new power level. + /// The entity uid + /// The new power level public void SetPowerLevel(EntityUid uid, float newPowerLevel) { // Get shadowkin component @@ -187,7 +185,6 @@ public void SetPowerLevel(EntityUid uid, float newPowerLevel) return; } - // Clamp power level using clamp function newPowerLevel = Math.Clamp(newPowerLevel, component.PowerLevelMin, component.PowerLevelMax); // Set the new power level @@ -196,7 +193,7 @@ public void SetPowerLevel(EntityUid uid, float newPowerLevel) /// - /// Tries to blackeye a shadowkin. + /// Tries to blackeye a shadowkin /// public bool TryBlackeye(EntityUid uid) { @@ -212,7 +209,7 @@ public bool TryBlackeye(EntityUid uid) } /// - /// Blackeyes a shadowkin. + /// Blackeyes a shadowkin /// public void Blackeye(EntityUid uid) { @@ -232,11 +229,11 @@ public void Blackeye(EntityUid uid) /// - /// Tries to add a power multiplier. + /// Tries to add a power multiplier /// - /// The entity uid. - /// The multiplier to add. - /// The time in seconds to wait before removing the multiplier. + /// The entity uid + /// The multiplier to add + /// The time in seconds to wait before removing the multiplier public bool TryAddMultiplier(EntityUid uid, float multiplier, float? time = null) { if (!_entity.HasComponent(uid) || @@ -249,11 +246,11 @@ public bool TryAddMultiplier(EntityUid uid, float multiplier, float? time = null } /// - /// Adds a power multiplier. + /// Adds a power multiplier /// - /// The entity uid. - /// The multiplier to add. - /// The time in seconds to wait before removing the multiplier. + /// The entity uid + /// The multiplier to add + /// The time in seconds to wait before removing the multiplier public void AddMultiplier(EntityUid uid, float multiplier, float? time = null) { // Get shadowkin component From 8bb0c80c106c72b7b24c053d9ebcdb9a8374514d Mon Sep 17 00:00:00 2001 From: Finket Date: Thu, 22 Feb 2024 09:48:55 +0200 Subject: [PATCH 29/59] Switch to const action prototypes with validators --- .../Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs | 6 ++++-- .../Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs | 5 +++-- .../Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs | 5 +++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index a34980f2fa..e2afc3b549 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -15,7 +15,7 @@ using Robust.Server.GameObjects; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; - +using Robust.Shared.Prototypes; namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; @@ -32,6 +32,8 @@ public sealed class ShadowkinDarkSwapSystem : EntitySystem [Dependency] private readonly MagicSystem _magic = default!; [Dependency] private readonly NpcFactionSystem _factions = default!; + [ValidatePrototypeId] + private const string ActionShadowkinDarkSwapId = "ActionShadowkinDarkSwap"; public override void Initialize() { @@ -50,7 +52,7 @@ public override void Initialize() private void Startup(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentStartup args) { var componentActionShadowkinDarkSwap = component.ActionShadowkinDarkSwap; - _actions.AddAction(uid, ref componentActionShadowkinDarkSwap, "ActionShadowkinDarkSwap"); + _actions.AddAction(uid, ref componentActionShadowkinDarkSwap, ActionShadowkinDarkSwapId); } private void Shutdown(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentShutdown args) diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index af4f80d9c8..9d30c8c827 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -11,10 +11,11 @@ namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; public sealed class ShadowkinRestSystem : EntitySystem { [Dependency] private readonly IEntityManager _entity = default!; - [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly ShadowkinPowerSystem _power = default!; + [ValidatePrototypeId] + private const string ActionShadowkinRestId = "ActionShadowkinRest"; public override void Initialize() { @@ -30,7 +31,7 @@ public override void Initialize() private void OnStartup(EntityUid uid, ShadowkinRestPowerComponent component, ComponentStartup args) { var componentActionShadowkinRest = component.ActionShadowkinRest; - _actions.AddAction(uid, ref componentActionShadowkinRest, "ActionShadowkinRest"); + _actions.AddAction(uid, ref componentActionShadowkinRest, ActionShadowkinRestId); } private void OnShutdown(EntityUid uid, ShadowkinRestPowerComponent component, ComponentShutdown args) diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index c15b68d45c..268be80e13 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -22,9 +22,10 @@ public sealed class ShadowkinTeleportSystem : EntitySystem [Dependency] private readonly StaminaSystem _stamina = default!; [Dependency] private readonly PullingSystem _pulling = default!; [Dependency] private readonly SharedActionsSystem _actions = default!; - [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly MagicSystem _magic = default!; + [ValidatePrototypeId] + private const string ActionShadowkinTeleportId = "ActionShadowkinTeleport"; public override void Initialize() { @@ -40,7 +41,7 @@ public override void Initialize() private void Startup(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentStartup args) { var componentActionShadowkinTeleport = component.ActionShadowkinTeleport; - _actions.AddAction(uid, ref componentActionShadowkinTeleport, "ActionShadowkinTeleport"); + _actions.AddAction(uid, ref componentActionShadowkinTeleport, ActionShadowkinTeleportId); } private void Shutdown(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentShutdown args) From 90363d01ea72e86d0bc38e5e28d3f7d83141a2fa Mon Sep 17 00:00:00 2001 From: Finket Date: Thu, 22 Feb 2024 09:59:30 +0200 Subject: [PATCH 30/59] Fix rest waking action finally --- .../Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index 9d30c8c827..e8ecf030d8 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -59,9 +59,8 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki // Sleepy time _entity.EnsureComponent(args.Performer); // No waking up normally (it would do nothing) - // Not sure what needs to be done here with the refactor - // _actions.RemoveAction(args.Performer, component.WakeAction); // ?? - // _actions.RemoveAction(args.Performer, new InstantAction(_prototype.Index("Wake"))); + if (_entity.TryGetComponent(uid, out var sleepingComponent)) + _actions.RemoveAction(args.Performer, sleepingComponent.WakeAction); _power.TryAddMultiplier(args.Performer, 1.5f); // No action cooldown From c69156908d74b7097442607f42d2b97107484fa3 Mon Sep 17 00:00:00 2001 From: Finket Date: Thu, 22 Feb 2024 10:03:41 +0200 Subject: [PATCH 31/59] Switch logger errors to debug assertions --- .../Shadowkin/Systems/ShadowkinPowerSystem.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs index 26d33ed214..0c3cabfef6 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs @@ -2,6 +2,7 @@ using Content.Shared.SimpleStation14.Species.Shadowkin.Components; using Content.Shared.SimpleStation14.Species.Shadowkin.Events; using System.Threading.Tasks; +using Robust.Shared.Utility; namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; @@ -71,7 +72,7 @@ public void UpdateAlert(EntityUid uid, bool enabled, float? powerLevel = null) // Get shadowkin component if (!_entity.TryGetComponent(uid, out var component)) { - Logger.ErrorS("ShadowkinPowerSystem", "Tried to update alert of entity without shadowkin component."); + DebugTools.Assert("Tried to update alert of entity without shadowkin component."); return; } @@ -116,7 +117,7 @@ public void UpdatePowerLevel(EntityUid uid, float frameTime) // Get shadowkin component if (!_entity.TryGetComponent(uid, out var component)) { - Logger.Error("Tried to update power level of entity without shadowkin component."); + DebugTools.Assert("Tried to update power level of entity without shadowkin component."); return; } @@ -157,7 +158,7 @@ public void AddPowerLevel(EntityUid uid, float amount) // Get shadowkin component if (!_entity.TryGetComponent(uid, out var component)) { - Logger.Error("Tried to add to power level of entity without shadowkin component."); + DebugTools.Assert("Tried to add to power level of entity without shadowkin component."); return; } @@ -181,7 +182,7 @@ public void SetPowerLevel(EntityUid uid, float newPowerLevel) // Get shadowkin component if (!_entity.TryGetComponent(uid, out var component)) { - Logger.Error("Tried to set power level of entity without shadowkin component."); + DebugTools.Assert("Tried to set power level of entity without shadowkin component."); return; } @@ -218,7 +219,7 @@ public void Blackeye(EntityUid uid) // Get shadowkin component if (!_entity.TryGetComponent(uid, out var component)) { - Logger.Error("Tried to blackeye entity without shadowkin component."); + DebugTools.Assert("Tried to blackeye entity without shadowkin component."); return; } @@ -256,7 +257,7 @@ public void AddMultiplier(EntityUid uid, float multiplier, float? time = null) // Get shadowkin component if (!_entity.TryGetComponent(uid, out var component)) { - Logger.Error("Tried to add multiplier to entity without shadowkin component."); + DebugTools.Assert("Tried to add multiplier to entity without shadowkin component."); return; } From 2a474d7ca79949a3416708025b70e6e6815c1927 Mon Sep 17 00:00:00 2001 From: Finket Date: Thu, 22 Feb 2024 13:19:23 +0200 Subject: [PATCH 32/59] Fix darkswap visibility --- .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 21 +++++++++++-------- .../Systems/ShadowkinPowerSystem.Darken.cs | 3 +-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index e2afc3b549..00e93c1e47 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -7,6 +7,7 @@ using Content.Shared.CombatMode.Pacification; using Content.Shared.Cuffs.Components; using Content.Shared.Damage.Systems; +using Content.Shared.Eye; using Content.Shared.Ghost; using Content.Shared.SimpleStation14.Species.Shadowkin.Components; using Content.Shared.SimpleStation14.Species.Shadowkin.Events; @@ -24,6 +25,7 @@ public sealed class ShadowkinDarkSwapSystem : EntitySystem [Dependency] private readonly ShadowkinPowerSystem _power = default!; [Dependency] private readonly VisibilitySystem _visibility = default!; [Dependency] private readonly IEntityManager _entity = default!; + [Dependency] private readonly SharedEyeSystem _eye = default!; [Dependency] private readonly ShadowkinDarkenSystem _darken = default!; [Dependency] private readonly StaminaSystem _stamina = default!; [Dependency] private readonly SharedStealthSystem _stealth = default!; @@ -188,7 +190,6 @@ private void OnInvisShutdown(EntityUid uid, ShadowkinDarkSwappedComponent compon component.DarkenedLights.Clear(); } - // Commented out eye and ghost stuff until ported public void SetVisibility(EntityUid uid, bool set) { // We require the visibility component for this to work @@ -197,12 +198,13 @@ public void SetVisibility(EntityUid uid, bool set) if (set) // Invisible { // Allow the entity to see DarkSwapped entities - /*if (_entity.TryGetComponent(uid, out EyeComponent? eye)) - eye.VisibilityMask |= (uint) VisibilityFlags.DarkSwapInvisibility;*/ + if (_entity.TryGetComponent(uid, out EyeComponent? eye)) + _eye.SetVisibilityMask(uid, eye.VisibilityMask | (int) VisibilityFlags.DarkSwapInvisibility, eye); + // eye.VisibilityMask |= (int) VisibilityFlags.DarkSwapInvisibility; // Make other entities unable to see the entity unless also DarkSwapped - // _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); - // _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + _visibility.AddLayer(uid, (ushort) VisibilityFlags.DarkSwapInvisibility, false); + _visibility.RemoveLayer(uid, (ushort) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); // If not a ghost, add a stealth shader to the entity @@ -212,12 +214,13 @@ public void SetVisibility(EntityUid uid, bool set) else // Visible { // Remove the ability to see DarkSwapped entities - /*if (_entity.TryGetComponent(uid, out EyeComponent? eye)) - eye.VisibilityMask &= ~(uint) VisibilityFlags.DarkSwapInvisibility;*/ + if (_entity.TryGetComponent(uid, out EyeComponent? eye)) + _eye.SetVisibilityMask(uid, eye.VisibilityMask & ~(int) VisibilityFlags.DarkSwapInvisibility, eye); + // eye.VisibilityMask &= ~(int) VisibilityFlags.DarkSwapInvisibility; // Make other entities able to see the entity again - // _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); - // _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + _visibility.RemoveLayer(uid, (ushort) VisibilityFlags.DarkSwapInvisibility, false); + _visibility.AddLayer(uid, (ushort) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); // Remove the stealth shader from the entity diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs index bb5bc01c9d..7c3730f5fe 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs @@ -42,14 +42,13 @@ public override void Update(float frameTime) if (!shadowkin.Darken) continue; - var transform = Transform(uid); - // Cooldown shadowkin.DarkenAccumulator -= frameTime; if (shadowkin.DarkenAccumulator > 0f) continue; shadowkin.DarkenAccumulator += shadowkin.DarkenRate; + var transform = Transform(uid); var darkened = new List(); // Get all lights in range From 030c3c8698ba32772841092ae4761ac586c37dfb Mon Sep 17 00:00:00 2001 From: Finket Date: Thu, 22 Feb 2024 14:10:09 +0200 Subject: [PATCH 33/59] Clean SetDarkened to Darkened and UnDarkened functions --- .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 85 +++++++------------ 1 file changed, 32 insertions(+), 53 deletions(-) diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 00e93c1e47..e681ec15de 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -79,43 +79,15 @@ private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, var hasComp = _entity.HasComponent(args.Performer); - SetDarkened( - performer, - !hasComp, - !hasComp, - !hasComp, - true, - args.StaminaCostOn, - args.PowerCostOn, - args.SoundOn, - args.VolumeOn, - args.StaminaCostOff, - args.PowerCostOff, - args.SoundOff, - args.VolumeOff, - args - ); + if (hasComp) + Darkened(performer, args.StaminaCostOff, args.PowerCostOff, args.SoundOff, args.VolumeOff, args); + else + UnDarkened(performer, args.StaminaCostOn, args.PowerCostOn, args.SoundOn, args.VolumeOn, args); _magic.Speak(args, false); } - - public void SetDarkened( - NetEntity performer, - bool addComp, - bool invisible, - bool pacify, - bool darken, - float staminaCostOn, - float powerCostOn, - SoundSpecifier soundOn, - float volumeOn, - float staminaCostOff, - float powerCostOff, - SoundSpecifier soundOff, - float volumeOff, - ShadowkinDarkSwapEvent? args - ) + public void Darkened(NetEntity performer, float staminaCostOff, float powerCostOff, SoundSpecifier soundOff, float volumeOff, ShadowkinDarkSwapEvent? args) { var performerUid = _entity.GetEntity(performer); @@ -124,36 +96,43 @@ public void SetDarkened( if (ev.Cancelled) return; - if (addComp) - { - var comp = _entity.EnsureComponent(performerUid); - comp.Invisible = invisible; - comp.Pacify = pacify; - comp.Darken = darken; + _entity.RemoveComponent(performerUid); + RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, false)); - RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, true)); + _audio.PlayPvs(soundOff, performerUid, AudioParams.Default.WithVolume(volumeOff)); - _audio.PlayPvs(soundOn, performerUid, AudioParams.Default.WithVolume(volumeOn)); + _power.TryAddPowerLevel(performerUid, -powerCostOff); + _stamina.TakeStaminaDamage(performerUid, staminaCostOff); - _power.TryAddPowerLevel(performerUid, -powerCostOn); - _stamina.TakeStaminaDamage(performerUid, staminaCostOn); - } - else - { - _entity.RemoveComponent(performerUid); - RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, false)); + if (args != null) + args.Handled = true; + } - _audio.PlayPvs(soundOff, performerUid, AudioParams.Default.WithVolume(volumeOff)); + public void UnDarkened(NetEntity performer, float staminaCostOn, float powerCostOn, SoundSpecifier soundOn, float volumeOn, ShadowkinDarkSwapEvent? args) + { + var performerUid = _entity.GetEntity(performer); - _power.TryAddPowerLevel(performerUid, -powerCostOff); - _stamina.TakeStaminaDamage(performerUid, staminaCostOff); - } + var ev = new ShadowkinDarkSwapAttemptEvent(performerUid); + RaiseLocalEvent(ev); + if (ev.Cancelled) + return; + + var comp = _entity.EnsureComponent(performerUid); + comp.Invisible = true; + comp.Pacify = true; + comp.Darken = true; + + RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, true)); + + _audio.PlayPvs(soundOn, performerUid, AudioParams.Default.WithVolume(volumeOn)); + + _power.TryAddPowerLevel(performerUid, -powerCostOn); + _stamina.TakeStaminaDamage(performerUid, staminaCostOn); if (args != null) args.Handled = true; } - private void OnInvisStartup(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentStartup args) { if (component.Pacify) From bd1f7a8437a4f22aac8723a64692b9107a6d1fc8 Mon Sep 17 00:00:00 2001 From: Finket Date: Thu, 22 Feb 2024 16:25:08 +0200 Subject: [PATCH 34/59] Fix action ECS again and fix action removal --- .../Components/ShadowkinDarkSwapPowerComponent.cs | 5 ++++- .../Shadowkin/Components/ShadowkinRestPowerComponent.cs | 3 ++- .../Components/ShadowkinTeleportPowerComponent.cs | 3 ++- .../Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs | 7 +++---- .../Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs | 7 +++---- .../Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs | 7 +++---- Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml | 6 +++--- 7 files changed, 20 insertions(+), 18 deletions(-) diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs index 00789ab7d1..07903e62c2 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs @@ -1,4 +1,6 @@ using Content.Server.NPC.Components; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; @@ -17,5 +19,6 @@ public sealed partial class ShadowkinDarkSwapPowerComponent : Component [DataField("factions", customTypeSerializer: typeof(PrototypeIdListSerializer))] public List AddedFactions = new() { "ShadowkinDarkFriendly" }; - public EntityUid? ActionShadowkinDarkSwap { get; set; } + [DataField("shadowkinDarkSwapActionEntity")] + public EntityUid? ShadowkinDarkSwapActionEntity; } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinRestPowerComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinRestPowerComponent.cs index e25640fb11..2d7912a735 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinRestPowerComponent.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinRestPowerComponent.cs @@ -6,5 +6,6 @@ public sealed partial class ShadowkinRestPowerComponent : Component [ViewVariables(VVAccess.ReadOnly)] public bool IsResting = false; - public EntityUid? ActionShadowkinRest { get; set; } + [DataField("shadowkinRestActionEntity")] + public EntityUid? ShadowkinRestActionEntity; } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinTeleportPowerComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinTeleportPowerComponent.cs index eca292667a..ebddf29702 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinTeleportPowerComponent.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinTeleportPowerComponent.cs @@ -5,5 +5,6 @@ namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; [RegisterComponent] public sealed partial class ShadowkinTeleportPowerComponent : Component { - public EntityUid? ActionShadowkinTeleport { get; set; } + [DataField("shadowkinTeleportActionEntity")] + public EntityUid? ShadowkinTeleportActionEntity; } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index e681ec15de..a632806555 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -35,7 +35,7 @@ public sealed class ShadowkinDarkSwapSystem : EntitySystem [Dependency] private readonly NpcFactionSystem _factions = default!; [ValidatePrototypeId] - private const string ActionShadowkinDarkSwapId = "ActionShadowkinDarkSwap"; + private const string ShadowkinDarkSwapActionId = "ShadowkinDarkSwapAction"; public override void Initialize() { @@ -53,13 +53,12 @@ public override void Initialize() private void Startup(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentStartup args) { - var componentActionShadowkinDarkSwap = component.ActionShadowkinDarkSwap; - _actions.AddAction(uid, ref componentActionShadowkinDarkSwap, ActionShadowkinDarkSwapId); + _actions.AddAction(uid, ref component.ShadowkinDarkSwapActionEntity, ShadowkinDarkSwapActionId, uid); } private void Shutdown(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentShutdown args) { - _actions.RemoveAction(uid, component.ActionShadowkinDarkSwap); + _actions.RemoveAction(uid, component.ShadowkinDarkSwapActionEntity); } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index e8ecf030d8..d7421be80a 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -15,7 +15,7 @@ public sealed class ShadowkinRestSystem : EntitySystem [Dependency] private readonly ShadowkinPowerSystem _power = default!; [ValidatePrototypeId] - private const string ActionShadowkinRestId = "ActionShadowkinRest"; + private const string ShadowkinRestActionId = "ShadowkinRestAction"; public override void Initialize() { @@ -30,13 +30,12 @@ public override void Initialize() private void OnStartup(EntityUid uid, ShadowkinRestPowerComponent component, ComponentStartup args) { - var componentActionShadowkinRest = component.ActionShadowkinRest; - _actions.AddAction(uid, ref componentActionShadowkinRest, ActionShadowkinRestId); + _actions.AddAction(uid, ref component.ShadowkinRestActionEntity, ShadowkinRestActionId); } private void OnShutdown(EntityUid uid, ShadowkinRestPowerComponent component, ComponentShutdown args) { - _actions.RemoveAction(uid, component.ActionShadowkinRest); + _actions.RemoveAction(uid, component.ShadowkinRestActionEntity); } private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, ShadowkinRestEvent args) diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index 268be80e13..50ca693f4b 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -25,7 +25,7 @@ public sealed class ShadowkinTeleportSystem : EntitySystem [Dependency] private readonly MagicSystem _magic = default!; [ValidatePrototypeId] - private const string ActionShadowkinTeleportId = "ActionShadowkinTeleport"; + private const string ShadowkinTeleportActionId = "ShadowkinTeleportAction"; public override void Initialize() { @@ -40,13 +40,12 @@ public override void Initialize() private void Startup(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentStartup args) { - var componentActionShadowkinTeleport = component.ActionShadowkinTeleport; - _actions.AddAction(uid, ref componentActionShadowkinTeleport, ActionShadowkinTeleportId); + _actions.AddAction(uid, ref component.ShadowkinTeleportActionEntity, ShadowkinTeleportActionId); } private void Shutdown(EntityUid uid, ShadowkinTeleportPowerComponent component, ComponentShutdown args) { - _actions.RemoveAction(uid, component.ActionShadowkinTeleport); + _actions.RemoveAction(uid, component.ShadowkinTeleportActionEntity); } diff --git a/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml index a029e421b1..42e60f6c0f 100644 --- a/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Magic/shadowkin.yml @@ -1,5 +1,5 @@ - type: entity - id: ActionShadowkinTeleport + id: ShadowkinTeleportAction name: action-name-shadowkin-teleport description: action-description-shadowkin-teleport components: @@ -19,7 +19,7 @@ speech: action-description-shadowkin-teleport - type: entity - id: ActionShadowkinDarkSwap + id: ShadowkinDarkSwapAction name: action-name-shadowkin-darkswap description: action-description-shadowkin-darkswap components: @@ -38,7 +38,7 @@ speech: action-description-shadowkin-darkswap - type: entity - id: ActionShadowkinRest + id: ShadowkinRestAction name: action-name-shadowkin-rest description: action-description-shadowkin-rest components: From 24e03dffe4dc2c3da3a062f68078fa0124585a60 Mon Sep 17 00:00:00 2001 From: Finket Date: Thu, 22 Feb 2024 16:31:34 +0200 Subject: [PATCH 35/59] Address miscellaneous review items --- .../Speech/EntitySystems/ShadowkinAccentSystem.cs | 2 +- .../Species/Shadowkin/Components/ShadowkinComponent.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs b/Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs index f8d44253cc..b7fe9e920a 100644 --- a/Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs +++ b/Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs @@ -9,7 +9,7 @@ public sealed class ShadowkinAccentSystem : EntitySystem { [Dependency] private readonly IRobustRandom _random = default!; - private static readonly Regex mRegex = new(@"[adgjmps]", RegexOptions.Compiled | RegexOptions.IgnoreCase); + private static readonly Regex mRegex = new(@"[adgjmpsv]", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex aRegex = new(@"[behknqtwy]", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex rRegex = new(@"[cfiloruxz]", RegexOptions.Compiled | RegexOptions.IgnoreCase); diff --git a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs index eaad9d3870..91a4a8f0df 100644 --- a/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs +++ b/Content.Shared/SimpleStation14/Species/Shadowkin/Components/ShadowkinComponent.cs @@ -30,7 +30,7 @@ public sealed partial class ShadowkinComponent : Component public float MinPowerMin = 15f; [ViewVariables(VVAccess.ReadWrite)] - public float MinPowerMax = 60f; + public float MinPowerMax = 40f; #endregion From f2cbbaebd0c7a59e44200e26fbe1dbc7511d6598 Mon Sep 17 00:00:00 2001 From: Finket Date: Thu, 22 Feb 2024 17:11:38 +0200 Subject: [PATCH 36/59] Give shadowkin lungs so they can breath again --- .../SimpleStation14/Entities/Body/Prototypes/shadowkin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/SimpleStation14/Entities/Body/Prototypes/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entities/Body/Prototypes/shadowkin.yml index 2cbe244983..b3e47eb224 100644 --- a/Resources/Prototypes/SimpleStation14/Entities/Body/Prototypes/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Entities/Body/Prototypes/shadowkin.yml @@ -19,7 +19,7 @@ - right leg organs: # placeholders heart: OrganHumanHeart - # lungs: OrganLungs + lungs: OrganHumanLungs stomach: OrganHumanStomach liver: OrganHumanLiver kidneys: OrganHumanKidneys From e3401d895e625d1e982a6146a26a81af3e684adf Mon Sep 17 00:00:00 2001 From: Finket Date: Thu, 22 Feb 2024 17:43:58 +0200 Subject: [PATCH 37/59] Reenable empathy chat --- Content.Server/SimpleStation14/Chat/ESayCommand.cs | 8 ++++---- .../SimpleStation14/Chat/SimpleStationChatSystem.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Content.Server/SimpleStation14/Chat/ESayCommand.cs b/Content.Server/SimpleStation14/Chat/ESayCommand.cs index b9743c622a..425b1437ed 100644 --- a/Content.Server/SimpleStation14/Chat/ESayCommand.cs +++ b/Content.Server/SimpleStation14/Chat/ESayCommand.cs @@ -1,8 +1,8 @@ using Content.Server.Chat.Systems; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; +using Robust.Shared.Player; namespace Content.Server.SimpleStation14.Chat.Commands; @@ -18,7 +18,7 @@ internal sealed class ESayCommand : IConsoleCommand public void Execute(IConsoleShell shell, string argStr, string[] args) { - /*if (shell.Player is not IPlayerSession player) + if (shell.Player is not ICommonSession player) { shell.WriteError("This command cannot be run from the server."); return; @@ -31,7 +31,7 @@ public void Execute(IConsoleShell shell, string argStr, string[] args) { shell.WriteError("You don't have an entity!"); return; - }*/ + } if (args.Length < 1) return; @@ -40,6 +40,6 @@ public void Execute(IConsoleShell shell, string argStr, string[] args) if (string.IsNullOrEmpty(message)) return; - // EntitySystem.Get().TrySendInGameICMessage(playerEntity, message, InGameICChatType.Empathy, false, false, shell, player, checkRadioPrefix: false); + EntitySystem.Get().TrySendInGameICMessage(playerEntity, message, InGameICChatType.Empathy, false, false, shell, player, checkRadioPrefix: false); } } diff --git a/Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs b/Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs index 327c695cfd..90308de38d 100644 --- a/Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs +++ b/Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs @@ -16,7 +16,7 @@ namespace Content.Server.SimpleStation14.Chat { /// - /// qExtensions for Parkstation's chat stuff + /// Extensions for Parkstation's chat stuff /// public sealed class SimpleStationChatSystem : EntitySystem { From 74d53c83541593ccabeeccce7898be24c768e63c Mon Sep 17 00:00:00 2001 From: Finket Date: Sat, 24 Feb 2024 10:21:10 +0200 Subject: [PATCH 38/59] Temporarily remove respirator values and psionic chance --- .../SimpleStation14/Entities/Mobs/Player/shadowkin.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml index 4fe8a05e00..5c7830c011 100644 --- a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml @@ -37,6 +37,13 @@ damage: types: Blunt: 0.35 # per second, scales with pressure and other constants. + - type: Respirator # this is a temporary fix, shadowkin should not be BaseMobHuman nor MobRespirator + maxSaturation: 5.0 + minSaturation: 5.0 # shadowkin never lose saturation, so they basically don't breath + cycleDelay: 0.0 # this should set all multipliers in the respirator system to zero + damage: + types: + Asphyxiation: 0 # just in case, no airloss damage from respirator component, recovery rate is unchanged - type: Bloodstream bloodlossDamage: types: @@ -119,7 +126,8 @@ interactSuccessString: petting-success-soft-floofy interactSuccessSound: /Audio/Effects/thudswoosh.ogg messagePerceivedByOthers: petting-success-soft-floofy-others - # - type: PotentialPsionic # They've their own abilities. + - type: PotentialPsionic + chance: 0.0 # They have their own abilities. - type: MovementSpeedModifier baseWalkSpeed : 4.5 baseSprintSpeed : 2.7 From 1ca9a796fa8ef7a7d8abd141e576830ea948321d Mon Sep 17 00:00:00 2001 From: Finket Date: Fri, 1 Mar 2024 13:22:33 +0200 Subject: [PATCH 39/59] Adjust potentialpsionic value for shadowkin --- .../SimpleStation14/Entities/Mobs/Player/shadowkin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml index 5c7830c011..ec84316a87 100644 --- a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml +++ b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/shadowkin.yml @@ -127,7 +127,7 @@ interactSuccessSound: /Audio/Effects/thudswoosh.ogg messagePerceivedByOthers: petting-success-soft-floofy-others - type: PotentialPsionic - chance: 0.0 # They have their own abilities. + chance: -2 # They have their own abilities. - type: MovementSpeedModifier baseWalkSpeed : 4.5 baseSprintSpeed : 2.7 From 58e1f2320828aa3da7fd60d79648fbec7d79e2a3 Mon Sep 17 00:00:00 2001 From: Finket Date: Fri, 1 Mar 2024 13:30:35 +0200 Subject: [PATCH 40/59] Fix shadowkin accent not capitalizing first letters --- .../Speech/EntitySystems/ShadowkinAccentSystem.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs b/Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs index b7fe9e920a..d40a6b8c4f 100644 --- a/Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs +++ b/Content.Server/SimpleStation14/Speech/EntitySystems/ShadowkinAccentSystem.cs @@ -9,9 +9,12 @@ public sealed class ShadowkinAccentSystem : EntitySystem { [Dependency] private readonly IRobustRandom _random = default!; - private static readonly Regex mRegex = new(@"[adgjmpsv]", RegexOptions.Compiled | RegexOptions.IgnoreCase); - private static readonly Regex aRegex = new(@"[behknqtwy]", RegexOptions.Compiled | RegexOptions.IgnoreCase); - private static readonly Regex rRegex = new(@"[cfiloruxz]", RegexOptions.Compiled | RegexOptions.IgnoreCase); + private static readonly Regex mRegex = new(@"[adgjmpsv]", RegexOptions.Compiled); + private static readonly Regex aRegex = new(@"[behknqtwy]", RegexOptions.Compiled); + private static readonly Regex rRegex = new(@"[cfiloruxz]", RegexOptions.Compiled); + private static readonly Regex MRegex = new(@"[ADGJMPSV]", RegexOptions.Compiled); + private static readonly Regex ARegex = new(@"[BEHKNQTWY]", RegexOptions.Compiled); + private static readonly Regex RRegex = new(@"[CFILORUXZ]", RegexOptions.Compiled); public override void Initialize() @@ -28,6 +31,9 @@ public string Accentuate(string message) message = mRegex.Replace(message, "m"); message = aRegex.Replace(message, "a"); message = rRegex.Replace(message, "r"); + message = MRegex.Replace(message, "M"); + message = ARegex.Replace(message, "A"); + message = RRegex.Replace(message, "R"); return message; } From bb5d848516fb3169c2f706e46eebd137c739a4d9 Mon Sep 17 00:00:00 2001 From: Finket <42383212+Finket@users.noreply.github.com> Date: Wed, 6 Mar 2024 14:53:07 +0200 Subject: [PATCH 41/59] Remove Finket's grubby mitts from comments that aren't hers Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> --- Content.Client/Chat/Managers/ChatManager.cs | 6 +++--- .../Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs | 1 - .../SimpleStation14/Chat/SimpleStationChatSystem.cs | 2 +- .../Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs | 2 ++ 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Content.Client/Chat/Managers/ChatManager.cs b/Content.Client/Chat/Managers/ChatManager.cs index 70336fe99c..009579df98 100644 --- a/Content.Client/Chat/Managers/ChatManager.cs +++ b/Content.Client/Chat/Managers/ChatManager.cs @@ -14,7 +14,7 @@ internal sealed class ChatManager : IChatManager [Dependency] private readonly IEntitySystemManager _systems = default!; private ISawmill _sawmill = default!; - public event Action? PermissionsUpdated; //Nyano - Summary: need to be able to update perms for new psionics + public event Action? PermissionsUpdated; //Nyano - Summary: need to be able to update perms for new psionics. public void Initialize() { _sawmill = Logger.GetSawmill("chat"); @@ -67,7 +67,7 @@ public void SendMessage(string text, ChatSelectChannel channel) _consoleHost.ExecuteCommand($"whisper \"{CommandParsing.Escape(str)}\""); break; - //Nyano - Summary: sends the command for telepath communication + //Nyano - Summary: sends the command for telepath communication. case ChatSelectChannel.Telepathic: _consoleHost.ExecuteCommand($"tsay \"{CommandParsing.Escape(str)}\""); break; @@ -81,7 +81,7 @@ public void SendMessage(string text, ChatSelectChannel channel) throw new ArgumentOutOfRangeException(nameof(channel), channel, null); } } - //Nyano - Summary: fires off the update permissions script + //Nyano - Summary: fires off the update permissions script. public void UpdatePermissions() { PermissionsUpdated?.Invoke(); diff --git a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs index 7f8e49b382..7c853cdf01 100644 --- a/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs +++ b/Content.Client/SimpleStation14/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs @@ -86,7 +86,6 @@ public override void Update(float frameTime) const float min = 0.45f; const float max = 0.75f; - // TODO This math doesn't match the comments, figure out which is correct comp.TintIntensity = Math.Clamp(min + (comp.PowerLevel / comp.PowerLevelMax) / 3, min, max); UpdateShader(comp.TintColor, comp.TintIntensity); diff --git a/Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs b/Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs index 90308de38d..6655e023d8 100644 --- a/Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs +++ b/Content.Server/SimpleStation14/Chat/SimpleStationChatSystem.cs @@ -16,7 +16,7 @@ namespace Content.Server.SimpleStation14.Chat { /// - /// Extensions for Parkstation's chat stuff + /// Extensions for Parkstation's chat stuff /// public sealed class SimpleStationChatSystem : EntitySystem { diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs index 7c3730f5fe..d69280bc88 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs @@ -77,6 +77,7 @@ public override void Update(float frameTime) // Not a light we should affect if (!_entity.TryGetComponent(light, out ShadowkinLightComponent? shadowkinLight)) continue; + // Not powered, undo changes if (_entity.TryGetComponent(light, out PoweredLightComponent? powered) && !powered.On) { @@ -98,6 +99,7 @@ public override void Update(float frameTime) shadowkin.DarkenedLights.Remove(light); continue; } + // 3% chance to remove the attached entity so it can become another Shadowkin's light if (shadowkinLight.AttachedEntity == uid) { From 00e486f1516c6bb04434f35164b4a106194ad6ae Mon Sep 17 00:00:00 2001 From: Finket Date: Mon, 18 Mar 2024 17:59:30 +0200 Subject: [PATCH 42/59] Fix some dependency namespaces --- .../Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs | 3 +-- Content.Server/Parkstation/Chat/SimpleStationChatSystem.cs | 3 +-- .../Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs b/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs index 25037d348a..50fa6dd4a7 100644 --- a/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs +++ b/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs @@ -1,12 +1,11 @@ using Content.Client.Parkstation.Overlays.Shaders; using Content.Shared.GameTicking; using Content.Shared.Humanoid; -using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.Parkstation.Species.Shadowkin.Components; using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Shared.Player; -using ShadowkinComponent = Content.Shared.Parkstation.Species.Shadowkin.Components.ShadowkinComponent; namespace Content.Client.Parkstation.Species.Shadowkin.Systems; diff --git a/Content.Server/Parkstation/Chat/SimpleStationChatSystem.cs b/Content.Server/Parkstation/Chat/SimpleStationChatSystem.cs index d4fbe387cb..678ac0bcfb 100644 --- a/Content.Server/Parkstation/Chat/SimpleStationChatSystem.cs +++ b/Content.Server/Parkstation/Chat/SimpleStationChatSystem.cs @@ -6,10 +6,9 @@ using Content.Server.Parkstation.Speech.EntitySystems; using Content.Shared.Chat; using Content.Shared.Database; -using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.Parkstation.Species.Shadowkin.Components; using Robust.Shared.Network; using Robust.Shared.Player; -using EmpathyChatComponent = Content.Shared.Parkstation.Species.Shadowkin.Components.EmpathyChatComponent; namespace Content.Server.Parkstation.Chat { diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs index 28297676cb..6405d883ef 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Darken.cs @@ -1,10 +1,9 @@ using System.Linq; using Content.Server.Light.Components; using Content.Server.Parkstation.Species.Shadowkin.Components; -using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.Parkstation.Species.Shadowkin.Components; using Robust.Server.GameObjects; using Robust.Shared.Random; -using ShadowkinDarkSwappedComponent = Content.Shared.Parkstation.Species.Shadowkin.Components.ShadowkinDarkSwappedComponent; namespace Content.Server.Parkstation.Species.Shadowkin.Systems; From 6482129470044068275828cf7b613c9ece533f3f Mon Sep 17 00:00:00 2001 From: Finket Date: Mon, 18 Mar 2024 18:03:27 +0200 Subject: [PATCH 43/59] Fix more dependency namespaces --- Content.Client/Parkstation/Chat/ShadowkinChatUpdateSystem.cs | 3 +-- .../Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs | 3 +-- .../Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs | 3 +-- .../Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs | 4 +--- .../Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs | 3 +-- .../Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs | 3 +-- .../Species/Shadowkin/Systems/ShadowkinPowerSystem.cs | 2 -- .../Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs | 3 --- .../Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.cs | 3 --- 9 files changed, 6 insertions(+), 21 deletions(-) diff --git a/Content.Client/Parkstation/Chat/ShadowkinChatUpdateSystem.cs b/Content.Client/Parkstation/Chat/ShadowkinChatUpdateSystem.cs index 6f395794fe..bae216a03d 100644 --- a/Content.Client/Parkstation/Chat/ShadowkinChatUpdateSystem.cs +++ b/Content.Client/Parkstation/Chat/ShadowkinChatUpdateSystem.cs @@ -1,7 +1,6 @@ using Content.Client.Chat.Managers; -using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.Parkstation.Species.Shadowkin.Components; using Robust.Client.Player; -using EmpathyChatComponent = Content.Shared.Parkstation.Species.Shadowkin.Components.EmpathyChatComponent; namespace Content.Client.Parkstation.Chat { diff --git a/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs b/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs index 02be926abb..2cde60487c 100644 --- a/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs +++ b/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs @@ -1,10 +1,9 @@ using Content.Client.Parkstation.Overlays.Shaders; using Content.Shared.Humanoid; -using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.Parkstation.Species.Shadowkin.Components; using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Shared.Player; -using ShadowkinDarkSwappedComponent = Content.Shared.Parkstation.Species.Shadowkin.Components.ShadowkinDarkSwappedComponent; namespace Content.Client.Parkstation.Species.Shadowkin.Systems; diff --git a/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs b/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs index 954c6ca222..37583553e6 100644 --- a/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs +++ b/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs @@ -1,8 +1,7 @@ using Content.Shared.Humanoid; using Content.Shared.Parkstation.Species.Shadowkin.Events; -using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.Parkstation.Species.Shadowkin.Components; using Robust.Client.GameObjects; -using ShadowkinComponent = Content.Shared.Parkstation.Species.Shadowkin.Components.ShadowkinComponent; namespace Content.Client.Parkstation.Species.Shadowkin.Systems; diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 5c043ef524..98ec0b7a9f 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -10,15 +10,13 @@ using Content.Shared.Eye; using Content.Shared.Ghost; using Content.Shared.Parkstation.Species.Shadowkin.Events; -using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.Parkstation.Species.Shadowkin.Components; using Content.Shared.Stealth; using Content.Shared.Stealth.Components; using Robust.Server.GameObjects; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Prototypes; -using ShadowkinComponent = Content.Shared.Parkstation.Species.Shadowkin.Components.ShadowkinComponent; -using ShadowkinDarkSwappedComponent = Content.Shared.Parkstation.Species.Shadowkin.Components.ShadowkinDarkSwappedComponent; namespace Content.Server.Parkstation.Species.Shadowkin.Systems; diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index dceda5c84e..318ded033b 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -2,9 +2,8 @@ using Content.Shared.Actions; using Content.Shared.Bed.Sleep; using Content.Shared.Parkstation.Species.Shadowkin.Events; -using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.Parkstation.Species.Shadowkin.Components; using Robust.Shared.Prototypes; -using ShadowkinComponent = Content.Shared.Parkstation.Species.Shadowkin.Components.ShadowkinComponent; namespace Content.Server.Parkstation.Species.Shadowkin.Systems; diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index 2f7be00be0..f18cc6da53 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -6,11 +6,10 @@ using Content.Shared.Damage.Systems; using Content.Shared.Parkstation.Species.Shadowkin.Events; using Content.Shared.Pulling.Components; -using Content.Shared.SimpleStation14.Species.Shadowkin.Components; +using Content.Shared.Parkstation.Species.Shadowkin.Components; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Prototypes; -using ShadowkinComponent = Content.Shared.Parkstation.Species.Shadowkin.Components.ShadowkinComponent; namespace Content.Server.Parkstation.Species.Shadowkin.Systems; diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs index 59e36f38c4..f3befa418a 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs @@ -2,9 +2,7 @@ using Content.Shared.Alert; using Content.Shared.Parkstation.Species.Shadowkin.Components; using Content.Shared.Parkstation.Species.Shadowkin.Events; -using Content.Shared.SimpleStation14.Species.Shadowkin.Components; using Robust.Shared.Utility; -using ShadowkinComponent = Content.Shared.Parkstation.Species.Shadowkin.Components.ShadowkinComponent; namespace Content.Server.Parkstation.Species.Shadowkin.Systems; diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs index c24fd4e719..434e78f30e 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs @@ -8,10 +8,7 @@ using Content.Shared.Parkstation.Species.Shadowkin.Components; using Content.Shared.Parkstation.Species.Shadowkin.Events; using Content.Shared.Popups; -using Content.Shared.SimpleStation14.Species.Shadowkin.Components; using Robust.Shared.Prototypes; -using ShadowkinComponent = Content.Shared.Parkstation.Species.Shadowkin.Components.ShadowkinComponent; -using ShadowkinDarkSwappedComponent = Content.Shared.Parkstation.Species.Shadowkin.Components.ShadowkinDarkSwappedComponent; namespace Content.Server.Parkstation.Species.Shadowkin.Systems; diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.cs index a9daa5fb70..626217612c 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.cs @@ -9,11 +9,8 @@ using Content.Shared.Parkstation.Species.Shadowkin.Components; using Content.Shared.Parkstation.Species.Shadowkin.Events; using Content.Shared.Physics; -using Content.Shared.SimpleStation14.Species.Shadowkin.Components; using Robust.Shared.Map; using Robust.Shared.Random; -using ShadowkinComponent = Content.Shared.Parkstation.Species.Shadowkin.Components.ShadowkinComponent; -using ShadowkinDarkSwappedComponent = Content.Shared.Parkstation.Species.Shadowkin.Components.ShadowkinDarkSwappedComponent; namespace Content.Server.Parkstation.Species.Shadowkin.Systems; From 65466c8d9859a6e153120f07bb09594330ea9c6f Mon Sep 17 00:00:00 2001 From: Finket Date: Mon, 18 Mar 2024 18:11:26 +0200 Subject: [PATCH 44/59] Remove redundant hardsuits.yml --- .../Clothing/OuterClothing/hardsuits.yml | 28 ------------------- 1 file changed, 28 deletions(-) delete mode 100644 Resources/Prototypes/Parkstation/Entities/Clothing/OuterClothing/hardsuits.yml diff --git a/Resources/Prototypes/Parkstation/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Parkstation/Entities/Clothing/OuterClothing/hardsuits.yml deleted file mode 100644 index 43f01db5ec..0000000000 --- a/Resources/Prototypes/Parkstation/Entities/Clothing/OuterClothing/hardsuits.yml +++ /dev/null @@ -1,28 +0,0 @@ -- type: entity - parent: ClothingOuterHardsuitBase - id: ClothingOuterHardsuitHoP - name: head of personnel's hardsuit - description: A stylish hardsuit for only the most esteemed crew members. Doesn't offer much damage protection. - components: - - type: Sprite - sprite: Parkstation/Clothing/OuterClothing/Hardsuits/hopsuit.rsi - - type: Clothing - sprite: Parkstation/Clothing/OuterClothing/Hardsuits/hopsuit.rsi - - type: PressureProtection - highPressureMultiplier: 0.02 - lowPressureMultiplier: 4500 - - type: ClothingSpeedModifier - walkModifier: 0.8 - sprintModifier: 0.8 - - type: Armor - modifiers: - coefficients: - Blunt: 0.90 - Slash: 0.8 - Piercing: 0.90 - Heat: 0.8 - Radiation: 0.6 - - type: ExplosionResistance - damageCoefficient: 0.8 - - type: ToggleableClothing - clothingPrototype: ClothingHeadHelmetHardsuitHoP From bece17ebc5a2e857c51d3e6cdde770bde320a10a Mon Sep 17 00:00:00 2001 From: Finket Date: Mon, 18 Mar 2024 18:16:23 +0200 Subject: [PATCH 45/59] Move from SimpleStation14 to Parkstation namespaces --- Content.Server/Chat/Systems/ChatSystem.cs | 4 ++-- ...tationChatSystem.cs => ParkstationChatSystem.cs} | 2 +- .../Shadowkin/Events/ShadowkinEvents.Powers.cs | 6 +++--- .../Effects/Shadowkin/Powers/darkswapoff.ogg | Bin .../Effects/Shadowkin/Powers/darkswapon.ogg | Bin .../Shadowkin/Powers/futuristic-teleport.ogg | Bin .../Effects/Shadowkin/Powers/license.txt | 0 .../Effects/Shadowkin/Powers/teleport.ogg | Bin .../Actions/shadowkin_icons.rsi/darkswap.png | Bin .../Interface/Actions/shadowkin_icons.rsi/meta.json | 0 .../Interface/Actions/shadowkin_icons.rsi/rest.png | Bin .../Actions/shadowkin_icons.rsi/teleport.png | Bin .../Interface/Alerts/shadowkin_power.rsi/meta.json | 0 .../Interface/Alerts/shadowkin_power.rsi/power0.png | Bin .../Interface/Alerts/shadowkin_power.rsi/power1.png | Bin .../Interface/Alerts/shadowkin_power.rsi/power2.png | Bin .../Interface/Alerts/shadowkin_power.rsi/power3.png | Bin .../Interface/Alerts/shadowkin_power.rsi/power4.png | Bin .../Interface/Alerts/shadowkin_power.rsi/power5.png | Bin .../Interface/Alerts/shadowkin_power.rsi/power6.png | Bin .../Interface/Alerts/shadowkin_power.rsi/power7.png | Bin .../Mobs/Species/shadowkin.rsi/eyes.png | Bin .../Mobs/Species/shadowkin.rsi/full.png | Bin .../Mobs/Species/shadowkin.rsi/head_f.png | Bin .../Mobs/Species/shadowkin.rsi/head_m.png | Bin .../Mobs/Species/shadowkin.rsi/l_arm.png | Bin .../Mobs/Species/shadowkin.rsi/l_foot.png | Bin .../Mobs/Species/shadowkin.rsi/l_hand.png | Bin .../Mobs/Species/shadowkin.rsi/l_leg.png | Bin .../Mobs/Species/shadowkin.rsi/meta.json | 0 .../Mobs/Species/shadowkin.rsi/r_arm.png | Bin .../Mobs/Species/shadowkin.rsi/r_foot.png | Bin .../Mobs/Species/shadowkin.rsi/r_hand.png | Bin .../Mobs/Species/shadowkin.rsi/r_leg.png | Bin .../Mobs/Species/shadowkin.rsi/torso_f.png | Bin .../Mobs/Species/shadowkin.rsi/torso_m.png | Bin .../Objects/Fun/Plushies/shadowkin.rsi/meta.json | 0 .../Fun/Plushies/shadowkin.rsi/shadowkin.png | Bin .../Shaders/color_tint.swsl | 0 .../Shaders/ethereal.swsl | 0 40 files changed, 6 insertions(+), 6 deletions(-) rename Content.Server/Parkstation/Chat/{SimpleStationChatSystem.cs => ParkstationChatSystem.cs} (97%) rename Resources/Audio/{SimpleStation14 => Parkstation}/Effects/Shadowkin/Powers/darkswapoff.ogg (100%) rename Resources/Audio/{SimpleStation14 => Parkstation}/Effects/Shadowkin/Powers/darkswapon.ogg (100%) rename Resources/Audio/{SimpleStation14 => Parkstation}/Effects/Shadowkin/Powers/futuristic-teleport.ogg (100%) rename Resources/Audio/{SimpleStation14 => Parkstation}/Effects/Shadowkin/Powers/license.txt (100%) rename Resources/Audio/{SimpleStation14 => Parkstation}/Effects/Shadowkin/Powers/teleport.ogg (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Interface/Actions/shadowkin_icons.rsi/darkswap.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Interface/Actions/shadowkin_icons.rsi/meta.json (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Interface/Actions/shadowkin_icons.rsi/rest.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Interface/Actions/shadowkin_icons.rsi/teleport.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Interface/Alerts/shadowkin_power.rsi/meta.json (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Interface/Alerts/shadowkin_power.rsi/power0.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Interface/Alerts/shadowkin_power.rsi/power1.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Interface/Alerts/shadowkin_power.rsi/power2.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Interface/Alerts/shadowkin_power.rsi/power3.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Interface/Alerts/shadowkin_power.rsi/power4.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Interface/Alerts/shadowkin_power.rsi/power5.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Interface/Alerts/shadowkin_power.rsi/power6.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Interface/Alerts/shadowkin_power.rsi/power7.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Mobs/Species/shadowkin.rsi/eyes.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Mobs/Species/shadowkin.rsi/full.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Mobs/Species/shadowkin.rsi/head_f.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Mobs/Species/shadowkin.rsi/head_m.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Mobs/Species/shadowkin.rsi/l_arm.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Mobs/Species/shadowkin.rsi/l_foot.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Mobs/Species/shadowkin.rsi/l_hand.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Mobs/Species/shadowkin.rsi/l_leg.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Mobs/Species/shadowkin.rsi/meta.json (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Mobs/Species/shadowkin.rsi/r_arm.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Mobs/Species/shadowkin.rsi/r_foot.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Mobs/Species/shadowkin.rsi/r_hand.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Mobs/Species/shadowkin.rsi/r_leg.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Mobs/Species/shadowkin.rsi/torso_f.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Mobs/Species/shadowkin.rsi/torso_m.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Objects/Fun/Plushies/shadowkin.rsi/meta.json (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Objects/Fun/Plushies/shadowkin.rsi/shadowkin.png (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Shaders/color_tint.swsl (100%) rename Resources/Textures/{SimpleStation14 => Parkstation}/Shaders/ethereal.swsl (100%) diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 4476f7d7b0..70faaa7c4e 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -60,7 +60,7 @@ public sealed partial class ChatSystem : SharedChatSystem [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!; [Dependency] private readonly StationSystem _stationSystem = default!; [Dependency] private readonly MobStateSystem _mobStateSystem = default!; - [Dependency] private readonly SimpleStationChatSystem _simpleStationChatSystem = default!; // Parkstation-EmpathyChat + [Dependency] private readonly ParkstationChatSystem _parkstationChatSystem = default!; // Parkstation-EmpathyChat [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly ReplacementAccentSystem _wordreplacement = default!; @@ -286,7 +286,7 @@ public void TrySendInGameICMessage( break; // Parkstation-EmpathyChat case InGameICChatType.Empathy: - _simpleStationChatSystem.SendEmpathyChat(source, message, range == ChatTransmitRange.HideChat); + _parkstationChatSystem.SendEmpathyChat(source, message, range == ChatTransmitRange.HideChat); break; } } diff --git a/Content.Server/Parkstation/Chat/SimpleStationChatSystem.cs b/Content.Server/Parkstation/Chat/ParkstationChatSystem.cs similarity index 97% rename from Content.Server/Parkstation/Chat/SimpleStationChatSystem.cs rename to Content.Server/Parkstation/Chat/ParkstationChatSystem.cs index 678ac0bcfb..9872d9b69e 100644 --- a/Content.Server/Parkstation/Chat/SimpleStationChatSystem.cs +++ b/Content.Server/Parkstation/Chat/ParkstationChatSystem.cs @@ -15,7 +15,7 @@ namespace Content.Server.Parkstation.Chat /// /// Extensions for Parkstation's chat stuff /// - public sealed class SimpleStationChatSystem : EntitySystem + public sealed class ParkstationChatSystem : EntitySystem { [Dependency] private readonly IAdminManager _adminManager = default!; [Dependency] private readonly IChatManager _chatManager = default!; diff --git a/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs b/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs index 5ebf3eebfc..33f9d29e42 100644 --- a/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs +++ b/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs @@ -12,7 +12,7 @@ namespace Content.Shared.Parkstation.Species.Shadowkin.Events; public sealed partial class ShadowkinTeleportEvent : WorldTargetActionEvent, ISpeakSpell { [DataField("sound")] - public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/SimpleStation14/Effects/Shadowkin/Powers/teleport.ogg"); + public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Parkstation/Effects/Shadowkin/Powers/teleport.ogg"); [DataField("volume")] public float Volume = 5f; @@ -35,13 +35,13 @@ public sealed partial class ShadowkinTeleportEvent : WorldTargetActionEvent, ISp public sealed partial class ShadowkinDarkSwapEvent : InstantActionEvent, ISpeakSpell { [DataField("soundOn")] - public SoundSpecifier SoundOn = new SoundPathSpecifier("/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapon.ogg"); + public SoundSpecifier SoundOn = new SoundPathSpecifier("/Audio/Parkstation/Effects/Shadowkin/Powers/darkswapon.ogg"); [DataField("volumeOn")] public float VolumeOn = 5f; [DataField("soundOff")] - public SoundSpecifier SoundOff = new SoundPathSpecifier("/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapoff.ogg"); + public SoundSpecifier SoundOff = new SoundPathSpecifier("/Audio/Parkstation/Effects/Shadowkin/Powers/darkswapoff.ogg"); [DataField("volumeOff")] public float VolumeOff = 5f; diff --git a/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapoff.ogg b/Resources/Audio/Parkstation/Effects/Shadowkin/Powers/darkswapoff.ogg similarity index 100% rename from Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapoff.ogg rename to Resources/Audio/Parkstation/Effects/Shadowkin/Powers/darkswapoff.ogg diff --git a/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapon.ogg b/Resources/Audio/Parkstation/Effects/Shadowkin/Powers/darkswapon.ogg similarity index 100% rename from Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/darkswapon.ogg rename to Resources/Audio/Parkstation/Effects/Shadowkin/Powers/darkswapon.ogg diff --git a/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/futuristic-teleport.ogg b/Resources/Audio/Parkstation/Effects/Shadowkin/Powers/futuristic-teleport.ogg similarity index 100% rename from Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/futuristic-teleport.ogg rename to Resources/Audio/Parkstation/Effects/Shadowkin/Powers/futuristic-teleport.ogg diff --git a/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/license.txt b/Resources/Audio/Parkstation/Effects/Shadowkin/Powers/license.txt similarity index 100% rename from Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/license.txt rename to Resources/Audio/Parkstation/Effects/Shadowkin/Powers/license.txt diff --git a/Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/teleport.ogg b/Resources/Audio/Parkstation/Effects/Shadowkin/Powers/teleport.ogg similarity index 100% rename from Resources/Audio/SimpleStation14/Effects/Shadowkin/Powers/teleport.ogg rename to Resources/Audio/Parkstation/Effects/Shadowkin/Powers/teleport.ogg diff --git a/Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/darkswap.png b/Resources/Textures/Parkstation/Interface/Actions/shadowkin_icons.rsi/darkswap.png similarity index 100% rename from Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/darkswap.png rename to Resources/Textures/Parkstation/Interface/Actions/shadowkin_icons.rsi/darkswap.png diff --git a/Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/meta.json b/Resources/Textures/Parkstation/Interface/Actions/shadowkin_icons.rsi/meta.json similarity index 100% rename from Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/meta.json rename to Resources/Textures/Parkstation/Interface/Actions/shadowkin_icons.rsi/meta.json diff --git a/Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/rest.png b/Resources/Textures/Parkstation/Interface/Actions/shadowkin_icons.rsi/rest.png similarity index 100% rename from Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/rest.png rename to Resources/Textures/Parkstation/Interface/Actions/shadowkin_icons.rsi/rest.png diff --git a/Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/teleport.png b/Resources/Textures/Parkstation/Interface/Actions/shadowkin_icons.rsi/teleport.png similarity index 100% rename from Resources/Textures/SimpleStation14/Interface/Actions/shadowkin_icons.rsi/teleport.png rename to Resources/Textures/Parkstation/Interface/Actions/shadowkin_icons.rsi/teleport.png diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/meta.json b/Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/meta.json similarity index 100% rename from Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/meta.json rename to Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/meta.json diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power0.png b/Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power0.png similarity index 100% rename from Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power0.png rename to Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power0.png diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power1.png b/Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power1.png similarity index 100% rename from Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power1.png rename to Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power1.png diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power2.png b/Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power2.png similarity index 100% rename from Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power2.png rename to Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power2.png diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power3.png b/Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power3.png similarity index 100% rename from Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power3.png rename to Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power3.png diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power4.png b/Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power4.png similarity index 100% rename from Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power4.png rename to Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power4.png diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power5.png b/Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power5.png similarity index 100% rename from Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power5.png rename to Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power5.png diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power6.png b/Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power6.png similarity index 100% rename from Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power6.png rename to Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power6.png diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power7.png b/Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power7.png similarity index 100% rename from Resources/Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi/power7.png rename to Resources/Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi/power7.png diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/eyes.png b/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/eyes.png similarity index 100% rename from Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/eyes.png rename to Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/eyes.png diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/full.png b/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/full.png similarity index 100% rename from Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/full.png rename to Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/full.png diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/head_f.png b/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/head_f.png similarity index 100% rename from Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/head_f.png rename to Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/head_f.png diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/head_m.png b/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/head_m.png similarity index 100% rename from Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/head_m.png rename to Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/head_m.png diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_arm.png b/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_arm.png similarity index 100% rename from Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_arm.png rename to Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_arm.png diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_foot.png b/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_foot.png similarity index 100% rename from Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_foot.png rename to Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_foot.png diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_hand.png b/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_hand.png similarity index 100% rename from Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_hand.png rename to Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_hand.png diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_leg.png b/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_leg.png similarity index 100% rename from Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/l_leg.png rename to Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_leg.png diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/meta.json b/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/meta.json similarity index 100% rename from Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/meta.json rename to Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/meta.json diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_arm.png b/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_arm.png similarity index 100% rename from Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_arm.png rename to Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_arm.png diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_foot.png b/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_foot.png similarity index 100% rename from Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_foot.png rename to Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_foot.png diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_hand.png b/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_hand.png similarity index 100% rename from Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_hand.png rename to Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_hand.png diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_leg.png b/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_leg.png similarity index 100% rename from Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/r_leg.png rename to Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_leg.png diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/torso_f.png b/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/torso_f.png similarity index 100% rename from Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/torso_f.png rename to Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/torso_f.png diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/torso_m.png b/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/torso_m.png similarity index 100% rename from Resources/Textures/SimpleStation14/Mobs/Species/shadowkin.rsi/torso_m.png rename to Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/torso_m.png diff --git a/Resources/Textures/SimpleStation14/Objects/Fun/Plushies/shadowkin.rsi/meta.json b/Resources/Textures/Parkstation/Objects/Fun/Plushies/shadowkin.rsi/meta.json similarity index 100% rename from Resources/Textures/SimpleStation14/Objects/Fun/Plushies/shadowkin.rsi/meta.json rename to Resources/Textures/Parkstation/Objects/Fun/Plushies/shadowkin.rsi/meta.json diff --git a/Resources/Textures/SimpleStation14/Objects/Fun/Plushies/shadowkin.rsi/shadowkin.png b/Resources/Textures/Parkstation/Objects/Fun/Plushies/shadowkin.rsi/shadowkin.png similarity index 100% rename from Resources/Textures/SimpleStation14/Objects/Fun/Plushies/shadowkin.rsi/shadowkin.png rename to Resources/Textures/Parkstation/Objects/Fun/Plushies/shadowkin.rsi/shadowkin.png diff --git a/Resources/Textures/SimpleStation14/Shaders/color_tint.swsl b/Resources/Textures/Parkstation/Shaders/color_tint.swsl similarity index 100% rename from Resources/Textures/SimpleStation14/Shaders/color_tint.swsl rename to Resources/Textures/Parkstation/Shaders/color_tint.swsl diff --git a/Resources/Textures/SimpleStation14/Shaders/ethereal.swsl b/Resources/Textures/Parkstation/Shaders/ethereal.swsl similarity index 100% rename from Resources/Textures/SimpleStation14/Shaders/ethereal.swsl rename to Resources/Textures/Parkstation/Shaders/ethereal.swsl From 912e6996ca5cc4442a86c7e7069af34f7d50086a Mon Sep 17 00:00:00 2001 From: Finket Date: Mon, 18 Mar 2024 18:18:43 +0200 Subject: [PATCH 46/59] Fix more namespace issues --- .../Content/Interaction/interaction-popup.ftl | 0 .../Content/Species/Shadowkin/shadowkin.ftl | 0 .../Prototypes/Alerts/shadowkin.ftl | 0 .../Prototypes/Magic/shadowkin.ftl | 0 .../Prototypes/Species/shadowkin.ftl | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename Resources/Locale/en-US/{simplestation14 => parkstation}/Content/Interaction/interaction-popup.ftl (100%) rename Resources/Locale/en-US/{simplestation14 => parkstation}/Content/Species/Shadowkin/shadowkin.ftl (100%) rename Resources/Locale/en-US/{simplestation14 => parkstation}/Prototypes/Alerts/shadowkin.ftl (100%) rename Resources/Locale/en-US/{simplestation14 => parkstation}/Prototypes/Magic/shadowkin.ftl (100%) rename Resources/Locale/en-US/{simplestation14 => parkstation}/Prototypes/Species/shadowkin.ftl (100%) diff --git a/Resources/Locale/en-US/simplestation14/Content/Interaction/interaction-popup.ftl b/Resources/Locale/en-US/parkstation/Content/Interaction/interaction-popup.ftl similarity index 100% rename from Resources/Locale/en-US/simplestation14/Content/Interaction/interaction-popup.ftl rename to Resources/Locale/en-US/parkstation/Content/Interaction/interaction-popup.ftl diff --git a/Resources/Locale/en-US/simplestation14/Content/Species/Shadowkin/shadowkin.ftl b/Resources/Locale/en-US/parkstation/Content/Species/Shadowkin/shadowkin.ftl similarity index 100% rename from Resources/Locale/en-US/simplestation14/Content/Species/Shadowkin/shadowkin.ftl rename to Resources/Locale/en-US/parkstation/Content/Species/Shadowkin/shadowkin.ftl diff --git a/Resources/Locale/en-US/simplestation14/Prototypes/Alerts/shadowkin.ftl b/Resources/Locale/en-US/parkstation/Prototypes/Alerts/shadowkin.ftl similarity index 100% rename from Resources/Locale/en-US/simplestation14/Prototypes/Alerts/shadowkin.ftl rename to Resources/Locale/en-US/parkstation/Prototypes/Alerts/shadowkin.ftl diff --git a/Resources/Locale/en-US/simplestation14/Prototypes/Magic/shadowkin.ftl b/Resources/Locale/en-US/parkstation/Prototypes/Magic/shadowkin.ftl similarity index 100% rename from Resources/Locale/en-US/simplestation14/Prototypes/Magic/shadowkin.ftl rename to Resources/Locale/en-US/parkstation/Prototypes/Magic/shadowkin.ftl diff --git a/Resources/Locale/en-US/simplestation14/Prototypes/Species/shadowkin.ftl b/Resources/Locale/en-US/parkstation/Prototypes/Species/shadowkin.ftl similarity index 100% rename from Resources/Locale/en-US/simplestation14/Prototypes/Species/shadowkin.ftl rename to Resources/Locale/en-US/parkstation/Prototypes/Species/shadowkin.ftl From e6698fe976dc487929e574f64731d1835cca2657 Mon Sep 17 00:00:00 2001 From: Finket Date: Mon, 18 Mar 2024 18:22:07 +0200 Subject: [PATCH 47/59] Move texture references to Parkstation namespace --- .../Parkstation/Alerts/shadowkin.yml | 16 +++++----- .../Entities/Body/Parts/shadowkin.yml | 4 +-- .../Entities/Mobs/Player/shadowkin.yml | 2 +- .../Parkstation/Entities/Objects/Fun/toys.yml | 2 +- .../Parkstation/Magic/shadowkin.yml | 6 ++-- .../Parkstation/Shaders/shaders.yml | 4 +-- .../Parkstation/Species/shadowkin.yml | 30 +++++++++---------- 7 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Resources/Prototypes/Parkstation/Alerts/shadowkin.yml b/Resources/Prototypes/Parkstation/Alerts/shadowkin.yml index 126441b79d..52bdb7c4ab 100644 --- a/Resources/Prototypes/Parkstation/Alerts/shadowkin.yml +++ b/Resources/Prototypes/Parkstation/Alerts/shadowkin.yml @@ -2,21 +2,21 @@ id: ShadowkinPower category: ShadowkinPower icons: - - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + - sprite: /Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi state: power0 - - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + - sprite: /Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi state: power1 - - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + - sprite: /Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi state: power2 - - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + - sprite: /Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi state: power3 - - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + - sprite: /Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi state: power4 - - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + - sprite: /Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi state: power5 - - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + - sprite: /Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi state: power6 - - sprite: /Textures/SimpleStation14/Interface/Alerts/shadowkin_power.rsi + - sprite: /Textures/Parkstation/Interface/Alerts/shadowkin_power.rsi state: power7 name: alerts-shadowkin-power-name description: alerts-shadowkin-power-desc diff --git a/Resources/Prototypes/Parkstation/Entities/Body/Parts/shadowkin.yml b/Resources/Prototypes/Parkstation/Entities/Body/Parts/shadowkin.yml index a28ca19701..7edfb6b7ec 100644 --- a/Resources/Prototypes/Parkstation/Entities/Body/Parts/shadowkin.yml +++ b/Resources/Prototypes/Parkstation/Entities/Body/Parts/shadowkin.yml @@ -6,9 +6,9 @@ components: - type: Sprite netsync: false - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi - type: Icon - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi - type: Damageable damageContainer: Biological - type: BodyPart diff --git a/Resources/Prototypes/Parkstation/Entities/Mobs/Player/shadowkin.yml b/Resources/Prototypes/Parkstation/Entities/Mobs/Player/shadowkin.yml index ec84316a87..a3394a2347 100644 --- a/Resources/Prototypes/Parkstation/Entities/Mobs/Player/shadowkin.yml +++ b/Resources/Prototypes/Parkstation/Entities/Mobs/Player/shadowkin.yml @@ -9,7 +9,7 @@ - type: Hunger - type: Thirst - type: Icon - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: full - type: Body prototype: Shadowkin diff --git a/Resources/Prototypes/Parkstation/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Parkstation/Entities/Objects/Fun/toys.yml index d3a9748354..b0bc44e90a 100644 --- a/Resources/Prototypes/Parkstation/Entities/Objects/Fun/toys.yml +++ b/Resources/Prototypes/Parkstation/Entities/Objects/Fun/toys.yml @@ -10,5 +10,5 @@ darken: true range: 4 - type: Sprite - sprite: SimpleStation14/Objects/Fun/Plushies/shadowkin.rsi + sprite: Parkstation/Objects/Fun/Plushies/shadowkin.rsi state: shadowkin diff --git a/Resources/Prototypes/Parkstation/Magic/shadowkin.yml b/Resources/Prototypes/Parkstation/Magic/shadowkin.yml index 42e60f6c0f..5aff780346 100644 --- a/Resources/Prototypes/Parkstation/Magic/shadowkin.yml +++ b/Resources/Prototypes/Parkstation/Magic/shadowkin.yml @@ -8,7 +8,7 @@ range: 32 itemIconStyle: NoItem icon: - sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi + sprite: Parkstation/Interface/Actions/shadowkin_icons.rsi state: teleport checkCanAccess: true repeat: true @@ -28,7 +28,7 @@ itemIconStyle: NoItem priority: -21 icon: - sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi + sprite: Parkstation/Interface/Actions/shadowkin_icons.rsi state: darkswap event: !type:ShadowkinDarkSwapEvent powerCostOn: 60 @@ -47,7 +47,7 @@ itemIconStyle: NoItem priority: -22 icon: - sprite: SimpleStation14/Interface/Actions/shadowkin_icons.rsi + sprite: Parkstation/Interface/Actions/shadowkin_icons.rsi state: rest checkCanInteract: false event: !type:ShadowkinRestEvent diff --git a/Resources/Prototypes/Parkstation/Shaders/shaders.yml b/Resources/Prototypes/Parkstation/Shaders/shaders.yml index b394e308c7..79e8ae2f8e 100644 --- a/Resources/Prototypes/Parkstation/Shaders/shaders.yml +++ b/Resources/Prototypes/Parkstation/Shaders/shaders.yml @@ -1,9 +1,9 @@ - type: shader id: ColorTint kind: source - path: "/Textures/SimpleStation14/Shaders/color_tint.swsl" + path: "/Textures/Parkstation/Shaders/color_tint.swsl" - type: shader id: Ethereal kind: source - path: "/Textures/SimpleStation14/Shaders/ethereal.swsl" + path: "/Textures/Parkstation/Shaders/ethereal.swsl" diff --git a/Resources/Prototypes/Parkstation/Species/shadowkin.yml b/Resources/Prototypes/Parkstation/Species/shadowkin.yml index 269ea2e4be..d0c5388b35 100644 --- a/Resources/Prototypes/Parkstation/Species/shadowkin.yml +++ b/Resources/Prototypes/Parkstation/Species/shadowkin.yml @@ -73,89 +73,89 @@ - type: humanoidBaseSprite id: MobShadowkinHead baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: head_m - type: humanoidBaseSprite id: MobShadowkinHeadMale baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: head_m - type: humanoidBaseSprite id: MobShadowkinHeadFemale baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: head_f - type: humanoidBaseSprite id: MobShadowkinTorso baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: torso_m - type: humanoidBaseSprite id: MobShadowkinTorsoMale baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: torso_m - type: humanoidBaseSprite id: MobShadowkinTorsoFemale baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: torso_f - type: humanoidBaseSprite id: MobShadowkinLLeg baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: l_leg - type: humanoidBaseSprite id: MobShadowkinLHand baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: l_hand - type: humanoidBaseSprite id: MobShadowkinEyes baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: eyes - type: humanoidBaseSprite id: MobShadowkinLArm baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: l_arm - type: humanoidBaseSprite id: MobShadowkinLFoot baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: l_foot - type: humanoidBaseSprite id: MobShadowkinRLeg baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: r_leg - type: humanoidBaseSprite id: MobShadowkinRHand baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: r_hand - type: humanoidBaseSprite id: MobShadowkinRArm baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: r_arm - type: humanoidBaseSprite id: MobShadowkinRFoot baseSprite: - sprite: SimpleStation14/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/shadowkin.rsi state: r_foot From cdf7f1cac1208a5b471196fb805515ccef9e1412 Mon Sep 17 00:00:00 2001 From: Finket Date: Sat, 27 Apr 2024 13:32:05 +0300 Subject: [PATCH 48/59] Update LocalPlayer to LocalEntity where applicable --- .../Parkstation/Chat/ShadowkinChatUpdateSystem.cs | 2 +- .../Parkstation/Overlays/Shaders/ColorTintOverlay.cs | 2 +- .../Parkstation/Overlays/Shaders/EtherealOverlay.cs | 2 +- .../Overlays/Shaders/IgnoreHumanoidWithComponentOverlay.cs | 2 +- .../Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs | 4 ++-- .../Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs | 6 +++--- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Content.Client/Parkstation/Chat/ShadowkinChatUpdateSystem.cs b/Content.Client/Parkstation/Chat/ShadowkinChatUpdateSystem.cs index bae216a03d..c6359c5035 100644 --- a/Content.Client/Parkstation/Chat/ShadowkinChatUpdateSystem.cs +++ b/Content.Client/Parkstation/Chat/ShadowkinChatUpdateSystem.cs @@ -19,7 +19,7 @@ public override void Initialize() } - public EmpathyChatComponent? Player => CompOrNull(_playerManager.LocalPlayer?.ControlledEntity); + public EmpathyChatComponent? Player => CompOrNull(_playerManager.LocalEntity); public bool IsShadowkin => Player != null; private void OnInit(EntityUid uid, EmpathyChatComponent component, ComponentInit args) diff --git a/Content.Client/Parkstation/Overlays/Shaders/ColorTintOverlay.cs b/Content.Client/Parkstation/Overlays/Shaders/ColorTintOverlay.cs index b0928de31f..b34291d827 100644 --- a/Content.Client/Parkstation/Overlays/Shaders/ColorTintOverlay.cs +++ b/Content.Client/Parkstation/Overlays/Shaders/ColorTintOverlay.cs @@ -43,7 +43,7 @@ public ColorTintOverlay() protected override void Draw(in OverlayDrawArgs args) { if (ScreenTexture == null || - _player.LocalPlayer?.ControlledEntity is not { Valid: true } player || + _player.LocalEntity is not { Valid: true } player || Comp != null && !_entity.HasComponent(player, Comp.GetType())) return; diff --git a/Content.Client/Parkstation/Overlays/Shaders/EtherealOverlay.cs b/Content.Client/Parkstation/Overlays/Shaders/EtherealOverlay.cs index e5ae6ec266..40ae3108c0 100644 --- a/Content.Client/Parkstation/Overlays/Shaders/EtherealOverlay.cs +++ b/Content.Client/Parkstation/Overlays/Shaders/EtherealOverlay.cs @@ -25,7 +25,7 @@ public EtherealOverlay() protected override void Draw(in OverlayDrawArgs args) { if (ScreenTexture == null) return; - if (_player.LocalPlayer?.ControlledEntity is not { Valid: true } player) return; + if (_player.LocalEntity is not { Valid: true } player) return; _shader?.SetParameter("SCREEN_TEXTURE", ScreenTexture); diff --git a/Content.Client/Parkstation/Overlays/Shaders/IgnoreHumanoidWithComponentOverlay.cs b/Content.Client/Parkstation/Overlays/Shaders/IgnoreHumanoidWithComponentOverlay.cs index 0f21c02d33..91c249cf73 100644 --- a/Content.Client/Parkstation/Overlays/Shaders/IgnoreHumanoidWithComponentOverlay.cs +++ b/Content.Client/Parkstation/Overlays/Shaders/IgnoreHumanoidWithComponentOverlay.cs @@ -30,7 +30,7 @@ protected override void Draw(in OverlayDrawArgs args) foreach (var humanoid in _entityManager.EntityQuery(true)) { - if (_playerManager.LocalPlayer?.ControlledEntity == humanoid.Owner) + if (_playerManager.LocalEntity == humanoid.Owner) continue; var cont = true; diff --git a/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs b/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs index 2cde60487c..cbda937ac5 100644 --- a/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs +++ b/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwapped.cs @@ -34,7 +34,7 @@ public override void Initialize() private void OnStartup(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentStartup args) { - if (_player.LocalPlayer?.ControlledEntity != uid) + if (_player.LocalEntity != uid) return; AddOverlay(); @@ -42,7 +42,7 @@ private void OnStartup(EntityUid uid, ShadowkinDarkSwappedComponent component, C private void OnShutdown(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentShutdown args) { - if (_player.LocalPlayer?.ControlledEntity != uid) + if (_player.LocalEntity != uid) return; RemoveOverlay(); diff --git a/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs b/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs index 50fa6dd4a7..e6cabf01c5 100644 --- a/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs +++ b/Content.Client/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Tint.cs @@ -39,7 +39,7 @@ public override void Initialize() private void OnStartup(EntityUid uid, ShadowkinComponent component, ComponentStartup args) { - if (_player.LocalPlayer?.ControlledEntity != uid) + if (_player.LocalEntity != uid) return; _overlay.AddOverlay(_tintOverlay); @@ -47,7 +47,7 @@ private void OnStartup(EntityUid uid, ShadowkinComponent component, ComponentSta private void OnShutdown(EntityUid uid, ShadowkinComponent component, ComponentShutdown args) { - if (_player.LocalPlayer?.ControlledEntity != uid) + if (_player.LocalEntity != uid) return; _overlay.RemoveOverlay(_tintOverlay); @@ -73,7 +73,7 @@ public override void Update(float frameTime) { base.Update(frameTime); - var uid = _player.LocalPlayer?.ControlledEntity; + var uid = _player.LocalEntity; if (uid == null || !_entity.TryGetComponent(uid, out ShadowkinComponent? comp) || !_entity.TryGetComponent(uid, out SpriteComponent? sprite) || From d07db68501d11d2fb92a8892dd5a802ac862eb7b Mon Sep 17 00:00:00 2001 From: Finket Date: Sat, 27 Apr 2024 13:40:39 +0300 Subject: [PATCH 49/59] Move ForceDarkSwap and ForceTeleport to their relevant power systems --- .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 9 +++ .../Systems/ShadowkinPowerSystem.Teleport.cs | 45 ++++++++++++++- .../Shadowkin/Systems/ShadowkinSystem.cs | 57 ++----------------- 3 files changed, 59 insertions(+), 52 deletions(-) diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 98ec0b7a9f..d25d4a2e5e 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -247,4 +247,13 @@ public void SuppressFactions(EntityUid uid, bool set) component.SuppressedFactions.Clear(); } } + + public void ForceDarkSwap(EntityUid uid, ShadowkinComponent component) + { + // Add/Remove the component, which should handle the rest + if (_entity.HasComponent(uid)) + _entity.RemoveComponent(uid); + else + _entity.AddComponent(uid); + } } diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index f18cc6da53..ffb6f78179 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -1,20 +1,26 @@ -using Content.Server.Magic; +using System.Numerics; +using Content.Server.Magic; using Content.Server.Parkstation.Species.Shadowkin.Components; using Content.Server.Pulling; using Content.Shared.Actions; using Content.Shared.Cuffs.Components; using Content.Shared.Damage.Systems; +using Content.Shared.Interaction; using Content.Shared.Parkstation.Species.Shadowkin.Events; using Content.Shared.Pulling.Components; using Content.Shared.Parkstation.Species.Shadowkin.Components; +using Content.Shared.Physics; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; +using Robust.Shared.Map; using Robust.Shared.Prototypes; +using Robust.Shared.Random; namespace Content.Server.Parkstation.Species.Shadowkin.Systems; public sealed class ShadowkinTeleportSystem : EntitySystem { + [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly ShadowkinPowerSystem _power = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; @@ -23,6 +29,8 @@ public sealed class ShadowkinTeleportSystem : EntitySystem [Dependency] private readonly PullingSystem _pulling = default!; [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly MagicSystem _magic = default!; + [Dependency] private readonly SharedInteractionSystem _interaction = default!; + [ValidatePrototypeId] private const string ShadowkinTeleportActionId = "ShadowkinTeleportAction"; @@ -107,4 +115,39 @@ private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, args.Handled = true; } + + + public void ForceTeleport(EntityUid uid, ShadowkinComponent component) + { + // Create the event we'll later raise, and set it to our Shadowkin. + var args = new ShadowkinTeleportEvent { Performer = uid }; + + // Pick a random location on the map until we find one that can be reached. + var coords = Transform(uid).Coordinates; + EntityCoordinates? target = null; + + // It'll iterate up to 8 times, shrinking in distance each time, and if it doesn't find a valid location, it'll return. + for (var i = 8; i != 0; i--) + { + var angle = Angle.FromDegrees(_random.Next(360)); + var offset = new Vector2((float) (i * Math.Cos(angle)), (float) (i * Math.Sin(angle))); + + target = coords.Offset(offset); + + if (_interaction.InRangeUnobstructed(uid, target.Value, 0, + CollisionGroup.MobMask | CollisionGroup.MobLayer)) + break; + + target = null; + } + + // If we didn't find a valid location, return. + if (target == null) + return; + + args.Target = target.Value; + + // Raise the event to teleport the Shadowkin. + RaiseLocalEvent(uid, args); + } } diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.cs index 626217612c..882920c21a 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.cs @@ -1,15 +1,11 @@ -using System.Numerics; -using Content.Server.Mind; +using Content.Server.Mind; using Content.Shared.Bed.Sleep; using Content.Shared.Cuffs.Components; using Content.Shared.Examine; using Content.Shared.IdentityManagement; -using Content.Shared.Interaction; using Content.Shared.Mobs.Systems; using Content.Shared.Parkstation.Species.Shadowkin.Components; using Content.Shared.Parkstation.Species.Shadowkin.Events; -using Content.Shared.Physics; -using Robust.Shared.Map; using Robust.Shared.Random; namespace Content.Server.Parkstation.Species.Shadowkin.Systems; @@ -19,9 +15,11 @@ public sealed class ShadowkinSystem : EntitySystem [Dependency] private readonly ShadowkinPowerSystem _power = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IEntityManager _entity = default!; - [Dependency] private readonly SharedInteractionSystem _interaction = default!; [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly ShadowkinDarkSwapSystem _darkSwap = default!; + [Dependency] private readonly ShadowkinTeleportSystem _teleport = default!; + public override void Initialize() { @@ -138,11 +136,11 @@ public override void Update(float frameTime) if (chance <= 2) { - ForceDarkSwap(uid, shadowkin); + _darkSwap.ForceDarkSwap(uid, shadowkin); } else if (chance <= 7) { - ForceTeleport(uid, shadowkin); + _teleport.ForceTeleport(uid, shadowkin); } } } @@ -190,47 +188,4 @@ public override void Update(float frameTime) #endregion } } - - private void ForceDarkSwap(EntityUid uid, ShadowkinComponent component) - { - // Add/Remove the component, which should handle the rest - if (_entity.HasComponent(uid)) - _entity.RemoveComponent(uid); - else - _entity.AddComponent(uid); - } - - private void ForceTeleport(EntityUid uid, ShadowkinComponent component) - { - // Create the event we'll later raise, and set it to our Shadowkin. - var args = new ShadowkinTeleportEvent { Performer = uid }; - - // Pick a random location on the map until we find one that can be reached. - var coords = Transform(uid).Coordinates; - EntityCoordinates? target = null; - - // It'll iterate up to 8 times, shrinking in distance each time, and if it doesn't find a valid location, it'll return. - for (var i = 8; i != 0; i--) - { - var angle = Angle.FromDegrees(_random.Next(360)); - var offset = new Vector2((float) (i * Math.Cos(angle)), (float) (i * Math.Sin(angle))); - - target = coords.Offset(offset); - - if (_interaction.InRangeUnobstructed(uid, target.Value, 0, - CollisionGroup.MobMask | CollisionGroup.MobLayer)) - break; - - target = null; - } - - // If we didn't find a valid location, return. - if (target == null) - return; - - args.Target = target.Value; - - // Raise the event to teleport the Shadowkin. - RaiseLocalEvent(uid, args); - } } From fe60220364eaf73256fc80da145bd282bad70344 Mon Sep 17 00:00:00 2001 From: Finket Date: Sat, 27 Apr 2024 13:54:20 +0300 Subject: [PATCH 50/59] Pass ShadowKinPowerSystem Blackeye methods to Blackeye system --- .../Shadowkin/Systems/ShadowkinPowerSystem.cs | 24 ++---------- .../Systems/ShadowkinSystem.Blackeye.cs | 37 +++++++++++++++++++ 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs index f3befa418a..c17e4b4c01 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs @@ -10,6 +10,7 @@ public sealed class ShadowkinPowerSystem : EntitySystem { [Dependency] private readonly IEntityManager _entity = default!; [Dependency] private readonly AlertsSystem _alerts = default!; + [Dependency] private readonly ShadowkinBlackeyeSystem _blackeye = default!; private readonly Dictionary _powerDictionary; @@ -198,15 +199,7 @@ public void SetPowerLevel(EntityUid uid, float newPowerLevel) ///
public bool TryBlackeye(EntityUid uid) { - var ent = _entity.GetNetEntity(uid); - // Raise an attempted blackeye event - var ev = new ShadowkinBlackeyeAttemptEvent(ent); - RaiseLocalEvent(ev); - if (ev.Cancelled) - return false; - - Blackeye(uid); - return true; + return _blackeye.TryBlackeye(uid); } /// @@ -214,18 +207,7 @@ public bool TryBlackeye(EntityUid uid) /// public void Blackeye(EntityUid uid) { - var ent = _entity.GetNetEntity(uid); - - // Get shadowkin component - if (!_entity.TryGetComponent(uid, out var component)) - { - DebugTools.Assert("Tried to blackeye entity without shadowkin component."); - return; - } - - component.Blackeye = true; - RaiseNetworkEvent(new ShadowkinBlackeyeEvent(ent)); - RaiseLocalEvent(new ShadowkinBlackeyeEvent(ent)); + _blackeye.Blackeye(uid); } diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs index 434e78f30e..825d526e7e 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs @@ -9,6 +9,7 @@ using Content.Shared.Parkstation.Species.Shadowkin.Events; using Content.Shared.Popups; using Robust.Shared.Prototypes; +using Robust.Shared.Utility; namespace Content.Server.Parkstation.Species.Shadowkin.Systems; @@ -92,4 +93,40 @@ private void OnBlackeye(ShadowkinBlackeyeEvent ev) null, null); } + + + /// + /// Tries to blackeye a shadowkin + /// + public bool TryBlackeye(EntityUid uid) + { + var ent = _entity.GetNetEntity(uid); + // Raise an attempted blackeye event + var ev = new ShadowkinBlackeyeAttemptEvent(ent); + RaiseLocalEvent(ev); + if (ev.Cancelled) + return false; + + Blackeye(uid); + return true; + } + + /// + /// Blackeyes a shadowkin + /// + public void Blackeye(EntityUid uid) + { + var ent = _entity.GetNetEntity(uid); + + // Get shadowkin component + if (!_entity.TryGetComponent(uid, out var component)) + { + DebugTools.Assert("Tried to blackeye entity without shadowkin component."); + return; + } + + component.Blackeye = true; + RaiseNetworkEvent(new ShadowkinBlackeyeEvent(ent)); + RaiseLocalEvent(new ShadowkinBlackeyeEvent(ent)); + } } From 65e73ffb9b1395701fde5c4b4fac79905823613c Mon Sep 17 00:00:00 2001 From: Finket Date: Sat, 27 Apr 2024 14:01:43 +0300 Subject: [PATCH 51/59] Fix YAMLs --- .../Species/Shadowkin/Events/ShadowkinEvents.Powers.cs | 4 ++-- Resources/Prototypes/Parkstation/Damage/modifier_sets.yml | 2 +- .../Parkstation/Entities/Mobs/Player/shadowkin.yml | 8 ++++---- Resources/Prototypes/Parkstation/Traits/disabilities.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs b/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs index 33f9d29e42..febc58b8c5 100644 --- a/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs +++ b/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs @@ -63,13 +63,13 @@ public sealed partial class ShadowkinDarkSwapEvent : InstantActionEvent, ISpeakS /// How much stamina to drain when darkening. ///
[DataField("staminaCostOn")] - public float StaminaCostOn; + public float StaminaCostOn = 25f; /// /// How much stamina to drain when lightening. /// [DataField("staminaCostOff")] - public float StaminaCostOff; + public float StaminaCostOff = 25f; [DataField("speech")] diff --git a/Resources/Prototypes/Parkstation/Damage/modifier_sets.yml b/Resources/Prototypes/Parkstation/Damage/modifier_sets.yml index 2d446c37be..f1a86d203c 100644 --- a/Resources/Prototypes/Parkstation/Damage/modifier_sets.yml +++ b/Resources/Prototypes/Parkstation/Damage/modifier_sets.yml @@ -6,7 +6,7 @@ Piercing: 1.1 Asphyxiation: 0 Cold: 0.75 - Heat: 1.2 + Heat: 1.5 Cellular: 0.25 Bloodloss: 1.35 Shock: 1.25 diff --git a/Resources/Prototypes/Parkstation/Entities/Mobs/Player/shadowkin.yml b/Resources/Prototypes/Parkstation/Entities/Mobs/Player/shadowkin.yml index a3394a2347..f8a2449c66 100644 --- a/Resources/Prototypes/Parkstation/Entities/Mobs/Player/shadowkin.yml +++ b/Resources/Prototypes/Parkstation/Entities/Mobs/Player/shadowkin.yml @@ -17,15 +17,15 @@ # - type: DiseaseCarrier # diseaseResist: 0.1 - type: Flammable - damage: - types: - Heat: 1.5 # burn more + # damage: + # types: + # Heat: 1.5 # burn more - type: MobState - type: MobThresholds thresholds: # Weak 0: Alive 80: Critical - 160: Dead + 180: Dead - type: SlowOnDamage speedModifierThresholds: 48: 0.85 diff --git a/Resources/Prototypes/Parkstation/Traits/disabilities.yml b/Resources/Prototypes/Parkstation/Traits/disabilities.yml index b4908edb5d..48b512695d 100644 --- a/Resources/Prototypes/Parkstation/Traits/disabilities.yml +++ b/Resources/Prototypes/Parkstation/Traits/disabilities.yml @@ -12,7 +12,7 @@ - type: trait id: ShadowkinBlackeye name: Blackeye - description: You lose your special Shadowkin powers, in return for some points. + description: You have lost your Shadowkin powers. cost: 5 category: Negative whitelist: From 1606712052cc748b6a7a8190ac515aee1f213dc2 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Mon, 19 Aug 2024 19:12:30 -0700 Subject: [PATCH 52/59] remove duplicate namepreset-first --- Content.Shared/Humanoid/NamingSystem.cs | 3 --- Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs | 1 - Resources/Locale/en-US/species/namepreset.ftl | 2 -- 3 files changed, 6 deletions(-) diff --git a/Content.Shared/Humanoid/NamingSystem.cs b/Content.Shared/Humanoid/NamingSystem.cs index df3a052058..d4cca026ef 100644 --- a/Content.Shared/Humanoid/NamingSystem.cs +++ b/Content.Shared/Humanoid/NamingSystem.cs @@ -40,9 +40,6 @@ public string GetName(string species, Gender? gender = null) case SpeciesNaming.FirstDashFirst: return Loc.GetString("namepreset-firstdashfirst", ("first1", GetFirstName(speciesProto, gender)), ("first2", GetFirstName(speciesProto, gender))); - case SpeciesNaming.First: // Parkstation-Shadowkin - return Loc.GetString("namepreset-first", - ("first", GetFirstName(speciesProto, gender))); case SpeciesNaming.FirstLast: default: return Loc.GetString("namepreset-firstlast", diff --git a/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs b/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs index 68df1b3c04..340ce5acd0 100644 --- a/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs +++ b/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs @@ -179,5 +179,4 @@ public enum SpeciesNaming : byte LastNoFirst, //End of Nyano - Summary: for Oni naming TheFirstofLast, - First, // Parkstation-Shadowkin } diff --git a/Resources/Locale/en-US/species/namepreset.ftl b/Resources/Locale/en-US/species/namepreset.ftl index 1b3e137440..5a42c87b78 100644 --- a/Resources/Locale/en-US/species/namepreset.ftl +++ b/Resources/Locale/en-US/species/namepreset.ftl @@ -2,5 +2,3 @@ namepreset-first = {$first} namepreset-firstlast = {$first} {$last} namepreset-firstdashfirst = {$first1}-{$first2} namepreset-thefirstoflast = The {$first} of {$last} -## Parkstation-Shadowkin -namepreset-first = {$first} From 24f8afe635e91e72a3e999e866256bdab6f539fc Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Mon, 19 Aug 2024 20:11:21 -0700 Subject: [PATCH 53/59] fix empathy --- .../Parkstation/Chat/ESayCommand.cs | 4 +- .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 90 ++++++++++--------- .../Systems/ShadowkinPowerSystem.Teleport.cs | 20 ++--- Content.Shared/Chat/ChatChannel.cs | 4 +- Content.Shared/Chat/ChatSelectChannel.cs | 2 +- Content.Shared/Chat/SharedChatSystem.cs | 3 +- .../Components/ShadowkinLightComponent.cs | 6 +- 7 files changed, 68 insertions(+), 61 deletions(-) rename {Content.Server => Content.Shared}/Parkstation/Species/Shadowkin/Components/ShadowkinLightComponent.cs (76%) diff --git a/Content.Server/Parkstation/Chat/ESayCommand.cs b/Content.Server/Parkstation/Chat/ESayCommand.cs index 6af4d7bdcc..ab5129129a 100644 --- a/Content.Server/Parkstation/Chat/ESayCommand.cs +++ b/Content.Server/Parkstation/Chat/ESayCommand.cs @@ -1,5 +1,6 @@ using Content.Server.Chat.Systems; using Content.Shared.Administration; +using Content.Shared.Chat; using Robust.Shared.Console; using Robust.Shared.Enums; using Robust.Shared.Player; @@ -7,9 +8,6 @@ namespace Content.Server.Parkstation.Chat; [AnyCommand] -/// -/// Chat commands are stupid -/// internal sealed class ESayCommand : IConsoleCommand { public string Command => "esay"; diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index d25d4a2e5e..7838d3f5d2 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -37,6 +37,7 @@ public sealed class ShadowkinDarkSwapSystem : EntitySystem [ValidatePrototypeId] private const string ShadowkinDarkSwapActionId = "ShadowkinDarkSwapAction"; + public override void Initialize() { base.Initialize(); @@ -61,6 +62,42 @@ private void Shutdown(EntityUid uid, ShadowkinDarkSwapPowerComponent component, _actions.RemoveAction(uid, component.ShadowkinDarkSwapActionEntity); } + private void OnInvisStartup(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentStartup args) + { + if (component.Pacify) + EnsureComp(uid); + + if (!component.Invisible) + return; + + SetVisibility(uid, true); + SuppressFactions(uid, true); + } + + private void OnInvisShutdown(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentShutdown args) + { + RemComp(uid); + + if (component.Invisible) + { + SetVisibility(uid, false); + SuppressFactions(uid, false); + } + + component.Darken = false; + + foreach (var light in component.DarkenedLights.ToArray()) + { + if (!_entity.TryGetComponent(light, out var pointLight) || + !_entity.TryGetComponent(light, out var shadowkinLight)) + continue; + + _darken.ResetLight(pointLight, shadowkinLight); + } + + component.DarkenedLights.Clear(); + } + private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ShadowkinDarkSwapEvent args) { @@ -132,69 +169,39 @@ public void UnDarkened(NetEntity performer, float staminaCostOn, float powerCost args.Handled = true; } - private void OnInvisStartup(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentStartup args) - { - if (component.Pacify) - EnsureComp(uid); - - if (component.Invisible) - { - SetVisibility(uid, true); - SuppressFactions(uid, true); - } - } - - private void OnInvisShutdown(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentShutdown args) + public void SetVisibility(EntityUid uid, bool set) { - RemComp(uid); - - if (component.Invisible) - { - SetVisibility(uid, false); - SuppressFactions(uid, false); - } - - component.Darken = false; + // We require the visibility component for this to work + EnsureComp(uid); - foreach (var light in component.DarkenedLights.ToArray()) + // Allow ghosts to see DarkSwapped entities + if (_entity.HasComponent(uid)) { - if (!_entity.TryGetComponent(light, out var pointLight) || - !_entity.TryGetComponent(light, out var shadowkinLight)) - continue; + if (_entity.TryGetComponent(uid, out EyeComponent? eye)) + _eye.SetVisibilityMask(uid, eye.VisibilityMask | (int) VisibilityFlags.DarkSwapInvisibility, eye); - _darken.ResetLight(pointLight, shadowkinLight); + return; } - component.DarkenedLights.Clear(); - } - - public void SetVisibility(EntityUid uid, bool set) - { - // We require the visibility component for this to work - var visibility = EnsureComp(uid); - if (set) // Invisible { // Allow the entity to see DarkSwapped entities if (_entity.TryGetComponent(uid, out EyeComponent? eye)) _eye.SetVisibilityMask(uid, eye.VisibilityMask | (int) VisibilityFlags.DarkSwapInvisibility, eye); - // eye.VisibilityMask |= (int) VisibilityFlags.DarkSwapInvisibility; // Make other entities unable to see the entity unless also DarkSwapped _visibility.AddLayer(uid, (ushort) VisibilityFlags.DarkSwapInvisibility, false); _visibility.RemoveLayer(uid, (ushort) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); - // If not a ghost, add a stealth shader to the entity - if (!_entity.TryGetComponent(uid, out var _)) - _stealth.SetVisibility(uid, 0.8f, _entity.EnsureComponent(uid)); + // Add a stealth shader to the entity + _stealth.SetVisibility(uid, 0.8f, _entity.EnsureComponent(uid)); } else // Visible { // Remove the ability to see DarkSwapped entities if (_entity.TryGetComponent(uid, out EyeComponent? eye)) _eye.SetVisibilityMask(uid, eye.VisibilityMask & ~(int) VisibilityFlags.DarkSwapInvisibility, eye); - // eye.VisibilityMask &= ~(int) VisibilityFlags.DarkSwapInvisibility; // Make other entities able to see the entity again _visibility.RemoveLayer(uid, (ushort) VisibilityFlags.DarkSwapInvisibility, false); @@ -202,8 +209,7 @@ public void SetVisibility(EntityUid uid, bool set) _visibility.RefreshVisibility(uid); // Remove the stealth shader from the entity - if (!_entity.TryGetComponent(uid, out _)) - _stealth.SetVisibility(uid, 1f, _entity.EnsureComponent(uid)); + _stealth.SetVisibility(uid, 1f, _entity.EnsureComponent(uid)); } } diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index ffb6f78179..a576556d8e 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -1,13 +1,13 @@ using System.Numerics; using Content.Server.Magic; using Content.Server.Parkstation.Species.Shadowkin.Components; -using Content.Server.Pulling; using Content.Shared.Actions; using Content.Shared.Cuffs.Components; using Content.Shared.Damage.Systems; using Content.Shared.Interaction; +using Content.Shared.Movement.Pulling.Components; +using Content.Shared.Movement.Pulling.Systems; using Content.Shared.Parkstation.Species.Shadowkin.Events; -using Content.Shared.Pulling.Components; using Content.Shared.Parkstation.Species.Shadowkin.Components; using Content.Shared.Physics; using Robust.Shared.Audio; @@ -31,10 +31,10 @@ public sealed class ShadowkinTeleportSystem : EntitySystem [Dependency] private readonly MagicSystem _magic = default!; [Dependency] private readonly SharedInteractionSystem _interaction = default!; - [ValidatePrototypeId] private const string ShadowkinTeleportActionId = "ShadowkinTeleportAction"; + public override void Initialize() { base.Initialize(); @@ -73,19 +73,19 @@ private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, if (transform.MapID != args.Target.GetMapId(EntityManager)) return; - SharedPullableComponent? pullable = null; // To avoid "might not be initialized when accessed" warning - if (_entity.TryGetComponent(args.Performer, out var puller) && + PullableComponent? pullable = null; // To avoid "might not be initialized when accessed" warning + if (_entity.TryGetComponent(args.Performer, out var puller) && puller.Pulling != null && - _entity.TryGetComponent(puller.Pulling, out pullable) && + _entity.TryGetComponent(puller.Pulling, out pullable) && pullable.BeingPulled) { // Temporarily stop pulling to avoid not teleporting to the target - _pulling.TryStopPull(pullable); + _pulling.TryStopPull(puller.Pulling.Value, pullable); } // Teleport the performer to the target _transform.SetCoordinates(args.Performer, args.Target); - transform.AttachToGridOrMap(); + _transform.AttachToGridOrMap(args.Performer); if (pullable != null && puller != null) { @@ -95,11 +95,11 @@ private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, // Teleport the pulled entity to the target // TODO: Relative position to the performer _transform.SetCoordinates(pullable.Owner, args.Target); - pulledTransform.AttachToGridOrMap(); + _transform.AttachToGridOrMap(pullable.Owner); // Resume pulling // TODO: This does nothing? // This does things sometimes, but the client never knows // This does nothing?? - _pulling.TryStartPull(puller, pullable); + _pulling.TryStartPull(args.Performer, pullable.Owner); } diff --git a/Content.Shared/Chat/ChatChannel.cs b/Content.Shared/Chat/ChatChannel.cs index a2692ac5a7..31a0b686e4 100644 --- a/Content.Shared/Chat/ChatChannel.cs +++ b/Content.Shared/Chat/ChatChannel.cs @@ -4,7 +4,7 @@ namespace Content.Shared.Chat /// Represents chat channels that the player can filter chat tabs by. /// [Flags] - public enum ChatChannel : ushort + public enum ChatChannel { None = 0, @@ -93,7 +93,7 @@ public enum ChatChannel : ushort /// /// Empathy channel for Shadowkin. /// - Empathy = 1 << 15, // Parkstation-EmpathyChat + Empathy = 1 << 16, // Parkstation-EmpathyChat /// /// Channels considered to be IC. diff --git a/Content.Shared/Chat/ChatSelectChannel.cs b/Content.Shared/Chat/ChatSelectChannel.cs index 5b442c76ac..3ee7a71c4f 100644 --- a/Content.Shared/Chat/ChatSelectChannel.cs +++ b/Content.Shared/Chat/ChatSelectChannel.cs @@ -7,7 +7,7 @@ /// Maps to , giving better names. /// [Flags] - public enum ChatSelectChannel : ushort + public enum ChatSelectChannel { None = 0, diff --git a/Content.Shared/Chat/SharedChatSystem.cs b/Content.Shared/Chat/SharedChatSystem.cs index 02818fd948..cd5feceaba 100644 --- a/Content.Shared/Chat/SharedChatSystem.cs +++ b/Content.Shared/Chat/SharedChatSystem.cs @@ -256,7 +256,8 @@ public enum InGameICChatType : byte Speak, Emote, Whisper, - Telepathic + Telepathic, + Empathy, // Parkstation-EmpathyChat } /// diff --git a/Content.Server/Parkstation/Species/Shadowkin/Components/ShadowkinLightComponent.cs b/Content.Shared/Parkstation/Species/Shadowkin/Components/ShadowkinLightComponent.cs similarity index 76% rename from Content.Server/Parkstation/Species/Shadowkin/Components/ShadowkinLightComponent.cs rename to Content.Shared/Parkstation/Species/Shadowkin/Components/ShadowkinLightComponent.cs index eaac09e091..a287989a53 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Components/ShadowkinLightComponent.cs +++ b/Content.Shared/Parkstation/Species/Shadowkin/Components/ShadowkinLightComponent.cs @@ -1,6 +1,8 @@ -namespace Content.Server.Parkstation.Species.Shadowkin.Components; +using Robust.Shared.GameStates; -[RegisterComponent] +namespace Content.Shared.Parkstation.Species.Shadowkin.Components; + +[RegisterComponent, NetworkedComponent] public sealed partial class ShadowkinLightComponent : Component { [ViewVariables(VVAccess.ReadOnly)] From 23bb1a97428ab41becd77a7bb9f7cbba79e18985 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Mon, 19 Aug 2024 20:29:17 -0700 Subject: [PATCH 54/59] ghosts can see darkswapped Shadowkin --- Content.Server/Ghost/GhostSystem.cs | 3 +++ .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 15 ++++----------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Content.Server/Ghost/GhostSystem.cs b/Content.Server/Ghost/GhostSystem.cs index c0e753c4c5..d7b40efc59 100644 --- a/Content.Server/Ghost/GhostSystem.cs +++ b/Content.Server/Ghost/GhostSystem.cs @@ -149,6 +149,9 @@ private void OnGhostStartup(EntityUid uid, GhostComponent component, ComponentSt _visibilitySystem.RefreshVisibility(uid, visibilityComponent: visibility); } + if (TryComp(uid, out EyeComponent? eye)) + _eye.SetVisibilityMask(uid, eye.VisibilityMask | (int) VisibilityFlags.DarkSwapInvisibility, eye); + SetCanSeeGhosts(uid, true); var time = _gameTiming.CurTime; diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 7838d3f5d2..67b4560dbc 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -174,15 +174,6 @@ public void SetVisibility(EntityUid uid, bool set) // We require the visibility component for this to work EnsureComp(uid); - // Allow ghosts to see DarkSwapped entities - if (_entity.HasComponent(uid)) - { - if (_entity.TryGetComponent(uid, out EyeComponent? eye)) - _eye.SetVisibilityMask(uid, eye.VisibilityMask | (int) VisibilityFlags.DarkSwapInvisibility, eye); - - return; - } - if (set) // Invisible { // Allow the entity to see DarkSwapped entities @@ -195,7 +186,8 @@ public void SetVisibility(EntityUid uid, bool set) _visibility.RefreshVisibility(uid); // Add a stealth shader to the entity - _stealth.SetVisibility(uid, 0.8f, _entity.EnsureComponent(uid)); + if (!_entity.HasComponent(uid)) + _stealth.SetVisibility(uid, 0.8f, _entity.EnsureComponent(uid)); } else // Visible { @@ -209,7 +201,8 @@ public void SetVisibility(EntityUid uid, bool set) _visibility.RefreshVisibility(uid); // Remove the stealth shader from the entity - _stealth.SetVisibility(uid, 1f, _entity.EnsureComponent(uid)); + if (!_entity.HasComponent(uid)) + _stealth.SetVisibility(uid, 1f, _entity.EnsureComponent(uid)); } } From b88dcb01afd7d96fa01ab528d1d8fe58689303aa Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Mon, 19 Aug 2024 20:32:42 -0700 Subject: [PATCH 55/59] fix rest ability --- .../Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs | 5 ++++- Resources/Prototypes/Parkstation/Magic/shadowkin.yml | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index 318ded033b..e6c7e81e71 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -16,6 +16,7 @@ public sealed class ShadowkinRestSystem : EntitySystem [ValidatePrototypeId] private const string ShadowkinRestActionId = "ShadowkinRestAction"; + public override void Initialize() { base.Initialize(); @@ -61,8 +62,9 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki _actions.RemoveAction(args.Performer, sleepingComponent.WakeAction); _power.TryAddMultiplier(args.Performer, 1.5f); + // No action cooldown - args.Handled = false; + _actions.ClearCooldown(sleepingComponent?.WakeAction); } // Waking else @@ -71,6 +73,7 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki _entity.RemoveComponent(args.Performer); _entity.RemoveComponent(args.Performer); _power.TryAddMultiplier(args.Performer, -1.5f); + // Action cooldown args.Handled = true; } diff --git a/Resources/Prototypes/Parkstation/Magic/shadowkin.yml b/Resources/Prototypes/Parkstation/Magic/shadowkin.yml index 5aff780346..e90a5d332c 100644 --- a/Resources/Prototypes/Parkstation/Magic/shadowkin.yml +++ b/Resources/Prototypes/Parkstation/Magic/shadowkin.yml @@ -50,4 +50,5 @@ sprite: Parkstation/Interface/Actions/shadowkin_icons.rsi state: rest checkCanInteract: false + checkConsciousness: false event: !type:ShadowkinRestEvent From 995676b4570f83ffeef46c212a69ef2ebfe37306 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Mon, 19 Aug 2024 20:52:41 -0700 Subject: [PATCH 56/59] fix tests --- .../Locale/en-US/parkstation/Traits/disabilities.ftl | 3 +++ .../Prototypes/Parkstation/Traits/disabilities.yml | 10 ++++------ .../Mobs/Customization/reptilian_parts.rsi/meta.json | 10 ++++++++++ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Resources/Locale/en-US/parkstation/Traits/disabilities.ftl b/Resources/Locale/en-US/parkstation/Traits/disabilities.ftl index 8360aaeb9d..ea2a7f347b 100644 --- a/Resources/Locale/en-US/parkstation/Traits/disabilities.ftl +++ b/Resources/Locale/en-US/parkstation/Traits/disabilities.ftl @@ -1,2 +1,5 @@ trait-name-Nearsighted = Nearsighted trait-description-Nearsighted = You require glasses to see properly. + +trait-name-ShadowkinBlackeye = Blackeye +trait-description-ShadowkinBlackeye = You have lost your Shadowkin powers. diff --git a/Resources/Prototypes/Parkstation/Traits/disabilities.yml b/Resources/Prototypes/Parkstation/Traits/disabilities.yml index 71e83e302a..2ae402e5c7 100644 --- a/Resources/Prototypes/Parkstation/Traits/disabilities.yml +++ b/Resources/Prototypes/Parkstation/Traits/disabilities.yml @@ -13,13 +13,11 @@ - type: trait id: ShadowkinBlackeye - name: Blackeye - description: You have lost your Shadowkin powers. - cost: 5 + points: 5 category: Negative requirements: - - !type:CharacterSpeciesRequirement - species: - - Shadowkin + - !type:CharacterSpeciesRequirement + species: + - Shadowkin components: - type: ShadowkinBlackeyeTrait diff --git a/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/meta.json b/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/meta.json index 89a44c1cfd..1cc52acb4d 100644 --- a/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/meta.json +++ b/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/meta.json @@ -83,6 +83,16 @@ "name": "tail_ltiger", "directions": 4 }, + { + "name": "tail_smooth_wagging", + "directions": 4, + "delays": [ + [0.125, 0.1, 0.075, 0.075, 0.075, 0.075, 0.075, 0.1, 0.125, 0.1, 0.075, 0.075, 0.075, 0.075, 0.075, 0.1], + [0.125, 0.1, 0.075, 0.075, 0.075, 0.075, 0.075, 0.1, 0.125, 0.1, 0.075, 0.075, 0.075, 0.075, 0.075, 0.1], + [0.125, 0.1, 0.075, 0.075, 0.075, 0.075, 0.075, 0.1, 0.125, 0.1, 0.075, 0.075, 0.075, 0.075, 0.075, 0.1], + [0.125, 0.1, 0.075, 0.075, 0.075, 0.075, 0.075, 0.1, 0.125, 0.1, 0.075, 0.075, 0.075, 0.075, 0.075, 0.1] + ] + }, { "name": "tail_smooth_wagging_primary", "directions": 4, From 9ce2fea66bacbc1a9c1e68a4daf85dcd5320c1c1 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Mon, 19 Aug 2024 23:09:25 -0700 Subject: [PATCH 57/59] https://github.com/Simple-Station/Parkstation/pull/209 --- Content.Server/Cloning/CloningSystem.cs | 11 ++ .../Parkstation/Cloning/CloningEvents.cs | 21 +++ .../ShadowkinDarkSwapPowerComponent.cs | 32 ++++ .../Components/ShadowkinSightComponent.cs | 4 + .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 163 ++++++++++++------ .../Systems/ShadowkinPowerSystem.Rest.cs | 4 +- .../Systems/ShadowkinPowerSystem.Teleport.cs | 14 +- .../Shadowkin/Systems/ShadowkinPowerSystem.cs | 10 +- .../Shadowkin/Systems/ShadowkinSightSystem.cs | 29 ++++ .../Systems/ShadowkinSystem.Blackeye.cs | 52 ++++-- .../Pacification/PacifiedComponent.cs | 1 - .../Cuffs/Components/HandcuffComponent.cs | 6 + .../ClothingGrantComponentComponent.cs | 19 +- .../Components/ShadowkinComponent.cs | 6 +- .../ShadowkinDarkSwappedComponent.cs | 17 +- .../Events/ShadowkinEvents.Blackeye.cs | 22 +-- .../Events/ShadowkinEvents.Powers.cs | 26 +-- .../Systems/ShadowkinPowerSystem.DarkSwap.cs | 12 +- .../Nyanotrasen/metempsychoticHumanoids.yml | 1 + .../Parkstation/Body/Organs/shadowkin.yml | 136 +++++++++++++++ .../Chemistry/metabolizer_types.yml | 3 + .../Entities/Body/Parts/shadowkin.yml | 4 +- .../Entities/Body/Prototypes/shadowkin.yml | 16 +- .../Entities/Clothing/Eyes/glasses.yml | 14 ++ .../Clothing/Head/hardsuit-helmets.yml | 27 +++ .../Entities/Clothing/Head/hardsuits.yml | 30 ++++ .../Entities/Mobs/Player/shadowkin.yml | 56 +++++- .../Entities/Objects/Misc/handcuffs.yml | 21 +++ .../HumanoidProfiles/shadowkin.yml | 6 + .../Parkstation/Magic/shadowkin.yml | 17 ++ .../Parkstation/Species/shadowkin.yml | 30 ++-- Resources/Prototypes/Reagents/toxins.yml | 8 + .../Glasses/darkened.rsi/equipped-EYES.png | Bin 0 -> 314 bytes .../Eyes/Glasses/darkened.rsi/icon.png | Bin 0 -> 415 bytes .../Eyes/Glasses/darkened.rsi/inhand-left.png | Bin 0 -> 386 bytes .../Glasses/darkened.rsi/inhand-right.png | Bin 0 -> 397 bytes .../Eyes/Glasses/darkened.rsi/meta.json | 26 +++ .../darkened.rsi/equipped-HELMET.png | Bin 0 -> 1388 bytes .../Head/Hardsuits/darkened.rsi/icon.png | Bin 0 -> 847 bytes .../Head/Hardsuits/darkened.rsi/meta.json | 18 ++ .../darkened.rsi/equipped-OUTERCLOTHING.png | Bin 0 -> 1972 bytes .../Hardsuits/darkened.rsi/icon.png | Bin 0 -> 1183 bytes .../Hardsuits/darkened.rsi/inhand-left.png | Bin 0 -> 1097 bytes .../Hardsuits/darkened.rsi/inhand-right.png | Bin 0 -> 1158 bytes .../Hardsuits/darkened.rsi/meta.json | 26 +++ .../body-overlay-2.png | Bin 0 -> 1142 bytes .../Misc/shadowkin_restraints.rsi/icon.png | Bin 0 -> 3072 bytes .../shadowkin_restraints.rsi/inhand-left.png | Bin 0 -> 234 bytes .../shadowkin_restraints.rsi/inhand-right.png | Bin 0 -> 242 bytes .../Misc/shadowkin_restraints.rsi/meta.json | 26 +++ .../Species/Shadowkin/organs.rsi/appendix.png | Bin 0 -> 1609 bytes .../Species/Shadowkin/organs.rsi/brain.png | Bin 0 -> 823 bytes .../Species/Shadowkin/organs.rsi/core.png | Bin 0 -> 927 bytes .../Species/Shadowkin/organs.rsi/ears.png | Bin 0 -> 1677 bytes .../Species/Shadowkin/organs.rsi/eyes.png | Bin 0 -> 1014 bytes .../Species/Shadowkin/organs.rsi/heart.png | Bin 0 -> 670 bytes .../Species/Shadowkin/organs.rsi/kidneys.png | Bin 0 -> 759 bytes .../Species/Shadowkin/organs.rsi/liver.png | Bin 0 -> 710 bytes .../Species/Shadowkin/organs.rsi/lungs.png | Bin 0 -> 735 bytes .../Species/Shadowkin/organs.rsi/meta.json | 44 +++++ .../Species/Shadowkin/organs.rsi/stomach.png | Bin 0 -> 770 bytes .../Species/Shadowkin/organs.rsi/tongue.png | Bin 0 -> 2303 bytes .../parts.rsi}/eyes.png | Bin .../parts.rsi}/full.png | Bin .../parts.rsi}/head_f.png | Bin .../parts.rsi}/head_m.png | Bin .../parts.rsi}/l_arm.png | Bin .../parts.rsi}/l_foot.png | Bin .../parts.rsi}/l_hand.png | Bin .../parts.rsi}/l_leg.png | Bin .../parts.rsi}/meta.json | 8 +- .../parts.rsi}/r_arm.png | Bin .../parts.rsi}/r_foot.png | Bin .../parts.rsi}/r_hand.png | Bin .../parts.rsi}/r_leg.png | Bin .../parts.rsi}/torso_f.png | Bin .../parts.rsi}/torso_m.png | Bin 77 files changed, 786 insertions(+), 180 deletions(-) create mode 100644 Content.Server/Parkstation/Cloning/CloningEvents.cs create mode 100644 Content.Server/Parkstation/Species/Shadowkin/Components/ShadowkinSightComponent.cs create mode 100644 Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSightSystem.cs create mode 100644 Resources/Prototypes/Parkstation/Body/Organs/shadowkin.yml create mode 100644 Resources/Prototypes/Parkstation/Chemistry/metabolizer_types.yml create mode 100644 Resources/Prototypes/Parkstation/Entities/Clothing/Eyes/glasses.yml create mode 100644 Resources/Prototypes/Parkstation/Entities/Objects/Misc/handcuffs.yml create mode 100644 Resources/Prototypes/Parkstation/HumanoidProfiles/shadowkin.yml create mode 100644 Resources/Textures/Parkstation/Clothing/Eyes/Glasses/darkened.rsi/equipped-EYES.png create mode 100644 Resources/Textures/Parkstation/Clothing/Eyes/Glasses/darkened.rsi/icon.png create mode 100644 Resources/Textures/Parkstation/Clothing/Eyes/Glasses/darkened.rsi/inhand-left.png create mode 100644 Resources/Textures/Parkstation/Clothing/Eyes/Glasses/darkened.rsi/inhand-right.png create mode 100644 Resources/Textures/Parkstation/Clothing/Eyes/Glasses/darkened.rsi/meta.json create mode 100644 Resources/Textures/Parkstation/Clothing/Head/Hardsuits/darkened.rsi/equipped-HELMET.png create mode 100644 Resources/Textures/Parkstation/Clothing/Head/Hardsuits/darkened.rsi/icon.png create mode 100644 Resources/Textures/Parkstation/Clothing/Head/Hardsuits/darkened.rsi/meta.json create mode 100644 Resources/Textures/Parkstation/Clothing/OuterClothing/Hardsuits/darkened.rsi/equipped-OUTERCLOTHING.png create mode 100644 Resources/Textures/Parkstation/Clothing/OuterClothing/Hardsuits/darkened.rsi/icon.png create mode 100644 Resources/Textures/Parkstation/Clothing/OuterClothing/Hardsuits/darkened.rsi/inhand-left.png create mode 100644 Resources/Textures/Parkstation/Clothing/OuterClothing/Hardsuits/darkened.rsi/inhand-right.png create mode 100644 Resources/Textures/Parkstation/Clothing/OuterClothing/Hardsuits/darkened.rsi/meta.json create mode 100644 Resources/Textures/Parkstation/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi/body-overlay-2.png create mode 100644 Resources/Textures/Parkstation/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi/icon.png create mode 100644 Resources/Textures/Parkstation/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi/inhand-left.png create mode 100644 Resources/Textures/Parkstation/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi/inhand-right.png create mode 100644 Resources/Textures/Parkstation/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi/meta.json create mode 100644 Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/appendix.png create mode 100644 Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/brain.png create mode 100644 Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/core.png create mode 100644 Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/ears.png create mode 100644 Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/eyes.png create mode 100644 Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/heart.png create mode 100644 Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/kidneys.png create mode 100644 Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/liver.png create mode 100644 Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/lungs.png create mode 100644 Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/meta.json create mode 100644 Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/stomach.png create mode 100644 Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/tongue.png rename Resources/Textures/Parkstation/Mobs/Species/{shadowkin.rsi => Shadowkin/parts.rsi}/eyes.png (100%) rename Resources/Textures/Parkstation/Mobs/Species/{shadowkin.rsi => Shadowkin/parts.rsi}/full.png (100%) rename Resources/Textures/Parkstation/Mobs/Species/{shadowkin.rsi => Shadowkin/parts.rsi}/head_f.png (100%) rename Resources/Textures/Parkstation/Mobs/Species/{shadowkin.rsi => Shadowkin/parts.rsi}/head_m.png (100%) rename Resources/Textures/Parkstation/Mobs/Species/{shadowkin.rsi => Shadowkin/parts.rsi}/l_arm.png (100%) rename Resources/Textures/Parkstation/Mobs/Species/{shadowkin.rsi => Shadowkin/parts.rsi}/l_foot.png (100%) rename Resources/Textures/Parkstation/Mobs/Species/{shadowkin.rsi => Shadowkin/parts.rsi}/l_hand.png (100%) rename Resources/Textures/Parkstation/Mobs/Species/{shadowkin.rsi => Shadowkin/parts.rsi}/l_leg.png (100%) rename Resources/Textures/Parkstation/Mobs/Species/{shadowkin.rsi => Shadowkin/parts.rsi}/meta.json (100%) rename Resources/Textures/Parkstation/Mobs/Species/{shadowkin.rsi => Shadowkin/parts.rsi}/r_arm.png (100%) rename Resources/Textures/Parkstation/Mobs/Species/{shadowkin.rsi => Shadowkin/parts.rsi}/r_foot.png (100%) rename Resources/Textures/Parkstation/Mobs/Species/{shadowkin.rsi => Shadowkin/parts.rsi}/r_hand.png (100%) rename Resources/Textures/Parkstation/Mobs/Species/{shadowkin.rsi => Shadowkin/parts.rsi}/r_leg.png (100%) rename Resources/Textures/Parkstation/Mobs/Species/{shadowkin.rsi => Shadowkin/parts.rsi}/torso_f.png (100%) rename Resources/Textures/Parkstation/Mobs/Species/{shadowkin.rsi => Shadowkin/parts.rsi}/torso_m.png (100%) diff --git a/Content.Server/Cloning/CloningSystem.cs b/Content.Server/Cloning/CloningSystem.cs index 92e658591a..4eeba58093 100644 --- a/Content.Server/Cloning/CloningSystem.cs +++ b/Content.Server/Cloning/CloningSystem.cs @@ -46,6 +46,7 @@ using Content.Shared.Humanoid.Prototypes; using Robust.Shared.GameObjects.Components.Localization; //DeltaV End Metem Usings using Content.Server.EntityList; +using Content.Server.Parkstation.Cloning; using Content.Shared.SSDIndicator; using Content.Shared.Damage.ForceSay; using Content.Server.Polymorph.Components; @@ -249,6 +250,12 @@ public bool TryCloning(EntityUid uid, EntityUid bodyToClone, Entity(uid); + // For other systems adding components to the mob + var bce = new BeenClonedEvent(pref, mind, mob, bodyToClone, clonePod.Owner); + RaiseLocalEvent(bce); + // TODO: Ideally, components like this should be components on the mind entity so this isn't necessary. // Add on special job components to the mob. if (_jobs.MindTryGetJob(mindEnt, out _, out var prototype)) diff --git a/Content.Server/Parkstation/Cloning/CloningEvents.cs b/Content.Server/Parkstation/Cloning/CloningEvents.cs new file mode 100644 index 0000000000..f1ab620f3d --- /dev/null +++ b/Content.Server/Parkstation/Cloning/CloningEvents.cs @@ -0,0 +1,21 @@ +using Content.Shared.Mind; +using Content.Shared.Preferences; + +namespace Content.Server.Parkstation.Cloning; + +[ByRefEvent] +public sealed class BeingClonedEvent(HumanoidCharacterProfile profile, MindComponent mind, EntityUid cloner) : CancellableEntityEventArgs +{ + public HumanoidCharacterProfile Profile = profile; + public MindComponent Mind = mind; + public EntityUid Cloner = cloner; +} + +public sealed class BeenClonedEvent(HumanoidCharacterProfile profile, MindComponent mind, EntityUid mob, EntityUid OriginalMob, EntityUid cloner) : EntityEventArgs +{ + public HumanoidCharacterProfile Profile = profile; + public MindComponent Mind = mind; + public EntityUid Mob = mob; + public EntityUid OriginalMob = OriginalMob; + public EntityUid Cloner = cloner; +} diff --git a/Content.Server/Parkstation/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs b/Content.Server/Parkstation/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs index 26b5fde57f..500a487c20 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs @@ -19,4 +19,36 @@ public sealed partial class ShadowkinDarkSwapPowerComponent : Component [DataField("shadowkinDarkSwapActionEntity")] public EntityUid? ShadowkinDarkSwapActionEntity; + + + /// + /// If the entity should be sent to the dark + /// + [DataField("invisible")] + public bool Invisible = true; + + /// + /// If it should be pacified + /// + [DataField("pacify")] + public bool Pacify = true; + + /// + /// If the entity should dim nearby lights when swapped + /// + [DataField("darken"), ViewVariables(VVAccess.ReadWrite)] + public bool Darken = true; + + /// + /// How far to dim nearby lights + /// + [DataField("range"), ViewVariables(VVAccess.ReadWrite)] + public float DarkenRange = 5f; + + /// + /// How fast to refresh nearby light dimming in seconds + /// Without this performance would be significantly worse + /// + [ViewVariables(VVAccess.ReadWrite)] + public float DarkenRate = 0.084f; // 1/12th of a second } diff --git a/Content.Server/Parkstation/Species/Shadowkin/Components/ShadowkinSightComponent.cs b/Content.Server/Parkstation/Species/Shadowkin/Components/ShadowkinSightComponent.cs new file mode 100644 index 0000000000..b9b097a149 --- /dev/null +++ b/Content.Server/Parkstation/Species/Shadowkin/Components/ShadowkinSightComponent.cs @@ -0,0 +1,4 @@ +namespace Content.Server.Parkstation.Species.Shadowkin.Components; + +[RegisterComponent] +public sealed partial class ShadowkinSightComponent : Component; diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 67b4560dbc..610e25a37f 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -65,13 +65,17 @@ private void Shutdown(EntityUid uid, ShadowkinDarkSwapPowerComponent component, private void OnInvisStartup(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentStartup args) { if (component.Pacify) - EnsureComp(uid); - - if (!component.Invisible) - return; + { + var pax = EnsureComp(uid); + pax.DisallowAllCombat = true; + pax.DisallowDisarm = true; + } - SetVisibility(uid, true); - SuppressFactions(uid, true); + if (component.Invisible) + { + SetVisibility(uid, true, true, true); + SuppressFactions(uid, true); + } } private void OnInvisShutdown(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentShutdown args) @@ -80,13 +84,15 @@ private void OnInvisShutdown(EntityUid uid, ShadowkinDarkSwappedComponent compon if (component.Invisible) { - SetVisibility(uid, false); + SetVisibility(uid, false, true, true); SuppressFactions(uid, false); } + // Prevent more updates while cleaning up component.Darken = false; - foreach (var light in component.DarkenedLights.ToArray()) + // In case more updates occur for some reason. create a copy of the list to prevent error + foreach (var light in component.DarkenedLights.ToList()) { if (!_entity.TryGetComponent(light, out var pointLight) || !_entity.TryGetComponent(light, out var shadowkinLight)) @@ -95,6 +101,7 @@ private void OnInvisShutdown(EntityUid uid, ShadowkinDarkSwappedComponent compon _darken.ResetLight(pointLight, shadowkinLight); } + // Clear the original list component.DarkenedLights.Clear(); } @@ -103,8 +110,10 @@ private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, { var performer = _entity.GetNetEntity(args.Performer); - // Need power to drain power - if (!_entity.HasComponent(args.Performer)) + // Need power to drain power + if (!_entity.HasComponent(args.Performer) + || _entity.TryGetComponent(args.Performer, out var cuff) + && cuff.AntiShadowkin) return; // Don't activate abilities if handcuffed @@ -112,64 +121,97 @@ private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, if (_entity.HasComponent(args.Performer)) return; - - var hasComp = _entity.HasComponent(args.Performer); - - if (hasComp) - Darkened(performer, args.StaminaCostOff, args.PowerCostOff, args.SoundOff, args.VolumeOff, args); - else - UnDarkened(performer, args.StaminaCostOn, args.PowerCostOn, args.SoundOn, args.VolumeOn, args); + SetDarkened(performer, !_entity.HasComponent(args.Performer), args.SoundOn, + args.VolumeOn, args.SoundOff, args.VolumeOff, args, args.StaminaCostOn, args.PowerCostOn, + args.StaminaCostOff, args.PowerCostOff); _magic.Speak(args, false); } - public void Darkened(NetEntity performer, float staminaCostOff, float powerCostOff, SoundSpecifier soundOff, float volumeOff, ShadowkinDarkSwapEvent? args) + + /// + /// Handles the effects of darkswapping + /// + /// The entity being modified + /// Is the entity swapping in to or out of The Dark? + /// Sound for the darkswapping + /// Volume for the on sound + /// Sound for the un swapping + /// Volume for the off sound + /// Stamina cost for darkswapping + /// Power cost for darkswapping + /// Stamina cost for un swapping + /// Power cost for un swapping + /// If from an event, handle it + public void SetDarkened( + NetEntity performer, + bool addComp, + SoundSpecifier? soundOn, + float? volumeOn, + SoundSpecifier? soundOff, + float? volumeOff, + ShadowkinDarkSwapEvent? args, + float staminaCostOn = 0, + float powerCostOn = 0, + float staminaCostOff = 0, + float powerCostOff = 0) { - var performerUid = _entity.GetEntity(performer); + var ent = _entity.GetEntity(performer); - var ev = new ShadowkinDarkSwapAttemptEvent(performerUid); - RaiseLocalEvent(ev); - if (ev.Cancelled) + // We require the power component to DarkSwap + if (!_entity.TryGetComponent(ent, out var power)) return; - _entity.RemoveComponent(performerUid); - RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, false)); - - _audio.PlayPvs(soundOff, performerUid, AudioParams.Default.WithVolume(volumeOff)); - - _power.TryAddPowerLevel(performerUid, -powerCostOff); - _stamina.TakeStaminaDamage(performerUid, staminaCostOff); - - if (args != null) - args.Handled = true; - } - - public void UnDarkened(NetEntity performer, float staminaCostOn, float powerCostOn, SoundSpecifier soundOn, float volumeOn, ShadowkinDarkSwapEvent? args) - { - var performerUid = _entity.GetEntity(performer); - - var ev = new ShadowkinDarkSwapAttemptEvent(performerUid); + // Ask other systems if we can DarkSwap + var ev = new ShadowkinDarkSwapAttemptEvent(ent); RaiseLocalEvent(ev); if (ev.Cancelled) return; - var comp = _entity.EnsureComponent(performerUid); - comp.Invisible = true; - comp.Pacify = true; - comp.Darken = true; + if (addComp) // Into The Dark + { + // Add the DarkSwapped component and set variables to match the power component + var comp = _entity.EnsureComponent(ent); + comp.Invisible = power.Invisible; + comp.Pacify = power.Pacify; + comp.Darken = power.Darken; + comp.DarkenRange = power.DarkenRange; + comp.DarkenRate = power.DarkenRate; + + // Tell other systems we've DarkSwapped + RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, true)); + + // Play a sound if there is one + if (soundOn != null) + _audio.PlayPvs(soundOn, ent, AudioParams.Default.WithVolume(volumeOn ?? 5f)); + + // Drain power and stamina if we have a cost + _power.TryAddPowerLevel(ent, -powerCostOn); + _stamina.TakeStaminaDamage(ent, staminaCostOn); + } + else // Out on The Dark + { + // Remove the DarkSwapped component, the rest is handled in the shutdown event + _entity.RemoveComponent(ent); - RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, true)); + // Tell other systems we've un DarkSwapped + RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, false)); - _audio.PlayPvs(soundOn, performerUid, AudioParams.Default.WithVolume(volumeOn)); + // Play a sound if there is one + if (soundOff != null) + _audio.PlayPvs(soundOff, ent, AudioParams.Default.WithVolume(volumeOff ?? 5f)); - _power.TryAddPowerLevel(performerUid, -powerCostOn); - _stamina.TakeStaminaDamage(performerUid, staminaCostOn); + // Drain power and stamina if we have a cost + _power.TryAddPowerLevel(ent, -powerCostOff); + _stamina.TakeStaminaDamage(ent, staminaCostOff); + } + // If we have an event, handle it if (args != null) args.Handled = true; } - public void SetVisibility(EntityUid uid, bool set) + public void SetVisibility(EntityUid uid, bool set, bool invisibility, bool stealth) { // We require the visibility component for this to work EnsureComp(uid); @@ -180,14 +222,20 @@ public void SetVisibility(EntityUid uid, bool set) if (_entity.TryGetComponent(uid, out EyeComponent? eye)) _eye.SetVisibilityMask(uid, eye.VisibilityMask | (int) VisibilityFlags.DarkSwapInvisibility, eye); - // Make other entities unable to see the entity unless also DarkSwapped - _visibility.AddLayer(uid, (ushort) VisibilityFlags.DarkSwapInvisibility, false); - _visibility.RemoveLayer(uid, (ushort) VisibilityFlags.Normal, false); + if (invisibility) + { + // Make other entities unable to see the entity unless also DarkSwapped + _visibility.AddLayer(uid, (ushort) VisibilityFlags.DarkSwapInvisibility, false); + _visibility.RemoveLayer(uid, (ushort) VisibilityFlags.Normal, false); + } _visibility.RefreshVisibility(uid); // Add a stealth shader to the entity - if (!_entity.HasComponent(uid)) + if (!_entity.HasComponent(uid) && stealth) + { _stealth.SetVisibility(uid, 0.8f, _entity.EnsureComponent(uid)); + _stealth.SetEnabled(uid, true); + } } else // Visible { @@ -195,14 +243,17 @@ public void SetVisibility(EntityUid uid, bool set) if (_entity.TryGetComponent(uid, out EyeComponent? eye)) _eye.SetVisibilityMask(uid, eye.VisibilityMask & ~(int) VisibilityFlags.DarkSwapInvisibility, eye); - // Make other entities able to see the entity again - _visibility.RemoveLayer(uid, (ushort) VisibilityFlags.DarkSwapInvisibility, false); - _visibility.AddLayer(uid, (ushort) VisibilityFlags.Normal, false); + if (invisibility) + { + // Make other entities able to see the entity again + _visibility.RemoveLayer(uid, (ushort) VisibilityFlags.DarkSwapInvisibility, false); + _visibility.AddLayer(uid, (ushort) VisibilityFlags.Normal, false); + } _visibility.RefreshVisibility(uid); // Remove the stealth shader from the entity if (!_entity.HasComponent(uid)) - _stealth.SetVisibility(uid, 1f, _entity.EnsureComponent(uid)); + _stealth.SetEnabled(uid, false); } } diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index e6c7e81e71..f568ed706a 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -61,7 +61,7 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki if (_entity.TryGetComponent(uid, out var sleepingComponent)) _actions.RemoveAction(args.Performer, sleepingComponent.WakeAction); - _power.TryAddMultiplier(args.Performer, 1.5f); + _power.TryAddMultiplier(args.Performer, 2f); // No action cooldown _actions.ClearCooldown(sleepingComponent?.WakeAction); @@ -72,7 +72,7 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki // Wake up _entity.RemoveComponent(args.Performer); _entity.RemoveComponent(args.Performer); - _power.TryAddMultiplier(args.Performer, -1.5f); + _power.TryAddMultiplier(args.Performer, -2f); // Action cooldown args.Handled = true; diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs index a576556d8e..3d81c0254a 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Teleport.cs @@ -59,17 +59,16 @@ private void Shutdown(EntityUid uid, ShadowkinTeleportPowerComponent component, private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, ShadowkinTeleportEvent args) { - // Need power to drain power - if (!_entity.TryGetComponent(args.Performer, out var comp)) - return; - - // Don't activate abilities if handcuffed - // TODO: Something like the Psionic Headcage to disable powers for Shadowkin - if (_entity.HasComponent(args.Performer)) + // Need power to drain power + if (!_entity.TryGetComponent(args.Performer, out var comp) + // Don't activate abilities if handcuffed + || _entity.TryGetComponent(args.Performer, out var cuff) + && cuff.AntiShadowkin) return; var transform = Transform(args.Performer); + // Must be on the same map if (transform.MapID != args.Target.GetMapId(EntityManager)) return; @@ -98,7 +97,6 @@ private void Teleport(EntityUid uid, ShadowkinTeleportPowerComponent component, _transform.AttachToGridOrMap(pullable.Owner); // Resume pulling - // TODO: This does nothing? // This does things sometimes, but the client never knows // This does nothing?? _pulling.TryStartPull(args.Performer, pullable.Owner); } diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs index c17e4b4c01..5a9fc9a58a 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.cs @@ -26,7 +26,7 @@ public ShadowkinPowerSystem() { ShadowkinPowerThreshold.Good, Locale.GetString("shadowkin-power-good") }, { ShadowkinPowerThreshold.Okay, Locale.GetString("shadowkin-power-okay") }, { ShadowkinPowerThreshold.Tired, Locale.GetString("shadowkin-power-tired") }, - { ShadowkinPowerThreshold.Min, Locale.GetString("shadowkin-power-min") } + { ShadowkinPowerThreshold.Min, Locale.GetString("shadowkin-power-min") }, }; } @@ -197,17 +197,17 @@ public void SetPowerLevel(EntityUid uid, float newPowerLevel) /// /// Tries to blackeye a shadowkin /// - public bool TryBlackeye(EntityUid uid) + public bool TryBlackeye(EntityUid uid, bool damage = true, bool checkPower = true) { - return _blackeye.TryBlackeye(uid); + return _blackeye.TryBlackeye(uid, damage, checkPower); } /// /// Blackeyes a shadowkin /// - public void Blackeye(EntityUid uid) + public void Blackeye(EntityUid uid, bool damage = true) { - _blackeye.Blackeye(uid); + _blackeye.Blackeye(uid, damage); } diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSightSystem.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSightSystem.cs new file mode 100644 index 0000000000..24ab53914b --- /dev/null +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSightSystem.cs @@ -0,0 +1,29 @@ +using Content.Server.Parkstation.Species.Shadowkin.Components; +using Content.Shared.Inventory.Events; + +namespace Content.Server.Parkstation.Species.Shadowkin.Systems; + +public sealed class ShadowkinSightSystem : EntitySystem +{ + [Dependency] private readonly ShadowkinDarkSwapSystem _darkSwap = default!; + + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnEquipped); + SubscribeLocalEvent(OnUnEquipped); + } + + + private void OnEquipped(EntityUid uid, ShadowkinSightComponent component, GotEquippedEvent args) + { + _darkSwap.SetVisibility(args.Equipee, true, false, false); + } + + private void OnUnEquipped(EntityUid uid, ShadowkinSightComponent component, GotUnequippedEvent args) + { + _darkSwap.SetVisibility(args.Equipee, false, false, false); + } +} diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs index 825d526e7e..86f652e0e0 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinSystem.Blackeye.cs @@ -1,4 +1,6 @@ -using Content.Server.Parkstation.Species.Shadowkin.Components; +using Content.Server.Nyanotrasen.Cloning; +using Content.Server.Parkstation.Cloning; +using Content.Server.Parkstation.Species.Shadowkin.Components; using Content.Shared.Damage; using Content.Shared.Damage.Components; using Content.Shared.Damage.Prototypes; @@ -30,15 +32,18 @@ public override void Initialize() SubscribeLocalEvent(OnBlackeyeAttempt); SubscribeAllEvent(OnBlackeye); + + SubscribeLocalEvent(OnCloned); } private void OnBlackeyeAttempt(ShadowkinBlackeyeAttemptEvent ev) { var uid = _entity.GetEntity(ev.Ent); - if (!_entity.TryGetComponent(uid, out var component) || - component.Blackeye || - !(component.PowerLevel <= ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Min] + 5)) + if (!_entity.TryGetComponent(uid, out var component) + || component.Blackeye + || ev.CheckPower + && component.PowerLevel > ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Min] + 5) ev.Cancel(); } @@ -56,13 +61,14 @@ private void OnBlackeye(ShadowkinBlackeyeEvent ev) _power.SetPowerLevel(uid, ShadowkinComponent.PowerThresholds[ShadowkinPowerThreshold.Min]); // Update client state - Dirty(component); + Dirty(uid, component); // Remove powers _entity.RemoveComponent(uid); _entity.RemoveComponent(uid); _entity.RemoveComponent(uid); _entity.RemoveComponent(uid); + _entity.RemoveComponent(uid); if (!ev.Damage) @@ -73,9 +79,7 @@ private void OnBlackeye(ShadowkinBlackeyeEvent ev) // Stamina crit if (_entity.TryGetComponent(uid, out var stamina)) - { _stamina.TakeStaminaDamage(uid, stamina.CritThreshold, null, uid); - } // Nearly crit with cellular damage // If already 5 damage off of crit, don't do anything @@ -87,34 +91,46 @@ private void OnBlackeye(ShadowkinBlackeyeEvent ev) _damageable.TryChangeDamage(uid, new DamageSpecifier(_prototype.Index("Cellular"), - Math.Max((double) (key.Value - minus - 5), 0)), - true, - true, - null, - null); + Math.Max((double) (key.Value - minus - 5), 0)), true); + } + + private void OnCloned(BeenClonedEvent ev) + { + // Don't give blackeyed Shadowkin their abilities back when they're cloned. + if (_entity.TryGetComponent(ev.OriginalMob, out var shadowkin) && + shadowkin.Blackeye) + _power.TryBlackeye(ev.Mob, false, false); + + // Blackeye the Shadowkin that come from the metempsychosis machine + if (_entity.HasComponent(ev.Cloner) && + _entity.HasComponent(ev.Mob)) + _power.TryBlackeye(ev.Mob, false, false); } /// /// Tries to blackeye a shadowkin /// - public bool TryBlackeye(EntityUid uid) + public bool TryBlackeye(EntityUid uid, bool damage = true, bool checkPower = true) { + if (!_entity.HasComponent(uid)) + return false; + var ent = _entity.GetNetEntity(uid); // Raise an attempted blackeye event - var ev = new ShadowkinBlackeyeAttemptEvent(ent); + var ev = new ShadowkinBlackeyeAttemptEvent(ent, checkPower); RaiseLocalEvent(ev); if (ev.Cancelled) return false; - Blackeye(uid); + Blackeye(uid, damage); return true; } /// /// Blackeyes a shadowkin /// - public void Blackeye(EntityUid uid) + public void Blackeye(EntityUid uid, bool damage = true) { var ent = _entity.GetNetEntity(uid); @@ -126,7 +142,7 @@ public void Blackeye(EntityUid uid) } component.Blackeye = true; - RaiseNetworkEvent(new ShadowkinBlackeyeEvent(ent)); - RaiseLocalEvent(new ShadowkinBlackeyeEvent(ent)); + RaiseNetworkEvent(new ShadowkinBlackeyeEvent(ent, damage)); + RaiseLocalEvent(new ShadowkinBlackeyeEvent(ent, damage)); } } diff --git a/Content.Shared/CombatMode/Pacification/PacifiedComponent.cs b/Content.Shared/CombatMode/Pacification/PacifiedComponent.cs index 464ef77885..e8c4f34732 100644 --- a/Content.Shared/CombatMode/Pacification/PacifiedComponent.cs +++ b/Content.Shared/CombatMode/Pacification/PacifiedComponent.cs @@ -12,7 +12,6 @@ namespace Content.Shared.CombatMode.Pacification; /// If you want full-pacifism (no combat mode at all), you can simply set before adding. /// [RegisterComponent, NetworkedComponent, AutoGenerateComponentPause] -[Access(typeof(PacificationSystem))] public sealed partial class PacifiedComponent : Component { [DataField] diff --git a/Content.Shared/Cuffs/Components/HandcuffComponent.cs b/Content.Shared/Cuffs/Components/HandcuffComponent.cs index 07468a4dab..ffc5a1f423 100644 --- a/Content.Shared/Cuffs/Components/HandcuffComponent.cs +++ b/Content.Shared/Cuffs/Components/HandcuffComponent.cs @@ -99,6 +99,12 @@ public sealed partial class HandcuffComponent : Component /// [DataField] public bool UncuffEasierWhenLarge = false; + + + // Parkstation-Shadowkin Start + [DataField] + public bool AntiShadowkin; + // Parkstation-Shadowkin End } /// diff --git a/Content.Shared/Parkstation/Clothing/Components/ClothingGrantComponentComponent.cs b/Content.Shared/Parkstation/Clothing/Components/ClothingGrantComponentComponent.cs index 749ed07366..a3ffb93754 100644 --- a/Content.Shared/Parkstation/Clothing/Components/ClothingGrantComponentComponent.cs +++ b/Content.Shared/Parkstation/Clothing/Components/ClothingGrantComponentComponent.cs @@ -1,15 +1,14 @@ using Robust.Shared.Prototypes; -namespace Content.Shared.Parkstation.Clothing.Components +namespace Content.Shared.Parkstation.Clothing.Components; + +[RegisterComponent] +public sealed partial class ClothingGrantComponentComponent : Component { - [RegisterComponent] - public sealed partial class ClothingGrantComponentComponent : Component - { - [DataField("component", required: true)] - [AlwaysPushInheritance] - public ComponentRegistry Components { get; private set; } = new(); + [DataField("component", required: true)] + [AlwaysPushInheritance] + public ComponentRegistry Components { get; private set; } = new(); - [ViewVariables(VVAccess.ReadWrite)] - public bool IsActive = false; - } + [ViewVariables(VVAccess.ReadWrite)] + public bool IsActive = false; } diff --git a/Content.Shared/Parkstation/Species/Shadowkin/Components/ShadowkinComponent.cs b/Content.Shared/Parkstation/Species/Shadowkin/Components/ShadowkinComponent.cs index 023bae1be5..41186eae39 100644 --- a/Content.Shared/Parkstation/Species/Shadowkin/Components/ShadowkinComponent.cs +++ b/Content.Shared/Parkstation/Species/Shadowkin/Components/ShadowkinComponent.cs @@ -13,10 +13,10 @@ public sealed partial class ShadowkinComponent : Component public float MaxedPowerRoof = 0f; [ViewVariables(VVAccess.ReadWrite)] - public float MaxedPowerRateMin = 45f; + public float MaxedPowerRateMin = 90f; [ViewVariables(VVAccess.ReadWrite)] - public float MaxedPowerRateMax = 150f; + public float MaxedPowerRateMax = 240f; [ViewVariables(VVAccess.ReadWrite)] @@ -76,7 +76,7 @@ public float PowerLevel /// How much energy is gained per second. /// [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] - public float PowerLevelGain = 0.75f; + public float PowerLevelGain = 0.5f; /// /// Power gain multiplier diff --git a/Content.Shared/Parkstation/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs b/Content.Shared/Parkstation/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs index 9d4e3d8675..7eabadd869 100644 --- a/Content.Shared/Parkstation/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs +++ b/Content.Shared/Parkstation/Species/Shadowkin/Components/ShadowkinDarkSwappedComponent.cs @@ -6,19 +6,23 @@ namespace Content.Shared.Parkstation.Species.Shadowkin.Components; public sealed partial class ShadowkinDarkSwappedComponent : Component { /// - /// If it should be sent to the dark + /// If the entity should be sent to the dark /// + /// + /// This is also defined in the power component, this is if you want to use only some effects of the swap without a toggle + /// [DataField("invisible")] public bool Invisible = true; /// - /// If it should be pacified + /// If the entity should be pacified /// + /// [DataField("pacify")] public bool Pacify = true; /// - /// If it should dim nearby lights + /// If the entity should dim nearby lights when swapped /// [DataField("darken"), ViewVariables(VVAccess.ReadWrite)] public bool Darken = true; @@ -26,12 +30,19 @@ public sealed partial class ShadowkinDarkSwappedComponent : Component /// /// How far to dim nearby lights /// + /// [DataField("range"), ViewVariables(VVAccess.ReadWrite)] public float DarkenRange = 5f; [ViewVariables(VVAccess.ReadOnly)] public List DarkenedLights = new(); + /// + /// How fast to refresh nearby light dimming in seconds + ///
+ /// Without this, performance would be significantly worse + ///
+ /// [ViewVariables(VVAccess.ReadWrite)] public float DarkenRate = 0.084f; // 1/12th of a second diff --git a/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs b/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs index 42b2206230..70613f4b22 100644 --- a/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs +++ b/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Blackeye.cs @@ -5,28 +5,18 @@ namespace Content.Shared.Parkstation.Species.Shadowkin.Events; /// /// Raised to notify other systems of an attempt to blackeye a shadowkin. /// -public sealed class ShadowkinBlackeyeAttemptEvent : CancellableEntityEventArgs +public sealed class ShadowkinBlackeyeAttemptEvent(NetEntity ent, bool checkPower = true) : CancellableEntityEventArgs { - public readonly NetEntity Ent; - - public ShadowkinBlackeyeAttemptEvent(NetEntity ent) - { - Ent = ent; - } + public readonly NetEntity Ent = ent; + public readonly bool CheckPower = checkPower; } /// /// Raised when a shadowkin becomes a blackeye. /// [Serializable, NetSerializable] -public sealed class ShadowkinBlackeyeEvent : EntityEventArgs +public sealed class ShadowkinBlackeyeEvent(NetEntity ent, bool damage = true) : EntityEventArgs { - public readonly NetEntity Ent; - public readonly bool Damage; - - public ShadowkinBlackeyeEvent(NetEntity ent, bool damage = true) - { - Ent = ent; - Damage = damage; - } + public readonly NetEntity Ent = ent; + public readonly bool Damage = damage; } diff --git a/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs b/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs index febc58b8c5..d30413cfa4 100644 --- a/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs +++ b/Content.Shared/Parkstation/Species/Shadowkin/Events/ShadowkinEvents.Powers.cs @@ -76,35 +76,21 @@ public sealed partial class ShadowkinDarkSwapEvent : InstantActionEvent, ISpeakS public string? Speech { get; set; } } -public sealed class ShadowkinDarkSwapAttemptEvent : CancellableEntityEventArgs +public sealed class ShadowkinDarkSwapAttemptEvent(EntityUid performer) : CancellableEntityEventArgs { - EntityUid Performer; - - public ShadowkinDarkSwapAttemptEvent(EntityUid performer) - { - Performer = performer; - } + public EntityUid Performer = performer; } -public sealed partial class ShadowkinRestEvent: InstantActionEvent -{ - -} +public sealed partial class ShadowkinRestEvent: InstantActionEvent; /// /// Raised over network to notify the client that they're going in/out of The Dark. /// [Serializable, NetSerializable] -public sealed class ShadowkinDarkSwappedEvent : EntityEventArgs +public sealed class ShadowkinDarkSwappedEvent(NetEntity performer, bool darkSwapped) : EntityEventArgs { - public NetEntity Performer { get; } - public bool DarkSwapped { get; } - - public ShadowkinDarkSwappedEvent(NetEntity performer, bool darkSwapped) - { - Performer = performer; - DarkSwapped = darkSwapped; - } + public NetEntity Performer = performer; + public bool DarkSwapped = darkSwapped; } diff --git a/Content.Shared/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Shared/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 60299b5011..48068385d9 100644 --- a/Content.Shared/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Shared/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -22,15 +22,15 @@ public override void Initialize() private void OnInteractionAttempt(EntityUid uid, ShadowkinDarkSwappedComponent component, InteractionAttemptEvent args) { - if (args.Target == null || !_entity.TryGetComponent(args.Target, out var __) || - _entity.TryGetComponent(args.Target, out _)) + if (args.Target == null + || !_entity.HasComponent(args.Target) + || _entity.HasComponent(args.Target)) return; args.Cancel(); - if (_gameTiming.InPrediction) - return; - // TODO This appears on way too many things - _popup.PopupEntity(Loc.GetString("ethereal-pickup-fail"), args.Target.Value, uid); + if (_gameTiming is { InPrediction: true, IsFirstTimePredicted: true }) + //TODO: This appears on way too many things + _popup.PopupEntity(Loc.GetString("ethereal-pickup-fail"), args.Target.Value, uid); } } diff --git a/Resources/Prototypes/Nyanotrasen/metempsychoticHumanoids.yml b/Resources/Prototypes/Nyanotrasen/metempsychoticHumanoids.yml index 891067b1c1..87101c7139 100644 --- a/Resources/Prototypes/Nyanotrasen/metempsychoticHumanoids.yml +++ b/Resources/Prototypes/Nyanotrasen/metempsychoticHumanoids.yml @@ -11,3 +11,4 @@ Reptilian: 0.5 SlimePerson: 0.5 Vulpkanin: 0.5 + Shadowkin: 0.4 diff --git a/Resources/Prototypes/Parkstation/Body/Organs/shadowkin.yml b/Resources/Prototypes/Parkstation/Body/Organs/shadowkin.yml new file mode 100644 index 0000000000..3d51544e08 --- /dev/null +++ b/Resources/Prototypes/Parkstation/Body/Organs/shadowkin.yml @@ -0,0 +1,136 @@ +- type: entity + id: BaseShadowkinOrgan + parent: BaseItem + abstract: true + components: + - type: Organ + - type: Sprite + sprite: Parkstation/Mobs/Species/Shadowkin/organs.rsi + + +- type: entity + id: OrganShadowkinBrain + parent: BaseShadowkinOrgan + name: brain + description: The source of incredible, unending intelligence. + components: + - type: Sprite + state: brain + - type: Organ + - type: Input + context: ghost + - type: InputMover + - type: MovementSpeedModifier # How the hell does it walk? + baseWalkSpeed: 0 + baseSprintSpeed: 0 + - type: Brain + +- type: entity + id: OrganShadowkinEyes + parent: BaseShadowkinOrgan + name: eyes + description: I see beyond anything you ever will! + components: + - type: Sprite + state: eyes + - type: Organ + +- type: entity + id: OrganShadowkinEars + parent: BaseShadowkinOrgan + name: ears + description: Hey, listen! + components: + - type: Sprite + state: ears + - type: Organ + +- type: entity + id: OrganShadowkinTongue + parent: BaseShadowkinOrgan + name: tongue + description: A fleshy muscle mostly used for lying. + components: + - type: Sprite + state: tongue + - type: Organ + + +- type: entity + id: OrganShadowkinAppendix + parent: BaseShadowkinOrgan + name: appendix + description: What does this do? + components: + - type: Sprite + state: appendix + - type: Organ + + +- type: entity + id: OrganShadowkinHeart + parent: BaseShadowkinOrgan + name: heart + description: I feel bad for the heartless bastard who lost this. + components: + - type: Sprite + state: heart + - type: Organ + - type: Metabolizer + maxReagents: 2 + metabolizerTypes: [Shadowkin] + groups: + - id: Medicine + - id: Poison + - id: Narcotic + +- type: entity + id: OrganShadowkinStomach + parent: BaseShadowkinOrgan + name: stomach + description: '"Yummy!", says the stomach, although you are unable to hear it.' + components: + - type: Sprite + state: stomach + - type: Organ + - type: SolutionContainerManager + solutions: + stomach: + maxVol: 40 + - type: Stomach + - type: Metabolizer + maxReagents: 3 + metabolizerTypes: [Shadowkin] + groups: + - id: Food + - id: Drink + +- type: entity + id: OrganShadowkinLiver + parent: BaseShadowkinOrgan + name: liver + description: "Live 'er? I hardly know 'er!" + components: + - type: Sprite + state: liver + - type: Organ + - type: Metabolizer + maxReagents: 1 + metabolizerTypes: [Shadowkin] + groups: + - id: Alcohol + rateModifier: 0.1 + +- type: entity + id: OrganShadowkinKidneys + parent: BaseShadowkinOrgan + name: kidneys + description: Give the kid their knees back, please, this is the third time this week. + components: + - type: Sprite + state: kidneys + - type: Organ + - type: Metabolizer + maxReagents: 5 + metabolizerTypes: [Shadowkin] + removeEmpty: true \ No newline at end of file diff --git a/Resources/Prototypes/Parkstation/Chemistry/metabolizer_types.yml b/Resources/Prototypes/Parkstation/Chemistry/metabolizer_types.yml new file mode 100644 index 0000000000..66ce009b66 --- /dev/null +++ b/Resources/Prototypes/Parkstation/Chemistry/metabolizer_types.yml @@ -0,0 +1,3 @@ +- type: metabolizerType + id: Shadowkin + name: shadowkin diff --git a/Resources/Prototypes/Parkstation/Entities/Body/Parts/shadowkin.yml b/Resources/Prototypes/Parkstation/Entities/Body/Parts/shadowkin.yml index 7edfb6b7ec..da5fba8dd2 100644 --- a/Resources/Prototypes/Parkstation/Entities/Body/Parts/shadowkin.yml +++ b/Resources/Prototypes/Parkstation/Entities/Body/Parts/shadowkin.yml @@ -6,9 +6,9 @@ components: - type: Sprite netsync: false - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi - type: Icon - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi - type: Damageable damageContainer: Biological - type: BodyPart diff --git a/Resources/Prototypes/Parkstation/Entities/Body/Prototypes/shadowkin.yml b/Resources/Prototypes/Parkstation/Entities/Body/Prototypes/shadowkin.yml index b3e47eb224..88e30ad0b2 100644 --- a/Resources/Prototypes/Parkstation/Entities/Body/Prototypes/shadowkin.yml +++ b/Resources/Prototypes/Parkstation/Entities/Body/Prototypes/shadowkin.yml @@ -8,8 +8,8 @@ connections: - torso organs: - brain: OrganHumanBrain - eyes: OrganHumanEyes + brain: OrganShadowkinBrain + eyes: OrganShadowkinEyes torso: part: TorsoShadowkin connections: @@ -17,12 +17,12 @@ - right arm - left leg - right leg - organs: # placeholders - heart: OrganHumanHeart - lungs: OrganHumanLungs - stomach: OrganHumanStomach - liver: OrganHumanLiver - kidneys: OrganHumanKidneys + organs: + heart: OrganShadowkinHeart + # lungs: OrganShadowkinLungs + stomach: OrganShadowkinStomach + liver: OrganShadowkinLiver + kidneys: OrganShadowkinKidneys right arm: part: RightArmShadowkin connections: diff --git a/Resources/Prototypes/Parkstation/Entities/Clothing/Eyes/glasses.yml b/Resources/Prototypes/Parkstation/Entities/Clothing/Eyes/glasses.yml new file mode 100644 index 0000000000..3693a440ee --- /dev/null +++ b/Resources/Prototypes/Parkstation/Entities/Clothing/Eyes/glasses.yml @@ -0,0 +1,14 @@ +- type: entity + parent: ClothingEyesBase + id: ClothingEyesGlassesShadowkinDarkWindow + name: darkened goggles + description: An unusual pair of goggles designed to allow the wearer to peer into The Dark. + components: + - type: Sprite + sprite: Parkstation/Clothing/Eyes/Glasses/darkened.rsi + - type: Clothing + sprite: Parkstation/Clothing/Eyes/Glasses/darkened.rsi + - type: EyeProtection + - type: DropOnSlip + chance: 20 + - type: ShadowkinSight diff --git a/Resources/Prototypes/Parkstation/Entities/Clothing/Head/hardsuit-helmets.yml b/Resources/Prototypes/Parkstation/Entities/Clothing/Head/hardsuit-helmets.yml index fc6b369310..f636057462 100644 --- a/Resources/Prototypes/Parkstation/Entities/Clothing/Head/hardsuit-helmets.yml +++ b/Resources/Prototypes/Parkstation/Entities/Clothing/Head/hardsuit-helmets.yml @@ -39,3 +39,30 @@ Piercing: 0.95 Heat: 0.9 Radiation: 0.6 + +- type: entity + parent: ClothingHeadHardsuitBase + id: ClothingHeadHelmetHardsuitShadowkinDarkswap + noSpawn: true + name: darkened softsuit helmet + components: + - type: Sprite + sprite: Parkstation/Clothing/Head/Hardsuits/darkened.rsi + - type: Clothing + sprite: Parkstation/Clothing/Head/Hardsuits/darkened.rsi + - type: PointLight + color: "#d6adff" + - type: Armor + modifiers: + coefficients: + Blunt: 1.4 + Slash: 1.3 + Piercing: 1.2 + Radiation: 0.4 + - type: ClothingSpeedModifier + walkModifier: 0.5 + sprintModifier: 0.5 + - type: ClothingGrantComponent + component: + - type: ShadowkinDarkSwapped + darken: false diff --git a/Resources/Prototypes/Parkstation/Entities/Clothing/Head/hardsuits.yml b/Resources/Prototypes/Parkstation/Entities/Clothing/Head/hardsuits.yml index 43f01db5ec..148219f03f 100644 --- a/Resources/Prototypes/Parkstation/Entities/Clothing/Head/hardsuits.yml +++ b/Resources/Prototypes/Parkstation/Entities/Clothing/Head/hardsuits.yml @@ -26,3 +26,33 @@ damageCoefficient: 0.8 - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitHoP + +- type: entity + parent: ClothingOuterHardsuitBase + id: ClothingOuterHardsuitShadowkinDarkswap + name: darkened softsuit + description: This hardsuit allows the wearer to jump the gap between the "normal" dimension and The Dark. + components: + - type: Sprite + sprite: Parkstation/Clothing/OuterClothing/Hardsuits/darkened.rsi + - type: Clothing + sprite: Parkstation/Clothing/OuterClothing/Hardsuits/darkened.rsi + - type: Armor + modifiers: + coefficients: + Blunt: 0.9 + Slash: 0.8 + Piercing: 0.9 + Radiation: 0.3 + - type: ClothingSpeedModifier + walkModifier: 0.9 + sprintModifier: 0.9 + - type: Item + size: 65 + - type: Tag + tags: + - FullBodyOuter + - Hardsuit + - type: ToggleableClothing + clothingPrototype: ClothingHeadHelmetHardsuitShadowkinDarkswap + actionId: ShadowkinDarkSwapHardsuitToggle diff --git a/Resources/Prototypes/Parkstation/Entities/Mobs/Player/shadowkin.yml b/Resources/Prototypes/Parkstation/Entities/Mobs/Player/shadowkin.yml index f8a2449c66..916bf83767 100644 --- a/Resources/Prototypes/Parkstation/Entities/Mobs/Player/shadowkin.yml +++ b/Resources/Prototypes/Parkstation/Entities/Mobs/Player/shadowkin.yml @@ -6,10 +6,11 @@ components: - type: HumanoidAppearance species: Shadowkin + initial: Shadowkin - type: Hunger - type: Thirst - type: Icon - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: full - type: Body prototype: Shadowkin @@ -82,7 +83,58 @@ layer: - MobLayer - type: Sprite + noRot: true + drawdepth: Mobs scale: 0.85, 0.85 # Small + layers: + - map: ["enum.HumanoidVisualLayers.Chest"] + - map: ["enum.HumanoidVisualLayers.Head"] + - map: ["enum.HumanoidVisualLayers.Snout"] + - map: ["enum.HumanoidVisualLayers.Eyes"] + - map: ["enum.HumanoidVisualLayers.RArm"] + - map: ["enum.HumanoidVisualLayers.LArm"] + - map: ["enum.HumanoidVisualLayers.RLeg"] + - map: ["enum.HumanoidVisualLayers.LLeg"] + - shader: StencilClear + sprite: Mobs/Species/Human/parts.rsi + state: l_leg + - shader: StencilMask + map: ["enum.HumanoidVisualLayers.StencilMask"] + sprite: Mobs/Customization/masking_helpers.rsi + state: full + visible: false + - map: ["enum.HumanoidVisualLayers.LFoot"] + - map: ["enum.HumanoidVisualLayers.RFoot"] + - map: ["socks"] + - map: ["underpants"] + - map: ["undershirt"] + - map: ["jumpsuit"] + - map: ["enum.HumanoidVisualLayers.LHand"] + - map: ["enum.HumanoidVisualLayers.RHand"] + - map: ["enum.HumanoidVisualLayers.Handcuffs"] + color: "#ffffff" + sprite: Objects/Misc/handcuffs.rsi + state: body-overlay-2 + visible: false + - map: ["id"] + - map: ["gloves"] + - map: ["shoes"] + - map: ["ears"] + - map: ["outerClothing"] + - map: ["eyes"] + - map: ["belt"] + - map: ["neck"] + - map: ["back"] + - map: ["enum.HumanoidVisualLayers.FacialHair"] + - map: ["enum.HumanoidVisualLayers.Hair"] + - map: ["enum.HumanoidVisualLayers.HeadSide"] + - map: ["enum.HumanoidVisualLayers.HeadTop"] + - map: ["mask"] + - map: ["head"] + - map: ["pocket1"] + - map: ["pocket2"] + - map: ["enum.HumanoidVisualLayers.Tail"] + - map: ["enum.HumanoidVisualLayers.Wings"] - type: Eye zoom: "0.85, 0.85" - type: MeleeWeapon @@ -129,8 +181,6 @@ - type: PotentialPsionic chance: -2 # They have their own abilities. - type: MovementSpeedModifier - baseWalkSpeed : 4.5 - baseSprintSpeed : 2.7 - type: entity diff --git a/Resources/Prototypes/Parkstation/Entities/Objects/Misc/handcuffs.yml b/Resources/Prototypes/Parkstation/Entities/Objects/Misc/handcuffs.yml new file mode 100644 index 0000000000..e458dd804f --- /dev/null +++ b/Resources/Prototypes/Parkstation/Entities/Objects/Misc/handcuffs.yml @@ -0,0 +1,21 @@ +- type: entity + parent: Handcuffs + id: HandcuffsShadowkin + name: shadowkin restraints + description: One of the first creations after finding Shadowkin, these were used to contain the Shadowkin during research so they didn't teleport away. + components: + - type: Item + size: 20 + - type: Handcuff + cuffedRSI: Parkstation/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi + breakoutTime: 40 + damageOnResist: + types: + Blunt: 2 + cuffTime: 4 + uncuffTime: 5 + stunBonus: 4 + antiShadowkin: true + - type: Sprite + sprite: Parkstation/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi + state: icon diff --git a/Resources/Prototypes/Parkstation/HumanoidProfiles/shadowkin.yml b/Resources/Prototypes/Parkstation/HumanoidProfiles/shadowkin.yml new file mode 100644 index 0000000000..1093b4f2c7 --- /dev/null +++ b/Resources/Prototypes/Parkstation/HumanoidProfiles/shadowkin.yml @@ -0,0 +1,6 @@ +- type: humanoidProfile + id: Shadowkin + profile: + species: Shadowkin + height: 0.85 + width: 0.85 diff --git a/Resources/Prototypes/Parkstation/Magic/shadowkin.yml b/Resources/Prototypes/Parkstation/Magic/shadowkin.yml index e90a5d332c..f33d94d59b 100644 --- a/Resources/Prototypes/Parkstation/Magic/shadowkin.yml +++ b/Resources/Prototypes/Parkstation/Magic/shadowkin.yml @@ -1,5 +1,6 @@ - type: entity id: ShadowkinTeleportAction + noSpawn: true name: action-name-shadowkin-teleport description: action-description-shadowkin-teleport components: @@ -20,6 +21,7 @@ - type: entity id: ShadowkinDarkSwapAction + noSpawn: true name: action-name-shadowkin-darkswap description: action-description-shadowkin-darkswap components: @@ -39,6 +41,7 @@ - type: entity id: ShadowkinRestAction + noSpawn: true name: action-name-shadowkin-rest description: action-description-shadowkin-rest components: @@ -52,3 +55,17 @@ checkCanInteract: false checkConsciousness: false event: !type:ShadowkinRestEvent + +- type: entity + id: ShadowkinDarkSwapHardsuitToggle + noSpawn: true + name: action-name-shadowkin-darkswap + components: + - type: InstantAction + useDelay: 15 + itemIconStyle: NoItem + priority: -21 + icon: + sprite: Parkstation/Clothing/Head/Hardsuits/darkened.rsi + state: icon + event: !type:ToggleClothingEvent diff --git a/Resources/Prototypes/Parkstation/Species/shadowkin.yml b/Resources/Prototypes/Parkstation/Species/shadowkin.yml index d0c5388b35..fd44829b3e 100644 --- a/Resources/Prototypes/Parkstation/Species/shadowkin.yml +++ b/Resources/Prototypes/Parkstation/Species/shadowkin.yml @@ -73,89 +73,89 @@ - type: humanoidBaseSprite id: MobShadowkinHead baseSprite: - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: head_m - type: humanoidBaseSprite id: MobShadowkinHeadMale baseSprite: - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: head_m - type: humanoidBaseSprite id: MobShadowkinHeadFemale baseSprite: - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: head_f - type: humanoidBaseSprite id: MobShadowkinTorso baseSprite: - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: torso_m - type: humanoidBaseSprite id: MobShadowkinTorsoMale baseSprite: - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: torso_m - type: humanoidBaseSprite id: MobShadowkinTorsoFemale baseSprite: - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: torso_f - type: humanoidBaseSprite id: MobShadowkinLLeg baseSprite: - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: l_leg - type: humanoidBaseSprite id: MobShadowkinLHand baseSprite: - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: l_hand - type: humanoidBaseSprite id: MobShadowkinEyes baseSprite: - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: eyes - type: humanoidBaseSprite id: MobShadowkinLArm baseSprite: - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: l_arm - type: humanoidBaseSprite id: MobShadowkinLFoot baseSprite: - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: l_foot - type: humanoidBaseSprite id: MobShadowkinRLeg baseSprite: - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: r_leg - type: humanoidBaseSprite id: MobShadowkinRHand baseSprite: - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: r_hand - type: humanoidBaseSprite id: MobShadowkinRArm baseSprite: - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: r_arm - type: humanoidBaseSprite id: MobShadowkinRFoot baseSprite: - sprite: Parkstation/Mobs/Species/shadowkin.rsi + sprite: Parkstation/Mobs/Species/Shadowkin/parts.rsi state: r_foot diff --git a/Resources/Prototypes/Reagents/toxins.yml b/Resources/Prototypes/Reagents/toxins.yml index 661e1b7dd1..30cb3893a1 100644 --- a/Resources/Prototypes/Reagents/toxins.yml +++ b/Resources/Prototypes/Reagents/toxins.yml @@ -512,6 +512,14 @@ shouldHave: true reagent: Protein amount: 0.5 + # Parkstation-Shadowkin Start + - !type:AdjustReagent + conditions: + - !type:OrganType + type: Shadowkin + reagent: Protein + amount: 0.5 + # Parkstation-Shadowkin End - type: reagent id: Allicin diff --git a/Resources/Textures/Parkstation/Clothing/Eyes/Glasses/darkened.rsi/equipped-EYES.png b/Resources/Textures/Parkstation/Clothing/Eyes/Glasses/darkened.rsi/equipped-EYES.png new file mode 100644 index 0000000000000000000000000000000000000000..39fafeb1449fe4e7c941553177275a6764af8e1c GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|Zh5*mhE&XX zdut=-AqSCTAN3Q|UFIH`ptbe^i{wGWAPzsJB_|~MCU7!sTR-UqgB$DXh>k^UD(NCR z|MtIox1;?1y1o8P3|pqFc)m6I|GsLS^ckPaC)X548vpil&)0eOxhi^^)x7h)TOIeW zFBHg_xon=d?{oGEOKP`HR>?heh`Tvc*Yn?r|4XI_Uq8(VbPW^~JpFU`k5r3+@!VAp zYh%`g+y6aOcSh~U;^svfRZ-_Roq74^+}UG=G1F&HUXmTRAbYP_-pm$-FH@ge&V(Cs t;S}q2Q?u7ykFCA|4dqLX@J#ddWzYh$IiQwY3Z4vNdAjk1@5Yiy`?t)*pFY&zJ)JZy|?rD;)PEug}uGP&tKIsEKllg ziaw&cIwYHAR@mz~A2Tu-w^+x{{UV)Yec?6#m*txnZ|Hnl6UNO@Q{ODWw=_w#;pSqd z1!X~xpMJHSGr87ylW$IG(5_ukcD%jJ#SFL4z0GL;5$M`-Y@WI2n}SC?I@9GJZWiG4 z@;&@LXyu;8qK6o-tvsuElm}?X-pHEkE3b&;{C|F7d*Pg9u2v<6osXLn`LH zy|vNnaDc?okHL-^f=p~oGhMVIc5#<~V%(H^+V~mgF9tvH8m5Cqp3|KkvN0tcd}!q{ zM@DC-p!5IzmfyYi6`Yu)%m_3Y2+~u=Uup_~*8ZiTeX0rzM`)vq@+F^!T;LlF4jme|vs0&+6g){B!ZWU29cd zzWWzc8auyc{;E}nUY~APd8rlos-kAn)^GLd4wKew-E4E;b5hOi6PD^Pvlrf<^L~Bt zxs%&_RW#3+FV@lTozM^$C~~lRy@~Hsm6M*DD^_Wh#4i6=)058$aVdzLv(@u|Y41h3 z&U^env^U;Tp6ugr=G%!SLI!TtDMg$MY?&B3o(uoBZMR#qUH2SNJzr{sXPU1sgBFm@ V0WtsxE(K2pQJ$`TF6*2UngG@6p5y=k literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Clothing/Eyes/Glasses/darkened.rsi/inhand-right.png b/Resources/Textures/Parkstation/Clothing/Eyes/Glasses/darkened.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..26fd8e57a42b5079a1d9454b1601a85f3f7e71b3 GIT binary patch literal 397 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zbv<1iLn`LH zz2)e2*g@jx$8g6CK_)h)$j*=rCHiMhF{ezwJI7G{1!D}WP2&ZlC9|CpnHV=dNQzmx zVB5xx39J6!H``nh|LnAuKNHYoAow@c@phxm=|feflh$kN-l={4^S;@>J)9qZwodxu zx%uWA)AuLWwO7vD&uc$Z&FEOmVOLw5WS<#6!asLisxl3l_k3;T_I--kxijo-yeFMo zw9#y~_0-gxzj+OgwLJU~)_>M%Qb}p;szn;xp8eaxc(K-bWVyu5G_!9yzV``kz3Nw|Ahf1-bagXRH5) zcei(547Zk6x?Pf)^dCmKEqiO3=NOJGUY6*wY%xL-3_RXFEzq5 c&DWPf3&`dGnF9ouf+vG0Pgg&ebxsLQ0Bh{1tN;K2 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Clothing/Eyes/Glasses/darkened.rsi/meta.json b/Resources/Textures/Parkstation/Clothing/Eyes/Glasses/darkened.rsi/meta.json new file mode 100644 index 0000000000..555efbc7da --- /dev/null +++ b/Resources/Textures/Parkstation/Clothing/Eyes/Glasses/darkened.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "JustAnOrange", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-EYES", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Parkstation/Clothing/Head/Hardsuits/darkened.rsi/equipped-HELMET.png b/Resources/Textures/Parkstation/Clothing/Head/Hardsuits/darkened.rsi/equipped-HELMET.png new file mode 100644 index 0000000000000000000000000000000000000000..f6599f7bd49ada543988813203ec1592c7d91c7e GIT binary patch literal 1388 zcmV-y1(W)TP)EX>4Tx04R}tkv&MmKpe$iQ^gM|LaiX;kfA!+MMWG-6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|>f)s6A|?JWDYS_3;J6>}?mh0_0Yam~RI@7zsG4P@ z;xRFsTNQg=(T8CGK?Egc>WTDX2A<>V9zMR_MR=C?xj)B%k~bOP6N#ftH!R`};@M40 z=e$oGVkJo-J|~_u=z_$LT$f#b<6LxD;F%#KlbRIIO4|K2h+1tNoTK)Y1U|DjXP`A2J00006VoOIv0RI600RN!9r;`8x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=Lr=66BVIw;XeQX02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00TrxL_t(|+U=T8Xwz^M$G<7X9b_Fp);T1UfCYya$;u8} zZxxD+;bkx>jP5AwO{#R)fymfk13^~sI4@#hm*GKr7~-g76fJs?2|JV#T-S}@{(%ts z^U(fcR;!TMUzzwm5J+E|ygzxr_Y1rS5dSxd*BdhvD_oo}!)Y#* z=M59$a2nGo=PgZxIE4Ptz#^BL0ctqSeSQ_eUjHxG4h}8sZac2Zis`DpA~>eqjiA+i$%2x6~R?vkd#( z>3pl}vJlS3qWU@KMFvO>007L?O4(us%qbi0`<5EJI@pl{m|H8_PCL`zSrepggF!XH zL)r+sBHgy^`}@@C>=$7lK_CRv($0@1VIo4K@bE%5ClOG1VIqQzero=0{~$DWzwf8N=Mq{ zoO5O7?(>>c=5Be#-nc5mnCIHA>27GHY znOKe_Q(cknb2j7+6O$3$br4(y;7Wfz(xMe@nnwVD&1z5fq`G%jtbomJ@M&4z&u#GO zVg>A^x_7o&?a4ZA5H<-Lr34@r)$P;=>aA&EfZ+9)`s9cVnxAc&M|PWBECsi70fZ?Zj9dtU}08i@2)V*>)HBw^=YPdni7TA$-$w8nq|1^7Q3$4YB`#LNQbt`fEa0b8TwqZ~rdDIafI6!T{c?(l%t5ynb7_s9C<>>G!e?!b=8R u)X&EX>4Tx04R}tkv&MmKpe$iQ^gM|LaiX;kfA!+MMWG-6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|>f)s6A|?JWDYS_3;J6>}?mh0_0Yam~RI@7zsG4P@ z;xRFsTNQg=(T8CGK?Egc>WTDX2A<>V9zMR_MR=C?xj)B%k~bOP6N#ftH!R`};@M40 z=e$oGVkJo-J|~_u=z_$LT$f#b<6LxD;F%#KlbRIIO4|K2h+1tNoTK)Y1U|DjXP`A2J00006VoOIv0RI600RN!9r;`8x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=Lr=66gAafS1eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00AdSL_t(o!|j!^O9EjS#(#GRP7RV0aYUfd7#a<^2GQUw zG&u^l8sr}k4hpswjZQ+)=H%GW66Mg+&=7HiP>9qbi0ANepz_`2HQi_5Grqjv3(t>- z=L0RR|1RS%kIsrMS2l0lltSM#BTc}{R9pb(^}?8S-gO4j{Ua+8nuHnz%$Nm0ay_=x z(a*0j0PioSM&t8sP{z{{B)2S+5m;k8~|55E8c{j zlGcd}u(h2BAilRI-5WiAiw1nV7met&jn&A&j1xhE{M_&7{f=RrtCa!2OazcprwO&R Zw5Ih3RAP-((z5^n002ovPDHLkV1oJ>d3*o> literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Clothing/Head/Hardsuits/darkened.rsi/meta.json b/Resources/Textures/Parkstation/Clothing/Head/Hardsuits/darkened.rsi/meta.json new file mode 100644 index 0000000000..66589a849a --- /dev/null +++ b/Resources/Textures/Parkstation/Clothing/Head/Hardsuits/darkened.rsi/meta.json @@ -0,0 +1,18 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "JustAnOrange", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-HELMET", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Parkstation/Clothing/OuterClothing/Hardsuits/darkened.rsi/equipped-OUTERCLOTHING.png b/Resources/Textures/Parkstation/Clothing/OuterClothing/Hardsuits/darkened.rsi/equipped-OUTERCLOTHING.png new file mode 100644 index 0000000000000000000000000000000000000000..c93eb1bc511730e7d3472d14ca20ffb4309bce07 GIT binary patch literal 1972 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Clothing/OuterClothing/Hardsuits/darkened.rsi/inhand-left.png b/Resources/Textures/Parkstation/Clothing/OuterClothing/Hardsuits/darkened.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..6872735699de40c11816ec2058c1159ac582212d GIT binary patch literal 1097 zcmV-P1h)H$P)EX>4Tx04R}tkvmAkP!xv$riu?Lf_4yb$WWbH5EXGORV;#q(pG5I!Q`edXws0R zxHt-~1qUCCRRf)s6A|;-i6k5c1;Br6yd;Xt$&jo}=g{fv&6i_wG zNX27fHn%GFyrK_7@L>{RiJ5vLy_kV#ece+h)m?;VdH4NU14`axfKMcjGTpFiCo7lF3yD zBgX=&P$4;f@IUxHTeC1d$WEE0hc?#$dfJ^k|X(P355dien#Jv1BP#b{xx@Qt#h0{02!Lq@(pls z2uu_yd)?#Ry`6LWx2H9~ALiw9)mX_M_5c6?24YJ`L;(K){{a7>y{D4^000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2j>YA10*A1TvBoX000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}0006YNkl3`3`~yXYAPx?$Dozyy9TgFU z;vhJ5a8(pU5GQdF6kHt~x@ZwB4mv6b6~Upd4h}&gD3*eANE{?3(Td*P7s>EGOPfo1 zFS*`*x$ppl5JCtcgb+dqA%qYe+`g5_?OTa{Ytzlj3P&Pju&^J^PL2Wq4$5v620m=Z z#p1#^0O0hzH>%$(SteOe535!d17IAwwOw!hQ>W+G-_FN30|1*FgO+aAUkC8tXTU-E z5@FzDZf3ge`DXJSmFgL6$2HE%?GmsZ7nSN+>-+uH2nNP#2m>FLs`sax|1B#kY}0_^ z)G)%pPqkHRFR9}&@KKx^7Rkz84OlCdBLFzOx%lxnrNRUNVCQ7P(#?AFkMmgslhqpl zUSB?^d>HuX>h9GlVC}N}$2}{TOWFMlnQlD|VNmf>yAh8+{ui50LrCpnD7GE?7A%qY@2qA_=iBBkR+2f##$t0JZ2tt{4MOqM&rul-P~6Foiv0DV-AVk#Ou P00000NkvXXu0mjfH!Rw| literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Clothing/OuterClothing/Hardsuits/darkened.rsi/inhand-right.png b/Resources/Textures/Parkstation/Clothing/OuterClothing/Hardsuits/darkened.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..37b71b2cd3eedc31aafb459425441bf363d93fab GIT binary patch literal 1158 zcmV;11bO?3P)EX>4Tx04R}tkvmAkP!xv$riu?Lf_4yb$WWbH5EXGORV;#q(pG5I!Q`edXws0R zxHt-~1qUCCRRf)s6A|;-i6k5c1;Br6yd;Xt$&jo}=g{fv&6i_wG zNX27fHn%GFyrK_7@L>{RiJ5vLy_kV#ece+h)m?;VdH4NU14`axfKMcjGTpFiCo7lF3yD zBgX=&P$4;f@IUxHTeC1d$WEE0hc?#$dfJ^k|X(P355dien#Jv1BP#b{xx@Qt#h0{02!Lq@(pls z2uu_yd)?#Ry`6LWx2H9~ALiw9)mX_M_5c6?24YJ`L;(K){{a7>y{D4^000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2j>YA10*sF>~eqr000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}0007ANklh6z9S-Tx!L^Zs5TT%> zrIZ#z1)+mO*GdZ_h?BSo3R#0VWRXxw$Pg!Kq0lT2>Ds~J2vh1H7Sr{xR;7L#NbVH|0N%XL zCb9_GTtVq-4m<(H(lK1e#?IDeX!3sl3gv1IhBQ;N4aR8>-2#R*QLfg8-_K7TV&%~p zT*pSaY9)U0-JYYZ+3*MQ8>?^~dn8spYmfYP9UJ+L)kGITS94$wzs#2u0DNwIyEXaq z+!Fx6`=i}N_JEA}ROxCKlNw2+H@PXO=e)75N@OSHYd21A-?T^tHS znj_sb$=E+X3SG^{xJJ_NUj@2px96nlLN`hCtp)Hd5Saxz^6ACXfR1LNbCGB^_C;7M z=>oMsZK2z9@crupbbAguZEL2B z4;$BiI;yF;79dW~fV3<;yT5{)>r32RU*h+#A9(fR%Y1u45EX>4Tx04R}tkvmAkP!xv$riu?Lf_4yb$WWbH5EXGORV;#q(pG5I!Q`edXws0R zxHt-~1qUCCRRf)s6A|;-i6k5c1;Br6yd;Xt$&jo}=g{fv&6i_wG zNX27fHn%GFyrK_7@L>{RiJ5vLy_kV#ece+h)m?;VdH4NU14`axfKMcjGTpFiCo7lF3yD zBgX=&P$4;f@IUxHTeC1d$WEE0hc?#$dfJ^k|X(P355dien#Jv1BP#b{xx@Qt#h0{02!Lq@(pls z2uu_yd)?#Ry`6LWx2H9~ALiw9)mX_M_5c6?24YJ`L;(K){{a7>y{D4^000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2j>YA11c0pV%qZn000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}0006_NklZ&eO{^M^Ka+(6yh{bDPO10E2Vi#(vFbg zhfCy$z&(PM25>Alf_bue`d;^ZN0_Z-s5Dw+9RrXAU>-)Fn-+FjG?RM8? z1|u~1;mm*>Pc1Klztf`!8vMu0AdaUTV;iDW2om;u?9@U9{?q@+Q!ta)#9M~c-{DAt zM)B{*-aMuJH=-68!he)^b1MJ0@|T2*G4*G63bU+|{kAh|<-% zVByw-(fkI3!C){L3ic}rYyH@bN=(&wcT3Ydq3&$G;cQDA7kc$Vp}*@(a#OBkq&FjipB=|~B?-j&Ex zM}GI<(t!29rx!^Ifx0z4LBkwK!yu`10at609t3LaZ6+RyI6%2LJ#7 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi/icon.png b/Resources/Textures/Parkstation/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..def3161bb0aa157191591f4a2c2d4600ff9d1708 GIT binary patch literal 3072 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 YKsE=+5Foe|JQ+lJy85}Sb4q9e03B>vRsaA1 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi/inhand-right.png b/Resources/Textures/Parkstation/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..99c96d368ad662720c069d13f2110606a75f60db GIT binary patch literal 242 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|CV9FzhE&XX zdut(s@4Z{Qzbx}!;Jtc}lh$4z6SwREX=7m6d$;OW zkfDB#`QkrM_c^?J^S|d*ZKK$3uBq{h_Hb+6Pn!Mzz*=jD2lHzf*Kw5`XO6vG57fk$ f8sVAd>&u`8WOIN_0fI}xlR=cHtDnm{r-UW|L>OEz literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi/meta.json b/Resources/Textures/Parkstation/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi/meta.json new file mode 100644 index 0000000000..365122e186 --- /dev/null +++ b/Resources/Textures/Parkstation/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "JustAnOrange", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "body-overlay-2", + "directions": 4 + }, + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/appendix.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/appendix.png new file mode 100644 index 0000000000000000000000000000000000000000..0d2ad309c74d012db5d5dab59a953f02654d7a5e GIT binary patch literal 1609 zcmV-P2DbT$P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-_Zk|ZY#{pS=u0$PFNutxX>KE5BBl~uh|bWcx@ ze;l1erYMz=#Cr$`^Pj(0_zMqZ%Rwz=FYXbK7A;)S$?@^bn=CP|-B-MH)6w0E!mB^7 z9-%$cGo(Pusl3ON?MPk>@VlgEda^fqxrgCb8Rg3nqrK2KyN7tBa(mYrd120BTWeJZ zK7O0jHI<_W!v+u?NyPVvh~2Qz0gai=arU0Mk6EJ|YalEfoGFYh)}T)5 zazT4LvCSD6V zf0s9Y$z0gf{R!s6rtS%I?|FN|+SvPh-*p(VvF$S4phiLY!C>af85aCC8NNE;$I*|Y z|He_bqo~pE?n$D z+oTr5QCK@|D}1x#tlHUW{$QTrJHWJNipxkf8y3v5f0{QOe>mHa&qQt=N(FcW8r&M} z1Wd6jp7Yw1IdXi+@K*6fNp0wk<6+r8M0t*#L&i>+30rHe*mfzMfC8uDJ)Vf|NfpP< zC;Bl>_}U(A-`I}McjXI5z5rGhH9=Nw99>)#eE+dQGR(r~USKzcvhTs?uYmj4FOd7W z48LM{qH}%$7GL1lEpO2t1HXdo_mK*p8omtsLDcXE2>WsLKX;UHg~1*a{soGNSj#pX zO4R@W0flKpLr_UWLm+T+Z)Rz1WdHzpoPCi!NW(xJ#a~mUDisGSh&W`ZPF6%k97`38 zV4<`XT6HkF^h0RUkfgXc3a$kQKNhPFF3!3-xC(;c2Z*bSlcI~1_`jskBF2N`e!RQ) zxO)c(^)geYYVzG_o zHfAM5C7vb@E2>8MLe^!4^A=~dTxHFB@)rj4+H#ufG=~w#A`(bKgp4XSP=w3Vu9j|qgF|4nNZD&1@9t{v?cX!a{(b=U>2lk$kG59;000JJOGiWi{{a60 z|De66lK=n!32;bRa{vGf6951U69E94oEQKA00(qQO+^Ri2^9i1CxXzlHUIzs8FWQh zbVF}#ZDnqB07G(RVRU6=Aa`kWXdp*PO;A^X4i^9b0G>%iK~z}7?Ub<%!ypty&&Z`+ zcmQZ<>;b(0B2JUgQ$UX^OJ6Ax!52=7djs(94g^35Aw+?7zF6mr<_x2euiK7kUZ4qK zH0eV)06-POXxd-o6q`$owPFBRw;drI$SGo)7u7o&YUENT-6SE>X3>`{Av#clnUMt#ph0Cn0Wc{I?+pA*7WPP4YcQ=~tct00000NkvXX Hu0mjf8{*v2 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/brain.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/brain.png new file mode 100644 index 0000000000000000000000000000000000000000..ac2806b79cefb50b0dafdbb93575cdde187cc7e8 GIT binary patch literal 823 zcmV-71IYY|P)EX>4Tx04R}tkv&MmKpe$iQ^gM|3RV$u$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|>f)s6A|?JWDYS_3;J6>}?mh0_0Ya_BRI_aYP&La) zL?dE4vnqDHq6-5MFo-^hnR+a_n1bi{x`&UicVV98eeTcEqhw76_(bA4rW+RV2Jy_M zrE}gV4zhxz5T6r|8+1Y9N3P2*zj4kxEbz>rkxI-H2Z_ae3(GCc3WiENO&n5Gjq-)G z%L?Z$&T6T`8u#Qc3}m&HB-d$nDK!8MxA#{&EeN{Up8G z)Ivu2C8-PGhg;Bp5TdeS9BawI=ZA(sQ*&*+;nK>sb!z2^4T*vIJukfN@ZZ-9eC zU@TAB>mKj!Z0+seGmZX!06^_>lj{7Tu>b%724YJ`L;wH)0002_L%V+f000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2j>YD0v#@meDV7L00A>eL_t(o!|jz_Pr@)1hMx^) zwt+J!aX8RKK>z>mQ7;8<{9pp@*w)q?UBGAp3&fi~H*HSRzHi>}#M?-Va1j@1`6Oypqs%m~1 zkO_$&26&zaA!I^Qtk;xf$-xaQ(iCG1VY`J~35s=2^TZ<)a!Wi-)59B>K2ID57-LLj zL~BhkFNmUuJj(#czSg6)VKV4%y{+&2D5YpL8Yra*!w?|^d7d+yOr4|5flaRZi3x(B zmiXRX@Efzq)R9sGRN_aUgnuQmY07>w7K_EQE1!JgsDt#P++qL#002ovPDHLkV1nd; BZnppc literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/core.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/core.png new file mode 100644 index 0000000000000000000000000000000000000000..ac2d7893fdb13dd286886878c3ad64ea8ca4f934 GIT binary patch literal 927 zcmV;Q17Q4#P)EX>4Tx04R}tkv&MmKpe$iQ^gM|3RV$u$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|>f)s6A|?JWDYS_3;J6>}?mh0_0Ya_BRI_aYP&La) zL?dE4vnqDHq6-5MFo-^hnR+a_n1bi{x`&UicVV98eeTcEqhw76_(bA4rW+RV2Jy_M zrE}gV4zhxz5T6r|8+1Y9N3P2*zj4kxEbz>rkxI-H2Z_ae3(GCc3WiENO&n5Gjq-)G z%L?Z$&T6T`8u#Qc3}m&HB-d$nDK!8MxA#{&EeN{Up8G z)Ivu2C8-PGhg;Bp5TdeS9BawI=ZA(sQ*&*+;nK>sb!z2^4T*vIJukfN@ZZ-9eC zU@TAB>mKj!Z0+seGmZX!06^_>lj{7Tu>b%724YJ`L;wH)0002_L%V+f000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2j>YD0v$8%dYvKw00EmxL_t(o!|hc)Yr;?zJx`=V zZJ>n=Ej)#yODVV{yL+c@4*7i<-24mfW)VskMTh}22nM2A)4|@yO^j(0Q>UEi<%67) zbI-jOXwaZRMRa@pxQ_3LI>^J_5daWGzPO110C>EAjsZZ^I{<(O?Fj&|U3;a3w5yPE z5HSEqIRF5>K*rx+b5WZEZ|`P;c)RvaM6Xian|+LdyVH3zov3$$$QRvSKi;@2QAq$N zmvR8lTb{i`e{P!wM$-uZ;1KTB^GoCa&?;N|+2{D|OrnUKhm!(YSpZo{u;z{;r!xT9 zLnAXAe+9CT17s(+--RQ5V<|InW0qmgxYvCkB7HLUQw(WTG z(?PUNLzTtzmW2f5mO#@x2qItbkEAo9GVn`on?`1*Tr~%>oJc!D4)8V%cSmS?C$|m7 zHB*q2^GtA;XjESk(Jo3(WgsDGa1eS0UyCP+lDml=v-zS zwyFvUB41E_>3ZX?68CCf$63fr_`f>Pph1JW@B`15%vja@;{E^t002ovPDHLkV1j#; Bn(F`n literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/ears.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/ears.png new file mode 100644 index 0000000000000000000000000000000000000000..6ff3ac86b7642a95b27e60e079439eb127376880 GIT binary patch literal 1677 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 Ef{!*J8~^|S literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/kidneys.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/kidneys.png new file mode 100644 index 0000000000000000000000000000000000000000..482bb2410227df442ae3e7ee251ef6fcd27fa473 GIT binary patch literal 759 zcmVEX>4Tx04R}tkv&MmKpe$iQ^gM|3RV$u$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|>f)s6A|?JWDYS_3;J6>}?mh0_0Ya_BRI_aYP&La) zL?dE4vnqDHq6-5MFo-^hnR+a_n1bi{x`&UicVV98eeTcEqhw76_(bA4rW+RV2Jy_M zrE}gV4zhxz5T6r|8+1Y9N3P2*zj4kxEbz>rkxI-H2Z_ae3(GCc3WiENO&n5Gjq-)G z%L?Z$&T6T`8u#Qc3}m&HB-d$nDK!8MxA#{&EeN{Up8G z)Ivu2C8-PGhg;Bp5TdeS9BawI=ZA(sQ*&*+;nK>sb!z2^4T*vIJukfN@ZZ-9eC zU@TAB>mKj!Z0+seGmZX!06^_>lj{7Tu>b%724YJ`L;wH)0002_L%V+f000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2j>YD0v#~`bo>qg008qzL_t(o!|jx@3WG2dMQ=(c zTfssH2X)awKfwS006##7y4Vg5fd*2urc**96sne%!aIwQ7hmpuUIP#WK@b~=f>^uH zHSB(EV!vc_n&sB%b?DjB`X&Ksmg{49LXs3_NlQL?^|Gn~0Jqx(X_o7EMC{%@+-+_U zYGhFmYoSJakg1nd?M-BJ22A55DbTeIB%i$SU5B1^ZDS|o3jJ6HT#V}|i1k#yEh{RxB`8Mr^@d2`7pgy(~GF8KsE poSQQ+7vVa8Ri~?%APC|wcmnhbg@c}Xw&(x=002ovPDHLkV1mhNOmF}I literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/liver.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/liver.png new file mode 100644 index 0000000000000000000000000000000000000000..0a2e6ab25ae4c51e237c78ed7f9e592422c6fe16 GIT binary patch literal 710 zcmV;%0y+JOP)EX>4Tx04R}tkv&MmKpe$iQ^gM|3RV$u$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|>f)s6A|?JWDYS_3;J6>}?mh0_0Ya_BRI_aYP&La) zL?dE4vnqDHq6-5MFo-^hnR+a_n1bi{x`&UicVV98eeTcEqhw76_(bA4rW+RV2Jy_M zrE}gV4zhxz5T6r|8+1Y9N3P2*zj4kxEbz>rkxI-H2Z_ae3(GCc3WiENO&n5Gjq-)G z%L?Z$&T6T`8u#Qc3}m&HB-d$nDK!8MxA#{&EeN{Up8G z)Ivu2C8-PGhg;Bp5TdeS9BawI=ZA(sQ*&*+;nK>sb!z2^4T*vIJukfN@ZZ-9eC zU@TAB>mKj!Z0+seGmZX!06^_>lj{7Tu>b%724YJ`L;wH)0002_L%V+f000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2j>YD0v#@meDV7L006>CL_t(o!|jv54uUWchkqC* z0tsv^?ZN^N!23Ud51<1s+QGr3Catb@Y66PdYieBX8!y*>_ooFIhGCdLlf@hovUA^Z zPRB!*yZ|rmhj9^CYJxQy{V+nQ2>@V?4k{w2$i3K0Jaf4<8USD}x1f7->iE~>0I=U} z7vk&voNfg|cCM_Nm$;WdcN{8@n!qP9RZc3v8jZ4Q-tL$xj+%fqdi8O|%1Pf)$j+te sdd?;^@fUJ3bEX>4Tx04R}tkv&MmKpe$iQ^gM|3RV$u$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|>f)s6A|?JWDYS_3;J6>}?mh0_0Ya_BRI_aYP&La) zL?dE4vnqDHq6-5MFo-^hnR+a_n1bi{x`&UicVV98eeTcEqhw76_(bA4rW+RV2Jy_M zrE}gV4zhxz5T6r|8+1Y9N3P2*zj4kxEbz>rkxI-H2Z_ae3(GCc3WiENO&n5Gjq-)G z%L?Z$&T6T`8u#Qc3}m&HB-d$nDK!8MxA#{&EeN{Up8G z)Ivu2C8-PGhg;Bp5TdeS9BawI=ZA(sQ*&*+;nK>sb!z2^4T*vIJukfN@ZZ-9eC zU@TAB>mKj!Z0+seGmZX!06^_>lj{7Tu>b%724YJ`L;wH)0002_L%V+f000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2j>YD0v$4$eXXL z1Bq-7)kOw<0N?)scmNpcq8%8TKvK$z6Qng7h0>_WeM^)7+T7iLmjVPq5dY3@f9QSQ zN509Ar?XcP(YGCpd~KIfc#UH<*LDE?EB$u8upkatNiduPwm!v)**hSmK%As#b&WVl zolykY0lRxC1vt;p>KXvh>KdG9V-Ztah~{)|C)3J2)faa_E8`^LJcCvSO;<6kjH62_ z#=?R-@J?T}0DIQM{Owp-N002ovPDHLkV1j7)Ls|d; literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/meta.json b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/meta.json new file mode 100644 index 0000000000..1c9aebfb6d --- /dev/null +++ b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/meta.json @@ -0,0 +1,44 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "https://github.com/tgstation/tgstation/commit/f309886bf3e29808206693e9142304260df134e9", + "states": [ + { + "name": "appendix" + }, + { + "name": "brain" + }, + { + "name": "core" + }, + { + "name": "ears" + }, + { + "name": "eyes" + }, + { + "name": "heart" + }, + { + "name": "kidneys" + }, + { + "name": "liver" + }, + { + "name": "lungs" + }, + { + "name": "stomach" + }, + { + "name": "tongue" + } + ] +} diff --git a/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/stomach.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/stomach.png new file mode 100644 index 0000000000000000000000000000000000000000..a0341750d3247e864d1def1b4c272b696493d930 GIT binary patch literal 770 zcmV+d1O5DoP)EX>4Tx04R}tkv&MmKpe$iQ^gM|3RV$u$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|>f)s6A|?JWDYS_3;J6>}?mh0_0Ya_BRI_aYP&La) zL?dE4vnqDHq6-5MFo-^hnR+a_n1bi{x`&UicVV98eeTcEqhw76_(bA4rW+RV2Jy_M zrE}gV4zhxz5T6r|8+1Y9N3P2*zj4kxEbz>rkxI-H2Z_ae3(GCc3WiENO&n5Gjq-)G z%L?Z$&T6T`8u#Qc3}m&HB-d$nDK!8MxA#{&EeN{Up8G z)Ivu2C8-PGhg;Bp5TdeS9BawI=ZA(sQ*&*+;nK>sb!z2^4T*vIJukfN@ZZ-9eC zU@TAB>mKj!Z0+seGmZX!06^_>lj{7Tu>b%724YJ`L;wH)0002_L%V+f000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2j>YD0v#{UMq;_4>Y36V0N{E#qszo78Q>)&MgGzX=I@VTbs_1Dr=tS{faG~64Z%|?@>k=O z7iHo8Hxiy7DtNVG3FjpnZwe&*d^!RE{KXueAAVIW_d_3e?@v&LtBbQpv@NE- z@Ie`HgeCLN&BwzI!qR#tzh556^Wrzv_Bf&c&j07*qoM6N<$f=-=I AiU0rr literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/tongue.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/organs.rsi/tongue.png new file mode 100644 index 0000000000000000000000000000000000000000..64306900f57f8f8214509ed2fe4ee22edb47debf GIT binary patch literal 2303 zcmV zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|aavV1d{pTri1Y#q|$QU6_!#c}8V#f7$Rm;FnMdvzgBmeO-lQ}sXw$mnpn)wa zFLp@g!E()2ac(>$3yCICQQGX%WJ(p5!Ak_Q{M-v&>$YpTK@|&6f+iD;5#G2)dffc# z_|(wejUZYvUcK zOP7sr(mix@?u@tFE?UBh|KS-L}j2U3c5@MD0Q~y~FGya^FUc?x+E(m@Oe>LRvHPwd{1 z`+!?Q-Ty3Z{EA#U(ESeN(t++18?4jdTPLOfH0Y*|ZKq_rtYX2<=}w=`hDF>q1)n*#u8tRp`Cp&^^qL?s666 z9AYnhHAl)-F<(f*b+l?jMkjcSX3@t+FSEw#fshdQ5}|9Cjx$Eo%9>7H2bz*j^E?<1 z9XP{mA#i1L!ue2Y3_R3NjCc`UCjCmxL5R275#4qWZ1q z!tpyRx>=UCb`TQ829Df09W}vqtrLU=e@<+cPx#tTD(zgV`7M_cl4+vIakOrd*h;t9 zozQi1_z264WwCT9WH-|c3h+JKbqd~#JGJFM>)Sh-z9<4g5!j;$;wl2a6#;gHXS0~V zW^5$M0H&MiD%QhCGrC^YO7E-n;R?D}bM&QXZ@^VM?1ih=lWNj`EX>4Tx0C=2zkv&MmKpe$iQ>7{u2P=p;WT;M7 zL`57+6^me@v=v%)FuC+YXws0RxHt-~1qVMCs}3&Cx;nTDg5U>;tBaGOi}v_(b9;(+!Jwop@%`(mC%FhgeBch|h_~47wokBiCh@-#8Z?7Isb!v+DNN+{ftykfE-YZh(VBV6;ftYaZ|JYVYmeGtK^f0QKo|+p>?gR{#J224YJ` zL;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2j>YD0yY}jxcDak z000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}0005vNkl8xhd~l5T^Rp?;tPn-oi6eOcByn>DHL3|@C|$fcOn`Wv6YHw zHH|1;#1>N2j#`?G$9uG#D;+2e9OzZ@ZEEM=YofahsXbp)NSGXRkn>+fl8+e}@VVxzHzRjqOH@+D?-r$ygF2v9Ig z5g~{X9YPx(=3pR5`h>~C{St>2mGM(qiua0tm5F`LtzeiU?jK+*q@a(a88UUM&nf_n zWskD-;yFN9B0a59!7xQm86}fAL{uGQq4E;d7v}iMNvvv(>h`9qgs&HYJF9P{l}3$s z)<=R$lmnp%)5}HaZs{R!Ha9S}G&9+}==mRTlel^;A~NeAXgaN*!3CK9_Ejiyl)iP~ z2aS$H-L_HX$ZzM09A)m+qSUtx{L1xQUYM~IYxPguC@=PR3;q;JJ*=@S;ren94-b!j ZhVN3>q1ffHIM)CG002ovPDHLkV1iKRO}YR8 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/eyes.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/eyes.png similarity index 100% rename from Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/eyes.png rename to Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/eyes.png diff --git a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/full.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/full.png similarity index 100% rename from Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/full.png rename to Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/full.png diff --git a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/head_f.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/head_f.png similarity index 100% rename from Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/head_f.png rename to Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/head_f.png diff --git a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/head_m.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/head_m.png similarity index 100% rename from Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/head_m.png rename to Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/head_m.png diff --git a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_arm.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/l_arm.png similarity index 100% rename from Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_arm.png rename to Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/l_arm.png diff --git a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_foot.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/l_foot.png similarity index 100% rename from Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_foot.png rename to Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/l_foot.png diff --git a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_hand.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/l_hand.png similarity index 100% rename from Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_hand.png rename to Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/l_hand.png diff --git a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_leg.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/l_leg.png similarity index 100% rename from Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/l_leg.png rename to Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/l_leg.png diff --git a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/meta.json b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/meta.json similarity index 100% rename from Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/meta.json rename to Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/meta.json index 11752d5140..c4f9c9c10f 100644 --- a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/meta.json +++ b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/meta.json @@ -7,6 +7,10 @@ "license": "CC-BY-SA-3.0", "copyright": "https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13/commit/5bc3ea02ce03a551c85017f1ddd411315a19a5ca#diff-519788fa2ca74299d1686a44d3ab2098b49ed5ab65d293ec742bead7d49f0b8d", "states": [ + { + "name": "eyes", + "directions": 4 + }, { "name": "full", "directions": 4 @@ -58,10 +62,6 @@ { "name": "l_foot", "directions": 4 - }, - { - "name": "eyes", - "directions": 4 } ] } diff --git a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_arm.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/r_arm.png similarity index 100% rename from Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_arm.png rename to Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/r_arm.png diff --git a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_foot.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/r_foot.png similarity index 100% rename from Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_foot.png rename to Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/r_foot.png diff --git a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_hand.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/r_hand.png similarity index 100% rename from Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_hand.png rename to Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/r_hand.png diff --git a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_leg.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/r_leg.png similarity index 100% rename from Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/r_leg.png rename to Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/r_leg.png diff --git a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/torso_f.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/torso_f.png similarity index 100% rename from Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/torso_f.png rename to Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/torso_f.png diff --git a/Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/torso_m.png b/Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/torso_m.png similarity index 100% rename from Resources/Textures/Parkstation/Mobs/Species/shadowkin.rsi/torso_m.png rename to Resources/Textures/Parkstation/Mobs/Species/Shadowkin/parts.rsi/torso_m.png From ade3ff0ebaf2445760d6eeb6196c4db86a232d8e Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Mon, 19 Aug 2024 23:26:38 -0700 Subject: [PATCH 58/59] fix tests --- .../Parkstation/Entities/Clothing/Head/hardsuits.yml | 4 +--- .../Parkstation/Entities/Objects/Misc/handcuffs.yml | 5 ----- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/Resources/Prototypes/Parkstation/Entities/Clothing/Head/hardsuits.yml b/Resources/Prototypes/Parkstation/Entities/Clothing/Head/hardsuits.yml index 148219f03f..aaf97e3bb0 100644 --- a/Resources/Prototypes/Parkstation/Entities/Clothing/Head/hardsuits.yml +++ b/Resources/Prototypes/Parkstation/Entities/Clothing/Head/hardsuits.yml @@ -47,12 +47,10 @@ - type: ClothingSpeedModifier walkModifier: 0.9 sprintModifier: 0.9 - - type: Item - size: 65 - type: Tag tags: - FullBodyOuter - Hardsuit - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitShadowkinDarkswap - actionId: ShadowkinDarkSwapHardsuitToggle + action: ShadowkinDarkSwapHardsuitToggle diff --git a/Resources/Prototypes/Parkstation/Entities/Objects/Misc/handcuffs.yml b/Resources/Prototypes/Parkstation/Entities/Objects/Misc/handcuffs.yml index e458dd804f..792a745205 100644 --- a/Resources/Prototypes/Parkstation/Entities/Objects/Misc/handcuffs.yml +++ b/Resources/Prototypes/Parkstation/Entities/Objects/Misc/handcuffs.yml @@ -4,14 +4,9 @@ name: shadowkin restraints description: One of the first creations after finding Shadowkin, these were used to contain the Shadowkin during research so they didn't teleport away. components: - - type: Item - size: 20 - type: Handcuff cuffedRSI: Parkstation/Clothing/OuterClothing/Misc/shadowkin_restraints.rsi breakoutTime: 40 - damageOnResist: - types: - Blunt: 2 cuffTime: 4 uncuffTime: 5 stunBonus: 4 From aa667eacfb215ecfbc23f3c43286eff4bbff271e Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Mon, 19 Aug 2024 23:28:11 -0700 Subject: [PATCH 59/59] consistent variable rest --- .../Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs index f568ed706a..a574ac50a3 100644 --- a/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs +++ b/Content.Server/Parkstation/Species/Shadowkin/Systems/ShadowkinPowerSystem.Rest.cs @@ -59,9 +59,9 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki _entity.EnsureComponent(args.Performer); // No waking up normally (it would do nothing) if (_entity.TryGetComponent(uid, out var sleepingComponent)) - _actions.RemoveAction(args.Performer, sleepingComponent.WakeAction); + _actions.RemoveAction(uid, sleepingComponent.WakeAction); - _power.TryAddMultiplier(args.Performer, 2f); + _power.TryAddMultiplier(uid, 2f); // No action cooldown _actions.ClearCooldown(sleepingComponent?.WakeAction); @@ -70,9 +70,9 @@ private void Rest(EntityUid uid, ShadowkinRestPowerComponent component, Shadowki else { // Wake up - _entity.RemoveComponent(args.Performer); - _entity.RemoveComponent(args.Performer); - _power.TryAddMultiplier(args.Performer, -2f); + _entity.RemoveComponent(uid); + _entity.RemoveComponent(uid); + _power.TryAddMultiplier(uid, -2f); // Action cooldown args.Handled = true;