From 1141f261ae1d0277f2555ae8a9b4dae5a90412db Mon Sep 17 00:00:00 2001 From: gluesniffler <159397573+gluesniffler@users.noreply.github.com> Date: Mon, 5 Aug 2024 21:14:31 -0400 Subject: [PATCH 01/32] Adds PKA & Jetpack Module for Salvage Cyborgs (#550) # Description Gives salvage borgs a special jetpack module with half of the capacity of a normal mini-jetpack. Granting them about 2 minutes of thrust, which allows them to be more useful in space, partake in some rescue missions and to some extent be independent for a limited amount of time if something happens to the salvagers. It also adds a PKA module, which gives them a PKA which can't be wielded, leading to a hilarious accuracy penalty. ---

Media

Demo of the Modules [![Crafting demo, basic usage](https://i.ytimg.com/vi/k6xbEAtudVA/maxresdefault.jpg)](https://youtu.be/k6xbEAtudVA "PKA/Jetpack Borg Demo") Stormtrooper aim vs dragon AI [![Soloing space dragon AI, ft. stormtrooper aim](https://i.ytimg.com/vi/0e8iXbtD-Pc/maxresdefault.jpg)](https://www.youtube.com/watch?v=0e8iXbtD-Pc "Stormtrooper vs Space Dragon AI") Refillable jetpack module demo [![Refilling jetpack](https://i.ytimg.com/vi/y7Ie81NV2QM/maxresdefault.jpg)](https://youtu.be/y7Ie81NV2QM "Refill showcase of the jetpack module")

--- # Changelog :cl: - add: Added an unlockable PKA and Jetpack module to Salvage Cyborgs --------- Signed-off-by: gluesniffler <159397573+gluesniffler@users.noreply.github.com> --- .../Unary/EntitySystems/GasCanisterSystem.cs | 26 +++++++++++- .../Silicons/Borgs/BorgSystem.Modules.cs | 5 +++ .../Borgs/Components/BorgJetpackComponent.cs | 12 ++++++ .../Locale/en-US/research/technologies.ftl | 1 + .../Specific/Robotics/borg_modules.yml | 28 ++++++++++++ .../Entities/Objects/Tools/jetpacks.yml | 40 ++++++++++++++++++ .../Entities/Structures/Machines/lathe.yml | 2 + .../Storage/Canisters/gas_canisters.yml | 1 + .../Prototypes/Recipes/Lathes/robotics.yml | 24 +++++++++++ Resources/Prototypes/Research/industrial.yml | 13 ++++++ .../Robotics/borgmodule.rsi/icon-jetpack.png | Bin 0 -> 303 bytes .../Robotics/borgmodule.rsi/icon-pka.png | Bin 0 -> 299 bytes .../Robotics/borgmodule.rsi/meta.json | 6 +++ 13 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 Content.Server/Silicons/Borgs/Components/BorgJetpackComponent.cs create mode 100644 Resources/Textures/Objects/Specific/Robotics/borgmodule.rsi/icon-jetpack.png create mode 100644 Resources/Textures/Objects/Specific/Robotics/borgmodule.rsi/icon-pka.png diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs index 3e4340bf1db..d53e29c9499 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs @@ -15,6 +15,7 @@ using Content.Shared.Database; using Content.Shared.Interaction; using Content.Shared.Lock; +using Content.Server.Silicons.Borgs.Components; using Robust.Server.GameObjects; using Robust.Shared.Audio.Systems; using Robust.Shared.Containers; @@ -91,6 +92,10 @@ private void DirtyUI(EntityUid uid, if (canister.GasTankSlot.Item != null) { var tank = canister.GasTankSlot.Item.Value; + if (TryComp(tank, out var jetpack) && jetpack.JetpackUid.HasValue) + { + tank = jetpack.JetpackUid.Value; + } var tankComponent = Comp(tank); tankLabel = Name(tank); tankPressure = tankComponent.Air.Pressure; @@ -163,7 +168,12 @@ private void OnCanisterUpdated(EntityUid uid, GasCanisterComponent canister, ref { if (canister.GasTankSlot.Item != null) { - var gasTank = Comp(canister.GasTankSlot.Item.Value); + var tank = canister.GasTankSlot.Item; + if (TryComp(tank, out var jetpack) && jetpack.JetpackUid.HasValue) + { + tank = jetpack.JetpackUid.Value; + } + var gasTank = Comp(tank.Value); _atmos.ReleaseGasTo(canister.Air, gasTank.Air, canister.ReleasePressure); } else @@ -233,7 +243,19 @@ private void OnCanisterInsertAttempt(EntityUid uid, GasCanisterComponent compone if (args.Slot.ID != component.ContainerName || args.User == null) return; - if (!TryComp(args.Item, out var gasTank) || gasTank.IsValveOpen) + var tank = args.Item; + + if (TryComp(tank, out var jetpack)) + { + if (!jetpack.JetpackUid.HasValue) + { + args.Cancelled = true; + return; + } + tank = jetpack.JetpackUid.Value; + } + + if (!TryComp(tank, out var gasTank) || gasTank.IsValveOpen) { args.Cancelled = true; return; diff --git a/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs b/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs index cc57c34c475..7ede2342428 100644 --- a/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs +++ b/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs @@ -2,6 +2,7 @@ using Content.Shared.Hands.Components; using Content.Shared.Interaction.Components; using Content.Shared.Silicons.Borgs.Components; +using Content.Server.Silicons.Borgs.Components; using Robust.Shared.Containers; namespace Content.Server.Silicons.Borgs; @@ -190,6 +191,10 @@ private void ProvideItems(EntityUid chassis, EntityUid uid, BorgChassisComponent if (!component.ItemsCreated) { item = Spawn(itemProto, xform.Coordinates); + if (TryComp(uid, out var module)) + { + module.JetpackUid = item; + } } else { diff --git a/Content.Server/Silicons/Borgs/Components/BorgJetpackComponent.cs b/Content.Server/Silicons/Borgs/Components/BorgJetpackComponent.cs new file mode 100644 index 00000000000..3a71dd3a501 --- /dev/null +++ b/Content.Server/Silicons/Borgs/Components/BorgJetpackComponent.cs @@ -0,0 +1,12 @@ +using Robust.Shared.GameStates; + +namespace Content.Server.Silicons.Borgs.Components; + +/// +/// Server side indicator for a jetpack module. Used as conditional for inserting in canisters. +/// +[RegisterComponent] +public sealed partial class BorgJetpackComponent : Component +{ + public EntityUid? JetpackUid = null; +} \ No newline at end of file diff --git a/Resources/Locale/en-US/research/technologies.ftl b/Resources/Locale/en-US/research/technologies.ftl index a68f9e80b4e..96cb2039116 100644 --- a/Resources/Locale/en-US/research/technologies.ftl +++ b/Resources/Locale/en-US/research/technologies.ftl @@ -16,6 +16,7 @@ research-technology-shuttlecraft = Shuttlecraft research-technology-ripley-aplu = Ripley APLU research-technology-advanced-atmospherics = Advanced Atmospherics research-technology-advanced-tools = Advanced Tools +research-technology-mechanized-salvaging = Mechanized Salvaging research-technology-super-powercells = Super Powercells research-technology-bluespace-storage = Bluespace Storage research-technology-portable-fission = Portable Fission diff --git a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml index d37523bd735..a7cf7ad5c80 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml @@ -210,6 +210,34 @@ - Crowbar - RadioHandheld +- type: entity + id: BorgModuleJetpack + parent: [ BaseBorgModuleCargo, BaseProviderBorgModule ] + name: jetpack cyborg module + description: A piece of tech that gives cyborgs new abilities. Needs to be loaded by a cyborg before you can refill the jetpack. + components: + - type: Sprite + layers: + - state: cargo + - state: icon-jetpack + - type: BorgJetpack + - type: ItemBorgModule + items: + - JetpackMicroFilled + +- type: entity + id: BorgModulePka + parent: [ BaseBorgModuleCargo, BaseProviderBorgModule ] + name: proto kinetic accelerator cyborg module + components: + - type: Sprite + layers: + - state: cargo + - state: icon-pka + - type: ItemBorgModule + items: + - WeaponProtoKineticAccelerator + - type: entity id: BorgModuleGrapplingGun parent: [ BaseBorgModuleCargo, BaseProviderBorgModule ] diff --git a/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml b/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml index d0ac9c7a78a..a4c103847fe 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml @@ -295,3 +295,43 @@ moles: - 1.025689525 # oxygen - 1.025689525 # nitrogen + +#Empty micro - Used in the Cyborg module, visually the same as mini jetpack. +- type: entity + id: JetpackMicro + parent: BaseJetpack + name: micro jetpack + suffix: Empty + components: + - type: Item + sprite: Objects/Tanks/Jetpacks/mini.rsi + - type: Sprite + sprite: Objects/Tanks/Jetpacks/mini.rsi + - type: Clothing + sprite: Objects/Tanks/Jetpacks/mini.rsi + slots: + - Back + - suitStorage + - Belt + - type: GasTank + outputPressure: 42.6 + air: + volume: 0.75 + + +# Filled micro +- type: entity + id: JetpackMicroFilled + parent: JetpackMicro + name: micro jetpack + suffix: Filled + components: + - type: GasTank + outputPressure: 42.6 + air: + # 2 minutes of thrust + volume: 0.75 + temperature: 293.15 + moles: + - 0.153853429 # oxygen + - 0.153853429 # nitrogen diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 5d727207fe6..7e861db0d5a 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -594,6 +594,8 @@ - BorgModuleAdvancedTool - BorgModuleGPS - BorgModuleRCD + - BorgModuleJetpack + - BorgModulePka - BorgModuleArtifact - BorgModuleAnomaly - BorgModuleGardening diff --git a/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml b/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml index cd44f5f585a..52b008c7f2c 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml @@ -98,6 +98,7 @@ whitelist: components: - GasTank + - BorgJetpack - type: StaticPrice price: 1000 - type: AccessReader diff --git a/Resources/Prototypes/Recipes/Lathes/robotics.yml b/Resources/Prototypes/Recipes/Lathes/robotics.yml index f42e2851c78..bf6f479703e 100644 --- a/Resources/Prototypes/Recipes/Lathes/robotics.yml +++ b/Resources/Prototypes/Recipes/Lathes/robotics.yml @@ -612,3 +612,27 @@ Steel: 250 Glass: 250 Plastic: 250 + +- type: latheRecipe + id: BorgModulePka + result: BorgModulePka + category: Robotics + completetime: 3 + materials: + Steel: 1000 + Glass: 500 + Plastic: 500 + Silver: 100 + +- type: latheRecipe + id: BorgModuleJetpack + result: BorgModuleJetpack + category: Robotics + completetime: 3 + materials: + Steel: 250 + Glass: 250 + Plastic: 250 + Gold: 100 + Plasma: 1000 + diff --git a/Resources/Prototypes/Research/industrial.yml b/Resources/Prototypes/Research/industrial.yml index edcc9c66364..33377f52520 100644 --- a/Resources/Prototypes/Research/industrial.yml +++ b/Resources/Prototypes/Research/industrial.yml @@ -179,6 +179,19 @@ - BorgModuleAdvancedTool - BorgModuleRCD +- type: technology + id: MechanizedSalvaging + name: research-technology-mechanized-salvaging + icon: + sprite: Mobs/Silicon/chassis.rsi + state: miner + discipline: Industrial + tier: 2 + cost: 10000 + recipeUnlocks: + - BorgModulePka + - BorgModuleJetpack + # Tier 3 - type: technology diff --git a/Resources/Textures/Objects/Specific/Robotics/borgmodule.rsi/icon-jetpack.png b/Resources/Textures/Objects/Specific/Robotics/borgmodule.rsi/icon-jetpack.png new file mode 100644 index 0000000000000000000000000000000000000000..ec7033ec2fed40d598cfbe156ccc2dd8030c3855 GIT binary patch literal 303 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?3oArNM~bhqvgQ1GFr zi(^QHdvbyV>taO%DJB?kK=FXbs=wuZ`hU*rYqTwV`}lV_kJhx0DzlHftYWVFmzeP5 z>ud4D{0hpO)ASC1m)|d0_y6D756|UKmNl%(p5w_ebcip%-Lt@(6$WsMB4)L?~ZHs72j;rE1bH=;zhy6;oiQ-K6 z_tm96u&EGS^E0iDe?}Vnr~118Uh?cecFi(o@q5PtaO%DJB?kK=FXbs=wuZ`hU*rYqTwV`}lV_kJhx0DzlHftYS`>*8cm7 z!JfU9eGkvHN+&3n>D=&H6`1f<=gAAB6MIi5tXDf|kbF>(?cDTdJl0E>8Mo}vnvg8Q zd{VLC*Bj9`j+wDM`|Imdew_Ozo}>BPSh+3w`uxks8MCjwPq}d6Qo; Date: Tue, 6 Aug 2024 01:15:00 +0000 Subject: [PATCH 02/32] Automatic Changelog Update (#550) --- Resources/Changelog/Changelog.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index a0631c5f9d8..35142b8bbfa 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -4934,3 +4934,9 @@ Entries: message: Lamiae should now be rendered much better. id: 6217 time: '2024-08-05T17:15:51.0000000+00:00' +- author: gluesniffler + changes: + - type: Add + message: Added an unlockable PKA and Jetpack module to Salvage Cyborgs + id: 6218 + time: '2024-08-06T01:14:31.0000000+00:00' From 981b7dd9e3ce6be45911d29b605593cf7b48ea34 Mon Sep 17 00:00:00 2001 From: VMSolidus Date: Tue, 6 Aug 2024 00:52:32 -0400 Subject: [PATCH 03/32] Rebase Blood Drinker System, Arachne, Oneirophage (#438) # Description This is a simple rebase of the Blood Drinker System, and its related features that have been commented out and/or omitted due to its lack of rebase. I am NOT substantially updating any of this code at this time, outside of the barest minimum updates needed to make it run in the first place. The reason I am doing this is that I require the Blood Drinker system functional as a prerequisite for future features, and I will update or refactor it when needed. Arachne are still pending a Full Rework, but that is beyond the scope of this PR. # TODO - [x] Make the code functional - [x] Port Arachne - [x] Uncomment Oneirophages - [x] Re-add Oneirophage midround event # Changelog :cl: - add: Arachne have been reimplemented! - add: Oneirophages are back! --------- Signed-off-by: VMSolidus --- Content.Server/Arachne/ArachneSystem.cs | 231 ++++++++++++++++ Content.Server/Arachne/CocoonComponent.cs | 13 + .../Vampire/BloodSuckedComponent.cs | 9 + .../Vampire/BloodSuckerComponent.cs | 44 +++ Content.Server/Vampire/BloodSuckerSystem.cs | 213 ++++++++++++++ .../BloodSuckerGlandInjectorComponent.cs | 23 ++ .../BloodSuckerGlandInjectorSystem.cs | 39 +++ Content.Shared/Arachne/ArachneComponent.cs | 21 ++ Content.Shared/Arachne/Events.cs | 11 + Content.Shared/Arachne/WebComponent.cs | 8 + .../Vampiric/BloodSuckDoAfterEvent.cs | 10 + Resources/Locale/en-US/abilities/arachne.ftl | 13 + .../Locale/en-US/abilities/bloodsucker.ftl | 19 ++ Resources/Locale/en-US/species/species.ftl | 1 + .../Chemistry/metabolizer_types.yml | 6 +- Resources/Prototypes/Damage/containers.yml | 10 + Resources/Prototypes/Damage/modifier_sets.yml | 13 + .../Entities/Clothing/OuterClothing/armor.yml | 6 + .../OuterClothing/base_clothingouter.yml | 1 + .../Entities/Clothing/OuterClothing/suits.yml | 20 ++ .../Entities/Mobs/Player/arachne.yml | 35 +++ .../Entities/Mobs/Species/arachne.yml | 220 +++++++++++++++ Resources/Prototypes/GameRules/events.yml | 16 ++ .../anytaur_inventory_template.yml | 112 ++++++++ .../Entities/Body/Mechanisms/vampiric.yml | 22 ++ .../Entities/Body/Parts/spider.yml | 24 +- .../Entities/Body/Prototypes/arachne.yml | 63 +++++ .../Body/Prototypes/vampiricanimal.yml | 43 +++ .../Entities/Markers/Spawners/ghost_roles.yml | 40 +-- .../Entities/Mobs/NPCs/mutants.yml | 259 +++++++++--------- .../Entities/Structures/Webbing/webs.yml | 93 +++++++ Resources/Prototypes/Reagents/biological.yml | 23 ++ Resources/Prototypes/Species/arachne.yml | 50 ++++ Resources/Prototypes/tags.yml | 9 + .../female_full.png | Bin 0 -> 140 bytes .../female_none.png | Bin 0 -> 112 bytes .../female_top.png | Bin 0 -> 140 bytes .../anytaur_masking_helpers.rsi/full.png | Bin 0 -> 112 bytes .../anytaur_masking_helpers.rsi/male_full.png | Bin 0 -> 112 bytes .../anytaur_masking_helpers.rsi/male_none.png | Bin 0 -> 112 bytes .../anytaur_masking_helpers.rsi/male_top.png | Bin 0 -> 112 bytes .../anytaur_masking_helpers.rsi/meta.json | 59 ++++ .../anytaur_masking_helpers.rsi/none.png | Bin 0 -> 112 bytes .../anytaur_masking_helpers.rsi/top.png | Bin 0 -> 112 bytes .../unisex_full.png | Bin 0 -> 112 bytes .../unisex_none.png | Bin 0 -> 112 bytes .../unisex_top.png | Bin 0 -> 112 bytes .../Customization/spidereyes.rsi/eyes.png | Bin 0 -> 5070 bytes .../Customization/spidereyes.rsi/meta.json | 15 + .../Mobs/Species/arachne.rsi/meta.json | 19 ++ .../Mobs/Species/arachne.rsi/spider_body.png | Bin 0 -> 3288 bytes .../Species/arachne.rsi/spider_body_front.png | Bin 0 -> 761 bytes .../Textures/Mobs/Species/eyes.rsi/eyes.png | Bin 0 -> 5553 bytes .../Textures/Mobs/Species/eyes.rsi/meta.json | 15 + .../Structures/cocoon.rsi/cocoon1.png | Bin 0 -> 669 bytes .../Structures/cocoon.rsi/cocoon2.png | Bin 0 -> 636 bytes .../Structures/cocoon.rsi/cocoon3.png | Bin 0 -> 578 bytes .../Structures/cocoon.rsi/cocoon_large1.png | Bin 0 -> 762 bytes .../Structures/cocoon.rsi/cocoon_large2.png | Bin 0 -> 683 bytes .../Structures/cocoon.rsi/cocoon_large3.png | Bin 0 -> 876 bytes .../Structures/cocoon.rsi/meta.json | 35 +++ 61 files changed, 1704 insertions(+), 159 deletions(-) create mode 100644 Content.Server/Arachne/ArachneSystem.cs create mode 100644 Content.Server/Arachne/CocoonComponent.cs create mode 100644 Content.Server/Vampire/BloodSuckedComponent.cs create mode 100644 Content.Server/Vampire/BloodSuckerComponent.cs create mode 100644 Content.Server/Vampire/BloodSuckerSystem.cs create mode 100644 Content.Server/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs create mode 100644 Content.Server/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs create mode 100644 Content.Shared/Arachne/ArachneComponent.cs create mode 100644 Content.Shared/Arachne/Events.cs create mode 100644 Content.Shared/Arachne/WebComponent.cs create mode 100644 Content.Shared/Vampiric/BloodSuckDoAfterEvent.cs create mode 100644 Resources/Locale/en-US/abilities/arachne.ftl create mode 100644 Resources/Locale/en-US/abilities/bloodsucker.ftl create mode 100644 Resources/Prototypes/Entities/Mobs/Player/arachne.yml create mode 100644 Resources/Prototypes/Entities/Mobs/Species/arachne.yml create mode 100644 Resources/Prototypes/InventoryTemplates/anytaur_inventory_template.yml create mode 100644 Resources/Prototypes/Nyanotrasen/Entities/Body/Mechanisms/vampiric.yml create mode 100644 Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml create mode 100644 Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/vampiricanimal.yml create mode 100644 Resources/Prototypes/Nyanotrasen/Entities/Structures/Webbing/webs.yml create mode 100644 Resources/Prototypes/Species/arachne.yml create mode 100644 Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/female_full.png create mode 100644 Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/female_none.png create mode 100644 Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/female_top.png create mode 100644 Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/full.png create mode 100644 Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/male_full.png create mode 100644 Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/male_none.png create mode 100644 Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/male_top.png create mode 100644 Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/meta.json create mode 100644 Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/none.png create mode 100644 Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/top.png create mode 100644 Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_full.png create mode 100644 Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_none.png create mode 100644 Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_top.png create mode 100644 Resources/Textures/Mobs/Customization/spidereyes.rsi/eyes.png create mode 100644 Resources/Textures/Mobs/Customization/spidereyes.rsi/meta.json create mode 100644 Resources/Textures/Mobs/Species/arachne.rsi/meta.json create mode 100644 Resources/Textures/Mobs/Species/arachne.rsi/spider_body.png create mode 100644 Resources/Textures/Mobs/Species/arachne.rsi/spider_body_front.png create mode 100644 Resources/Textures/Mobs/Species/eyes.rsi/eyes.png create mode 100644 Resources/Textures/Mobs/Species/eyes.rsi/meta.json create mode 100644 Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon1.png create mode 100644 Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon2.png create mode 100644 Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon3.png create mode 100644 Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large1.png create mode 100644 Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large2.png create mode 100644 Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large3.png create mode 100644 Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/meta.json diff --git a/Content.Server/Arachne/ArachneSystem.cs b/Content.Server/Arachne/ArachneSystem.cs new file mode 100644 index 00000000000..9cdefb441be --- /dev/null +++ b/Content.Server/Arachne/ArachneSystem.cs @@ -0,0 +1,231 @@ +using Content.Shared.Arachne; +using Content.Shared.Actions; +using Content.Shared.IdentityManagement; +using Content.Shared.Verbs; +using Content.Shared.Buckle.Components; +using Content.Shared.DoAfter; +using Content.Shared.Stunnable; +using Content.Shared.Eye.Blinding.Systems; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Damage; +using Content.Shared.Inventory; +using Content.Shared.Administration.Logs; +using Content.Shared.Database; +using Content.Shared.Humanoid; +using Content.Shared.Nutrition.EntitySystems; +using Content.Server.Buckle.Systems; +using Content.Server.Popups; +using Content.Server.DoAfter; +using Content.Server.Body.Components; +using Content.Server.Vampiric; +using Content.Server.Speech.Components; +using Robust.Shared.Physics.Components; +using Robust.Shared.Containers; +using Robust.Shared.Map; +using Robust.Shared.Utility; +using Robust.Server.Console; + +namespace Content.Server.Arachne +{ + public sealed class ArachneSystem : EntitySystem + { + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly DoAfterSystem _doAfter = default!; + [Dependency] private readonly BuckleSystem _buckleSystem = default!; + [Dependency] private readonly ItemSlotsSystem _itemSlots = default!; + [Dependency] private readonly BlindableSystem _blindableSystem = default!; + [Dependency] private readonly DamageableSystem _damageableSystem = default!; + + [Dependency] private readonly IServerConsoleHost _host = default!; + [Dependency] private readonly BloodSuckerSystem _bloodSuckerSystem = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + + private const string BodySlot = "body_slot"; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent>(AddCocoonVerb); + + SubscribeLocalEvent(OnCocEntInserted); + SubscribeLocalEvent(OnCocEntRemoved); + SubscribeLocalEvent(OnDamageChanged); + SubscribeLocalEvent>(AddSuccVerb); + SubscribeLocalEvent(OnCocoonDoAfter); + } + + private void AddCocoonVerb(EntityUid uid, ArachneComponent component, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract) + return; + + if (args.Target == uid) + return; + + if (!TryComp(args.Target, out var bloodstream)) + return; + + if (bloodstream.BloodReagent != component.WebBloodReagent) + return; + + InnateVerb verb = new() + { + Act = () => + { + StartCocooning(uid, component, args.Target); + }, + Text = Loc.GetString("cocoon"), + Priority = 2 + }; + args.Verbs.Add(verb); + } + + private void OnCocEntInserted(EntityUid uid, CocoonComponent component, EntInsertedIntoContainerMessage args) + { + _blindableSystem.UpdateIsBlind(args.Entity); + EnsureComp(args.Entity); + + if (TryComp(args.Entity, out var currentAccent)) + { + component.WasReplacementAccent = true; + component.OldAccent = currentAccent.Accent; + currentAccent.Accent = "mumble"; + } else + { + component.WasReplacementAccent = false; + var replacement = EnsureComp(args.Entity); + replacement.Accent = "mumble"; + } + } + + private void OnCocEntRemoved(EntityUid uid, CocoonComponent component, EntRemovedFromContainerMessage args) + { + if (component.WasReplacementAccent && TryComp(args.Entity, out var replacement)) + { + replacement.Accent = component.OldAccent; + } else + { + RemComp(args.Entity); + } + + RemComp(args.Entity); + _blindableSystem.UpdateIsBlind(args.Entity); + } + + private void OnDamageChanged(EntityUid uid, CocoonComponent component, DamageChangedEvent args) + { + if (!args.DamageIncreased) + return; + + if (args.DamageDelta == null) + return; + + var body = _itemSlots.GetItemOrNull(uid, BodySlot); + + if (body == null) + return; + + var damage = args.DamageDelta * component.DamagePassthrough; + _damageableSystem.TryChangeDamage(body, damage); + } + + private void AddSuccVerb(EntityUid uid, CocoonComponent component, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract) + return; + + if (!TryComp(args.User, out var sucker)) + return; + + if (!sucker.WebRequired) + return; + + var victim = _itemSlots.GetItemOrNull(uid, BodySlot); + + if (victim == null) + return; + + if (!TryComp(victim, out var stream)) + return; + + AlternativeVerb verb = new() + { + Act = () => + { + _bloodSuckerSystem.StartSuccDoAfter(args.User, victim.Value, sucker, stream, false); // start doafter + }, + Text = Loc.GetString("action-name-suck-blood"), + Icon = new SpriteSpecifier.Texture(new ("/Textures/Nyanotrasen/Icons/verbiconfangs.png")), + Priority = 2 + }; + args.Verbs.Add(verb); + } + + private void OnEntRemoved(EntityUid uid, WebComponent web, EntRemovedFromContainerMessage args) + { + if (!TryComp(uid, out var strap)) + return; + + if (HasComp(args.Entity)) + _buckleSystem.StrapSetEnabled(uid, false, strap); + } + + private void StartCocooning(EntityUid uid, ArachneComponent component, EntityUid target) + { + _popupSystem.PopupEntity(Loc.GetString("cocoon-start-third-person", ("target", Identity.Entity(target, EntityManager)), ("spider", Identity.Entity(uid, EntityManager))), uid, + Shared.Popups.PopupType.MediumCaution); + + _popupSystem.PopupEntity(Loc.GetString("cocoon-start-second-person", ("target", Identity.Entity(target, EntityManager))), uid, uid, Shared.Popups.PopupType.Medium); + + var delay = component.CocoonDelay; + + if (HasComp(target)) + delay *= component.CocoonKnockdownMultiplier; + + // Is it good practice to use empty data just to disambiguate doafters + // Who knows, there's no docs! + var ev = new ArachneCocoonDoAfterEvent(); + + var args = new DoAfterArgs(EntityManager, uid, delay, ev, uid, target: target) + { + BreakOnUserMove = true, + BreakOnTargetMove = true, + }; + + _doAfter.TryStartDoAfter(args); + } + + private void OnCocoonDoAfter(EntityUid uid, ArachneComponent component, ArachneCocoonDoAfterEvent args) + { + if (args.Handled || args.Cancelled || args.Args.Target == null) + return; + + var spawnProto = HasComp(args.Args.Target) ? "CocoonedHumanoid" : "CocoonSmall"; + Transform(args.Args.Target.Value).AttachToGridOrMap(); + var cocoon = Spawn(spawnProto, Transform(args.Args.Target.Value).Coordinates); + + if (!TryComp(cocoon, out var slots)) + return; + + // todo: our species should use scale visuals probably... + // TODO: We need a client-accessible notion of scale influence here. + /* if (spawnProto == "CocoonedHumanoid" && TryComp(args.Args.Target.Value, out var sprite)) */ + /* { */ + /* // why the fuck is this only available as a console command. */ + /* _host.ExecuteCommand(null, "scale " + cocoon + " " + sprite.Scale.Y); */ + if (TryComp(args.Args.Target.Value, out var physics)) + { + var scale = Math.Clamp(1 / (35 / physics.FixturesMass), 0.35, 2.5); + _host.ExecuteCommand(null, "scale " + cocoon + " " + scale); + } + _itemSlots.SetLock(cocoon, BodySlot, false, slots); + _itemSlots.TryInsert(cocoon, BodySlot, args.Args.Target.Value, args.Args.User); + _itemSlots.SetLock(cocoon, BodySlot, true, slots); + + var impact = (spawnProto == "CocoonedHumanoid") ? LogImpact.High : LogImpact.Medium; + + _adminLogger.Add(LogType.Action, impact, $"{ToPrettyString(args.Args.User):player} cocooned {ToPrettyString(args.Args.Target.Value):target}"); + args.Handled = true; + } + } +} diff --git a/Content.Server/Arachne/CocoonComponent.cs b/Content.Server/Arachne/CocoonComponent.cs new file mode 100644 index 00000000000..42ecf27971a --- /dev/null +++ b/Content.Server/Arachne/CocoonComponent.cs @@ -0,0 +1,13 @@ +namespace Content.Server.Arachne +{ + [RegisterComponent] + public sealed partial class CocoonComponent : Component + { + public bool WasReplacementAccent = false; + + public string OldAccent = ""; + + [DataField("damagePassthrough")] + public float DamagePassthrough = 0.5f; + } +} diff --git a/Content.Server/Vampire/BloodSuckedComponent.cs b/Content.Server/Vampire/BloodSuckedComponent.cs new file mode 100644 index 00000000000..d7e402cd98a --- /dev/null +++ b/Content.Server/Vampire/BloodSuckedComponent.cs @@ -0,0 +1,9 @@ +namespace Content.Server.Vampiric +{ + /// + /// For entities who have been succed. + /// + [RegisterComponent] + public sealed partial class BloodSuckedComponent : Component + {} +} diff --git a/Content.Server/Vampire/BloodSuckerComponent.cs b/Content.Server/Vampire/BloodSuckerComponent.cs new file mode 100644 index 00000000000..f5619d1cb49 --- /dev/null +++ b/Content.Server/Vampire/BloodSuckerComponent.cs @@ -0,0 +1,44 @@ +namespace Content.Server.Vampiric +{ + [RegisterComponent] + public sealed partial class BloodSuckerComponent : Component + { + /// + /// How much to succ each time we succ. + /// + [DataField("unitsToSucc")] + public float UnitsToSucc = 20f; + + /// + /// The time (in seconds) that it takes to succ an entity. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public TimeSpan Delay = TimeSpan.FromSeconds(4); + + // ***INJECT WHEN SUCC*** + + /// + /// Whether to inject chems into a chemstream when we suck something. + /// + [DataField("injectWhenSucc")] + public bool InjectWhenSucc = false; + + /// + /// How many units of our injected chem to inject. + /// + [DataField("unitsToInject")] + public float UnitsToInject = 5; + + /// + /// Which reagent to inject. + /// + [DataField("injectReagent")] + public string InjectReagent = ""; + + /// + /// Whether we need to web the thing up first... + /// + [DataField("webRequired")] + public bool WebRequired = false; + } +} diff --git a/Content.Server/Vampire/BloodSuckerSystem.cs b/Content.Server/Vampire/BloodSuckerSystem.cs new file mode 100644 index 00000000000..a63334a8943 --- /dev/null +++ b/Content.Server/Vampire/BloodSuckerSystem.cs @@ -0,0 +1,213 @@ +using Content.Shared.Verbs; +using Content.Shared.Damage; +using Content.Shared.DoAfter; +using Content.Shared.Damage.Prototypes; +using Content.Shared.Interaction; +using Content.Shared.Inventory; +using Content.Shared.Administration.Logs; +using Content.Shared.Vampiric; +using Content.Server.Atmos.Components; +using Content.Server.Body.Components; +using Content.Server.Body.Systems; +using Content.Shared.Chemistry.EntitySystems; +using Content.Server.Popups; +using Content.Server.HealthExaminable; +using Content.Server.DoAfter; +using Content.Server.Nutrition.Components; +using Robust.Shared.Prototypes; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Utility; + +namespace Content.Server.Vampiric +{ + public sealed class BloodSuckerSystem : EntitySystem + { + [Dependency] private readonly BodySystem _bodySystem = default!; + [Dependency] private readonly SharedSolutionContainerSystem _solutionSystem = default!; + [Dependency] private readonly PopupSystem _popups = default!; + [Dependency] private readonly DoAfterSystem _doAfter = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly StomachSystem _stomachSystem = default!; + [Dependency] private readonly DamageableSystem _damageableSystem = default!; + [Dependency] private readonly InventorySystem _inventorySystem = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; + [Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent>(AddSuccVerb); + SubscribeLocalEvent(OnHealthExamined); + SubscribeLocalEvent(OnDamageChanged); + SubscribeLocalEvent(OnDoAfter); + } + + private void AddSuccVerb(EntityUid uid, BloodSuckerComponent component, GetVerbsEvent args) + { + if (args.User == args.Target) + return; + if (component.WebRequired) + return; // handled elsewhere + if (!TryComp(args.Target, out var bloodstream)) + return; + if (!args.CanAccess) + return; + + InnateVerb verb = new() + { + Act = () => + { + StartSuccDoAfter(uid, args.Target, component, bloodstream); // start doafter + }, + Text = Loc.GetString("action-name-suck-blood"), + Icon = new SpriteSpecifier.Texture(new ("/Textures/Nyanotrasen/Icons/verbiconfangs.png")), + Priority = 2 + }; + args.Verbs.Add(verb); + } + + private void OnHealthExamined(EntityUid uid, BloodSuckedComponent component, HealthBeingExaminedEvent args) + { + args.Message.PushNewline(); + args.Message.AddMarkup(Loc.GetString("bloodsucked-health-examine", ("target", uid))); + } + + private void OnDamageChanged(EntityUid uid, BloodSuckedComponent component, DamageChangedEvent args) + { + if (args.DamageIncreased) + return; + + if (_prototypeManager.TryIndex("Brute", out var brute) && args.Damageable.Damage.TryGetDamageInGroup(brute, out var bruteTotal) + && _prototypeManager.TryIndex("Airloss", out var airloss) && args.Damageable.Damage.TryGetDamageInGroup(airloss, out var airlossTotal)) + { + if (bruteTotal == 0 && airlossTotal == 0) + RemComp(uid); + } + } + + private void OnDoAfter(EntityUid uid, BloodSuckerComponent component, BloodSuckDoAfterEvent args) + { + if (args.Cancelled || args.Handled || args.Args.Target == null) + return; + + args.Handled = TrySucc(uid, args.Args.Target.Value); + } + + public void StartSuccDoAfter(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodSuckerComponent = null, BloodstreamComponent? stream = null, bool doChecks = true) + { + if (!Resolve(bloodsucker, ref bloodSuckerComponent)) + return; + + if (!Resolve(victim, ref stream)) + return; + + if (doChecks) + { + if (!_interactionSystem.InRangeUnobstructed(bloodsucker, victim)) + { + return; + } + + if (_inventorySystem.TryGetSlotEntity(victim, "head", out var headUid) && HasComp(headUid)) + { + _popups.PopupEntity(Loc.GetString("bloodsucker-fail-helmet", ("helmet", headUid)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + return; + } + + if (_inventorySystem.TryGetSlotEntity(bloodsucker, "mask", out var maskUid) && + EntityManager.TryGetComponent(maskUid, out var blocker) && + blocker.Enabled) + { + _popups.PopupEntity(Loc.GetString("bloodsucker-fail-mask", ("mask", maskUid)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + return; + } + } + + if (stream.BloodReagent != "Blood") + { + _popups.PopupEntity(Loc.GetString("bloodsucker-fail-not-blood", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + return; + } + + if (_solutionSystem.PercentFull(stream.Owner) != 0) + _popups.PopupEntity(Loc.GetString("bloodsucker-fail-no-blood", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + + _popups.PopupEntity(Loc.GetString("bloodsucker-doafter-start-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); + _popups.PopupEntity(Loc.GetString("bloodsucker-doafter-start", ("target", victim)), victim, bloodsucker, Shared.Popups.PopupType.Medium); + + var ev = new BloodSuckDoAfterEvent(); + var args = new DoAfterArgs(EntityManager, bloodsucker, bloodSuckerComponent.Delay, ev, bloodsucker, target: victim) + { + BreakOnTargetMove = true, + BreakOnUserMove = false, + DistanceThreshold = 2f, + NeedHand = false + }; + + _doAfter.TryStartDoAfter(args); + } + + public bool TrySucc(EntityUid bloodsucker, EntityUid victim, BloodSuckerComponent? bloodsuckerComp = null) + { + // Is bloodsucker a bloodsucker? + if (!Resolve(bloodsucker, ref bloodsuckerComp)) + return false; + + // Does victim have a bloodstream? + if (!TryComp(victim, out var bloodstream)) + return false; + + // No blood left, yikes. + if (_bloodstreamSystem.GetBloodLevelPercentage(victim, bloodstream) == 0.0f) + return false; + + // Does bloodsucker have a stomach? + var stomachList = _bodySystem.GetBodyOrganComponents(bloodsucker); + if (stomachList.Count == 0) + return false; + + if (!_solutionSystem.TryGetSolution(stomachList[0].Comp.Owner, StomachSystem.DefaultSolutionName, out var stomachSolution)) + return false; + + // Are we too full? + + if (_solutionSystem.PercentFull(bloodsucker) >= 1) + { + _popups.PopupEntity(Loc.GetString("drink-component-try-use-drink-had-enough"), bloodsucker, bloodsucker, Shared.Popups.PopupType.MediumCaution); + return false; + } + + _adminLogger.Add(Shared.Database.LogType.MeleeHit, Shared.Database.LogImpact.Medium, $"{ToPrettyString(bloodsucker):player} sucked blood from {ToPrettyString(victim):target}"); + + // All good, succ time. + _audio.PlayPvs("/Audio/Items/drink.ogg", bloodsucker); + _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked-victim", ("sucker", bloodsucker)), victim, victim, Shared.Popups.PopupType.LargeCaution); + _popups.PopupEntity(Loc.GetString("bloodsucker-blood-sucked", ("target", victim)), bloodsucker, bloodsucker, Shared.Popups.PopupType.Medium); + EnsureComp(victim); + + // Make everything actually ingest. + if (bloodstream.BloodSolution == null) + return false; + + var temp = _solutionSystem.SplitSolution(bloodstream.BloodSolution.Value, bloodsuckerComp.UnitsToSucc); + _stomachSystem.TryTransferSolution(stomachList[0].Comp.Owner, temp, stomachList[0].Comp); + + // Add a little pierce + DamageSpecifier damage = new(); + damage.DamageDict.Add("Piercing", 1); // Slowly accumulate enough to gib after like half an hour + + _damageableSystem.TryChangeDamage(victim, damage, true, true); + + //I'm not porting the nocturine gland, this code is deprecated, and will be reworked at a later date. + //if (bloodsuckerComp.InjectWhenSucc && _solutionSystem.TryGetInjectableSolution(victim, out var injectable)) + //{ + // _solutionSystem.TryAddReagent(victim, injectable, bloodsuckerComp.InjectReagent, bloodsuckerComp.UnitsToInject, out var acceptedQuantity); + //} + return true; + } + + private record struct BloodSuckData() + {} + } +} diff --git a/Content.Server/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs b/Content.Server/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs new file mode 100644 index 00000000000..1a3c9b1588a --- /dev/null +++ b/Content.Server/Vampire/Injector/BloodSuckerGlandInjectorComponent.cs @@ -0,0 +1,23 @@ +namespace Content.Server.Vampiric +{ + [RegisterComponent] + /// + /// Item that gives a bloodsucker injection glands (for poison, usually) + /// + public sealed partial class BloodSuckerGlandInjectorComponent : Component + { + public bool Used = false; + + /// + /// How many units of our injected chem to inject. + /// + [DataField("unitsToInject")] + public float UnitsToInject = 5; + + /// + /// Which reagent to inject. + /// + [DataField("injectReagent")] + public string InjectReagent = ""; + } +} diff --git a/Content.Server/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs b/Content.Server/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs new file mode 100644 index 00000000000..d2a92f24be6 --- /dev/null +++ b/Content.Server/Vampire/Injector/BloodSuckerGlandInjectorSystem.cs @@ -0,0 +1,39 @@ +using Content.Server.Popups; +using Content.Shared.Interaction; + +namespace Content.Server.Vampiric +{ + public sealed class BloodSuckerGlandInjectorSystem : EntitySystem + { + [Dependency] private readonly PopupSystem _popupSystem = default!; + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnAfterInteract); + } + + private void OnAfterInteract(EntityUid uid, BloodSuckerGlandInjectorComponent component, AfterInteractEvent args) + { + if (component.Used) + return; + + if (!args.CanReach) + return; + + if (!TryComp(args.Target, out var bloodSuckerComponent)) + return; + + // They already have one. + if (bloodSuckerComponent.InjectWhenSucc) + return; + + bloodSuckerComponent.InjectWhenSucc = true; + bloodSuckerComponent.InjectReagent = component.InjectReagent; + bloodSuckerComponent.UnitsToInject = component.UnitsToInject; + component.Used = true; + QueueDel(uid); + + _popupSystem.PopupEntity(Loc.GetString("bloodsucker-glands-throb"), args.Target.Value, args.Target.Value); + } + } +} diff --git a/Content.Shared/Arachne/ArachneComponent.cs b/Content.Shared/Arachne/ArachneComponent.cs new file mode 100644 index 00000000000..04c369cc456 --- /dev/null +++ b/Content.Shared/Arachne/ArachneComponent.cs @@ -0,0 +1,21 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Arachne +{ + [RegisterComponent, NetworkedComponent] + public sealed partial class ArachneComponent : Component + { + [DataField("cocoonDelay")] + public float CocoonDelay = 12f; + + [DataField("cocoonKnockdownMultiplier")] + public float CocoonKnockdownMultiplier = 0.5f; + + /// + /// Blood reagent required to web up a mob. + /// + + [DataField("webBloodReagent")] + public string WebBloodReagent = "Blood"; + } +} diff --git a/Content.Shared/Arachne/Events.cs b/Content.Shared/Arachne/Events.cs new file mode 100644 index 00000000000..02001286ac6 --- /dev/null +++ b/Content.Shared/Arachne/Events.cs @@ -0,0 +1,11 @@ +using Robust.Shared.Map; +using Robust.Shared.Serialization; +using Content.Shared.DoAfter; + +namespace Content.Shared.Arachne +{ + [Serializable, NetSerializable] + public sealed partial class ArachneCocoonDoAfterEvent : SimpleDoAfterEvent + { + } +} diff --git a/Content.Shared/Arachne/WebComponent.cs b/Content.Shared/Arachne/WebComponent.cs new file mode 100644 index 00000000000..c8284f39434 --- /dev/null +++ b/Content.Shared/Arachne/WebComponent.cs @@ -0,0 +1,8 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Arachne +{ + [RegisterComponent, NetworkedComponent] + public sealed partial class WebComponent : Component + {} +} diff --git a/Content.Shared/Vampiric/BloodSuckDoAfterEvent.cs b/Content.Shared/Vampiric/BloodSuckDoAfterEvent.cs new file mode 100644 index 00000000000..6aadc258d73 --- /dev/null +++ b/Content.Shared/Vampiric/BloodSuckDoAfterEvent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.Serialization; +using Content.Shared.DoAfter; + +namespace Content.Shared.Vampiric +{ + [Serializable, NetSerializable] + public sealed partial class BloodSuckDoAfterEvent : SimpleDoAfterEvent + { + } +} diff --git a/Resources/Locale/en-US/abilities/arachne.ftl b/Resources/Locale/en-US/abilities/arachne.ftl new file mode 100644 index 00000000000..6f6348d7212 --- /dev/null +++ b/Resources/Locale/en-US/abilities/arachne.ftl @@ -0,0 +1,13 @@ +action-name-spin-web = Spin Web +action-desc-spin-web = Use your spinnerets to make a spider web in the current tile. Makes you hungrier and thirstier. +action-name-spin-web-space = You can't spin a web in space! +action-name-spin-web-blocked = There's no room for a web here. +spin-web-action-hungry = You're too hungry to spin a web! +spin-web-action-thirsty = You're too thirsty to spin a web! +spin-web-start-second-person = You start spinning a web. +spin-web-start-third-person = {CAPITALIZE(THE($spider))} starts spinning a web! +cocoon-start-second-person = You start cocooning {THE($target)}. +cocoon-start-third-person = {CAPITALIZE(THE($spider))} starts cocooning {THE($target)}. +spun-web-second-person = You spin up a web. +spun-web-third-person = {CAPITALIZE(THE($spider))} spins up a web! +cocoon = Cocoon diff --git a/Resources/Locale/en-US/abilities/bloodsucker.ftl b/Resources/Locale/en-US/abilities/bloodsucker.ftl new file mode 100644 index 00000000000..d956eaff84e --- /dev/null +++ b/Resources/Locale/en-US/abilities/bloodsucker.ftl @@ -0,0 +1,19 @@ +action-name-suck-blood = Suck Blood +action-description-suck-blood = Suck the blood of the victim in your hand. + +bloodsucker-fail-helmet = You'd need to remove {THE($helmet)}. +bloodsucker-fail-mask = You'd need to remove your mask! + +bloodsucker-fail-not-blood = { CAPITALIZE(SUBJECT($target)) } doesn't have delicious, nourishing mortal blood. +bloodsucker-fail-no-blood = { CAPITALIZE(SUBJECT($target)) } has no blood in { POSS-ADJ($target) } body. +bloodsucker-fail-no-blood-bloodsucked = { CAPITALIZE(SUBJECT($target)) } has been sucked dry. + +bloodsucker-blood-sucked = You suck some blood from {$target}. +bloodsucker-doafter-start = You try to suck blood from {$target}. + +bloodsucker-doafter-start-victim = {CAPITALIZE(THE($sucker))} is trying to bite your neck! +bloodsucker-blood-sucked-victim = {CAPITALIZE(THE($sucker))} sucks some of your blood! + +bloodsucked-health-examine = [color=red]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } bite marks on { POSS-ADJ($target) } neck.[/color] + +bloodsucker-glands-throb = The glands behind your fangs feel a bit sore. diff --git a/Resources/Locale/en-US/species/species.ftl b/Resources/Locale/en-US/species/species.ftl index f31b1fa0f00..79ce7fea6a1 100644 --- a/Resources/Locale/en-US/species/species.ftl +++ b/Resources/Locale/en-US/species/species.ftl @@ -6,6 +6,7 @@ species-name-reptilian = Reptilian species-name-slime = Slime Person species-name-diona = Diona species-name-arachnid = Arachnid +species-name-arachne = Arachne species-name-moth = Moth Person species-name-skeleton = Skeleton species-name-vox = Vox diff --git a/Resources/Prototypes/Chemistry/metabolizer_types.yml b/Resources/Prototypes/Chemistry/metabolizer_types.yml index 259387b6d5c..4d48dab9925 100644 --- a/Resources/Prototypes/Chemistry/metabolizer_types.yml +++ b/Resources/Prototypes/Chemistry/metabolizer_types.yml @@ -1,4 +1,4 @@ -# If your species wants to metabolize stuff differently, +# If your species wants to metabolize stuff differently, # you'll likely have to tag its metabolizers with something other than Human. - type: metabolizerType @@ -44,3 +44,7 @@ - type: metabolizerType id: Arachnid name: arachnid + +- type: metabolizerType + id: Vampiric + name: vampiric diff --git a/Resources/Prototypes/Damage/containers.yml b/Resources/Prototypes/Damage/containers.yml index fb40e9b658f..b01d22df3b7 100644 --- a/Resources/Prototypes/Damage/containers.yml +++ b/Resources/Prototypes/Damage/containers.yml @@ -52,3 +52,13 @@ id: ShadowHaze supportedTypes: - Heat + +- type: damageContainer + id: HalfSpirit + supportedGroups: + - Burn + - Brute + - Airloss + - Immaterial + supportedTypes: + - Poison diff --git a/Resources/Prototypes/Damage/modifier_sets.yml b/Resources/Prototypes/Damage/modifier_sets.yml index 31dd47a9e16..a6798e39cfe 100644 --- a/Resources/Prototypes/Damage/modifier_sets.yml +++ b/Resources/Prototypes/Damage/modifier_sets.yml @@ -336,3 +336,16 @@ flatReductions: # can't punch the endoskeleton to death Blunt: 5 + +- type: damageModifierSet + id: HalfSpirit + coefficients: + Cold: 0.5 + Shock: 0.75 + Blunt: 0.75 + Slash: 0.75 + Piercing: 0.75 + Heat: 1.25 + Holy: 1.5 + flatReductions: + Cold: 3 diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml index 9a1f1427402..b62658270eb 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml @@ -138,6 +138,9 @@ Radiation: 0 Caustic: 0.75 - type: GroupExamine + - type: Tag + tags: + - FullBodyOuter - type: entity parent: ClothingOuterArmorHeavy @@ -234,6 +237,9 @@ - type: ExplosionResistance damageCoefficient: 0.5 - type: GroupExamine + - type: Tag + tags: + - FullBodyOuter - type: entity parent: ClothingOuterBaseLarge diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml index 8f4312e7711..36327fe1f78 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml @@ -138,6 +138,7 @@ - Hardsuit - WhitelistChameleon - HidesHarpyWings #DeltaV: Used by harpies to help render their hardsuit sprites + - FullBodyOuter - type: Clothing equipDelay: 2.5 # Hardsuits are heavy and take a while to put on/off. unequipDelay: 2.5 diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml index d6cd5295731..9f0a01cc481 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml @@ -25,6 +25,7 @@ tags: - Hardsuit - WhitelistChameleon + - FullBodyOuter - HidesHarpyWings - type: entity @@ -38,6 +39,17 @@ sprite: Clothing/OuterClothing/Suits/janitor_bombsuit.rsi - type: Clothing sprite: Clothing/OuterClothing/Suits/janitor_bombsuit.rsi + - type: ClothingSpeedModifier + walkModifier: 0.8 + sprintModifier: 0.8 + - type: ExplosionResistance + damageCoefficient: 0.15 + - type: GroupExamine + - type: Tag + tags: + - Hardsuit + - WhitelistChameleon + - FullBodyOuter - type: entity parent: ClothingOuterBaseLarge @@ -97,6 +109,7 @@ - type: GroupExamine - type: Tag tags: + - FullBodyOuter - WhitelistChameleon - HidesHarpyWings @@ -124,6 +137,7 @@ toggleable-clothing: !type:ContainerSlot {} - type: Tag tags: + - FullBodyOuter - WhitelistChameleon - HidesHarpyWings @@ -177,6 +191,9 @@ sprite: Clothing/OuterClothing/Suits/chicken.rsi - type: Clothing sprite: Clothing/OuterClothing/Suits/chicken.rsi + - type: Tag + tags: + - FullBodyOuter - type: entity parent: ClothingOuterBase @@ -202,6 +219,9 @@ - type: ContainerContainer containers: toggleable-clothing: !type:ContainerSlot {} + - type: Tag + tags: + - FullBodyOuter - type: entity parent: ClothingOuterBase diff --git a/Resources/Prototypes/Entities/Mobs/Player/arachne.yml b/Resources/Prototypes/Entities/Mobs/Player/arachne.yml new file mode 100644 index 00000000000..bebf42f31ba --- /dev/null +++ b/Resources/Prototypes/Entities/Mobs/Player/arachne.yml @@ -0,0 +1,35 @@ +- type: entity + save: false + name: Urist McArachne + parent: MobArachneBase + id: MobArachne + components: + - type: CombatMode + - type: InteractionPopup + successChance: 1 + interactSuccessString: hugging-success-generic + interactSuccessSound: /Audio/Effects/thudswoosh.ogg + messagePerceivedByOthers: hugging-success-generic-others + - type: MindContainer + showExamineInfo: true + - type: Input + context: "human" + - type: MobMover + - type: InputMover + - type: Respirator + damage: + types: + Asphyxiation: 1.0 + damageRecovery: + types: + Asphyxiation: -1.0 + - type: Alerts + - type: Actions + - type: Eye + - type: CameraRecoil + - type: Examiner + - type: CanHostGuardian + - type: NpcFactionMember + factions: + - NanoTrasen + - type: PotentialPsionic diff --git a/Resources/Prototypes/Entities/Mobs/Species/arachne.yml b/Resources/Prototypes/Entities/Mobs/Species/arachne.yml new file mode 100644 index 00000000000..2f6437dc14e --- /dev/null +++ b/Resources/Prototypes/Entities/Mobs/Species/arachne.yml @@ -0,0 +1,220 @@ +- type: entity + save: false + name: Urist McArachne + parent: BaseMobHuman + id: MobArachneBase + abstract: true + components: + - type: Sprite + # Arachne are one of the species that needs a manual visual layers setup. + layers: + - map: [ "enum.HumanoidVisualLayers.LLeg" ] + sprite: Mobs/Species/arachne.rsi + state: spider_body + - map: [ "enum.HumanoidVisualLayers.Chest" ] + color: "#e8b59b" + sprite: Mobs/Species/Human/parts.rsi + state: torso_m + - map: [ "enum.HumanoidVisualLayers.RLeg" ] + sprite: Mobs/Species/arachne.rsi + state: spider_body_front + - map: [ "enum.HumanoidVisualLayers.Head" ] + color: "#e8b59b" + sprite: Mobs/Species/Human/parts.rsi + state: head_m + - map: [ "enum.HumanoidVisualLayers.Eyes" ] + color: "#008800" + sprite: Mobs/Species/eyes.rsi + state: eyes + - map: [ "enum.HumanoidVisualLayers.RArm" ] + color: "#e8b59b" + sprite: Mobs/Species/Human/parts.rsi + state: r_arm + - map: [ "enum.HumanoidVisualLayers.LArm" ] + color: "#e8b59b" + sprite: Mobs/Species/Human/parts.rsi + state: l_arm + - shader: StencilClear + sprite: Mobs/Species/Human/parts.rsi + state: l_leg + - shader: StencilMask + map: [ "enum.HumanoidVisualLayers.StencilMask" ] + sprite: Mobs/Customization/anytaur_masking_helpers.rsi + state: unisex_full + visible: false + - map: [ "jumpsuit" ] + - map: [ "enum.HumanoidVisualLayers.LHand" ] + color: "#e8b59b" + sprite: Mobs/Species/Human/parts.rsi + state: l_hand + - map: [ "enum.HumanoidVisualLayers.RHand" ] + color: "#e8b59b" + sprite: Mobs/Species/Human/parts.rsi + state: r_hand + - 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.Hair" ] + state: bald + sprite: Mobs/Customization/human_hair.rsi + - map: [ "mask" ] + - map: [ "head" ] + - map: [ "pocket1" ] + - map: [ "pocket2" ] + - map: [ "enum.HumanoidVisualLayers.Tail" ] + sprite: Mobs/Customization/masking_helpers.rsi + state: none + visible: false + - map: [ "clownedon" ] # Dynamically generated + sprite: "Effects/creampie.rsi" + state: "creampie_human" + visible: false + - type: HumanoidAppearance + species: Arachne + - type: Fixtures + fixtures: # TODO: This needs a second fixture just for mob collisions. + fix1: + shape: + !type:PhysShapeCircle + radius: 0.40 + density: 140 + restitution: 0.0 + mask: + - MobMask + layer: + - MobLayer + - type: Body + prototype: Arachne + requiredLegs: 8 + - type: Speech + speechSounds: Alto + - type: Inventory + templateId: anytaur + - type: Tag + tags: + - CanPilot + - ShoesRequiredStepTriggerImmune + - DoorBumpOpener + - type: Bloodstream + bloodReagent: DemonsBlood + - type: BloodSucker + webRequired: true + - type: Arachne + - type: DamageVisuals + thresholds: [ 20, 40, 100 ] + targetLayers: + - "enum.HumanoidVisualLayers.Chest" + - "enum.HumanoidVisualLayers.Head" + - "enum.HumanoidVisualLayers.LArm" + - "enum.HumanoidVisualLayers.RArm" + - type: MovedByPressure + pressureResistance: 4 + - type: Barotrauma + damage: + types: + Blunt: 0.05 #per second, scales with pressure and other constants. Reduced Damage. This allows medicine to heal faster than damage. + - type: MovementAlwaysTouching + - type: MovementSpeedModifier + baseWalkSpeed : 3.0 + baseSprintSpeed : 5.0 + - type: FireVisuals + sprite: Mobs/Effects/onfire.rsi + normalState: Generic_mob_burning + alternateState: arachne_standing + fireStackAlternateState: 3 + - type: Spider + - type: IgnoreSpiderWeb + +- type: entity + save: false + name: Urist McHands + parent: MobHumanDummy + id: MobArachneDummy + noSpawn: true + description: A dummy arachne meant to be used in character setup. + components: + - type: Sprite + layers: + - map: [ "enum.HumanoidVisualLayers.LLeg" ] + sprite: Mobs/Species/arachne.rsi + state: spider_body + - map: [ "enum.HumanoidVisualLayers.Chest" ] + color: "#e8b59b" + sprite: Mobs/Species/Human/parts.rsi + state: torso_m + - map: [ "enum.HumanoidVisualLayers.RLeg" ] + sprite: Mobs/Species/arachne.rsi + state: spider_body_front + - map: [ "enum.HumanoidVisualLayers.Head" ] + color: "#e8b59b" + sprite: Mobs/Species/Human/parts.rsi + state: head_m + - map: [ "enum.HumanoidVisualLayers.Eyes" ] + color: "#008800" + sprite: Mobs/Species/eyes.rsi + state: eyes + - map: [ "enum.HumanoidVisualLayers.RArm" ] + color: "#e8b59b" + sprite: Mobs/Species/Human/parts.rsi + state: r_arm + - map: [ "enum.HumanoidVisualLayers.LArm" ] + color: "#e8b59b" + sprite: Mobs/Species/Human/parts.rsi + state: l_arm + - shader: StencilClear + sprite: Mobs/Species/Human/parts.rsi + state: l_leg + - shader: StencilMask + map: [ "enum.HumanoidVisualLayers.StencilMask" ] + sprite: Mobs/Customization/anytaur_masking_helpers.rsi + state: unisex_full + visible: false + - map: [ "jumpsuit" ] + - map: [ "enum.HumanoidVisualLayers.LHand" ] + color: "#e8b59b" + sprite: Mobs/Species/Human/parts.rsi + state: l_hand + - map: [ "enum.HumanoidVisualLayers.RHand" ] + color: "#e8b59b" + sprite: Mobs/Species/Human/parts.rsi + state: r_hand + - 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.Hair" ] + state: bald + sprite: Mobs/Customization/human_hair.rsi + - map: [ "mask" ] + - map: [ "head" ] + - map: [ "pocket1" ] + - map: [ "pocket2" ] + - map: [ "enum.HumanoidVisualLayers.Tail" ] + sprite: Mobs/Customization/masking_helpers.rsi + state: none + visible: false + - type: Inventory + templateId: anytaur + - type: HumanoidAppearance + species: Arachne diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index 7863224436c..ca885117449 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -413,6 +413,22 @@ # - id: MobClownSpider # prob: 0.05 +- type: entity + id: OneirophageSpawn + parent: BaseGameRule + noSpawn: true + components: + - type: StationEvent + id: VentCritters + earliestStart: 15 + minimumPlayers: 15 + weight: 4 + duration: 60 + - type: VentCrittersRule + entries: + - id: MobGiantSpiderVampireAngry + prob: 0.01 + - type: entity id: ZombieOutbreak parent: BaseGameRule diff --git a/Resources/Prototypes/InventoryTemplates/anytaur_inventory_template.yml b/Resources/Prototypes/InventoryTemplates/anytaur_inventory_template.yml new file mode 100644 index 00000000000..0dd5961aef3 --- /dev/null +++ b/Resources/Prototypes/InventoryTemplates/anytaur_inventory_template.yml @@ -0,0 +1,112 @@ +- type: inventoryTemplate + id: anytaur + slots: + - name: jumpsuit + slotTexture: uniform + slotFlags: INNERCLOTHING + stripTime: 5 + uiWindowPos: 0,2 + strippingWindowPos: 0,2 + displayName: Jumpsuit + - name: outerClothing + slotTexture: suit + slotFlags: OUTERCLOTHING + slotGroup: MainHotbar + stripTime: 6 + uiWindowPos: 1,2 + strippingWindowPos: 1,2 + displayName: Suit + blacklist: + tags: + - FullBodyOuter + - name: gloves + slotTexture: gloves + slotFlags: GLOVES + uiWindowPos: 2,2 + strippingWindowPos: 2,2 + displayName: Gloves + - name: neck + slotTexture: neck + slotFlags: NECK + uiWindowPos: 0,1 + strippingWindowPos: 0,1 + displayName: Neck + - name: mask + slotTexture: mask + slotFlags: MASK + uiWindowPos: 1,1 + strippingWindowPos: 1,1 + displayName: Mask + - name: eyes + slotTexture: glasses + slotFlags: EYES + stripTime: 2 + uiWindowPos: 0,0 + strippingWindowPos: 0,0 + displayName: Eyes + - name: ears + slotTexture: ears + slotFlags: EARS + stripTime: 2 + uiWindowPos: 2,0 + strippingWindowPos: 2,1 + displayName: Ears + - name: head + slotTexture: head + slotFlags: HEAD + uiWindowPos: 1,0 + strippingWindowPos: 1,0 + displayName: Head + - name: pocket1 + slotTexture: pocket + slotFlags: POCKET + slotGroup: MainHotbar + stripTime: 2 + uiWindowPos: 0,3 + strippingWindowPos: 0,3 + dependsOn: jumpsuit + displayName: Pocket 1 + stripHidden: true + - name: pocket2 + slotTexture: pocket + slotFlags: POCKET + slotGroup: MainHotbar + stripTime: 2 + uiWindowPos: 2,3 + strippingWindowPos: 2,3 + dependsOn: jumpsuit + displayName: Pocket 2 + stripHidden: true + - name: suitstorage + slotTexture: suit_storage + slotFlags: SUITSTORAGE + stripTime: 2 + uiWindowPos: 2,0 + strippingWindowPos: 2,0 + dependsOn: outerClothing + displayName: Suit Storage + - name: id + slotTexture: id + slotFlags: IDCARD + slotGroup: SecondHotbar + stripTime: 6 + uiWindowPos: 2,1 + strippingWindowPos: 2,4 + dependsOn: jumpsuit + displayName: ID + - name: belt + slotTexture: belt + slotFlags: BELT + slotGroup: SecondHotbar + stripTime: 5 + uiWindowPos: 3,1 + strippingWindowPos: 1,3 + displayName: Belt + - name: back + slotTexture: back + slotFlags: BACK + slotGroup: SecondHotbar + stripTime: 5 + uiWindowPos: 3,0 + strippingWindowPos: 0,4 + displayName: Back diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Mechanisms/vampiric.yml b/Resources/Prototypes/Nyanotrasen/Entities/Body/Mechanisms/vampiric.yml new file mode 100644 index 00000000000..23934b3ebcc --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Entities/Body/Mechanisms/vampiric.yml @@ -0,0 +1,22 @@ +- type: entity + id: OrganVampiricHumanoidStomach + parent: OrganHumanStomach + components: + - type: Metabolizer + # mm yummy + maxReagents: 3 + metabolizerTypes: [Vampiric] + groups: + - id: Food + - id: Drink + +- type: entity + id: OrganVampiricStomach + parent: OrganAnimalStomach + components: + - type: Metabolizer + maxReagents: 3 + metabolizerTypes: [Vampiric] + groups: + - id: Food + - id: Drink diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml b/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml index a900f7524e7..7e71227dbcb 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Body/Parts/spider.yml @@ -24,13 +24,33 @@ - ReagentId: DemonsBlood Quantity: 10 +- type: entity + id: ThoraxSpider + name: "spider thorax" #for arachne, actual spiders should get a cephalothorax that combines with head. + parent: PartSpider + components: + - type: Sprite + sprite: Mobs/Species/Moth/parts.rsi # placeholder sprite + state: "torso_m" + - type: Icon + sprite: Mobs/Species/Moth/parts.rsi + state: "torso_m" + - type: BodyPart #"Other" type + - type: Extractable + juiceSolution: + reagents: + - ReagentId: Fat + Quantity: 10 + - ReagentId: DemonsBlood + Quantity: 20 + - type: entity id: RightLegSpider name: "right spider leg" parent: PartSpider components: - type: Sprite - sprite: Objects/Consumable/Food/meat.rsi + sprite: Objects/Consumable/Food/meat.rsi # placeholder sprite state: spiderleg - type: Icon sprite: Objects/Consumable/Food/meat.rsi @@ -48,7 +68,7 @@ parent: PartSpider components: - type: Sprite - sprite: Objects/Consumable/Food/meat.rsi + sprite: Objects/Consumable/Food/meat.rsi # placeholder sprite state: spiderleg - type: Icon sprite: Objects/Consumable/Food/meat.rsi diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml b/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml new file mode 100644 index 00000000000..553391484e2 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/arachne.yml @@ -0,0 +1,63 @@ +- type: body + id: Arachne + name: "arachne" + root: torso + slots: + head: + part: HeadHuman + connections: + - torso + organs: + brain: OrganHumanBrain + eyes: OrganHumanEyes + torso: + part: TorsoHuman + connections: + - left arm + - right arm + - thorax + organs: + heart: OrganHumanHeart + lungs: OrganHumanLungs + stomach: OrganVampiricHumanoidStomach + liver: OrganHumanLiver + kidneys: OrganHumanKidneys + right arm: + part: RightArmHuman + connections: + - right hand + left arm: + part: LeftArmHuman + connections: + - left hand + right hand: + part: RightHandHuman + left hand: + part: LeftHandHuman + thorax: + part: ThoraxSpider + connections: + - left foreleg + - left second leg + - left third leg + - left hind leg + - right foreleg + - right second leg + - right third leg + - right hind leg + left foreleg: + part: LeftLegSpider + left second leg: + part: LeftLegSpider + left third leg: + part: LeftLegSpider + left hind leg: + part: LeftLegSpider + right foreleg: + part: RightLegSpider + right second leg: + part: RightLegSpider + right third leg: + part: RightLegSpider + right hind leg: + part: RightLegSpider diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/vampiricanimal.yml b/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/vampiricanimal.yml new file mode 100644 index 00000000000..3f4cdb06de1 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Entities/Body/Prototypes/vampiricanimal.yml @@ -0,0 +1,43 @@ +- type: body + id: VampiricAnimal + name: "vampiric animal" + root: torso + slots: + torso: + part: TorsoAnimal + connections: + - legs + organs: + lungs: OrganAnimalLungs + stomach: OrganVampiricStomach + liver: OrganAnimalLiver + heart: OrganAnimalHeart + kidneys: OrganAnimalKidneys + legs: + part: LegsAnimal + connections: + - feet + feet: + part: FeetAnimal + +- type: body + id: VampiricAnimalLarge + name: "large vampiric animal" + root: torso + slots: + torso: + part: TorsoAnimal + connections: + - legs + organs: + lungs: OrganAnimalLungs + stomach: OrganVampiricHumanoidStomach + liver: OrganAnimalLiver + heart: OrganAnimalHeart + kidneys: OrganAnimalKidneys + legs: + part: LegsAnimal + connections: + - feet + feet: + part: FeetAnimal diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/ghost_roles.yml b/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/ghost_roles.yml index 2652a89127e..046a324e6f6 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/ghost_roles.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/ghost_roles.yml @@ -51,23 +51,23 @@ - state: prisoner # - type: MidRoundAntagSpawnLocation # When MidRoundAntag? -# - type: entity -# id: SpawnPointGhostVampSpider -# name: ghost role spawn point -# suffix: Vampire spider -# parent: MarkerBase -# noSpawn: true -# components: -# - type: GhostRoleMobSpawner -# prototype: MobGiantSpiderVampireAngry -# - type: GhostRole -# makeSentient: true -# name: ghost-role-information-giant-spider-vampire-name -# description: ghost-role-information-giant-spider-vampire-description -# rules: No antagonist restrictions. Just don't talk in emote; you have telepathic chat. -# - type: Sprite -# sprite: Markers/jobs.rsi -# layers: -# - state: green -# - sprite: Mobs/Animals/bat.rsi -# state: bat +- type: entity + id: SpawnPointGhostVampSpider + name: ghost role spawn point + suffix: Vampire spider + parent: MarkerBase + noSpawn: true + components: + - type: GhostRoleMobSpawner + prototype: MobGiantSpiderVampireAngry + - type: GhostRole + makeSentient: true + name: ghost-role-information-giant-spider-vampire-name + description: ghost-role-information-giant-spider-vampire-description + rules: No antagonist restrictions. Just don't talk in emote; you have telepathic chat. + - type: Sprite + sprite: Markers/jobs.rsi + layers: + - state: green + - sprite: Mobs/Animals/bat.rsi + state: bat diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/NPCs/mutants.yml b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/NPCs/mutants.yml index 5daf2e15e56..462b3254f1e 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/NPCs/mutants.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/NPCs/mutants.yml @@ -70,143 +70,130 @@ - type: Produce - type: NoSlip -# - type: entity -# name: oneirophage -# parent: SimpleMobBase -# id: MobGiantSpiderVampire -# description: The 'dream-eater' spider, rumored to be one of the potential genetic sources for arachne. -# components: -# - type: Sprite -# drawdepth: Mobs -# layers: -# - map: ["enum.DamageStateVisualLayers.Base"] -# state: viper -# sprite: Mobs/Animals/spider.rsi -# - type: Physics -# - type: Fixtures -# fixtures: -# fix1: -# shape: -# !type:PhysShapeCircle -# radius: 0.35 -# density: 130 -# mask: -# - SmallMobMask -# layer: -# - SmallMobLayer -# - type: Appearance -# - type: DamageStateVisuals -# states: -# Alive: -# Base: viper -# Critical: -# Base: viper_dead -# Dead: -# Base: viper_dead -# - type: Butcherable -# spawned: -# - id: FoodMeatSpider -# amount: 2 -# - type: CombatMode -# - type: ReplacementAccent -# accent: xeno -# - type: InteractionPopup -# successChance: 0.5 -# interactSuccessString: petting-success-tarantula -# interactFailureString: petting-failure-generic -# - type: Puller -# needsHands: false -# - type: Arachne -# cocoonDelay: 8 -# - type: SolutionContainerManager -# solutions: -# melee: -# reagents: -# - ReagentId: Nocturine -# Quantity: 20 -# - type: MeleeChemicalInjector -# solution: melee -# transferAmount: 3.5 -# - type: SolutionRegeneration -# solution: melee -# generated: -# reagents: -# - ReagentId: Nocturine -# Quantity: 0.15 -# - type: BloodSucker -# unitsToSucc: 35 -# injectWhenSucc: true -# injectReagent: Cryptobiolin -# unitsToInject: 10 -# webRequired: true -# - type: Bloodstream -# bloodReagent: DemonsBlood -# - type: Body -# prototype: VampiricAnimalLarge -# - type: PotentialPsionic -# - type: Psionic -# removable: false -# - type: MetapsionicPower -# - type: MeleeWeapon -# hidden: true -# angle: 0 -# animation: WeaponArcBite -# damage: -# types: -# Piercing: 8 -# - type: AntiPsionicWeapon -# punish: false -# modifiers: -# coefficients: -# Piercing: 2.25 -# - type: Damageable -# damageContainer: HalfSpirit -# damageModifierSet: HalfSpirit -# - type: StatusEffects -# allowed: -# - Stun -# - KnockedDown -# - SlowedDown -# - Stutter -# - SeeingRainbows -# - Electrocution -# - Drunk -# - SlurredSpeech -# - PressureImmunity -# - Muted -# - ForcedSleep -# - TemporaryBlindness -# - Pacified -# - PsionicsDisabled -# - PsionicallyInsulated -# - type: Tag -# tags: -# - Oneirophage -# - type: MovementAlwaysTouching -# - type: PsionicInvisibleContacts -# whitelist: -# tags: -# - ArachneWeb +- type: entity + name: oneirophage + parent: MobGiantSpider + id: MobGiantSpiderVampire + description: The 'dream-eater' spider, rumored to be one of the potential genetic sources for arachne. + components: + - type: Sprite + drawdepth: Mobs + layers: + - map: ["enum.DamageStateVisualLayers.Base", "movement"] + state: viper + sprite: Mobs/Animals/spider.rsi + - type: SpriteMovement + movementLayers: + movement: + state: viper-moving + noMovementLayers: + movement: + state: viper + - type: Appearance + - type: DamageStateVisuals + states: + Alive: + Base: viper + Critical: + Base: viper_dead + Dead: + Base: viper_dead + - type: ReplacementAccent + accent: xeno + - type: InteractionPopup + successChance: 0.5 + interactSuccessString: petting-success-tarantula + interactFailureString: petting-failure-generic + interactSuccessSpawn: EffectHearts + interactSuccessSound: + path: /Audio/Animals/snake_hiss.ogg + - type: Puller + needsHands: false + - type: Arachne + cocoonDelay: 8 + - type: SolutionContainerManager + solutions: + melee: + reagents: + - ReagentId: Nocturine + Quantity: 20 + - type: MeleeChemicalInjector + solution: melee + transferAmount: 3.5 + - type: SolutionRegeneration + solution: melee + generated: + reagents: + - ReagentId: Nocturine + Quantity: 0.15 + - type: BloodSucker + unitsToSucc: 35 + injectWhenSucc: true + injectReagent: Cryptobiolin + unitsToInject: 10 + webRequired: true + - type: Bloodstream + bloodReagent: DemonsBlood + - type: Body + prototype: VampiricAnimalLarge + - type: PotentialPsionic + - type: Psionic + removable: false + - type: MetapsionicPower + - type: AntiPsionicWeapon + punish: false + modifiers: + coefficients: + Piercing: 2.25 + - type: Damageable + damageContainer: HalfSpirit + damageModifierSet: HalfSpirit + - type: StatusEffects + allowed: + - Stun + - KnockedDown + - SlowedDown + - Stutter + - SeeingRainbows + - Electrocution + - Drunk + - SlurredSpeech + - PressureImmunity + - Muted + - ForcedSleep + - TemporaryBlindness + - Pacified + - PsionicsDisabled + - PsionicallyInsulated + - type: Tag + tags: + - Oneirophage + - type: MovementAlwaysTouching + - type: PsionicInvisibleContacts + whitelist: + tags: + - ArachneWeb -# - type: entity -# name: oneirophage -# parent: MobGiantSpiderVampire -# id: MobGiantSpiderVampireAngry -# suffix: Angry -# components: -# - type: NpcFactionMember -# factions: -# - SimpleHostile -# - type: InputMover -# - type: MobMover -# - type: HTN -# rootTask: SimpleHostileCompound -# - type: GhostRole -# makeSentient: true -# name: ghost-role-information-giant-spider-vampire-name -# description: ghost-role-information-giant-spider-vampire-description -# rules: No antagonist restrictions. Just don't talk in emote; you have telepathic chat. -# - type: GhostTakeoverAvailable +- type: entity + name: oneirophage + parent: MobGiantSpiderVampire + id: MobGiantSpiderVampireAngry + suffix: Angry + components: + - type: NpcFactionMember + factions: + - SimpleHostile + - type: InputMover + - type: MobMover + - type: HTN + rootTask: + task: SimpleHostileCompound + - type: GhostRole + makeSentient: true + name: ghost-role-information-giant-spider-vampire-name + description: ghost-role-information-giant-spider-vampire-description + rules: No antagonist restrictions. Just don't talk in emote; you have telepathic chat. + - type: GhostTakeoverAvailable - type: entity parent: SimpleMobBase diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Structures/Webbing/webs.yml b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Webbing/webs.yml new file mode 100644 index 00000000000..e483ea5da71 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Webbing/webs.yml @@ -0,0 +1,93 @@ +- type: entity + id: CocoonedHumanoid + name: cocooned humanoid + description: Unlucky. + placement: + mode: SnapgridCenter + snap: + - Wall + components: + - type: Sprite + layers: + - sprite: Nyanotrasen/Structures/cocoon.rsi + state: cocoon_large1 + map: [ "enum.DamageStateVisualLayers.Base" ] + - type: RandomSprite + available: + - enum.DamageStateVisualLayers.Base: + cocoon_large1: "" + - enum.DamageStateVisualLayers.Base: #your guess for why randomsprite requires an arbitrary layer is as good as mine friend + cocoon_large2: "" + - enum.DamageStateVisualLayers.Base: + cocoon_large3: "" + - type: Cocoon + - type: Clickable + - type: InteractionOutline + - type: Transform + noRot: true + - type: Damageable + damageModifierSet: Web + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 40 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.25,-0.4,0.25,0.1" + density: 20 + mask: + - SmallMobMask + layer: + - SmallMobLayer + - type: Physics + bodyType: Dynamic + - type: Pullable + - type: AntiRottingContainer + - type: ItemSlots + slots: + body_slot: + name: Body + locked: true + ejectOnBreak: true + - type: Butcherable + butcheringType: Knife + butcherDelay: 12 + spawned: + - id: MaterialCloth1 + amount: 1 + prob: 0.5 #This doesn't cost hunger so should at least make it not worth it time-wise + - type: Appearance + - type: ContainerContainer + containers: + body_slot: !type:ContainerSlot + +- type: entity + id: CocoonSmall + parent: CocoonedHumanoid + name: cocoon + description: What could be inside...? + placement: + mode: SnapgridCenter + snap: + - Wall + components: + - type: Sprite + layers: + - sprite: Nyanotrasen/Structures/cocoon.rsi + state: cocoon1 + map: [ "enum.DamageStateVisualLayers.Base" ] + - type: RandomSprite + available: + - enum.DamageStateVisualLayers.Base: + cocoon1: "" + - enum.DamageStateVisualLayers.Base: #your guess for why randomsprite requires an arbitrary layer is as good as mine friend + cocoon2: "" + - enum.DamageStateVisualLayers.Base: + cocoon3: "" diff --git a/Resources/Prototypes/Reagents/biological.yml b/Resources/Prototypes/Reagents/biological.yml index 0c53ae10fd1..5c0cef314ca 100644 --- a/Resources/Prototypes/Reagents/biological.yml +++ b/Resources/Prototypes/Reagents/biological.yml @@ -23,6 +23,29 @@ - !type:OrganType type: Human shouldHave: false + - !type:SatiateHunger + factor: 0.5 + conditions: + - !type:OrganType + type: Vampiric + - !type:AdjustReagent + conditions: + - !type:OrganType + type: Vampiric + reagent: Water + amount: 0.15 + - !type:AdjustReagent + conditions: + - !type:OrganType + type: Vampiric + reagent: Protein + amount: 0.15 + - !type:AdjustReagent + conditions: + - !type:OrganType + type: Vampiric + reagent: Omnizine + amount: 0.2 Food: effects: - !type:AdjustReagent diff --git a/Resources/Prototypes/Species/arachne.yml b/Resources/Prototypes/Species/arachne.yml new file mode 100644 index 00000000000..ed494c37cc8 --- /dev/null +++ b/Resources/Prototypes/Species/arachne.yml @@ -0,0 +1,50 @@ +- type: species + id: Arachne + name: species-name-arachne + roundStart: true + prototype: MobArachne + sprites: MobArachneSprites + markingLimits: MobArachneMarkingLimits + dollPrototype: MobArachneDummy + skinColoration: HumanToned + sexes: + - Female + minAge: 60 + youngAge: 150 + oldAge: 400 + maxAge: 666 + +- type: markingPoints + id: MobArachneMarkingLimits + points: + Hair: + points: 1 + required: false + Tail: + points: 1 + required: false + Chest: + points: 1 + required: false + Arms: + points: 2 + required: false + + +- type: speciesBaseSprites + id: MobArachneSprites + sprites: + Head: MobHumanHead + Hair: MobHumanoidAnyMarking + Chest: MobHumanTorso + Eyes: MobArachneEyes + LArm: MobHumanLArm + RArm: MobHumanRArm + LHand: MobHumanLHand + RHand: MobHumanRHand + +- type: humanoidBaseSprite + id: MobArachneEyes + baseSprite: + sprite: Mobs/Species/eyes.rsi + state: eyes diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index 9b0ad51cfb6..786f641ddd1 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -16,6 +16,9 @@ - type: Tag id: AppraisalTool +- type: Tag + id: ArachneWeb + - type: Tag id: ArtifactFragment @@ -602,6 +605,9 @@ - type: Tag id: Fruit +- type: Tag + id: FullBodyOuter + - type: Tag id: Galaxythistle @@ -919,6 +925,9 @@ - type: Tag id: Ointment +- type: Tag + id: Oneirophage + - type: Tag id: Ore diff --git a/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/female_full.png b/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/female_full.png new file mode 100644 index 0000000000000000000000000000000000000000..acb96562e7374cbaba2d9f8eac4f1983c2722946 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pW8&%J7@~1LIYA=F!GWQPv*Eu3gIdO!1&Rrbf?NSjtdA<$*!Y?lS%R69 i8<@M9!xb)?)i4xI-eS7+u8$Z{KZB>MpUXO@geCy^0w-qx literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/female_none.png b/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/female_none.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/female_top.png b/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/female_top.png new file mode 100644 index 0000000000000000000000000000000000000000..acb96562e7374cbaba2d9f8eac4f1983c2722946 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pW8&%J7@~1LIYA=F!GWQPv*Eu3gIdO!1&Rrbf?NSjtdA<$*!Y?lS%R69 i8<@M9!xb)?)i4xI-eS7+u8$Z{KZB>MpUXO@geCy^0w-qx literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/full.png b/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/full.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/male_full.png b/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/male_full.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/male_none.png b/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/male_none.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/male_top.png b/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/male_top.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/meta.json b/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/meta.json new file mode 100644 index 00000000000..b44be570c4f --- /dev/null +++ b/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/meta.json @@ -0,0 +1,59 @@ +{ + "version": 1, + "copyright": "Rane", + "license": "CC-BY-SA-3.0", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "female_none", + "directions": 4 + }, + { + "name": "female_full", + "directions": 4 + }, + { + "name": "female_top", + "directions": 4 + }, + { + "name": "male_none", + "directions": 4 + }, + { + "name": "male_full", + "directions": 4 + }, + { + "name": "male_top", + "directions": 4 + }, + { + "name": "full", + "directions": 4 + }, + { + "name": "none", + "directions": 4 + }, + { + "name": "top", + "directions": 4 + }, + { + "name": "unisex_full", + "directions": 4 + }, + { + "name": "unisex_none", + "directions": 4 + }, + { + "name": "unisex_top", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/none.png b/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/none.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/top.png b/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/top.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_full.png b/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_full.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_none.png b/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_none.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_top.png b/Resources/Textures/Mobs/Customization/anytaur_masking_helpers.rsi/unisex_top.png new file mode 100644 index 0000000000000000000000000000000000000000..20ccfaa8db4caa19d2762bbb84aa2c4a5dff53bc GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pBjM@d7@~1LIYDC41ABo6PATIylLfUu7#QYSZ1zpv!|)iWhQZU-&t;uc GLK6T%$RK0@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/spidereyes.rsi/eyes.png b/Resources/Textures/Mobs/Customization/spidereyes.rsi/eyes.png new file mode 100644 index 0000000000000000000000000000000000000000..0f2534769440310b1f727cde206dfda449257ab0 GIT binary patch literal 5070 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Species/arachne.rsi/spider_body_front.png b/Resources/Textures/Mobs/Species/arachne.rsi/spider_body_front.png new file mode 100644 index 0000000000000000000000000000000000000000..0171f16fe385fe420c6f1b1142b5381e2284ba92 GIT binary patch literal 761 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSoCO|{#S9F5M?jcysy3fA0|V1U zPZ!6KiaBrZ9`qM>6gmF!{+8Vi+G2O6t>rz%CBtGXu=nNv`4z?wm8z7c6lHq3>b})` z_pMSxSHic)aOSLUzju~yJ9%bb<>#{RUsQlrUqp7-u2zqhRC<9m~TO#Ecr>eQ`KzJ5W|QoS~ZL{9TeyS3u#mg`xS{f-Zc zH_f%!X2A2MsQ$i*T>MNm)e}>_W+zHysQ0bC`&KU}RO?vs)5>*@^G?6XTR*qBXwtFA z8^4=YdN(}xOj>-=W3fqaYOe1jv*p+4EHOEo_W!p@d(eyKnVA+ct77#2PhxNl{A2R0 zdpb*n)NwJE$t#b!F0?ssYWp|XHPA;)WQzDUp%86RR>uVfJSFu&(@%YlIrnpaYQAWK zDo<#?QtY?iRXg^r%WppT=GK>T+b$K|ce7vG#C`gA#G7eO`R;X3=3HIuan6#L?fS0z zL&DF`SgJptqxZXZuI_`E?Ms&2+_L26pSR6=nPzVzKYu(_&xt({v4}Q2eYn;6dH3B| zW8+XQ(Y^MT3$0(+uIJ~^HIX`LxtxFb@_R{-x7O}C6S6jJ>n@>JZ!cb4Q~zoA3IjA^m*&&Ubxth`@pA}Idyk3R@{B*k#_1*$lJK{*`{;6U*7GLyP1~j zeE)L{|Ekc^YTMW^zrDXo+~`y4mgbG+Z|7=u2#??YV$uJ~l}VU>`gfN9lgpc9^P48s h0VVlTBRtc5eHpZXY!0a6OTm*tEKgTImvv4FO#o58J(mCg literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Species/eyes.rsi/eyes.png b/Resources/Textures/Mobs/Species/eyes.rsi/eyes.png new file mode 100644 index 0000000000000000000000000000000000000000..b6250e22b38a17c35b2b54789f66bb5cda1db308 GIT binary patch literal 5553 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Species/eyes.rsi/meta.json b/Resources/Textures/Mobs/Species/eyes.rsi/meta.json new file mode 100644 index 00000000000..a98aba406f1 --- /dev/null +++ b/Resources/Textures/Mobs/Species/eyes.rsi/meta.json @@ -0,0 +1,15 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Created by @Rane#7518", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "eyes", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon1.png b/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon1.png new file mode 100644 index 0000000000000000000000000000000000000000..27741fdf314bc38be7153151d603479000af1891 GIT binary patch literal 669 zcmV;O0%HA%P)$5Dx(m zFBXfsFs^ZhFvIKhs_Q@?a2Eu|Znw+%d={V2CxgL2(&@BRt5s77QvgGJv)QP)!{Lxf zBqH5zS3;qX0suChPIdoDARG?Ma5&VIZq5}t7z~=4e3$?qrcx<&lF#R5GMOk0#n$Wf zbgvNx%x1I6<#LhTZYQJB=)MNvY>Qb6p90{%P$;MnB8HP#EGF%CTX=>j_YedE$8-R| z2pY9PD*b+6(|S1pqs>SHF&0TClhWyQ6o&J|;UM$*{N4f71zSRDY#+4%AZuXAG5}6) zJ*{FSF&>X~3xL8MAVy2#m^3I#?&oqjg$5#%$!M*-lmLq%x>zjq8dr$n%mCybVgTLx zUR_f8)C2?Ph&LJyX|-C`y5LqQR|<#N5hY3%&StYJXt<{%0O37mT984J0?BUyP@joE zOaO?F549B$#R;MmAA^~AnE_;<*&=3=1DK@06q*z%=`4(1e*jw4~ z0qlJMWovU6H!CGJl-MY-xwmdtq%iY)ns=JT%y?aMo6Y-_-gBJS`Tw5(^PJ}DNTn6v)$^dz}l z?&{uG0e*DwrC2OVzu#ADv6;^I`F#40Q3}HmU~mHGDA`>A1U8Z_U5_|(ZouJi__HaQ zb4ntSh&q9ItyYt6w|oCZ)ai881#Y-_Jg%Y$7#{#)v6!9+#DQ$JTE_40cff%7Zs&#L z)@(La1XswMBT4plyIm@kirRiH^P2&PUpCc0o8Q&ftnh~bj4)&Ervm)TumCIo3*Z}` WA1sKIggnat0000>)WwzxBKr~01&TMs}c%@WV_wUYPFI?BEi)4t02Yzh&P)}+3)w-zg#X- zDwPz3@mqWv#0bC=C*w>eBcstsa=Dy%JRWspHk*mt?Us7It}P&@5XKH5PW1czd*+CH zy=I<#amf@8*aR#6tkGuT&~3hV6jRB0QN)BpQv%Znx93ryd@e$n4R$MNZwy{|3K8G+z z!Wb@C4gm4&)`v%71mO4kWiS|M;ZcBOY1xfC6eHr)fzRi=uS=y;5BGiuKv5kI2Xz3D zbULj^5ex=jy*HoFRS*~g7kH2Lwg7s)9`;=ujfVCSW>Y>rs(-WDs2hPmKqp|B26zX=cKp8o0}g-#@aF*j10gEyIQQql Q8~^|S07*qoM6N<$f*=3`Hvj+t literal 0 HcmV?d00001 diff --git a/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large1.png b/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large1.png new file mode 100644 index 0000000000000000000000000000000000000000..f9431f6428586fe569344878961bd645cbc04fc6 GIT binary patch literal 762 zcmVgc z)HGVt5GrUW(MCfaUs*`R6?PUu8&3| zNvG3tb#*1>a@o1Oyxf|EOMu{L0LW@nhDS$7QYw{P@YQN1KA%r^cX!o}?e_MT;npOS z0IYMloFtP;d3$?vgMWN{xLH0wKdZ(L0YI@wA`ywlP)iTC$+wedl~_5y~WPfkvBj3y>__7w^Rr`>L^ z5zz`*DNQVxW%cy*B;jyavm+Di%jHt5z#cw`quGZf5((9|PBO$gJv}9kQ>j#T)_MSj znM}ql8BVj=Oq~EE3y3gB=JUBr#MYRT2ni7n!3I&PNX3w1u}F_;pC|#GC@tUs6Lhgy zXaidIcHUNUn{!$Y^}?1i+)CY#N=3DoO#J%UXS&qe~DNc>iKw1&f>5L*PT;*8~QGffs!} zpU=Pki~!)>Zr7AbC3$_n-??}$BvKPl@Or&&PN$QpR;%WCJR0t~kVr)!dh+Mb%Vi;e0@UO25G7E>wo((o??RzquGg!nR4V3jxrFbX&*%3O z0E81G`|WlU5)_17DiwjiTW>rbi}%=(&*ww%*=%N(%jNq**lxEagrpwNU$2*_ffB3L z${IWs0l-J2k@(Mp0$hEk3tY;H0N}k|Po8sfE##*a31Y2Q6cTGIE(O#1Pj;9&toXiW$VheODDlgT8zK?E?T*O80l5Ya3g z4hJEF1z2KRP8L9d0(`w*ixt?Qz^Fn+hf<~lIGK9w2T~;8?RMdb)e4s!I1vDV(_;Z@ zaAJsPK?p0bYO~p7OCV?~nE~2@bb^MDJU|djc%Q%;i;ZYaz@K~`sb}CY@i-+99Y(s8 zAhX?W!`+Zni39-V>bIfvJK>}Bq&oirjJ71z@AtXHst`+{)9H8sBQF4W&yONKK#(DT zyoWmEg6Am1XCX43PGd<}SpWz>hyvPj6oG^YkErDOS?<#jTvI6!Y&B08jIW6P@f20a z0#hxX%$l3vJF)B8X%5)#dD~4${QyPKZkme+ R_X7X`002ovPDHLkV1mDMGcW)E literal 0 HcmV?d00001 diff --git a/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large3.png b/Resources/Textures/Nyanotrasen/Structures/cocoon.rsi/cocoon_large3.png new file mode 100644 index 0000000000000000000000000000000000000000..9a033961ffa27e1796d98c10f6fc9d563f13066a GIT binary patch literal 876 zcmV-y1C#uTP)P6p9*9R5b`t4M~gH+uwv|vr7wIu9v%9!kbKXc6WH6-}`4~`Dy;KodM1O zXMq0~pwVbJn!mrlo5#n;AAbb^VFc^-x=E+g=JoZ}j(k4v%;$5{ZnsYYISByqTrOv7 zwVJuOxG?MW+Hj9uUtgQaWWv-r1tK&6;zS*dMolahvjAM5pPy|e7K??sy1FuzN`)+h z4k{FY#EEjXTG^3ICM^VmdolqKFsu)og-`&AM8Z1e${_WsJ@>Nhc5BBe_9ejW?XBZB zm`y#x5`1}ivC#uTHvG^27y#ncYSqq_b|M4;| za|~gkCEcuJOs7*jPO%RF_xJZssZ{bB3Nbl}=HBV1Z zwiJ4&5-<=Js4E;0Z#J9Wx8hhy0swb+ced-*Ob8%O#Hm!ut2qXwj8m{&E;Dt2K-~3Z z-|aHx9D)b{5EUJdai!im;UbZUd3$@a5Tu<>M;N1I7(2#YZ_f>Sf#zjBr>G0;d{&+S z01k;V?-3skhjz|8t_T9m z+}|fW$GGwZB@4Y?FOY=*0ClCCHQ-*^ct8vPUUAI}K#JNiLu*@g_>hbjTa zp9$BgLl%fe;>v~^j7|qqe@X^I;+0IbvLu-NH#yC###c+Y{tIbhlW zM6IJ*< Date: Tue, 6 Aug 2024 04:52:58 +0000 Subject: [PATCH 04/32] Automatic Changelog Update (#438) --- Resources/Changelog/Changelog.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 35142b8bbfa..afe00fec1f2 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -4940,3 +4940,11 @@ Entries: message: Added an unlockable PKA and Jetpack module to Salvage Cyborgs id: 6218 time: '2024-08-06T01:14:31.0000000+00:00' +- author: VMSolidus + changes: + - type: Add + message: Arachne have been reimplemented! + - type: Add + message: Oneirophages are back! + id: 6219 + time: '2024-08-06T04:52:32.0000000+00:00' From aed3baba152a568b0b291fe714beb68f6934761c Mon Sep 17 00:00:00 2001 From: VMSolidus Date: Tue, 6 Aug 2024 01:28:53 -0400 Subject: [PATCH 05/32] CPR Remake (#487) # Description This is a re implementation and complete rewrite of the original Nyanotrasen CPR feature, this time as its own completely standalone system. Unlike the original CPR, this system requires no modification of base game code, and can be toggled on and off via CVars while the server is running. Fixes #473 Fixes #49 # Changelog :cl: - add: CPR has been added to the game. People with CPR training can now perform CPR on anyone who is in either crit or dead states. - add: CPR Training has been added to the game as a new positive trait. All medical staff start with this trait for free. --------- Signed-off-by: VMSolidus --- Content.Server/Atmos/Rotting/RottingSystem.cs | 107 +------------ .../Atmos/Rotting/SharedRottingSystem.cs | 141 +++++++++++++++++- Content.Shared/CCVar/CCVars.cs | 49 ++++++ .../CPR/Components/CPRTrainingComponent.cs | 33 ++++ .../Medical/CPR/Systems/CPRSystem.CVars.cs | 27 ++++ .../Medical/CPR/Systems/CPRSystem.cs | 132 ++++++++++++++++ Resources/Audio/Effects/CPR.ogg | Bin 0 -> 68840 bytes .../components/cpr-training-component.ftl | 6 + Resources/Locale/en-US/traits/traits.ftl | 7 + .../DeltaV/Roles/Jobs/Security/brigmedic.yml | 3 + .../Prototypes/Roles/Jobs/Medical/chemist.yml | 4 + .../Jobs/Medical/chief_medical_officer.yml | 1 + .../Roles/Jobs/Medical/medical_doctor.yml | 4 + .../Roles/Jobs/Medical/medical_intern.yml | 4 + .../Roles/Jobs/Medical/paramedic.yml | 4 + .../Roles/Jobs/Medical/senior_physician.yml | 4 + Resources/Prototypes/Traits/skills.yml | 17 +++ 17 files changed, 431 insertions(+), 112 deletions(-) create mode 100644 Content.Shared/Medical/CPR/Components/CPRTrainingComponent.cs create mode 100644 Content.Shared/Medical/CPR/Systems/CPRSystem.CVars.cs create mode 100644 Content.Shared/Medical/CPR/Systems/CPRSystem.cs create mode 100644 Resources/Audio/Effects/CPR.ogg create mode 100644 Resources/Locale/en-US/medical/components/cpr-training-component.ftl diff --git a/Content.Server/Atmos/Rotting/RottingSystem.cs b/Content.Server/Atmos/Rotting/RottingSystem.cs index 47bac84e0ca..5070b3f197f 100644 --- a/Content.Server/Atmos/Rotting/RottingSystem.cs +++ b/Content.Server/Atmos/Rotting/RottingSystem.cs @@ -1,15 +1,9 @@ -using Content.Shared.Damage; -using Content.Shared.Atmos; using Content.Server.Atmos.EntitySystems; using Content.Server.Body.Components; using Content.Server.Temperature.Components; +using Content.Shared.Atmos; using Content.Shared.Atmos.Rotting; -using Content.Shared.Examine; -using Content.Shared.IdentityManagement; -using Content.Shared.Mobs; -using Content.Shared.Mobs.Components; -using Content.Shared.Mobs.Systems; -using Content.Shared.Rejuvenate; +using Content.Shared.Damage; using Robust.Server.Containers; using Robust.Shared.Physics.Components; using Robust.Shared.Timing; @@ -22,83 +16,16 @@ public sealed class RottingSystem : SharedRottingSystem [Dependency] private readonly AtmosphereSystem _atmosphere = default!; [Dependency] private readonly ContainerSystem _container = default!; [Dependency] private readonly DamageableSystem _damageable = default!; - [Dependency] private readonly MobStateSystem _mobState = default!; public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnPerishableMapInit); - SubscribeLocalEvent(OnMobStateChanged); - SubscribeLocalEvent(OnPerishableExamined); - - SubscribeLocalEvent(OnShutdown); - SubscribeLocalEvent(OnRottingMobStateChanged); SubscribeLocalEvent(OnGibbed); - SubscribeLocalEvent(OnRejuvenate); SubscribeLocalEvent(OnTempIsRotting); } - private void OnPerishableMapInit(EntityUid uid, PerishableComponent component, MapInitEvent args) - { - component.RotNextUpdate = _timing.CurTime + component.PerishUpdateRate; - } - - private void OnMobStateChanged(EntityUid uid, PerishableComponent component, MobStateChangedEvent args) - { - if (args.NewMobState != MobState.Dead && args.OldMobState != MobState.Dead) - return; - - if (HasComp(uid)) - return; - - component.RotAccumulator = TimeSpan.Zero; - component.RotNextUpdate = _timing.CurTime + component.PerishUpdateRate; - } - - private void OnShutdown(EntityUid uid, RottingComponent component, ComponentShutdown args) - { - if (TryComp(uid, out var perishable)) - { - perishable.RotNextUpdate = TimeSpan.Zero; - } - } - - private void OnRottingMobStateChanged(EntityUid uid, RottingComponent component, MobStateChangedEvent args) - { - if (args.NewMobState == MobState.Dead) - return; - RemCompDeferred(uid, component); - } - - public bool IsRotProgressing(EntityUid uid, PerishableComponent? perishable) - { - // things don't perish by default. - if (!Resolve(uid, ref perishable, false)) - return false; - - // only dead things or inanimate objects can rot - if (TryComp(uid, out var mobState) && !_mobState.IsDead(uid, mobState)) - return false; - - if (_container.TryGetOuterContainer(uid, Transform(uid), out var container) && - HasComp(container.Owner)) - { - return false; - } - - var ev = new IsRottingEvent(); - RaiseLocalEvent(uid, ref ev); - - return !ev.Handled; - } - - public bool IsRotten(EntityUid uid, RottingComponent? rotting = null) - { - return Resolve(uid, ref rotting, false); - } - private void OnGibbed(EntityUid uid, RottingComponent component, BeingGibbedEvent args) { if (!TryComp(uid, out var physics)) @@ -112,36 +39,6 @@ private void OnGibbed(EntityUid uid, RottingComponent component, BeingGibbedEven tileMix?.AdjustMoles(Gas.Ammonia, molsToDump); } - private void OnPerishableExamined(Entity perishable, ref ExaminedEvent args) - { - int stage = PerishStage(perishable, MaxStages); - if (stage < 1 || stage > MaxStages) - { - // We dont push an examined string if it hasen't started "perishing" or it's already rotting - return; - } - - var isMob = HasComp(perishable); - var description = "perishable-" + stage + (!isMob ? "-nonmob" : string.Empty); - args.PushMarkup(Loc.GetString(description, ("target", Identity.Entity(perishable, EntityManager)))); - } - - /// - /// Return an integer from 0 to maxStage representing how close to rotting an entity is. Used to - /// generate examine messages for items that are starting to rot. - /// - public int PerishStage(Entity perishable, int maxStages) - { - if (perishable.Comp.RotAfter.TotalSeconds == 0 || perishable.Comp.RotAccumulator.TotalSeconds == 0) - return 0; - return (int)(1 + maxStages * perishable.Comp.RotAccumulator.TotalSeconds / perishable.Comp.RotAfter.TotalSeconds); - } - - private void OnRejuvenate(EntityUid uid, RottingComponent component, RejuvenateEvent args) - { - RemCompDeferred(uid); - } - private void OnTempIsRotting(EntityUid uid, TemperatureComponent component, ref IsRottingEvent args) { if (args.Handled) diff --git a/Content.Shared/Atmos/Rotting/SharedRottingSystem.cs b/Content.Shared/Atmos/Rotting/SharedRottingSystem.cs index 5e1758203a8..840818dee59 100644 --- a/Content.Shared/Atmos/Rotting/SharedRottingSystem.cs +++ b/Content.Shared/Atmos/Rotting/SharedRottingSystem.cs @@ -1,29 +1,85 @@ using Content.Shared.Examine; using Content.Shared.IdentityManagement; +using Content.Shared.Mobs; using Content.Shared.Mobs.Components; +using Content.Shared.Mobs.Systems; +using Content.Shared.Rejuvenate; +using Robust.Shared.Containers; +using Robust.Shared.Timing; namespace Content.Shared.Atmos.Rotting; public abstract class SharedRottingSystem : EntitySystem { + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly SharedContainerSystem _container = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + public const int MaxStages = 3; public override void Initialize() { base.Initialize(); + SubscribeLocalEvent(OnPerishableMapInit); + SubscribeLocalEvent(OnMobStateChanged); + SubscribeLocalEvent(OnPerishableExamined); + + SubscribeLocalEvent(OnShutdown); + SubscribeLocalEvent(OnRottingMobStateChanged); + SubscribeLocalEvent(OnRejuvenate); SubscribeLocalEvent(OnExamined); } - /// - /// Return the rot stage, usually from 0 to 2 inclusive. - /// - public int RotStage(EntityUid uid, RottingComponent? comp = null, PerishableComponent? perishable = null) + private void OnPerishableMapInit(EntityUid uid, PerishableComponent component, MapInitEvent args) { - if (!Resolve(uid, ref comp, ref perishable)) - return 0; + component.RotNextUpdate = _timing.CurTime + component.PerishUpdateRate; + } - return (int) (comp.TotalRotTime.TotalSeconds / perishable.RotAfter.TotalSeconds); + private void OnMobStateChanged(EntityUid uid, PerishableComponent component, MobStateChangedEvent args) + { + if (args.NewMobState != MobState.Dead && args.OldMobState != MobState.Dead) + return; + + if (HasComp(uid)) + return; + + component.RotAccumulator = TimeSpan.Zero; + component.RotNextUpdate = _timing.CurTime + component.PerishUpdateRate; + } + + private void OnPerishableExamined(Entity perishable, ref ExaminedEvent args) + { + int stage = PerishStage(perishable, MaxStages); + if (stage < 1 || stage > MaxStages) + { + // We dont push an examined string if it hasen't started "perishing" or it's already rotting + return; + } + + var isMob = HasComp(perishable); + var description = "perishable-" + stage + (!isMob ? "-nonmob" : string.Empty); + args.PushMarkup(Loc.GetString(description, ("target", Identity.Entity(perishable, EntityManager)))); + } + + private void OnShutdown(EntityUid uid, RottingComponent component, ComponentShutdown args) + { + if (TryComp(uid, out var perishable)) + { + perishable.RotNextUpdate = TimeSpan.Zero; + } + } + + private void OnRottingMobStateChanged(EntityUid uid, RottingComponent component, MobStateChangedEvent args) + { + if (args.NewMobState == MobState.Dead) + return; + RemCompDeferred(uid, component); + } + + private void OnRejuvenate(EntityUid uid, RottingComponent component, RejuvenateEvent args) + { + RemCompDeferred(uid); } private void OnExamined(EntityUid uid, RottingComponent component, ExaminedEvent args) @@ -41,4 +97,75 @@ private void OnExamined(EntityUid uid, RottingComponent component, ExaminedEvent args.PushMarkup(Loc.GetString(description, ("target", Identity.Entity(uid, EntityManager)))); } + + /// + /// Return an integer from 0 to maxStage representing how close to rotting an entity is. Used to + /// generate examine messages for items that are starting to rot. + /// + public int PerishStage(Entity perishable, int maxStages) + { + if (perishable.Comp.RotAfter.TotalSeconds == 0 || perishable.Comp.RotAccumulator.TotalSeconds == 0) + return 0; + return (int)(1 + maxStages * perishable.Comp.RotAccumulator.TotalSeconds / perishable.Comp.RotAfter.TotalSeconds); + } + + public bool IsRotProgressing(EntityUid uid, PerishableComponent? perishable) + { + // things don't perish by default. + if (!Resolve(uid, ref perishable, false)) + return false; + + // only dead things or inanimate objects can rot + if (TryComp(uid, out var mobState) && !_mobState.IsDead(uid, mobState)) + return false; + + if (_container.TryGetOuterContainer(uid, Transform(uid), out var container) && + HasComp(container.Owner)) + { + return false; + } + + var ev = new IsRottingEvent(); + RaiseLocalEvent(uid, ref ev); + + return !ev.Handled; + } + + public bool IsRotten(EntityUid uid, RottingComponent? rotting = null) + { + return Resolve(uid, ref rotting, false); + } + + public void ReduceAccumulator(EntityUid uid, TimeSpan time) + { + if (!TryComp(uid, out var perishable)) + return; + + if (!TryComp(uid, out var rotting)) + { + perishable.RotAccumulator -= time; + return; + } + var total = (rotting.TotalRotTime + perishable.RotAccumulator) - time; + + if (total < perishable.RotAfter) + { + RemCompDeferred(uid, rotting); + perishable.RotAccumulator = total; + } + + else + rotting.TotalRotTime = total - perishable.RotAfter; + } + + /// + /// Return the rot stage, usually from 0 to 2 inclusive. + /// + public int RotStage(EntityUid uid, RottingComponent? comp = null, PerishableComponent? perishable = null) + { + if (!Resolve(uid, ref comp, ref perishable)) + return 0; + + return (int) (comp.TotalRotTime.TotalSeconds / perishable.RotAfter.TotalSeconds); + } } diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index facbd1d71b6..3fc7e7247e6 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -2291,6 +2291,55 @@ public static readonly CVarDef /// public static readonly CVarDef StationGoalsChance = CVarDef.Create("game.station_goals_chance", 0.1f, CVar.SERVERONLY); + + + #region CPR System + /// + /// Controls whether the entire CPR system runs. When false, nobody can perform CPR. You should probably remove the trait too + /// if you are wishing to permanently disable the system on your server. + /// + public static readonly CVarDef EnableCPR = + CVarDef.Create("cpr.enable", true, CVar.REPLICATED | CVar.SERVER); + + /// + /// Toggles whether or not CPR reduces rot timers(As an abstraction of delaying brain death, the IRL actual purpose of CPR) + /// + public static readonly CVarDef CPRReducesRot = + CVarDef.Create("cpr.reduces_rot", true, CVar.REPLICATED | CVar.SERVER); + + /// + /// Toggles whether or not CPR heals airloss, included for completeness sake. I'm not going to stop you if your intention is to make CPR do nothing. + /// I guess it might be funny to troll your players with? I won't judge. + /// + public static readonly CVarDef CPRHealsAirloss = + CVarDef.Create("cpr.heals_airloss", true, CVar.REPLICATED | CVar.SERVER); + + /// + /// The chance for a patient to be resuscitated when CPR is successfully performed. + /// Setting this above 0 isn't very realistic, but people who see CPR in movies and TV will expect CPR to work this way. + /// + public static readonly CVarDef CPRResuscitationChance = + CVarDef.Create("cpr.resuscitation_chance", 0.05f, CVar.REPLICATED | CVar.SERVER); + + /// + /// By default, CPR reduces rot timers by an amount of seconds equal to the time spent performing CPR. This is an optional multiplier that can increase or decrease the amount + /// of rot reduction. Set it to 2 for if you want 3 seconds of CPR to reduce 6 seconds of rot. + /// + /// + /// If you're wondering why there isn't a CVar for setting the duration of the doafter, that's because it's not actually possible to have a timespan in cvar form + /// Curiously, it's also not possible for **shared** systems to set variable timespans. Which is where this system lives. + /// + public static readonly CVarDef CPRRotReductionMultiplier = + CVarDef.Create("cpr.rot_reduction_multiplier", 1f, CVar.REPLICATED | CVar.SERVER); + + /// + /// By default, CPR heals airloss by 1 point for every second spent performing CPR. Just like above, this directly multiplies the healing amount. + /// Set it to 2 to get 6 points of airloss healing for every 3 seconds of CPR. + /// + public static readonly CVarDef CPRAirlossReductionMultiplier = + CVarDef.Create("cpr.airloss_reduction_multiplier", 1f, CVar.REPLICATED | CVar.SERVER); + + #endregion #region Contests System diff --git a/Content.Shared/Medical/CPR/Components/CPRTrainingComponent.cs b/Content.Shared/Medical/CPR/Components/CPRTrainingComponent.cs new file mode 100644 index 00000000000..e01250858a1 --- /dev/null +++ b/Content.Shared/Medical/CPR/Components/CPRTrainingComponent.cs @@ -0,0 +1,33 @@ +using Robust.Shared.GameStates; +using Content.Shared.DoAfter; +using Robust.Shared.Audio; +using Robust.Shared.Serialization; + +namespace Content.Shared.Medical.CPR +{ + [RegisterComponent, NetworkedComponent] + public sealed partial class CPRTrainingComponent : Component + { + [DataField] + public SoundSpecifier CPRSound = new SoundPathSpecifier("/Audio/Effects/CPR.ogg"); + + /// + /// How long the doafter for CPR takes + /// + [DataField] + public TimeSpan DoAfterDuration = TimeSpan.FromSeconds(3); + + [DataField] + public int AirlossHeal = 6; + + [DataField] + public float CrackRibsModifier = 1f; + public EntityUid? CPRPlayingStream; + } + + [Serializable, NetSerializable] + public sealed partial class CPRDoAfterEvent : SimpleDoAfterEvent + { + + } +} diff --git a/Content.Shared/Medical/CPR/Systems/CPRSystem.CVars.cs b/Content.Shared/Medical/CPR/Systems/CPRSystem.CVars.cs new file mode 100644 index 00000000000..9840b8ffbd4 --- /dev/null +++ b/Content.Shared/Medical/CPR/Systems/CPRSystem.CVars.cs @@ -0,0 +1,27 @@ +using Content.Shared.CCVar; +using Robust.Shared.Configuration; + +namespace Content.Shared.Medical.CPR +{ + public sealed partial class CPRSystem + { + [Dependency] private readonly IConfigurationManager _cfg = default!; + + public bool EnableCPR { get; private set; } + public bool HealsAirloss { get; private set; } + public bool ReducesRot { get; private set; } + public float ResuscitationChance { get; private set; } + public float RotReductionMultiplier { get; private set; } + public float AirlossReductionMultiplier { get; private set; } + + private void InitializeCVars() + { + Subs.CVar(_cfg, CCVars.EnableCPR, value => EnableCPR = value, true); + Subs.CVar(_cfg, CCVars.CPRHealsAirloss, value => HealsAirloss = value, true); + Subs.CVar(_cfg, CCVars.CPRReducesRot, value => ReducesRot = value, true); + Subs.CVar(_cfg, CCVars.CPRResuscitationChance, value => ResuscitationChance = value, true); + Subs.CVar(_cfg, CCVars.CPRRotReductionMultiplier, value => RotReductionMultiplier = value, true); + Subs.CVar(_cfg, CCVars.CPRAirlossReductionMultiplier, value => AirlossReductionMultiplier = value, true); + } + } +} diff --git a/Content.Shared/Medical/CPR/Systems/CPRSystem.cs b/Content.Shared/Medical/CPR/Systems/CPRSystem.cs new file mode 100644 index 00000000000..799c0664a66 --- /dev/null +++ b/Content.Shared/Medical/CPR/Systems/CPRSystem.cs @@ -0,0 +1,132 @@ +using Content.Shared.Popups; +using Content.Shared.Atmos.Rotting; +using Content.Shared.Damage; +using Content.Shared.DoAfter; +using Content.Shared.Inventory; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Components; +using Content.Shared.Mobs.Systems; +using Content.Shared.Verbs; +using Robust.Shared.Network; +using Robust.Shared.Utility; +using Robust.Shared.Random; +using Robust.Shared.Audio.Systems; + +namespace Content.Shared.Medical.CPR +{ + public sealed partial class CPRSystem : EntitySystem + { + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; + [Dependency] private readonly MobStateSystem _mobStateSystem = default!; + [Dependency] private readonly DamageableSystem _damageable = default!; + [Dependency] private readonly MobThresholdSystem _mobThreshold = default!; + [Dependency] private readonly IRobustRandom _robustRandom = default!; + [Dependency] private readonly SharedRottingSystem _rottingSystem = default!; + [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly INetManager _net = default!; + public override void Initialize() + { + base.Initialize(); + InitializeCVars(); + SubscribeLocalEvent>(AddCPRVerb); + SubscribeLocalEvent(OnCPRDoAfter); + } + + private void AddCPRVerb(EntityUid uid, CPRTrainingComponent component, GetVerbsEvent args) + { + if (!EnableCPR || !args.CanInteract || !args.CanAccess + || !TryComp(args.Target, out var targetState) + || targetState.CurrentState == MobState.Alive) + return; + + InnateVerb verb = new() + { + Act = () => + { + StartCPR(uid, args.Target, component); + }, + Text = Loc.GetString("cpr-verb"), + Icon = new SpriteSpecifier.Rsi(new("Interface/Alerts/human_alive.rsi"), "health4"), + Priority = 2 + }; + args.Verbs.Add(verb); + } + + private void StartCPR(EntityUid performer, EntityUid target, CPRTrainingComponent cprComponent) + { + if (HasComp(target)) + { + _popupSystem.PopupEntity(Loc.GetString("cpr-target-rotting", ("entity", target)), performer, performer); + return; + } + + if (_inventory.TryGetSlotEntity(target, "outerClothing", out var outer)) + { + _popupSystem.PopupEntity(Loc.GetString("cpr-must-remove", ("clothing", outer)), performer, performer, PopupType.MediumCaution); + return; + } + + if (_inventory.TryGetSlotEntity(target, "mask", out var mask)) + { + _popupSystem.PopupEntity(Loc.GetString("cpr-must-remove", ("clothing", mask)), performer, performer, PopupType.MediumCaution); + return; + } + + if (_inventory.TryGetSlotEntity(performer, "mask", out var maskSelf)) + { + _popupSystem.PopupEntity(Loc.GetString("cpr-must-remove-own-mask", ("clothing", maskSelf)), performer, performer, PopupType.MediumCaution); + return; + } + + if (_net.IsServer) + { + _popupSystem.PopupEntity(Loc.GetString("cpr-start-second-person", ("target", target)), target, performer, PopupType.Medium); + _popupSystem.PopupEntity(Loc.GetString("cpr-start-second-person-patient", ("user", performer)), target, target, PopupType.Medium); + cprComponent.CPRPlayingStream = _audio.PlayPvs(cprComponent.CPRSound, performer).Value.Entity; + } + + _doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager, performer, cprComponent.DoAfterDuration, new CPRDoAfterEvent(), performer, target, performer) + { + BreakOnTargetMove = true, + BreakOnUserMove = true, + NeedHand = true, + BlockDuplicate = true + }); + } + + private void OnCPRDoAfter(EntityUid performer, CPRTrainingComponent component, CPRDoAfterEvent args) + { + component.CPRPlayingStream = _audio.Stop(component.CPRPlayingStream); + + if (args.Target == null) + return; + + if (HealsAirloss) + { + // There is PROBABLY a better way to do this, by all means let me know + var healing = new DamageSpecifier() + { + DamageDict = new() + { + { "Asphyxiation", -component.AirlossHeal * AirlossReductionMultiplier} + } + }; + _damageable.TryChangeDamage(args.Target, healing, true, origin: performer); + } + + if (ReducesRot) + _rottingSystem.ReduceAccumulator((EntityUid) args.Target, component.DoAfterDuration * RotReductionMultiplier); + + if (_robustRandom.Prob(ResuscitationChance) + && _mobThreshold.TryGetThresholdForState((EntityUid) args.Target, MobState.Dead, out var threshold) + && TryComp(args.Target, out var damageableComponent) + && TryComp(args.Target, out var state) + && damageableComponent.TotalDamage < threshold) + { + _mobStateSystem.ChangeMobState(args.Target.Value, MobState.Critical, state, performer); + } + } + } +} diff --git a/Resources/Audio/Effects/CPR.ogg b/Resources/Audio/Effects/CPR.ogg new file mode 100644 index 0000000000000000000000000000000000000000..2c7cedd2033c906029dcd1a8d90ab45b68bb0eba GIT binary patch literal 68840 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.mL>w?>>sa5J>hq2ux0H{*l6BSYS#*3Iz* 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

UUXQ{C-_~qG0dZv#l zCq_`E1x}SXgE`LQ zbrkgM_!ki11;k1qn1qlZ>3gGrlgiLc#;m7K+btJxRUTw*KY!M+G`4Gt zL!o!!t=q2pemc#DBobXk8@LecZ1vX+_U7cn-s3Nuw@%JLOx~W!vzwR2bO^gmY#ziR zUK28rv(w!%)+>qaP>q0wG|pQ;ayN|XGy)-K(|n*6JhSMK^}`F;Gat8djN-&9FH=U! zsK3F?$t=T;b=4`y+%#7bn0I?kP%P>~@yAbAJQn=iG=p{a8IT`UnE>*YwrMn$s#oO5 z6iX+$Om%$BuDNgi;4^=+4O`#AosL~gZ`25mst4u!QO5{fn{Aw>=I2~KYu4*$`>aF< zbDaIJ<%@4cdef;_BOB-{)ka=X;=rvhAHaElEJ}-Cge??rQT1Bep`4 z!1bNMLnhXf^IT+eXG*#(G(xB&sGsoAVnit6VgDJan8Bk4j?{f?<(_{#p~^jeN+mmo zGjPAi%Fd`+hRUKI1anaj?b928=EI88MEdokw_o2lKr4qJXd)+7R^F?3vf9ZSx|Q)G%#oW)tK_F)G}i&WSGGgV`sud z@r&}eb`%(1F&@sw@a0-a7d_o{$3&06>Ph{Bc)?bOqvA$`en>yJUJO-l^t=q%U1`WL z&qmmLx9pS}1!N15KFR3mckDlFz1VA(*~nVgEZvv#^SJ1MKUePm&`;*)_Q5%%&-gK(#xusMm618_PK{3@q~EU~XZe$M&vt;f`H3MH)H${hE|8*v&w7%IHE zPrkO={i3yfl-3lldHS4xJjzgBp&%7|R^q$$kp%K$)Rj6lJJX{zYT7qr)bh~8*I|OQ z&L4bMQ=tOvb)D@n{%fE!#gpQp$R{n7&enr!dSA4fthW9_%PR7IG)munD@O8?ip}58 zca0nu96BFafheG3^VgdK=Q%hmS(?upPCSZIhtCMT-uYi{(qMOW6`rGjAR;NjPF{u*AI~i89u%rBwDN`}Qeqk4b3f(A;2d zDH3A|Ri0Lh6oH_qWe4p=I3}vleR@IH16MxdA)A{vzv6*shF6v7j2rEF`SBaE10h|Z*(!2 ze~QwpJ)Sy=2YaX)ZgcPMDT`6<@f zg%_l-DW-TWxzD}PFlbg;_7oJW+6ek9H{b>|QHofMuIW6{&+GnW`RMH3^SKbY_2tkO zvn}aqp|=Vr5&S0k2&RTn(u?#vW(9ou0$4mYcreMDiSf8$7q1eJx^zT5us!&vy;(f?OFBw;9M`vdbK zK{?81CVms{)hG|uU0UO)g_fji5c8?fnu0Eh| zkLwv}W6It$n=sDMD!>=$$m#9M2_s61?#A{)7m9y1`eG&pEwWz&ak0>}+{#72V%ud; zjgxJpME!VWj%M=@>MwT-tb^P>tC6n8JduY^!cRcVGkeb`U?!F%0DR4#*wG66TX&!Z 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 literal 0 HcmV?d00001 diff --git a/Resources/Locale/en-US/medical/components/cpr-training-component.ftl b/Resources/Locale/en-US/medical/components/cpr-training-component.ftl new file mode 100644 index 00000000000..7ed824a369f --- /dev/null +++ b/Resources/Locale/en-US/medical/components/cpr-training-component.ftl @@ -0,0 +1,6 @@ +cpr-start-second-person = You start performing CPR on {CAPITALIZE($target)}. +cpr-start-second-person-patient = {CAPITALIZE(THE($user))} starts performing CPR on you. +cpr-must-remove = You must remove {THE($clothing)} from the patient. +cpr-must-remove-own-mask = You must remove your {THE($clothing)}. +cpr-target-rotting = {CAPITALIZE($entity)} is too far gone... +cpr-verb = Perform CPR diff --git a/Resources/Locale/en-US/traits/traits.ftl b/Resources/Locale/en-US/traits/traits.ftl index 600a9834fd4..f4c4b158fce 100644 --- a/Resources/Locale/en-US/traits/traits.ftl +++ b/Resources/Locale/en-US/traits/traits.ftl @@ -35,6 +35,13 @@ trait-description-Stutter = You t-t-talk with a bit of a s-s-stutter... trait-name-Snoring = Snoring trait-description-Snoring = You will snore while sleeping. +trait-name-CPRTraining = CPR Training +trait-description-CPRTraining = At some point in your life, you have received training in how to perform CPR. + This trait is automatically given for free to medical doctors, and is intended for non-medical characters + +trait-name-NormalVisionHarpy = Trichromat Modification +trait-description-NormalVisionHarpy = Your eyes have been modified by means of advanced medicine to see in the standard colors of Red, Green, and Blue. + trait-name-Southern = Southern Drawl trait-description-Southern = You have a different way of speakin'. diff --git a/Resources/Prototypes/DeltaV/Roles/Jobs/Security/brigmedic.yml b/Resources/Prototypes/DeltaV/Roles/Jobs/Security/brigmedic.yml index daf7f1195c0..f4b2fe95e14 100644 --- a/Resources/Prototypes/DeltaV/Roles/Jobs/Security/brigmedic.yml +++ b/Resources/Prototypes/DeltaV/Roles/Jobs/Security/brigmedic.yml @@ -26,6 +26,9 @@ special: - !type:AddImplantSpecial implants: [ MindShieldImplant ] + - !type:AddComponentSpecial + components: + - type: CPRTraining - type: startingGear id: CorpsmanGear # see Prototypes/Roles/Jobs/Fun/misc_startinggear.yml for "BrigmedicGear" diff --git a/Resources/Prototypes/Roles/Jobs/Medical/chemist.yml b/Resources/Prototypes/Roles/Jobs/Medical/chemist.yml index 3fe22792092..66466352cbe 100644 --- a/Resources/Prototypes/Roles/Jobs/Medical/chemist.yml +++ b/Resources/Prototypes/Roles/Jobs/Medical/chemist.yml @@ -14,6 +14,10 @@ - Medical - Chemistry - Maintenance + special: + - !type:AddComponentSpecial + components: + - type: CPRTraining - type: startingGear id: ChemistGear diff --git a/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml b/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml index 4a65b791283..61b1df7784f 100644 --- a/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml +++ b/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml @@ -44,6 +44,7 @@ components: - type: PsionicBonusChance #Nyano - Summary: makes it more likely to become psionic. flatBonus: 0.025 + - type: CPRTraining - type: startingGear id: CMOGear diff --git a/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml b/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml index cc048470f0c..627b0e17dc3 100644 --- a/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml +++ b/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml @@ -16,6 +16,10 @@ extendedAccess: - Chemistry - Paramedic # DeltaV - Add Paramedic access + special: + - !type:AddComponentSpecial + components: + - type: CPRTraining - type: startingGear id: DoctorGear diff --git a/Resources/Prototypes/Roles/Jobs/Medical/medical_intern.yml b/Resources/Prototypes/Roles/Jobs/Medical/medical_intern.yml index 0166a3dfadb..003eab22d25 100644 --- a/Resources/Prototypes/Roles/Jobs/Medical/medical_intern.yml +++ b/Resources/Prototypes/Roles/Jobs/Medical/medical_intern.yml @@ -15,6 +15,10 @@ access: - Medical - Maintenance + special: + - !type:AddComponentSpecial + components: + - type: CPRTraining - type: startingGear id: MedicalInternGear diff --git a/Resources/Prototypes/Roles/Jobs/Medical/paramedic.yml b/Resources/Prototypes/Roles/Jobs/Medical/paramedic.yml index 9e3484a8dcf..0937a4627ae 100644 --- a/Resources/Prototypes/Roles/Jobs/Medical/paramedic.yml +++ b/Resources/Prototypes/Roles/Jobs/Medical/paramedic.yml @@ -23,6 +23,10 @@ - Paramedic # DeltaV - Add Paramedic access extendedAccess: - Chemistry + special: + - !type:AddComponentSpecial + components: + - type: CPRTraining - type: startingGear id: ParamedicGear diff --git a/Resources/Prototypes/Roles/Jobs/Medical/senior_physician.yml b/Resources/Prototypes/Roles/Jobs/Medical/senior_physician.yml index ac6e0620f5a..d13fd18afdd 100644 --- a/Resources/Prototypes/Roles/Jobs/Medical/senior_physician.yml +++ b/Resources/Prototypes/Roles/Jobs/Medical/senior_physician.yml @@ -21,6 +21,10 @@ - Medical - Maintenance - Chemistry + special: + - !type:AddComponentSpecial + components: + - type: CPRTraining - type: startingGear id: SeniorPhysicianGear diff --git a/Resources/Prototypes/Traits/skills.yml b/Resources/Prototypes/Traits/skills.yml index 16b628a56d8..b23e0216224 100644 --- a/Resources/Prototypes/Traits/skills.yml +++ b/Resources/Prototypes/Traits/skills.yml @@ -1,3 +1,20 @@ +- type: trait + id: CPRTraining + category: Mental + points: -2 + components: + - type: CPRTraining + requirements: + - !type:CharacterJobRequirement + inverted: true + jobs: + - MedicalDoctor + - Chemist + - MedicalIntern + - Paramedic + - ChiefMedicalOfficer + - Brigmedic + - type: trait id: HeavyweightDrunk category: Physical From b1674d169148573dfcc11a26156c1a4559672337 Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Tue, 6 Aug 2024 05:29:22 +0000 Subject: [PATCH 06/32] Automatic Changelog Update (#487) --- Resources/Changelog/Changelog.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index afe00fec1f2..e294394372d 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -4948,3 +4948,15 @@ Entries: message: Oneirophages are back! id: 6219 time: '2024-08-06T04:52:32.0000000+00:00' +- author: VMSolidus + changes: + - type: Add + message: >- + CPR has been added to the game. People with CPR training can now perform + CPR on anyone who is in either crit or dead states. + - type: Add + message: >- + CPR Training has been added to the game as a new positive trait. All + medical staff start with this trait for free. + id: 6220 + time: '2024-08-06T05:28:54.0000000+00:00' From 22ff27c0985a04bf16a4e567326dfbd4ada4450e Mon Sep 17 00:00:00 2001 From: Angelo Fallaria Date: Tue, 6 Aug 2024 16:05:58 +0800 Subject: [PATCH 07/32] New Trait: Self-Aware (#680) # Description **Self-Aware** is a 2-point Mental trait that allows you to precisely examine your Brute/Burn damage as if using a health analyzer, and estimate the level of your toxin/airloss damage. Inspired by the SS13 trait of the same name. ## Media

Expand **Trait entry** ![image](https://github.com/user-attachments/assets/8faae16f-7dd5-42cd-8332-c65a0c610429) **No damage** ![image](https://github.com/user-attachments/assets/72bfa0f4-57fa-4b8d-b974-a604b4030ea6) **Damaged** ![image](https://github.com/user-attachments/assets/ec6318b4-41dc-4d3b-9aec-8f02333363e7)
# Changelog :cl: Skubman add: Add the Self-Aware trait, a 2-point trait that allows you to examine your Brute/Burn damage numbers like a health analyzer, and estimate your toxin/airloss damage. --------- Signed-off-by: Angelo Fallaria Co-authored-by: VMSolidus --- .../Body/Systems/BloodstreamSystem.cs | 15 ++- .../HealthExaminableComponent.cs | 8 +- .../HealthExaminableSystem.cs | 116 +++++++++++++++++- .../Traits/Assorted/SelfAwareComponent.cs | 31 +++++ .../Locale/en-US/bloodstream/bloodstream.ftl | 4 + .../health-examinable-selfaware.ftl | 22 ++++ Resources/Locale/en-US/traits/traits.ftl | 6 + Resources/Prototypes/Traits/skills.yml | 18 +++ 8 files changed, 210 insertions(+), 10 deletions(-) create mode 100644 Content.Server/Traits/Assorted/SelfAwareComponent.cs create mode 100644 Resources/Locale/en-US/health-examinable/health-examinable-selfaware.ftl diff --git a/Content.Server/Body/Systems/BloodstreamSystem.cs b/Content.Server/Body/Systems/BloodstreamSystem.cs index 9e29fdf7568..0edb190c16e 100644 --- a/Content.Server/Body/Systems/BloodstreamSystem.cs +++ b/Content.Server/Body/Systems/BloodstreamSystem.cs @@ -242,20 +242,29 @@ private void OnHealthBeingExamined(Entity ent, ref HealthB if (ent.Comp.BleedAmount > ent.Comp.MaxBleedAmount / 2) { args.Message.PushNewline(); - args.Message.AddMarkup(Loc.GetString("bloodstream-component-profusely-bleeding", ("target", ent.Owner))); + if (!args.IsSelfAware) + args.Message.AddMarkup(Loc.GetString("bloodstream-component-profusely-bleeding", ("target", ent.Owner))); + else + args.Message.AddMarkup(Loc.GetString("bloodstream-component-selfaware-profusely-bleeding")); } // Shows bleeding message when bleeding, but less than profusely. else if (ent.Comp.BleedAmount > 0) { args.Message.PushNewline(); - args.Message.AddMarkup(Loc.GetString("bloodstream-component-bleeding", ("target", ent.Owner))); + if (!args.IsSelfAware) + args.Message.AddMarkup(Loc.GetString("bloodstream-component-bleeding", ("target", ent.Owner))); + else + args.Message.AddMarkup(Loc.GetString("bloodstream-component-selfaware-bleeding")); } // If the mob's blood level is below the damage threshhold, the pale message is added. if (GetBloodLevelPercentage(ent, ent) < ent.Comp.BloodlossThreshold) { args.Message.PushNewline(); - args.Message.AddMarkup(Loc.GetString("bloodstream-component-looks-pale", ("target", ent.Owner))); + if (!args.IsSelfAware) + args.Message.AddMarkup(Loc.GetString("bloodstream-component-looks-pale", ("target", ent.Owner))); + else + args.Message.AddMarkup(Loc.GetString("bloodstream-component-selfaware-looks-pale")); } } diff --git a/Content.Server/HealthExaminable/HealthExaminableComponent.cs b/Content.Server/HealthExaminable/HealthExaminableComponent.cs index 3f434a93cfe..04053aed70e 100644 --- a/Content.Server/HealthExaminable/HealthExaminableComponent.cs +++ b/Content.Server/HealthExaminable/HealthExaminableComponent.cs @@ -1,4 +1,4 @@ -using Content.Shared.Damage.Prototypes; +using Content.Shared.Damage.Prototypes; using Content.Shared.FixedPoint; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set; @@ -7,8 +7,12 @@ namespace Content.Server.HealthExaminable; [RegisterComponent, Access(typeof(HealthExaminableSystem))] public sealed partial class HealthExaminableComponent : Component { + // + // The thresholds for determining the examine text for certain amounts of damage. + // These are calculated as a percentage of the entity's critical threshold. + // public List Thresholds = new() - { FixedPoint2.New(10), FixedPoint2.New(25), FixedPoint2.New(50), FixedPoint2.New(75) }; + { FixedPoint2.New(0.10), FixedPoint2.New(0.25), FixedPoint2.New(0.50), FixedPoint2.New(0.75) }; [DataField("examinableTypes", required: true, customTypeSerializer:typeof(PrototypeIdHashSetSerializer))] public HashSet ExaminableTypes = default!; diff --git a/Content.Server/HealthExaminable/HealthExaminableSystem.cs b/Content.Server/HealthExaminable/HealthExaminableSystem.cs index ed69a1c096a..89291726fbe 100644 --- a/Content.Server/HealthExaminable/HealthExaminableSystem.cs +++ b/Content.Server/HealthExaminable/HealthExaminableSystem.cs @@ -1,15 +1,20 @@ -using Content.Shared.Damage; +using Content.Server.Traits.Assorted; +using Content.Shared.Damage; using Content.Shared.Examine; using Content.Shared.FixedPoint; using Content.Shared.IdentityManagement; +using Content.Shared.Mobs.Components; +using Content.Shared.Mobs.Systems; using Content.Shared.Verbs; using Robust.Shared.Utility; +using System.Linq; namespace Content.Server.HealthExaminable; public sealed class HealthExaminableSystem : EntitySystem { [Dependency] private readonly ExamineSystemShared _examineSystem = default!; + [Dependency] private readonly MobThresholdSystem _threshold = default!; public override void Initialize() { @@ -29,7 +34,13 @@ private void OnGetExamineVerbs(EntityUid uid, HealthExaminableComponent componen { Act = () => { - var markup = CreateMarkup(uid, component, damage); + FormattedMessage markup; + if (uid == args.User + && TryComp(uid, out var selfAware)) + markup = CreateMarkupSelfAware(uid, selfAware, component, damage); + else + markup = CreateMarkup(uid, component, damage); + _examineSystem.SendExamineTooltip(args.User, uid, markup, false, false); }, Text = Loc.GetString("health-examinable-verb-text"), @@ -47,6 +58,9 @@ private FormattedMessage CreateMarkup(EntityUid uid, HealthExaminableComponent c var msg = new FormattedMessage(); var first = true; + + var adjustedThresholds = GetAdjustedThresholds(uid, component.Thresholds); + foreach (var type in component.ExaminableTypes) { if (!damage.Damage.DamageDict.TryGetValue(type, out var dmg)) @@ -58,7 +72,7 @@ private FormattedMessage CreateMarkup(EntityUid uid, HealthExaminableComponent c FixedPoint2 closest = FixedPoint2.Zero; string chosenLocStr = string.Empty; - foreach (var threshold in component.Thresholds) + foreach (var threshold in adjustedThresholds) { var str = $"health-examinable-{component.LocPrefix}-{type}-{threshold}"; var tempLocStr = Loc.GetString($"health-examinable-{component.LocPrefix}-{type}-{threshold}", ("target", Identity.Entity(uid, EntityManager))); @@ -94,10 +108,100 @@ private FormattedMessage CreateMarkup(EntityUid uid, HealthExaminableComponent c } // Anything else want to add on to this? - RaiseLocalEvent(uid, new HealthBeingExaminedEvent(msg), true); + RaiseLocalEvent(uid, new HealthBeingExaminedEvent(msg, false), true); return msg; } + + private FormattedMessage CreateMarkupSelfAware(EntityUid target, SelfAwareComponent selfAware, HealthExaminableComponent component, DamageableComponent damage) + { + var msg = new FormattedMessage(); + + var first = true; + + foreach (var type in selfAware.AnalyzableTypes) + { + if (!damage.Damage.DamageDict.TryGetValue(type, out var typeDmgUnrounded)) + continue; + + var typeDmg = (int) Math.Round(typeDmgUnrounded.Float(), 0); + if (typeDmg <= 0) + continue; + + var damageString = Loc.GetString( + "health-examinable-selfaware-type-text", + ("damageType", Loc.GetString($"health-examinable-selfaware-type-{type}")), + ("amount", typeDmg) + ); + + if (!first) + msg.PushNewline(); + else + first = false; + msg.AddMarkup(damageString); + } + + var adjustedThresholds = GetAdjustedThresholds(target, selfAware.Thresholds); + + foreach (var group in selfAware.DetectableGroups) + { + if (!damage.DamagePerGroup.TryGetValue(group, out var groupDmg) + || groupDmg == FixedPoint2.Zero) + continue; + + FixedPoint2 closest = FixedPoint2.Zero; + + string chosenLocStr = string.Empty; + foreach (var threshold in adjustedThresholds) + { + var locName = $"health-examinable-selfaware-group-{group}-{threshold}"; + var locStr = Loc.GetString(locName); + + var locDoesNotExist = locStr == locName; + if (locDoesNotExist) + continue; + + if (groupDmg > threshold && threshold > closest) + { + chosenLocStr = locStr; + closest = threshold; + } + } + + if (closest == FixedPoint2.Zero) + continue; + + if (!first) + msg.PushNewline(); + else + first = false; + msg.AddMarkup(chosenLocStr); + } + + if (msg.IsEmpty) + msg.AddMarkup(Loc.GetString($"health-examinable-selfaware-none")); + + // Event listeners can know if the examination is Self-Aware. + RaiseLocalEvent(target, new HealthBeingExaminedEvent(msg, true), true); + + return msg; + } + + /// + /// Return thresholds as percentages of an entity's critical threshold. + /// + private List GetAdjustedThresholds(EntityUid uid, List thresholdPercentages) + { + FixedPoint2 critThreshold = 0; + if (TryComp(uid, out var threshold)) + critThreshold = _threshold.GetThresholdForState(uid, Shared.Mobs.MobState.Critical, threshold); + + // Fallback to 100 crit threshold if none found + if (critThreshold == 0) + critThreshold = 100; + + return thresholdPercentages.Select(percentage => critThreshold * percentage).ToList(); + } } /// @@ -108,9 +212,11 @@ private FormattedMessage CreateMarkup(EntityUid uid, HealthExaminableComponent c public sealed class HealthBeingExaminedEvent { public FormattedMessage Message; + public bool IsSelfAware; - public HealthBeingExaminedEvent(FormattedMessage message) + public HealthBeingExaminedEvent(FormattedMessage message, bool isSelfAware) { Message = message; + IsSelfAware = isSelfAware; } } diff --git a/Content.Server/Traits/Assorted/SelfAwareComponent.cs b/Content.Server/Traits/Assorted/SelfAwareComponent.cs new file mode 100644 index 00000000000..03f5cd15502 --- /dev/null +++ b/Content.Server/Traits/Assorted/SelfAwareComponent.cs @@ -0,0 +1,31 @@ +using Content.Shared.Damage.Prototypes; +using Content.Shared.FixedPoint; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set; + +namespace Content.Server.Traits.Assorted; + +/// +/// This is used for the Self-Aware trait to enhance the information received from HealthExaminableSystem. +/// +[RegisterComponent] +public sealed partial class SelfAwareComponent : Component +{ + // + // Damage types that an entity is able to precisely analyze like a health analyzer when they examine themselves. + // + [DataField(required: true, customTypeSerializer:typeof(PrototypeIdHashSetSerializer))] + public HashSet AnalyzableTypes = default!; + + // + // Damage groups that an entity is able to detect the presence of when they examine themselves. + // + [DataField(required: true, customTypeSerializer:typeof(PrototypeIdHashSetSerializer))] + public HashSet DetectableGroups = default!; + + // + // The thresholds for determining the examine text of DetectableGroups for certain amounts of damage. + // These are calculated as a percentage of the entity's critical threshold. + // + public List Thresholds = new() + { FixedPoint2.New(0.10), FixedPoint2.New(0.25), FixedPoint2.New(0.40), FixedPoint2.New(0.60) }; +} diff --git a/Resources/Locale/en-US/bloodstream/bloodstream.ftl b/Resources/Locale/en-US/bloodstream/bloodstream.ftl index 7d8f98c3087..65e475f1ab4 100644 --- a/Resources/Locale/en-US/bloodstream/bloodstream.ftl +++ b/Resources/Locale/en-US/bloodstream/bloodstream.ftl @@ -3,3 +3,7 @@ bloodstream-component-bleeding = [color=red]{CAPITALIZE(SUBJECT($target))} {CONJ bloodstream-component-profusely-bleeding = [color=crimson]{CAPITALIZE(SUBJECT($target))} {CONJUGATE-BE($target)} profusely bleeding![/color] bloodstream-component-wounds-cauterized = You feel your wounds painfully close! + +bloodstream-component-selfaware-looks-pale = [color=bisque]You feel dizzy from blood loss.[/color] +bloodstream-component-selfaware-bleeding = [color=red]You are bleeding.[/color] +bloodstream-component-selfaware-profusely-bleeding = [color=crimson]You are profusely bleeding![/color] diff --git a/Resources/Locale/en-US/health-examinable/health-examinable-selfaware.ftl b/Resources/Locale/en-US/health-examinable/health-examinable-selfaware.ftl new file mode 100644 index 00000000000..897c3f718de --- /dev/null +++ b/Resources/Locale/en-US/health-examinable/health-examinable-selfaware.ftl @@ -0,0 +1,22 @@ +health-examinable-selfaware-none = You feel healthy and well. + +health-examinable-selfaware-type-text = You have {$damageType}, around [bold]{$amount}[/bold]. + +health-examinable-selfaware-type-Blunt = [color=red]Blunt[/color] trauma +health-examinable-selfaware-type-Slash = [color=red]Slash[/color] wounds +health-examinable-selfaware-type-Piercing = [color=red]Piercing[/color] wounds + +health-examinable-selfaware-type-Heat = [color=orange]Heat[/color] burns +health-examinable-selfaware-type-Shock = [color=lightgoldenrodyellow]Shock[/color] burns +health-examinable-selfaware-type-Cold = [color=lightblue]Cold[/color] burns +health-examinable-selfaware-type-Caustic = [color=yellowgreen]Caustic[/color] burns + +health-examinable-selfaware-group-Toxin-10 = [color=green]You feel sick.[/color] +health-examinable-selfaware-group-Toxin-25 = [color=green]You feel nauseated.[/color] +health-examinable-selfaware-group-Toxin-40 = [color=green]You feel very unwell![/color] +health-examinable-selfaware-group-Toxin-60 = [color=green]You feel gravely ill![/color] + +health-examinable-selfaware-group-Airloss-10 = [color=lightblue]You feel lightheaded.[/color] +health-examinable-selfaware-group-Airloss-25 = [color=lightblue]You feel faint and woozy.[/color] +health-examinable-selfaware-group-Airloss-40 = [color=lightblue]You're struggling to breathe![/color] +health-examinable-selfaware-group-Airloss-60 = [color=lightblue]You're suffocating badly![/color] diff --git a/Resources/Locale/en-US/traits/traits.ftl b/Resources/Locale/en-US/traits/traits.ftl index f4c4b158fce..07ef099f832 100644 --- a/Resources/Locale/en-US/traits/traits.ftl +++ b/Resources/Locale/en-US/traits/traits.ftl @@ -8,6 +8,12 @@ trait-description-Narcolepsy = You fall asleep randomly trait-name-Pacifist = Pacifist trait-description-Pacifist = You cannot attack or hurt any living beings. +trait-name-SelfAware = Self-Aware +trait-description-SelfAware = + You possess a keen intuition of your body and senses. + You can accurately examine the severity of your wounds and burns like a health analyzer, + and can gauge if you have toxin or airloss damage. + trait-name-LightweightDrunk = Lightweight Drunk trait-description-LightweightDrunk = Alcohol has a stronger effect on you diff --git a/Resources/Prototypes/Traits/skills.yml b/Resources/Prototypes/Traits/skills.yml index b23e0216224..6d10886e8fa 100644 --- a/Resources/Prototypes/Traits/skills.yml +++ b/Resources/Prototypes/Traits/skills.yml @@ -15,6 +15,24 @@ - ChiefMedicalOfficer - Brigmedic +- type: trait + id: SelfAware + category: Mental + points: -2 + components: + - type: SelfAware + analyzableTypes: + - Blunt + - Slash + - Piercing + - Heat + - Shock + - Cold + - Caustic + detectableGroups: + - Airloss + - Toxin + - type: trait id: HeavyweightDrunk category: Physical From 5fcec4720ed3fb3697aa3517ce7fcfb3228493ae Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Tue, 6 Aug 2024 08:06:27 +0000 Subject: [PATCH 08/32] Automatic Changelog Update (#680) --- Resources/Changelog/Changelog.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index e294394372d..01f1a833faf 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -4960,3 +4960,12 @@ Entries: medical staff start with this trait for free. id: 6220 time: '2024-08-06T05:28:54.0000000+00:00' +- author: Skubman + changes: + - type: Add + message: >- + Add the Self-Aware trait, a 2-point trait that allows you to examine + your Brute/Burn damage numbers like a health analyzer, and estimate your + toxin/airloss damage. + id: 6221 + time: '2024-08-06T08:05:59.0000000+00:00' From 498d070a73227dedb9e08636a6f574682b86f0d3 Mon Sep 17 00:00:00 2001 From: "Tad \"Taddy\" Johnson" <120885811+TadJohnson00@users.noreply.github.com> Date: Wed, 7 Aug 2024 05:05:46 +1000 Subject: [PATCH 09/32] Remove Overlay Restrict From Vulps (#683) # Description As title, will allow players to put as many overlay markings as required for their vulps. --- # Changelog :cl: TJohnson - tweak: Removed overlay restriction for vulps, you can now have as many overlay markings as you want! Signed-off-by: Tad "Taddy" Johnson <120885811+TadJohnson00@users.noreply.github.com> --- Resources/Prototypes/DeltaV/Species/vulpkanin.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/Resources/Prototypes/DeltaV/Species/vulpkanin.yml b/Resources/Prototypes/DeltaV/Species/vulpkanin.yml index 8a3cd4c47ce..e139279dd5c 100644 --- a/Resources/Prototypes/DeltaV/Species/vulpkanin.yml +++ b/Resources/Prototypes/DeltaV/Species/vulpkanin.yml @@ -62,9 +62,6 @@ points: 1 required: true defaultMarkings: [ VulpEar ] - Overlay: - points: 2 - required: false - type: humanoidBaseSprite id: MobVulpkaninHead From cb3ddd458132809a21f0bfc38028f0ed79795b83 Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Tue, 6 Aug 2024 19:06:41 +0000 Subject: [PATCH 10/32] Automatic Changelog Update (#683) --- Resources/Changelog/Changelog.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 01f1a833faf..39fcb78cfa7 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -4969,3 +4969,11 @@ Entries: toxin/airloss damage. id: 6221 time: '2024-08-06T08:05:59.0000000+00:00' +- author: TJohnson + changes: + - type: Tweak + message: >- + Removed overlay restriction for vulps, you can now have as many overlay + markings as you want! + id: 6222 + time: '2024-08-06T19:05:46.0000000+00:00' From 55aa822a96f2ef8777e3b17efff0d4b4860b7010 Mon Sep 17 00:00:00 2001 From: username <113782077+whateverusername0@users.noreply.github.com> Date: Wed, 7 Aug 2024 05:08:47 +1000 Subject: [PATCH 11/32] Stamina Damage Resistance Real (#679) # Description Added stamina damage resistance, acts the same way as armor does. Call this shock resistance if you wish :trollface: Just attach StaminaDamageResistance component to an entity with a set multiplier and have fun. Made all hardsuits 25% stun resistant by default. With some variety, e.g. nukie, ERT, captain, HoS suits are 50%, DS are 90%, etc. etc. This will not remove stuneta but it will make it more difficult to stamcrit a traitor or such. Some armor/batong ratios that you need to hit before the target is stamcritted: 0% - 3 batong hits 25% - 4 batong hits 50% - 6 batong hits 75% - 12 batong hits 90% - 28 batong hits :trollface: 100% - ![image](https://github.com/user-attachments/assets/da147676-520b-4e3c-b027-ef9dc6a7394b) # Changelog :cl: - add: Added different stamina damage resistance to hardsuits. --------- Co-authored-by: whateverusername0 --- .../Abilities/Boxer/BoxingSystem.cs | 4 +- .../Nyanotrasen/Abilities/Oni/OniSystem.cs | 4 +- .../Nyanotrasen/Psionics/PsionicsSystem.cs | 12 +++-- ...eHitEvent.cs => TakeStaminaDamageEvent.cs} | 12 ++--- .../Damage/Systems/StaminaSystem.cs | 35 ++++++++++----- .../Inventory/InventorySystem.Relay.cs | 2 + .../StaminaDamageResistanceComponent.cs | 12 +++++ .../StaminaDamageResistanceSystem.cs | 26 +++++++++++ .../Locale/en-US/armor/armor-examine.ftl | 1 + .../OuterClothing/base_clothingouter.yml | 2 + .../Clothing/OuterClothing/hardsuits.yml | 44 +++++++++++++++++++ 11 files changed, 128 insertions(+), 26 deletions(-) rename Content.Shared/Damage/Events/{StaminaMeleeHitEvent.cs => TakeStaminaDamageEvent.cs} (67%) create mode 100644 Content.Shared/Stunnable/StaminaDamageResistanceComponent.cs create mode 100644 Content.Shared/Stunnable/StaminaDamageResistanceSystem.cs diff --git a/Content.Server/Nyanotrasen/Abilities/Boxer/BoxingSystem.cs b/Content.Server/Nyanotrasen/Abilities/Boxer/BoxingSystem.cs index 8bb68cb6f55..6f533c34199 100644 --- a/Content.Server/Nyanotrasen/Abilities/Boxer/BoxingSystem.cs +++ b/Content.Server/Nyanotrasen/Abilities/Boxer/BoxingSystem.cs @@ -14,7 +14,7 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnMeleeHit); - SubscribeLocalEvent(OnStamHit); + SubscribeLocalEvent(OnStamHit); } private void OnInit(EntityUid uid, BoxerComponent component, ComponentInit args) @@ -27,7 +27,7 @@ private void OnMeleeHit(EntityUid uid, BoxerComponent component, MeleeHitEvent a args.ModifiersList.Add(component.UnarmedModifiers); } - private void OnStamHit(EntityUid uid, BoxingGlovesComponent component, StaminaMeleeHitEvent args) + private void OnStamHit(EntityUid uid, BoxingGlovesComponent component, TakeStaminaDamageEvent args) { if (!_containerSystem.TryGetContainingContainer(uid, out var equipee)) return; diff --git a/Content.Server/Nyanotrasen/Abilities/Oni/OniSystem.cs b/Content.Server/Nyanotrasen/Abilities/Oni/OniSystem.cs index 6fdb27097e9..4fc078e85bc 100644 --- a/Content.Server/Nyanotrasen/Abilities/Oni/OniSystem.cs +++ b/Content.Server/Nyanotrasen/Abilities/Oni/OniSystem.cs @@ -21,7 +21,7 @@ public override void Initialize() SubscribeLocalEvent(OnEntRemoved); SubscribeLocalEvent(OnOniMeleeHit); SubscribeLocalEvent(OnHeldMeleeHit); - SubscribeLocalEvent(OnStamHit); + SubscribeLocalEvent(OnStamHit); } private void OnEntInserted(EntityUid uid, OniComponent component, EntInsertedIntoContainerMessage args) @@ -68,7 +68,7 @@ private void OnHeldMeleeHit(EntityUid uid, HeldByOniComponent component, MeleeHi args.ModifiersList.Add(oni.MeleeModifiers); } - private void OnStamHit(EntityUid uid, HeldByOniComponent component, StaminaMeleeHitEvent args) + private void OnStamHit(EntityUid uid, HeldByOniComponent component, TakeStaminaDamageEvent args) { if (!TryComp(component.Holder, out var oni)) return; diff --git a/Content.Server/Nyanotrasen/Psionics/PsionicsSystem.cs b/Content.Server/Nyanotrasen/Psionics/PsionicsSystem.cs index 5a96af2e96b..33505e3f6fc 100644 --- a/Content.Server/Nyanotrasen/Psionics/PsionicsSystem.cs +++ b/Content.Server/Nyanotrasen/Psionics/PsionicsSystem.cs @@ -51,7 +51,7 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnMeleeHit); - SubscribeLocalEvent(OnStamHit); + SubscribeLocalEvent(OnStamHit); SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnRemove); @@ -110,14 +110,12 @@ private void OnRemove(EntityUid uid, PsionicComponent component, ComponentRemove _npcFactonSystem.RemoveFaction(uid, "PsionicInterloper"); } - private void OnStamHit(EntityUid uid, AntiPsionicWeaponComponent component, StaminaMeleeHitEvent args) + private void OnStamHit(EntityUid uid, AntiPsionicWeaponComponent component, TakeStaminaDamageEvent args) { var bonus = false; - foreach (var stam in args.HitList) - { - if (HasComp(stam.Entity)) - bonus = true; - } + + if (HasComp(args.Target)) + bonus = true; if (!bonus) return; diff --git a/Content.Shared/Damage/Events/StaminaMeleeHitEvent.cs b/Content.Shared/Damage/Events/TakeStaminaDamageEvent.cs similarity index 67% rename from Content.Shared/Damage/Events/StaminaMeleeHitEvent.cs rename to Content.Shared/Damage/Events/TakeStaminaDamageEvent.cs index c5ed0ddb602..6fca9dc2ef3 100644 --- a/Content.Shared/Damage/Events/StaminaMeleeHitEvent.cs +++ b/Content.Shared/Damage/Events/TakeStaminaDamageEvent.cs @@ -1,5 +1,5 @@ using Content.Shared.Damage.Components; -using Robust.Shared.Collections; +using Content.Shared.Inventory; namespace Content.Shared.Damage.Events; @@ -7,12 +7,14 @@ namespace Content.Shared.Damage.Events; /// The components in the list are going to be hit, /// give opportunities to change the damage or other stuff. /// -public sealed class StaminaMeleeHitEvent : HandledEntityEventArgs +public sealed class TakeStaminaDamageEvent : HandledEntityEventArgs, IInventoryRelayEvent { + public SlotFlags TargetSlots { get; } = ~SlotFlags.POCKET; + /// /// List of hit stamina components. /// - public List<(EntityUid Entity, StaminaComponent Component)> HitList; + public EntityUid Target; /// /// The multiplier. Generally, try to use *= or /= instead of overwriting. @@ -24,8 +26,8 @@ public sealed class StaminaMeleeHitEvent : HandledEntityEventArgs /// public float FlatModifier = 0; - public StaminaMeleeHitEvent(List<(EntityUid Entity, StaminaComponent Component)> hitList) + public TakeStaminaDamageEvent(EntityUid target) { - HitList = hitList; + Target = target; } } diff --git a/Content.Shared/Damage/Systems/StaminaSystem.cs b/Content.Shared/Damage/Systems/StaminaSystem.cs index de5338615ee..5c46e6055d1 100644 --- a/Content.Shared/Damage/Systems/StaminaSystem.cs +++ b/Content.Shared/Damage/Systems/StaminaSystem.cs @@ -166,20 +166,20 @@ private void OnMeleeHit(EntityUid uid, StaminaDamageOnHitComponent component, Me toHit.Add((ent, stam)); } - var hitEvent = new StaminaMeleeHitEvent(toHit); - RaiseLocalEvent(uid, hitEvent); + foreach (var (ent, comp) in toHit) + { + var hitEvent = new TakeStaminaDamageEvent(ent); + RaiseLocalEvent(uid, hitEvent); - if (hitEvent.Handled) - return; + if (hitEvent.Handled) + return; - var damage = component.Damage; + var damage = component.Damage; - damage *= hitEvent.Multiplier; + damage *= hitEvent.Multiplier; - damage += hitEvent.FlatModifier; + damage += hitEvent.FlatModifier; - foreach (var (ent, comp) in toHit) - { TakeStaminaDamage(ent, damage / toHit.Count, comp, source: args.User, with: args.Weapon, sound: component.Sound); } } @@ -204,12 +204,27 @@ private void OnThrowHit(EntityUid uid, StaminaDamageOnCollideComponent component private void OnCollide(EntityUid uid, StaminaDamageOnCollideComponent component, EntityUid target) { + if (!TryComp(target, out var stamComp)) + return; + var ev = new StaminaDamageOnHitAttemptEvent(); RaiseLocalEvent(uid, ref ev); if (ev.Cancelled) return; - TakeStaminaDamage(target, component.Damage, source: uid, sound: component.Sound); + var hitEvent = new TakeStaminaDamageEvent(target); + RaiseLocalEvent(target, hitEvent); + + if (hitEvent.Handled) + return; + + var damage = component.Damage; + + damage *= hitEvent.Multiplier; + + damage += hitEvent.FlatModifier; + + TakeStaminaDamage(target, damage, source: uid, sound: component.Sound); } private void SetStaminaAlert(EntityUid uid, StaminaComponent? component = null) diff --git a/Content.Shared/Inventory/InventorySystem.Relay.cs b/Content.Shared/Inventory/InventorySystem.Relay.cs index c43a5885077..3308e881c52 100644 --- a/Content.Shared/Inventory/InventorySystem.Relay.cs +++ b/Content.Shared/Inventory/InventorySystem.Relay.cs @@ -1,5 +1,6 @@ using Content.Shared.Chemistry; using Content.Shared.Damage; +using Content.Shared.Damage.Events; using Content.Shared.Electrocution; using Content.Shared.Explosion; using Content.Shared.Eye.Blinding.Systems; @@ -20,6 +21,7 @@ public partial class InventorySystem public void InitializeRelay() { SubscribeLocalEvent(RelayInventoryEvent); + SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); diff --git a/Content.Shared/Stunnable/StaminaDamageResistanceComponent.cs b/Content.Shared/Stunnable/StaminaDamageResistanceComponent.cs new file mode 100644 index 00000000000..dc291bbe8ba --- /dev/null +++ b/Content.Shared/Stunnable/StaminaDamageResistanceComponent.cs @@ -0,0 +1,12 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Stunnable; + +[RegisterComponent, NetworkedComponent] +public sealed partial class StaminaDamageResistanceComponent : Component +{ + /// + /// 1 - no reduction, 0 - full reduction + /// + [DataField] public float Coefficient = 1; +} diff --git a/Content.Shared/Stunnable/StaminaDamageResistanceSystem.cs b/Content.Shared/Stunnable/StaminaDamageResistanceSystem.cs new file mode 100644 index 00000000000..7632eed504d --- /dev/null +++ b/Content.Shared/Stunnable/StaminaDamageResistanceSystem.cs @@ -0,0 +1,26 @@ +using Content.Shared.Damage.Events; +using Content.Shared.Examine; +using Content.Shared.Inventory; + +namespace Content.Shared.Stunnable; + +public sealed partial class StaminaDamageResistanceSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent>(OnStaminaMeleeHit); + SubscribeLocalEvent(OnExamine); + } + + private void OnStaminaMeleeHit(Entity ent, ref InventoryRelayedEvent args) + { + args.Args.Multiplier *= ent.Comp.Coefficient; + } + private void OnExamine(Entity ent, ref ExaminedEvent args) + { + var percentage = (1 - ent.Comp.Coefficient) * 100; + args.PushMarkup(Loc.GetString("armor-examine-stamina", ("num", percentage))); + } +} diff --git a/Resources/Locale/en-US/armor/armor-examine.ftl b/Resources/Locale/en-US/armor/armor-examine.ftl index d49a1373f28..6dc511e66e5 100644 --- a/Resources/Locale/en-US/armor/armor-examine.ftl +++ b/Resources/Locale/en-US/armor/armor-examine.ftl @@ -17,3 +17,4 @@ armor-damage-type-cold = Cold armor-damage-type-poison = Poison armor-damage-type-shock = Shock armor-damage-type-structural = Structural +armor-examine-stamina = Reduces your stamina damage by [color=cyan]{$num}%[/color]. \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml index 36327fe1f78..d6a2cd446be 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml @@ -142,6 +142,8 @@ - type: Clothing equipDelay: 2.5 # Hardsuits are heavy and take a while to put on/off. unequipDelay: 2.5 + - type: StaminaDamageResistance + coefficient: 0.75 # 25% - type: entity abstract: true diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml index e0d8e7290da..70ab3016469 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml @@ -100,6 +100,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitEngineering + - type: StaminaDamageResistance + coefficient: 0.75 # 25% #Spationaut Hardsuit - type: entity @@ -221,6 +223,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitSecurity + - type: StaminaDamageResistance + coefficient: 0.75 # 25% #Brigmedic Hardsuit - type: entity @@ -248,6 +252,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitBrigmedic + - type: StaminaDamageResistance + coefficient: 0.75 # 25% #Warden's Hardsuit - type: entity @@ -278,6 +284,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitWarden + - type: StaminaDamageResistance + coefficient: 0.65 # 35% #Captain's Hardsuit - type: entity @@ -310,6 +318,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitCap + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Chief Engineer's Hardsuit - type: entity @@ -345,6 +355,8 @@ - type: ClothingGrantComponent component: - type: SupermatterImmune + - type: StaminaDamageResistance + coefficient: 0.65 # 35% #Chief Medical Officer's Hardsuit - type: entity @@ -412,6 +424,8 @@ price: 750 - type: StealTarget stealGroup: ClothingOuterHardsuitRd + - type: StaminaDamageResistance + coefficient: 0.75 # 25% as in "shock resistance" :trollface: #Head of Security's Hardsuit - type: entity @@ -443,6 +457,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitSecurityRed + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Luxury Mining Hardsuit - type: entity @@ -520,6 +536,8 @@ - Hardsuit - WhitelistChameleon - HidesHarpyWings + - type: StaminaDamageResistance + coefficient: 0.5 # 50% # Syndicate Medic Hardsuit - type: entity @@ -539,6 +557,8 @@ - Hardsuit - WhitelistChameleon - HidesHarpyWings + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Syndicate Elite Hardsuit - type: entity @@ -575,6 +595,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitSyndieElite + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Syndicate Commander Hardsuit - type: entity @@ -607,6 +629,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitSyndieCommander + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Cybersun Juggernaut Hardsuit - type: entity @@ -639,6 +663,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitCybersun + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Wizard Hardsuit - type: entity @@ -671,6 +697,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitWizard + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Ling Space Suit - type: entity @@ -766,6 +794,8 @@ clothingPrototype: ClothingHeadHelmetHardsuitPirateCap - type: StaticPrice price: 0 + - type: StaminaDamageResistance + coefficient: 0.75 # 25% #CENTCOMM / ERT HARDSUITS #ERT Leader Hardsuit @@ -781,6 +811,8 @@ sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertleader.rsi - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitERTLeader + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #ERT Chaplain Hardsuit - type: entity @@ -795,6 +827,8 @@ sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertchaplain.rsi - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitERTChaplain + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #ERT Engineer Hardsuit - type: entity @@ -809,6 +843,8 @@ sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertengineer.rsi - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitERTEngineer + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #ERT Medic Hardsuit - type: entity @@ -823,6 +859,8 @@ sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertmedical.rsi - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitERTMedical + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #ERT Security Hardsuit - type: entity @@ -841,6 +879,8 @@ tags: - Hardsuit - WhitelistChameleon + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #ERT Janitor Hardsuit - type: entity @@ -855,6 +895,8 @@ sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertjanitor.rsi - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitERTJanitor + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Deathsquad - type: entity @@ -889,6 +931,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitDeathsquad + - type: StaminaDamageResistance + coefficient: 0.1 # 90% #CBURN Hardsuit - type: entity From b7d30808f78456443343312d16b64ae01ea54d10 Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Tue, 6 Aug 2024 19:09:14 +0000 Subject: [PATCH 12/32] Automatic Changelog Update (#679) --- Resources/Changelog/Changelog.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 39fcb78cfa7..018c5adbd0d 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -4977,3 +4977,9 @@ Entries: markings as you want! id: 6222 time: '2024-08-06T19:05:46.0000000+00:00' +- author: whateverusername0 + changes: + - type: Add + message: Added different stamina damage resistance to hardsuits. + id: 6223 + time: '2024-08-06T19:08:48.0000000+00:00' From 6ab179737b5f42b800ab7436791509e9cc917254 Mon Sep 17 00:00:00 2001 From: Angelo Fallaria Date: Wed, 7 Aug 2024 03:12:33 +0800 Subject: [PATCH 13/32] New Trait: Blood Deficiency (#686) # Description **Blood Deficiency** is a +2 points negative Physical trait that makes you slowly lose blood over time. When left untreated you will die from blood loss. Inspired by the SS13 trait of the same name. Slash/Piercing weapons and bleeding are much more lethal against you. The moment you start taking **any** blood loss damage, you start dying because you can't regenerate blood. Even just two consecutive kitchen knife stabs will make you bleed enough to die slowly unless you immediately apply gauze. Blood packs, iron pills (or copper for Arachnids), and gauze to stop bleeding will help you survive with this trait. Here's how the timeline looks for untreated blood deficiency: - ~0-21 minutes: losing blood slowly - ~21-31 minutes: blood level below 90%, start taking bloodloss damage - ~31-33 minutes: critical - ~34 minutes: death ## Media
Expand **Trait entry** ![image](https://github.com/user-attachments/assets/ea4a0c3c-7c05-45fc-8a32-48957701a246) ![image](https://github.com/user-attachments/assets/37398779-90a4-4f4f-a183-38d806184394) As shown above, even just reducing the blood volume to less than 90% means you will die a slow and painful death.

# Changelog :cl: Skubman - add: Add the Blood Deficiency trait, a new negative trait that makes you slowly lose blood over time. You must routinely receive blood loss treatment to live, and even normally non-lethal bleeding can make you start dying slowly. --- .../Body/Components/BloodstreamComponent.cs | 15 ++++++++++- .../Body/Systems/BloodstreamSystem.cs | 25 +++++++++++++++---- .../Traits/BloodDeficiencyComponent.cs | 14 +++++++++++ .../Traits/BloodDeficiencySystem.cs | 23 +++++++++++++++++ Resources/Locale/en-US/traits/traits.ftl | 5 ++++ Resources/Prototypes/Traits/disabilities.yml | 14 +++++++++++ 6 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 Content.Server/Traits/BloodDeficiencyComponent.cs create mode 100644 Content.Server/Traits/BloodDeficiencySystem.cs diff --git a/Content.Server/Body/Components/BloodstreamComponent.cs b/Content.Server/Body/Components/BloodstreamComponent.cs index 1d8aa9ffd3d..7a4af3e4cc1 100644 --- a/Content.Server/Body/Components/BloodstreamComponent.cs +++ b/Content.Server/Body/Components/BloodstreamComponent.cs @@ -1,5 +1,6 @@ using Content.Server.Body.Systems; using Content.Server.Chemistry.EntitySystems; +using Content.Server.Traits.Assorted; using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Reagent; using Content.Shared.Damage; @@ -11,7 +12,7 @@ namespace Content.Server.Body.Components { - [RegisterComponent, Access(typeof(BloodstreamSystem), typeof(ReactionMixerSystem))] + [RegisterComponent, Access(typeof(BloodstreamSystem), typeof(ReactionMixerSystem), typeof(BloodDeficiencySystem))] public sealed partial class BloodstreamComponent : Component { public static string DefaultChemicalsSolutionName = "chemicals"; @@ -171,5 +172,17 @@ public sealed partial class BloodstreamComponent : Component /// [ViewVariables(VVAccess.ReadWrite)] public TimeSpan StatusTime; + + /// + /// If this is true, the entity will not passively regenerate blood, + /// and instead will slowly lose blood. + /// + public bool HasBloodDeficiency = false; + + /// + /// How much reagent of blood should be removed with blood deficiency in each update interval? + /// + [DataField] + public FixedPoint2 BloodDeficiencyLossAmount; } } diff --git a/Content.Server/Body/Systems/BloodstreamSystem.cs b/Content.Server/Body/Systems/BloodstreamSystem.cs index 0edb190c16e..fafc649eb29 100644 --- a/Content.Server/Body/Systems/BloodstreamSystem.cs +++ b/Content.Server/Body/Systems/BloodstreamSystem.cs @@ -118,11 +118,14 @@ public override void Update(float frameTime) if (!_solutionContainerSystem.ResolveSolution(uid, bloodstream.BloodSolutionName, ref bloodstream.BloodSolution, out var bloodSolution)) continue; - // Adds blood to their blood level if it is below the maximum; Blood regeneration. Must be alive. - if (bloodSolution.Volume < bloodSolution.MaxVolume && !_mobStateSystem.IsDead(uid)) - { - TryModifyBloodLevel(uid, bloodstream.BloodRefreshAmount, bloodstream); - } + // Removes blood for Blood Deficiency constantly. + if (bloodstream.HasBloodDeficiency) + if (!_mobStateSystem.IsDead(uid)) + RemoveBlood(uid, bloodstream.BloodDeficiencyLossAmount, bloodstream); + // Adds blood to their blood level if it is below the maximum. + else if (bloodSolution.Volume < bloodSolution.MaxVolume) + if (!_mobStateSystem.IsDead(uid)) + TryModifyBloodLevel(uid, bloodstream.BloodRefreshAmount, bloodstream); // Removes blood from the bloodstream based on bleed amount (bleed rate) // as well as stop their bleeding to a certain extent. @@ -472,4 +475,16 @@ public void ChangeBloodReagent(EntityUid uid, string reagent, BloodstreamCompone if (currentVolume > 0) _solutionContainerSystem.TryAddReagent(component.BloodSolution.Value, component.BloodReagent, currentVolume, out _); } + + /// + /// Remove blood from an entity, without spilling it. + /// + private void RemoveBlood(EntityUid uid, FixedPoint2 amount, BloodstreamComponent? component = null) + { + if (!Resolve(uid, ref component, logMissing: false) + || !_solutionContainerSystem.ResolveSolution(uid, component.BloodSolutionName, ref component.BloodSolution, out var bloodSolution)) + return; + + bloodSolution.RemoveReagent(component.BloodReagent, amount); + } } diff --git a/Content.Server/Traits/BloodDeficiencyComponent.cs b/Content.Server/Traits/BloodDeficiencyComponent.cs new file mode 100644 index 00000000000..616f60cd834 --- /dev/null +++ b/Content.Server/Traits/BloodDeficiencyComponent.cs @@ -0,0 +1,14 @@ +namespace Content.Server.Traits.Assorted; + +/// +/// This is used for the Blood Deficiency trait. +/// +[RegisterComponent] +public sealed partial class BloodDeficiencyComponent : Component +{ + // + // How much reagent of blood should be removed in each update interval? + // + [DataField(required: true)] + public float BloodLossAmount; +} diff --git a/Content.Server/Traits/BloodDeficiencySystem.cs b/Content.Server/Traits/BloodDeficiencySystem.cs new file mode 100644 index 00000000000..f1ae4909956 --- /dev/null +++ b/Content.Server/Traits/BloodDeficiencySystem.cs @@ -0,0 +1,23 @@ +using Content.Server.Body.Systems; +using Content.Server.Body.Components; +using Content.Shared.Damage; + +namespace Content.Server.Traits.Assorted; + +public sealed class BloodDeficiencySystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnStartup); + } + + private void OnStartup(EntityUid uid, BloodDeficiencyComponent component, ComponentStartup args) + { + if (!TryComp(uid, out var bloodstream)) + return; + + bloodstream.HasBloodDeficiency = true; + bloodstream.BloodDeficiencyLossAmount = component.BloodLossAmount; + } +} diff --git a/Resources/Locale/en-US/traits/traits.ftl b/Resources/Locale/en-US/traits/traits.ftl index 07ef099f832..bf0a44e767e 100644 --- a/Resources/Locale/en-US/traits/traits.ftl +++ b/Resources/Locale/en-US/traits/traits.ftl @@ -23,6 +23,11 @@ trait-description-HeavyweightDrunk = Alcohol is afraid of you. trait-name-Muted = Muted trait-description-Muted = You can't speak +trait-name-BloodDeficiency = Blood Deficiency +trait-description-BloodDeficiency = + Your body loses more blood than it can replenish. + You lose blood over time, and when left untreated you will eventually die from blood loss. + trait-name-Paracusia = Paracusia trait-description-Paracusia = You hear sounds that aren't really there diff --git a/Resources/Prototypes/Traits/disabilities.yml b/Resources/Prototypes/Traits/disabilities.yml index eb96d37e01a..afdd27f339d 100644 --- a/Resources/Prototypes/Traits/disabilities.yml +++ b/Resources/Prototypes/Traits/disabilities.yml @@ -94,3 +94,17 @@ - MedicalBorg components: - type: Snoring + +- type: trait + id: BloodDeficiency + category: Physical + points: 2 + requirements: + - !type:CharacterJobRequirement + inverted: true + jobs: + - Borg + - MedicalBorg + components: + - type: BloodDeficiency # 0.07 = start taking bloodloss damage at around ~21.4 minutes, + bloodLossAmount: 0.07 # then become crit ~10 minutes later From bc3ffaf0cb61ba7febfad2c94c90e3d371510fc6 Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Tue, 6 Aug 2024 19:13:16 +0000 Subject: [PATCH 14/32] Automatic Changelog Update (#686) --- Resources/Changelog/Changelog.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 018c5adbd0d..7b3e9c5f2cc 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -4983,3 +4983,13 @@ Entries: message: Added different stamina damage resistance to hardsuits. id: 6223 time: '2024-08-06T19:08:48.0000000+00:00' +- author: Skubman + changes: + - type: Add + message: >- + Add the Blood Deficiency trait, a new negative trait that makes you + slowly lose blood over time. You must routinely receive blood loss + treatment to live, and even normally non-lethal bleeding can make you + start dying slowly. + id: 6224 + time: '2024-08-06T19:12:34.0000000+00:00' From 65748934f108517a3551805f20440038551fedb1 Mon Sep 17 00:00:00 2001 From: Angelo Fallaria Date: Wed, 7 Aug 2024 03:50:19 +0800 Subject: [PATCH 15/32] New Trait: Oni Damage Bonuses (#676) # Description Adds three new 1-point traits for Onis that **redistribute** your damage bonuses, allowing you to specialize in Slash or Piercing instead of Blunt, or be a generalist who is equally effective with all melee Brute weapons. The three new traits are **Swashbuckler**, **Spearmaster**, and **Weapons Generalist**. | Traits / Damage Bonus | Blunt | Slash | Piercing | |------------------------|-------|-------|----------| | Base Oni (No Traits) | 35% | 20% | 20% | | **Swashbuckler** | 20% | 35% | 20% | | **Spearmaster** | 20% | 20% | 35% | | **Weapons Generalist** | 25% | 25% | 25% | # Changelog :cl: Skubman - add: Add three new 1-point traits for Onis that allow you to specialize in Slash or Piercing damage or be a melee weapons generalist. --------- Signed-off-by: Angelo Fallaria Co-authored-by: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> --- .../Assorted/OniDamageModifierComponent.cs | 16 +++++ .../Assorted/OniDamageModifierSystem.cs | 31 ++++++++++ Resources/Locale/en-US/traits/traits.ftl | 15 +++++ Resources/Prototypes/Traits/species.yml | 62 +++++++++++++++++++ 4 files changed, 124 insertions(+) create mode 100644 Content.Server/Traits/Assorted/OniDamageModifierComponent.cs create mode 100644 Content.Server/Traits/Assorted/OniDamageModifierSystem.cs create mode 100644 Resources/Prototypes/Traits/species.yml diff --git a/Content.Server/Traits/Assorted/OniDamageModifierComponent.cs b/Content.Server/Traits/Assorted/OniDamageModifierComponent.cs new file mode 100644 index 00000000000..d6cf032aabd --- /dev/null +++ b/Content.Server/Traits/Assorted/OniDamageModifierComponent.cs @@ -0,0 +1,16 @@ +using Content.Shared.Damage; + +namespace Content.Server.Traits.Assorted; + +/// +/// This is used for traits that modify Oni damage modifiers. +/// +[RegisterComponent] +public sealed partial class OniDamageModifierComponent : Component +{ + /// + /// Which damage modifiers to override. + /// + [DataField("modifiers", required: true)] + public DamageModifierSet MeleeModifierReplacers = default!; +} diff --git a/Content.Server/Traits/Assorted/OniDamageModifierSystem.cs b/Content.Server/Traits/Assorted/OniDamageModifierSystem.cs new file mode 100644 index 00000000000..9d701053769 --- /dev/null +++ b/Content.Server/Traits/Assorted/OniDamageModifierSystem.cs @@ -0,0 +1,31 @@ +using Content.Server.Abilities.Oni; +using Content.Shared.Damage; + +namespace Content.Server.Traits.Assorted; + +public sealed class OniDamageModifierSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnStartup); + } + + private void OnStartup(EntityUid uid, OniDamageModifierComponent component, ComponentStartup args) + { + if (!TryComp(uid, out var oni)) + return; + + foreach (var (key, value) in component.MeleeModifierReplacers.Coefficients) + { + oni.MeleeModifiers.Coefficients[key] = value; + + } + + foreach (var (key, value) in component.MeleeModifierReplacers.FlatReduction) + { + oni.MeleeModifiers.FlatReduction[key] = value; + + } + } +} diff --git a/Resources/Locale/en-US/traits/traits.ftl b/Resources/Locale/en-US/traits/traits.ftl index bf0a44e767e..528517684c4 100644 --- a/Resources/Locale/en-US/traits/traits.ftl +++ b/Resources/Locale/en-US/traits/traits.ftl @@ -87,3 +87,18 @@ trait-description-Voracious = trait-name-LightStep = Light Step trait-description-LightStep = You move with a gentle step, making your footsteps quieter. + +trait-name-Swashbuckler = Swashbuckler +trait-description-Swashbuckler = + You are an expert in swordsmanship, wielding swords, knives, and other blades with unrivaled finesse. + Your melee Slash bonus is increased to 35%, but your melee Blunt bonus is reduced to 20%. + +trait-name-Spearmaster = Spearmaster +trait-description-Spearmaster = + You have an outstanding proficiency with spears, wielding them as an extension of your body. + Your melee Piercing bonus is increased to 35%, but your melee Blunt bonus is reduced to 20%. + +trait-name-WeaponsGeneralist = Weapons Generalist +trait-description-WeaponsGeneralist = + You are a jack of all trades with melee weapons, enabling you to be versatile with your weapon arsenal. + Your melee damage bonus for all Brute damage types (Blunt, Slash, Piercing) becomes 25%. \ No newline at end of file diff --git a/Resources/Prototypes/Traits/species.yml b/Resources/Prototypes/Traits/species.yml new file mode 100644 index 00000000000..2c298252289 --- /dev/null +++ b/Resources/Prototypes/Traits/species.yml @@ -0,0 +1,62 @@ +- type: trait + id: Swashbuckler + category: Physical + points: -1 + components: + - type: OniDamageModifier + modifiers: + coefficients: + Blunt: 1.2 + Slash: 1.35 + Piercing: 1.2 + requirements: + - !type:CharacterSpeciesRequirement + species: + - Oni + - !type:CharacterTraitRequirement + inverted: true + traits: + - Spearmaster + - WeaponsGeneralist + +- type: trait + id: Spearmaster + category: Physical + points: -1 + components: + - type: OniDamageModifier + modifiers: + coefficients: + Blunt: 1.2 + Slash: 1.2 + Piercing: 1.35 + requirements: + - !type:CharacterSpeciesRequirement + species: + - Oni + - !type:CharacterTraitRequirement + inverted: true + traits: + - Swashbuckler + - WeaponsGeneralist + +- type: trait + id: WeaponsGeneralist + category: Physical + points: -1 + components: + - type: OniDamageModifier + modifiers: + coefficients: + Blunt: 1.25 + Slash: 1.25 + Piercing: 1.25 + requirements: + - !type:CharacterSpeciesRequirement + species: + - Oni + - !type:CharacterTraitRequirement + inverted: true + traits: + - Swashbuckler + - Spearmaster From 0e293730ebcb5f38f0a8cd455f90b399369ddbcb Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Tue, 6 Aug 2024 19:50:43 +0000 Subject: [PATCH 16/32] Automatic Changelog Update (#676) --- Resources/Changelog/Changelog.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 7b3e9c5f2cc..6263b7d4005 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -4993,3 +4993,11 @@ Entries: start dying slowly. id: 6224 time: '2024-08-06T19:12:34.0000000+00:00' +- author: Skubman + changes: + - type: Add + message: >- + Add three new 1-point traits for Onis that allow you to specialize in + Slash or Piercing damage or be a melee weapons generalist. + id: 6225 + time: '2024-08-06T19:50:20.0000000+00:00' From 32b08b03501bd65faed05fdffa1c8f7a6d55b016 Mon Sep 17 00:00:00 2001 From: VMSolidus Date: Tue, 6 Aug 2024 16:23:34 -0400 Subject: [PATCH 17/32] Port Justice Department From DeltaV (#675) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description This ports https://github.com/DeltaV-Station/Delta-v/pull/660 > ## About the PR > Adds the Justice Department, a department enveloping the lawyer and 3 new roles that manage the court system and charges against the accused. Includes: • New department, Justice! • 3 new roles: ◦ Chief Justice: The main, impartial judge for the station responsible for adjudicating criminal and civil trials, as well as other small matters like paroles and pardons. ◦ Clerk: The court clerk, who organizes trials, notarizes court documents (warrants, sentences, etc), and ensures correct sentencing and due process for the accused in sec custody. ◦ Prosecutor: A special lawyer role that legally advises sec and handles all of its court prep and prosecution, freeing up sec's time to go stun baton the clown instead of waiting for trial. • Antag objective to steal the Clerk's notary stamp, an object imbued with the authority to officialize court decisions. • Made the Lawyer role easier to understand and added them to the department. Renamed to Attorney, they now exclusively defend the accused or can sue on their behalf. Can also curse at the prosecutor in the bar. • Changed SoP to match. Notable changes include ◦ Felony charges and above must be reviewed and approved by the Clerk or Chief Justice if those roles are active. ◦ Parole, criminal trials, and civil trials are now all adjudicated by the Chief Justice, or the clerk in their absence. ◦ To ensure fair judgement, a Captain can only remove the Chief Justice with a majority vote from command. ◦ Warrants and court decisions must be written down and stamped with the notary stamp. Warrants must be approved by the Chief Justice. ◦ Full list of SoP changes can be found here: https://docs.google.com/document/d/12ZKTtzvVWBuC7PuiREL9v7mhVZve11p0-T6MBPpVeGs/edit?usp=sharing • Classy wooden desk timer to help keep trials timely and within limits. > > **TO DO:** Chief Justice > > * [x] Role > * [x] Inventory > * [x] Job Description > * [x] Icon > * [x] Access (CMD/CJ/Sec/Justice*) > * [x] Airlocks > * [x] Spawnpoint > * [x] Closet(just reuse legal w/ a lock) > * [x] Gavel** (proto/sprite/sound) > * [x] Stamp (proto/sprite) > * [x] Drip > > Court Clerk > > * [x] Role > * [x] Inventory > * [x] Job Description > * [x] Icon > * [x] Access (Sec/Justice*) > * [x] Spawnpoint > * [x] Closet(just reuse legal w/ a lock) > * [x] Stamp** (proto/sprite) > * [x] Warrant document > * [x] Drip > > Prosecutor > > * [x] Role > * [x] Inventory > * [x] Job Description > * [x] Icon > * [x] Access (Sec/Justice*) > * [x] Spawnpoint > * [x] Closet(just reuse legal w/ a lock) > * [x] Drip(Can be same as lawyer but should have a unique badge) > > SoP/Guidlines > > * [x] Civil and criminal law-penalties > * [x] Legal mutiny? > * [x] Assigning judges when no judge is present > * [x] Judge is representative of CC. Not necessarily _above_ captain but outside. > * [x] When to appeal to a jury? How to pick a jury? (random would be good) > * [x] Rules for gaining warrants > * [x] Procedure for arresting officer filing criminal charges > * [x] Rules for summoning witnesses > * [ ] Guide/book > > Other > > * [ ] Station Beacons > > ## Notes: > * We might want to consider bringing back brig access for cells to give legal dept sec access and not control over prisoners. > * Mapping would need to provide offices for CJ, CC, and Prosecuter. > * Chief Justice is a rep of CC not necessarily above captain but outside > > ## Why / Balance > The current legal system in-game is built around LRP gameplay, with security handling everything relating to arrests, sentencing, trials, and execution. Additionally, it is near-impossible to find an impartial judge for any court case with the current system. New legal department would guarantee an impartial and available judge (whether it be the Chief Justice or Clerk) for any court case, take pressure off of security to handle things like sentencing and trials. Additionally, there will be more roleplay opportunities for things like civil cases, inter-department disputes, internal affairs, or whatever else you may need legal help with. > > ## Technical details > n/a > > ## Media > ![image](https://private-user-images.githubusercontent.com/136020119/295444469-8569ec5a-8a44-41a5-83c8-165c940e9a9a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjI4MjY5MTEsIm5iZiI6MTcyMjgyNjYxMSwicGF0aCI6Ii8xMzYwMjAxMTkvMjk1NDQ0NDY5LTg1NjllYzVhLThhNDQtNDFhNS04M2M4LTE2NWM5NDBlOWE5YS5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwODA1JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDgwNVQwMjU2NTFaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT03ZjE2M2UxNmE2OWE3YmNkM2MwMzY3YmQ5MWU5MGEwNzFjZTg5NDAyMGZkNzkyZTJjZDRhYWJlYzk1MTNmZDg3JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.kv3SVoSKceqwlIctnBa4u6E3NHMJ3rPrg3VxoTl-jZQ) ![image](https://private-user-images.githubusercontent.com/136020119/295444610-9ab40e2b-149b-4d9d-af13-47c8fec40be3.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjI4MjY5MTEsIm5iZiI6MTcyMjgyNjYxMSwicGF0aCI6Ii8xMzYwMjAxMTkvMjk1NDQ0NjEwLTlhYjQwZTJiLTE0OWItNGQ5ZC1hZjEzLTQ3YzhmZWM0MGJlMy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwODA1JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDgwNVQwMjU2NTFaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT01ZDUyZWQ4NWVkZTM5NDlhNDcxNTNiZGIxZDljMjJkZTBmZThmN2IxNWEwMzk5MWQwMDdjNmQ4MWY1NTcxNWFlJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.jZUnQ8Xj6uor4NAU-IHU7MoD1e3F964XkmZ3aNjPj0U) > > * [x] I have added screenshots/videos to this PR showcasing its changes in-game, **or** this PR does not require an in-game showcase > > ## Breaking changes > none that I know of 😓 > **Changelog** 🆑 Leo, Velcroboy, and Timemaster - add: Added The Justice Department >:) --- .../Components/IdCardConsoleComponent.cs | 3 + Resources/Audio/DeltaV/Items/gavel.ogg | Bin 0 -> 10265 bytes .../en-US/deltav/devices/device-network.ftl | 2 + .../deltav/headset/headset-component.ftl | 2 + .../en-US/deltav/job/department-desc.ftl | 2 + .../Locale/en-US/deltav/job/department.ftl | 2 + .../en-US/deltav/job/job-description.ftl | 4 + .../Locale/en-US/deltav/job/job-names.ftl | 5 + .../en-US/deltav/job/job-supervisors.ftl | 2 + Resources/Locale/en-US/deltav/misc/pda.ftl | 4 + .../deltav/navmap-beacons/station-beacons.ftl | 4 + .../en-US/deltav/paper/stamp-component.ftl | 5 +- .../deltav/prototypes/access/accesses.ftl | 5 +- Resources/Locale/en-US/job/job-names.ftl | 3 +- Resources/Prototypes/Access/misc.yml | 3 + .../Prototypes/DeltaV/Access/justice.yml | 20 ++ Resources/Prototypes/DeltaV/Access/misc.yml | 3 + .../DeltaV/Catalog/Fills/Boxes/general.yml | 26 +++ .../DeltaV/Catalog/Fills/Boxes/pda.yml | 13 ++ .../Catalog/Fills/Lockers/chiefjustice.yml | 21 ++ .../DeltaV/Catalog/Fills/Lockers/clerk.yml | 14 ++ .../DeltaV/Device/devicenet_frequencies.yml | 5 + .../Entities/Clothing/Ears/headsets.yml | 40 ++++ .../DeltaV/Entities/Clothing/Head/hats.yml | 12 ++ .../DeltaV/Entities/Clothing/Neck/cloaks.yml | 12 ++ .../DeltaV/Entities/Clothing/Neck/misc.yml | 13 ++ .../Entities/Clothing/OuterClothing/coats.yml | 14 ++ .../Entities/Clothing/OuterClothing/vests.yml | 12 ++ .../Entities/Clothing/Uniforms/jumpskirts.yml | 34 +++ .../Entities/Clothing/Uniforms/jumpsuits.yml | 56 +++++ .../DeltaV/Entities/Markers/Spawners/jobs.yml | 52 +++++ .../Entities/Objects/Devices/door_remote.yml | 15 ++ .../Objects/Devices/encryption_keys.yml | 16 ++ .../DeltaV/Entities/Objects/Devices/pda.yml | 117 +++++++++++ .../Objects/Devices/station_beacon.yml | 25 +++ .../DeltaV/Entities/Objects/Misc/paper.yml | 25 +++ .../Entities/Objects/Misc/rubber_stamp.yml | 30 +++ .../Objects/Specific/Justice/gavel.yml | 21 ++ .../Objects/Specific/Justice/gavelblock.yml | 19 ++ .../Objects/Specific/Justice/trialtimer.yml | 24 +++ .../Structures/Doors/Airlocks/access.yml | 82 ++++++++ .../Structures/Doors/Airlocks/airlocks.yml | 22 ++ .../Structures/Doors/Windoors/windoor.yml | 36 ++++ .../Storage/Closets/Lockers/lockers.yml | 25 +++ .../Structures/Wallmounts/Signs/signs.yml | 22 ++ .../DeltaV/Objectives/stealTargetGroups.yml | 9 + .../Prototypes/DeltaV/Objectives/traitor.yml | 13 ++ .../Roles/Jobs/Justice/chief_justice.yml | 59 ++++++ .../DeltaV/Roles/Jobs/Justice/clerk.yml | 41 ++++ .../DeltaV/Roles/Jobs/Justice/prosecutor.yml | 34 +++ .../DeltaV/Roles/Jobs/departments.yml | 11 + .../DeltaV/Roles/play_time_trackers.yml | 3 + .../Prototypes/DeltaV/StatusEffects/job.yml | 21 ++ .../Prototypes/DeltaV/radio_channels.yml | 11 +- Resources/Prototypes/DeltaV/tags.yml | 6 + .../Devices/Electronics/door_access.yml | 24 +++ .../Objects/Devices/encryption_keys.yml | 1 + .../Objects/Misc/identification_cards.yml | 55 ++++- .../Objects/Tools/access_configurator.yml | 3 + .../Structures/Doors/Airlocks/access.yml | 6 +- .../Structures/Doors/airlock_groups.yml | 2 + .../Structures/Machines/telecomms.yml | 82 ++++++++ .../Prototypes/Palettes/departmental.yml | 3 +- .../Prototypes/Roles/Jobs/Civilian/lawyer.yml | 2 +- .../Prototypes/Roles/Jobs/departments.yml | 2 +- .../Prototypes/Roles/play_time_trackers.yml | 9 + Resources/Prototypes/StatusEffects/job.yml | 4 +- .../justice.rsi/alt-equipped-EARS.png | Bin 0 -> 847 bytes .../Headsets/justice.rsi/equipped-EARS.png | Bin 0 -> 628 bytes .../Ears/Headsets/justice.rsi/icon.png | Bin 0 -> 728 bytes .../Ears/Headsets/justice.rsi/icon_alt.png | Bin 0 -> 876 bytes .../Ears/Headsets/justice.rsi/meta.json | 25 +++ .../Hats/cj_toque.rsi/equipped-HELMET.png | Bin 0 -> 781 bytes .../Clothing/Head/Hats/cj_toque.rsi/icon.png | Bin 0 -> 647 bytes .../Head/Hats/cj_toque.rsi/inhand-left.png | Bin 0 -> 832 bytes .../Head/Hats/cj_toque.rsi/inhand-right.png | Bin 0 -> 806 bytes .../Clothing/Head/Hats/cj_toque.rsi/meta.json | 26 +++ .../Neck/Cloaks/cjcloak.rsi/equipped-NECK.png | Bin 0 -> 1771 bytes .../Clothing/Neck/Cloaks/cjcloak.rsi/icon.png | Bin 0 -> 1016 bytes .../Neck/Cloaks/cjcloak.rsi/inhand-left.png | Bin 0 -> 831 bytes .../Neck/Cloaks/cjcloak.rsi/inhand-right.png | Bin 0 -> 840 bytes .../Neck/Cloaks/cjcloak.rsi/meta.json | 26 +++ .../prosecutorbadge.rsi/equipped-NECK.png | Bin 0 -> 607 bytes .../Neck/Misc/prosecutorbadge.rsi/icon.png | Bin 0 -> 1018 bytes .../Neck/Misc/prosecutorbadge.rsi/meta.json | 18 ++ .../mantles/cjmantle.rsi/equipped-NECK.png | Bin 0 -> 1346 bytes .../Neck/mantles/cjmantle.rsi/icon.png | Bin 0 -> 744 bytes .../Neck/mantles/cjmantle.rsi/meta.json | 18 ++ .../cjrobe.rsi/equipped-OUTERCLOTHING.png | Bin 0 -> 1830 bytes .../OuterClothing/Coats/cjrobe.rsi/icon.png | Bin 0 -> 979 bytes .../Coats/cjrobe.rsi/inhand-left.png | Bin 0 -> 1058 bytes .../Coats/cjrobe.rsi/inhand-right.png | Bin 0 -> 1028 bytes .../OuterClothing/Coats/cjrobe.rsi/meta.json | 26 +++ .../clerkvest.rsi/equipped-OUTERCLOTHING.png | Bin 0 -> 1137 bytes .../Vests/clerkvest.rsi/icon.png | Bin 0 -> 709 bytes .../Vests/clerkvest.rsi/inhand-left.png | Bin 0 -> 785 bytes .../Vests/clerkvest.rsi/inhand-right.png | Bin 0 -> 787 bytes .../Vests/clerkvest.rsi/meta.json | 26 +++ .../cj.rsi/equipped-INNERCLOTHING.png | Bin 0 -> 1719 bytes .../Uniforms/Jumpskirt/cj.rsi/icon.png | Bin 0 -> 995 bytes .../Uniforms/Jumpskirt/cj.rsi/inhand-left.png | Bin 0 -> 955 bytes .../Jumpskirt/cj.rsi/inhand-right.png | Bin 0 -> 939 bytes .../Uniforms/Jumpskirt/cj.rsi/meta.json | 26 +++ .../clerk.rsi/equipped-INNERCLOTHING.png | Bin 0 -> 1384 bytes .../Uniforms/Jumpskirt/clerk.rsi/icon.png | Bin 0 -> 884 bytes .../Jumpskirt/clerk.rsi/inhand-left.png | Bin 0 -> 967 bytes .../Jumpskirt/clerk.rsi/inhand-right.png | Bin 0 -> 952 bytes .../Uniforms/Jumpskirt/clerk.rsi/meta.json | 26 +++ .../equipped-INNERCLOTHING.png | Bin 0 -> 1681 bytes .../Jumpskirt/prosecutorred.rsi/icon.png | Bin 0 -> 877 bytes .../prosecutorred.rsi/inhand-left.png | Bin 0 -> 983 bytes .../prosecutorred.rsi/inhand-right.png | Bin 0 -> 985 bytes .../Jumpskirt/prosecutorred.rsi/meta.json | 26 +++ .../cj.rsi/equipped-INNERCLOTHING.png | Bin 0 -> 1559 bytes .../Uniforms/Jumpsuit/cj.rsi/icon.png | Bin 0 -> 902 bytes .../Uniforms/Jumpsuit/cj.rsi/inhand-left.png | Bin 0 -> 955 bytes .../Uniforms/Jumpsuit/cj.rsi/inhand-right.png | Bin 0 -> 939 bytes .../Uniforms/Jumpsuit/cj.rsi/meta.json | 26 +++ .../cj_white.rsi/equipped-INNERCLOTHING.png | Bin 0 -> 9718 bytes .../Uniforms/Jumpsuit/cj_white.rsi/icon.png | Bin 0 -> 537 bytes .../Jumpsuit/cj_white.rsi/inhand-left.png | Bin 0 -> 7793 bytes .../Jumpsuit/cj_white.rsi/inhand-right.png | Bin 0 -> 7879 bytes .../Uniforms/Jumpsuit/cj_white.rsi/meta.json | 26 +++ .../cjformal.rsi/equipped-INNERCLOTHING.png | Bin 0 -> 9423 bytes .../Uniforms/Jumpsuit/cjformal.rsi/icon.png | Bin 0 -> 5678 bytes .../Jumpsuit/cjformal.rsi/inhand-left.png | Bin 0 -> 7183 bytes .../Jumpsuit/cjformal.rsi/inhand-right.png | Bin 0 -> 7415 bytes .../Uniforms/Jumpsuit/cjformal.rsi/meta.json | 26 +++ .../clerk.rsi/equipped-INNERCLOTHING.png | Bin 0 -> 1447 bytes .../Uniforms/Jumpsuit/clerk.rsi/icon.png | Bin 0 -> 910 bytes .../Jumpsuit/clerk.rsi/inhand-left.png | Bin 0 -> 967 bytes .../Jumpsuit/clerk.rsi/inhand-right.png | Bin 0 -> 952 bytes .../Uniforms/Jumpsuit/clerk.rsi/meta.json | 26 +++ .../equipped-INNERCLOTHING.png | Bin 0 -> 1615 bytes .../Jumpsuit/prosecutorred.rsi/icon.png | Bin 0 -> 868 bytes .../prosecutorred.rsi/inhand-left.png | Bin 0 -> 983 bytes .../prosecutorred.rsi/inhand-right.png | Bin 0 -> 985 bytes .../Jumpsuit/prosecutorred.rsi/meta.json | 26 +++ .../Misc/job_icons.rsi/ChiefJustice.png | Bin 0 -> 568 bytes .../Interface/Misc/job_icons.rsi/Clerk.png | Bin 0 -> 537 bytes .../Interface/Misc/job_icons.rsi/Lawyer.png | Bin 0 -> 539 bytes .../Misc/job_icons.rsi/Prosecutor.png | Bin 0 -> 5005 bytes .../Interface/Misc/job_icons.rsi/meta.json | 14 +- .../Interface/Paper/paper_heading_warrant.svg | 127 ++++++++++++ .../paper_heading_warrant.svg.200dpi.png | Bin 0 -> 10022 bytes .../paper_heading_warrant.svg.200dpi.png.yml | 2 + .../DeltaV/Markers/jobs.rsi/chiefjustice.png | Bin 0 -> 1439 bytes .../DeltaV/Markers/jobs.rsi/clerk.png | Bin 0 -> 1031 bytes .../DeltaV/Markers/jobs.rsi/meta.json | 9 + .../DeltaV/Markers/jobs.rsi/prosecutor.png | Bin 0 -> 836 bytes .../encryption_keys.rsi/justice_label.png | Bin 0 -> 570 bytes .../Devices/encryption_keys.rsi/meta.json | 9 +- .../DeltaV/Objects/Devices/pda.rsi/meta.json | 11 +- .../Devices/pda.rsi/pda-chiefjustice.png | Bin 0 -> 943 bytes .../Objects/Devices/pda.rsi/pda-clerk.png | Bin 0 -> 1022 bytes .../Devices/pda.rsi/pda-prosecutor.png | Bin 0 -> 6141 bytes .../Objects/Misc/bureaucracy.rsi/meta.json | 2 +- .../DeltaV/Objects/Misc/stamps.rsi/meta.json | 8 +- .../Objects/Misc/stamps.rsi/stamp-cj.png | Bin 0 -> 5263 bytes .../Objects/Misc/stamps.rsi/stamp-notary.png | Bin 0 -> 777 bytes .../Specific/Justice/gavel.rsi/icon.png | Bin 0 -> 434 bytes .../Justice/gavel.rsi/inhand-left.png | Bin 0 -> 11051 bytes .../Justice/gavel.rsi/inhand-right.png | Bin 0 -> 11817 bytes .../Specific/Justice/gavel.rsi/meta.json | 22 ++ .../Specific/Justice/gavelblock.rsi/icon.png | Bin 0 -> 225 bytes .../Specific/Justice/gavelblock.rsi/meta.json | 14 ++ .../Specific/Justice/trialtimer.rsi/meta.json | 14 ++ .../Justice/trialtimer.rsi/trialtimer.png | Bin 0 -> 1170 bytes .../Airlocks/Glass/justice.rsi/assembly.png | Bin 0 -> 1645 bytes .../Glass/justice.rsi/bolted_unlit.png | Bin 0 -> 144 bytes .../Airlocks/Glass/justice.rsi/closed.png | Bin 0 -> 1763 bytes .../Glass/justice.rsi/closed_unlit.png | Bin 0 -> 144 bytes .../Airlocks/Glass/justice.rsi/closing.png | Bin 0 -> 3014 bytes .../Glass/justice.rsi/closing_unlit.png | Bin 0 -> 432 bytes .../Airlocks/Glass/justice.rsi/deny_unlit.png | Bin 0 -> 321 bytes .../Glass/justice.rsi/emergency_unlit.png | Bin 0 -> 588 bytes .../Airlocks/Glass/justice.rsi/meta.json | 195 ++++++++++++++++++ .../Doors/Airlocks/Glass/justice.rsi/open.png | Bin 0 -> 760 bytes .../Airlocks/Glass/justice.rsi/opening.png | Bin 0 -> 3247 bytes .../Glass/justice.rsi/opening_unlit.png | Bin 0 -> 284 bytes .../Glass/justice.rsi/panel_closing.png | Bin 0 -> 445 bytes .../Airlocks/Glass/justice.rsi/panel_open.png | Bin 0 -> 315 bytes .../Glass/justice.rsi/panel_opening.png | Bin 0 -> 470 bytes .../Airlocks/Glass/justice.rsi/sparks.png | Bin 0 -> 697 bytes .../Glass/justice.rsi/sparks_broken.png | Bin 0 -> 183 bytes .../Glass/justice.rsi/sparks_damaged.png | Bin 0 -> 184 bytes .../Glass/justice.rsi/sparks_open.png | Bin 0 -> 175 bytes .../Airlocks/Glass/justice.rsi/welded.png | Bin 0 -> 296 bytes .../Standard/justice.rsi/assembly.png | Bin 0 -> 1369 bytes .../Standard/justice.rsi/bolted_unlit.png | Bin 0 -> 144 bytes .../Airlocks/Standard/justice.rsi/closed.png | Bin 0 -> 1488 bytes .../Standard/justice.rsi/closed_unlit.png | Bin 0 -> 144 bytes .../Airlocks/Standard/justice.rsi/closing.png | Bin 0 -> 2683 bytes .../Standard/justice.rsi/closing_unlit.png | Bin 0 -> 432 bytes .../Standard/justice.rsi/deny_unlit.png | Bin 0 -> 321 bytes .../Standard/justice.rsi/emergency_unlit.png | Bin 0 -> 588 bytes .../Airlocks/Standard/justice.rsi/meta.json | 195 ++++++++++++++++++ .../Airlocks/Standard/justice.rsi/open.png | Bin 0 -> 729 bytes .../Airlocks/Standard/justice.rsi/opening.png | Bin 0 -> 2825 bytes .../Standard/justice.rsi/opening_unlit.png | Bin 0 -> 284 bytes .../Standard/justice.rsi/panel_closing.png | Bin 0 -> 445 bytes .../Standard/justice.rsi/panel_open.png | Bin 0 -> 315 bytes .../Standard/justice.rsi/panel_opening.png | Bin 0 -> 470 bytes .../Airlocks/Standard/justice.rsi/sparks.png | Bin 0 -> 697 bytes .../Standard/justice.rsi/sparks_broken.png | Bin 0 -> 183 bytes .../Standard/justice.rsi/sparks_damaged.png | Bin 0 -> 184 bytes .../Standard/justice.rsi/sparks_open.png | Bin 0 -> 175 bytes .../Airlocks/Standard/justice.rsi/welded.png | Bin 0 -> 296 bytes .../Wallmounts/signs.rsi/direction_court.png | Bin 0 -> 898 bytes .../signs.rsi/direction_justice.png | Bin 0 -> 926 bytes .../Structures/Wallmounts/signs.rsi/meta.json | 10 +- .../Objects/Misc/bureaucracy.rsi/meta.json | 3 + .../bureaucracy.rsi/paper_stamp-notary.png | Bin 0 -> 625 bytes .../Structures/Storage/closet.rsi/cj.png | Bin 0 -> 5692 bytes .../Structures/Storage/closet.rsi/cj_door.png | Bin 0 -> 5840 bytes .../Structures/Storage/closet.rsi/cj_open.png | Bin 0 -> 5529 bytes .../Structures/Storage/closet.rsi/clerk.png | Bin 0 -> 5806 bytes .../Storage/closet.rsi/clerk_door.png | Bin 0 -> 5853 bytes .../Storage/closet.rsi/clerk_open.png | Bin 0 -> 5588 bytes .../Structures/Storage/closet.rsi/meta.json | 20 +- 220 files changed, 2278 insertions(+), 23 deletions(-) create mode 100644 Resources/Audio/DeltaV/Items/gavel.ogg create mode 100644 Resources/Locale/en-US/deltav/devices/device-network.ftl create mode 100644 Resources/Locale/en-US/deltav/job/department-desc.ftl create mode 100644 Resources/Locale/en-US/deltav/job/job-supervisors.ftl create mode 100644 Resources/Locale/en-US/deltav/misc/pda.ftl create mode 100644 Resources/Prototypes/DeltaV/Access/justice.yml create mode 100644 Resources/Prototypes/DeltaV/Catalog/Fills/Lockers/chiefjustice.yml create mode 100644 Resources/Prototypes/DeltaV/Catalog/Fills/Lockers/clerk.yml create mode 100644 Resources/Prototypes/DeltaV/Device/devicenet_frequencies.yml create mode 100644 Resources/Prototypes/DeltaV/Entities/Clothing/Neck/misc.yml create mode 100644 Resources/Prototypes/DeltaV/Entities/Objects/Devices/door_remote.yml create mode 100644 Resources/Prototypes/DeltaV/Entities/Objects/Misc/paper.yml create mode 100644 Resources/Prototypes/DeltaV/Entities/Objects/Specific/Justice/gavel.yml create mode 100644 Resources/Prototypes/DeltaV/Entities/Objects/Specific/Justice/gavelblock.yml create mode 100644 Resources/Prototypes/DeltaV/Entities/Objects/Specific/Justice/trialtimer.yml create mode 100644 Resources/Prototypes/DeltaV/Entities/Structures/Doors/Airlocks/airlocks.yml create mode 100644 Resources/Prototypes/DeltaV/Entities/Structures/Storage/Closets/Lockers/lockers.yml create mode 100644 Resources/Prototypes/DeltaV/Roles/Jobs/Justice/chief_justice.yml create mode 100644 Resources/Prototypes/DeltaV/Roles/Jobs/Justice/clerk.yml create mode 100644 Resources/Prototypes/DeltaV/Roles/Jobs/Justice/prosecutor.yml create mode 100644 Resources/Prototypes/DeltaV/Roles/Jobs/departments.yml create mode 100644 Resources/Textures/DeltaV/Clothing/Ears/Headsets/justice.rsi/alt-equipped-EARS.png create mode 100644 Resources/Textures/DeltaV/Clothing/Ears/Headsets/justice.rsi/equipped-EARS.png create mode 100644 Resources/Textures/DeltaV/Clothing/Ears/Headsets/justice.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Clothing/Ears/Headsets/justice.rsi/icon_alt.png create mode 100644 Resources/Textures/DeltaV/Clothing/Ears/Headsets/justice.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Clothing/Head/Hats/cj_toque.rsi/equipped-HELMET.png create mode 100644 Resources/Textures/DeltaV/Clothing/Head/Hats/cj_toque.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Clothing/Head/Hats/cj_toque.rsi/inhand-left.png create mode 100644 Resources/Textures/DeltaV/Clothing/Head/Hats/cj_toque.rsi/inhand-right.png create mode 100644 Resources/Textures/DeltaV/Clothing/Head/Hats/cj_toque.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Clothing/Neck/Cloaks/cjcloak.rsi/equipped-NECK.png create mode 100644 Resources/Textures/DeltaV/Clothing/Neck/Cloaks/cjcloak.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Clothing/Neck/Cloaks/cjcloak.rsi/inhand-left.png create mode 100644 Resources/Textures/DeltaV/Clothing/Neck/Cloaks/cjcloak.rsi/inhand-right.png create mode 100644 Resources/Textures/DeltaV/Clothing/Neck/Cloaks/cjcloak.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Clothing/Neck/Misc/prosecutorbadge.rsi/equipped-NECK.png create mode 100644 Resources/Textures/DeltaV/Clothing/Neck/Misc/prosecutorbadge.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Clothing/Neck/Misc/prosecutorbadge.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Clothing/Neck/mantles/cjmantle.rsi/equipped-NECK.png create mode 100644 Resources/Textures/DeltaV/Clothing/Neck/mantles/cjmantle.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Clothing/Neck/mantles/cjmantle.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Clothing/OuterClothing/Coats/cjrobe.rsi/equipped-OUTERCLOTHING.png create mode 100644 Resources/Textures/DeltaV/Clothing/OuterClothing/Coats/cjrobe.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Clothing/OuterClothing/Coats/cjrobe.rsi/inhand-left.png create mode 100644 Resources/Textures/DeltaV/Clothing/OuterClothing/Coats/cjrobe.rsi/inhand-right.png create mode 100644 Resources/Textures/DeltaV/Clothing/OuterClothing/Coats/cjrobe.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Clothing/OuterClothing/Vests/clerkvest.rsi/equipped-OUTERCLOTHING.png create mode 100644 Resources/Textures/DeltaV/Clothing/OuterClothing/Vests/clerkvest.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Clothing/OuterClothing/Vests/clerkvest.rsi/inhand-left.png create mode 100644 Resources/Textures/DeltaV/Clothing/OuterClothing/Vests/clerkvest.rsi/inhand-right.png create mode 100644 Resources/Textures/DeltaV/Clothing/OuterClothing/Vests/clerkvest.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/cj.rsi/equipped-INNERCLOTHING.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/cj.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/cj.rsi/inhand-left.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/cj.rsi/inhand-right.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/cj.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/clerk.rsi/equipped-INNERCLOTHING.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/clerk.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/clerk.rsi/inhand-left.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/clerk.rsi/inhand-right.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/clerk.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/prosecutorred.rsi/equipped-INNERCLOTHING.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/prosecutorred.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/prosecutorred.rsi/inhand-left.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/prosecutorred.rsi/inhand-right.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/prosecutorred.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj.rsi/equipped-INNERCLOTHING.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj.rsi/inhand-left.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj.rsi/inhand-right.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj_white.rsi/equipped-INNERCLOTHING.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj_white.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj_white.rsi/inhand-left.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj_white.rsi/inhand-right.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj_white.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cjformal.rsi/equipped-INNERCLOTHING.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cjformal.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cjformal.rsi/inhand-left.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cjformal.rsi/inhand-right.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cjformal.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/clerk.rsi/equipped-INNERCLOTHING.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/clerk.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/clerk.rsi/inhand-left.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/clerk.rsi/inhand-right.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/clerk.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/prosecutorred.rsi/equipped-INNERCLOTHING.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/prosecutorred.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/prosecutorred.rsi/inhand-left.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/prosecutorred.rsi/inhand-right.png create mode 100644 Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/prosecutorred.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Interface/Misc/job_icons.rsi/ChiefJustice.png create mode 100644 Resources/Textures/DeltaV/Interface/Misc/job_icons.rsi/Clerk.png create mode 100644 Resources/Textures/DeltaV/Interface/Misc/job_icons.rsi/Lawyer.png create mode 100644 Resources/Textures/DeltaV/Interface/Misc/job_icons.rsi/Prosecutor.png create mode 100644 Resources/Textures/DeltaV/Interface/Paper/paper_heading_warrant.svg create mode 100644 Resources/Textures/DeltaV/Interface/Paper/paper_heading_warrant.svg.200dpi.png create mode 100644 Resources/Textures/DeltaV/Interface/Paper/paper_heading_warrant.svg.200dpi.png.yml create mode 100644 Resources/Textures/DeltaV/Markers/jobs.rsi/chiefjustice.png create mode 100644 Resources/Textures/DeltaV/Markers/jobs.rsi/clerk.png create mode 100644 Resources/Textures/DeltaV/Markers/jobs.rsi/prosecutor.png create mode 100644 Resources/Textures/DeltaV/Objects/Devices/encryption_keys.rsi/justice_label.png create mode 100644 Resources/Textures/DeltaV/Objects/Devices/pda.rsi/pda-chiefjustice.png create mode 100644 Resources/Textures/DeltaV/Objects/Devices/pda.rsi/pda-clerk.png create mode 100644 Resources/Textures/DeltaV/Objects/Devices/pda.rsi/pda-prosecutor.png create mode 100644 Resources/Textures/DeltaV/Objects/Misc/stamps.rsi/stamp-cj.png create mode 100644 Resources/Textures/DeltaV/Objects/Misc/stamps.rsi/stamp-notary.png create mode 100644 Resources/Textures/DeltaV/Objects/Specific/Justice/gavel.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Objects/Specific/Justice/gavel.rsi/inhand-left.png create mode 100644 Resources/Textures/DeltaV/Objects/Specific/Justice/gavel.rsi/inhand-right.png create mode 100644 Resources/Textures/DeltaV/Objects/Specific/Justice/gavel.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Objects/Specific/Justice/gavelblock.rsi/icon.png create mode 100644 Resources/Textures/DeltaV/Objects/Specific/Justice/gavelblock.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Objects/Specific/Justice/trialtimer.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Objects/Specific/Justice/trialtimer.rsi/trialtimer.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/assembly.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/bolted_unlit.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/closed.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/closed_unlit.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/closing.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/closing_unlit.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/deny_unlit.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/emergency_unlit.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/open.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/opening.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/opening_unlit.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/panel_closing.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/panel_open.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/panel_opening.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/sparks.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/sparks_broken.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/sparks_damaged.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/sparks_open.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/welded.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/assembly.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/bolted_unlit.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/closed.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/closed_unlit.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/closing.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/closing_unlit.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/deny_unlit.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/emergency_unlit.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/meta.json create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/open.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/opening.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/opening_unlit.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/panel_closing.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/panel_open.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/panel_opening.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/sparks.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/sparks_broken.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/sparks_damaged.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/sparks_open.png create mode 100644 Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/welded.png create mode 100644 Resources/Textures/DeltaV/Structures/Wallmounts/signs.rsi/direction_court.png create mode 100644 Resources/Textures/DeltaV/Structures/Wallmounts/signs.rsi/direction_justice.png create mode 100644 Resources/Textures/Objects/Misc/bureaucracy.rsi/paper_stamp-notary.png create mode 100644 Resources/Textures/Structures/Storage/closet.rsi/cj.png create mode 100644 Resources/Textures/Structures/Storage/closet.rsi/cj_door.png create mode 100644 Resources/Textures/Structures/Storage/closet.rsi/cj_open.png create mode 100644 Resources/Textures/Structures/Storage/closet.rsi/clerk.png create mode 100644 Resources/Textures/Structures/Storage/closet.rsi/clerk_door.png create mode 100644 Resources/Textures/Structures/Storage/closet.rsi/clerk_open.png diff --git a/Content.Shared/Access/Components/IdCardConsoleComponent.cs b/Content.Shared/Access/Components/IdCardConsoleComponent.cs index 417b77855cc..c994d83d9c5 100644 --- a/Content.Shared/Access/Components/IdCardConsoleComponent.cs +++ b/Content.Shared/Access/Components/IdCardConsoleComponent.cs @@ -89,6 +89,9 @@ public WriteToTargetIdMessage(string fullName, string jobTitle, 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 P@xgTe~DWM4f39E$c literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Ears/Headsets/justice.rsi/equipped-EARS.png b/Resources/Textures/DeltaV/Clothing/Ears/Headsets/justice.rsi/equipped-EARS.png new file mode 100644 index 0000000000000000000000000000000000000000..0633bb36441674a5eddb9d7907ca1a5b08699128 GIT binary patch literal 628 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV9d*Ob`Ho)PG(@xm{>aTthP&_ z#Ibtg4hbEPNk?OOB70_OOzd^rcrdBQ=*FF$pO-$nxAU&`h2p0&+$<%N1E*)vB zS)(9R^rYd?bT9uYKRpYVoyqT-8&M+jXVvm)KM!`w=cLF6@9?+Cc-H0i)aI31;}lbK z?XBKv=6Zo@oeL%|IALVT^~HOu%I5vG5A*NyRDP8Bv_0~upnKbz3g<;)OS8SQqP|S2 zu?!1+xBqj=B1R(&bLiX^rmfIwWhd+eWPjRBJCS@o8xZY z-}QyHZ$XC7ZKqc&fDyo1;1OBOz`%C|gc+x5^GO2**Lb=(hE&A8y|t0IK|z2u;E~L_ z2MT90AI-{2PU37~?n?h#Trn-UoKJbaBeXWy?yT}1n?a;u$h>hXKz2(g#_i`P}^{@Un{6BCZw#M`GOv&sQ o;qr&hXurt8riDWwL%4#$q+NJ@K~vOgpt~77UHx3vIVCg!0LP{XRR910 literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Ears/Headsets/justice.rsi/icon.png b/Resources/Textures/DeltaV/Clothing/Ears/Headsets/justice.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0ce0c363f81ec594bc330d63cd30799599611907 GIT binary patch literal 728 zcmV;}0w?{6P)0NRq`}3|WktD3OguvB6@DGT7X?^QGqAx!pUHWUFi}l!e&% zTKEsxDqBh^Qj(p$uZ^bbJ!Wbo&h6ay*K^MEcFuFaKb12~w>Au>RdAw{5p6!cpw&MU zpoI=b7}X8eo}QhE@$dM!#i!~`zv}h>zCTA(GUXcJYY-kXY^NYRCOoxLuoZ6#w;NeK zDSRLta^!%*mr75R`AKo6%x{XFSaclxs;8Fu!HFMiWF1quPdI4iibmx;>L!7dH8(4@ zOJ+ANQ6`C?k)X&jISTYkwIs8@ec^B440-Vw^0!&V5l4osctfHVrE5xRTJ)5BIaXEf zzw>m{g9GL6fe6$+dfsaf)Ney+%kw@DJ+E{GH4kuZRsDI%Y4~0At*RE>ht_pCy{Kx5 z9XQ*7&U;&T^lzy~razsAmlJ4?L)$epE|#;ZtaE$^u{C+3E7;wGUfJKe^aYNfXiVEe z>Zkw!010qNS#tmY3labT3lag+-G2N4009t5L_t(oN9|Ox4uUWcJ&Y3xj>5!-i%$Fm zD}Tb`H^K*qi)>6qH;E+10l6j+FbG%L#KB%d3iR&YyLasYXwwR41^!(DLqq__aq5j_ z!M!YjF(wo%f-~xi;CY^R4}ME0r6%Zu`@XM~#EMD+{lYMW%=3$OKv-(=_=jwgl&atdWPw z&hzU1;lP1WjdPm9CCdi!wrzK_p(qMc?lrXn1Zyhh07;TePC_a;<`QZF_B@W`$=-{A zQ;Q$?^=0mFeEYu$WG?6vOa`2EP{s%?IdF4@>3yw$RzNH869wM2dTcC2di%!!0000< KMNUMnLSTYB21$$n literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Ears/Headsets/justice.rsi/icon_alt.png b/Resources/Textures/DeltaV/Clothing/Ears/Headsets/justice.rsi/icon_alt.png new file mode 100644 index 0000000000000000000000000000000000000000..2142eee0392083d55fbd91f71fb92f30607e72ee GIT binary patch literal 876 zcmV-y1C#uTP)0NRq`}3|WktD3OguvB6@DGT7X?^QGqAx!pUHWUFi}l!e&% zTKEsxDqBh^Qj(p$uZ^bbJ!Wbo&h6ay*K^MEcFuFaKb12~w>Au>RdAw{5p6!cpw&MU zpoI=b7}X8eo}QhE@$dM!#i!~`zv}h>zCTA(GUXcJYY-kXY^NYRCOoxLuoZ6#w;NeK zDSRLta^!%*mr75R`AKo6%x{XFSaclxs;8Fu!HFMiWF1quPdI4iibmx;>L!7dH8(4@ zOJ+ANQ6`C?k)X&jISTYkwIs8@ec^B440-Vw^0!&V5l4osctfHVrE5xRTJ)5BIaXEf zzw>m{g9GL6fe6$+dfsaf)Ney+%kw@DJ+E{GH4kuZRsDI%Y4~0At*RE>ht_pCy{Kx5 z9XQ*7&U;&T^lzy~razsAmlJ4?L)$epE|#;ZtaE$^u{C+3E7;wGUfJKe^aYNfXiVEe z>Zkw!010qNS#tmY3labT3lag+-G2N400E>)L_t(oN9~j`Pr^_T#}608gt}QKHe75R z7)TnN7-WS{!s4f6U~R&vbrBO1rh+U&Y$XoW|0UPd(E8qMH7>oRd2QdlyWjoayGK-6 zr9h>?KPyl(&41bH#8`7$uP00Iecw2aEH+wr?KqrV?EP?H5E+YrXak^fN%pi@@VYD@ znbTEP3qTT~(yRoSPpe@9p#-=c4B{|~XtUjZ+jmr$mRun4-vr=9CDn8`tDQ9(N6D>b zlK>~{0l3@m`H_RFij8@t0(n7DF(6>i%O%a{^Tf5+>k;Nml+b}a^0{%{xYcUKtJR91 zZnqmpQN-`~uM+40La{Kw`nq&P#A{v@bK4CaOVElz z5GdPR>0sM-(oXC3I@2E)&z0jOML+uf@7@7`NP}d_iaTthP&_ z#Ibtg4hbEPNk?OOB70_OOzd^rcrdBQ=*FF$pO-$nxAU&`h2p0&+$<%N1E*)vB zS)(9R^rYd?bT9uYKRpYVoyqT-8&M+jXVvm)KM!`w=cLF6@9?+Cc-H0i)aI31;}lbK z?XBKv=6Zo@oeL%|IALVT^~HOu%I5vG5A*NyRDP8Bv_0~upnKbz3g<;)OS8SQqP|S2 zu?!1+xBqj=B1R(&bLiX^rmfIwWhd+eWPjRBJCS@o8xZY z-}QyHZ$XC7ZKqc&fDyo1;1OBOz@VoL!i*J5?aP4C;p*w)7*Y}U_LgDxp#XscAA?T_ zO}NoyRU%lTXJJwP`L@UYM(6#GA8(fwzf-W-@#2keARCIiqZ&_LX zz50FXPT`-={m%x~FaBB5v*^Wn|E@(7?tVMH<=NWD;eKW!>rb+^SoHbtd|s)yu%gyR zV9%p)Hjbmc@#@Eqx3_)SC3~}GxlvW+wEmk;x7POQgs+tOW<7J?{+ZXd%wg#Nu`J~) z*PQqJ#1e3F= zf2PlceHaqiPgQ-H|9R`{nucTYe80kH`x`J%`TAnBPOaelF{r5}E)VQCV03 literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Head/Hats/cj_toque.rsi/icon.png b/Resources/Textures/DeltaV/Clothing/Head/Hats/cj_toque.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a06285c67cf62e498813b9a494d5a41ea86ab70 GIT binary patch literal 647 zcmV;20(kw2P)0NRq`}3|WktD3OguvB6@DGT7X?^QGqAx!pUHWUFi}l!e&% zTKEsxDqBh^Qj(p$uZ^bbJ!Wbo&h6ay*K^MEcFuFaKb12~w>Au>RdAw{5p6!cpw&MU zpoI=b7}X8eo}QhE@$dM!#i!~`zv}h>zCTA(GUXcJYY-kXY^NYRCOoxLuoZ6#w;NeK zDSRLta^!%*mr75R`AKo6%x{XFSaclxs;8Fu!HFMiWF1quPdI4iibmx;>L!7dH8(4@ zOJ+ANQ6`C?k)X&jISTYkwIs8@ec^B440-Vw^0!&V5l4osctfHVrE5xRTJ)5BIaXEf zzw>m{g9GL6fe6$+dfsaf)Ney+%kw@DJ+E{GH4kuZRsDI%Y4~0At*RE>ht_pCy{Kx5 z9XQ*7&U;&T^lzy~razsAmlJ4?L)$epE|#;ZtaE$^u{C+3E7;wGUfJKe^aYNfXiVEe z>Zkw!010qNS#tmYE+YT{E+YYWr9XB6006&9L_t(oM`K_Z1*0J_8UmvsFd6~_90H7_ z+Ak!k@E@0+cds9iY#s|K4&W7#{?En5g;UFKp#0|#Pf2nF(TYKqv$C>+Eyw1FZ{NOw z<$nME%|MDHn1~GlkfG60abOETmZ4*iI7prp%RzP%9ReW5pin3(C}2=l5NCMx`Xz&# zy&l7^gO?b@M8z4d-G0e1b?OA#I{*|7xT1j6;3qi*V4;93+DHw4Vxxal-Dn7mhQMeD hjE2By2n_EK000Y@PE)UtxyAqh002ovPDHLkV1oKU9f$w` literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Head/Hats/cj_toque.rsi/inhand-left.png b/Resources/Textures/DeltaV/Clothing/Head/Hats/cj_toque.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..60426ff87fd29312e636f4662f9e04a2e77339e0 GIT binary patch literal 832 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 C3xgN{ literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Neck/Cloaks/cjcloak.rsi/meta.json b/Resources/Textures/DeltaV/Clothing/Neck/Cloaks/cjcloak.rsi/meta.json new file mode 100644 index 00000000000..a0670a97c96 --- /dev/null +++ b/Resources/Textures/DeltaV/Clothing/Neck/Cloaks/cjcloak.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC0-1.0", + "copyright": "Spritework by leonardo_dabepis (Discord)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-NECK", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/DeltaV/Clothing/Neck/Misc/prosecutorbadge.rsi/equipped-NECK.png b/Resources/Textures/DeltaV/Clothing/Neck/Misc/prosecutorbadge.rsi/equipped-NECK.png new file mode 100644 index 0000000000000000000000000000000000000000..ce4e527400f155d092f564064b37b9a6fd13deb3 GIT binary patch literal 607 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEU@XXVb`Ho)PG(@xm{>Y-zxQDW zk>mSwr*?&Ptx$M0VWC*NSXYyU7whhj_H9j})1S=R;xwtvyGtbe;L(K-6n6c{{$PJ0 zv>;S~#Z{oN-Nj(7Z5uBgTXTf>k>;b0h2asOZ62v9UX3{! zB)8m@QCf1zgccT7(Hy7tW{cFxY1eK}&-gJdP>p}_{#Gpu%Px(H=5AT7yH-sxy%hSZ zB;@Fw|K~4XOIx=0-9nWMzhCW|KiQ!`e#P~e@87SKzD{>|z`DaM`k&F+%y+ZDM0t11 zFh7)i@M+mnP4)v<^$fn{oQ%oyV2rBsWwz66IA~)~!~bP{_2#U1kNEakt5%>1OLf!@gfwqfP z%N&eTMB7>oG*y2LVZ>D1_nkZ77hUg2N2^cQ=$LQ+H)Gw z@#XZnbg!NdSiF@JuQxt>)LH z;5!2FVH87%%FMQwvWq!%jh{!VrFe*oUft_D#y~-}8Q|+9o@Ewyi06sZTaG1ok9dTY zE@~=<%0ep35u%e$i7Zwz1O2ti%oCDdLEsS6K5r;wB;0T**=% zr!@f^8KjVe1O*jrLWhGmWs_#s*_UYemQf}TqrZhJI5~bjqkKyV+Z*If7a)OG7;K;Q+qHe3EO&1vqN^jb@c90TDU;PR%W zDF?vSE-?0N$y{zo0a|`d13oT*!8|a05A?5lvuf_+{0Ycy(-YkRhetq^>cbm<+Gc0@ ziLXu;00009a7bBm000ie000ie0hKEb8vpVGweA)h=c>RI08mE6fXoW zx}XL@xy`#lo(6 zllNZ@cn~Bhm-~UX;V+U(&*%SQoZ8$Uk?D7`8^Q#={k`8tJTpKLtz{R;EeeKlY+Unv z&+keXUK@$H1*(GD*X}Fu>^Di#SCdG8_=N1}fB=i7n}AdY^mo(p*uS*pTHi5%;5`$w zvSR|#2uAR()k9>>81}4th`g#Tzn4C&#!{(gn0nLY+Js{Ry^RU;c_LmG9BF4G1h4s= z!S9cmYfTV1ULBW4mj~ZtJ8xj}d)^Vl69e`&k&WZdw@61WG`hDTPFhWT-s+HPJL zh&pMYuIgdt*UAE(G`Hg9^bZaW3c|oq{tV}cV$F;Scq&rD=HVt{$(OjeEJ^HK-)muD zt7r^4VK`m^>8A!rJtWZWO5^y-1iklF)iOtd!}p+Lh|%{;kHmOl`+> z{ZZJ1)mf@@tFL>E!q1}Yocs3+&f1=T#r8&cZWNok_sa8gV>K`XN)yxrr>*o}cJ8OS oTVs_lEB!wy9u^51xOWWv1&=&5X?=^%A^-pY07*qoM6N<$f?3eo#{d8T literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Neck/Misc/prosecutorbadge.rsi/meta.json b/Resources/Textures/DeltaV/Clothing/Neck/Misc/prosecutorbadge.rsi/meta.json new file mode 100644 index 00000000000..7f12698657f --- /dev/null +++ b/Resources/Textures/DeltaV/Clothing/Neck/Misc/prosecutorbadge.rsi/meta.json @@ -0,0 +1,18 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "sprites by leonardo_dabepis (Discord)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-NECK", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/DeltaV/Clothing/Neck/mantles/cjmantle.rsi/equipped-NECK.png b/Resources/Textures/DeltaV/Clothing/Neck/mantles/cjmantle.rsi/equipped-NECK.png new file mode 100644 index 0000000000000000000000000000000000000000..9a881bf0dd0d24b2a35d5f4b346901bcaba2c084 GIT binary patch literal 1346 zcmV-I1-<%-P)0NRq`}3|WktD3OguvB6@DGT7X?^QGqAx!pUHWUFi}l!e&% zTKEsxDqBh^Qj(p$uZ^bbJ!Wbo&h6ay*K^MEcFuFaKb12~w>Au>RdAw{5p6!cpw&MU zpoI=b7}X8eo}QhE@$dM!#i!~`zv}h>zCTA(GUXcJYY-kXY^NYRCOoxLuoZ6#w;NeK zDSRLta^!%*mr75R`AKo6%x{XFSaclxs;8Fu!HFMiWF1quPdI4iibmx;>L!7dH8(4@ zOJ+ANQ6`C?k)X&jISTYkwIs8@ec^B440-Vw^0!&V5l4osctfHVrE5xRTJ)5BIaXEf zzw>m{g9GL6fe6$+dfsaf)Ney+%kw@DJ+E{GH4kuZRsDI%Y4~0At*RE>ht_pCy{Kx5 z9XQ*7&U;&T^lzy~razsAmlJ4?L)$epE|#;ZtaE$^u{C+3E7;wGUfJKe^aYNfXiVEe z>Zkw!010qNS#tmYE+YT{E+YYWr9XB600VkSL_t(|UhSH{Yg17a$8S@A;HaQ!X%}4_ zL_1_CZtg+?LjQq+75oQU3OX1lag2kYLjM7$1l+qxhYTtXF70Azql2SJZDYPSIggW< z_j=BIFE>y;7Xte3J@*V&ZF~ItJRC=U8~i?dr1=J ziAeKBVPk*%k_OEc)kuwpz>lM&UcKHNqmLjw$9yOVq!07ZiT~(%R(;jASzV}j)3w*n zUA0m*ZuIZ0`eKq0zjb`U3+!F| z>l&R8?s~aA0s-cKcDrt)^3d_MlYqeWIjpdTbvWMWWSpQXs4?JIQ zbluy{dH40xiK94eB5CWe544jYB*l<HW8v3Gm*`$YCiOZ36;6{LB5kCHxmSxz7E znQlN@a+AFBX&V0a^&w!MK8k!TjALl8KE(z-wY=9{io>6;Jq3ZP1iegS~FF*i5WKe0m-WqMSmd0ztMi2O7|m9$i&2LvjS zhwjzE$pSpg!#GBf{s0j`nt4ta%?gwhK!myt{M6BpK*rIJ@P1=q?7%fm66#j~yC)SO zQKR#Tu#OGQ)yuPnx57XZ#;G5H=f>-Xl8zbx1gQSTH$|O}Uqet2HPD1XT`0(h_anS& z4{C!L)XbsDLj{1$C)VFs!BQhwbPaM@+d6bl>er%143yV|1CTTqb zMU5uKQ`?KSA3@V5BLeX6{;b?|G>z&kX}nol6dN%#Im4T}MJB|F=G}7|{Rktup&p-9 zlh11)bliE%H#861-v}51BVYuKfDtePM!*OdfpG%=03&uuhB5S%XaE2J07*qoM6N<$ Ef*^o--~a#s literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Neck/mantles/cjmantle.rsi/icon.png b/Resources/Textures/DeltaV/Clothing/Neck/mantles/cjmantle.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7fd93b7fd5b97f8fd15cad9174ba1618fa234c1c GIT binary patch literal 744 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 U)yR3|H~;_u07*qoM6N<$f@f8Te*gdg literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/OuterClothing/Coats/cjrobe.rsi/icon.png b/Resources/Textures/DeltaV/Clothing/OuterClothing/Coats/cjrobe.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..eb6ff72244d2c3e507ee9e791fb11826a1dc5a5f GIT binary patch literal 979 zcmV;^11$WBP)0NRq`}3|WktD3OguvB6@DGT7X?^QGqAx!pUHWUFi}l!e&% zTKEsxDqBh^Qj(p$uZ^bbJ!Wbo&h6ay*K^MEcFuFaKb12~w>Au>RdAw{5p6!cpw&MU zpoI=b7}X8eo}QhE@$dM!#i!~`zv}h>zCTA(GUXcJYY-kXY^NYRCOoxLuoZ6#w;NeK zDSRLta^!%*mr75R`AKo6%x{XFSaclxs;8Fu!HFMiWF1quPdI4iibmx;>L!7dH8(4@ zOJ+ANQ6`C?k)X&jISTYkwIs8@ec^B440-Vw^0!&V5l4osctfHVrE5xRTJ)5BIaXEf zzw>m{g9GL6fe6$+dfsaf)Ney+%kw@DJ+E{GH4kuZRsDI%Y4~0At*RE>ht_pCy{Kx5 z9XQ*7&U;&T^lzy~razsAmlJ4?L)$epE|#;ZtaE$^u{C+3E7;wGUfJKe^aYNfXiVEe z>Zkw!010qNS#tmYE+YT{E+YYWr9XB600Ik1L_t(oN9|R+N&`U@y?GduVAKS0jf$O$ zk(8Q3|3F9@KR^U)vGxP3EVLEHM#M%);UB0FEJZ`G6E%s*iVxz0#MLv)EUWHhW=SKs z7lxhLd+#~t-kF^x^33bNfA4_LZ3CwI#tc!;QKje_&s74*uj@6T=7C_8+=}q4cA&I1 zXmt4k1QI91d-xHjiitQS0sD(dV`;gY;esU97Gv|Z&2{#~8t-9}5@Cb``} zp3P=05q6(byhxDr3{3P6vuZ;Apj9Q-2RElwC=@7@$9HFbXL1(m4SrYq&D)a za>T)Sp6o101ppu%3Nsv3#zpWp+t={h<7MRV3)_>==M7EM=<>46aOUP0m=J7-$WZm` z`zvj4ZLpA`p(ItSRm$aZLY}4_h@a0g5RBcOO{+Q({T#eYh~qiPmzjA|98A|A>DaeI zRJ{1*ZMMJ2!(fJdJ{RyvKNFtU+0|$8szsu)Js6J<6=htdLnv!wD}GOa@DPgHIvj{F z7ytQS&M&88!@LLFm@5Hep%}Y}_-$t=8jr>a{?ixpCR8=$GmwtN8Kx7t{XLIU6`=gN z05ICoBmK|Up6^^?stR?C`??!i%J-7J4*ZD@d;-fKyUB0_YmNW_002ovPDHLkV1iZo B&shKf literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/OuterClothing/Coats/cjrobe.rsi/inhand-left.png b/Resources/Textures/DeltaV/Clothing/OuterClothing/Coats/cjrobe.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..f7b9b21ebdba468b4db6d332a66132674c01058f GIT binary patch literal 1058 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 D_Phh$ literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/OuterClothing/Vests/clerkvest.rsi/icon.png b/Resources/Textures/DeltaV/Clothing/OuterClothing/Vests/clerkvest.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..443dbf1af9775da318c591b41f8813205b7e22ee GIT binary patch literal 709 zcmV;$0y_PPP)0NRq`}3|WktD3OguvB6@DGT7X?^QGqAx!pUHWUFi}l!e&% zTKEsxDqBh^Qj(p$uZ^bbJ!Wbo&h6ay*K^MEcFuFaKb12~w>Au>RdAw{5p6!cpw&MU zpoI=b7}X8eo}QhE@$dM!#i!~`zv}h>zCTA(GUXcJYY-kXY^NYRCOoxLuoZ6#w;NeK zDSRLta^!%*mr75R`AKo6%x{XFSaclxs;8Fu!HFMiWF1quPdI4iibmx;>L!7dH8(4@ zOJ+ANQ6`C?k)X&jISTYkwIs8@ec^B440-Vw^0!&V5l4osctfHVrE5xRTJ)5BIaXEf zzw>m{g9GL6fe6$+dfsaf)Ney+%kw@DJ+E{GH4kuZRsDI%Y4~0At*RE>ht_pCy{Kx5 z9XQ*7&U;&T^lzy~razsAmlJ4?L)$epE|#;ZtaE$^u{C+3E7;wGUfJKe^aYNfXiVEe z>Zkw!010qNS#tmYE+YT{E+YYWr9XB6008|-L_t(oM`K_Z1*0J_8UmvsFu)^~bTJL9oek5P>L{P{CpE68#HHwVO0WbpOJX9i@45$iD~ zVim&Ffh-4EhHg1FM-gK-$qpdKP*T*8H%Dq r6RHb{38hgrqaiRF0;3@?yh8v0o7h!0tg)Lb00000NkvXXu0mjfp!7G| literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/OuterClothing/Vests/clerkvest.rsi/inhand-left.png b/Resources/Textures/DeltaV/Clothing/OuterClothing/Vests/clerkvest.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..cf49f4588a69013853e1b0e5505a5b2b01fec9d6 GIT binary patch literal 785 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV9d*Ob`Ho)PG(@xm{>aTthP&_ z#Ibtg4hbEPNk?OOB70_OOzd^rcrdBQ=*FF$pO-$nxAU&`h2p0&+$<%N1E*)vB zS)(9R^rYd?bT9uYKRpYVoyqT-8&M+jXVvm)KM!`w=cLF6@9?+Cc-H0i)aI31;}lbK z?XBKv=6Zo@oeL%|IALVT^~HOu%I5vG5A*NyRDP8Bv_0~upnKbz3g<;)OS8SQqP|S2 zu?!1+xBqj=B1R(&bLiX^rmfIwWhd+eWPjRBJCS@o8xZY z-}QyHZ$XC7ZKqc&fDyo1;1OBOz@VoL!i*J5?aP4C;pyq(7*Y}U_SQzOLk0p34>g(= zbxiJF(EUK|2b1hB>)#yj>^iICkEs_178D8z-q8}z)LgnW*CJZ0e%S@J>5sGf_&N}eermlwNsiF@Ta>8d9 z-1uL&@$Ri|Z^wDNQ>2f2AM^SaoAhrFOG@M6e_7Wj23_!oc;qQ__L7(LiZ>0{e`h|H zYu>rjKCe*I<^1Zpje9CWA5W3IuWh^{&agUbv|-wAAyQsCbAYGO?`$MDvg uQ?H`;{KWkZU(`LmN&ELeJ)O~hfZbtoblQ97(!0QrX7F_Nb6Mw<&;$T8JyaaTthP&_ z#Ibtg4hbEPNk?OOB70_OOzd^rcrdBQ=*FF$pO-$nxAU&`h2p0&+$<%N1E*)vB zS)(9R^rYd?bT9uYKRpYVoyqT-8&M+jXVvm)KM!`w=cLF6@9?+Cc-H0i)aI31;}lbK z?XBKv=6Zo@oeL%|IALVT^~HOu%I5vG5A*NyRDP8Bv_0~upnKbz3g<;)OS8SQqP|S2 zu?!1+xBqj=B1R(&bLiX^rmfIwWhd+eWPjRBJCS@o8xZY z-}QyHZ$XC7ZKqc&fDyo1;1OBOz@VoL!i*J5?aP4C;qB?-7*Y}U_SRmmLk1#k4>g(= ziKvSoRN}~MGJkO4?#nJBTwBC7@zDh5Uz4LM<~o_G$Isgm+js1P zBLgFgfCCzFKy$*8?k&D9QTNuJPg`;$L*S=R=AZ3RarzA>D{lR0TgCT)<%Zt%`?qVi z-&*qh_*tIc6Hmskw+gsfHRUPP_f&F-uM&RnwJxpr`|+6* zFK_Q}*cnQ{XI6Nds0;vvhH zf7Lrwj)n!zUK|y<_W!!G`M;|58|w4A#aq8HO>q5`n=YCC_xqxQPG>)}O-R`GKhJvO z!b8_K_K7=0|JM)DoU`Za+u8Q^>q-Q>6d_hPa5VCZ?TIUx`}AKsFsvCoUHx3vIVCg! E05ED~Z~y=R literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/OuterClothing/Vests/clerkvest.rsi/meta.json b/Resources/Textures/DeltaV/Clothing/OuterClothing/Vests/clerkvest.rsi/meta.json new file mode 100644 index 00000000000..11ac46694ce --- /dev/null +++ b/Resources/Textures/DeltaV/Clothing/OuterClothing/Vests/clerkvest.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC0-1.0", + "copyright": "sprites by leonardo_dabepis (Discord)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-OUTERCLOTHING", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/cj.rsi/equipped-INNERCLOTHING.png b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/cj.rsi/equipped-INNERCLOTHING.png new file mode 100644 index 0000000000000000000000000000000000000000..24c2af227bb3225ef1a887fbcb027fa911c53dd0 GIT binary patch literal 1719 zcmV;o21xmdP)0NRq`}3|WktD3OguvB6@DGT7X?^QGqAx!pUHWUFi}l!e&% zTKEsxDqBh^Qj(p$uZ^bbJ!Wbo&h6ay*K^MEcFuFaKb12~w>Au>RdAw{5p6!cpw&MU zpoI=b7}X8eo}QhE@$dM!#i!~`zv}h>zCTA(GUXcJYY-kXY^NYRCOoxLuoZ6#w;NeK zDSRLta^!%*mr75R`AKo6%x{XFSaclxs;8Fu!HFMiWF1quPdI4iibmx;>L!7dH8(4@ zOJ+ANQ6`C?k)X&jISTYkwIs8@ec^B440-Vw^0!&V5l4osctfHVrE5xRTJ)5BIaXEf zzw>m{g9GL6fe6$+dfsaf)Ney+%kw@DJ+E{GH4kuZRsDI%Y4~0At*RE>ht_pCy{Kx5 z9XQ*7&U;&T^lzy~razsAmlJ4?L)$epE|#;ZtaE$^u{C+3E7;wGUfJKe^aYNfXiVEe z>Zkw!010qNS#tmYE+YT{E+YYWr9XB600i$zL_t(|UhP{=PZU8AtrbWVVo1=4341^< za`8+^^e@PTUtr|K)fi(uni!QU2gQRwfP)Z!fJPJKz(KvB2jH+IViZHraZ^9$J zo!ObLo}FEcU1T#mGu{2FUe(mhP8A|S0t118z(8OiFc26B4E(1IRQ^S~XJ==l{{DWc zR;yC0)nt8rT}DSoy=+lUs#dQ?AZ%*tK^-6znwYqsa9OK;Qmv_R0P(ZtXz`tu1$bvy zmvqIS-JKnonVE(MDzOKmv9WPE)7>rm`}=Ybf3!-tkU)Hlg$}@?nEP7%Q?B4Jkizc+ z0|QA!*ymh4<$}vGSdSPmmL#NYF;0V@OMnRub}3t1Te7ycCfHJVUaLeF8IADM=J?>} z55PKKPjt@aEx`tSm3e1Ltr0S7}Bguz$BFTyervcGY4q# zou31ea5;JmHlO@(9Qz;z=gSnXZ{LZy?}M+p1V{pnG!r4SewhSt?X(==V?5SVMF16m zx5+xT*l&jvNq*GVivW{|b{O7FObr2*JjRdCJ116+AxNw)_}T>QOhCM_Jbm^kdD=_6 z25}tcF|I6e!PjCt6TpQ(et0b}XI~r>0mHG678*JhZ)G9emJtE%#xKLBux4N& zFc26B3<8(+ZzCE6#-_GgsnK<4ZeFjm#kSpGHdFy3Rj`?S)v1HjmHE z%?Wcu9TK1YX@;lP{m&Coe!xia;0W1l_cv@)qlJtO8+sQX;^tOqCh|VAy;u zj_+ml1!Z~DF3acD3>vMaPJ(GQIA3sWxN^L0ys48`7Zm}l&)bTlMh`*1z?GZ6X1UE{ zPXb1xKcJ|nbATNI=6=zxFc)LkC&aO7RVqymP(^^PpqT($od?W^9&Om0c6brsTZ?z` zu+JFk<3oh{IUp_cTHPpR-+6otrybq|aDjF;M*zPW*jfVel4jm{p9r_- N002ovPDHLkV1fg`A9(-( literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/cj.rsi/icon.png b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/cj.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..77371a3ba8c82b2b47d2bfbd3159a13792c60827 GIT binary patch literal 995 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 KMNUMnLSTZ`0gvGT literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/clerk.rsi/inhand-left.png b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/clerk.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..5dcb8e026ee553ee2026f27b8edb10f6232c786e GIT binary patch literal 967 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV9d*Ob`Ho)PG(@xm{>aTthP&_ z#Ibtg4hbEPNk?OOB70_OOzd^rcrdBQ=*FF$pO-$nxAU&`h2p0&+$<%N1E*)vB zS)(9R^rYd?bT9uYKRpYVoyqT-8&M+jXVvm)KM!`w=cLF6@9?+Cc-H0i)aI31;}lbK z?XBKv=6Zo@oeL%|IALVT^~HOu%I5vG5A*NyRDP8Bv_0~upnKbz3g<;)OS8SQqP|S2 zu?!1+xBqj=B1R(&bLiX^rmfIwWhd+eWPjRBJCS@o8xZY z-}QyHZ$XC7ZKqc&fDyo1;1OBOz@VoL!i*J5?aP4C@!!+MF{C2y?X3M?EQSKd7RxM> zyD_gKBUMqU?AC7{GqHUQy{)|orEAynKhloT%ur9-I<=^&wYTD*_MgwJ&v~kMPv5Dc zty8!1P}(Qe&$nlq7#}N`z`%(W{n2L<*1ThD`L4!k`Q5ykZ}0BaIQ#Qjm!;K>ja9$f z=W6Ko=1-Pd9B5Whmt1_;>i+Ay{4=>^-dYyKec4i-^kxx5$LAdf4w*AJoZz=u+&bZU zccIU2bBTuPo4e=R^K-1*Y;@g0JoYY<@J@nmIOTzaopF5LOqM*f^Y7Z>J+7uQ~G;=Q_a<^6`L zn*SS~m#*Ku@w~=m?u(z6Iv!465P5#yva>#$Gv%Z@hIdobH1BIDdTS%&RBanBYklhLovW_7sitgx3WisRr`Yu}2{L}rdleae~* z|Cr15UeDT8^Ok`j>(soKC?%QW literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/clerk.rsi/inhand-right.png b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/clerk.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..5e7d37745187ab3867fdeb0e22655dceb99718e9 GIT binary patch literal 952 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 D52}=N literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/prosecutorred.rsi/inhand-left.png b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/prosecutorred.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..d04680f3ca65d0edec4b2d879fbca4607012024c GIT binary patch literal 983 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEU@XXVb`Ho)PG(@xm{>Y-zxQDW zk>mSwr*?&Ptx$M0VWC*NSXYyU7whhj_H9j})1S=R;xwtvyGtbe;L(K-6n6c{{$PJ0 zv>;S~#Z{oN-Nj(7Z5uBgTXTf>k>;b0h2asOZ62v9UX3{! zB)8m@QCf1zgccT7(Hy7tW{cFxY1eK}&-gJdP>p}_{#Gpu%Px(H=5AT7yH-sxy%hSZ zB;@Fw|K~4XOIx=0-9nWMzhCW|KiQ!`e#P~e@87SKzD{>|z`DaM`k&F+%y+ZDM0t11 zFh7)i@M+mnP4)v<^$fn{oQ%oyV2rBsWwz66IA~)~!~bP{_2#U1kN*?YcQW5ud=0>l>0U~Yv zN-r)2X>ny8b^IWECsw3}<>0}iZ(M7b*bf>`ZoVZhz~y)CYI=rw=0@kO)0Ql9H7L^B zZjyQV&XM5PQ|-Myiq8F?|NHLk>V@qb;v5YOIFLgS)9&KzID_pmdew*T^?!O$agO`g zk*gOak8kmt;Kw7reWD+Ki{A6Fj{C30)|Xi5R~)@~aplb9BMchOx3^UrKi{`)@1dtt z^K|!FoO}EyaaSjc^Q2`eN3N{NeKu{yt%A(w-xjG?Z{F&^np<<%`l~A+S%lQob9|k0 zsndAbOpAkw8*it(Z>gxe`#VN!Dw~t!xnBnrMRm2W1bL~So8c11ApPmm`#B=JHqWhJ zH~IAzjj87@y!`Wh)ePHv%BMFe{asR0qS*14(Pqc)W69UeXP^D??oV9$hdC-sKfh*} zqIkaSzi7=hT^}#?Q~o)u8jGWrzx~W(=Ps(UR`{tpUjy&#vtif6?=J4*_^r3p_*DE8 zkr(C<7N7h3W6ARATKN@mPjw}eHRmq*Fp-@}fdL2lu${xBbkXF$$(D&?L31G1Diup5L*l%Vq2+hq{ y%=p3UMY-zxQDW zk>mSwr*?&Ptx$M0VWC*NSXYyU7whhj_H9j})1S=R;xwtvyGtbe;L(K-6n6c{{$PJ0 zv>;S~#Z{oN-Nj(7Z5uBgTXTf>k>;b0h2asOZ62v9UX3{! zB)8m@QCf1zgccT7(Hy7tW{cFxY1eK}&-gJdP>p}_{#Gpu%Px(H=5AT7yH-sxy%hSZ zB;@Fw|K~4XOIx=0-9nWMzhCW|KiQ!`e#P~e@87SKzD{>|z`DaM`k&F+%y+ZDM0t11 zFh7)i@M+mnP4)v<^$fn{oQ%oyV2rBsWwz66IA~)~!~bP{_2#U1kNymC>d*GaVx586#CacAgYdV1UXll||Em+#guIc*hb|Jy^#_|u{V zJAz}Dy4_y>_xS9OpANqh%+=AqRJ_^sYh1t9ef`GwxBg@{H3kFZEi_&hwxAY?HoA zU;b}qiTgVSv+q~xWUuOqd}>rbzdK`|tKVwtZ$eML$~UrpEY)yod=@+o1z$5fs|_#Gy+| z)^Foo_3gS9V~on`l^eMlzR4Qo{#qrJP#r7XAdod{-z~Ehx9&?cWP-)+N-%JndB*2T uhrC_?Rcu1HLT#wxQ7euHhiM#t7&rWup3(B$#{`&O7(8A5T-G@yGywn;ZoQHK literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/prosecutorred.rsi/meta.json b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/prosecutorred.rsi/meta.json new file mode 100644 index 00000000000..322f9da00e0 --- /dev/null +++ b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpskirt/prosecutorred.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Heavily modified by leonardo_dabepis (Discord), original sprite taken from tgstation at commit https://github.com/tgstation/tgstation/commit/3a72dd925f7d6aeec620fe83bc4f88a3d7e5f693", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-INNERCLOTHING", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj.rsi/equipped-INNERCLOTHING.png b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj.rsi/equipped-INNERCLOTHING.png new file mode 100644 index 0000000000000000000000000000000000000000..b2e475bdbe1be1521d64a5a124b31a3c54ea5727 GIT binary patch literal 1559 zcmV+y2I%>TP)0NRq`}3|WktD3OguvB6@DGT7X?^QGqAx!pUHWUFi}l!e&% zTKEsxDqBh^Qj(p$uZ^bbJ!Wbo&h6ay*K^MEcFuFaKb12~w>Au>RdAw{5p6!cpw&MU zpoI=b7}X8eo}QhE@$dM!#i!~`zv}h>zCTA(GUXcJYY-kXY^NYRCOoxLuoZ6#w;NeK zDSRLta^!%*mr75R`AKo6%x{XFSaclxs;8Fu!HFMiWF1quPdI4iibmx;>L!7dH8(4@ zOJ+ANQ6`C?k)X&jISTYkwIs8@ec^B440-Vw^0!&V5l4osctfHVrE5xRTJ)5BIaXEf zzw>m{g9GL6fe6$+dfsaf)Ney+%kw@DJ+E{GH4kuZRsDI%Y4~0At*RE>ht_pCy{Kx5 z9XQ*7&U;&T^lzy~razsAmlJ4?L)$epE|#;ZtaE$^u{C+3E7;wGUfJKe^aYNfXiVEe z>Zkw!010qNS#tmYE+YT{E+YYWr9XB600d7-L_t(|UhP^7g~QpHx2#)QP53R-9#65lYkMe6w_9k)^SeogxAL; zGxyC$Tl!uI=_K#HbMCo!?o8)i5kI^FUIDLwSHLUa74Qn2Q3Xn;(eCy2^`KIzNVQs( zR;wkQPDkeF=bda(Evi?VX5L#M#+}EJ#%c_^|?*;82&N+wDrb-4=Xu@OLeVQDO|kk6Pn`A1eTX z7~VYI+1Zh1vnlvA1u#QXr5W%Fx8mR~*^B(`B5=J!Z|n2&W> zpJo(+9~%MiC_E2OnjV2+W&}V0dK~l2b*>`V``GyAzOMKaqsT>tFB1*3G1lAXXPU4# z`4oXaQh;INm{)_Sp0lWWz8AXz>%@ z2N00Pn*<;RzAs`R-0dq-n$u7f0sV94|E(wt1{n&%te>|C!~r(m)F@q=B-8>#)#=}?zHlbsA{ZTTZ}GvAUIA@y0I*d8m`xHk zaXhB_@V?$}ns6~H$r^Y*9Kp?7clw4$anOpOej;Q7qYl95bNC)%iH?yZ#yHLifI$wx z1_zEPQQ~makHxtmOVK7ky{|dYO>tIz3cP*TmM@<_$*b4TwcK-?4=&&YZrY*p z79s!utis^)q(p#O8Ok*RAb|N?KB`uy^@7WMyB_FTp;9M7*5XXkuHY_)V~uUR$w|va zB>?O5HgVMGG0-n??XIg?$=0za0khE`kannZfE@umPTLWtF@(KB_UXvu+;RXmHbcxz zfEoj`nu{ABJNz}qgNOPuND)lnBE1jN;9!=>(sZP$1<1;KCuJXJ0kqjRPlMBNaTXv? zgNoc+bs4mYrBOZ$BhxfT5#Lz=8h@N3MD+?}A*|oSD{zJs_y^3V&=AQ*#y0=}002ov JPDHLkV1nJ{-6a43 literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj.rsi/icon.png b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..03f703a26ccf83f715569b0cfc22840f2dfb1b9b GIT binary patch literal 902 zcmV;119|+3P)0NRq`}3|WktD3OguvB6@DGT7X?^QGqAx!pUHWUFi}l!e&% zTKEsxDqBh^Qj(p$uZ^bbJ!Wbo&h6ay*K^MEcFuFaKb12~w>Au>RdAw{5p6!cpw&MU zpoI=b7}X8eo}QhE@$dM!#i!~`zv}h>zCTA(GUXcJYY-kXY^NYRCOoxLuoZ6#w;NeK zDSRLta^!%*mr75R`AKo6%x{XFSaclxs;8Fu!HFMiWF1quPdI4iibmx;>L!7dH8(4@ zOJ+ANQ6`C?k)X&jISTYkwIs8@ec^B440-Vw^0!&V5l4osctfHVrE5xRTJ)5BIaXEf zzw>m{g9GL6fe6$+dfsaf)Ney+%kw@DJ+E{GH4kuZRsDI%Y4~0At*RE>ht_pCy{Kx5 z9XQ*7&U;&T^lzy~razsAmlJ4?L)$epE|#;ZtaE$^u{C+3E7;wGUfJKe^aYNfXiVEe z>Zkw!010qNS#tmYE+YT{E+YYWr9XB600F*9L_t(oN9|NGPQySDT!&bKNGJsekn9K0 z@BsdiFYp5@K0rZ!z!%c^38|>4Xk0;KOMpNq!cI^O95Y@==TZOz10m2{WaNcE322c?yMn@NPsL9O{Mv2(*9^#_LiLqATEQ z;3WJs&AAkShykqu(w#BT)dDz!ujg3DzSKkjq``gs{~Um*51=BnTiYN;vpM-x-uv_n c{2K;-0LZK71P8U)CjbBd07*qoM6N<$f=F?czyJUM literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj.rsi/inhand-left.png b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..9b19bead358e0fc8be9ce1a23807753f7df8b751 GIT binary patch literal 955 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 KTJ?4N@c#m0(W=A% literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj_white.rsi/icon.png b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj_white.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bf6ed67bc86a2668c33a6b1a00998ceb9793daa0 GIT binary patch literal 537 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj_white.rsi/inhand-right.png b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cj_white.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..deb205205ab91d09acd1729baa444204c3560f69 GIT binary patch literal 7879 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
xVuL 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 kbrf4712OWQUrly!^`%irUedqm2=0U1cD(f|Me literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cjformal.rsi/inhand-left.png b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cjformal.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..4e73693046fa1d1ad954add9430787349fb847e1 GIT binary patch literal 7183 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cjformal.rsi/inhand-right.png b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/cjformal.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..567d302dc529f82b62c390a392703de835c62b06 GIT binary patch literal 7415 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/clerk.rsi/inhand-left.png b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/clerk.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..5dcb8e026ee553ee2026f27b8edb10f6232c786e GIT binary patch literal 967 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV9d*Ob`Ho)PG(@xm{>aTthP&_ z#Ibtg4hbEPNk?OOB70_OOzd^rcrdBQ=*FF$pO-$nxAU&`h2p0&+$<%N1E*)vB zS)(9R^rYd?bT9uYKRpYVoyqT-8&M+jXVvm)KM!`w=cLF6@9?+Cc-H0i)aI31;}lbK z?XBKv=6Zo@oeL%|IALVT^~HOu%I5vG5A*NyRDP8Bv_0~upnKbz3g<;)OS8SQqP|S2 zu?!1+xBqj=B1R(&bLiX^rmfIwWhd+eWPjRBJCS@o8xZY z-}QyHZ$XC7ZKqc&fDyo1;1OBOz@VoL!i*J5?aP4C@!!+MF{C2y?X3M?EQSKd7RxM> zyD_gKBUMqU?AC7{GqHUQy{)|orEAynKhloT%ur9-I<=^&wYTD*_MgwJ&v~kMPv5Dc zty8!1P}(Qe&$nlq7#}N`z`%(W{n2L<*1ThD`L4!k`Q5ykZ}0BaIQ#Qjm!;K>ja9$f z=W6Ko=1-Pd9B5Whmt1_;>i+Ay{4=>^-dYyKec4i-^kxx5$LAdf4w*AJoZz=u+&bZU zccIU2bBTuPo4e=R^K-1*Y;@g0JoYY<@J@nmIOTzaopF5LOqM*f^Y7Z>J+7uQ~G;=Q_a<^6`L zn*SS~m#*Ku@w~=m?u(z6Iv!465P5#yva>#$Gv%Z@hIdobH1BIDdTS%&RBanBYklhLovW_7sitgx3WisRr`Yu}2{L}rdleae~* z|Cr15UeDT8^Ok`j>(soKC?%QW literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/clerk.rsi/inhand-right.png b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/clerk.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..5e7d37745187ab3867fdeb0e22655dceb99718e9 GIT binary patch literal 952 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV9d*Ob`Ho)PG(@xm{>aTthP&_ z#Ibtg4hbEPNk?OOB70_OOzd^rcrdBQ=*FF$pO-$nxAU&`h2p0&+$<%N1E*)vB zS)(9R^rYd?bT9uYKRpYVoyqT-8&M+jXVvm)KM!`w=cLF6@9?+Cc-H0i)aI31;}lbK z?XBKv=6Zo@oeL%|IALVT^~HOu%I5vG5A*NyRDP8Bv_0~upnKbz3g<;)OS8SQqP|S2 zu?!1+xBqj=B1R(&bLiX^rmfIwWhd+eWPjRBJCS@o8xZY z-}QyHZ$XC7ZKqc&fDyo1;1OBOz@VoL!i*J5?aP4C@xjx@F{C2y?X3M?EQSKd7RxM> zyAd&`A|q8%sqEHoF}v2*-h|S%YkTz*Rtm z?-y>J?J<*f{;ZpPM%37=Z~_A-R`f@oDcP>5zn|~3&Tj2(Iq$#i`S$CN--)g4zxVDr zdH>@s`N_S%Y>t%gmfgB<W;nci+m2YW)8VTaUV#RuXkV9 zP-nx|KRIjF-LUU#Uw(Q${kr;B8<{q*O9$Vk{9H4A|1}LgopsYZUH9zWxo^um?saD_ zCS?7yI`zm%NP!U_`Vq)fJoo9TNfuri6$bMkt$53CaP-aFoX}}!0u_%n|Fq{`urA&~ zTqb$t9aV*E!V9|H=ic4^@7<##`RfW-ee~SVaO%+|%cftu|Mdlxtoh62+c1~mfWxZ4 zOxrF$!NdSiF@JuQxt>)LH z;5!2FVH87%%FMQwvWq!%jh{!VrFe*oUft_D#y~-}8Q|+9o@Ewyi06sZTaG1ok9dTY zE@~=<%0ep35u%e$i7Zwz1O2ti%oCDdLEsS6K5r;wB;0T**=% zr!@f^8KjVe1O*jrLWhGmWs_#s*_UYemQf}TqrZhJI5~bjqkKyV+Z*If7a)OG7;K;Q+qHe3EO&1vqN^jb@c90TDU;PR%W zDF?vSE-?0N$y{zo0a|`d13oT*!8|a05A?5lvuf_+{0Ycy(-YkRhetq^>cbm<+Gc0@ ziLXu;00009a7bBm000ie000ie0hKEb8vpWK77DBZU0I!mqb7)@k<(&JxW0_&CFC->AT@$C9aNjJSsg1!g)B2f*QZM zfTUicyu=7U8=UwwU)lrYqqI^?gkKW`T$cgR=;$bY{`g5fMvdQW0L#K?Kixsv-Shx! z%VF)it}iIQF9A@BQN`3An);?NzV{8#^z^iH95sHUpdE6MkFq%Ny>y%4mt6up_25)y zX{iYJ(Zc~+URtDBeFI(AT9jONgS4 zifVoiIVV|RXM>LKwgEyvKbPW{CE#G+4LbMX72SF>DDnaF=!gDc%EgyYm7eoYZj01F z9{teYuZWJTOMBb$r{f95_WPCwnw^=Uw)S>9HMdAOhQ{V|TQkKE*rXl!9rg9DdkimA zo~c3g2U-Gd$`%$D)nl%M0!Asv>pqN5BLc7{u>n3ikWzKjYu?WxIF1iy9Dn!gnC|j(2XH5Ni^bWU|1=Uc=-A zJAJrQDZzJj5(x1{1hBabHa3+b7=>3;=bNC+HJLQyW9fCQZ;)bIjP?L9&1W-eud~_I zsB-<7XdNH&rUPI^KqVZjmQG7RwU{@>^*Z}a-w8yUAl6-Gs`yV49PxT?>ZDgcg+rzI z&Z97DT&vGAU>UFsSOzQumI2FvWxz6E8L$lecMOOwMcMoQ{(f~inM$ST_{kF#+gE3# zCoG%D4?u7h@kx}Po*uCs;tqP$6?bvRhVLs9UJMNz8DK&J2Hh2EnjO z7j~X=5-);kN z@zW=I6NEC(6VjuxrujL3#(A~7@Og+jtYy9g*(5QIX(Go2!-`QTb!_SO%)Vz(013TN3ImS-=1Q N002ovPDHLkV1lje?7jd1 literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/prosecutorred.rsi/icon.png b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/prosecutorred.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0d2266c7ff736f194c2cde2bab940aa2e7391054 GIT binary patch literal 868 zcmV-q1DpJbP)!NdSiF@JuQxt>)LH z;5!2FVH87%%FMQwvWq!%jh{!VrFe*oUft_D#y~-}8Q|+9o@Ewyi06sZTaG1ok9dTY zE@~=<%0ep35u%e$i7Zwz1O2ti%oCDdLEsS6K5r;wB;0T**=% zr!@f^8KjVe1O*jrLWhGmWs_#s*_UYemQf}TqrZhJI5~bjqkKyV+Z*If7a)OG7;K;Q+qHe3EO&1vqN^jb@c90TDU;PR%W zDF?vSE-?0N$y{zo0a|`d13oT*!8|a05A?5lvuf_+{0Ycy(-YkRhetq^>cbm<+Gc0@ ziLXu;00009a7bBm000ie000ie0hKEb8vp8t*Wl%MceETLAbp92>;#T}qWK@MLqDGz9$+`i;apaB{<U1UjTT!HJihfD$zwjoWV+w?C;E+6gGaPG=~)vXcUhJCBtB z)tVacVr^4eRr@$eu$zU*RU;lG9r@Q&pz*tE2igr7s|Sv^He_)1PasQc+K&S*1(XV; ufSP$4OKLz;Kz9P-By8>&1&jiJuD~~;2cX7Z7GrY&0000Y-zxQDW zk>mSwr*?&Ptx$M0VWC*NSXYyU7whhj_H9j})1S=R;xwtvyGtbe;L(K-6n6c{{$PJ0 zv>;S~#Z{oN-Nj(7Z5uBgTXTf>k>;b0h2asOZ62v9UX3{! zB)8m@QCf1zgccT7(Hy7tW{cFxY1eK}&-gJdP>p}_{#Gpu%Px(H=5AT7yH-sxy%hSZ zB;@Fw|K~4XOIx=0-9nWMzhCW|KiQ!`e#P~e@87SKzD{>|z`DaM`k&F+%y+ZDM0t11 zFh7)i@M+mnP4)v<^$fn{oQ%oyV2rBsWwz66IA~)~!~bP{_2#U1kN*?YcQW5ud=0>l>0U~Yv zN-r)2X>ny8b^IWECsw3}<>0}iZ(M7b*bf>`ZoVZhz~y)CYI=rw=0@kO)0Ql9H7L^B zZjyQV&XM5PQ|-Myiq8F?|NHLk>V@qb;v5YOIFLgS)9&KzID_pmdew*T^?!O$agO`g zk*gOak8kmt;Kw7reWD+Ki{A6Fj{C30)|Xi5R~)@~aplb9BMchOx3^UrKi{`)@1dtt z^K|!FoO}EyaaSjc^Q2`eN3N{NeKu{yt%A(w-xjG?Z{F&^np<<%`l~A+S%lQob9|k0 zsndAbOpAkw8*it(Z>gxe`#VN!Dw~t!xnBnrMRm2W1bL~So8c11ApPmm`#B=JHqWhJ zH~IAzjj87@y!`Wh)ePHv%BMFe{asR0qS*14(Pqc)W69UeXP^D??oV9$hdC-sKfh*} zqIkaSzi7=hT^}#?Q~o)u8jGWrzx~W(=Ps(UR`{tpUjy&#vtif6?=J4*_^r3p_*DE8 zkr(C<7N7h3W6ARATKN@mPjw}eHRmq*Fp-@}fdL2lu${xBbkXF$$(D&?L31G1Diup5L*l%Vq2+hq{ y%=p3UMY-zxQDW zk>mSwr*?&Ptx$M0VWC*NSXYyU7whhj_H9j})1S=R;xwtvyGtbe;L(K-6n6c{{$PJ0 zv>;S~#Z{oN-Nj(7Z5uBgTXTf>k>;b0h2asOZ62v9UX3{! zB)8m@QCf1zgccT7(Hy7tW{cFxY1eK}&-gJdP>p}_{#Gpu%Px(H=5AT7yH-sxy%hSZ zB;@Fw|K~4XOIx=0-9nWMzhCW|KiQ!`e#P~e@87SKzD{>|z`DaM`k&F+%y+ZDM0t11 zFh7)i@M+mnP4)v<^$fn{oQ%oyV2rBsWwz66IA~)~!~bP{_2#U1kNymC>d*GaVx586#CacAgYdV1UXll||Em+#guIc*hb|Jy^#_|u{V zJAz}Dy4_y>_xS9OpANqh%+=AqRJ_^sYh1t9ef`GwxBg@{H3kFZEi_&hwxAY?HoA zU;b}qiTgVSv+q~xWUuOqd}>rbzdK`|tKVwtZ$eML$~UrpEY)yod=@+o1z$5fs|_#Gy+| z)^Foo_3gS9V~on`l^eMlzR4Qo{#qrJP#r7XAdod{-z~Ehx9&?cWP-)+N-%JndB*2T uhrC_?Rcu1HLT#wxQ7euHhiM#t7&rWup3(B$#{`&O7(8A5T-G@yGywn;ZoQHK literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/prosecutorred.rsi/meta.json b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/prosecutorred.rsi/meta.json new file mode 100644 index 00000000000..322f9da00e0 --- /dev/null +++ b/Resources/Textures/DeltaV/Clothing/Uniforms/Jumpsuit/prosecutorred.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Heavily modified by leonardo_dabepis (Discord), original sprite taken from tgstation at commit https://github.com/tgstation/tgstation/commit/3a72dd925f7d6aeec620fe83bc4f88a3d7e5f693", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-INNERCLOTHING", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/DeltaV/Interface/Misc/job_icons.rsi/ChiefJustice.png b/Resources/Textures/DeltaV/Interface/Misc/job_icons.rsi/ChiefJustice.png new file mode 100644 index 0000000000000000000000000000000000000000..6cba0e4a93f5f568d4ea91b8ef1b0845aea763a6 GIT binary patch literal 568 zcmV-80>}M{P)0NRq`}3|WktD3OguvB6@DGT7X?^QGqAx!pUHWUFi}l!e&% zTKEsxDqBh^Qj(p$uZ^bbJ!Wbo&h6ay*K^MEcFuFaKb12~w>Au>RdAw{5p6!cpw&MU zpoI=b7}X8eo}QhE@$dM!#i!~`zv}h>zCTA(GUXcJYY-kXY^NYRCOoxLuoZ6#w;NeK zDSRLta^!%*mr75R`AKo6%x{XFSaclxs;8Fu!HFMiWF1quPdI4iibmx;>L!7dH8(4@ zOJ+ANQ6`C?k)X&jISTYkwIs8@ec^B440-Vw^0!&V5l4osctfHVrE5xRTJ)5BIaXEf zzw>m{g9GL6fe6$+dfsaf)Ney+%kw@DJ+E{GH4kuZRsDI%Y4~0At*RE>ht_pCy{Kx5 z9XQ*7&U;&T^lzy~razsAmlJ4?L)$epE|#;ZtaE$^u{C+3E7;wGUfJKe^aYNfXiVEe z>Zkw!010qNS#tmYE+YT{E+YYWr9XB6003}FL_t&-S7T%V0@1*x|KG0eVc^nsVL+z8 z-a5p{$gO7gU%)XPqz(+8%!p!;$yf$v|9W+ofeEAwSrVoQM1xFY0GS}2zVtr`pwl3$ z;U>V0g_#E8gG^uo8-oLYtS9IOMv!KZJJ7ud;=f*B#|Qv96iQmwy+H8*00000NRq`}3|WktD3OguvB6@DGT7X?^QGqAx!pUHWUFi}l!e&% zTKEsxDqBh^Qj(p$uZ^bbJ!Wbo&h6ay*K^MEcFuFaKb12~w>Au>RdAw{5p6!cpw&MU zpoI=b7}X8eo}QhE@$dM!#i!~`zv}h>zCTA(GUXcJYY-kXY^NYRCOoxLuoZ6#w;NeK zDSRLta^!%*mr75R`AKo6%x{XFSaclxs;8Fu!HFMiWF1quPdI4iibmx;>L!7dH8(4@ zOJ+ANQ6`C?k)X&jISTYkwIs8@ec^B440-Vw^0!&V5l4osctfHVrE5xRTJ)5BIaXEf zzw>m{g9GL6fe6$+dfsaf)Ney+%kw@DJ+E{GH4kuZRsDI%Y4~0At*RE>ht_pCy{Kx5 z9XQ*7&U;&T^lzy~razsAmlJ4?L)$epE|#;ZtaE$^u{C+3E7;wGUfJKe^aYNfXiVEe z>Zkw!010qNS#tmYE+YT{E+YYWr9XB6002=*L_t&-S7T%V0v|rv{~#J2Z29z0NRq`}3|WktD3OguvB6@DGT7X?^QGqAx!pUHWUFi}l!e&% zTKEsxDqBh^Qj(p$uZ^bbJ!Wbo&h6ay*K^MEcFuFaKb12~w>Au>RdAw{5p6!cpw&MU zpoI=b7}X8eo}QhE@$dM!#i!~`zv}h>zCTA(GUXcJYY-kXY^NYRCOoxLuoZ6#w;NeK zDSRLta^!%*mr75R`AKo6%x{XFSaclxs;8Fu!HFMiWF1quPdI4iibmx;>L!7dH8(4@ zOJ+ANQ6`C?k)X&jISTYkwIs8@ec^B440-Vw^0!&V5l4osctfHVrE5xRTJ)5BIaXEf zzw>m{g9GL6fe6$+dfsaf)Ney+%kw@DJ+E{GH4kuZRsDI%Y4~0At*RE>ht_pCy{Kx5 z9XQ*7&U;&T^lzy~razsAmlJ4?L)$epE|#;ZtaE$^u{C+3E7;wGUfJKe^aYNfXiVEe z>Zkw!010qNS#tmYE+YT{E+YYWr9XB6002`-L_t&-S7T%V0v|rv{~#J2Z29z3;wK literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Interface/Misc/job_icons.rsi/Prosecutor.png b/Resources/Textures/DeltaV/Interface/Misc/job_icons.rsi/Prosecutor.png new file mode 100644 index 0000000000000000000000000000000000000000..997b29b2a446fecd8201e255aa482d1ef5e02c83 GIT binary patch literal 5005 zcmeHKc~leU7LT}K1Bk6vkk1Qi9XRa>i6isn&iMcs;Z~{f6#TA$mr4Wf4 zl!EFp1&O4;aoiA_b9aGt+RNCfRpVy&O+McgS@L+&<0n5QI|ZJ38a)pSIWaMkxHPX4 z8+_TYe3RzAs%+bHvK^Q2Jn4*bJ-Yj5xkqo$^E&)m(awgNE0=6?`+!*fNw@%+`Mjq5tjbo!PXPQ6UZABc#kDev1~ z?yzBT-bala7MxsA+Po&r-CwwItyS3%ZF|3|UG>{u%>Jgu&8_534m&?fUKg`+%n`cN zZ425){2IPKbF1ja&u3Db2OHZStZ~iJ@(uJ%{+WB_6^|PG6`z#PD4p*~&0N2(9i3C< zXO|xIaluYsUh%eov8hgT4)1m=Pf_SPp!xZ1s{o?Et5)+;YOhG9-~S^mBWvH^>=e6gtQM*}iz6&vo`(t!OucK-Q?s34 zy~l2B-n?g%CO4DE(N0d-(UTJ(^P|`#lM502TMG-v6i)hw74}W7^4eCH4E>IL%IZaJ zE?E=pxtpa|Eh27N-V1!P#c_dms_m?=vr^I=m$W}X(z9imcO%^-xq-7<@^Xqk&peiB zH4WOcswQWSTie+zWO=8yt*9}o>B4y1>4#GczSGt`|G-dN*kY*5%QPOV-(nwI60U=! zd)*yvpqlow`{ChhvzL^vYqq~8E*{fBc>&#~1P&pNipm+J9iKc zm##0%>+HEzX(W;t4<60GG4R9ht?DHY5Z5n@rWbZurJQQ@tmG-P@7}3CS4LZV&8V4U zyU@v|+rTfaj;}M&otN%*b}QakStk9^yQ3og(4#GZ;>*)YcKLQctK08yt9aDUPdwM1 zydlu3`_p^UIOC@emOgyoS~9fsOH|g(&aTPX49^JU8G;p z8QL0d@87iI(l^27zc$PnzaQT7!eY!~a^j^Q{-`IB#;7qLpCAlDz^VN_F8ez-@d~@v zP3&~Lg#kG&Yphpo+dDsdyWfc>**4bouG3G8e!O+Mdr_{uRJkxO?fSEip4nbsuzHDW za8AM5itWXZM2eW%ZNGH=c1_pzG`>yO=#|f2_JzB3ahT>%?)xgw`U4$aQx2p}^0Vu( zxwda#L3&^Bv)Yy;52Xzc|NXMw%Rhv5-~Rj9$<8e05sJrLkLuvcsW|xyhgBli4HQT1 zz2vWUEeXsUkgPAhfM*s&5RT7Fju-}-GG;2}P9e2{{OBJu{qB1_oVz)X%X6z%>00Cts{;dEb9ancnBnw4&H0F&`Q8HVDGQ9ydHC zuB48=|9JDnc2Ux;Slf2o2Rr}N(^gbLjN{sB)M0~(=dfpMjK@o+b#1*G$3J^CCc}w; zGr8^K)d@!Ym|wA1!IoW9qIdY*P1vDuMqq;ndwxD8A8O0 zs1ed2iVv3qdG*3X$TBgQ%sz&438s3R4Q1fyvk3dkxEDC z)w*F7fF5)`tf4b$47y51AMK$deB%Mha6*6Tp$i3ni0Hwn4v*6!sBb)~CR|2S$dM6$ zO`KL~E=P{gQ6;JZP#uWMd?Td4L>e^WVUi#UQ)$dzKt)f8VS#}P~}H2>tY*)oL!Wf}#*dpx{BUyE_}=Ddb#~C*yON zEWs#>KrIHk5>}4R%0wjxR5A`rz>^~g#1n8>AR9Rfs5o+n$7HZz4won3aph(zIU@AK zwJI2FC#HgS3rY3NLapzDX8h8~re`7lu^=3^m*k)aZFa6CGsG2j|nLZV@H6bk0YaKpZ` zV}H^NGSEEW;y|doj0tg=d<23~*d0%E&vkD{ZI$S{{z*^Kh3g`&50u5@` ziZXwAt6bm2Cq$#BeE^a{3^p_(8J9t&4;M=}O^jF7deHw%4-Ye7)QACoLpCtFz$B!P zjKX2PK(2q~HM|dhWe5u8U68lZ_nlnt5Ti#KNf^Jzu3 TKc9665l9l><>K + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/Resources/Textures/DeltaV/Interface/Paper/paper_heading_warrant.svg.200dpi.png b/Resources/Textures/DeltaV/Interface/Paper/paper_heading_warrant.svg.200dpi.png new file mode 100644 index 0000000000000000000000000000000000000000..d13d8cf76b7f251b4c1064e87cea2230f43df73b GIT binary patch literal 10022 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 RbU^?B002ovPDHLkV1kb2nQ{OC literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Objects/Devices/pda.rsi/pda-clerk.png b/Resources/Textures/DeltaV/Objects/Devices/pda.rsi/pda-clerk.png new file mode 100644 index 0000000000000000000000000000000000000000..6f690e235d826c957098322cbea4a474f77d7b21 GIT binary patch literal 1022 zcmV0NRq`}3|WktD3OguvB6@DGT7X?^QGqAx!pUHWUFi}l!e&% zTKEsxDqBh^Qj(p$uZ^bbJ!Wbo&h6ay*K^MEcFuFaKb12~w>Au>RdAw{5p6!cpw&MU zpoI=b7}X8eo}QhE@$dM!#i!~`zv}h>zCTA(GUXcJYY-kXY^NYRCOoxLuoZ6#w;NeK zDSRLta^!%*mr75R`AKo6%x{XFSaclxs;8Fu!HFMiWF1quPdI4iibmx;>L!7dH8(4@ zOJ+ANQ6`C?k)X&jISTYkwIs8@ec^B440-Vw^0!&V5l4osctfHVrE5xRTJ)5BIaXEf zzw>m{g9GL6fe6$+dfsaf)Ney+%kw@DJ+E{GH4kuZRsDI%Y4~0At*RE>ht_pCy{Kx5 z9XQ*7&U;&T^lzy~razsAmlJ4?L)$epE|#;ZtaE$^u{C+3E7;wGUfJKe^aYNfXiVEe z>Zkw!010qNS#tmY3labT3lag+-G2N400K5iL_t(oM`K_Z1*0J_8UjRyfQ6aaePCq)ihAdNQ9aHO-U#cMLy& zeqmr|=K;&}a0)RzetCsq%bs~4E?zrW2zm{u;Ntzc3}3%~XJAmkqWact25xRn22JUB z6iF_2K4Oe!Aj$zC%S&5J7;Zhhgkh+fydFb$bq~Ya504lYPW{AC(P#iy1ByBvQ3F>) zlmkGjkDWdM*CZk)1ZKZ^^$v&;;$L>}1&SgZKui!2?EpSOUJUcl#afOP6JsZe8ltn| zr}v*3U>IfsI=`d-0?7`bY6!rh;MkQZ;DkvGAldXF(+fOsRVE@M;`1KRRo73+YxZl5F_#>vo5P652C!yg8QXIx4Q+&|wiy!m*CLGm9_MiW;M=_@9K<5cq4Wehj4aDQju zU%41CQsfJd0Qf?zFcNAF<^TWy07*qoM6N<$g23v+W&i*H literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Objects/Devices/pda.rsi/pda-prosecutor.png b/Resources/Textures/DeltaV/Objects/Devices/pda.rsi/pda-prosecutor.png new file mode 100644 index 0000000000000000000000000000000000000000..e44dcea1b57c088bcd901ae4ef1344c790bcd572 GIT binary patch literal 6141 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 aJIy%T7g?1U4 literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Objects/Misc/stamps.rsi/stamp-notary.png b/Resources/Textures/DeltaV/Objects/Misc/stamps.rsi/stamp-notary.png new file mode 100644 index 0000000000000000000000000000000000000000..b726cab3d3aa4c490adc09b14135bb1b8d658072 GIT binary patch literal 777 zcmV+k1NQuhP)0NRq`}3|WktD3OguvB6@DGT7X?^QGqAx!pUHWUFi}l!e&% zTKEsxDqBh^Qj(p$uZ^bbJ!Wbo&h6ay*K^MEcFuFaKb12~w>Au>RdAw{5p6!cpw&MU zpoI=b7}X8eo}QhE@$dM!#i!~`zv}h>zCTA(GUXcJYY-kXY^NYRCOoxLuoZ6#w;NeK zDSRLta^!%*mr75R`AKo6%x{XFSaclxs;8Fu!HFMiWF1quPdI4iibmx;>L!7dH8(4@ zOJ+ANQ6`C?k)X&jISTYkwIs8@ec^B440-Vw^0!&V5l4osctfHVrE5xRTJ)5BIaXEf zzw>m{g9GL6fe6$+dfsaf)Ney+%kw@DJ+E{GH4kuZRsDI%Y4~0At*RE>ht_pCy{Kx5 z9XQ*7&U;&T^lzy~razsAmlJ4?L)$epE|#;ZtaE$^u{C+3E7;wGUfJKe^aYNfXiVEe z>Zkw!010qNS#tmY3labT3lag+-G2N400BWsL_t(oM`K_Z1*0J_8UmvsFd6~_90H8w z+Mg(7{a@lgBf|^E{|xir9VOcw7IGW_vfP%9i$RRxFM~M49|i^>pIk?f=JJgK&H00000NkvXX Hu0mjfH4R;e literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Objects/Specific/Justice/gavel.rsi/icon.png b/Resources/Textures/DeltaV/Objects/Specific/Justice/gavel.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3cf56d453711e1d07d02997fa223579b8f31a149 GIT binary patch literal 434 zcmV;j0ZsmiP)J=&Ll)CgG(?|+_o$Ghwf9~^iw`8Z+=bka=iZR#Y|ryVp0Y*G z`UluOfM)F?!nOPC6*33FO;p{o1R)5>SP@dS z2cPu*-w>Qibbt!&tYpiBARxE`-E`{F_3ab?62MxxfQd%_mjswELp6>z3J_zu5Qz>D z1PbnT9ExDRP;1_5Tt-|Fsb2v>P@DSiA9@8Yh_#<#Ql)c2X#EX2AhdtSx)3aRKnH>? zkZcRVnuxZ6V2@;R5V%KwCIE2|P!fc(P`V01iVH7BQ!zoLJ!3qU10pR+XR=i(1poj507*qoM6N<$f@Zw2pa1{> literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Objects/Specific/Justice/gavel.rsi/inhand-left.png b/Resources/Textures/DeltaV/Objects/Specific/Justice/gavel.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..a41d27bcc71f367c6771ae5b670d87dc72dc4068 GIT binary patch literal 11051 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 NgQu&X%Q~loCICE+PhJ23 literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Objects/Specific/Justice/gavelblock.rsi/meta.json b/Resources/Textures/DeltaV/Objects/Specific/Justice/gavelblock.rsi/meta.json new file mode 100644 index 00000000000..5abad9b4225 --- /dev/null +++ b/Resources/Textures/DeltaV/Objects/Specific/Justice/gavelblock.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Sprites sourced from https://github.com/tgstation/tgstation/pull/8495", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + } + ] +} diff --git a/Resources/Textures/DeltaV/Objects/Specific/Justice/trialtimer.rsi/meta.json b/Resources/Textures/DeltaV/Objects/Specific/Justice/trialtimer.rsi/meta.json new file mode 100644 index 00000000000..8081065c329 --- /dev/null +++ b/Resources/Textures/DeltaV/Objects/Specific/Justice/trialtimer.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Original screen timer sprite by brainfood1183 (Github) for Space Station 14, modified by Leonardo_dabepis (Discord)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "trialtimer" + } + ] +} diff --git a/Resources/Textures/DeltaV/Objects/Specific/Justice/trialtimer.rsi/trialtimer.png b/Resources/Textures/DeltaV/Objects/Specific/Justice/trialtimer.rsi/trialtimer.png new file mode 100644 index 0000000000000000000000000000000000000000..34c8f1b90a973a28041bc16e327ca95415305509 GIT binary patch literal 1170 zcmV;D1a13?P)aQ>CJn4l0N^WT@iMLQxP$sbH7t&{nYOlDsCZkfh-yMT)E7;!to9 zUHlsS4|Ek=6$C*ML>!&{TBOALnnH`TFWlT8=e=`zIRT`!!Az$o0hpG{GpVG!nqQMc z?~pJ;6#*3H*h|^P9J;QbM+8KFh>Ka>&vje_1xjVd@fiYSpcMrwtoYSeYoHF^wGMehIe zbo7~Ne|k6x^uBuD=L8Vi2kJG?`#tr%`WX;>0j{l6rJ-WRi(u z7lb^fyTAIrs;;g9_|MJC@_&41Tb|o?T9xJD^RGEv4Y+Rnlp_yrZpkYbj=}9)XOusK zp_>w7Hu2*3pP$CHM0$DfOU)}1p$q&t)c0?kg2_}U@=u-~)*`paq(}EgphZZI?+QPe z>oOVjk7xHl;ukJB2*yEzz@II!@S~(F@?Ho5QsA47$wYTD^@w9Q2ixgE;Q7FOA9m&2 zDveV3`|eeoFCYj4;4Fye(IE1KN4_uuLvzq0dKP$boL6LbkAKL0F5T>$F_?_&rFjyC zqX=ZZejmVJBuAn#oB<0Ml4t6Ju<;T|&cYy|&_vN!ONXL|64A2`&0<)k0(cm)CJo(Q zYPkT(vxq#C7+EAcWkoVB0;awaNji`xX`;UEOtMruStm*-KPLADPeesj>{foUvK_qyWS;X0t2s$SOWf zLWo{HuPPd-6#kz3z8=7wSy}vC22hhi%}SYNi%51)Ij#fD3k#lBI|*9U1SPT7jUNl} z`ilkAnFYfQA3lF)Q2Ku$YGqdmPf;7(6@ID{+!=9r@s4s^wHd2$tTR`3fuGs}!$BW* zM$Ml8MM@leE7qqA{9FyVcIh;Xrygu>xUJnsCmi`~|3~2gw{HAgA5bTE|K&Mx6s}*~ zQpf$}p@c!dU0vQBNqBX5l*<70VeR-SC$tD{N3@8%#v~EC#BUqhtZx)B3K#{90!9I& kfKk9GU=%P4{2dDX1|sUKK8xh*;Q#;t07*qoM6N<$g0DRnGXMYp literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/assembly.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/assembly.png new file mode 100644 index 0000000000000000000000000000000000000000..056fcc5c14180f45674a4b128b840a76a31ef1f4 GIT binary patch literal 1645 zcmV-z29o)SP)!NdSiF@JuQxt>)LH z;5!2FVH87%%FMQwvWq!%jh{!VrFe*oUft_D#y~-}8Q|+9o@Ewyi06sZTaG1ok9dTY zE@~=<%0ep35u%e$i7Zwz1O2ti%oCDdLEsS6K5r;wB;0T**=% zr!@f^8KjVe1O*jrLWhGmWs_#s*_UYemQf}TqrZhJI5~bjqkKyV+Z*If7a)OG7;K;Q+qHe3EO&1vqN^jb@c90TDU;PR%W zDF?vSE-?0N$y{zo0a|`d13oT*!8|a05A?5lvuf_+{0Ycy(-YkRhetq^>cbm<+Gc0@ ziLXu;00009a7bBm000id000id0mpBsWB>pJqe(ghw%Oc5L5H zw=4?ypa19`>5dooqlYCP5%Z248XB@p+o7-jZ34)3K&L$M(z{$Y9ENR~d%kV=frEXe zOUm%bh-*tZttZ@q_T1M`FW=QiW)N$YnuKNr0%}53Qer!{JHpZxW$cCb4}u5VGCult zz4q2}a?!K8no;xlteRiRw%qE=t9rS1N{NM2p45ee%A0%gl@FkU0RSnAk}l;^fm&s) zioR0=cJj~<-MnEe0)WSAx3}+H`Eo9R-mI`tuGrbIn`btJ#^j9%V4xWv(2OV1o3;76 zue}mlAY*AZ0C3}A0))5--t!2Aw{+WiYB_IqijSFF+TbS5D00%U`*9e7MDGv%q@Ne& z(-3z7_~z4)>)?^y=)=Wg@oyY&ECL(Gn~?wZW!BOgtE1S;ICz2%MKB((k<2a*=h?rC zG6^#i>Av<6pfwF)^We3y)niJ3C7*M4(i! zvIuBt*t`O@3GlBc!8nYfWilCJV0a3&-Y7wQqZF^Fap+Q2l@=El>G#J@(C1GbVPlqp zTekNawveNIHWgOat7pLvkGqLh8*hTp$w6#DOMC+lG*<|!CLS*s@{x~6_3uf&bDsJ$ zPj~Oq2OGu{ipvq1)A-}_K1$XaPvuVc0HHW;-o(3eZjSDEX}9mBj=(rwxN#P)^=hJB z3Q%&mc+4`Ns0rGwL@bwTM=uQz57WHXD$ywQYh#eyBRLGu#g*V&(X(9vUn^r0LZx&2=R^BZcntE<2tx; z$ch)9aTx)GOtomch+HcOtb^y`dbiKdYME7m>yIPvJ^A*h2UJNaI;g(&%(+zY^sk34 z?V+yu1=9(jV07FUxiR3BNoGgvcl(~+i(bad7c{-^nKyo%PZy>?o35R&y7l+C1>rXQ z@L10BHbi;0`Zu^(cb1QT`$OfIWKreDVVnJ!*gc&^9G(7{*y&~|z}p{aTK$-G5^64s z2Mpd3cDkLSV4kca&t*CRB0gdOqLpq|1>%!S^nmlBtkXxSDBo_a^XIhwN1M&!_0#Hi rfb(1b8AAv5MyjcWq|{gC?)Yg=ABppUv000000NkvXXu0mjfO|dJ^ literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/bolted_unlit.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/bolted_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..6857f2a24154b06497367e4b2474465b750393e2 GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJa8DP!NdSiF@JuQxt>)LH z;5!2FVH87%%FMQwvWq!%jh{!VrFe*oUft_D#y~-}8Q|+9o@Ewyi06sZTaG1ok9dTY zE@~=<%0ep35u%e$i7Zwz1O2ti%oCDdLEsS6K5r;wB;0T**=% zr!@f^8KjVe1O*jrLWhGmWs_#s*_UYemQf}TqrZhJI5~bjqkKyV+Z*If7a)OG7;K;Q+qHe3EO&1vqN^jb@c90TDU;PR%W zDF?vSE-?0N$y{zo0a|`d13oT*!8|a05A?5lvuf_+{0Ycy(-YkRhetq^>cbm<+Gc0@ ziLXu;00009a7bBm000XT000XT0n*)m`~Uz28A(JzR9Hu?S6fURWfVR$%yw9Im%>tZ z#oDE$Af*XyYKT^A6ctl7u`vxMHokg^`lLSSQ;o(nHjTbn-+VERP4q!Av0gCs(xz=B zY5}`7i%r>H7Iw=5yDaR$UYzeA&g|^$?1D{CGMSnGT)yv||1NcRcNa;Q-rims9Ua9d zWwTlFE*6FAwumH2)ZE-GVs&+O(b(9S_*NJ^5{b~`p@L{Ub;C;o0|VsO9X7SLngnhp z5|o^srQzXWdUW$LeSJxz=XZI8e(18irq6?|8DV=`$3ns&Aq@@=76A^WuU_z}De<&M z0iP;tj$g=_1lIDi>KC*e{TBC#N+{!lN}f`SE8@RlL#e$M zXssAtRiP)gX!MV%Q zxP!d$Pz$|sf0GysP7w?mfy8XqEkHUsY@ca@4kQK9T+V}dq)3Hg<{QQiT zN+q?_Y*MR6V0zw|uGJ(uanTdM5!Lu{_rH3KtI3rV1ni=!YGQFN?l0t)^LW=psi8z1 z#NY@2R&#W}69Htb)q9(+Wf$iBc-t}3+1z?LiCC7W!q2e+u+qWXbnqD7cCYoU7gZQm zbf+T$21gK(um(f+T!G-m`kIxnlXptSoYYusRx`g#2Ss0%jegc!v;XK)*4HRoie6Ur{blP zV^g$!?_8^$#FeoOJz0MTu`QE`FJGrvGE_kpvBH$5=(%s->Fev$vqEMr8W|ZOEJM(9 ztgwG=zUe%0(A$p---Ynpm=6xW=N2+iQ_cnDX80On2NUo4j)a^XmWCr{(R~@ zef7)<@oyKU?Ga-nV?^%=H=26%T`Cz5YAg9GJ9aiwu*Xd_U%nFrE^MZ@U6nHdvBKfB z87uTzr}5oyyn_2nvCJ_*a*-}BrRafuhS4f`RCU#b#z#}s6Y){3P@X}xF@RXqRmyeG z_&7c6(s#&ygTeIBk{Qc!Z)I>%#+7`uRu_D(Md_egIS}EaFTK>>-cAwy$#ry4i~e8H z1=fZJsm{#Y-tI)=xeX!m%Pu;W{g?1<7Yx1*9T?*Edc|NYb+Tb?j)94v(zLbLG^8otXiG=lxxE2YvWpLP6+t_5Mtra9>Du~Xj zR*|(xK#$C=c5YwuRlA?Un+tCcuD?!vxc|K`j%bpUsiWei%h%$WOTQm?#KU~IZY*}A z){Y)u=uW>PlPs3f9}gXP8}G8sh%0~-FHXLYp+nEU^-Cm?9{O^qa6Ruf&f^Y(-SCsM zb5-vKQ$;0v?uVaqXJQ$R!TEH};iT6FI>q^rE3uvGGl&xr>tO{Xs>OgWz=18}f+$Gnm4H}}Tnxf( z3|{R}YHhD|aAk0DIkjHTaZiLKlg8=jc8lL{EOyrG`G4STl?ehIlk)%o002ovPDHLk FV1n3VX|ezS literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/closed_unlit.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/closed_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..c78d01c42d084dd5be78e8a33a599a90cc86107f GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJa8DPP>^Ss#&mpghvZkX~#s0-h3N2b6`K?}O)meqDd+l#VI$hWM`6MlQ q&#%(rqf#%I&Hk(pG?9U!&gT+u#1#>y1s3nVf%u-TelF{r5}E)5_cy%& literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/closing.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/closing.png new file mode 100644 index 0000000000000000000000000000000000000000..fd27f05b3a2cc24421e7756fbdca2d77b94cac00 GIT binary patch literal 3014 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 IM6N<$f(|R_lK=n! literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/closing_unlit.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/closing_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..2a71f76d5d0c792fe84b136920ab32a386dfc7a5 GIT binary patch literal 432 zcmeAS@N?(olHy`uVBq!ia0vp^2|(UR&i(je0cL#ec*0}-@j8|{(iQzwzWT#=l!&5f jT;0h840aHhFykh_!rG~;5AeP$1@S#y{an^LB{Ts5_a?jl literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/deny_unlit.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/deny_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..7c56263f83958a17893b3db0b04ce3078c15cea0 GIT binary patch literal 321 zcmeAS@N?(olHy`uVBq!ia0vp^2|(x;TbZ%z1lzVbEa*5x0l` zFLCLtQfk)goBm*9Wqa5)W5IyH?gg7O+Vq@#{gzqI_j{ICbSF<}<0|vo?Y_6yOll7; z+AsO(r`@v>Kf7}$KR*umYV~i&zP&s*_xJv-=38t1deYzEyLbMqy6^o$Z`IbavsGXD zr!(F8`6z;|L6RYjVFqIYc7~Z}LvrZvRZ(vk567Q>-*~3QX2MKG<^wzo#tdf|3@{iQ zO7s8d*3Gv+{xi?r|HRuDl15mS!8LAhWr_IppL3FmClFnFq60fUCY M)78&qol`;+0G5h<`v3p{ literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/emergency_unlit.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/emergency_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..817f2fb3f95c53ee8720a7c5be418b6208a6a7e6 GIT binary patch literal 588 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/opening_unlit.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/opening_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..84933bd5ed9cd40a972aee792b227f9aec95f233 GIT binary patch literal 284 zcmeAS@N?(olHy`uVBq!ia0vp^2|(X)s_s z#KIwr!I-V$V11^#dUpKLjjy-9DY|#Kuw+Jjzzl{&rWQ^CH3uAwt;hGhNWR~>|B3$l qhyP2a-~C|qG6v`^C}^l(vC57yE3)EC^YOwKkf5ilpUXO@geCx+nr^EA literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/panel_closing.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/panel_closing.png new file mode 100644 index 0000000000000000000000000000000000000000..db7be0bc4a0ec0b2bc29e8718fb6b71796846f16 GIT binary patch literal 445 zcmeAS@N?(olHy`uVBq!ia0vp^2|(qk=b{5eiK-()1~xQ&@cMV`(mao8yQ?TZq;#^Y}m${ zacWZ!Yev-i>$j948lYsxftl|YY`yljZkp{(pFL*+-lj#WWzI6YweB*{ESZG)8eLCP zH-4D=_wruJUKQWqugks*3w-~bxAmsS_S>R@6K&4#1!`fty>^f8^xkc+O+xqazTJA; z{=7~2>uGDRIhyR%SJ)ONH}BrkKUz=f@~-S!d-avVtb5`KJrkcF_ZOUaf4N)v?bouY zpX0AZna`Cr-@$dKByUdGcPkF5{Og%j`&-%%FXZlavSVWw{8-KzzB@7SM0TXvt!o+A zif+H$q2jsc@9*!WwR0M*e5Y<-(ETyu&`qBj{lx9nl5Os{*Qk05m8bu?%XoF&`KQ?? l*%zfe7FQS8+W~`WRsIyAi(3!btSA5lf~TvW%Q~loCIEIM%9sEE literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/panel_open.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/panel_open.png new file mode 100644 index 0000000000000000000000000000000000000000..24eb2aedc2248aeb772b38f63ff992254e7aaec0 GIT binary patch literal 315 zcmV-B0mS}^P)G_@Zv*NK(#C83< z0hCg#mPY_q%Og#e`P2l!*GQEjpT`0MYBKbMv^%3TIE=g7KF`WXCR28pn>(x2n zemoXytpJ?bfcIZ;wOEjBHdt%rI!S!%PGhZ=2c^1AoGrxJR_5RoDx&OEP+E*gAHf&mPbH>ZE8FCH9e&*rpCoP%1 zIy_fR`1DT4EhW}ImG2+Fy>#^EcBOlIu{N4r8M|lHdv8DdMa^XX`Q)41s%D;5@l3t_ z>U!DiCu(!NfiicFek|lsbn*16WPNgF)9u86nlDcO+<9uZb*sRm>zlTKo#3wDtk_cV zGUiQg0fX*;t18(yxo?DbZh3Nv5#oCg`Gddm{r7*~nV;{o)~0;#=kiD}oLj`YgzrYV zCx61j+EYJuRBRcZ$AIaEWtl7E0M--(oM3v-T6o|50rvB z?(X|$_9K~q!b>Jme`5^XKVF&j%`2QtMsN-@c!MQ;uYX{&xPXV-MV4h*a7^*H)mTo% z^duKBlw8QrI7#Az6a!+!k42gRM*{jVXw(2^)BtAG0A@rO5W6r+TTo*dR0c>itn&u= ziYhf*#29dhKzXbye)sb`x`T#9jF|@skRQx^J~1)&r}u;k?=m8#VH_qLszE1c7I|*U z-vi17+kNaSpCz%9yQ#rS&sN2x0`#dRVZ$Zo3 z(YozxD(tDJ*Nd^#9ngM11*`#hZL|qqUX-aA#5S}G^!n=WLLU@GQ4~c{6dSK|xP5Tx z!-H@vnhtn%y49-Lc3NyR!WG{&^FjpmIbAy+o5nPrx)V}}E%fz`bB+BtcI@^)8^rTf zBx((Ky3EXU1aLM2IGxVm^KA+58-UdY;QHA(FXNaPN!aD?zV8}<6&DioA6qwm%&S`B zG(?rf)v;@BC^IYu=$f%ZGhhqXw5SF!qXsa;V!%*uXSl{qZh&O*G5ePMUQntINQ83i z$upoRb}H)fv5TKDu*ZP$-hvmY3!Atq6ENBh(WYFFM67|7l05p#?E1nmayZKasmvEs z4%uF#@2=U$hCc&#<3^>qaoRUjD5t(Q@!@5>eLn%YPa&y@Wk6F&Jf;Amr=S&p`TF~H zKQmyzZBbK@-3j_NfaCqFrZteLVgLD`ViBgsl+FQ!832*%0DhkaTq4i015y-4Q4~c{ f6h%=KHvsSpwHV1KmpgiI00000NkvXXu0mjf++aJ5 literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/sparks_broken.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/sparks_broken.png new file mode 100644 index 0000000000000000000000000000000000000000..fb5d774588ae44eab5608571cb6aafad7375e158 GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^2|(DFD66%%n7hj|c25u0=Hbzuz>&Md dbBcZ?)Aw7<0^jOhxdW|Y@O1TaS?83{1ORW&Jrn={ literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/sparks_damaged.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/sparks_damaged.png new file mode 100644 index 0000000000000000000000000000000000000000..f16a028dee5bbe41a7f4e35f686043e8a112ce4e GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeK3?y%aJ*@^(YymzYu0Z<#e`9lQK{p_au_VYZ zn8D%MjWi%9!PCVtL_+fI!HvAl4m=D8Hh=XH6ZQR;XyVo{y01gP^_0k+pXD$8l*-N4 z&iUk!V5<=?maE{?*yyS)-udN6;H*Pi5*L(-Fs)pAdDY$x8SUGCM{GTG-~v& dN}IerjGt7Q1>7HnEC$-e;OXk;vd$@?2>`@EK-2&L literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/sparks_open.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Glass/justice.rsi/sparks_open.png new file mode 100644 index 0000000000000000000000000000000000000000..630eabb976ecf11fa59ba29f03502b02bde399aa GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^2|(GM)~O;5D{Ad0LZe;7N97KJC6BX-upNVgWUu;=WLfz+qP_d4j_bJ3vh=hfa5r9 z0qVN81qdO4*#ozUc?-;6LK?t17pG~m0|2;<_}}aJ8%Xzkw*de?p>!O_N2;HSWO<%5 ub^zoJEX!gGaL3n-QrC61fn;4*wm#k_G(h}nBOLz#0000!NdSiF@JuQxt>)LH z;5!2FVH87%%FMQwvWq!%jh{!VrFe*oUft_D#y~-}8Q|+9o@Ewyi06sZTaG1ok9dTY zE@~=<%0ep35u%e$i7Zwz1O2ti%oCDdLEsS6K5r;wB;0T**=% zr!@f^8KjVe1O*jrLWhGmWs_#s*_UYemQf}TqrZhJI5~bjqkKyV+Z*If7a)OG7;K;Q+qHe3EO&1vqN^jb@c90TDU;PR%W zDF?vSE-?0N$y{zo0a|`d13oT*!8|a05A?5lvuf_+{0Ycy(-YkRhetq^>cbm<+Gc0@ ziLXu;00009a7bBm000id000id0mpBsWB>pIk4Z#9R9HvFS6fdLK@>h)wioC{C~_%; zB1vt8L`@6{nixgJM2#jsYWxMh^5n1JQGb9j_~_-u2MCEVAtXeD5-JyoK%`oX zQ^~j_Nzl;HK)&Vc@e=tMTMfa$zyL(`f#Xe0WuTvHYmi-EhmnyHxZ1uAFF&i6Mjo6E zlCf8d9$T!7O$AEk(d|>VE@$#8G>83U!n3IYSVds)M$%CPcqN%NB6VJ<_12Wfwsv+Q zx4A>wb-ulR*B0~%)vyTxRG3)!Wx(!BG!ha)f0?Ii`*zqKUZJ}!0_=yDSVY8(>*(k( zUACb&a|VJ8L&Qdh(YA+qjtWj>@KPf@yigA!iS1%Z!k-xl5trFQ+a4TrY8-WcY|!m` zP+>L+f&VFv3FMXHk??d(ARO5LPN>GbOrV;FIL5|Xjs*@J3Eo!OE%Xovcu(;#LgD*{ z-qQ0zJPolHV83`8G7QFAv{A7HVwm5*&YF5_b`+Z#$3785v>|`}Q~+g$da7t82uPIE z_gw{U23jFKR=Mpm+utmgK-5LWgdBntLX ztqx1jI2uLi>gpn7=0<1fLG&*~RaID8T7nO^Cg8>0=YVY#x#vs-Vr|CE?pcjMOSc}G zjmk>UJk^c~Xv#Tu#fXEuCY8#U_2W+y^t+$_$ul2wP(SN40M4j6=$;Qlx>R`qahn5x zo8#mj{Q2o=xa`%dZ$D+QuhRv$92Opt^{~1O_x*9x==lA9=$EBca{qaqjdfIf@#n)X&_hK{0o8ZGxjRwQD7fk5F$`;_166E8 zu^#YuL^noxT{{fJQG8To*UAAx0N0y|UD-X1YRKF4;LTSgQ7zn94WEqvHm!!ZJ)OJ_ zn8RpW#%niz;02M71dQW~<#%iJMVrmy?Z@in%lfTf#)yFr*Gl2_E9XX| b^pN`tggBXyxtD+e00000NkvXXu0mjf4R4AJ literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/bolted_unlit.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/bolted_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..6857f2a24154b06497367e4b2474465b750393e2 GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJa8DP1uy!EP)!NdSiF@JuQxt>)LH z;5!2FVH87%%FMQwvWq!%jh{!VrFe*oUft_D#y~-}8Q|+9o@Ewyi06sZTaG1ok9dTY zE@~=<%0ep35u%e$i7Zwz1O2ti%oCDdLEsS6K5r;wB;0T**=% zr!@f^8KjVe1O*jrLWhGmWs_#s*_UYemQf}TqrZhJI5~bjqkKyV+Z*If7a)OG7;K;Q+qHe3EO&1vqN^jb@c90TDU;PR%W zDF?vSE-?0N$y{zo0a|`d13oT*!8|a05A?5lvuf_+{0Ycy(-YkRhetq^>cbm<+Gc0@ ziLXu;00009a7bBm000XT000XT0n*)m`~Uz121!IgR9HvFS8YoaQ4~JAj_&HNo35!@ zqzNmgAVLTgMOhhCP(&CM{er&sL;6@hAfi6@^1%WlFhK;Ve8H`D3oP=rw%qk)r&hOl z?r_GtcV=f+3p%ju%suBk=eg&eJLg_sdwYAH4C(6XqKSzKJW@8B7619XQ2i6}`FvDc zTPv{I+S+Jxa#B2N96XUo(AnlqG5B&eOnrTQ6g3=n*VkJFzAY_L>c6sB* z!_31<@X_RV8}{K?ogfi1oV^6W-7w(qGk%EeN80hiGiS$+y%FLcbes{kWfE8hRoGU= z05-_U;>QbWU1kl(QsmZ&I=XqZM%03rFea1W{Ur!sRx)cZFxD?Do7=TiVG@YNnG^*6 zmtgsKL?DyR{WH!xB2dcrqEv>C1l(o_9qSu+1xt-%`KS)orpCvH1v5ktd8VwF$8Haq z-wXa6v%idmv0_-zSs8f!G*v)OO|zLL&w}Yk4y)?H{ObgS%PM{2E}RsSk$%!b7X3YPL>-Tve#s=@MPV>^6sr3`F@~(rt1NF zA;K*X2vAE)3nh$S&ZvPpCna-Mha^ISdgpT%SNkzYjwVZ-9*oa zh?2Q2ENcl4U5q-OVmKo7d@S==6=JN<$u&pQV^`{lTe-Cj)PA7q-AHW5)?cjg za6j;x?ceIfnGnJa1nbS>)pobj4S~tnaP>^Ss#&mpghvZkX~#s0-h3N2b6`K?}O)meqDd+l#VI$hWM`6MlQ q&#%(rqf#%I&Hk(pG?9U!&gT+u#1#>y1s3nVf%u-TelF{r5}E)5_cy%& literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/closing.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/closing.png new file mode 100644 index 0000000000000000000000000000000000000000..2a33b5d48af43b76c044ea70b1f28fee76866d9b GIT binary patch literal 2683 zcmV->3WW8EP)!NdSiF@JuQxt>)LH z;5!2FVH87%%FMQwvWq!%jh{!VrFe*oUft_D#y~-}8Q|+9o@Ewyi06sZTaG1ok9dTY zE@~=<%0ep35u%e$i7Zwz1O2ti%oCDdLEsS6K5r;wB;0T**=% zr!@f^8KjVe1O*jrLWhGmWs_#s*_UYemQf}TqrZhJI5~bjqkKyV+Z*If7a)OG7;K;Q+qHe3EO&1vqN^jb@c90TDU;PR%W zDF?vSE-?0N$y{zo0a|`d13oT*!8|a05A?5lvuf_+{0Ycy(-YkRhetq^>cbm<+Gc0@ ziLXu;00009a7bBm000XT000XT0n*)m`~Uz5u}MThRCr$PoZoL$MHI)+wzu7d{s4-! z6w>k|tx#em8WJ=b1+57hMPq`|_~5gzKKbZhz@ra7Y7FX=;sa<(FiK*Ypae>&&`N{~ zg@PrtKzI9Vy=Sgxdv&3&1ugUkZb~|#fNt;LH4(=;lWG}4)09+ z|4v2=a^dQakoAdwOI^>EmM|u^xawtXV|~>$bgaw3?EE53KbjXBlG4(;wgJ{O)Qc`x z_0lBn!s?WtMkWP#f6qpdge0_J@Q23!5!^azHciG!gyHDPD@7Q2_IIU4=AwwcEv-Te z_C_qWwWyfHLbgc2M=xxI51(BRt{TpxJ-4uw!XK3|ms)gORmY1P7ZavP!0r1u9o0rz zX<7N<*BHd1k7X?Y9{(gYN?q7v}CHc5|T5Yq!y6?TnksTV2`6-x6-tTZg=$O zU`-ll-@`P4xIZFRJBJ=GyoL8TS6WnDt{Fd!VX>(tj7coy6^5WBf=>u;V0>`Z{NPv1SB1F&dcR;;B_9%K>PWvH~}Z71({*R zrIs-6o|~=E(YFTRe(_F_4J|4ruJlGmW<&^9{2YKmxRjfQzR?z#SSmgjaWw}3E(Cjn zE?8Iv(UK{N+u&I4dRdGsEjq4BR9r3PnCWyHQXe#J7whu2x(4_(`zPe)ml8W0elOjv zOoU4<7*NhFS_MgWfUUU5%+9(rjP%aH^txTa9DoH63EF?Hjk&0F@p}f)6+6`58(zsf5JFrEc1LE%bMY)q}X*U#CKv?(|F>g!U zxTxAnEM(WtF;tWcT6irU0O8*Mfxh-4W0r-gL#rSr`j60uR5Qjb66Uh;a@}f_gUhj#r*-?!i1g1&u#FV8S2yC#6mXpwzxW?a!~`ZaT1h+ zuZss>r(KRJ z7cmK|)5C1aTd;Aw@+O{mx{Y~HimRhiE+w2F$VAm5e;Sq#cf#U}Y%v7Mw^UrOyv`FJ zb{oglQ7ISo$Za;&qS}gxQkQpb@E&CIOOQzg(}4}Iyv`GkwrnbY{qPxNF9r7SxH_V6 z&z?OCt^Sb+y$3z}Cx&lD)-o|w>h9zIf8JJN;&tMB=#S^+>O$!!yUM4|(s!aD6oO^P zjvd0AFKfVSwspu{{QJtO%S8fhYcXMJS3x#|k9DCZ{@S%`aPGAs`1Y-@Y*!yzpUlO- zT^AE(!5d0qYYh*2*drP%* z|37alF*^<~KZ_uq58%ayS6=xH81uv<@0p7i;l+jq_++sG)?aQc>5P@=h{7E@5M-e6 z9$(+3+3CnyRC56L|MRvI^Y-!C!m|jGY$>?Z!%Z*Ut&5)cFzY#b;9$y1`u548jDbx`2Qi7q9m|wp+gemkY!ClwawKT#l{fLk^9diF4|q-* zS4UJXYC!glsacV9ax7P(#l#y#!6&B&#Xx)x;5`ukj_Z}zdE)sHA~&30i>f0Emj^<& zjZ+d#w5Wowx|=BB^!=oT1dvai{=tn|HpW_&CthZ8zq~CSCR}8lxzi;4IaK0kF=Z0# z#CRG!@~NwWZNn?C^2Bo%7ma>-TRL=H;-Ebcy_%E+8jdQ_V#-7|1|QiaN0PR^@+QZQ z{K%046IX``7g=bK6-n^#1T1m1m@+B&!kioB%UW&Q)3L#AZNUT5Q&Z}1tWw<(DjiYm p>6}ZpcydTb)e>cxrnYi>`oA(9fB?(0zd8T_002ovPDHLkV1kIOCo=#5 literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/closing_unlit.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/closing_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..2a71f76d5d0c792fe84b136920ab32a386dfc7a5 GIT binary patch literal 432 zcmeAS@N?(olHy`uVBq!ia0vp^2|(UR&i(je0cL#ec*0}-@j8|{(iQzwzWT#=l!&5f jT;0h840aHhFykh_!rG~;5AeP$1@S#y{an^LB{Ts5_a?jl literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/deny_unlit.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/deny_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..7c56263f83958a17893b3db0b04ce3078c15cea0 GIT binary patch literal 321 zcmeAS@N?(olHy`uVBq!ia0vp^2|(x;TbZ%z1lzVbEa*5x0l` zFLCLtQfk)goBm*9Wqa5)W5IyH?gg7O+Vq@#{gzqI_j{ICbSF<}<0|vo?Y_6yOll7; z+AsO(r`@v>Kf7}$KR*umYV~i&zP&s*_xJv-=38t1deYzEyLbMqy6^o$Z`IbavsGXD zr!(F8`6z;|L6RYjVFqIYc7~Z}LvrZvRZ(vk567Q>-*~3QX2MKG<^wzo#tdf|3@{iQ zO7s8d*3Gv+{xi?r|HRuDl15mS!8LAhWr_IppL3FmClFnFq60fUCY M)78&qol`;+0G5h<`v3p{ literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/emergency_unlit.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/emergency_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..817f2fb3f95c53ee8720a7c5be418b6208a6a7e6 GIT binary patch literal 588 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/opening_unlit.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/opening_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..84933bd5ed9cd40a972aee792b227f9aec95f233 GIT binary patch literal 284 zcmeAS@N?(olHy`uVBq!ia0vp^2|(X)s_s z#KIwr!I-V$V11^#dUpKLjjy-9DY|#Kuw+Jjzzl{&rWQ^CH3uAwt;hGhNWR~>|B3$l qhyP2a-~C|qG6v`^C}^l(vC57yE3)EC^YOwKkf5ilpUXO@geCx+nr^EA literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/panel_closing.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/panel_closing.png new file mode 100644 index 0000000000000000000000000000000000000000..db7be0bc4a0ec0b2bc29e8718fb6b71796846f16 GIT binary patch literal 445 zcmeAS@N?(olHy`uVBq!ia0vp^2|(qk=b{5eiK-()1~xQ&@cMV`(mao8yQ?TZq;#^Y}m${ zacWZ!Yev-i>$j948lYsxftl|YY`yljZkp{(pFL*+-lj#WWzI6YweB*{ESZG)8eLCP zH-4D=_wruJUKQWqugks*3w-~bxAmsS_S>R@6K&4#1!`fty>^f8^xkc+O+xqazTJA; z{=7~2>uGDRIhyR%SJ)ONH}BrkKUz=f@~-S!d-avVtb5`KJrkcF_ZOUaf4N)v?bouY zpX0AZna`Cr-@$dKByUdGcPkF5{Og%j`&-%%FXZlavSVWw{8-KzzB@7SM0TXvt!o+A zif+H$q2jsc@9*!WwR0M*e5Y<-(ETyu&`qBj{lx9nl5Os{*Qk05m8bu?%XoF&`KQ?? l*%zfe7FQS8+W~`WRsIyAi(3!btSA5lf~TvW%Q~loCIEIM%9sEE literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/panel_open.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/panel_open.png new file mode 100644 index 0000000000000000000000000000000000000000..24eb2aedc2248aeb772b38f63ff992254e7aaec0 GIT binary patch literal 315 zcmV-B0mS}^P)G_@Zv*NK(#C83< z0hCg#mPY_q%Og#e`P2l!*GQEjpT`0MYBKbMv^%3TIE=g7KF`WXCR28pn>(x2n zemoXytpJ?bfcIZ;wOEjBHdt%rI!S!%PGhZ=2c^1AoGrxJR_5RoDx&OEP+E*gAHf&mPbH>ZE8FCH9e&*rpCoP%1 zIy_fR`1DT4EhW}ImG2+Fy>#^EcBOlIu{N4r8M|lHdv8DdMa^XX`Q)41s%D;5@l3t_ z>U!DiCu(!NfiicFek|lsbn*16WPNgF)9u86nlDcO+<9uZb*sRm>zlTKo#3wDtk_cV zGUiQg0fX*;t18(yxo?DbZh3Nv5#oCg`Gddm{r7*~nV;{o)~0;#=kiD}oLj`YgzrYV zCx61j+EYJuRBRcZ$AIaEWtl7E0M--(oM3v-T6o|50rvB z?(X|$_9K~q!b>Jme`5^XKVF&j%`2QtMsN-@c!MQ;uYX{&xPXV-MV4h*a7^*H)mTo% z^duKBlw8QrI7#Az6a!+!k42gRM*{jVXw(2^)BtAG0A@rO5W6r+TTo*dR0c>itn&u= ziYhf*#29dhKzXbye)sb`x`T#9jF|@skRQx^J~1)&r}u;k?=m8#VH_qLszE1c7I|*U z-vi17+kNaSpCz%9yQ#rS&sN2x0`#dRVZ$Zo3 z(YozxD(tDJ*Nd^#9ngM11*`#hZL|qqUX-aA#5S}G^!n=WLLU@GQ4~c{6dSK|xP5Tx z!-H@vnhtn%y49-Lc3NyR!WG{&^FjpmIbAy+o5nPrx)V}}E%fz`bB+BtcI@^)8^rTf zBx((Ky3EXU1aLM2IGxVm^KA+58-UdY;QHA(FXNaPN!aD?zV8}<6&DioA6qwm%&S`B zG(?rf)v;@BC^IYu=$f%ZGhhqXw5SF!qXsa;V!%*uXSl{qZh&O*G5ePMUQntINQ83i z$upoRb}H)fv5TKDu*ZP$-hvmY3!Atq6ENBh(WYFFM67|7l05p#?E1nmayZKasmvEs z4%uF#@2=U$hCc&#<3^>qaoRUjD5t(Q@!@5>eLn%YPa&y@Wk6F&Jf;Amr=S&p`TF~H zKQmyzZBbK@-3j_NfaCqFrZteLVgLD`ViBgsl+FQ!832*%0DhkaTq4i015y-4Q4~c{ f6h%=KHvsSpwHV1KmpgiI00000NkvXXu0mjf++aJ5 literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/sparks_broken.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/sparks_broken.png new file mode 100644 index 0000000000000000000000000000000000000000..fb5d774588ae44eab5608571cb6aafad7375e158 GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^2|(DFD66%%n7hj|c25u0=Hbzuz>&Md dbBcZ?)Aw7<0^jOhxdW|Y@O1TaS?83{1ORW&Jrn={ literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/sparks_damaged.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/sparks_damaged.png new file mode 100644 index 0000000000000000000000000000000000000000..f16a028dee5bbe41a7f4e35f686043e8a112ce4e GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeK3?y%aJ*@^(YymzYu0Z<#e`9lQK{p_au_VYZ zn8D%MjWi%9!PCVtL_+fI!HvAl4m=D8Hh=XH6ZQR;XyVo{y01gP^_0k+pXD$8l*-N4 z&iUk!V5<=?maE{?*yyS)-udN6;H*Pi5*L(-Fs)pAdDY$x8SUGCM{GTG-~v& dN}IerjGt7Q1>7HnEC$-e;OXk;vd$@?2>`@EK-2&L literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/sparks_open.png b/Resources/Textures/DeltaV/Structures/Doors/Airlocks/Standard/justice.rsi/sparks_open.png new file mode 100644 index 0000000000000000000000000000000000000000..630eabb976ecf11fa59ba29f03502b02bde399aa GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^2|(GM)~O;5D{Ad0LZe;7N97KJC6BX-upNVgWUu;=WLfz+qP_d4j_bJ3vh=hfa5r9 z0qVN81qdO4*#ozUc?-;6LK?t17pG~m0|2;<_}}aJ8%Xzkw*de?p>!O_N2;HSWO<%5 ub^zoJEX!gGaL3n-QrC61fn;4*wm#k_G(h}nBOLz#0000Y-zxQDW zk>mSwr*?&Ptx$M0VWC*NSXYyU7whhj_H9j})1S=R;xwtvyGtbe;L(K-6n6c{{$PJ0 zv>;S~#Z{oN-Nj(7Z5uBgTXTf>k>;b0h2asOZ62v9UX3{! zB)8m@QCf1zgccT7(Hy7tW{cFxY1eK}&-gJdP>p}_{#Gpu%Px(H=5AT7yH-sxy%hSZ zB;@Fw|K~4XOIx=0-9nWMzhCW|KiQ!`e#P~e@87SKzD{>|z`DaM`k&F+%y+ZDM0t11 zFh7)i@M+mnP4)v<^$fn{oQ%oyV2rBsWwz66IA~)~!~bP{_2#U1kN3SB;ar4dD zl(c<0dPo19GgM$;c%<|*o_Dh@x9{qbZd4J4$Z?D><`!W`mAJ-O6 z`p@|J`OMuj=IwU<8@J=k^SoD>vs?{IziTefh7iU39PMeOf%}qEP*p zc*fVx2l?QRNAd>}^G_wy;`cnftN1y#yZ6~Ce0#r2+9UV6<5$L8&%T7)ZC?t!I$ z*M0X=z2BafU{Kqjb|-_|=nG>}|AzhdL(L~NS^Qex@OA4EREPbDXNhBUXJzqU^*ii8 QFk%@zUHx3vIVCg!08QzehX4Qo literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Structures/Wallmounts/signs.rsi/direction_justice.png b/Resources/Textures/DeltaV/Structures/Wallmounts/signs.rsi/direction_justice.png new file mode 100644 index 0000000000000000000000000000000000000000..ef94a9998f3367c89c30de82e90cbf633de39a8a GIT binary patch literal 926 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/closet.rsi/cj_door.png b/Resources/Textures/Structures/Storage/closet.rsi/cj_door.png new file mode 100644 index 0000000000000000000000000000000000000000..f406e398073313aa73094d1239530fa0c9f747c6 GIT binary patch literal 5840 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/closet.rsi/cj_open.png b/Resources/Textures/Structures/Storage/closet.rsi/cj_open.png new file mode 100644 index 0000000000000000000000000000000000000000..8ba72a5bccf8a611fd93933b9fe00fbc53cdec3e GIT binary patch literal 5529 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 EZ{JG(3;+NC literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/closet.rsi/clerk_open.png b/Resources/Textures/Structures/Storage/closet.rsi/clerk_open.png new file mode 100644 index 0000000000000000000000000000000000000000..ab865e6cbe5b83f38babec92d33e6a41c2e9694e GIT binary patch literal 5588 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 Date: Wed, 7 Aug 2024 04:36:59 +0800 Subject: [PATCH 18/32] New Trait: Parkour Training (#670) # Description **Parkour Training** is a 3-point Physical trait that increases your table climbing speed (and all other climbables), and crawling speed, and reduces the cooldown on laying down/standing up. Inspired by the SS13 trait called Freerunning, expanding on it by including new mechanics around the Laying Down system. Stats (Adjustable): - 30% faster table climbing speed - 25% faster crawling speed - Cooldown on laying down/standing up reduced from 2.5 seconds to 2 seconds ## Media ![image](https://github.com/user-attachments/assets/09237d2f-667b-473a-98ad-71bd19bce6c3) # Changelog :cl: Skubman - add: Add Parkour Training, a 3-point trait that makes you faster with climbing tables and crawling. --------- Signed-off-by: Angelo Fallaria --- .../Assorted/LayingDownModifierComponent.cs | 22 +++++++++++++++++++ .../Assorted/LayingDownModifierSystem.cs | 22 +++++++++++++++++++ .../Climbing/Systems/ClimbSystem.cs | 7 +++++- .../Components/ClimbDelayModifierComponent.cs | 16 ++++++++++++++ Resources/Locale/en-US/traits/traits.ftl | 5 +++++ Resources/Prototypes/Traits/skills.yml | 11 ++++++++++ 6 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 Content.Server/Traits/Assorted/LayingDownModifierComponent.cs create mode 100644 Content.Server/Traits/Assorted/LayingDownModifierSystem.cs create mode 100644 Content.Shared/Traits/Assorted/Components/ClimbDelayModifierComponent.cs diff --git a/Content.Server/Traits/Assorted/LayingDownModifierComponent.cs b/Content.Server/Traits/Assorted/LayingDownModifierComponent.cs new file mode 100644 index 00000000000..22660ff4487 --- /dev/null +++ b/Content.Server/Traits/Assorted/LayingDownModifierComponent.cs @@ -0,0 +1,22 @@ +using Robust.Shared.GameStates; + +namespace Content.Server.Traits.Assorted; + +/// +/// This is used for traits that modify values related to the Laying Down system. +/// +[RegisterComponent] +public sealed partial class LayingDownModifierComponent : Component +{ + /// + /// What to multiply the cooldown of laying down and standing up by. + /// + [DataField] + public float LayingDownCooldownMultiplier = 1f; + + /// + /// What to multiply the speed multiplier when lying down by. + /// + [DataField] + public float DownedSpeedMultiplierMultiplier = 1f; +} diff --git a/Content.Server/Traits/Assorted/LayingDownModifierSystem.cs b/Content.Server/Traits/Assorted/LayingDownModifierSystem.cs new file mode 100644 index 00000000000..dc6dcd2de3b --- /dev/null +++ b/Content.Server/Traits/Assorted/LayingDownModifierSystem.cs @@ -0,0 +1,22 @@ +using Content.Server.Traits.Assorted; +using Content.Server.Standing; + +namespace Content.Shared.Traits.Assorted.Systems; + +public sealed class LayingDownModifierSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnStartup); + } + + private void OnStartup(EntityUid uid, LayingDownModifierComponent component, ComponentStartup args) + { + if (!TryComp(uid, out var layingDown)) + return; + + layingDown.Cooldown *= component.LayingDownCooldownMultiplier; + layingDown.DownedSpeedMultiplier *= component.DownedSpeedMultiplierMultiplier; + } +} diff --git a/Content.Shared/Climbing/Systems/ClimbSystem.cs b/Content.Shared/Climbing/Systems/ClimbSystem.cs index 8f6e8046aa4..521f5ace99d 100644 --- a/Content.Shared/Climbing/Systems/ClimbSystem.cs +++ b/Content.Shared/Climbing/Systems/ClimbSystem.cs @@ -13,6 +13,7 @@ using Content.Shared.Physics; using Content.Shared.Popups; using Content.Shared.Stunnable; +using Content.Shared.Traits.Assorted.Components; using Content.Shared.Verbs; using Robust.Shared.Audio.Systems; using Robust.Shared.Physics; @@ -216,7 +217,11 @@ public bool TryClimb( if (ev.Cancelled) return false; - var args = new DoAfterArgs(EntityManager, user, comp.ClimbDelay, new ClimbDoAfterEvent(), + var climbDelay = comp.ClimbDelay; + if (user == entityToMove && TryComp(user, out var delayModifier)) + climbDelay *= delayModifier.ClimbDelayMultiplier; + + var args = new DoAfterArgs(EntityManager, user, climbDelay, new ClimbDoAfterEvent(), entityToMove, target: climbable, used: entityToMove) diff --git a/Content.Shared/Traits/Assorted/Components/ClimbDelayModifierComponent.cs b/Content.Shared/Traits/Assorted/Components/ClimbDelayModifierComponent.cs new file mode 100644 index 00000000000..c04657a4875 --- /dev/null +++ b/Content.Shared/Traits/Assorted/Components/ClimbDelayModifierComponent.cs @@ -0,0 +1,16 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Traits.Assorted.Components; + +/// +/// This is used for any trait that modifies climbing speed. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class ClimbDelayModifierComponent : Component +{ + /// + /// What to multiply the climbing delay by. + /// + [DataField, AutoNetworkedField] + public float ClimbDelayMultiplier = 1f; +} diff --git a/Resources/Locale/en-US/traits/traits.ftl b/Resources/Locale/en-US/traits/traits.ftl index 528517684c4..3439ffcdc97 100644 --- a/Resources/Locale/en-US/traits/traits.ftl +++ b/Resources/Locale/en-US/traits/traits.ftl @@ -84,6 +84,11 @@ trait-description-Voracious = Nothing gets between you and your food. Your endless consumption of food and drinks is twice as fast. +trait-name-ParkourTraining = Parkour Training +trait-description-ParkourTraining = + Whether as a hobby, lifestyle, or professional training, you are trained in the discipline of parkour. + You're faster with climbing, crawling, lying down, and getting up. + trait-name-LightStep = Light Step trait-description-LightStep = You move with a gentle step, making your footsteps quieter. diff --git a/Resources/Prototypes/Traits/skills.yml b/Resources/Prototypes/Traits/skills.yml index 6d10886e8fa..1a4242aff80 100644 --- a/Resources/Prototypes/Traits/skills.yml +++ b/Resources/Prototypes/Traits/skills.yml @@ -87,6 +87,17 @@ foodDelayMultiplier: 0.5 drinkDelayMultiplier: 0.5 +- type: trait + id: ParkourTraining + category: Physical + points: -3 + components: + - type: ClimbDelayModifier + climbDelayMultiplier: 0.70 + - type: LayingDownModifier + layingDownCooldownMultiplier: 0.8 + downedSpeedMultiplierMultiplier: 1.25 + - type: trait id: LightStep category: Auditory From 8400f6c06baef4c34f5c29fdb9754683928c4c7a Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Tue, 6 Aug 2024 20:37:26 +0000 Subject: [PATCH 19/32] Automatic Changelog Update (#670) --- Resources/Changelog/Changelog.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 6263b7d4005..e0226cd7bf7 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -5001,3 +5001,11 @@ Entries: Slash or Piercing damage or be a melee weapons generalist. id: 6225 time: '2024-08-06T19:50:20.0000000+00:00' +- author: Skubman + changes: + - type: Add + message: >- + Add Parkour Training, a 3-point trait that makes you faster with + climbing tables and crawling. + id: 6226 + time: '2024-08-06T20:37:00.0000000+00:00' From 93ece39fc2bb998e3b9c593f2d63b4be5281ef18 Mon Sep 17 00:00:00 2001 From: WarMechanic <69510347+WarMechanic@users.noreply.github.com> Date: Wed, 7 Aug 2024 06:47:49 +1000 Subject: [PATCH 20/32] Cherry-Pick "EMP Grenade Actually Sabotages Power" From Wizden (#516) ## About the PR EMP has been changed to target APC-powered-devices (most electrical devices) as well as batteries to disable them. This means EMP can interfere with autolathes, airlocks, atmos devices, substations and SMES. The power draw of a single EMP grenade now cuts out a substation, and the disabling effect prevents further recharge until it subsides. EMP duration now also stacks, which creates a novel way to quietly black out the station by attacking engineering SMES with 3 EMP grenades (6tc EMP bundle) to black out the station for 3 minutes. Edit, here's a detailed changelog of the PR, Functionality: - EMP disable has been generalised to kill and prevent further function of every device/battery by interrupting recharge - As a result of the above, some hard coded interactions have been culled - EMP disable duration now stacks with multiple EMP blasts - EMP is now capable of draining from gravity generators - The Charger system has been slightly reworked to facilitate communication between batteries and chargers Results: - EMP grenade can disable basically every powered machine, most notably doors - EMP grenade has had its power drain upped to 2.7MW, which is slightly more than a substation and 1/3 a SMES - EMP grenade can now instantly kill substations - EMP grenade can now instantly kill gravity generators - 3 EMP grenades (6tc) can be used to kill SMES and disable recharge for 3 minutes with no evidence on the power monitor. ## Why / Balance EMP at 2tc has a relatively low value-proposition when compared to C4 which is also 2tc. While EMP can probably black out one (or two if you're lucky) APCs and can be used as a defensive option against Stun/Lasers. C4 can be used to cut wires, substations, SMES, generators, doors, reinforced walls, people and the list probably continues. New EMP can be used to soft-bomb station power in an explosion that isn't globally alarming (salv boom). Targeting the captain's office directly may let you crowbar in and steal the locker but it leaves ephemeral evidence in the form of everything electrical shimmering blue. Opting to bomb substations blacks out a wider area, providing several degrees of separation from your target. That is to say, new EMP grenade favours map knowledge and rewards better stealth. ## Technical details - `C.S/.../EmpSystem.cs` uses TryComp to turn on/off charging for `C.S/Power/Components/PowerNetworkBatteryComponent` - `C.S/Power/EntitySystems/PowerReceiverSystem.cs` listens to `EmpPulseEvent` to turn off. Requests to turn back on are additionally intercepted by `EmpSystem.cs` and cancelled. - `C.S/.../GravityGeneratorSystem.cs` listens to `EmpPulseEvent` and converts energy consumption to a normalised charge - `C.S/Power/EntitySystems/ApcSystem.cs` no longer toggles its breaker, but still listens to `EmpPulseEvent` for updating visuals. - `C.S/Power/EntitySystems/ChargerSystem.cs` was refactored to add a `ChargingComponent` flag to power cells instead of `ActiveCharger` on itself. Battery and Charger communicate through this flag. Listens to `EmpPulseEvent` for updating its state machine. New `ChargerUpdateStatusEvent` allows batteries to update the charger's status. - `C.S/Power/EntitySystems/BatterySystem.cs` can now be disabled, and checks for disabling before updating its charge. Raises `ChargerUpdateStatusEvent` when hearing `EmpDisabledRemoved` to tell its charger to start charging again. - `C.S/Power/PowerWireAction.cs` checks for `EmpDisabledComponent` before turning power back on. - `C.S/SurveillanceCamera/Systems/SurveillanceCameraSystem.cs` and `C.S/VendingMachines/VendingMachineSystem.cs` had redundant `EmpPulseEvent` listeners culled. - `Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml` buffed EMP grenade. ## Media https://www.youtube.com/embed/rSVph6OIg1s?si=8o4bx9Vx16B6usuu - outdated video demonstrating changes on a wizden map https://www.youtube.com/embed/B3iPhLcfs-0?si=trB1HY2ccjMf96Bj - electrical anomaly crit with updated emp - [x] I have added screenshots/videos to this PR showcasing its changes ingame, **or** this PR does not require an ingame showcase **Changelog** :cl: - tweak: EMP Grenades can now disable basically any electrical device, and stack in disable duration. --------- Signed-off-by: VMSolidus Co-authored-by: VMSolidus --- .../EntitySystems/GasThermoMachineSystem.cs | 2 +- .../Atmos/Portable/SpaceHeaterSystem.cs | 2 +- .../Unit/EntitySystems/DisposalUnitSystem.cs | 2 +- Content.Server/Emp/EmpSystem.cs | 33 ++-- .../Gravity/GravityGeneratorSystem.cs | 26 +++ .../Components/ActiveChargerComponent.cs | 10 -- .../Power/Components/ChargingComponent.cs | 19 +++ .../Power/EntitySystems/ApcSystem.cs | 19 ++- .../Power/EntitySystems/BatterySystem.cs | 32 +++- .../Power/EntitySystems/ChargerSystem.cs | 149 ++++++++++++++---- .../EntitySystems/PowerReceiverSystem.cs | 38 ++++- Content.Server/Power/PowerWireAction.cs | 4 + .../Systems/SurveillanceCameraSystem.cs | 19 --- .../VendingMachines/VendingMachineSystem.cs | 11 -- .../Objects/Weapons/Throwable/grenades.yml | 2 +- 15 files changed, 273 insertions(+), 95 deletions(-) delete mode 100644 Content.Server/Power/Components/ActiveChargerComponent.cs create mode 100644 Content.Server/Power/Components/ChargingComponent.cs diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs index 9b61044f03e..720fd5b5b91 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs @@ -143,7 +143,7 @@ private bool IsHeater(GasThermoMachineComponent comp) private void OnToggleMessage(EntityUid uid, GasThermoMachineComponent thermoMachine, GasThermomachineToggleMessage args) { - var powerState = _power.TogglePower(uid); + var powerState = _power.TryTogglePower(uid); _adminLogger.Add(LogType.AtmosPowerChanged, $"{ToPrettyString(args.Session.AttachedEntity)} turned {(powerState ? "On" : "Off")} {ToPrettyString(uid)}"); DirtyUI(uid, thermoMachine); } diff --git a/Content.Server/Atmos/Portable/SpaceHeaterSystem.cs b/Content.Server/Atmos/Portable/SpaceHeaterSystem.cs index fff15f696c4..8094b0e1a66 100644 --- a/Content.Server/Atmos/Portable/SpaceHeaterSystem.cs +++ b/Content.Server/Atmos/Portable/SpaceHeaterSystem.cs @@ -98,7 +98,7 @@ private void OnToggle(EntityUid uid, SpaceHeaterComponent spaceHeater, SpaceHeat if (!Resolve(uid, ref powerReceiver)) return; - _power.TogglePower(uid); + _power.TryTogglePower(uid); UpdateAppearance(uid); DirtyUI(uid, spaceHeater); diff --git a/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs b/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs index f9403f33b9d..d6647bbf2eb 100644 --- a/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs +++ b/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs @@ -235,7 +235,7 @@ private void OnUiButtonPressed(EntityUid uid, SharedDisposalUnitComponent compon _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(player):player} hit flush button on {ToPrettyString(uid)}, it's now {(component.Engaged ? "on" : "off")}"); break; case SharedDisposalUnitComponent.UiButton.Power: - _power.TogglePower(uid, user: args.Session.AttachedEntity); + _power.TryTogglePower(uid, user: args.Session.AttachedEntity); break; default: throw new ArgumentOutOfRangeException($"{ToPrettyString(player):player} attempted to hit a nonexistant button on {ToPrettyString(uid)}"); diff --git a/Content.Server/Emp/EmpSystem.cs b/Content.Server/Emp/EmpSystem.cs index 7c1a6f9b5db..3a1d2d28196 100644 --- a/Content.Server/Emp/EmpSystem.cs +++ b/Content.Server/Emp/EmpSystem.cs @@ -1,7 +1,7 @@ using Content.Server.Explosion.EntitySystems; +using Content.Server.Power.Components; using Content.Server.Power.EntitySystems; using Content.Server.Radio; -using Content.Server.SurveillanceCamera; using Content.Shared.Emp; using Content.Shared.Examine; using Robust.Shared.Map; @@ -22,8 +22,6 @@ public override void Initialize() SubscribeLocalEvent(OnRadioSendAttempt); SubscribeLocalEvent(OnRadioReceiveAttempt); - SubscribeLocalEvent(OnApcToggleMainBreaker); - SubscribeLocalEvent(OnCameraSetActive); } /// @@ -75,7 +73,19 @@ public void DoEmpEffects(EntityUid uid, float energyConsumption, float duration) if (ev.Disabled) { var disabled = EnsureComp(uid); - disabled.DisabledUntil = Timing.CurTime + TimeSpan.FromSeconds(duration); + // couldnt use null-coalescing operator here sadge + if (disabled.DisabledUntil == TimeSpan.Zero) + { + disabled.DisabledUntil = Timing.CurTime; + } + disabled.DisabledUntil = disabled.DisabledUntil + TimeSpan.FromSeconds(duration); + + /// i tried my best to go through the Pow3r server code but i literally couldn't find in relation to PowerNetworkBatteryComponent that uses the event system + /// the code is otherwise too esoteric for my innocent eyes + if (TryComp(uid, out var powerNetBattery)) + { + powerNetBattery.CanCharge = false; + } } } @@ -91,6 +101,11 @@ public override void Update(float frameTime) RemComp(uid); var ev = new EmpDisabledRemoved(); RaiseLocalEvent(uid, ref ev); + + if (TryComp(uid, out var powerNetBattery)) + { + powerNetBattery.CanCharge = true; + } } } } @@ -115,16 +130,6 @@ private void OnRadioReceiveAttempt(EntityUid uid, EmpDisabledComponent component { args.Cancelled = true; } - - private void OnApcToggleMainBreaker(EntityUid uid, EmpDisabledComponent component, ref ApcToggleMainBreakerAttemptEvent args) - { - args.Cancelled = true; - } - - private void OnCameraSetActive(EntityUid uid, EmpDisabledComponent component, ref SurveillanceCameraSetActiveAttemptEvent args) - { - args.Cancelled = true; - } } /// diff --git a/Content.Server/Gravity/GravityGeneratorSystem.cs b/Content.Server/Gravity/GravityGeneratorSystem.cs index b0c4bb56ff3..ec5646457e2 100644 --- a/Content.Server/Gravity/GravityGeneratorSystem.cs +++ b/Content.Server/Gravity/GravityGeneratorSystem.cs @@ -1,6 +1,7 @@ using Content.Server.Administration.Logs; using Content.Server.Audio; using Content.Server.Power.Components; +using Content.Server.Emp; using Content.Shared.Database; using Content.Shared.Gravity; using Content.Shared.Interaction; @@ -28,6 +29,8 @@ public override void Initialize() SubscribeLocalEvent(OnInteractHand); SubscribeLocalEvent( OnSwitchGenerator); + + SubscribeLocalEvent(OnEmpPulse); } private void OnParentChanged(EntityUid uid, GravityGeneratorComponent component, ref EntParentChangedMessage args) @@ -289,5 +292,28 @@ private void OnSwitchGenerator( { SetSwitchedOn(uid, component, args.On, session:args.Session); } + + private void OnEmpPulse(EntityUid uid, GravityGeneratorComponent component, EmpPulseEvent args) + { + /// i really don't think that the gravity generator should use normalised 0-1 charge + /// as opposed to watts charge that every other battery uses + + ApcPowerReceiverComponent? powerReceiver = null; + if (!Resolve(uid, ref powerReceiver, false)) + return; + + var ent = (uid, component, powerReceiver); + + // convert from normalised energy to watts and subtract + float maxEnergy = component.ActivePowerUse / component.ChargeRate; + float currentEnergy = maxEnergy * component.Charge; + currentEnergy = Math.Max(0, currentEnergy - args.EnergyConsumption); + + // apply renormalised energy to charge variable + component.Charge = currentEnergy / maxEnergy; + + // update power state + UpdateState(ent); + } } } diff --git a/Content.Server/Power/Components/ActiveChargerComponent.cs b/Content.Server/Power/Components/ActiveChargerComponent.cs deleted file mode 100644 index f3d863c9e43..00000000000 --- a/Content.Server/Power/Components/ActiveChargerComponent.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Content.Shared.Containers.ItemSlots; -using Content.Shared.Power; - -namespace Content.Server.Power.Components -{ - [RegisterComponent] - public sealed partial class ActiveChargerComponent : Component - { - } -} diff --git a/Content.Server/Power/Components/ChargingComponent.cs b/Content.Server/Power/Components/ChargingComponent.cs new file mode 100644 index 00000000000..db7c14f7082 --- /dev/null +++ b/Content.Server/Power/Components/ChargingComponent.cs @@ -0,0 +1,19 @@ +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Power; + +namespace Content.Server.Power.Components +{ + [RegisterComponent] + public sealed partial class ChargingComponent : Component + { + /// + ///References the entity of the charger that is currently powering this battery + /// + public EntityUid ChargerUid; + + /// + ///References the component of the charger that is currently powering this battery + /// + public ChargerComponent ChargerComponent; + } +} diff --git a/Content.Server/Power/EntitySystems/ApcSystem.cs b/Content.Server/Power/EntitySystems/ApcSystem.cs index 95b5d74a945..f345c9e88ea 100644 --- a/Content.Server/Power/EntitySystems/ApcSystem.cs +++ b/Content.Server/Power/EntitySystems/ApcSystem.cs @@ -7,6 +7,7 @@ using Content.Shared.APC; using Content.Shared.Emag.Components; using Content.Shared.Emag.Systems; +using Content.Shared.Emp; using Content.Shared.Popups; using Robust.Server.GameObjects; using Robust.Shared.Audio; @@ -37,6 +38,7 @@ public override void Initialize() SubscribeLocalEvent(OnEmagged); SubscribeLocalEvent(OnEmpPulse); + SubscribeLocalEvent(OnEmpDisabledRemoved); } public override void Update(float deltaTime) @@ -163,7 +165,7 @@ public void UpdateUIState(EntityUid uid, private ApcChargeState CalcChargeState(EntityUid uid, PowerState.Battery battery) { - if (HasComp(uid)) + if (HasComp(uid) || HasComp(uid)) return ApcChargeState.Emag; if (battery.CurrentStorage / battery.Capacity > ApcComponent.HighPowerThreshold) @@ -190,15 +192,16 @@ private ApcExternalPowerState CalcExtPowerState(EntityUid uid, PowerState.Batter return ApcExternalPowerState.Good; } - + private void OnEmpPulse(EntityUid uid, ApcComponent component, ref EmpPulseEvent args) { - if (component.MainBreakerEnabled) - { - args.Affected = true; - args.Disabled = true; - ApcToggleBreaker(uid, component); - } + EnsureComp(uid, out var emp); //event calls before EmpDisabledComponent is added, ensure it to force sprite update + UpdateApcState(uid); + } + + private void OnEmpDisabledRemoved(EntityUid uid, ApcComponent component, ref EmpDisabledRemoved args) + { + UpdateApcState(uid); } } diff --git a/Content.Server/Power/EntitySystems/BatterySystem.cs b/Content.Server/Power/EntitySystems/BatterySystem.cs index 0a0f2068b58..1c5d83b094d 100644 --- a/Content.Server/Power/EntitySystems/BatterySystem.cs +++ b/Content.Server/Power/EntitySystems/BatterySystem.cs @@ -1,5 +1,6 @@ using Content.Server.Cargo.Systems; using Content.Server.Emp; +using Content.Shared.Emp; using Content.Server.Power.Components; using Content.Shared.Examine; using Content.Shared.Rejuvenate; @@ -20,6 +21,7 @@ public override void Initialize() SubscribeLocalEvent(OnBatteryRejuvenate); SubscribeLocalEvent(CalculateBatteryPrice); SubscribeLocalEvent(OnEmpPulse); + SubscribeLocalEvent(OnEmpDisabledRemoved); SubscribeLocalEvent(PreSync); SubscribeLocalEvent(PostSync); @@ -85,7 +87,7 @@ public override void Update(float frameTime) { if (!comp.AutoRecharge) continue; if (batt.IsFullyCharged) continue; - SetCharge(uid, batt.CurrentCharge + comp.AutoRechargeRate * frameTime, batt); + TrySetCharge(uid, batt.CurrentCharge + comp.AutoRechargeRate * frameTime, batt); } } @@ -100,9 +102,21 @@ private void CalculateBatteryPrice(EntityUid uid, BatteryComponent component, re private void OnEmpPulse(EntityUid uid, BatteryComponent component, ref EmpPulseEvent args) { args.Affected = true; + args.Disabled = true; UseCharge(uid, args.EnergyConsumption, component); } + // if a disabled battery is put into a recharged, + // allow the recharger to start recharging again after the disable ends + private void OnEmpDisabledRemoved(EntityUid uid, BatteryComponent component, ref EmpDisabledRemoved args) + { + if (!TryComp(uid, out var charging)) + return; + + var ev = new ChargerUpdateStatusEvent(); + RaiseLocalEvent(charging.ChargerUid, ref ev); + } + public float UseCharge(EntityUid uid, float value, BatteryComponent? battery = null) { if (value <= 0 || !Resolve(uid, ref battery) || battery.CurrentCharge == 0) @@ -157,6 +171,18 @@ public bool TryUseCharge(EntityUid uid, float value, BatteryComponent? battery = return true; } + /// + /// Like SetCharge, but checks for conditions like EmpDisabled before executing + /// + public bool TrySetCharge(EntityUid uid, float value, BatteryComponent? battery = null) + { + if (!Resolve(uid, ref battery, false) || TryComp(uid, out var emp)) + return false; + + SetCharge(uid, value, battery); + return true; + } + /// /// Returns whether the battery is at least 99% charged, basically full. /// @@ -165,6 +191,10 @@ public bool IsFull(EntityUid uid, BatteryComponent? battery = null) if (!Resolve(uid, ref battery)) return false; + // If the battery is full, remove its charging component. + if (TryComp(uid, out _)) + RemComp(uid); + return battery.CurrentCharge / battery.MaxCharge >= 0.99f; } } diff --git a/Content.Server/Power/EntitySystems/ChargerSystem.cs b/Content.Server/Power/EntitySystems/ChargerSystem.cs index db16dfa008e..ae6b024162e 100644 --- a/Content.Server/Power/EntitySystems/ChargerSystem.cs +++ b/Content.Server/Power/EntitySystems/ChargerSystem.cs @@ -1,13 +1,16 @@ using Content.Server.Power.Components; +using Content.Server.Emp; using Content.Server.PowerCell; using Content.Shared.Examine; using Content.Shared.Power; using Content.Shared.PowerCell.Components; +using Content.Shared.Emp; using JetBrains.Annotations; using Robust.Shared.Containers; using System.Diagnostics.CodeAnalysis; using Content.Shared.Storage.Components; using Robust.Server.Containers; +using Content.Shared.Whitelist; namespace Content.Server.Power.EntitySystems; @@ -28,6 +31,11 @@ public override void Initialize() SubscribeLocalEvent(OnInsertAttempt); SubscribeLocalEvent(OnEntityStorageInsertAttempt); SubscribeLocalEvent(OnChargerExamine); + + SubscribeLocalEvent(OnUpdateStatus); + + SubscribeLocalEvent(OnEmpPulse); + SubscribeLocalEvent(OnEmpDisabledRemoved); } private void OnStartup(EntityUid uid, ChargerComponent component, ComponentStartup args) @@ -40,21 +48,58 @@ private void OnChargerExamine(EntityUid uid, ChargerComponent component, Examine args.PushMarkup(Loc.GetString("charger-examine", ("color", "yellow"), ("chargeRate", (int) component.ChargeRate))); } + private void StartChargingBattery(EntityUid uid, ChargerComponent component, EntityUid target) + { + bool charge = true; + + if (HasComp(uid)) + charge = false; + else + if (!TryComp(target, out var battery)) + charge = false; + else + if (Math.Abs(battery.MaxCharge - battery.CurrentCharge) < 0.01) + charge = false; + + // wrap functionality in an if statement instead of returning... + if (charge) + { + var charging = EnsureComp(target); + charging.ChargerUid = uid; + charging.ChargerComponent = component; + } + + // ...so the status always updates (for insertin a power cell) + UpdateStatus(uid, component); + } + + private void StopChargingBattery(EntityUid uid, ChargerComponent component, EntityUid target) + { + if (HasComp(target)) + RemComp(target); + UpdateStatus(uid, component); + } + public override void Update(float frameTime) { - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out _, out var charger, out var containerComp)) + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var charging)) { - if (!_container.TryGetContainer(uid, charger.SlotId, out var container, containerComp)) + if (!TryComp(charging.ChargerUid, out var chargerComponent)) continue; - if (charger.Status == CellChargerStatus.Empty || charger.Status == CellChargerStatus.Charged || container.ContainedEntities.Count == 0) + if (charging.ChargerComponent.Status == CellChargerStatus.Off || charging.ChargerComponent.Status == CellChargerStatus.Empty) continue; - foreach (var contained in container.ContainedEntities) - { - TransferPower(uid, contained, charger, frameTime); - } + if (HasComp(charging.ChargerUid)) + continue; + + if (!TryComp(uid, out var battery)) + continue; + + if (Math.Abs(battery.MaxCharge - battery.CurrentCharge) < 0.01) + StopChargingBattery(charging.ChargerUid, charging.ChargerComponent, uid); + TransferPower(charging.ChargerUid, uid, charging.ChargerComponent, frameTime); } } @@ -71,7 +116,7 @@ private void OnInserted(EntityUid uid, ChargerComponent component, EntInsertedIn if (args.Container.ID != component.SlotId) return; - UpdateStatus(uid, component); + StartChargingBattery(uid, component, args.Entity); } private void OnRemoved(EntityUid uid, ChargerComponent component, EntRemovedFromContainerMessage args) @@ -79,7 +124,7 @@ private void OnRemoved(EntityUid uid, ChargerComponent component, EntRemovedFrom if (args.Container.ID != component.SlotId) return; - UpdateStatus(uid, component); + StopChargingBattery(uid, component, args.Entity); } /// @@ -112,6 +157,11 @@ private void OnEntityStorageInsertAttempt(EntityUid uid, ChargerComponent compon args.Cancelled = true; } + private void OnUpdateStatus(EntityUid uid, ChargerComponent component, ref ChargerUpdateStatusEvent args) + { + UpdateStatus(uid, component); + } + private void UpdateStatus(EntityUid uid, ChargerComponent component) { var status = GetStatus(uid, component); @@ -126,15 +176,6 @@ private void UpdateStatus(EntityUid uid, ChargerComponent component) component.Status = status; - if (component.Status == CellChargerStatus.Charging) - { - AddComp(uid); - } - else - { - RemComp(uid); - } - switch (component.Status) { case CellChargerStatus.Off: @@ -146,7 +187,7 @@ private void UpdateStatus(EntityUid uid, ChargerComponent component) _appearance.SetData(uid, CellVisual.Light, CellChargerStatus.Empty, appearance); break; case CellChargerStatus.Charging: - receiver.Load = component.ChargeRate; + receiver.Load = component.ChargeRate; //does not scale with multiple slotted batteries _appearance.SetData(uid, CellVisual.Light, CellChargerStatus.Charging, appearance); break; case CellChargerStatus.Charged: @@ -157,6 +198,42 @@ private void UpdateStatus(EntityUid uid, ChargerComponent component) throw new ArgumentOutOfRangeException(); } } + + private void OnEmpPulse(EntityUid uid, ChargerComponent component, ref EmpPulseEvent args) + { + // we don't care if we haven't been disabled + if (!args.Disabled) + return; + + // if the recharger is hit by an emp pulse, + // stop recharging contained batteries to save resources + if (!_container.TryGetContainer(uid, component.SlotId, out var container)) + return; + + foreach (var containedEntity in container.ContainedEntities) + { + if (!SearchForBattery(containedEntity, out _, out _)) + continue; + + StopChargingBattery(uid, component, containedEntity); + } + } + + private void OnEmpDisabledRemoved(EntityUid uid, ChargerComponent component, ref EmpDisabledRemoved args) + { + // if an emp disable subsides, + // attempt to start charging all batteries + if (!_container.TryGetContainer(uid, component.SlotId, out var container)) + return; + + foreach (var containedEntity in container.ContainedEntities) + { + if (!SearchForBattery(containedEntity, out _, out _)) + continue; + + StartChargingBattery(uid, component, containedEntity); + } + } private CellChargerStatus GetStatus(EntityUid uid, ChargerComponent component) { @@ -178,13 +255,28 @@ private CellChargerStatus GetStatus(EntityUid uid, ChargerComponent component) if (container.ContainedEntities.Count == 0) return CellChargerStatus.Empty; - if (!SearchForBattery(container.ContainedEntities[0], out _, out var heldBattery)) - return CellChargerStatus.Off; + var statusOut = CellChargerStatus.Off; - if (Math.Abs(heldBattery.MaxCharge - heldBattery.CurrentCharge) < 0.01) - return CellChargerStatus.Charged; + foreach (var containedEntity in container.ContainedEntities) + { + // if none of the slotted items are actually batteries, represent the charger as off + if (!SearchForBattery(containedEntity, out _, out _)) + continue; - return CellChargerStatus.Charging; + // if all batteries are either EMP'd or fully charged, represent the charger as fully charged + statusOut = CellChargerStatus.Charged; + if (HasComp(containedEntity)) + continue; + + if (!HasComp(containedEntity)) + continue; + + // if we have atleast one battery being charged, represent the charger as charging; + statusOut = CellChargerStatus.Charging; + break; + } + + return statusOut; } private void TransferPower(EntityUid uid, EntityUid targetEntity, ChargerComponent component, float frameTime) @@ -201,11 +293,11 @@ private void TransferPower(EntityUid uid, EntityUid targetEntity, ChargerCompone if (!SearchForBattery(targetEntity, out var batteryUid, out var heldBattery)) return; - _battery.SetCharge(batteryUid.Value, heldBattery.CurrentCharge + component.ChargeRate * frameTime, heldBattery); + _battery.TrySetCharge(batteryUid.Value, heldBattery.CurrentCharge + component.ChargeRate * frameTime, heldBattery); // Just so the sprite won't be set to 99.99999% visibility if (heldBattery.MaxCharge - heldBattery.CurrentCharge < 0.01) { - _battery.SetCharge(batteryUid.Value, heldBattery.MaxCharge, heldBattery); + _battery.TrySetCharge(batteryUid.Value, heldBattery.MaxCharge, heldBattery); } UpdateStatus(uid, component); @@ -223,3 +315,6 @@ private bool SearchForBattery(EntityUid uid, [NotNullWhen(true)] out EntityUid? return true; } } + +[ByRefEvent] +public record struct ChargerUpdateStatusEvent(); \ No newline at end of file diff --git a/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs b/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs index 048fda23553..2157a53a53d 100644 --- a/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs +++ b/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs @@ -1,6 +1,7 @@ using Content.Server.Administration.Logs; using Content.Server.Administration.Managers; using Content.Server.Power.Components; +using Content.Server.Emp; using Content.Shared.Administration; using Content.Shared.Database; using Content.Shared.Examine; @@ -11,6 +12,7 @@ using Robust.Server.GameObjects; using Robust.Shared.Audio; using Robust.Shared.Utility; +using Content.Shared.Emp; namespace Content.Server.Power.EntitySystems { @@ -38,6 +40,9 @@ public override void Initialize() SubscribeLocalEvent>(OnGetVerbs); SubscribeLocalEvent>(AddSwitchPowerVerb); + SubscribeLocalEvent(OnEmpPulse); + SubscribeLocalEvent(OnEmpEnd); + _recQuery = GetEntityQuery(); _provQuery = GetEntityQuery(); } @@ -131,7 +136,7 @@ private void AddSwitchPowerVerb(EntityUid uid, PowerSwitchComponent component, G { Act = () => { - TogglePower(uid, user: args.User); + TryTogglePower(uid, user: args.User); }, Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/Spare/poweronoff.svg.192dpi.png")), Text = Loc.GetString("power-switch-component-toggle-verb"), @@ -192,5 +197,36 @@ public bool TogglePower(EntityUid uid, bool playSwitchSound = true, ApcPowerRece return !receiver.PowerDisabled; // i.e. PowerEnabled } + + public bool TryTogglePower(EntityUid uid, bool playSwitchSound = true, ApcPowerReceiverComponent? receiver = null, EntityUid? user = null) + { + if (HasComp(uid)) + return false; + + return TogglePower(uid, playSwitchSound, receiver, user); + } + + public void SetLoad(ApcPowerReceiverComponent comp, float load) + { + comp.Load = load; + } + + private void OnEmpPulse(EntityUid uid, ApcPowerReceiverComponent component, ref EmpPulseEvent args) + { + if (!component.PowerDisabled) + { + args.Affected = true; + args.Disabled = true; + TogglePower(uid, false); + } + } + + private void OnEmpEnd(EntityUid uid, ApcPowerReceiverComponent component, ref EmpDisabledRemoved args) + { + if (component.PowerDisabled) + { + TogglePower(uid, false); + } + } } } diff --git a/Content.Server/Power/PowerWireAction.cs b/Content.Server/Power/PowerWireAction.cs index 785eac91dba..374c1c41acb 100644 --- a/Content.Server/Power/PowerWireAction.cs +++ b/Content.Server/Power/PowerWireAction.cs @@ -1,6 +1,7 @@ using Content.Server.Electrocution; using Content.Server.Power.Components; using Content.Server.Wires; +using Content.Shared.Emp; using Content.Shared.Power; using Content.Shared.Wires; @@ -78,6 +79,9 @@ private void SetPower(EntityUid owner, bool pulsed) return; } + if (EntityManager.TryGetComponent(owner, out var emp)) + return; + power.PowerDisabled = false; } } diff --git a/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraSystem.cs b/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraSystem.cs index 410ba9f7540..ec3d33157ab 100644 --- a/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraSystem.cs +++ b/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraSystem.cs @@ -1,7 +1,6 @@ using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork.Components; using Content.Server.DeviceNetwork.Systems; -using Content.Server.Emp; using Content.Server.Power.Components; using Content.Shared.ActionBlocker; using Content.Shared.DeviceNetwork; @@ -59,9 +58,6 @@ public override void Initialize() SubscribeLocalEvent(OnSetName); SubscribeLocalEvent(OnSetNetwork); SubscribeLocalEvent>(AddVerbs); - - SubscribeLocalEvent(OnEmpPulse); - SubscribeLocalEvent(OnEmpDisabledRemoved); } private void OnPacketReceived(EntityUid uid, SurveillanceCameraComponent component, DeviceNetworkPacketEvent args) @@ -400,21 +396,6 @@ private void UpdateVisuals(EntityUid uid, SurveillanceCameraComponent? component _appearance.SetData(uid, SurveillanceCameraVisualsKey.Key, key, appearance); } - - private void OnEmpPulse(EntityUid uid, SurveillanceCameraComponent component, ref EmpPulseEvent args) - { - if (component.Active) - { - args.Affected = true; - args.Disabled = true; - SetActive(uid, false); - } - } - - private void OnEmpDisabledRemoved(EntityUid uid, SurveillanceCameraComponent component, ref EmpDisabledRemoved args) - { - SetActive(uid, true); - } } public sealed class OnSurveillanceCameraViewerAddEvent : EntityEventArgs diff --git a/Content.Server/VendingMachines/VendingMachineSystem.cs b/Content.Server/VendingMachines/VendingMachineSystem.cs index 7c9aed188fe..36fa69313e3 100644 --- a/Content.Server/VendingMachines/VendingMachineSystem.cs +++ b/Content.Server/VendingMachines/VendingMachineSystem.cs @@ -49,7 +49,6 @@ public override void Initialize() SubscribeLocalEvent(OnEmagged); SubscribeLocalEvent(OnDamage); SubscribeLocalEvent(OnVendingPrice); - SubscribeLocalEvent(OnEmpPulse); SubscribeLocalEvent(OnActivatableUIOpenAttempt); @@ -496,15 +495,5 @@ private void OnPriceCalculation(EntityUid uid, VendingMachineRestockComponent co args.Price += priceSets.Max(); } - - private void OnEmpPulse(EntityUid uid, VendingMachineComponent component, ref EmpPulseEvent args) - { - if (!component.Broken && this.IsPowered(uid, EntityManager)) - { - args.Affected = true; - args.Disabled = true; - component.NextEmpEject = _timing.CurTime; - } - } } } diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml index 1cad73e30ea..f25023b4541 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml @@ -314,7 +314,7 @@ sprite: Objects/Weapons/Grenades/empgrenade.rsi - type: EmpOnTrigger range: 4 - energyConsumption: 50000 + energyConsumption: 2700000 - type: DeleteOnTrigger - type: Appearance - type: TimerTriggerVisuals From b6b21da48d04d2ea6ee5d3062da853a5424647c6 Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Tue, 6 Aug 2024 20:48:10 +0000 Subject: [PATCH 21/32] Automatic Changelog Update (#516) --- Resources/Changelog/Changelog.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index e0226cd7bf7..c66b99d2ea1 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -5009,3 +5009,11 @@ Entries: climbing tables and crawling. id: 6226 time: '2024-08-06T20:37:00.0000000+00:00' +- author: WarMechanic + changes: + - type: Tweak + message: >- + EMP Grenades can now disable basically any electrical device, and stack + in disable duration. + id: 6227 + time: '2024-08-06T20:47:49.0000000+00:00' From 81ad859c46fc48ca3b19e8165454bda5ad52f8f1 Mon Sep 17 00:00:00 2001 From: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com> Date: Wed, 7 Aug 2024 00:22:11 +0300 Subject: [PATCH 22/32] Admeme Language Commands (Attempt 2) (#565) # Description #562 but using commands instead of tricks. Less user-friendly but makes you look like a hacker when you use them :trollface:

Media

![image](https://github.com/user-attachments/assets/818b6226-aea8-4f9a-b30d-5df39b8041e6) ![image](https://github.com/user-attachments/assets/f3c40feb-f84d-4083-bc9a-44f7b1dfb30d) ![image](https://github.com/user-attachments/assets/31827207-4903-4df1-9074-eb060d0cf63c) (ignore the missing locale, I fixes)

# Changelog :cl: - add: Admin tooling: added several admin commands to help manipulate entities' languages. --------- Signed-off-by: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com> Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> --- .../Language/Commands/AdminLanguageCommand.cs | 75 +++++++++ .../Commands/AdminTranslatorCommand.cs | 155 ++++++++++++++++++ Resources/Locale/en-US/language/commands.ftl | 18 ++ 3 files changed, 248 insertions(+) create mode 100644 Content.Server/Language/Commands/AdminLanguageCommand.cs create mode 100644 Content.Server/Language/Commands/AdminTranslatorCommand.cs diff --git a/Content.Server/Language/Commands/AdminLanguageCommand.cs b/Content.Server/Language/Commands/AdminLanguageCommand.cs new file mode 100644 index 00000000000..f02d9c7f401 --- /dev/null +++ b/Content.Server/Language/Commands/AdminLanguageCommand.cs @@ -0,0 +1,75 @@ +using Content.Server.Administration; +using Content.Shared.Administration; +using Content.Shared.Language; +using Content.Shared.Language.Components; +using Content.Shared.Language.Systems; +using Robust.Shared.Toolshed; +using Robust.Shared.Toolshed.Syntax; +using Robust.Shared.Toolshed.TypeParsers; + +namespace Content.Server.Language.Commands; + +[ToolshedCommand(Name = "language"), AdminCommand(AdminFlags.Admin)] +public sealed class AdminLanguageCommand : ToolshedCommand +{ + private LanguageSystem? _languagesField; + private LanguageSystem Languages => _languagesField ??= GetSys(); + + [CommandImplementation("add")] + public EntityUid AddLanguage( + [CommandInvocationContext] IInvocationContext ctx, + [PipedArgument] EntityUid input, + [CommandArgument] ValueRef> @ref, + [CommandArgument] bool canSpeak = true, + [CommandArgument] bool canUnderstand = true + ) + { + var language = @ref.Evaluate(ctx)!; + + if (language == SharedLanguageSystem.UniversalPrototype) + { + EnsureComp(input); + Languages.UpdateEntityLanguages(input); + } + else + { + EnsureComp(input); + Languages.AddLanguage(input, language, canSpeak, canUnderstand); + } + + return input; + } + + [CommandImplementation("rm")] + public EntityUid RemoveLanguage( + [CommandInvocationContext] IInvocationContext ctx, + [PipedArgument] EntityUid input, + [CommandArgument] ValueRef> @ref, + [CommandArgument] bool removeSpeak = true, + [CommandArgument] bool removeUnderstand = true + ) + { + var language = @ref.Evaluate(ctx)!; + if (language == SharedLanguageSystem.UniversalPrototype && HasComp(input)) + { + RemComp(input); + EnsureComp(input); + } + // We execute this branch even in case of universal so that it gets removed if it was added manually to the LanguageKnowledge + Languages.RemoveLanguage(input, language, removeSpeak, removeUnderstand); + + return input; + } + + [CommandImplementation("lsspoken")] + public IEnumerable ListSpoken([PipedArgument] EntityUid input) + { + return Languages.GetSpokenLanguages(input); + } + + [CommandImplementation("lsunderstood")] + public IEnumerable ListUnderstood([PipedArgument] EntityUid input) + { + return Languages.GetUnderstoodLanguages(input); + } +} diff --git a/Content.Server/Language/Commands/AdminTranslatorCommand.cs b/Content.Server/Language/Commands/AdminTranslatorCommand.cs new file mode 100644 index 00000000000..8a7984bc36b --- /dev/null +++ b/Content.Server/Language/Commands/AdminTranslatorCommand.cs @@ -0,0 +1,155 @@ +using System.Diagnostics.CodeAnalysis; +using Content.Server.Administration; +using Content.Shared.Administration; +using Content.Shared.Language; +using Content.Shared.Language.Components; +using Content.Shared.Language.Components.Translators; +using Content.Shared.Language.Systems; +using Robust.Server.Containers; +using Robust.Shared.Toolshed; +using Robust.Shared.Toolshed.Syntax; +using Robust.Shared.Toolshed.TypeParsers; + +namespace Content.Server.Language.Commands; + +[ToolshedCommand(Name = "translator"), AdminCommand(AdminFlags.Admin)] +public sealed class AdminTranslatorCommand : ToolshedCommand +{ + private LanguageSystem? _languagesField; + private ContainerSystem? _containersField; + + private ContainerSystem Containers => _containersField ??= GetSys(); + private LanguageSystem Languages => _languagesField ??= GetSys(); + + [CommandImplementation("addlang")] + public EntityUid AddLanguage( + [CommandInvocationContext] IInvocationContext ctx, + [PipedArgument] EntityUid input, + [CommandArgument] ValueRef> @ref, + [CommandArgument] bool addSpeak = true, + [CommandArgument] bool addUnderstand = true + ) + { + var language = @ref.Evaluate(ctx)!; + // noob trap - needs a universallanguagespeakercomponent + if (language == SharedLanguageSystem.UniversalPrototype) + throw new ArgumentException(Loc.GetString("command-language-error-this-will-not-work")); + + if (!TryGetTranslatorComp(input, out var translator)) + throw new ArgumentException(Loc.GetString("command-language-error-not-a-translator", ("entity", input))); + + if (addSpeak && !translator.SpokenLanguages.Contains(language)) + translator.SpokenLanguages.Add(language); + if (addUnderstand && !translator.UnderstoodLanguages.Contains(language)) + translator.UnderstoodLanguages.Add(language); + + UpdateTranslatorHolder(input); + + return input; + } + + [CommandImplementation("rmlang")] + public EntityUid RemoveLanguage( + [CommandInvocationContext] IInvocationContext ctx, + [PipedArgument] EntityUid input, + [CommandArgument] ValueRef> @ref, + [CommandArgument] bool removeSpeak = true, + [CommandArgument] bool removeUnderstand = true + ) + { + var language = @ref.Evaluate(ctx)!; + if (!TryGetTranslatorComp(input, out var translator)) + throw new ArgumentException(Loc.GetString("command-language-error-not-a-translator", ("entity", input))); + + if (removeSpeak) + translator.SpokenLanguages.Remove(language); + if (removeUnderstand) + translator.UnderstoodLanguages.Remove(language); + + UpdateTranslatorHolder(input); + + return input; + } + + [CommandImplementation("addrequired")] + public EntityUid AddRequiredLanguage( + [CommandInvocationContext] IInvocationContext ctx, + [PipedArgument] EntityUid input, + [CommandArgument] ValueRef> @ref) + { + var language = @ref.Evaluate(ctx)!; + if (!TryGetTranslatorComp(input, out var translator)) + throw new ArgumentException(Loc.GetString("command-language-error-not-a-translator", ("entity", input))); + + if (!translator.RequiredLanguages.Contains(language)) + { + translator.RequiredLanguages.Add(language); + UpdateTranslatorHolder(input); + } + + return input; + } + + [CommandImplementation("rmrequired")] + public EntityUid RemoveRequiredLanguage( + [CommandInvocationContext] IInvocationContext ctx, + [PipedArgument] EntityUid input, + [CommandArgument] ValueRef> @ref) + { + var language = @ref.Evaluate(ctx)!; + if (!TryGetTranslatorComp(input, out var translator)) + throw new ArgumentException(Loc.GetString("command-language-error-not-a-translator", ("entity", input))); + + if (translator.RequiredLanguages.Remove(language)) + UpdateTranslatorHolder(input); + + return input; + } + + [CommandImplementation("lsspoken")] + public IEnumerable ListSpoken([PipedArgument] EntityUid input) + { + if (!TryGetTranslatorComp(input, out var translator)) + return []; + return translator.SpokenLanguages; + } + + [CommandImplementation("lsunderstood")] + public IEnumerable ListUnderstood([PipedArgument] EntityUid input) + { + if (!TryGetTranslatorComp(input, out var translator)) + return []; + return translator.UnderstoodLanguages; + } + + [CommandImplementation("lsrequired")] + public IEnumerable ListRequired([PipedArgument] EntityUid input) + { + if (!TryGetTranslatorComp(input, out var translator)) + return []; + return translator.RequiredLanguages; + } + + private bool TryGetTranslatorComp(EntityUid uid, [NotNullWhen(true)] out BaseTranslatorComponent? translator) + { + if (TryComp(uid, out var handheld)) + translator = handheld; + else if (TryComp(uid, out var implant)) + translator = implant; + else if (TryComp(uid, out var intrinsic)) + translator = intrinsic; + else + translator = null; + + return translator != null; + } + + private void UpdateTranslatorHolder(EntityUid translator) + { + if (!Containers.TryGetContainingContainer(translator, out var cont) + || cont.Owner is not { Valid: true } holder) + return; + + Languages.UpdateEntityLanguages(holder); + } +} diff --git a/Resources/Locale/en-US/language/commands.ftl b/Resources/Locale/en-US/language/commands.ftl index ba2b3160094..65959e3f28f 100644 --- a/Resources/Locale/en-US/language/commands.ftl +++ b/Resources/Locale/en-US/language/commands.ftl @@ -14,3 +14,21 @@ command-language-entry = {$id}. {$language} - {$name} command-language-invalid-number = The language number must be between 0 and {$total}. Alternatively, use the language name. command-language-invalid-language = The language {$id} does not exist or you cannot speak it. + +# toolshed + +command-description-language-add = Adds a new language to the piped entity. The two last arguments indicate whether it should be spoken/understood. Example: 'self language:add "Canilunzt" true true' +command-description-language-rm = Removes a language from the piped entity. Works similarly to language:add. Example: 'self language:rm "GalacticCommon" true true'. +command-description-language-lsspoken = Lists all languages the entity can speak. Example: 'self language:lsspoken' +command-description-language-lsunderstood = Lists all languages the entity can understand. Example: 'self language:lssunderstood' + +command-description-translator-addlang = Adds a new target language to the piped translator entity. See language:add for details. +command-description-translator-rmlang = Removes a target language from the piped translator entity. See language:rm for details. +command-description-translator-addrequired = Adds a new required language to the piped translator entity. Example: 'ent 1234 translator:addrequired "GalacticCommon"' +command-description-translator-rmrequired = Removes a required language from the piped translator entity. Example: 'ent 1234 translator:rmrequired "GalacticCommon"' +command-description-translator-lsspoken = Lists all spoken languages for the piped translator entity. Example: 'ent 1234 translator:lsspoken' +command-description-translator-lsunderstood = Lists all understood languages for the piped translator entity. Example: 'ent 1234 translator:lssunderstood' +command-description-translator-lsrequired = Lists all required languages for the piped translator entity. Example: 'ent 1234 translator:lsrequired' + +command-language-error-this-will-not-work = This will not work. +command-language-error-not-a-translator = Entity {$entity} is not a translator. From 48c0770ff49c622491ded7ae9591e77842304e8b Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Tue, 6 Aug 2024 21:22:38 +0000 Subject: [PATCH 23/32] Automatic Changelog Update (#565) --- Resources/Changelog/Changelog.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index c66b99d2ea1..e3de08a18b0 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -5017,3 +5017,11 @@ Entries: in disable duration. id: 6227 time: '2024-08-06T20:47:49.0000000+00:00' +- author: Mnemotechnician + changes: + - type: Add + message: >- + Admin tooling: added several admin commands to help manipulate entities' + languages. + id: 6228 + time: '2024-08-06T21:22:11.0000000+00:00' From 04d01f687fb479d7f86e2df81cce6b9285dcbad6 Mon Sep 17 00:00:00 2001 From: SleepyScarecrow <136123749+SleepyScarecrow@users.noreply.github.com> Date: Tue, 6 Aug 2024 17:51:21 -0400 Subject: [PATCH 24/32] Added Penlights (#567) # Description Added in penlights that spawn in Medical Staff PDAs. --- # TODO - [x] EyeCheck system - [x] Add in the bloody pens. ---

Media

https://github.com/user-attachments/assets/dc746aa2-782e-4d86-b9ef-9e012343fb87

--- # Changelog :cl: Tilkku - add: Added Pen Lights - add: Eye Examination --------- Signed-off-by: SleepyScarecrow <136123749+SleepyScarecrow@users.noreply.github.com> Co-authored-by: VMSolidus --- .../PenLight/UI/PenLightBoundUserInterface.cs | 47 +++++++ .../Eye/PenLight/UI/PenLightWindow.xaml | 11 ++ .../Eye/PenLight/UI/PenLightWindow.xaml.cs | 78 ++++++++++++ .../EyeProtection/EyeProtectionSystem.cs | 2 +- Content.Server/Medical/PenLightSystem.cs | 118 ++++++++++++++++++ Content.Shared/Medical/PenLightComponent.cs | 33 +++++ Content.Shared/Medical/PenLightUiKey.cs | 9 ++ Content.Shared/Medical/PenLightUserMessage.cs | 24 ++++ .../en-US/medical/components/penlight.ftl | 11 ++ .../Entities/Objects/Devices/pda.yml | 54 ++++++++ .../Entities/Objects/Tools/penlight.yml | 90 +++++++++++++ .../Objects/Tools/cmopenlight.rsi/meta.json | 17 +++ .../Tools/cmopenlight.rsi/world-on.png | Bin 0 -> 4345 bytes .../Objects/Tools/cmopenlight.rsi/world.png | Bin 0 -> 4325 bytes .../Objects/Tools/penlight.rsi/meta.json | 17 +++ .../Objects/Tools/penlight.rsi/world-on.png | Bin 0 -> 253 bytes .../Objects/Tools/penlight.rsi/world.png | Bin 0 -> 234 bytes 17 files changed, 510 insertions(+), 1 deletion(-) create mode 100644 Content.Client/Eye/PenLight/UI/PenLightBoundUserInterface.cs create mode 100644 Content.Client/Eye/PenLight/UI/PenLightWindow.xaml create mode 100644 Content.Client/Eye/PenLight/UI/PenLightWindow.xaml.cs create mode 100644 Content.Server/Medical/PenLightSystem.cs create mode 100644 Content.Shared/Medical/PenLightComponent.cs create mode 100644 Content.Shared/Medical/PenLightUiKey.cs create mode 100644 Content.Shared/Medical/PenLightUserMessage.cs create mode 100644 Resources/Locale/en-US/medical/components/penlight.ftl create mode 100644 Resources/Prototypes/Entities/Objects/Tools/penlight.yml create mode 100644 Resources/Textures/Objects/Tools/cmopenlight.rsi/meta.json create mode 100644 Resources/Textures/Objects/Tools/cmopenlight.rsi/world-on.png create mode 100644 Resources/Textures/Objects/Tools/cmopenlight.rsi/world.png create mode 100644 Resources/Textures/Objects/Tools/penlight.rsi/meta.json create mode 100644 Resources/Textures/Objects/Tools/penlight.rsi/world-on.png create mode 100644 Resources/Textures/Objects/Tools/penlight.rsi/world.png diff --git a/Content.Client/Eye/PenLight/UI/PenLightBoundUserInterface.cs b/Content.Client/Eye/PenLight/UI/PenLightBoundUserInterface.cs new file mode 100644 index 00000000000..c4887531151 --- /dev/null +++ b/Content.Client/Eye/PenLight/UI/PenLightBoundUserInterface.cs @@ -0,0 +1,47 @@ +using Content.Shared.Medical; +using JetBrains.Annotations; +using Robust.Client.GameObjects; + +namespace Content.Client.Eye.PenLight.UI +{ + [UsedImplicitly] + public sealed class PenLightBoundUserInterface : BoundUserInterface + { + [ViewVariables] + private PenLightWindow? _window; + + public PenLightBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } + + protected override void Open() + { + base.Open(); + _window = new PenLightWindow + { + Title = EntMan.GetComponent(Owner).EntityName, + }; + _window.OnClose += Close; + _window.OpenCentered(); + } + + protected override void ReceiveMessage(BoundUserInterfaceMessage message) + { + if (_window == null + || message is not PenLightUserMessage cast) + return; + + _window.Diagnose(cast); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + if (_window != null) + _window.OnClose -= Close; + + _window?.Dispose(); + } + } +} diff --git a/Content.Client/Eye/PenLight/UI/PenLightWindow.xaml b/Content.Client/Eye/PenLight/UI/PenLightWindow.xaml new file mode 100644 index 00000000000..149b8a13828 --- /dev/null +++ b/Content.Client/Eye/PenLight/UI/PenLightWindow.xaml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/Content.Client/Eye/PenLight/UI/PenLightWindow.xaml.cs b/Content.Client/Eye/PenLight/UI/PenLightWindow.xaml.cs new file mode 100644 index 00000000000..809a569fa47 --- /dev/null +++ b/Content.Client/Eye/PenLight/UI/PenLightWindow.xaml.cs @@ -0,0 +1,78 @@ +using Content.Client.UserInterface.Controls; +using Content.Shared.Damage; +using Content.Shared.IdentityManagement; +using Content.Shared.Medical; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.XAML; +using System.Text; + + +namespace Content.Client.Eye.PenLight.UI +{ + [GenerateTypedNameReferences] + public sealed partial class PenLightWindow : FancyWindow + { + private readonly IEntityManager _entityManager; + private const int LightHeight = 150; + private const int LightWidth = 900; + + public PenLightWindow() + { + RobustXamlLoader.Load(this); + + var dependencies = IoCManager.Instance!; + _entityManager = dependencies.Resolve(); + } + public void Diagnose(PenLightUserMessage msg) + { + var target = _entityManager.GetEntity(msg.TargetEntity); + + if (target == null || !_entityManager.TryGetComponent(target, out var damageable)) + { + NoPatientDataText.Visible = true; + ExamDataLabel.Text = string.Empty; + return; + } + + NoPatientDataText.Visible = false; + + + string entityName = Loc.GetString("pen-light-window-entity-unknown-text"); + if (_entityManager.HasComponent(target.Value)) + entityName = Identity.Name(target.Value, _entityManager); + + var sb = new StringBuilder(); + sb.AppendLine(Loc.GetString("pen-light-window-entity-eyes-text", ("entityName", entityName))); + + // Check if Blind and return early if true + if (msg.Blind == true) + { + sb.AppendLine(Loc.GetString("pen-light-exam-blind-text")); + ExamDataLabel.Text = sb.ToString(); + SetHeight = LightHeight; + SetWidth = LightWidth; + return; + } + // EyeDamage + if (msg.EyeDamage == true) + sb.AppendLine(Loc.GetString("pen-light-exam-eyedamage-text")); + + // Drunk + if (msg.Drunk == true) + sb.AppendLine(Loc.GetString("pen-light-exam-drunk-text")); + + // Hallucinating + if (msg.SeeingRainbows == true) + sb.AppendLine(Loc.GetString("pen-light-exam-hallucinating-text")); + + // Healthy + if (msg.Healthy == true) + sb.AppendLine(Loc.GetString("pen-light-exam-healthy-text")); + + ExamDataLabel.Text = sb.ToString(); + + SetHeight = LightHeight; + SetWidth = LightWidth; + } + } +} \ No newline at end of file diff --git a/Content.Server/Eye/Blinding/EyeProtection/EyeProtectionSystem.cs b/Content.Server/Eye/Blinding/EyeProtection/EyeProtectionSystem.cs index 2d54c03b51b..744483cfb82 100644 --- a/Content.Server/Eye/Blinding/EyeProtection/EyeProtectionSystem.cs +++ b/Content.Server/Eye/Blinding/EyeProtection/EyeProtectionSystem.cs @@ -11,7 +11,7 @@ public sealed class EyeProtectionSystem : EntitySystem { [Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!; [Dependency] private readonly BlindableSystem _blindingSystem = default!; - + public override void Initialize() { base.Initialize(); diff --git a/Content.Server/Medical/PenLightSystem.cs b/Content.Server/Medical/PenLightSystem.cs new file mode 100644 index 00000000000..f48a84d0476 --- /dev/null +++ b/Content.Server/Medical/PenLightSystem.cs @@ -0,0 +1,118 @@ +using Content.Server.DoAfter; +using Content.Server.PowerCell; +using Content.Shared.Damage; +using Content.Shared.DoAfter; +using Content.Shared.Drugs; +using Content.Shared.Drunk; +using Content.Shared.Eye.Blinding.Components; +using Content.Shared.Interaction; +using Content.Shared.Medical; +using Content.Shared.Mobs.Systems; +using Content.Shared.Traits.Assorted.Components; +using Robust.Server.GameObjects; +using Robust.Shared.Player; +using Robust.Shared.Timing; + +namespace Content.Server.Medical; +/// +/// This stores the eye exam system for +/// +public sealed class PenLightSystem : EntitySystem +{ + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly DoAfterSystem _doAfter = default!; + [Dependency] private readonly PowerCellSystem _powerCell = default!; + [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; + /// + public override void Initialize() + { + SubscribeLocalEvent(OnAfterInteract); + SubscribeLocalEvent(OnDoAfter); + } + + private void OnAfterInteract(EntityUid uid, PenLightComponent component, AfterInteractEvent args) + { + if (args.Handled + || args.Target is not { } target) + return; + + args.Handled = TryStartExam(uid, target, args.User, component); + } + + private void OnDoAfter(Entity uid, ref PenLightDoAfterEvent args) + { + if (args.Handled + || args.Cancelled + || args.Target == null + || !_powerCell.HasDrawCharge(uid, user: args.User)) + return; + + OpenUserInterface(args.User, uid); + Diagnose(uid, args.Target.Value); + args.Handled = true; + } + + + /// + /// Actually handles the exam interaction. + /// + public bool TryStartExam(EntityUid uid, EntityUid target, EntityUid user, PenLightComponent? component = null) + { + if (!Resolve(uid, ref component)) + return false; + + return _doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, user, component.ExamSpeed, new PenLightDoAfterEvent(), + uid, target, uid) + { + BlockDuplicate = true, + BreakOnUserMove = true, + BreakOnTargetMove = true, + BreakOnHandChange = true, + NeedHand = true + }); + } + private void OpenUserInterface(EntityUid user, EntityUid penlight) + { + if (!TryComp(user, out var actor) + || !_uiSystem.TryGetUi(penlight, PenLightUiKey.Key, out var ui)) + return; + + _uiSystem.OpenUi(ui, actor.PlayerSession); + } + + /// + /// Runs the checks for the different types of eye damage + /// + private void Diagnose(EntityUid penlight, EntityUid target) + { + if (!_uiSystem.TryGetUi(penlight, PenLightUiKey.Key, out var ui) + || !HasComp(target)) + return; + // Blind + var blind = _entityManager.HasComponent(target); + + // Drunk + var drunk = _entityManager.HasComponent(target); + + // EyeDamage + var eyeDamage = false; + if (TryComp(target, out var eyeDam)) + { + eyeDamage = eyeDam.EyeDamage > 0 && eyeDam.EyeDamage < 6; //6 means perma-blind + } + + // Hallucinating + var seeingRainbows = _entityManager.HasComponent(target); + + // Healthy + var healthy = !(blind || drunk || eyeDamage || seeingRainbows); + + _uiSystem.SendUiMessage(ui, new PenLightUserMessage(GetNetEntity(target), + blind, + drunk, + eyeDamage, + healthy, + seeingRainbows + )); + } +} diff --git a/Content.Shared/Medical/PenLightComponent.cs b/Content.Shared/Medical/PenLightComponent.cs new file mode 100644 index 00000000000..50dacae3dc8 --- /dev/null +++ b/Content.Shared/Medical/PenLightComponent.cs @@ -0,0 +1,33 @@ +using Content.Shared.DoAfter; +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; +namespace Content.Shared.Medical; + +/// +/// This for penlights; a tool used to check for eye damage. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentPause] +public sealed partial class PenLightComponent : Component +{ + /// + /// Cooldown Time, exams take a bit + /// + [AutoPausedField] + public TimeSpan? NextExamTime; + + /// + /// The min time between exams + /// + [DataField] + public TimeSpan ExamDelay = TimeSpan.FromSeconds(3); + + /// + /// How long the doafter for the exam takes + /// + [DataField(required: true)] + public float ExamSpeed { get; set; } + +} + +[Serializable, NetSerializable] +public sealed partial class PenLightDoAfterEvent : SimpleDoAfterEvent { } \ No newline at end of file diff --git a/Content.Shared/Medical/PenLightUiKey.cs b/Content.Shared/Medical/PenLightUiKey.cs new file mode 100644 index 00000000000..52fc6ce3401 --- /dev/null +++ b/Content.Shared/Medical/PenLightUiKey.cs @@ -0,0 +1,9 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.Medical; + +[Serializable, NetSerializable] +public enum PenLightUiKey : byte +{ + Key +} diff --git a/Content.Shared/Medical/PenLightUserMessage.cs b/Content.Shared/Medical/PenLightUserMessage.cs new file mode 100644 index 00000000000..42502b2171b --- /dev/null +++ b/Content.Shared/Medical/PenLightUserMessage.cs @@ -0,0 +1,24 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.Medical; +[Serializable, NetSerializable] +public sealed class PenLightUserMessage : BoundUserInterfaceMessage +{ + public readonly NetEntity? TargetEntity; + public bool? Blind; + public bool? Drunk; + public bool? EyeDamage; + public bool? Healthy; + public bool? SeeingRainbows; + + public PenLightUserMessage(NetEntity? targetEntity, bool? blind, bool? drunk, bool? eyeDamage, bool? healthy, bool? seeingRainbows) + { + TargetEntity = targetEntity; + Blind = blind; + Drunk = drunk; + EyeDamage = eyeDamage; + Healthy = healthy; + SeeingRainbows = seeingRainbows; + } +} + diff --git a/Resources/Locale/en-US/medical/components/penlight.ftl b/Resources/Locale/en-US/medical/components/penlight.ftl new file mode 100644 index 00000000000..f0639ad7381 --- /dev/null +++ b/Resources/Locale/en-US/medical/components/penlight.ftl @@ -0,0 +1,11 @@ +penlight-off = The pen light is off. +pen-light-exam-title = Pen Light +pen-light-window-entity-eyes-text = {$entityName}'s conditions: +pen-light-window-no-patient-data-text = No patient data. +pen-light-window-entity-unknown-text = unknown + +pen-light-exam-blind-text = The patient's eyes are glassy and unfocused. They can't follow the light at all. +pen-light-exam-drunk-text = The patient's eyes are slow to follow the light, droopy. +pen-light-exam-eyedamage-text = The patient's eyes are partially focused, though they struggle to look at the light for too long. +pen-light-exam-hallucinating-text = The patient's eyes are wandering around, with dilated pupils. They don't focus on the light. +pen-light-exam-healthy-text = The patient follows the light perfectly with no stuttering. \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index 0f68afefe69..2c28f60da58 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -151,6 +151,12 @@ - type: Pda id: MedicalInternIDCard state: pda-internmed + penSlot: # Pen Lights + startingItem: PenLightBase + priority: -1 + whitelist: + tags: + - Write - type: PdaBorderColor borderColor: "#717059" accentVColor: "#447987" @@ -534,6 +540,12 @@ - type: Pda id: CMOIDCard state: pda-cmo + penSlot: # Fancy Pen Light + startingItem: CMOPenLight + priority: -1 + whitelist: + tags: + - Write - type: PdaBorderColor borderColor: "#d7d7d0" accentHColor: "#447987" @@ -550,6 +562,12 @@ - type: Pda id: MedicalIDCard state: pda-medical + penSlot: # Pen Lights + startingItem: PenLightBase + priority: -1 + whitelist: + tags: + - Write - type: PdaBorderColor borderColor: "#d7d7d0" accentVColor: "#447987" @@ -568,6 +586,12 @@ - type: Pda id: ParamedicIDCard state: pda-paramedic + penSlot: # Pen Lights + startingItem: PenLightBase + priority: -1 + whitelist: + tags: + - Write - type: PdaBorderColor borderColor: "#d7d7d0" accentVColor: "#2a4b5b" @@ -583,6 +607,12 @@ - type: Pda id: ChemistIDCard state: pda-chemistry + penSlot: # Pen Lights + startingItem: PenLightBase + priority: -1 + whitelist: + tags: + - Write - type: PdaBorderColor borderColor: "#d7d7d0" accentVColor: "#B34200" @@ -917,6 +947,12 @@ - type: Pda id: PsychologistIDCard state: pda-medical + penSlot: # Pen Lights + startingItem: PenLightBase + priority: -1 + whitelist: + tags: + - Write - type: PdaBorderColor borderColor: "#d7d7d0" accentVColor: "#447987" @@ -1002,6 +1038,12 @@ - type: Pda id: BrigmedicIDCard state: pda-brigmedic + penSlot: # Pen Lights + startingItem: PenLightBase + priority: -1 + whitelist: + tags: + - Write - type: PdaBorderColor borderColor: "#A32D26" accentHColor: "#d7d7d0" @@ -1079,6 +1121,12 @@ - type: Pda id: SeniorPhysicianIDCard state: pda-seniorphysician + penSlot: # Pen Lights + startingItem: PenLightBase + priority: -1 + whitelist: + tags: + - Write - type: PdaBorderColor borderColor: "#d7d7d0" accentHColor: "#447987" @@ -1129,6 +1177,12 @@ - type: Pda id: SyndicateIDCard state: pda-syndi-agent + penSlot: # Pen Lights + startingItem: PenLightBase + priority: -1 + whitelist: + tags: + - Write - type: PdaBorderColor borderColor: "#891417" - type: Icon diff --git a/Resources/Prototypes/Entities/Objects/Tools/penlight.yml b/Resources/Prototypes/Entities/Objects/Tools/penlight.yml new file mode 100644 index 00000000000..7f8a9b262c0 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Tools/penlight.yml @@ -0,0 +1,90 @@ +- type: entity + name: Pen Light + parent: Pen + id: PenLightBase + description: A pen-sized light, used by medical staff. + components: + - type: HandheldLight + addPrefix: false + - type: Sprite + sprite: Objects/Tools/penlight.rsi + layers: + - state: world + - state: world-on + shader: unshaded + visible: false + map: [ "light" ] + - type: Item + sprite: Objects/Tools/penlight.rsi + heldPrefix: off + - type: PointLight + enabled: false + mask: /Textures/Effects/LightMasks/cone.png + autoRot: true + radius: 2 + netsync: false + - type: PenLight + examSpeed: 3 #time in seconds + - type: Appearance + - type: UserInterface + interfaces: + - key: enum.PenLightUiKey.Key + type: PenLightBoundUserInterface + - type: ToggleableLightVisuals + - type: ContainerContainer + containers: + cell_slot: !type:ContainerSlot {} + - type: PowerCellSlot + cellSlotId: cell_slot + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellSmall + - type: Tag + tags: + - Flashlight + - Write + - Pen + +- type: entity + name: Chief Medical Officer's Pen Light + parent: PenLightBase + id: CMOPenLight + description: A pen-sized light, this one belonging to the Chief Medical Officer. When you get promoted you get a better pen. + components: + - type: HandheldLight + addPrefix: false + - type: Sprite + sprite: Objects/Tools/cmopenlight.rsi + layers: + - state: world + - state: world-on + shader: unshaded + visible: false + map: [ "light" ] + - type: Item + sprite: Objects/Tools/cmopenlight.rsi + heldPrefix: off + - type: PointLight + enabled: false + mask: /Textures/Effects/LightMasks/cone.png + autoRot: true + radius: 2 + netsync: false + - type: PenLight + examSpeed: 1.5 #time in seconds + - type: Appearance + - type: ToggleableLightVisuals + - type: PowerCellSlot + cellSlotId: cell_slot + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellSmall + - type: Tag + tags: + - Flashlight + - Write + - Pen diff --git a/Resources/Textures/Objects/Tools/cmopenlight.rsi/meta.json b/Resources/Textures/Objects/Tools/cmopenlight.rsi/meta.json new file mode 100644 index 00000000000..8f4b8ba253f --- /dev/null +++ b/Resources/Textures/Objects/Tools/cmopenlight.rsi/meta.json @@ -0,0 +1,17 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "MistakeNot4892, https://github.com/NebulaSS13/Nebula/blob/dev/icons/obj/lighting/penlight.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "world" + }, + { + "name": "world-on" + } + ] +} diff --git a/Resources/Textures/Objects/Tools/cmopenlight.rsi/world-on.png b/Resources/Textures/Objects/Tools/cmopenlight.rsi/world-on.png new file mode 100644 index 0000000000000000000000000000000000000000..fbd87cad2035e7c2b6594b9c55a43c83c01d4fcc GIT binary patch literal 4345 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Tools/penlight.rsi/world.png b/Resources/Textures/Objects/Tools/penlight.rsi/world.png new file mode 100644 index 0000000000000000000000000000000000000000..4cf616bf959f0b7b8905868edf5cdb484cb863b5 GIT binary patch literal 234 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?4jBOuH;Rhv&5C^*N{ z#WAE}&fBX8c^edXSOa|K9C;YSXuiRx*JR<5f=x>sXZ(qq()`n3vy{J^8>pV)L41Su zu`}UbnX~yS+CT3Vclyd|VKRM{xA>9thCMsiq_Vz5j0Rj>jF-*<-@ zeTmsegyx;!rmfae$yf39$OVO0)rXoS=C#;1d0!URTO1)UE&c94)>?lbc8(;?10eS^ ZFz`# Date: Tue, 6 Aug 2024 21:51:47 +0000 Subject: [PATCH 25/32] Automatic Changelog Update (#567) --- Resources/Changelog/Changelog.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index e3de08a18b0..b3218a908e1 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -5025,3 +5025,11 @@ Entries: languages. id: 6228 time: '2024-08-06T21:22:11.0000000+00:00' +- author: Tilkku + changes: + - type: Add + message: Added Pen Lights + - type: Add + message: Eye Examination + id: 6229 + time: '2024-08-06T21:51:21.0000000+00:00' From 8768df79121f3ccead72d97cba143cec49c9a369 Mon Sep 17 00:00:00 2001 From: Angelo Fallaria Date: Wed, 7 Aug 2024 06:03:35 +0800 Subject: [PATCH 26/32] Unique Glove Fibers (#642) # Description Cherry-picked from Delta-V, originally by @WarMechanic (https://github.com/DeltaV-Station/Delta-v/pull/1455). Original Description: > Every pair of gloves now has its own fingerprint, so items can be traced back to gloves which can then be traced back to people. > > ## Why / Balance > > Evidence is very important to court cases running smoothly, so detectives now have more evidence that can certify whether or not John Syndicate's behaviour is valid. Traitors are now encouraged to either clean evidence off syndicate gear regardless of glove status, or use a disposable pair of gloves specifically for handling syndicate gear to be disposed of later. > > Aside from being required to obfuscate evidence you leave behind, there is now a value proposition to searching glove prints of departments. Wearing gloves that does not correspond your department can punish an unknowing detective into searching the wrong people. > > ## Technical details > > `FiberComponent.cs` now stores a Fiberprint variable like `FingerprintComponent.cs`. The code for assigning a fiberprint is the same as the fingerprint. When evidence is placed on an object, the fiberprint is concatenated to its localised fiber type.

Original Media

> hm ok we have these specific gloves on an akms >
> > > > hm well we found the gloves and they have fingerprints >
> > > > gotem >
> >

# Changelog :cl: WarMechanic - add: Gloves now have unique fingerprints. Items can be traced back to gloves, which can then be traced back to people. --------- Signed-off-by: Angelo Fallaria Co-authored-by: WarMechanic <69510347+WarMechanic@users.noreply.github.com> Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com> Co-authored-by: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Co-authored-by: VMSolidus --- .../Forensics/Components/FiberComponent.cs | 3 +++ .../Forensics/Systems/ForensicsSystem.cs | 17 ++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Content.Server/Forensics/Components/FiberComponent.cs b/Content.Server/Forensics/Components/FiberComponent.cs index 2086c958702..4cbb1e7be7f 100644 --- a/Content.Server/Forensics/Components/FiberComponent.cs +++ b/Content.Server/Forensics/Components/FiberComponent.cs @@ -12,5 +12,8 @@ public sealed partial class FiberComponent : Component [DataField] public string? FiberColor; + + [DataField] + public string? Fiberprint; } } diff --git a/Content.Server/Forensics/Systems/ForensicsSystem.cs b/Content.Server/Forensics/Systems/ForensicsSystem.cs index a081429fd3a..1663c20fedb 100644 --- a/Content.Server/Forensics/Systems/ForensicsSystem.cs +++ b/Content.Server/Forensics/Systems/ForensicsSystem.cs @@ -23,6 +23,7 @@ public sealed class ForensicsSystem : EntitySystem public override void Initialize() { SubscribeLocalEvent(OnInteract); + SubscribeLocalEvent(OnFiberInit); SubscribeLocalEvent(OnFingerprintInit); SubscribeLocalEvent(OnDNAInit); @@ -39,6 +40,11 @@ private void OnInteract(EntityUid uid, FingerprintComponent component, ContactIn ApplyEvidence(uid, args.Other); } + private void OnFiberInit(EntityUid uid, FiberComponent component, MapInitEvent args) + { + component.Fiberprint = GenerateFingerprint(length: 7); + } + private void OnFingerprintInit(EntityUid uid, FingerprintComponent component, MapInitEvent args) { component.Fingerprint = GenerateFingerprint(); @@ -150,9 +156,9 @@ private void OnCleanForensicsDoAfter(EntityUid uid, ForensicsComponent component targetComp.Residues.Add(string.IsNullOrEmpty(residue.ResidueColor) ? Loc.GetString("forensic-residue", ("adjective", residue.ResidueAdjective)) : Loc.GetString("forensic-residue-colored", ("color", residue.ResidueColor), ("adjective", residue.ResidueAdjective))); } - public string GenerateFingerprint() + public string GenerateFingerprint(int length = 16) { - var fingerprint = new byte[16]; + var fingerprint = new byte[Math.Clamp(length, 0, 255)]; _random.NextBytes(fingerprint); return Convert.ToHexString(fingerprint); } @@ -179,7 +185,12 @@ private void ApplyEvidence(EntityUid user, EntityUid target) if (_inventory.TryGetSlotEntity(user, "gloves", out var gloves)) { if (TryComp(gloves, out var fiber) && !string.IsNullOrEmpty(fiber.FiberMaterial)) - component.Fibers.Add(string.IsNullOrEmpty(fiber.FiberColor) ? Loc.GetString("forensic-fibers", ("material", fiber.FiberMaterial)) : Loc.GetString("forensic-fibers-colored", ("color", fiber.FiberColor), ("material", fiber.FiberMaterial))); + { + var fiberLocale = string.IsNullOrEmpty(fiber.FiberColor) + ? Loc.GetString("forensic-fibers", ("material", fiber.FiberMaterial)) + : Loc.GetString("forensic-fibers-colored", ("color", fiber.FiberColor), ("material", fiber.FiberMaterial)); + component.Fibers.Add(fiberLocale + " ; " + fiber.Fiberprint); + } if (HasComp(gloves)) return; From 24a5f9201d906ee52b8a4da4c6e324cd2e64438e Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Tue, 6 Aug 2024 22:03:58 +0000 Subject: [PATCH 27/32] Automatic Changelog Update (#642) --- Resources/Changelog/Changelog.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index b3218a908e1..742c9222745 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -5033,3 +5033,11 @@ Entries: message: Eye Examination id: 6229 time: '2024-08-06T21:51:21.0000000+00:00' +- author: WarMechanic + changes: + - type: Add + message: >- + Gloves now have unique fingerprints. Items can be traced back to gloves, + which can then be traced back to people. + id: 6230 + time: '2024-08-06T22:03:36.0000000+00:00' From bd11307c54e0ed383246c81fec65a9d8dba1309f Mon Sep 17 00:00:00 2001 From: SleepyScarecrow <136123749+SleepyScarecrow@users.noreply.github.com> Date: Tue, 6 Aug 2024 18:04:15 -0400 Subject: [PATCH 28/32] Alphabetized physical-desc.ftl (Fr This Time) (#648) # Description alphabetized physical-desc.ftl because it annoyed me --- .../en-US/reagents/meta/physical-desc.ftl | 170 +++++++++--------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/Resources/Locale/en-US/reagents/meta/physical-desc.ftl b/Resources/Locale/en-US/reagents/meta/physical-desc.ftl index 50ea5f590c7..064b21eaa9c 100644 --- a/Resources/Locale/en-US/reagents/meta/physical-desc.ftl +++ b/Resources/Locale/en-US/reagents/meta/physical-desc.ftl @@ -1,101 +1,101 @@ -reagent-physical-desc-skunky = skunky -reagent-physical-desc-soapy = soapy -reagent-physical-desc-ferrous = ferrous -reagent-physical-desc-nothing = nothing +reagent-physical-desc-abrasive = abrasive +reagent-physical-desc-acidic = acidic reagent-physical-desc-acrid = acrid -reagent-physical-desc-thick-and-grainy = thick and grainy -reagent-physical-desc-necrotic = necrotic -reagent-physical-desc-oily = oily -reagent-physical-desc-glowing = glowing -reagent-physical-desc-heterogeneous = heterogeneous -reagent-physical-desc-mucus-like = mucus-like -reagent-physical-desc-cold = cold +reagent-physical-desc-alkaline = alkaline +reagent-physical-desc-aromatic = aromatic reagent-physical-desc-bee-guts = bee guts -reagent-physical-desc-tangy = tangy -reagent-physical-desc-fizzy = fizzy -reagent-physical-desc-fuzzy = fuzzy -reagent-physical-desc-spicy = spicy -reagent-physical-desc-abrasive = abrasive -reagent-physical-desc-chalky = chalky -reagent-physical-desc-roaring = roaring -reagent-physical-desc-robust = robust -reagent-physical-desc-sickly = sickly -reagent-physical-desc-murky = murky -reagent-physical-desc-bubbling = bubbling -reagent-physical-desc-wormy = wormy -reagent-physical-desc-frosty = frosty reagent-physical-desc-blazing = blazing -reagent-physical-desc-translucent = translucent -reagent-physical-desc-sugary = sugary -reagent-physical-desc-putrid = putrid -reagent-physical-desc-saucey = saucey -reagent-physical-desc-salty = salty -reagent-physical-desc-milky = milky -reagent-physical-desc-refreshing = refreshing -reagent-physical-desc-soothing = soothing -reagent-physical-desc-starchy = starchy -reagent-physical-desc-starry = starry -reagent-physical-desc-tart = tart -reagent-physical-desc-aromatic = aromatic -reagent-physical-desc-thick = thick -reagent-physical-desc-syrupy = syrupy -reagent-physical-desc-grainy = grainy -reagent-physical-desc-foamy = foamy -reagent-physical-desc-tropical = tropical +reagent-physical-desc-bubbling = bubbling +reagent-physical-desc-bubbly = bubbly +reagent-physical-desc-burning = burning +reagent-physical-desc-buzzy = buzzy +reagent-physical-desc-chalky = chalky +reagent-physical-desc-chewy = chewy +reagent-physical-desc-citric = citric +reagent-physical-desc-cloudy = cloudy +reagent-physical-desc-clumpy = clumpy reagent-physical-desc-coarse = coarse -reagent-physical-desc-opaque = opaque -reagent-physical-desc-pulpy = pulpy -reagent-physical-desc-reasonably-metallic = reasonably metallic -reagent-physical-desc-metallic = metallic -reagent-physical-desc-gaseous = gaseous -reagent-physical-desc-ground-brass = ground brass -reagent-physical-desc-dark-brown = dark brown +reagent-physical-desc-cold = cold +reagent-physical-desc-creamy = creamy +reagent-physical-desc-crisp = crisp reagent-physical-desc-crystalline = crystalline -reagent-physical-desc-viscous = viscous -reagent-physical-desc-shiny = shiny +reagent-physical-desc-dark-brown = dark brown reagent-physical-desc-dark-red = dark-red +reagent-physical-desc-electric = electric +reagent-physical-desc-energizing = energizing +reagent-physical-desc-enigmatic = enigmatic +reagent-physical-desc-ethereal = ethereal +reagent-physical-desc-exhilarating = exhilarating +reagent-physical-desc-exotic-smelling = exotic smelling +reagent-physical-desc-ferrous = ferrous +reagent-physical-desc-fibrous = fibrous +reagent-physical-desc-fizzy = fizzy +reagent-physical-desc-fizzy-and-creamy = fizzy and creamy +reagent-physical-desc-fluffy = fluffy +reagent-physical-desc-foamy = foamy +reagent-physical-desc-frosty = frosty +reagent-physical-desc-funny = funny +reagent-physical-desc-fuzzy = fuzzy +reagent-physical-desc-gaseous = gaseous +reagent-physical-desc-glittery = glittery +reagent-physical-desc-gloopy = gloopy +reagent-physical-desc-glowing = glowing +reagent-physical-desc-grainy = grainy +reagent-physical-desc-ground-brass = ground brass +reagent-physical-desc-heterogeneous = heterogeneous +reagent-physical-desc-holy = holy +reagent-physical-desc-inky = inky reagent-physical-desc-ionizing = ionizing +reagent-physical-desc-lemony-fresh = lemony fresh +reagent-physical-desc-metallic = metallic +reagent-physical-desc-milky = milky +reagent-physical-desc-mucus-like = mucus-like +reagent-physical-desc-murky = murky +reagent-physical-desc-necrotic = necrotic +reagent-physical-desc-neural = neural reagent-physical-desc-nondescript = nondescript -reagent-physical-desc-burning = burning +reagent-physical-desc-nothing = nothing +reagent-physical-desc-odorless = odorless +reagent-physical-desc-oily = oily +reagent-physical-desc-opaque = opaque +reagent-physical-desc-overpowering = overpowering reagent-physical-desc-porous = porous reagent-physical-desc-powdery = powdery -reagent-physical-desc-creamy = creamy -reagent-physical-desc-sticky = sticky -reagent-physical-desc-bubbly = bubbly +reagent-physical-desc-pulpy = pulpy +reagent-physical-desc-pungent = pungent +reagent-physical-desc-putrid = putrid +reagent-physical-desc-reasonably-metallic = reasonably metallic +reagent-physical-desc-reflective = reflective +reagent-physical-desc-refreshing = refreshing +reagent-physical-desc-roaring = roaring +reagent-physical-desc-robust = robust reagent-physical-desc-rocky = rocky -reagent-physical-desc-lemony-fresh = lemony fresh +reagent-physical-desc-salty = salty +reagent-physical-desc-saucey = saucey +reagent-physical-desc-shiny = shiny +reagent-physical-desc-sickly = sickly +reagent-physical-desc-skunky = skunky +reagent-physical-desc-slimy = slimy reagent-physical-desc-soapy = soapy -reagent-physical-desc-crisp = crisp -reagent-physical-desc-citric = citric -reagent-physical-desc-acidic = acidic -reagent-physical-desc-buzzy = buzzy -reagent-physical-desc-fibrous = fibrous -reagent-physical-desc-strong-smelling = strong smelling -reagent-physical-desc-fizzy-and-creamy = fizzy and creamy -reagent-physical-desc-overpowering = overpowering +reagent-physical-desc-soapy = soapy +reagent-physical-desc-soothing = soothing reagent-physical-desc-sour = sour -reagent-physical-desc-pungent = pungent -reagent-physical-desc-clumpy = clumpy +reagent-physical-desc-spicy = spicy +reagent-physical-desc-starchy = starchy +reagent-physical-desc-starry = starry +reagent-physical-desc-sticky = sticky +reagent-physical-desc-strong-smelling = strong smelling reagent-physical-desc-strong-smelling = strong-smelling -reagent-physical-desc-odorless = odorless -reagent-physical-desc-gloopy = gloopy -reagent-physical-desc-cloudy = cloudy +reagent-physical-desc-sugary = sugary reagent-physical-desc-sweet = sweet -reagent-physical-desc-electric = electric -reagent-physical-desc-chewy = chewy -reagent-physical-desc-volatile = volatile -reagent-physical-desc-inky = inky -reagent-physical-desc-enigmatic = enigmatic -reagent-physical-desc-exotic-smelling = exotic smelling -reagent-physical-desc-ethereal = ethereal -reagent-physical-desc-glittery = glittery -reagent-physical-desc-energizing = energizing -reagent-physical-desc-exhilarating = exhilarating +reagent-physical-desc-syrupy = syrupy +reagent-physical-desc-tangy = tangy +reagent-physical-desc-tart = tart +reagent-physical-desc-thick = thick +reagent-physical-desc-thick-and-grainy = thick and grainy +reagent-physical-desc-translucent = translucent +reagent-physical-desc-tropical = tropical reagent-physical-desc-vibrant = vibrant -reagent-physical-desc-fluffy = fluffy -reagent-physical-desc-funny = funny -reagent-physical-desc-alkaline = alkaline -reagent-physical-desc-reflective = reflective -reagent-physical-desc-holy = holy -reagent-physical-desc-slimy = slimy -reagent-physical-desc-neural = neural +reagent-physical-desc-viscous = viscous +reagent-physical-desc-volatile = volatile +reagent-physical-desc-wormy = wormy From ab2947b1ff5ba7ef8f60609454897616f8f13f55 Mon Sep 17 00:00:00 2001 From: Angelo Fallaria Date: Wed, 7 Aug 2024 14:07:35 +0800 Subject: [PATCH 29/32] Fix No Blood Regeneration (#689) # Description Being a little too clever with omitting braces in complicated if statement chains in #686 caused blood regeneration for entities without Blood Deficiency to stop working altogether. I added some braces and now blood regeneration works again. I also added `DataField` to `HasBloodDeficiency` because I forgot to add that. # Changelog :cl: Skubman - fix: Passive blood regeneration now works again. --- Content.Server/Body/Components/BloodstreamComponent.cs | 1 + Content.Server/Body/Systems/BloodstreamSystem.cs | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Content.Server/Body/Components/BloodstreamComponent.cs b/Content.Server/Body/Components/BloodstreamComponent.cs index 7a4af3e4cc1..76eadb99fd8 100644 --- a/Content.Server/Body/Components/BloodstreamComponent.cs +++ b/Content.Server/Body/Components/BloodstreamComponent.cs @@ -177,6 +177,7 @@ public sealed partial class BloodstreamComponent : Component /// If this is true, the entity will not passively regenerate blood, /// and instead will slowly lose blood. ///
+ [DataField] public bool HasBloodDeficiency = false; /// diff --git a/Content.Server/Body/Systems/BloodstreamSystem.cs b/Content.Server/Body/Systems/BloodstreamSystem.cs index fafc649eb29..b37ac5efeb4 100644 --- a/Content.Server/Body/Systems/BloodstreamSystem.cs +++ b/Content.Server/Body/Systems/BloodstreamSystem.cs @@ -120,12 +120,15 @@ public override void Update(float frameTime) // Removes blood for Blood Deficiency constantly. if (bloodstream.HasBloodDeficiency) + { if (!_mobStateSystem.IsDead(uid)) RemoveBlood(uid, bloodstream.BloodDeficiencyLossAmount, bloodstream); + } // Adds blood to their blood level if it is below the maximum. - else if (bloodSolution.Volume < bloodSolution.MaxVolume) - if (!_mobStateSystem.IsDead(uid)) - TryModifyBloodLevel(uid, bloodstream.BloodRefreshAmount, bloodstream); + else if (bloodSolution.Volume < bloodSolution.MaxVolume && !_mobStateSystem.IsDead(uid)) + { + TryModifyBloodLevel(uid, bloodstream.BloodRefreshAmount, bloodstream); + } // Removes blood from the bloodstream based on bleed amount (bleed rate) // as well as stop their bleeding to a certain extent. From cf310f302c2add2eb0fe25cc59d7807483049285 Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Wed, 7 Aug 2024 06:08:10 +0000 Subject: [PATCH 30/32] Automatic Changelog Update (#689) --- Resources/Changelog/Changelog.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 742c9222745..73e90b2faf9 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -5041,3 +5041,9 @@ Entries: which can then be traced back to people. id: 6230 time: '2024-08-06T22:03:36.0000000+00:00' +- author: Skubman + changes: + - type: Fix + message: Passive blood regeneration now works again. + id: 6231 + time: '2024-08-07T06:07:35.0000000+00:00' From 69946f87ce695bd0f1378a6705678845608b3a32 Mon Sep 17 00:00:00 2001 From: Fansana <116083121+Fansana@users.noreply.github.com> Date: Wed, 7 Aug 2024 19:31:55 +0200 Subject: [PATCH 31/32] Fix BarotraumaSystem (#694) # Description This PR fixes an issue with the BarotraumaSystem which would constantly report high pressure damage, even when no such damage was applied. --- - [x] Tested High pressure damage correctly reported - [x] Tested Low pressure damage correctly reported - [x] Tested No pressure damage correctly reported --- # Changelog :cl: - fix: Barotrauma admin log spam --- .../Atmos/EntitySystems/BarotraumaSystem.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs b/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs index d55ef355f02..948373940e4 100644 --- a/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs +++ b/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs @@ -247,7 +247,11 @@ public override void Update(float frameTime) var damageScale = MathF.Min(((pressure / Atmospherics.HazardHighPressure) - 1) * Atmospherics.PressureDamageCoefficient, Atmospherics.MaxHighPressureDamage); _damageableSystem.TryChangeDamage(uid, barotrauma.Damage * damageScale, true, false); - + if (!barotrauma.TakingDamage) + { + barotrauma.TakingDamage = true; + _adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} started taking high pressure damage"); + } _alertsSystem.ShowAlert(uid, AlertType.HighPressure, 2); } else @@ -258,11 +262,6 @@ public override void Update(float frameTime) barotrauma.TakingDamage = false; _adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} stopped taking pressure damage"); } - if (!barotrauma.TakingDamage) - { - barotrauma.TakingDamage = true; - _adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} started taking high pressure damage"); - } // Set correct alert. switch (pressure) { From 1b2c946240b1ce5b229bc67ae5a1019d1f983f01 Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Wed, 7 Aug 2024 17:32:22 +0000 Subject: [PATCH 32/32] Automatic Changelog Update (#694) --- Resources/Changelog/Changelog.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 73e90b2faf9..5aca84c9f32 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -5047,3 +5047,9 @@ Entries: message: Passive blood regeneration now works again. id: 6231 time: '2024-08-07T06:07:35.0000000+00:00' +- author: Fansana + changes: + - type: Fix + message: Barotrauma admin log spam + id: 6232 + time: '2024-08-07T17:31:55.0000000+00:00'