From fdbf09fdfafe264f52d67e6671865a75ea30f688 Mon Sep 17 00:00:00 2001 From: gluesniffler Date: Sat, 5 Oct 2024 10:35:35 -0400 Subject: [PATCH 01/16] The ShitMed --- .../Backmen/Body/Components/BrainComponent.cs | 9 + .../Backmen/Body/Components/LungComponent.cs | 9 + .../Body/Components/StomachComponent.cs | 9 + Content.Client/Backmen/Surgery/SurgeryBui.cs | 458 +++++++++++++ .../Backmen/Surgery/SurgeryStepButton.xaml | 4 + .../Backmen/Surgery/SurgeryStepButton.xaml.cs | 16 + .../Backmen/Surgery/SurgerySystem.cs | 13 + .../Backmen/Surgery/SurgeryWindow.xaml | 30 + .../Backmen/Surgery/SurgeryWindow.xaml.cs | 14 + .../Backmen/Targeting/TargetingSystem.cs | 94 +++ .../PartStatus/PartStatusUIController.cs | 81 +++ .../PartStatus/Widgets/PartStatusControl.xaml | 37 ++ .../Widgets/PartStatusControl.xaml.cs | 46 ++ .../Targeting/TargetingUIController.cs | 84 +++ .../Targeting/Widgets/TargetingControl.xaml | 66 ++ .../Widgets/TargetingControl.xaml.cs | 56 ++ Content.Client/Hands/Systems/HandsSystem.cs | 33 +- Content.Client/Input/ContentContexts.cs | 6 + .../Inventory/ClientInventorySystem.cs | 11 +- .../Inventory/InventorySlotsComponent.cs | 2 +- .../Options/UI/Tabs/KeyRebindTab.xaml.cs | 8 + .../Screens/DefaultGameScreen.xaml | 2 + .../Screens/DefaultGameScreen.xaml.cs | 1 + .../Screens/SeparatedChatGameScreen.xaml | 2 + .../Screens/SeparatedChatGameScreen.xaml.cs | 1 + .../Systems/Alerts/Widgets/AlertsUI.xaml | 10 +- .../Inventory/InventoryUIController.cs | 4 +- .../Xenonids/UI/XenoChoiceControl.xaml | 17 + .../Xenonids/UI/XenoChoiceControl.xaml.cs | 29 + .../Atmos/EntitySystems/BarotraumaSystem.cs | 5 +- .../Backmen/Sleep/SleepingSystem.cs | 260 ++++++++ .../Backmen/Surgery/SurgerySystem.cs | 208 ++++++ .../Backmen/Targeting/TargetingSystem.cs | 57 ++ .../Traits/Assorted/LightweightDrunkSystem.cs | 23 + Content.Server/Body/Systems/BodySystem.cs | 39 +- .../Thresholds/Behaviors/GibPartBehavior.cs | 19 + Content.Server/Hands/Systems/HandsSystem.cs | 46 +- Content.Server/Medical/HealingSystem.cs | 40 +- .../Surgery/Body/AmputateAttemptEvent.cs | 7 + .../Backmen/Surgery/Body/EyesComponent.cs | 6 + .../Backmen/Surgery/Body/HeartComponent.cs | 6 + .../Backmen/Surgery/Body/LiverComponent.cs | 6 + .../Body/SharedBodySystem.Integrity.cs | 291 ++++++++ .../SurgeryCloseIncisionConditionComponent.cs | 6 + .../SurgeryLarvaConditionComponent.cs | 6 + ...SurgeryOperatingTableConditionComponent.cs | 6 + .../SurgeryOrganConditionComponent.cs | 18 + .../SurgeryPartConditionComponent.cs | 17 + .../Conditions/SurgeryPartPresentCondition.cs | 6 + .../SurgeryPartRemovedConditionComponent.cs | 14 + .../Surgery/Conditions/SurgeryValidEvent.cs | 9 + .../SurgeryWoundedConditionComponent.cs | 7 + .../Effects/Complete/SurgeryCompletedEvent.cs | 7 + .../Complete/SurgeryRemoveLarvaComponent.cs | 6 + .../SurgeryDamageChangeEffectComponent.cs | 17 + ...rgerySpecialDamageChangeEffectComponent.cs | 14 + .../SurgeryStepAffixPartEffectComponent.cs | 6 + .../Step/SurgeryStepCavityEffectComponent.cs | 10 + .../Step/SurgeryStepEmoteEffectComponent.cs | 12 + .../Effects/Step/SurgeryStepSpawnEffect.cs | 13 + .../Step/SurgeryTendWoundsEffectComponent.cs | 20 + .../Surgery/OperatingTableComponent.cs | 6 + .../Surgery/SharedSurgerySystem.Steps.cs | 625 ++++++++++++++++++ .../Backmen/Surgery/SharedSurgerySystem.cs | 261 ++++++++ .../Backmen/Surgery/StepInvalidReason.cs | 10 + .../Steps/Parts/BleedersClampedComponent.cs | 6 + .../Parts/BodyPartReattachedComponent.cs | 6 + .../Steps/Parts/BodyPartSawedComponent.cs | 6 + .../Steps/Parts/IncisionOpenComponent.cs | 6 + .../Parts/InternalBleedersClampedComponent.cs | 6 + .../Steps/Parts/OrganReattachedComponent.cs | 6 + .../Steps/Parts/PartRemovedComponent.cs | 6 + .../Steps/Parts/RibcageOpenComponent.cs | 6 + .../Steps/Parts/RibcageSawedComponent.cs | 6 + .../Steps/Parts/SkinRetractedComponent.cs | 6 + .../Steps/SurgeryAddOrganStepComponent.cs | 6 + .../Steps/SurgeryAddPartStepComponent.cs | 6 + .../Steps/SurgeryCanPerformStepEvent.cs | 14 + .../SurgeryCutLarvaRootsStepComponent.cs | 6 + .../Steps/SurgeryRemoveOrganStepComponent.cs | 6 + .../Steps/SurgeryRemovePartStepComponent.cs | 6 + .../Steps/SurgeryStepCompleteCheckEvent.cs | 4 + .../Surgery/Steps/SurgeryStepComponent.cs | 22 + .../Backmen/Surgery/SurgeryComponent.cs | 18 + .../Backmen/Surgery/SurgeryDoAfterEvent.cs | 18 + .../Surgery/SurgerySpeedModifierComponent.cs | 11 + .../Backmen/Surgery/SurgeryStepDamageEvent.cs | 9 + .../Backmen/Surgery/SurgeryStepEvent.cs | 7 + .../Backmen/Surgery/SurgeryTargetComponent.cs | 10 + Content.Shared/Backmen/Surgery/SurgeryUI.cs | 27 + .../Backmen/Surgery/Tools/BoneGelComponent.cs | 11 + .../Backmen/Surgery/Tools/BoneSawComponent.cs | 10 + .../Surgery/Tools/BoneSetterComponent.cs | 6 + .../Backmen/Surgery/Tools/CauteryComponent.cs | 10 + .../Surgery/Tools/HemostatComponent.cs | 10 + .../Surgery/Tools/ISurgeryToolComponent.cs | 11 + .../Surgery/Tools/RetractorComponent.cs | 10 + .../Backmen/Surgery/Tools/ScalpelComponent.cs | 10 + .../Surgery/Tools/SurgeryToolComponent.cs | 16 + .../Surgery/Tools/SurgicalDrillComponent.cs | 10 + Content.Shared/Backmen/Targeting/Events.cs | 38 ++ .../Targeting/SharedTargetingSystem.cs | 10 + .../Backmen/Targeting/TargetBodyPart.cs | 10 + .../Backmen/Targeting/TargetIntegrity.cs | 13 + .../Backmen/Targeting/TargetingComponent.cs | 49 ++ Content.Shared/Body/Organ/OrganComponent.cs | 21 +- Content.Shared/Body/Part/BodyPartComponent.cs | 53 +- Content.Shared/Body/Part/BodyPartEvents.cs | 9 + .../Body/Systems/SharedBodySystem.Body.cs | 74 ++- .../Body/Systems/SharedBodySystem.Organs.cs | 11 + .../Body/Systems/SharedBodySystem.Parts.cs | 244 ++++++- .../Body/Systems/SharedBodySystem.cs | 2 +- .../Damage/Systems/DamageableSystem.cs | 82 ++- .../Hands/Components/HandsComponent.cs | 1 + Content.Shared/Input/ContentKeyFunctions.cs | 6 + .../Inventory/InventoryComponent.cs | 1 + .../Inventory/InventorySystem.Slots.cs | 48 +- .../Inventory/InventoryTemplatePrototype.cs | 5 + .../Weapons/Melee/MeleeWeaponComponent.cs | 24 + .../Weapons/Melee/SharedMeleeWeaponSystem.cs | 4 +- .../Audio/Medical/Surgery/attributions.yml | 49 ++ Resources/Audio/Medical/Surgery/cautery1.ogg | Bin 0 -> 34770 bytes Resources/Audio/Medical/Surgery/cautery2.ogg | Bin 0 -> 16854 bytes Resources/Audio/Medical/Surgery/hemostat1.ogg | Bin 0 -> 15729 bytes Resources/Audio/Medical/Surgery/organ1.ogg | Bin 0 -> 18912 bytes Resources/Audio/Medical/Surgery/organ2.ogg | Bin 0 -> 18946 bytes .../Audio/Medical/Surgery/retractor1.ogg | Bin 0 -> 11537 bytes .../Audio/Medical/Surgery/retractor2.ogg | Bin 0 -> 9915 bytes Resources/Audio/Medical/Surgery/saw.ogg | Bin 0 -> 46750 bytes Resources/Audio/Medical/Surgery/scalpel1.ogg | Bin 0 -> 13736 bytes Resources/Audio/Medical/Surgery/scalpel2.ogg | Bin 0 -> 13098 bytes .../en-US/escape-menu/ui/options-menu.ftl | 8 + Resources/Prototypes/Body/Organs/human.yml | 25 +- Resources/Prototypes/Body/Parts/base.yml | 54 ++ .../Prototypes/Body/Prototypes/a_ghost.yml | 16 +- .../Prototypes/Body/Prototypes/human.yml | 32 +- .../Catalog/Fills/Backpacks/duffelbag.yml | 2 + .../Catalog/Fills/Crates/medical.yml | 6 +- .../Entities/Clothing/Belt/belts.yml | 2 +- .../Prototypes/Entities/Mobs/NPCs/animals.yml | 10 + .../Prototypes/Entities/Mobs/Species/base.yml | 5 + .../Objects/Specific/Medical/surgery.yml | 115 +++- .../Furniture/Tables/operating_table.yml | 1 + .../Prototypes/EntityLists/Tools/surgery.yml | 8 +- Resources/Prototypes/Reagents/gases.yml | 16 +- .../Prototypes/Roles/Jobs/Medical/chemist.yml | 8 + .../Jobs/Medical/chief_medical_officer.yml | 8 +- .../Roles/Jobs/Medical/medical_doctor.yml | 8 + .../Roles/Jobs/Medical/medical_intern.yml | 8 + .../Roles/Jobs/Medical/paramedic.yml | 8 + .../Devices/Circuitboards/production.yml | 13 + .../Objects/Specific/Medical/surgery.yml | 76 +++ .../Entities/Structures/Machines/lathe.yml | 42 ++ .../_Backmen/Entities/Surgery/surgeries.yml | 445 +++++++++++++ .../Entities/Surgery/surgery_steps.yml | 444 +++++++++++++ .../_Backmen/Recipes/Lathes/surgery.yml | 91 +++ .../Targeting/Status/head.rsi/head_0.png | Bin 0 -> 140 bytes .../Targeting/Status/head.rsi/head_1.png | Bin 0 -> 140 bytes .../Targeting/Status/head.rsi/head_2.png | Bin 0 -> 140 bytes .../Targeting/Status/head.rsi/head_3.png | Bin 0 -> 140 bytes .../Targeting/Status/head.rsi/head_4.png | Bin 0 -> 140 bytes .../Targeting/Status/head.rsi/head_5.png | Bin 0 -> 140 bytes .../Targeting/Status/head.rsi/head_6.png | Bin 0 -> 140 bytes .../Targeting/Status/head.rsi/head_7.png | Bin 0 -> 140 bytes .../Targeting/Status/head.rsi/head_8.png | Bin 0 -> 155 bytes .../Targeting/Status/head.rsi/meta.json | 38 ++ .../Status/leftarm.rsi/leftarm_0.png | Bin 0 -> 129 bytes .../Status/leftarm.rsi/leftarm_1.png | Bin 0 -> 129 bytes .../Status/leftarm.rsi/leftarm_2.png | Bin 0 -> 129 bytes .../Status/leftarm.rsi/leftarm_3.png | Bin 0 -> 129 bytes .../Status/leftarm.rsi/leftarm_4.png | Bin 0 -> 129 bytes .../Status/leftarm.rsi/leftarm_5.png | Bin 0 -> 129 bytes .../Status/leftarm.rsi/leftarm_6.png | Bin 0 -> 129 bytes .../Status/leftarm.rsi/leftarm_7.png | Bin 0 -> 129 bytes .../Status/leftarm.rsi/leftarm_8.png | Bin 0 -> 145 bytes .../Targeting/Status/leftarm.rsi/meta.json | 38 ++ .../Status/leftleg.rsi/leftleg_0.png | Bin 0 -> 126 bytes .../Status/leftleg.rsi/leftleg_1.png | Bin 0 -> 126 bytes .../Status/leftleg.rsi/leftleg_2.png | Bin 0 -> 126 bytes .../Status/leftleg.rsi/leftleg_3.png | Bin 0 -> 126 bytes .../Status/leftleg.rsi/leftleg_4.png | Bin 0 -> 126 bytes .../Status/leftleg.rsi/leftleg_5.png | Bin 0 -> 126 bytes .../Status/leftleg.rsi/leftleg_6.png | Bin 0 -> 126 bytes .../Status/leftleg.rsi/leftleg_7.png | Bin 0 -> 126 bytes .../Status/leftleg.rsi/leftleg_8.png | Bin 0 -> 153 bytes .../Targeting/Status/leftleg.rsi/meta.json | 38 ++ .../Targeting/Status/rightarm.rsi/meta.json | 38 ++ .../Status/rightarm.rsi/rightarm_0.png | Bin 0 -> 129 bytes .../Status/rightarm.rsi/rightarm_1.png | Bin 0 -> 129 bytes .../Status/rightarm.rsi/rightarm_2.png | Bin 0 -> 129 bytes .../Status/rightarm.rsi/rightarm_3.png | Bin 0 -> 129 bytes .../Status/rightarm.rsi/rightarm_4.png | Bin 0 -> 129 bytes .../Status/rightarm.rsi/rightarm_5.png | Bin 0 -> 129 bytes .../Status/rightarm.rsi/rightarm_6.png | Bin 0 -> 129 bytes .../Status/rightarm.rsi/rightarm_7.png | Bin 0 -> 129 bytes .../Status/rightarm.rsi/rightarm_8.png | Bin 0 -> 146 bytes .../Targeting/Status/rightleg.rsi/meta.json | 38 ++ .../Status/rightleg.rsi/rightleg_0.png | Bin 0 -> 126 bytes .../Status/rightleg.rsi/rightleg_1.png | Bin 0 -> 126 bytes .../Status/rightleg.rsi/rightleg_2.png | Bin 0 -> 126 bytes .../Status/rightleg.rsi/rightleg_3.png | Bin 0 -> 126 bytes .../Status/rightleg.rsi/rightleg_4.png | Bin 0 -> 126 bytes .../Status/rightleg.rsi/rightleg_5.png | Bin 0 -> 126 bytes .../Status/rightleg.rsi/rightleg_6.png | Bin 0 -> 126 bytes .../Status/rightleg.rsi/rightleg_7.png | Bin 0 -> 126 bytes .../Status/rightleg.rsi/rightleg_8.png | Bin 0 -> 153 bytes .../Targeting/Status/torso.rsi/meta.json | 38 ++ .../Targeting/Status/torso.rsi/torso_0.png | Bin 0 -> 155 bytes .../Targeting/Status/torso.rsi/torso_1.png | Bin 0 -> 155 bytes .../Targeting/Status/torso.rsi/torso_2.png | Bin 0 -> 155 bytes .../Targeting/Status/torso.rsi/torso_3.png | Bin 0 -> 155 bytes .../Targeting/Status/torso.rsi/torso_4.png | Bin 0 -> 155 bytes .../Targeting/Status/torso.rsi/torso_5.png | Bin 0 -> 155 bytes .../Targeting/Status/torso.rsi/torso_6.png | Bin 0 -> 155 bytes .../Targeting/Status/torso.rsi/torso_7.png | Bin 0 -> 155 bytes .../Targeting/Status/torso.rsi/torso_8.png | Bin 0 -> 180 bytes .../Textures/Interface/Targeting/doll.png | Bin 0 -> 876 bytes .../Medical/Surgery/bone_gel.rsi/bone-gel.png | Bin 0 -> 432 bytes .../Surgery/bone_gel.rsi/bone-gel_0.png | Bin 0 -> 391 bytes .../Surgery/bone_gel.rsi/bone-gel_25.png | Bin 0 -> 444 bytes .../Surgery/bone_gel.rsi/bone-gel_50.png | Bin 0 -> 456 bytes .../Surgery/bone_gel.rsi/bone-gel_75.png | Bin 0 -> 444 bytes .../Medical/Surgery/bone_gel.rsi/meta.json | 29 + .../bone_gel.rsi/predator_bone-gel.png | Bin 0 -> 585 bytes .../Surgery/bonesetter.rsi/bonesetter.png | Bin 0 -> 581 bytes .../Medical/Surgery/bonesetter.rsi/meta.json | 17 + .../bonesetter.rsi/predator_bonesetter.png | Bin 0 -> 489 bytes .../Surgery/manipulation.rsi/insertion.png | Bin 0 -> 379 bytes .../Surgery/manipulation.rsi/meta.json | 14 + .../limbgrower.rsi/limbgrower_fill.png | Bin 0 -> 9056 bytes .../limbgrower.rsi/limbgrower_idleoff.png | Bin 0 -> 3320 bytes .../limbgrower.rsi/limbgrower_idleon.png | Bin 0 -> 11102 bytes .../limbgrower.rsi/limbgrower_openpanel.png | Bin 0 -> 3981 bytes .../limbgrower.rsi/limbgrower_panelopen.png | Bin 0 -> 2273 bytes .../limbgrower.rsi/limbgrower_unfill.png | Bin 0 -> 9104 bytes .../Machines/limbgrower.rsi/meta.json | 85 +++ Resources/keybinds.yml | 25 + 237 files changed, 6075 insertions(+), 123 deletions(-) create mode 100644 Content.Client/Backmen/Body/Components/BrainComponent.cs create mode 100644 Content.Client/Backmen/Body/Components/LungComponent.cs create mode 100644 Content.Client/Backmen/Body/Components/StomachComponent.cs create mode 100644 Content.Client/Backmen/Surgery/SurgeryBui.cs create mode 100644 Content.Client/Backmen/Surgery/SurgeryStepButton.xaml create mode 100644 Content.Client/Backmen/Surgery/SurgeryStepButton.xaml.cs create mode 100644 Content.Client/Backmen/Surgery/SurgerySystem.cs create mode 100644 Content.Client/Backmen/Surgery/SurgeryWindow.xaml create mode 100644 Content.Client/Backmen/Surgery/SurgeryWindow.xaml.cs create mode 100644 Content.Client/Backmen/Targeting/TargetingSystem.cs create mode 100644 Content.Client/Backmen/UserInterface/Systems/PartStatus/PartStatusUIController.cs create mode 100644 Content.Client/Backmen/UserInterface/Systems/PartStatus/Widgets/PartStatusControl.xaml create mode 100644 Content.Client/Backmen/UserInterface/Systems/PartStatus/Widgets/PartStatusControl.xaml.cs create mode 100644 Content.Client/Backmen/UserInterface/Systems/Targeting/TargetingUIController.cs create mode 100644 Content.Client/Backmen/UserInterface/Systems/Targeting/Widgets/TargetingControl.xaml create mode 100644 Content.Client/Backmen/UserInterface/Systems/Targeting/Widgets/TargetingControl.xaml.cs create mode 100644 Content.Client/Xenonids/UI/XenoChoiceControl.xaml create mode 100644 Content.Client/Xenonids/UI/XenoChoiceControl.xaml.cs create mode 100644 Content.Server/Backmen/Sleep/SleepingSystem.cs create mode 100644 Content.Server/Backmen/Surgery/SurgerySystem.cs create mode 100644 Content.Server/Backmen/Targeting/TargetingSystem.cs create mode 100644 Content.Server/Backmen/Traits/Assorted/LightweightDrunkSystem.cs create mode 100644 Content.Server/Destructible/Thresholds/Behaviors/GibPartBehavior.cs create mode 100644 Content.Shared/Backmen/Surgery/Body/AmputateAttemptEvent.cs create mode 100644 Content.Shared/Backmen/Surgery/Body/EyesComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Body/HeartComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Body/LiverComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Body/SharedBodySystem.Integrity.cs create mode 100644 Content.Shared/Backmen/Surgery/Conditions/SurgeryCloseIncisionConditionComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Conditions/SurgeryLarvaConditionComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Conditions/SurgeryOperatingTableConditionComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Conditions/SurgeryOrganConditionComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Conditions/SurgeryPartConditionComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Conditions/SurgeryPartPresentCondition.cs create mode 100644 Content.Shared/Backmen/Surgery/Conditions/SurgeryPartRemovedConditionComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Conditions/SurgeryValidEvent.cs create mode 100644 Content.Shared/Backmen/Surgery/Conditions/SurgeryWoundedConditionComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Effects/Complete/SurgeryCompletedEvent.cs create mode 100644 Content.Shared/Backmen/Surgery/Effects/Complete/SurgeryRemoveLarvaComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Effects/Step/SurgeryDamageChangeEffectComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Effects/Step/SurgerySpecialDamageChangeEffectComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepAffixPartEffectComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepCavityEffectComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepEmoteEffectComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepSpawnEffect.cs create mode 100644 Content.Shared/Backmen/Surgery/Effects/Step/SurgeryTendWoundsEffectComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/OperatingTableComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/SharedSurgerySystem.Steps.cs create mode 100644 Content.Shared/Backmen/Surgery/SharedSurgerySystem.cs create mode 100644 Content.Shared/Backmen/Surgery/StepInvalidReason.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/Parts/BleedersClampedComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/Parts/BodyPartReattachedComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/Parts/BodyPartSawedComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/Parts/IncisionOpenComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/Parts/InternalBleedersClampedComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/Parts/OrganReattachedComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/Parts/PartRemovedComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/Parts/RibcageOpenComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/Parts/RibcageSawedComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/Parts/SkinRetractedComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/SurgeryAddOrganStepComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/SurgeryAddPartStepComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/SurgeryCanPerformStepEvent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/SurgeryCutLarvaRootsStepComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/SurgeryRemoveOrganStepComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/SurgeryRemovePartStepComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/SurgeryStepCompleteCheckEvent.cs create mode 100644 Content.Shared/Backmen/Surgery/Steps/SurgeryStepComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/SurgeryComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/SurgeryDoAfterEvent.cs create mode 100644 Content.Shared/Backmen/Surgery/SurgerySpeedModifierComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/SurgeryStepDamageEvent.cs create mode 100644 Content.Shared/Backmen/Surgery/SurgeryStepEvent.cs create mode 100644 Content.Shared/Backmen/Surgery/SurgeryTargetComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/SurgeryUI.cs create mode 100644 Content.Shared/Backmen/Surgery/Tools/BoneGelComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Tools/BoneSawComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Tools/BoneSetterComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Tools/CauteryComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Tools/HemostatComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Tools/ISurgeryToolComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Tools/RetractorComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Tools/ScalpelComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Tools/SurgeryToolComponent.cs create mode 100644 Content.Shared/Backmen/Surgery/Tools/SurgicalDrillComponent.cs create mode 100644 Content.Shared/Backmen/Targeting/Events.cs create mode 100644 Content.Shared/Backmen/Targeting/SharedTargetingSystem.cs create mode 100644 Content.Shared/Backmen/Targeting/TargetBodyPart.cs create mode 100644 Content.Shared/Backmen/Targeting/TargetIntegrity.cs create mode 100644 Content.Shared/Backmen/Targeting/TargetingComponent.cs create mode 100644 Resources/Audio/Medical/Surgery/attributions.yml create mode 100644 Resources/Audio/Medical/Surgery/cautery1.ogg create mode 100644 Resources/Audio/Medical/Surgery/cautery2.ogg create mode 100644 Resources/Audio/Medical/Surgery/hemostat1.ogg create mode 100644 Resources/Audio/Medical/Surgery/organ1.ogg create mode 100644 Resources/Audio/Medical/Surgery/organ2.ogg create mode 100644 Resources/Audio/Medical/Surgery/retractor1.ogg create mode 100644 Resources/Audio/Medical/Surgery/retractor2.ogg create mode 100644 Resources/Audio/Medical/Surgery/saw.ogg create mode 100644 Resources/Audio/Medical/Surgery/scalpel1.ogg create mode 100644 Resources/Audio/Medical/Surgery/scalpel2.ogg create mode 100644 Resources/Prototypes/_Backmen/Entities/Objects/Devices/Circuitboards/production.yml create mode 100644 Resources/Prototypes/_Backmen/Entities/Objects/Specific/Medical/surgery.yml create mode 100644 Resources/Prototypes/_Backmen/Entities/Structures/Machines/lathe.yml create mode 100644 Resources/Prototypes/_Backmen/Entities/Surgery/surgeries.yml create mode 100644 Resources/Prototypes/_Backmen/Entities/Surgery/surgery_steps.yml create mode 100644 Resources/Prototypes/_Backmen/Recipes/Lathes/surgery.yml create mode 100644 Resources/Textures/Interface/Targeting/Status/head.rsi/head_0.png create mode 100644 Resources/Textures/Interface/Targeting/Status/head.rsi/head_1.png create mode 100644 Resources/Textures/Interface/Targeting/Status/head.rsi/head_2.png create mode 100644 Resources/Textures/Interface/Targeting/Status/head.rsi/head_3.png create mode 100644 Resources/Textures/Interface/Targeting/Status/head.rsi/head_4.png create mode 100644 Resources/Textures/Interface/Targeting/Status/head.rsi/head_5.png create mode 100644 Resources/Textures/Interface/Targeting/Status/head.rsi/head_6.png create mode 100644 Resources/Textures/Interface/Targeting/Status/head.rsi/head_7.png create mode 100644 Resources/Textures/Interface/Targeting/Status/head.rsi/head_8.png create mode 100644 Resources/Textures/Interface/Targeting/Status/head.rsi/meta.json create mode 100644 Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_0.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_1.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_2.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_3.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_4.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_5.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_6.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_7.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_8.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftarm.rsi/meta.json create mode 100644 Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_0.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_1.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_2.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_3.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_4.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_5.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_6.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_7.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_8.png create mode 100644 Resources/Textures/Interface/Targeting/Status/leftleg.rsi/meta.json create mode 100644 Resources/Textures/Interface/Targeting/Status/rightarm.rsi/meta.json create mode 100644 Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_0.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_1.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_2.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_3.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_4.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_5.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_6.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_7.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_8.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightleg.rsi/meta.json create mode 100644 Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_0.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_1.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_2.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_3.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_4.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_5.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_6.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_7.png create mode 100644 Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_8.png create mode 100644 Resources/Textures/Interface/Targeting/Status/torso.rsi/meta.json create mode 100644 Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_0.png create mode 100644 Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_1.png create mode 100644 Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_2.png create mode 100644 Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_3.png create mode 100644 Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_4.png create mode 100644 Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_5.png create mode 100644 Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_6.png create mode 100644 Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_7.png create mode 100644 Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_8.png create mode 100644 Resources/Textures/Interface/Targeting/doll.png create mode 100644 Resources/Textures/Objects/Specific/Medical/Surgery/bone_gel.rsi/bone-gel.png create mode 100644 Resources/Textures/Objects/Specific/Medical/Surgery/bone_gel.rsi/bone-gel_0.png create mode 100644 Resources/Textures/Objects/Specific/Medical/Surgery/bone_gel.rsi/bone-gel_25.png create mode 100644 Resources/Textures/Objects/Specific/Medical/Surgery/bone_gel.rsi/bone-gel_50.png create mode 100644 Resources/Textures/Objects/Specific/Medical/Surgery/bone_gel.rsi/bone-gel_75.png create mode 100644 Resources/Textures/Objects/Specific/Medical/Surgery/bone_gel.rsi/meta.json create mode 100644 Resources/Textures/Objects/Specific/Medical/Surgery/bone_gel.rsi/predator_bone-gel.png create mode 100644 Resources/Textures/Objects/Specific/Medical/Surgery/bonesetter.rsi/bonesetter.png create mode 100644 Resources/Textures/Objects/Specific/Medical/Surgery/bonesetter.rsi/meta.json create mode 100644 Resources/Textures/Objects/Specific/Medical/Surgery/bonesetter.rsi/predator_bonesetter.png create mode 100644 Resources/Textures/Objects/Specific/Medical/Surgery/manipulation.rsi/insertion.png create mode 100644 Resources/Textures/Objects/Specific/Medical/Surgery/manipulation.rsi/meta.json create mode 100644 Resources/Textures/Structures/Machines/limbgrower.rsi/limbgrower_fill.png create mode 100644 Resources/Textures/Structures/Machines/limbgrower.rsi/limbgrower_idleoff.png create mode 100644 Resources/Textures/Structures/Machines/limbgrower.rsi/limbgrower_idleon.png create mode 100644 Resources/Textures/Structures/Machines/limbgrower.rsi/limbgrower_openpanel.png create mode 100644 Resources/Textures/Structures/Machines/limbgrower.rsi/limbgrower_panelopen.png create mode 100644 Resources/Textures/Structures/Machines/limbgrower.rsi/limbgrower_unfill.png create mode 100644 Resources/Textures/Structures/Machines/limbgrower.rsi/meta.json diff --git a/Content.Client/Backmen/Body/Components/BrainComponent.cs b/Content.Client/Backmen/Body/Components/BrainComponent.cs new file mode 100644 index 00000000000..986bb2e9103 --- /dev/null +++ b/Content.Client/Backmen/Body/Components/BrainComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Client.Backmen.Body.Components +{ + [RegisterComponent] + public sealed partial class BrainComponent : Component + { + } +} diff --git a/Content.Client/Backmen/Body/Components/LungComponent.cs b/Content.Client/Backmen/Body/Components/LungComponent.cs new file mode 100644 index 00000000000..da4cdb99ba8 --- /dev/null +++ b/Content.Client/Backmen/Body/Components/LungComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Client.Backmen.Body.Components +{ + [RegisterComponent] + public sealed partial class LungComponent : Component + { + } +} diff --git a/Content.Client/Backmen/Body/Components/StomachComponent.cs b/Content.Client/Backmen/Body/Components/StomachComponent.cs new file mode 100644 index 00000000000..1435633b58a --- /dev/null +++ b/Content.Client/Backmen/Body/Components/StomachComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Client.Backmen.Body.Components +{ + [RegisterComponent] + public sealed partial class StomachComponent : Component + { + } +} diff --git a/Content.Client/Backmen/Surgery/SurgeryBui.cs b/Content.Client/Backmen/Surgery/SurgeryBui.cs new file mode 100644 index 00000000000..10bd64e5e0a --- /dev/null +++ b/Content.Client/Backmen/Surgery/SurgeryBui.cs @@ -0,0 +1,458 @@ +using Content.Client.Xenonids.UI; +using Content.Client.Administration.UI.CustomControls; +using Content.Shared.Backmen.Surgery; +using Content.Shared.Body.Components; +using Content.Shared.Body.Part; +using JetBrains.Annotations; +using Robust.Client.GameObjects; +using Robust.Client.Player; +using Robust.Shared.Prototypes; +using Robust.Shared.Utility; +using Robust.Shared.Timing; +using static Robust.Client.UserInterface.Control; + +namespace Content.Client.Backmen.Surgery; + +[UsedImplicitly] +public sealed class SurgeryBui : BoundUserInterface +{ + [Dependency] private readonly IEntityManager _entities = default!; + [Dependency] private readonly IPlayerManager _player = default!; + + [Dependency] private readonly IGameTiming _timing = default!; + + private readonly SurgerySystem _system; + + [ViewVariables] + private SurgeryWindow? _window; + + private EntityUid? _part; + private bool _isBody = false; + private (EntityUid Ent, EntProtoId Proto)? _surgery; + private readonly List _previousSurgeries = new(); + + public SurgeryBui(EntityUid owner, Enum uiKey) : base(owner, uiKey) + { + _system = _entities.System(); + } + + protected override void Open() + { + Logger.Debug("Attempting to open"); + _system.OnRefresh += () => + { + UpdateDisabledPanel(); + RefreshUI(); + }; + + if (State is SurgeryBuiState s) + Update(s); + } + + protected override void UpdateState(BoundUserInterfaceState state) + { + if (state is SurgeryBuiState s) + Update(s); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + _window?.Dispose(); + + _system.OnRefresh -= RefreshUI; + } + + private void Update(SurgeryBuiState state) + { + Logger.Debug($"Attempting to update surgerybuistate with {state}, {_player.LocalEntity}, first predicted? {_timing.IsFirstTimePredicted}, surgeryTargetComp? {_entities.TryGetComponent(_player.LocalEntity, out var surgeryTargetComp2)} {surgeryTargetComp2?.CanOperate}"); + if (!_entities.TryGetComponent(_player.LocalEntity, out var surgeryTargetComp) + || !surgeryTargetComp.CanOperate) + return; + Logger.Debug("Passed check"); + if (_window == null) + { + _window = new SurgeryWindow(); + _window.OnClose += Close; + _window.Title = "Surgery"; + + _window.PartsButton.OnPressed += _ => + { + _part = null; + _isBody = false; + _surgery = null; + _previousSurgeries.Clear(); + View(ViewType.Parts); + }; + + _window.SurgeriesButton.OnPressed += _ => + { + _surgery = null; + _previousSurgeries.Clear(); + + if (!_entities.TryGetNetEntity(_part, out var netPart) || + State is not SurgeryBuiState s || + !s.Choices.TryGetValue(netPart.Value, out var surgeries)) + { + return; + } + + OnPartPressed(netPart.Value, surgeries); + }; + + _window.StepsButton.OnPressed += _ => + { + if (!_entities.TryGetNetEntity(_part, out var netPart) || + _previousSurgeries.Count == 0) + { + return; + } + + var last = _previousSurgeries[^1]; + _previousSurgeries.RemoveAt(_previousSurgeries.Count - 1); + + if (_system.GetSingleton(last) is not { } previousId || + !_entities.TryGetComponent(previousId, out SurgeryComponent? previous)) + { + return; + } + + OnSurgeryPressed((previousId, previous), netPart.Value, last); + }; + } + + _window.Surgeries.DisposeAllChildren(); + _window.Steps.DisposeAllChildren(); + _window.Parts.DisposeAllChildren(); + + View(ViewType.Parts); + + var oldSurgery = _surgery; + var oldPart = _part; + _part = null; + _surgery = null; + + var options = new List<(NetEntity netEntity, EntityUid entity, string Name, BodyPartType? PartType)>(); + foreach (var choice in state.Choices.Keys) + { + if (_entities.TryGetEntity(choice, out var ent)) + { + if (_entities.TryGetComponent(ent, out BodyPartComponent? part)) + options.Add((choice, ent.Value, _entities.GetComponent(ent.Value).EntityName, part.PartType)); + else if (_entities.TryGetComponent(ent, out BodyComponent? body)) + options.Add((choice, ent.Value, _entities.GetComponent(ent.Value).EntityName, null)); + } + } + + options.Sort((a, b) => + { + int GetScore(BodyPartType? partType) + { + return partType switch + { + BodyPartType.Head => 1, + BodyPartType.Torso => 2, + BodyPartType.Arm => 3, + BodyPartType.Hand => 4, + BodyPartType.Leg => 5, + BodyPartType.Foot => 6, + // BodyPartType.Tail => 7, No tails yet! + BodyPartType.Other => 8, + _ => 9 + }; + } + + return GetScore(a.PartType) - GetScore(b.PartType); + }); + + foreach (var (netEntity, entity, partName, _) in options) + { + //var netPart = _entities.GetNetEntity(part.Owner); + var surgeries = state.Choices[netEntity]; + var partButton = new XenoChoiceControl(); + + partButton.Set(partName, null); + partButton.Button.OnPressed += _ => OnPartPressed(netEntity, surgeries); + + _window.Parts.AddChild(partButton); + + foreach (var surgeryId in surgeries) + { + if (_system.GetSingleton(surgeryId) is not { } surgery || + !_entities.TryGetComponent(surgery, out SurgeryComponent? surgeryComp)) + continue; + + if (oldPart == entity && oldSurgery?.Proto == surgeryId) + OnSurgeryPressed((surgery, surgeryComp), netEntity, surgeryId); + } + + if (oldPart == entity && oldSurgery == null) + OnPartPressed(netEntity, surgeries); + } + + + if (!_window.IsOpen) + { + Logger.Debug("Attempting to open"); + _window.OpenCentered(); + } + else + { + Logger.Debug("Attempting to refresh"); + RefreshUI(); + UpdateDisabledPanel(); + } + } + + private void AddStep(EntProtoId stepId, NetEntity netPart, EntProtoId surgeryId) + { + if (_window == null || + _system.GetSingleton(stepId) is not { } step) + { + return; + } + var stepName = new FormattedMessage(); + stepName.AddText(_entities.GetComponent(step).EntityName); + var stepButton = new SurgeryStepButton { Step = step }; + stepButton.Button.OnPressed += _ => SendMessage(new SurgeryStepChosenBuiMsg(netPart, surgeryId, stepId, _isBody)); + + _window.Steps.AddChild(stepButton); + } + + private void OnSurgeryPressed(Entity surgery, NetEntity netPart, EntProtoId surgeryId) + { + if (_window == null) + return; + + _part = _entities.GetEntity(netPart); + _isBody = _entities.HasComponent(_part); + _surgery = (surgery, surgeryId); + + _window.Steps.DisposeAllChildren(); + + // This apparently does not consider if theres multiple surgery requirements in one surgery. Maybe thats fine. + if (surgery.Comp.Requirement is { } requirementId && _system.GetSingleton(requirementId) is { } requirement) + { + var label = new XenoChoiceControl(); + label.Button.OnPressed += _ => + { + _previousSurgeries.Add(surgeryId); + + if (_entities.TryGetComponent(requirement, out SurgeryComponent? requirementComp)) + OnSurgeryPressed((requirement, requirementComp), netPart, requirementId); + }; + + var msg = new FormattedMessage(); + var surgeryName = _entities.GetComponent(requirement).EntityName; + msg.AddMarkup($"[bold]Requires: {surgeryName}[/bold]"); + label.Set(msg, null); + + _window.Steps.AddChild(label); + _window.Steps.AddChild(new HSeparator { Margin = new Thickness(0, 0, 0, 1) }); + } + foreach (var stepId in surgery.Comp.Steps) + { + AddStep(stepId, netPart, surgeryId); + } + + View(ViewType.Steps); + RefreshUI(); + } + + private void OnPartPressed(NetEntity netPart, List surgeryIds) + { + if (_window == null) + return; + + _part = _entities.GetEntity(netPart); + _isBody = _entities.HasComponent(_part); + _window.Surgeries.DisposeAllChildren(); + + var surgeries = new List<(Entity Ent, EntProtoId Id, string Name)>(); + foreach (var surgeryId in surgeryIds) + { + if (_system.GetSingleton(surgeryId) is not { } surgery || + !_entities.TryGetComponent(surgery, out SurgeryComponent? surgeryComp)) + { + continue; + } + + var name = _entities.GetComponent(surgery).EntityName; + surgeries.Add(((surgery, surgeryComp), surgeryId, name)); + } + + surgeries.Sort((a, b) => + { + var priority = a.Ent.Comp.Priority.CompareTo(b.Ent.Comp.Priority); + if (priority != 0) + return priority; + + return string.Compare(a.Name, b.Name, StringComparison.Ordinal); + }); + + foreach (var surgery in surgeries) + { + var surgeryButton = new XenoChoiceControl(); + surgeryButton.Set(surgery.Name, null); + + surgeryButton.Button.OnPressed += _ => OnSurgeryPressed(surgery.Ent, netPart, surgery.Id); + _window.Surgeries.AddChild(surgeryButton); + } + + RefreshUI(); + View(ViewType.Surgeries); + } + + private void RefreshUI() + { + if (_window == null + || !_timing.IsFirstTimePredicted + || !_window.IsOpen + || _part == null + || !_entities.HasComponent(_surgery?.Ent) + || !_entities.TryGetComponent(_player.LocalEntity ?? EntityUid.Invalid, out var surgeryComp) + || !surgeryComp.CanOperate) + { + return; + } + + var next = _system.GetNextStep(Owner, _part.Value, _surgery.Value.Ent); + var i = 0; + foreach (var child in _window.Steps.Children) + { + if (child is not SurgeryStepButton stepButton) + continue; + + var status = StepStatus.Incomplete; + if (next == null) + { + status = StepStatus.Complete; + } + else if (next.Value.Surgery.Owner != _surgery.Value.Ent) + { + status = StepStatus.Incomplete; + } + else if (next.Value.Step == i) + { + status = StepStatus.Next; + } + else if (i < next.Value.Step) + { + status = StepStatus.Complete; + } + + stepButton.Button.Disabled = status != StepStatus.Next; + + var stepName = new FormattedMessage(); + stepName.AddText(_entities.GetComponent(stepButton.Step).EntityName); + + if (status == StepStatus.Complete) + { + stepButton.Button.Modulate = Color.Green; + } + else + { + stepButton.Button.Modulate = Color.White; + // GOD THIS NEEDS A REWRITE SO BADLY, IT UPDATES ON EVERY SINGLE TICK + // THEN RUNS CANPERFORMSTEP WHICH CALLS A SHITLOAD OF EVENTS + // DID THEY NOT FUCKING PLAYTEST THIS??? + if (_player.LocalEntity is { } player + && status == StepStatus.Next + && !_system.CanPerformStep(player, Owner, _part.Value, stepButton.Step, false, out var popup, out var reason, out _)) + { + stepButton.ToolTip = popup; + stepButton.Button.Disabled = true; + + switch (reason) + { + case StepInvalidReason.MissingSkills: + stepName.AddMarkup(" [color=red](Missing surgery skill)[/color]"); + break; + case StepInvalidReason.NeedsOperatingTable: + stepName.AddMarkup(" [color=red](Needs operating table)[/color]"); + break; + case StepInvalidReason.Armor: + stepName.AddMarkup(" [color=red](Remove their armor!)[/color]"); + break; + case StepInvalidReason.MissingTool: + stepName.AddMarkup(" [color=red](Missing tool)[/color]"); + break; + } + } + } + + var texture = _entities.GetComponentOrNull(stepButton.Step)?.Icon?.Default; + stepButton.Set(stepName, texture); + i++; + } + + UpdateDisabledPanel(); + } + + private void UpdateDisabledPanel() + { + if (_window == null) + return; + + if (_system.IsLyingDown(Owner)) + { + _window.DisabledPanel.Visible = false; + _window.DisabledPanel.MouseFilter = MouseFilterMode.Ignore; + return; + } + + _window.DisabledPanel.Visible = true; + + var text = new FormattedMessage(); + text.AddMarkup("[color=red][font size=16]They need to be lying down![/font][/color]"); + _window.DisabledLabel.SetMessage(text); + _window.DisabledPanel.MouseFilter = MouseFilterMode.Stop; + } + + private void View(ViewType type) + { + if (_window == null) + return; + + _window.PartsButton.Parent!.Margin = new Thickness(0, 0, 0, 10); + + _window.Parts.Visible = type == ViewType.Parts; + _window.PartsButton.Disabled = type == ViewType.Parts; + + _window.Surgeries.Visible = type == ViewType.Surgeries; + _window.SurgeriesButton.Disabled = type != ViewType.Steps; + + _window.Steps.Visible = type == ViewType.Steps; + _window.StepsButton.Disabled = type != ViewType.Steps || _previousSurgeries.Count == 0; + + if (_entities.TryGetComponent(_part, out MetaDataComponent? partMeta) && + _entities.TryGetComponent(_surgery?.Ent, out MetaDataComponent? surgeryMeta)) + { + _window.Title = $"Surgery - {partMeta.EntityName}, {surgeryMeta.EntityName}"; + } + else if (partMeta != null) + { + _window.Title = $"Surgery - {partMeta.EntityName}"; + } + else + { + _window.Title = "Surgery"; + } + } + + private enum ViewType + { + Parts, + Surgeries, + Steps + } + + private enum StepStatus + { + Next, + Complete, + Incomplete + } +} diff --git a/Content.Client/Backmen/Surgery/SurgeryStepButton.xaml b/Content.Client/Backmen/Surgery/SurgeryStepButton.xaml new file mode 100644 index 00000000000..50d4733e68e --- /dev/null +++ b/Content.Client/Backmen/Surgery/SurgeryStepButton.xaml @@ -0,0 +1,4 @@ + + diff --git a/Content.Client/Backmen/Surgery/SurgeryStepButton.xaml.cs b/Content.Client/Backmen/Surgery/SurgeryStepButton.xaml.cs new file mode 100644 index 00000000000..0e18e15421a --- /dev/null +++ b/Content.Client/Backmen/Surgery/SurgeryStepButton.xaml.cs @@ -0,0 +1,16 @@ +using Content.Client.Xenonids.UI; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.XAML; + +namespace Content.Client.Backmen.Surgery; + +[GenerateTypedNameReferences] +public sealed partial class SurgeryStepButton : XenoChoiceControl +{ + public EntityUid Step { get; set; } + + public SurgeryStepButton() + { + RobustXamlLoader.Load(this); + } +} diff --git a/Content.Client/Backmen/Surgery/SurgerySystem.cs b/Content.Client/Backmen/Surgery/SurgerySystem.cs new file mode 100644 index 00000000000..d972ca87ad8 --- /dev/null +++ b/Content.Client/Backmen/Surgery/SurgerySystem.cs @@ -0,0 +1,13 @@ +using Content.Shared.Backmen.Surgery; + +namespace Content.Client.Backmen.Surgery; + +public sealed class SurgerySystem : SharedSurgerySystem +{ + public event Action? OnRefresh; + + public override void Update(float frameTime) + { + OnRefresh?.Invoke(); + } +} diff --git a/Content.Client/Backmen/Surgery/SurgeryWindow.xaml b/Content.Client/Backmen/Surgery/SurgeryWindow.xaml new file mode 100644 index 00000000000..af19d46ef6d --- /dev/null +++ b/Content.Client/Backmen/Surgery/SurgeryWindow.xaml @@ -0,0 +1,30 @@ + + + + + + \ No newline at end of file diff --git a/Content.Client/Xenonids/UI/XenoChoiceControl.xaml.cs b/Content.Client/Xenonids/UI/XenoChoiceControl.xaml.cs new file mode 100644 index 00000000000..7a463ca0f20 --- /dev/null +++ b/Content.Client/Xenonids/UI/XenoChoiceControl.xaml.cs @@ -0,0 +1,29 @@ +using Robust.Client.AutoGenerated; +using Robust.Client.Graphics; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Utility; + +namespace Content.Client.Xenonids.UI; + +[GenerateTypedNameReferences] +[Virtual] +public partial class XenoChoiceControl : Control +{ + public XenoChoiceControl() + { + RobustXamlLoader.Load(this); + } + + public void Set(string name, Texture? texture) + { + NameLabel.SetMessage(name); + Texture.Texture = texture; + } + + public void Set(FormattedMessage msg, Texture? texture) + { + NameLabel.SetMessage(msg); + Texture.Texture = texture; + } +} \ No newline at end of file diff --git a/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs b/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs index ec508790ba8..d6cf61d3061 100644 --- a/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs +++ b/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs @@ -237,8 +237,7 @@ public override void Update(float frameTime) if (pressure <= Atmospherics.HazardLowPressure) { // Deal damage and ignore resistances. Resistance to pressure damage should be done via pressure protection gear. - _damageableSystem.TryChangeDamage(uid, barotrauma.Damage * Atmospherics.LowPressureDamage, true, false); - + _damageableSystem.TryChangeDamage(uid, barotrauma.Damage * Atmospherics.LowPressureDamage, true, false, canSever: false); // backmen if (!barotrauma.TakingDamage) { barotrauma.TakingDamage = true; @@ -252,7 +251,7 @@ public override void Update(float frameTime) var damageScale = MathF.Min(((pressure / Atmospherics.HazardHighPressure) - 1) * Atmospherics.PressureDamageCoefficient, Atmospherics.MaxHighPressureDamage); // Deal damage and ignore resistances. Resistance to pressure damage should be done via pressure protection gear. - _damageableSystem.TryChangeDamage(uid, barotrauma.Damage * damageScale, true, false); + _damageableSystem.TryChangeDamage(uid, barotrauma.Damage * damageScale, true, false, canSever: false); // backmen if (!barotrauma.TakingDamage) { diff --git a/Content.Server/Backmen/Sleep/SleepingSystem.cs b/Content.Server/Backmen/Sleep/SleepingSystem.cs new file mode 100644 index 00000000000..089337caec9 --- /dev/null +++ b/Content.Server/Backmen/Sleep/SleepingSystem.cs @@ -0,0 +1,260 @@ +/*using Content.Server.Popups; +using Content.Server.Sound; +using Content.Shared.Sound.Components; +using Content.Shared.Actions; +using Content.Shared.Audio; +using Content.Shared.Bed.Sleep; +using Content.Shared.Damage; +using Content.Shared.Examine; +using Content.Shared.IdentityManagement; +using Content.Shared.Interaction; +using Content.Shared.Interaction.Events; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Components; +using Content.Shared.Slippery; +using Content.Shared.StatusEffect; +using Content.Shared.Stunnable; +using Content.Shared.Verbs; +using Robust.Shared.Audio; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Player; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Server.Bed.Sleep +{ + public sealed class SleepingSystem : SharedSleepingSystem + { + [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly IRobustRandom _robustRandom = default!; + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!; + [Dependency] private readonly EmitSoundSystem _emitSound = default!; + + [ValidatePrototypeId] public const string SleepActionId = "ActionSleep"; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnSleepStateChanged); + SubscribeLocalEvent(OnDamageChanged); + SubscribeLocalEvent(OnSleepAction); + SubscribeLocalEvent(OnBedSleepAction); + SubscribeLocalEvent(OnWakeAction); + SubscribeLocalEvent(OnMobStateChanged); + SubscribeLocalEvent>(AddWakeVerb); + SubscribeLocalEvent(OnInteractHand); + SubscribeLocalEvent(OnExamined); + SubscribeLocalEvent(OnSlip); + SubscribeLocalEvent(OnConsciousAttempt); + SubscribeLocalEvent(OnInit); + } + + /// + /// when sleeping component is added or removed, we do some stuff with other components. + /// + private void OnSleepStateChanged(EntityUid uid, MobStateComponent component, SleepStateChangedEvent args) + { + if (args.FellAsleep) + { + // Expiring status effects would remove the components needed for sleeping + _statusEffectsSystem.TryRemoveStatusEffect(uid, "Stun"); + _statusEffectsSystem.TryRemoveStatusEffect(uid, "KnockedDown"); + + EnsureComp(uid); + EnsureComp(uid); + + if (TryComp(uid, out var sleepSound)) + { + var emitSound = EnsureComp(uid); + if (HasComp(uid)) + { + emitSound.Sound = sleepSound.Snore; + } + emitSound.MinInterval = sleepSound.Interval; + emitSound.MaxInterval = sleepSound.MaxInterval; + emitSound.PopUp = sleepSound.PopUp; + } + + return; + } + + RemComp(uid); + RemComp(uid); + RemComp(uid); + } + + /// + /// Wake up on taking an instance of damage at least the value of WakeThreshold. + /// + private void OnDamageChanged(EntityUid uid, SleepingComponent component, DamageChangedEvent args) + { + if (!args.DamageIncreased || args.DamageDelta == null) + return; + + // Surgery needs this, sorry! If the nocturine gamers get too feisty + // I'll probably just increase the threshold + + if (args.DamageDelta.GetTotal() >= component.WakeThreshold + && !HasComp(uid)) + TryWaking(uid, component); + + } + + private void OnSleepAction(EntityUid uid, MobStateComponent component, SleepActionEvent args) + { + TrySleeping(uid); + } + + private void OnBedSleepAction(EntityUid uid, ActionsContainerComponent component, SleepActionEvent args) + { + TrySleeping(args.Performer); + } + + private void OnWakeAction(EntityUid uid, MobStateComponent component, WakeActionEvent args) + { + if (!TryWakeCooldown(uid)) + return; + + if (TryWaking(uid)) + args.Handled = true; + } + + /// + /// In crit, we wake up if we are not being forced to sleep. + /// And, you can't sleep when dead... + /// + private void OnMobStateChanged(EntityUid uid, SleepingComponent component, MobStateChangedEvent args) + { + if (args.NewMobState == MobState.Dead) + { + RemComp(uid); + RemComp(uid); + return; + } + if (TryComp(uid, out var spam)) + _emitSound.SetEnabled((uid, spam), args.NewMobState == MobState.Alive); + } + + private void AddWakeVerb(EntityUid uid, SleepingComponent component, GetVerbsEvent args) + { + if (!args.CanInteract || !args.CanAccess) + return; + + AlternativeVerb verb = new() + { + Act = () => + { + if (!TryWakeCooldown(uid)) + return; + + TryWaking(args.Target, user: args.User); + }, + Text = Loc.GetString("action-name-wake"), + Priority = 2 + }; + + args.Verbs.Add(verb); + } + + /// + /// When you click on a sleeping person with an empty hand, try to wake them. + /// + private void OnInteractHand(EntityUid uid, SleepingComponent component, InteractHandEvent args) + { + args.Handled = true; + + if (!TryWakeCooldown(uid)) + return; + + TryWaking(args.Target, user: args.User); + } + + private void OnExamined(EntityUid uid, SleepingComponent component, ExaminedEvent args) + { + if (args.IsInDetailsRange) + { + args.PushMarkup(Loc.GetString("sleep-examined", ("target", Identity.Entity(uid, EntityManager)))); + } + } + + private void OnSlip(EntityUid uid, SleepingComponent component, SlipAttemptEvent args) + { + args.Cancel(); + } + + private void OnConsciousAttempt(EntityUid uid, SleepingComponent component, ConsciousAttemptEvent args) + { + args.Cancel(); + } + + + private void OnInit(EntityUid uid, ForcedSleepingComponent component, ComponentInit args) + { + TrySleeping(uid); + } + + /// + /// Try sleeping. Only mobs can sleep. + /// + public bool TrySleeping(EntityUid uid) + { + if (!HasComp(uid)) + return false; + + var tryingToSleepEvent = new TryingToSleepEvent(uid); + RaiseLocalEvent(uid, ref tryingToSleepEvent); + if (tryingToSleepEvent.Cancelled) + return false; + + EnsureComp(uid); + return true; + } + + private bool TryWakeCooldown(EntityUid uid, SleepingComponent? component = null) + { + if (!Resolve(uid, ref component, false)) + return false; + + var curTime = _gameTiming.CurTime; + + if (curTime < component.CoolDownEnd) + { + return false; + } + + component.CoolDownEnd = curTime + component.Cooldown; + return true; + } + + /// + /// Try to wake up. + /// + public bool TryWaking(EntityUid uid, SleepingComponent? component = null, bool force = false, EntityUid? user = null) + { + if (!Resolve(uid, ref component, false)) + return false; + + if (!force && HasComp(uid)) + { + if (user != null) + { + _audio.PlayPvs("/Audio/Effects/thudswoosh.ogg", uid, AudioHelpers.WithVariation(0.05f, _robustRandom)); + _popupSystem.PopupEntity(Loc.GetString("wake-other-failure", ("target", Identity.Entity(uid, EntityManager))), uid, Filter.Entities(user.Value), true, Shared.Popups.PopupType.SmallCaution); + } + return false; + } + + if (user != null) + { + _audio.PlayPvs("/Audio/Effects/thudswoosh.ogg", uid, AudioHelpers.WithVariation(0.05f, _robustRandom)); + _popupSystem.PopupEntity(Loc.GetString("wake-other-success", ("target", Identity.Entity(uid, EntityManager))), uid, Filter.Entities(user.Value), true); + } + RemComp(uid); + return true; + } + } +} +*/ \ No newline at end of file diff --git a/Content.Server/Backmen/Surgery/SurgerySystem.cs b/Content.Server/Backmen/Surgery/SurgerySystem.cs new file mode 100644 index 00000000000..0f7761f2584 --- /dev/null +++ b/Content.Server/Backmen/Surgery/SurgerySystem.cs @@ -0,0 +1,208 @@ +using Content.Shared.Bed.Sleep; +using Content.Server.Body.Systems; +using Content.Shared.Body.Organ; +using Content.Shared.Body.Part; +using Content.Server.Chat.Systems; +using Content.Server.Popups; +using Content.Shared.Damage; +using Content.Shared.Interaction; +using Content.Shared.Medical.Surgery.Conditions; +using Content.Shared.Medical.Surgery.Effects.Step; +using Content.Server.Atmos.Rotting; +using Content.Shared.Eye.Blinding.Components; +using Content.Shared.Eye.Blinding.Systems; +//using Content.Shared.Medical.Wounds; +using Content.Shared.Prototypes; +using Robust.Server.GameObjects; +using Robust.Shared.Prototypes; +using Robust.Shared.Utility; +using System.Linq; +using Content.Shared.Backmen.Surgery; +using Content.Shared.Backmen.Surgery.Tools; + +namespace Content.Server.Backmen.Surgery; + +public sealed class SurgerySystem : SharedSurgerySystem +{ + [Dependency] private readonly BodySystem _body = default!; + [Dependency] private readonly ChatSystem _chat = default!; + + [Dependency] private readonly DamageableSystem _damageableSystem = default!; + [Dependency] private readonly IPrototypeManager _prototypes = default!; + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly UserInterfaceSystem _ui = default!; + [Dependency] private readonly RottingSystem _rot = default!; + [Dependency] private readonly BlindableSystem _blindableSystem = default!; + //[Dependency] private readonly WoundsSystem _wounds = default!; + + private readonly List _surgeries = new(); + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnToolAfterInteract); + SubscribeLocalEvent(OnSurgeryStepDamage); + SubscribeLocalEvent(OnSurgeryDamageChange); + SubscribeLocalEvent(OnSurgerySpecialDamageChange); + SubscribeLocalEvent(OnStepAffixPartComplete); + SubscribeLocalEvent(OnStepScreamComplete); + SubscribeLocalEvent(OnStepSpawnComplete); + + SubscribeLocalEvent(OnPrototypesReloaded); + + LoadPrototypes(); + } + + protected override void RefreshUI(EntityUid body) + { + var surgeries = new Dictionary>(); + foreach (var surgery in _surgeries) + { + if (GetSingleton(surgery) is not { } surgeryEnt) + continue; + + foreach (var part in _body.GetBodyChildren(body)) + { + var ev = new SurgeryValidEvent(body, part.Id); + RaiseLocalEvent(surgeryEnt, ref ev); + + if (ev.Cancelled) + continue; + + surgeries.GetOrNew(GetNetEntity(part.Id)).Add(surgery); + } + + } + Logger.Debug($"Setting UI state with {surgeries}, {body} and {SurgeryUIKey.Key}"); + _ui.SetUiState(body, SurgeryUIKey.Key, new SurgeryBuiState(surgeries)); + } + + private void SetDamage(EntityUid body, DamageSpecifier damage, float partMultiplier, + EntityUid user, EntityUid part) + { + var changed = _damageableSystem.TryChangeDamage(body, damage, true, origin: user, canSever: false, partMultiplier: partMultiplier); + if (changed != null + && changed.GetTotal() == 0 + && damage.GetTotal() < 0 + && TryComp(part, out var partComp)) + { + var targetPart = _body.GetTargetBodyPart(partComp.PartType, partComp.Symmetry); + _body.TryChangeIntegrity((part, partComp), damage.GetTotal().Float(), false, targetPart, out var _); + } + } + + private void OnToolAfterInteract(Entity ent, ref AfterInteractEvent args) + { + var user = args.User; + if (args.Handled + || !args.CanReach + || args.Target == null + || !TryComp(args.User, out var surgery) + || !surgery.CanOperate) + { + return; + } + /* lmao bet + if (user == args.Target) + { + _popup.PopupEntity("You can't perform surgery on yourself!", user, user); + return; + }*/ + Logger.Debug("OnToolAfterInteract passed, opening UI"); + args.Handled = true; + _ui.OpenUi(args.Target.Value, SurgeryUIKey.Key, user); + Logger.Debug("UI opened"); + RefreshUI(args.Target.Value); + } + + private void OnSurgeryStepDamage(Entity ent, ref SurgeryStepDamageEvent args) + { + SetDamage(args.Body, args.Damage, args.PartMultiplier, args.User, args.Part); + } + + private void OnSurgeryDamageChange(Entity ent, ref SurgeryStepEvent args) + { + // This unintentionally punishes the user if they have an organ in another hand that is already used. + // Imo surgery shouldnt let you automatically pick tools on both hands anyway, it should only use the one you've got in your selected hand. + if (ent.Comp.IsConsumable) + { + if (args.Tools.Where(tool => TryComp(tool, out var organComp) + && !_body.TrySetOrganUsed(tool, true, organComp)).Any()) + return; + } + + var damageChange = ent.Comp.Damage; + if (HasComp(args.Body)) + damageChange = damageChange * ent.Comp.SleepModifier; + + SetDamage(args.Body, damageChange, 0.5f, args.User, args.Part); + } + + private void OnSurgerySpecialDamageChange(Entity ent, ref SurgeryStepEvent args) + { + if (ent.Comp.IsConsumable) + { + if (args.Tools.Where(tool => TryComp(tool, out var organComp) + && !_body.TrySetOrganUsed(tool, true, organComp)).Any()) + return; + } + + if (ent.Comp.DamageType == "Rot") + { + _rot.ReduceAccumulator(args.Body, TimeSpan.FromSeconds(2147483648)); + } + else if (ent.Comp.DamageType == "Eye") + { + if (TryComp(args.Body, out BlindableComponent? blindComp) + && blindComp.EyeDamage > 0) + _blindableSystem.AdjustEyeDamage((args.Body, blindComp), -blindComp!.EyeDamage); + } + } + + private void OnStepAffixPartComplete(Entity ent, ref SurgeryStepEvent args) + { + if (!TryComp(args.Surgery, out SurgeryPartRemovedConditionComponent? removedComp)) + return; + + var targetPart = _body.GetBodyChildrenOfType(args.Body, removedComp.Part, symmetry: removedComp.Symmetry).FirstOrDefault(); + + if (targetPart != default) + { + var ev = new BodyPartEnableChangedEvent(true); + RaiseLocalEvent(targetPart.Id, ref ev); + // This is basically an equalizer, severing a part will badly damage it. + // and affixing it will heal it a bit if its not too badly damaged. + _body.TryChangeIntegrity(targetPart, targetPart.Component.Integrity - 20, false, + _body.GetTargetBodyPart(targetPart.Component.PartType, targetPart.Component.Symmetry), out _); + } + + } + + private void OnStepScreamComplete(Entity ent, ref SurgeryStepEvent args) + { + if (!HasComp(args.Body)) + _chat.TryEmoteWithChat(args.Body, ent.Comp.Emote); + } + private void OnStepSpawnComplete(Entity ent, ref SurgeryStepEvent args) + { + if (TryComp(args.Body, out TransformComponent? xform)) + SpawnAtPosition(ent.Comp.Entity, xform.Coordinates); + } + + private void OnPrototypesReloaded(PrototypesReloadedEventArgs args) + { + if (args.WasModified()) + LoadPrototypes(); + } + + private void LoadPrototypes() + { + _surgeries.Clear(); + foreach (var entity in _prototypes.EnumeratePrototypes()) + { + if (entity.HasComponent()) + _surgeries.Add(new EntProtoId(entity.ID)); + } + } +} diff --git a/Content.Server/Backmen/Targeting/TargetingSystem.cs b/Content.Server/Backmen/Targeting/TargetingSystem.cs new file mode 100644 index 00000000000..e2704b40a46 --- /dev/null +++ b/Content.Server/Backmen/Targeting/TargetingSystem.cs @@ -0,0 +1,57 @@ +using Content.Shared.Body.Systems; +using Content.Shared.Mobs; +using Content.Shared.Targeting; +using Content.Shared.Targeting.Events; +using Robust.Server.Audio; +using Robust.Shared.Audio; + +namespace Content.Server.Targeting; +public sealed class TargetingSystem : SharedTargetingSystem +{ + [Dependency] private readonly AudioSystem _audio = default!; + [Dependency] private readonly SharedBodySystem _bodySystem = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeNetworkEvent(OnTargetChange); + SubscribeLocalEvent(OnMobStateChange); + } + + private void OnTargetChange(TargetChangeEvent message, EntitySessionEventArgs args) + { + if (!TryComp(GetEntity(message.Uid), out var target)) + return; + + // Todo, get a better sound for this shit. + //_audio.PlayGlobal(target.SwapSound, args.SenderSession, AudioParams.Default.WithVolume(-8f)); + target.Target = message.BodyPart; + Dirty(GetEntity(message.Uid), target); + } + + private void OnMobStateChange(EntityUid uid, TargetingComponent component, MobStateChangedEvent args) + { + // Revival is handled by the server, so we're keeping all of this here. + var changed = false; + + if (args.NewMobState == MobState.Dead) + { + foreach (TargetBodyPart part in Enum.GetValues(typeof(TargetBodyPart))) + { + component.BodyStatus[part] = TargetIntegrity.Dead; + changed = true; + } + } + else if (args.OldMobState == MobState.Dead && (args.NewMobState == MobState.Alive || args.NewMobState == MobState.Critical)) + { + component.BodyStatus = _bodySystem.GetBodyPartStatus(uid); + changed = true; + } + + if (changed) + { + Dirty(uid, component); + RaiseNetworkEvent(new TargetIntegrityChangeEvent(GetNetEntity(uid)), uid); + } + } +} \ No newline at end of file diff --git a/Content.Server/Backmen/Traits/Assorted/LightweightDrunkSystem.cs b/Content.Server/Backmen/Traits/Assorted/LightweightDrunkSystem.cs new file mode 100644 index 00000000000..08fbbea7898 --- /dev/null +++ b/Content.Server/Backmen/Traits/Assorted/LightweightDrunkSystem.cs @@ -0,0 +1,23 @@ +/*using Content.Server.Body.Components; +using Content.Server.Body.Systems; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.Traits.Assorted.Components; + +namespace Content.Shared.Traits.Assorted.Systems; +public sealed class LightweightDrunkSystem : EntitySystem +{ + public override void Initialize() + { + SubscribeLocalEvent(OnTryMetabolizeReagent); + } + + private void OnTryMetabolizeReagent(EntityUid uid, LightweightDrunkComponent comp, ref TryMetabolizeReagent args) + { + //Log.Debug(args.Prototype.ID); + if (args.Prototype.ID != "Ethanol") + return; + + args.Scale *= comp.BoozeStrengthMultiplier; + args.QuantityMultiplier *= comp.BoozeStrengthMultiplier; + } +}*/ diff --git a/Content.Server/Body/Systems/BodySystem.cs b/Content.Server/Body/Systems/BodySystem.cs index 4279f3ed2b8..c1302a72d9d 100644 --- a/Content.Server/Body/Systems/BodySystem.cs +++ b/Content.Server/Body/Systems/BodySystem.cs @@ -4,6 +4,7 @@ using Content.Shared.Body.Components; using Content.Shared.Body.Part; using Content.Shared.Body.Systems; +using Content.Shared.Damage; using Content.Shared.Humanoid; using Content.Shared.Mind; using Content.Shared.Mobs.Systems; @@ -20,6 +21,7 @@ public sealed class BodySystem : SharedBodySystem [Dependency] private readonly GhostSystem _ghostSystem = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly HumanoidAppearanceSystem _humanoidSystem = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly MobStateSystem _mobState = default!; [Dependency] private readonly SharedMindSystem _mindSystem = default!; @@ -95,6 +97,7 @@ protected override void RemovePart( var layers = HumanoidVisualLayersExtension.Sublayers(layer.Value); _humanoidSystem.SetLayersVisibility( bodyEnt, layers, visible: false, permanent: true, humanoid); + _appearance.SetData(bodyEnt, layer, true); } public override HashSet GibBody( @@ -105,8 +108,7 @@ public override HashSet GibBody( Vector2? splatDirection = null, float splatModifier = 1, Angle splatCone = default, - SoundSpecifier? gibSoundOverride = null - ) + SoundSpecifier? gibSoundOverride = null) { if (!Resolve(bodyId, ref body, logMissing: false) || TerminatingOrDeleted(bodyId) @@ -120,7 +122,7 @@ public override HashSet GibBody( return new HashSet(); var gibs = base.GibBody(bodyId, gibOrgans, body, launchGibs: launchGibs, - splatDirection: splatDirection, splatModifier: splatModifier, splatCone:splatCone); + splatDirection: splatDirection, splatModifier: splatModifier, splatCone: splatCone); var ev = new BeingGibbedEvent(gibs); RaiseLocalEvent(bodyId, ref ev); @@ -129,4 +131,35 @@ public override HashSet GibBody( return gibs; } + + public override HashSet GibPart( + EntityUid partId, + BodyPartComponent? part = null, + bool launchGibs = true, + Vector2? splatDirection = null, + float splatModifier = 1, + Angle splatCone = default, + SoundSpecifier? gibSoundOverride = null) + { + if (!Resolve(partId, ref part, logMissing: false) + || TerminatingOrDeleted(partId) + || EntityManager.IsQueuedForDeletion(partId)) + { + return new HashSet(); + } + + var xform = Transform(partId); + if (xform.MapUid is null) + return new HashSet(); + + var gibs = base.GibPart(partId, part, launchGibs: launchGibs, + splatDirection: splatDirection, splatModifier: splatModifier, splatCone: splatCone); + + var ev = new BeingGibbedEvent(gibs); + RaiseLocalEvent(partId, ref ev); + + QueueDel(partId); + + return gibs; + } } diff --git a/Content.Server/Destructible/Thresholds/Behaviors/GibPartBehavior.cs b/Content.Server/Destructible/Thresholds/Behaviors/GibPartBehavior.cs new file mode 100644 index 00000000000..95f3a319bfe --- /dev/null +++ b/Content.Server/Destructible/Thresholds/Behaviors/GibPartBehavior.cs @@ -0,0 +1,19 @@ +using Content.Shared.Body.Components; +using Content.Shared.Body.Part; +using JetBrains.Annotations; + +namespace Content.Server.Destructible.Thresholds.Behaviors +{ + [UsedImplicitly] + [DataDefinition] + public sealed partial class GibPartBehavior : IThresholdBehavior + { + public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null) + { + if (system.EntityManager.TryGetComponent(owner, out BodyPartComponent? part)) + { + system.BodySystem.GibPart(owner, part); + } + } + } +} diff --git a/Content.Server/Hands/Systems/HandsSystem.cs b/Content.Server/Hands/Systems/HandsSystem.cs index 903fd1ff3f7..5bf0ec60ff9 100644 --- a/Content.Server/Hands/Systems/HandsSystem.cs +++ b/Content.Server/Hands/Systems/HandsSystem.cs @@ -2,6 +2,8 @@ using Content.Server.Inventory; using Content.Server.Stack; using Content.Server.Stunnable; +using Content.Shared.Body.Systems; +using Content.Shared.Body.Events; using Content.Shared.ActionBlocker; using Content.Shared.Body.Part; using Content.Shared.CombatMode; @@ -36,7 +38,7 @@ public sealed class HandsSystem : SharedHandsSystem [Dependency] private readonly SharedTransformSystem _transformSystem = default!; [Dependency] private readonly PullingSystem _pullingSystem = default!; [Dependency] private readonly ThrowingSystem _throwingSystem = default!; - + [Dependency] private readonly SharedBodySystem _bodySystem = default!; public override void Initialize() { base.Initialize(); @@ -52,6 +54,8 @@ public override void Initialize() SubscribeLocalEvent(GetComponentState); SubscribeLocalEvent(OnExploded); + SubscribeLocalEvent(HandleBodyPartEnabled); + SubscribeLocalEvent(HandleBodyPartDisabled); CommandBinds.Builder .Bind(ContentKeyFunctions.ThrowItemInHand, new PointerInputCmdHandler(HandleThrowItem)) @@ -101,32 +105,56 @@ private void OnDisarmed(EntityUid uid, HandsComponent component, DisarmedEvent a args.Handled = true; // no shove/stun. } - private void HandleBodyPartAdded(EntityUid uid, HandsComponent component, ref BodyPartAddedEvent args) + private void TryAddHand(EntityUid uid, HandsComponent component, Entity part, string slot) { - if (args.Part.Comp.PartType != BodyPartType.Hand) + if (part.Comp is null + || part.Comp.PartType != BodyPartType.Hand) return; // If this annoys you, which it should. // Ping Smugleaf. - var location = args.Part.Comp.Symmetry switch + var location = part.Comp.Symmetry switch { BodyPartSymmetry.None => HandLocation.Middle, BodyPartSymmetry.Left => HandLocation.Left, BodyPartSymmetry.Right => HandLocation.Right, - _ => throw new ArgumentOutOfRangeException(nameof(args.Part.Comp.Symmetry)) + _ => throw new ArgumentOutOfRangeException(nameof(part.Comp.Symmetry)) }; - AddHand(uid, args.Slot, location); + if (part.Comp.Enabled + && _bodySystem.TryGetParentBodyPart(part, out var _, out var parentPartComp) + && parentPartComp.Enabled) + AddHand(uid, slot, location); + } + + private void HandleBodyPartAdded(EntityUid uid, HandsComponent component, ref BodyPartAddedEvent args) + { + TryAddHand(uid, component, args.Part, args.Slot); } private void HandleBodyPartRemoved(EntityUid uid, HandsComponent component, ref BodyPartRemovedEvent args) { - if (args.Part.Comp.PartType != BodyPartType.Hand) + if (args.Part.Comp is null + || args.Part.Comp.PartType != BodyPartType.Hand) return; - RemoveHand(uid, args.Slot); } + private void HandleBodyPartEnabled(EntityUid uid, HandsComponent component, ref BodyPartEnabledEvent args) + { + TryAddHand(uid, component, args.Part, SharedBodySystem.GetPartSlotContainerId(args.Part.Comp.ParentSlot?.Id ?? string.Empty)); + } + + private void HandleBodyPartDisabled(EntityUid uid, HandsComponent component, ref BodyPartDisabledEvent args) + { + if (args.Part.Comp is null + || args.Part.Comp.PartType != BodyPartType.Hand) + return; + + RemoveHand(uid, SharedBodySystem.GetPartSlotContainerId(args.Part.Comp.ParentSlot?.Id ?? string.Empty)); + } + + #region pulling private void HandlePullStarted(EntityUid uid, HandsComponent component, PullStartedMessage args) @@ -195,7 +223,7 @@ hands.ActiveHandEntity is not { } throwEnt || { var splitStack = _stackSystem.Split(throwEnt, 1, EntityManager.GetComponent(player).Coordinates, stack); - if (splitStack is not {Valid: true}) + if (splitStack is not { Valid: true }) return false; throwEnt = splitStack.Value; diff --git a/Content.Server/Medical/HealingSystem.cs b/Content.Server/Medical/HealingSystem.cs index cf5869d1cbb..631196ecd15 100644 --- a/Content.Server/Medical/HealingSystem.cs +++ b/Content.Server/Medical/HealingSystem.cs @@ -6,9 +6,12 @@ using Content.Server.Stack; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Audio; +using Content.Shared.Body.Systems; using Content.Shared.Damage; using Content.Shared.Database; using Content.Shared.DoAfter; +using Content.Shared.Targeting; +using Content.Shared.Body.Components; using Content.Shared.FixedPoint; using Content.Shared.IdentityManagement; using Content.Shared.Interaction; @@ -21,6 +24,7 @@ using Content.Shared.Stacks; using Robust.Shared.Audio.Systems; using Robust.Shared.Random; +using System.Linq; namespace Content.Server.Medical; @@ -36,6 +40,7 @@ public sealed class HealingSystem : EntitySystem [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly MobThresholdSystem _mobThresholdSystem = default!; [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly SharedBodySystem _bodySystem = default!; [Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!; public override void Initialize() @@ -85,6 +90,25 @@ entity.Comp.DamageContainerID is not null && if (healed == null && healing.BloodlossModifier != 0) return; + /* This is rather shitcodey. Problem is that right now damage is coupled to integrity. + If the body is fully healed, all of the checks on TryChangeDamage stop us from actually healing. + So in this case we add a special check to heal anyway if TryChangeDamage returns null. + */ + if (healed != null && healed.GetTotal() == 0) + { + if (TryComp(args.User, out var user) + && TryComp(args.Target, out var target) + && healing.Damage.GetTotal() < 0) + { + // If they are valid, we check for body part presence, + // and integrity, then apply a direct integrity change. + var (type, symmetry) = _bodySystem.ConvertTargetBodyPart(user.Target); + if (_bodySystem.GetBodyChildrenOfType(args.Target.Value, type, symmetry: symmetry).FirstOrDefault() is { } bodyPart + && bodyPart.Component.Integrity < 100) + _bodySystem.TryChangeIntegrity(bodyPart, healing.Damage.GetTotal().Float(), false, target.Target, out var _); + } + } + var total = healed?.GetTotal() ?? FixedPoint2.Zero; // Re-verify that we can heal the damage. @@ -115,7 +139,7 @@ entity.Comp.DamageContainerID is not null && _audio.PlayPvs(healing.HealingEndSound, entity.Owner, AudioHelpers.WithVariation(0.125f, _random).WithVolume(1f)); // Logic to determine the whether or not to repeat the healing action - args.Repeat = (HasDamage(entity.Comp, healing) && !dontRepeat); + args.Repeat = HasDamage(entity.Comp, healing) && !dontRepeat || ArePartsDamaged(entity); if (!args.Repeat && !dontRepeat) _popupSystem.PopupEntity(Loc.GetString("medical-item-finished-using", ("item", args.Used)), entity.Owner, args.User); args.Handled = true; @@ -136,6 +160,19 @@ private bool HasDamage(DamageableComponent component, HealingComponent healing) return false; } + private bool ArePartsDamaged(EntityUid target) + { + if (!TryComp(target, out var body)) + return false; + + foreach (var part in _bodySystem.GetBodyChildren(target, body)) + { + if (part.Component.Integrity < 100) + return true; + } + return false; + } + private void OnHealingUse(Entity entity, ref UseInHandEvent args) { if (args.Handled) @@ -174,6 +211,7 @@ targetDamage.DamageContainerID is not null && var anythingToDo = HasDamage(targetDamage, component) || + ArePartsDamaged(target) || component.ModifyBloodLevel > 0 // Special case if healing item can restore lost blood... && TryComp(target, out var bloodstream) && _solutionContainerSystem.ResolveSolution(target, bloodstream.BloodSolutionName, ref bloodstream.BloodSolution, out var bloodSolution) diff --git a/Content.Shared/Backmen/Surgery/Body/AmputateAttemptEvent.cs b/Content.Shared/Backmen/Surgery/Body/AmputateAttemptEvent.cs new file mode 100644 index 00000000000..b71a0407bf2 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Body/AmputateAttemptEvent.cs @@ -0,0 +1,7 @@ +namespace Content.Shared.Body.Events; + +/// +/// Raised on an entity when attempting to remove a body part. +/// +[ByRefEvent] +public readonly record struct AmputateAttemptEvent(EntityUid Part); diff --git a/Content.Shared/Backmen/Surgery/Body/EyesComponent.cs b/Content.Shared/Backmen/Surgery/Body/EyesComponent.cs new file mode 100644 index 00000000000..55be5f1a9c4 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Body/EyesComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Body.Organ; + +[RegisterComponent] +public sealed partial class EyesComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Body/HeartComponent.cs b/Content.Shared/Backmen/Surgery/Body/HeartComponent.cs new file mode 100644 index 00000000000..fc4def945eb --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Body/HeartComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Body.Organ; + +[RegisterComponent] +public sealed partial class HeartComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Body/LiverComponent.cs b/Content.Shared/Backmen/Surgery/Body/LiverComponent.cs new file mode 100644 index 00000000000..23021bea319 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Body/LiverComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Body.Organ; + +[RegisterComponent] +public sealed partial class LiverComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Body/SharedBodySystem.Integrity.cs b/Content.Shared/Backmen/Surgery/Body/SharedBodySystem.Integrity.cs new file mode 100644 index 00000000000..0c2e24eb026 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Body/SharedBodySystem.Integrity.cs @@ -0,0 +1,291 @@ +using Content.Shared.Body.Components; +using Content.Shared.Body.Part; +using Content.Shared.Damage; +using Content.Shared.Mobs.Systems; +using Content.Shared.Mobs.Components; +using Content.Shared.Standing; +using Content.Shared.Targeting; +using Content.Shared.Targeting.Events; +using Robust.Shared.Network; +using Robust.Shared.Random; +using System.Linq; +using Content.Shared.Backmen.Surgery.Steps.Parts; + +namespace Content.Shared.Body.Systems; + +public partial class SharedBodySystem +{ + [Dependency] private readonly INetManager _net = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly IRobustRandom _random = default!; + private readonly string[] _severingDamageTypes = { "Slash", "Pierce", "Blunt" }; + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var ent, out var part)) + { + if (!_timing.IsFirstTimePredicted + || !HasComp(ent)) + continue; + + part.HealingTimer += frameTime; + + if (part.HealingTimer >= part.HealingTime) + { + part.HealingTimer = 0; + if (part.Body is not null + && part.Integrity > 50 + && part.Integrity < 100 + && !_mobState.IsDead(part.Body.Value)) + { + var healing = part.SelfHealingAmount; + if (healing + part.Integrity > 100) + healing = part.Integrity - 100; + + TryChangeIntegrity((ent, part), healing, + false, GetTargetBodyPart(part.PartType, part.Symmetry), out _); + } + } + + } + query.Dispose(); + } + + /// + /// Propagates damage to the specified parts of the entity. + /// + private void ApplyPartDamage(Entity partEnt, DamageSpecifier damage, + BodyPartType targetType, TargetBodyPart targetPart, bool canSever, float partMultiplier) + { + if (partEnt.Comp.Body is null) + return; + + foreach (var (damageType, damageValue) in damage.DamageDict) + { + if (damageValue.Float() == 0 + || TryEvadeDamage(partEnt.Comp.Body.Value, GetEvadeChance(targetType))) + continue; + + float modifier = GetDamageModifier(damageType); + float partModifier = GetPartDamageModifier(targetType); + float integrityDamage = damageValue.Float() * modifier * partModifier * partMultiplier; + TryChangeIntegrity(partEnt, integrityDamage, canSever && _severingDamageTypes.Contains(damageType), + targetPart, out var severed); + + if (severed) + break; + } + } + + public void TryChangeIntegrity(Entity partEnt, float integrity, bool canSever, + TargetBodyPart? targetPart, out bool severed) + { + severed = false; + if (!HasComp(partEnt.Comp.Body) || !_timing.IsFirstTimePredicted) + return; + + var partIdSlot = GetParentPartAndSlotOrNull(partEnt)?.Slot; + var originalIntegrity = partEnt.Comp.Integrity; + partEnt.Comp.Integrity = Math.Min(100, partEnt.Comp.Integrity - integrity); + if (canSever + && !HasComp(partEnt) + && !partEnt.Comp.Enabled + && partEnt.Comp.Integrity <= 0 + && partIdSlot is not null) + severed = true; + + // This will also prevent the torso from being removed. + if (partEnt.Comp.Enabled + && partEnt.Comp.Integrity <= 15.0f) + { + var ev = new BodyPartEnableChangedEvent(false); + RaiseLocalEvent(partEnt, ref ev); + } + else if (!partEnt.Comp.Enabled + && partEnt.Comp.Integrity >= 80.0f) + { + var ev = new BodyPartEnableChangedEvent(true); + RaiseLocalEvent(partEnt, ref ev); + } + + if (partEnt.Comp.Integrity != originalIntegrity + && TryComp(partEnt.Comp.Body, out var targeting) + && TryComp(partEnt.Comp.Body, out var _)) + { + var newIntegrity = GetIntegrityThreshold(partEnt.Comp.Integrity, severed, partEnt.Comp.Enabled); + // We need to check if the part is dead to prevent the UI from showing dead parts as alive. + if (targetPart is not null && targeting.BodyStatus[targetPart.Value] != TargetIntegrity.Dead) + { + targeting.BodyStatus[targetPart.Value] = newIntegrity; + Dirty(partEnt.Comp.Body.Value, targeting); + } + + // Revival events are handled by the server, so ends up being locked to a network event. + if (_net.IsServer) + RaiseNetworkEvent(new TargetIntegrityChangeEvent(GetNetEntity(partEnt.Comp.Body.Value)), partEnt.Comp.Body.Value); + } + + if (severed && partIdSlot is not null) + DropPart(partEnt); + + Dirty(partEnt, partEnt.Comp); + } + + /// + /// Gets the integrity of all body parts in the entity. + /// + public Dictionary GetBodyPartStatus(EntityUid entityUid) + { + var result = new Dictionary(); + + if (!TryComp(entityUid, out var body)) + return result; + + foreach (TargetBodyPart part in Enum.GetValues(typeof(TargetBodyPart))) + { + result[part] = TargetIntegrity.Severed; + } + + foreach (var partComponent in GetBodyChildren(entityUid, body)) + { + var targetBodyPart = GetTargetBodyPart(partComponent.Component.PartType, partComponent.Component.Symmetry); + + if (targetBodyPart != null) + { + result[targetBodyPart.Value] = GetIntegrityThreshold(partComponent.Component.Integrity, false, partComponent.Component.Enabled); + } + } + + return result; + } + + /// + /// Converts Enums from BodyPartType to their Targeting system equivalent. + /// + public TargetBodyPart? GetTargetBodyPart(BodyPartType type, BodyPartSymmetry symmetry) + { + return (type, symmetry) switch + { + (BodyPartType.Head, _) => TargetBodyPart.Head, + (BodyPartType.Torso, _) => TargetBodyPart.Torso, + (BodyPartType.Arm, BodyPartSymmetry.Left) => TargetBodyPart.LeftArm, + (BodyPartType.Arm, BodyPartSymmetry.Right) => TargetBodyPart.RightArm, + (BodyPartType.Leg, BodyPartSymmetry.Left) => TargetBodyPart.LeftLeg, + (BodyPartType.Leg, BodyPartSymmetry.Right) => TargetBodyPart.RightLeg, + _ => null + }; + } + + /// + /// Converts Enums from Targeting system to their BodyPartType equivalent. + /// + public (BodyPartType Type, BodyPartSymmetry Symmetry) ConvertTargetBodyPart(TargetBodyPart targetPart) + { + return targetPart switch + { + TargetBodyPart.Head => (BodyPartType.Head, BodyPartSymmetry.None), + TargetBodyPart.Torso => (BodyPartType.Torso, BodyPartSymmetry.None), + TargetBodyPart.LeftArm => (BodyPartType.Arm, BodyPartSymmetry.Left), + TargetBodyPart.RightArm => (BodyPartType.Arm, BodyPartSymmetry.Right), + TargetBodyPart.LeftLeg => (BodyPartType.Leg, BodyPartSymmetry.Left), + TargetBodyPart.RightLeg => (BodyPartType.Leg, BodyPartSymmetry.Right), + _ => (BodyPartType.Torso, BodyPartSymmetry.None) + }; + + } + + /// + /// Fetches the damage multiplier for part integrity based on damage types. + /// + public float GetDamageModifier(string damageType) + { + return damageType switch + { + "Blunt" => 0.8f, + "Slash" => 1.2f, + "Pierce" => 0.5f, + "Heat" => 1.0f, + "Cold" => 1.0f, + "Shock" => 0.8f, + "Poison" => 0.8f, + "Radiation" => 0.8f, + "Cellular" => 0.8f, + _ => 0.5f + }; + } + + /// + /// Fetches the damage multiplier for part integrity based on part types. + /// + public float GetPartDamageModifier(BodyPartType partType) + { + return partType switch + { + BodyPartType.Head => 0.5f, // 50% damage, necks are hard to cut + BodyPartType.Torso => 1.0f, // 100% damage + BodyPartType.Arm => 0.7f, // 70% damage + BodyPartType.Leg => 0.7f, // 70% damage + _ => 0.5f + }; + } + + /// + /// Fetches the TargetIntegrity equivalent of the current integrity value for the body part. + /// + public TargetIntegrity GetIntegrityThreshold(float integrity, bool severed, bool enabled) + { + if (severed) + return TargetIntegrity.Severed; + else if (!enabled) + return TargetIntegrity.Disabled; + else + return integrity switch + { + <= 10.0f => TargetIntegrity.CriticallyWounded, + <= 25.0f => TargetIntegrity.HeavilyWounded, + <= 40.0f => TargetIntegrity.ModeratelyWounded, + <= 60.0f => TargetIntegrity.SomewhatWounded, + <= 80.0f => TargetIntegrity.LightlyWounded, + _ => TargetIntegrity.Healthy + }; + } + + /// + /// Fetches the chance to evade integrity damage for a body part. + /// Used when the entity is not dead, laying down, or incapacitated. + /// + public float GetEvadeChance(BodyPartType partType) + { + return partType switch + { + BodyPartType.Head => 0.70f, // 70% chance to evade + BodyPartType.Arm => 0.20f, // 20% chance to evade + BodyPartType.Leg => 0.20f, // 20% chance to evade + BodyPartType.Torso => 0f, // 0% chance to evade + _ => 0f + }; + } + + public bool CanEvadeDamage(EntityUid uid) + { + if (!TryComp(uid, out var mobState) + || !TryComp(uid, out var standingState) + || _mobState.IsCritical(uid, mobState) + || _mobState.IsDead(uid, mobState) + || standingState.Standing == false) + return false; + + return true; + } + + public bool TryEvadeDamage(EntityUid uid, float evadeChance) + { + if (!CanEvadeDamage(uid)) + return false; + + return _random.NextFloat() < evadeChance; + } + +} diff --git a/Content.Shared/Backmen/Surgery/Conditions/SurgeryCloseIncisionConditionComponent.cs b/Content.Shared/Backmen/Surgery/Conditions/SurgeryCloseIncisionConditionComponent.cs new file mode 100644 index 00000000000..bab7e405ad5 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Conditions/SurgeryCloseIncisionConditionComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Medical.Surgery.Conditions; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryCloseIncisionConditionComponent : Component; \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Conditions/SurgeryLarvaConditionComponent.cs b/Content.Shared/Backmen/Surgery/Conditions/SurgeryLarvaConditionComponent.cs new file mode 100644 index 00000000000..3aac5951c6f --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Conditions/SurgeryLarvaConditionComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Medical.Surgery.Conditions; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryLarvaConditionComponent : Component; \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Conditions/SurgeryOperatingTableConditionComponent.cs b/Content.Shared/Backmen/Surgery/Conditions/SurgeryOperatingTableConditionComponent.cs new file mode 100644 index 00000000000..0c43549e669 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Conditions/SurgeryOperatingTableConditionComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Medical.Surgery.Conditions; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryOperatingTableConditionComponent : Component; \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Conditions/SurgeryOrganConditionComponent.cs b/Content.Shared/Backmen/Surgery/Conditions/SurgeryOrganConditionComponent.cs new file mode 100644 index 00000000000..19c8df14910 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Conditions/SurgeryOrganConditionComponent.cs @@ -0,0 +1,18 @@ +using Content.Shared.Body.Organ; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Medical.Surgery.Conditions; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryOrganConditionComponent : Component +{ + [DataField] + public ComponentRegistry? Organ; + + [DataField] + public bool Inverse = false; + + [DataField] + public bool Reattaching = false; +} \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Conditions/SurgeryPartConditionComponent.cs b/Content.Shared/Backmen/Surgery/Conditions/SurgeryPartConditionComponent.cs new file mode 100644 index 00000000000..5941e2fba3a --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Conditions/SurgeryPartConditionComponent.cs @@ -0,0 +1,17 @@ +using Content.Shared.Body.Part; +using Robust.Shared.GameStates; + +namespace Content.Shared.Medical.Surgery.Conditions; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryPartConditionComponent : Component +{ + [DataField] + public BodyPartType Part; + + [DataField] + public BodyPartSymmetry? Symmetry; + + [DataField] + public bool Inverse = false; +} \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Conditions/SurgeryPartPresentCondition.cs b/Content.Shared/Backmen/Surgery/Conditions/SurgeryPartPresentCondition.cs new file mode 100644 index 00000000000..608f90ba4cb --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Conditions/SurgeryPartPresentCondition.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Medical.Surgery.Conditions; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryPartPresentConditionComponent : Component; \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Conditions/SurgeryPartRemovedConditionComponent.cs b/Content.Shared/Backmen/Surgery/Conditions/SurgeryPartRemovedConditionComponent.cs new file mode 100644 index 00000000000..fb51ab5b060 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Conditions/SurgeryPartRemovedConditionComponent.cs @@ -0,0 +1,14 @@ +using Content.Shared.Body.Part; +using Robust.Shared.GameStates; + +namespace Content.Shared.Medical.Surgery.Conditions; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryPartRemovedConditionComponent : Component +{ + [DataField] + public BodyPartType Part; + + [DataField] + public BodyPartSymmetry? Symmetry; +} \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Conditions/SurgeryValidEvent.cs b/Content.Shared/Backmen/Surgery/Conditions/SurgeryValidEvent.cs new file mode 100644 index 00000000000..da769a457ac --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Conditions/SurgeryValidEvent.cs @@ -0,0 +1,9 @@ +using Content.Shared.Body.Part; + +namespace Content.Shared.Medical.Surgery.Conditions; + +/// +/// Raised on the entity that is receiving surgery. +/// +[ByRefEvent] +public record struct SurgeryValidEvent(EntityUid Body, EntityUid Part, bool Cancelled = false, BodyPartType PartType = default, BodyPartSymmetry? Symmetry = default); \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Conditions/SurgeryWoundedConditionComponent.cs b/Content.Shared/Backmen/Surgery/Conditions/SurgeryWoundedConditionComponent.cs new file mode 100644 index 00000000000..2279fcd0440 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Conditions/SurgeryWoundedConditionComponent.cs @@ -0,0 +1,7 @@ +using Content.Shared.Body.Part; +using Robust.Shared.GameStates; + +namespace Content.Shared.Medical.Surgery.Conditions; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryWoundedConditionComponent : Component; \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Effects/Complete/SurgeryCompletedEvent.cs b/Content.Shared/Backmen/Surgery/Effects/Complete/SurgeryCompletedEvent.cs new file mode 100644 index 00000000000..a0e040fbe7a --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Effects/Complete/SurgeryCompletedEvent.cs @@ -0,0 +1,7 @@ +namespace Content.Shared.Medical.Surgery.Effects.Complete; + +/// +/// Raised on the entity that received the surgery. +/// +[ByRefEvent] +public record struct SurgeryCompletedEvent; \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Effects/Complete/SurgeryRemoveLarvaComponent.cs b/Content.Shared/Backmen/Surgery/Effects/Complete/SurgeryRemoveLarvaComponent.cs new file mode 100644 index 00000000000..2077dfa53b8 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Effects/Complete/SurgeryRemoveLarvaComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Medical.Surgery.Effects.Complete; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryRemoveLarvaComponent : Component; \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryDamageChangeEffectComponent.cs b/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryDamageChangeEffectComponent.cs new file mode 100644 index 00000000000..646276bbeb4 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryDamageChangeEffectComponent.cs @@ -0,0 +1,17 @@ +using Content.Shared.Damage; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +namespace Content.Shared.Medical.Surgery.Effects.Step; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryDamageChangeEffectComponent : Component +{ + [DataField] + public DamageSpecifier Damage = default!; + + [DataField] + public float SleepModifier = 0.5f; + + [DataField] + public bool IsConsumable = false; +} \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Effects/Step/SurgerySpecialDamageChangeEffectComponent.cs b/Content.Shared/Backmen/Surgery/Effects/Step/SurgerySpecialDamageChangeEffectComponent.cs new file mode 100644 index 00000000000..823db704472 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Effects/Step/SurgerySpecialDamageChangeEffectComponent.cs @@ -0,0 +1,14 @@ +using Content.Shared.Damage; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +namespace Content.Shared.Medical.Surgery.Effects.Step; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgerySpecialDamageChangeEffectComponent : Component +{ + [DataField] + public string DamageType = ""; + + [DataField] + public bool IsConsumable = false; +} \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepAffixPartEffectComponent.cs b/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepAffixPartEffectComponent.cs new file mode 100644 index 00000000000..c41534ca833 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepAffixPartEffectComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Medical.Surgery.Effects.Step; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryStepAffixPartEffectComponent : Component; \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepCavityEffectComponent.cs b/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepCavityEffectComponent.cs new file mode 100644 index 00000000000..61300425a7d --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepCavityEffectComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Medical.Surgery.Effects.Step; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryStepCavityEffectComponent : Component +{ + [DataField] + public string Action = "Insert"; +} \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepEmoteEffectComponent.cs b/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepEmoteEffectComponent.cs new file mode 100644 index 00000000000..02e8b749eed --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepEmoteEffectComponent.cs @@ -0,0 +1,12 @@ +using Content.Shared.Chat.Prototypes; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Medical.Surgery.Effects.Step; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class SurgeryStepEmoteEffectComponent : Component +{ + [DataField, AutoNetworkedField] + public ProtoId Emote = "Scream"; +} \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepSpawnEffect.cs b/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepSpawnEffect.cs new file mode 100644 index 00000000000..766713c6f68 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryStepSpawnEffect.cs @@ -0,0 +1,13 @@ +using Content.Shared.Chat.Prototypes; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using System.ComponentModel.DataAnnotations; + +namespace Content.Shared.Medical.Surgery.Effects.Step; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class SurgeryStepSpawnEffectComponent : Component +{ + [DataField(required: true), AutoNetworkedField] + public EntProtoId Entity; +} \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryTendWoundsEffectComponent.cs b/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryTendWoundsEffectComponent.cs new file mode 100644 index 00000000000..58db1422d8f --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Effects/Step/SurgeryTendWoundsEffectComponent.cs @@ -0,0 +1,20 @@ +using Content.Shared.Damage; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +namespace Content.Shared.Medical.Surgery.Effects.Step; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class SurgeryTendWoundsEffectComponent : Component +{ + [DataField, AutoNetworkedField] + public string MainGroup = "Brute"; + + [DataField, AutoNetworkedField] + public bool IsAutoRepeatable = true; + + [DataField, AutoNetworkedField] + public DamageSpecifier Damage = default!; + + [DataField, AutoNetworkedField] + public float HealMultiplier = 0.07f; +} \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/OperatingTableComponent.cs b/Content.Shared/Backmen/Surgery/OperatingTableComponent.cs new file mode 100644 index 00000000000..05e2060f24b --- /dev/null +++ b/Content.Shared/Backmen/Surgery/OperatingTableComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery; + +[RegisterComponent, NetworkedComponent] +public sealed partial class OperatingTableComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/SharedSurgerySystem.Steps.cs b/Content.Shared/Backmen/Surgery/SharedSurgerySystem.Steps.cs new file mode 100644 index 00000000000..239481bd659 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/SharedSurgerySystem.Steps.cs @@ -0,0 +1,625 @@ +using Content.Shared.Medical.Surgery.Conditions; +using Content.Shared.Medical.Surgery.Effects.Step; +using Content.Shared.Medical.Surgery.Steps; +using Content.Shared.Body.Part; +using Content.Shared.Body.Organ; +using Content.Shared.Body.Events; +using Content.Shared.Buckle.Components; +using Content.Shared.Damage; +using Content.Shared.Damage.Prototypes; +using Content.Shared.Inventory; +using Content.Shared.Item; +using Content.Shared.DoAfter; +using Content.Shared.Popups; +using Robust.Shared.Prototypes; +using System.Linq; +using Content.Shared.Backmen.Surgery.Steps; +using Content.Shared.Backmen.Surgery.Tools; + +namespace Content.Shared.Backmen.Surgery; + +public abstract partial class SharedSurgerySystem +{ + private static readonly string[] BruteDamageTypes = { "Slash", "Blunt", "Piercing" }; + private static readonly string[] BurnDamageTypes = { "Heat", "Shock", "Cold", "Caustic" }; + private void InitializeSteps() + { + SubscribeLocalEvent(OnToolStep); + SubscribeLocalEvent(OnToolCheck); + SubscribeLocalEvent(OnToolCanPerform); + + //SubSurgery(OnCutLarvaRootsStep, OnCutLarvaRootsCheck); + SubSurgery(OnTendWoundsStep, OnTendWoundsCheck); + SubSurgery(OnCavityStep, OnCavityCheck); + SubSurgery(OnAddPartStep, OnAddPartCheck); + SubSurgery(OnRemovePartStep, OnRemovePartCheck); + SubSurgery(OnAddOrganStep, OnAddOrganCheck); + SubSurgery(OnRemoveOrganStep, OnRemoveOrganCheck); + Subs.BuiEvents(SurgeryUIKey.Key, + subs => + { + subs.Event(OnSurgeryTargetStepChosen); + }); + } + + private void SubSurgery(EntityEventRefHandler onStep, + EntityEventRefHandler onComplete) where TComp : IComponent + { + SubscribeLocalEvent(onStep); + SubscribeLocalEvent(onComplete); + } + + private void OnToolStep(Entity ent, ref SurgeryStepEvent args) + { + if (ent.Comp.Tool != null) + { + foreach (var reg in ent.Comp.Tool.Values) + { + if (!AnyHaveComp(args.Tools, reg.Component, out var tool)) + return; + + if (_net.IsServer && + TryComp(tool, out SurgeryToolComponent? toolComp) && + toolComp.EndSound != null) + { + _audio.PlayEntity(toolComp.EndSound, args.User, tool); + } + } + } + + if (ent.Comp.Add != null) + { + foreach (var reg in ent.Comp.Add.Values) + { + var compType = reg.Component.GetType(); + if (HasComp(args.Part, compType)) + continue; + + AddComp(args.Part, _compFactory.GetComponent(compType)); + } + } + + if (ent.Comp.Remove != null) + { + foreach (var reg in ent.Comp.Remove.Values) + { + RemComp(args.Part, reg.Component.GetType()); + } + } + + if (ent.Comp.BodyRemove != null) + { + foreach (var reg in ent.Comp.BodyRemove.Values) + { + RemComp(args.Body, reg.Component.GetType()); + } + } + + if (!_inventory.TryGetSlotEntity(args.User, "gloves", out var gloves) + || !_inventory.TryGetSlotEntity(args.User, "mask", out var mask)) + { + var sepsis = new DamageSpecifier(_prototypes.Index("Poison"), 5); + var ev = new SurgeryStepDamageEvent(args.User, args.Body, args.Part, args.Surgery, sepsis, 0.5f); + RaiseLocalEvent(args.Body, ref ev); + } + } + + private void OnToolCheck(Entity ent, ref SurgeryStepCompleteCheckEvent args) + { + if (ent.Comp.Add != null) + { + foreach (var reg in ent.Comp.Add.Values) + { + if (!HasComp(args.Part, reg.Component.GetType())) + { + args.Cancelled = true; + return; + } + } + } + + if (ent.Comp.Remove != null) + { + foreach (var reg in ent.Comp.Remove.Values) + { + if (HasComp(args.Part, reg.Component.GetType())) + { + args.Cancelled = true; + return; + } + } + } + + if (ent.Comp.BodyRemove != null) + { + foreach (var reg in ent.Comp.BodyRemove.Values) + { + if (HasComp(args.Body, reg.Component.GetType())) + { + args.Cancelled = true; + return; + } + } + } + } + + private void OnToolCanPerform(Entity ent, ref SurgeryCanPerformStepEvent args) + { + if (HasComp(ent)) + { + if (!TryComp(args.Body, out BuckleComponent? buckle) || + !HasComp(buckle.BuckledTo)) + { + args.Invalid = StepInvalidReason.NeedsOperatingTable; + return; + } + } + + RaiseLocalEvent(args.Body, ref args); + + if (args.Invalid != StepInvalidReason.None) + return; + + if (ent.Comp.Tool != null) + { + args.ValidTools ??= new HashSet(); + + foreach (var reg in ent.Comp.Tool.Values) + { + if (!AnyHaveComp(args.Tools, reg.Component, out var withComp)) + { + args.Invalid = StepInvalidReason.MissingTool; + + if (reg.Component is ISurgeryToolComponent tool) + args.Popup = $"You need {tool.ToolName} to perform this step!"; + + return; + } + + args.ValidTools.Add(withComp); + } + } + } + + private EntProtoId? GetProtoId(EntityUid entityUid) + { + if (!TryComp(entityUid, out var metaData)) + return null; + + return metaData.EntityPrototype?.ID; + } + + private void OnTendWoundsStep(Entity ent, ref SurgeryStepEvent args) + { + var group = ent.Comp.MainGroup == "Brute" ? BruteDamageTypes : BurnDamageTypes; + + if (!TryComp(args.Body, out DamageableComponent? damageable) + || !group.Any(damageType => damageable.Damage.DamageDict.TryGetValue(damageType, out var value) + && value > 0) + && (!TryComp(args.Part, out BodyPartComponent? bodyPart) + || bodyPart.Integrity == 100)) + return; + + var bonus = ent.Comp.HealMultiplier * damageable.DamagePerGroup[ent.Comp.MainGroup]; + if (_mobState.IsDead(args.Body)) + bonus *= 0.2; + + var adjustedDamage = new DamageSpecifier(ent.Comp.Damage); + var bonusPerType = bonus / group.Length; + + foreach (var type in group) + { + adjustedDamage.DamageDict[type] -= bonusPerType; + } + + var ev = new SurgeryStepDamageEvent(args.User, args.Body, args.Part, args.Surgery, adjustedDamage, 0.5f); + RaiseLocalEvent(args.Body, ref ev); + + if (ent.Comp.IsAutoRepeatable) + { + var stepProto = GetProtoId(ent); + var surgeryProto = GetProtoId(args.Surgery); + if (stepProto != null && surgeryProto != null) + CheckAndStartStep(args.User, args.Body, args.Part, ent, args.Surgery, stepProto.Value, surgeryProto.Value); + } + } + + private void OnTendWoundsCheck(Entity ent, ref SurgeryStepCompleteCheckEvent args) + { + var group = ent.Comp.MainGroup == "Brute" ? BruteDamageTypes : BurnDamageTypes; + + if (!TryComp(args.Body, out DamageableComponent? damageable) + || group.Any(damageType => damageable.Damage.DamageDict.TryGetValue(damageType, out var value) + && value > 0) + || !TryComp(args.Part, out BodyPartComponent? bodyPart) + || bodyPart.Integrity < 100) + args.Cancelled = true; + } + + /*private void OnCutLarvaRootsStep(Entity ent, ref SurgeryStepEvent args) + { + if (TryComp(args.Body, out VictimInfectedComponent? infected) && + infected.BurstAt > _timing.CurTime && + infected.SpawnedLarva == null) + { + infected.RootsCut = true; + } + } + + private void OnCutLarvaRootsCheck(Entity ent, ref SurgeryStepCompleteCheckEvent args) + { + if (!TryComp(args.Body, out VictimInfectedComponent? infected) || !infected.RootsCut) + args.Cancelled = true; + + // The larva has fully developed and surgery is now impossible + // TODO: Surgery should still be possible, but the fully developed larva should escape while also saving the hosts life + if (infected != null && infected.SpawnedLarva != null) + args.Cancelled = true; + }*/ + + private void OnCavityStep(Entity ent, ref SurgeryStepEvent args) + { + if (!TryComp(args.Part, out BodyPartComponent? partComp) || partComp.PartType != BodyPartType.Torso) + return; + + var activeHandEntity = _hands.EnumerateHeld(args.User).FirstOrDefault(); + if (activeHandEntity != default + && ent.Comp.Action == "Insert" + && TryComp(activeHandEntity, out ItemComponent? itemComp) + && (itemComp.Size.Id == "Tiny" + || itemComp.Size.Id == "Small")) + _itemSlotsSystem.TryInsert(ent, partComp.ItemInsertionSlot, activeHandEntity, args.User); + else if (ent.Comp.Action == "Remove") + _itemSlotsSystem.TryEjectToHands(ent, partComp.ItemInsertionSlot, args.User); + } + + private void OnCavityCheck(Entity ent, ref SurgeryStepCompleteCheckEvent args) + { + if (!TryComp(args.Part, out BodyPartComponent? partComp) + || ent.Comp.Action == "Insert" + && !partComp.ItemInsertionSlot.HasItem + || ent.Comp.Action == "Remove" + && partComp.ItemInsertionSlot.HasItem) + args.Cancelled = true; + } + + private void OnAddPartStep(Entity ent, ref SurgeryStepEvent args) + { + if (!TryComp(args.Surgery, out SurgeryPartRemovedConditionComponent? removedComp)) + return; + + foreach (var tool in args.Tools) + { + if (TryComp(tool, out BodyPartComponent? partComp) + && partComp.PartType == removedComp.Part + && (removedComp.Symmetry == null || partComp.Symmetry == removedComp.Symmetry)) + { + var slotName = removedComp.Symmetry != null + ? $"{removedComp.Symmetry?.ToString().ToLower()} {removedComp.Part.ToString().ToLower()}" + : removedComp.Part.ToString().ToLower(); + _body.TryCreatePartSlot(args.Part, slotName, partComp.PartType, out var _); + _body.AttachPart(args.Part, slotName, tool); + } + } + } + + private void OnAddPartCheck(Entity ent, ref SurgeryStepCompleteCheckEvent args) + { + if (!TryComp(args.Surgery, out SurgeryPartRemovedConditionComponent? removedComp) + || !_body.GetBodyChildrenOfType(args.Body, removedComp.Part, symmetry: removedComp.Symmetry).Any()) + args.Cancelled = true; + } + + private void OnRemovePartStep(Entity ent, ref SurgeryStepEvent args) + { + if (!TryComp(args.Part, out BodyPartComponent? partComp) + || partComp.Body != args.Body) + return; + + var ev = new AmputateAttemptEvent(args.Part); + RaiseLocalEvent(args.Part, ref ev); + _hands.TryPickupAnyHand(args.User, args.Part); + } + + private void OnRemovePartCheck(Entity ent, ref SurgeryStepCompleteCheckEvent args) + { + if (!TryComp(args.Part, out BodyPartComponent? partComp) + || partComp.Body == args.Body) + args.Cancelled = true; + } + + private void OnAddOrganStep(Entity ent, ref SurgeryStepEvent args) + { + if (!TryComp(args.Part, out BodyPartComponent? partComp) + || partComp.Body != args.Body + || !TryComp(args.Surgery, out SurgeryOrganConditionComponent? organComp) + || organComp.Organ == null) + return; + + // Adding organs is generally done for a single one at a time, so we only need to check for the first. + var firstOrgan = organComp.Organ.Values.FirstOrDefault(); + if (firstOrgan == default) + return; + + foreach (var tool in args.Tools) + { + if (HasComp(tool, firstOrgan.Component.GetType()) + && TryComp(tool, out var insertedOrgan) + && _body.InsertOrgan(args.Part, tool, insertedOrgan.SlotId, partComp, insertedOrgan)) + break; + } + } + + private void OnAddOrganCheck(Entity ent, ref SurgeryStepCompleteCheckEvent args) + { + if (!TryComp(args.Surgery, out var organComp) + || organComp.Organ is null + || !TryComp(args.Part, out BodyPartComponent? partComp) + || partComp.Body != args.Body) + return; + + // For now we naively assume that every entity will only have one of each organ type. + // that we do surgery on, but in the future we'll need to reference their prototype somehow + // to know if they need 2 hearts, 2 lungs, etc. + foreach (var reg in organComp.Organ.Values) + { + if (!_body.TryGetBodyPartOrgans(args.Part, reg.Component.GetType(), out var _)) + { + args.Cancelled = true; + } + } + } + + private void OnRemoveOrganStep(Entity ent, ref SurgeryStepEvent args) + { + if (!TryComp(args.Surgery, out var organComp) + || organComp.Organ == null) + return; + + foreach (var reg in organComp.Organ.Values) + { + _body.TryGetBodyPartOrgans(args.Part, reg.Component.GetType(), out var organs); + if (organs != null && organs.Count > 0) + { + _body.RemoveOrgan(organs[0].Id, organs[0].Organ); + _hands.TryPickupAnyHand(args.User, organs[0].Id); + } + } + } + + private void OnRemoveOrganCheck(Entity ent, ref SurgeryStepCompleteCheckEvent args) + { + if (!TryComp(args.Surgery, out var organComp) + || organComp.Organ == null + || !TryComp(args.Part, out BodyPartComponent? partComp) + || partComp.Body != args.Body) + return; + + foreach (var reg in organComp.Organ.Values) + { + if (_body.TryGetBodyPartOrgans(args.Part, reg.Component.GetType(), out var organs) + && organs != null + && organs.Count > 0) + { + args.Cancelled = true; + return; + } + } + } + + // Small duplicate for OnSurgeryTargetStepChosen, allows for continuously looping a given step. + private void CheckAndStartStep(EntityUid user, EntityUid body, EntityUid part, EntityUid step, EntityUid surgery, + EntProtoId stepProto, EntProtoId surgeryProto) + { + if (!CanPerformStep(user, body, part, step, true, out _, out _, out var validTools)) + return; + + if (_net.IsServer && validTools?.Count > 0) + { + foreach (var tool in validTools) + { + if (TryComp(tool, out SurgeryToolComponent? toolComp) && + toolComp.EndSound != null) + { + _audio.PlayEntity(toolComp.StartSound, user, tool); + } + } + } + + if (TryComp(body, out TransformComponent? xform)) + _rotateToFace.TryFaceCoordinates(user, _transform.GetMapCoordinates(body, xform).Position); + + var ev = new SurgeryDoAfterEvent(surgeryProto, stepProto); + // TODO: Make this serialized on a per surgery step basis, and also add penalties based on ghetto tools. + var duration = 2f; + if (TryComp(user, out SurgerySpeedModifierComponent? surgerySpeedMod)) + duration = duration / surgerySpeedMod.SpeedModifier; + + var doAfter = new DoAfterArgs(EntityManager, user, TimeSpan.FromSeconds(duration), ev, body, part) + { + BreakOnMove = true, + BreakOnHandChange = true, + BreakOnDamage = true, + BreakOnDropItem = true, + }; + _doAfter.TryStartDoAfter(doAfter); + } + + private void OnSurgeryTargetStepChosen(Entity ent, ref SurgeryStepChosenBuiMsg args) + { + var user = args.Actor; + if (GetEntity(args.Entity) is not { Valid: true } body || + GetEntity(args.Part) is not { Valid: true } targetPart || + !IsSurgeryValid(body, targetPart, args.Surgery, args.Step, out var surgery, out var part, out var step)) + { + return; + } + + if (!PreviousStepsComplete(body, part, surgery, args.Step) || + IsStepComplete(body, part, args.Step, surgery)) + return; + + if (!CanPerformStep(user, body, part, step, true, out _, out _, out var validTools)) + return; + + if (_net.IsServer && validTools?.Count > 0) + { + foreach (var tool in validTools) + { + if (TryComp(tool, out SurgeryToolComponent? toolComp) && + toolComp.EndSound != null) + { + _audio.PlayEntity(toolComp.StartSound, user, tool); + } + } + } + + if (TryComp(body, out TransformComponent? xform)) + _rotateToFace.TryFaceCoordinates(user, _transform.GetMapCoordinates(body, xform).Position); + + var ev = new SurgeryDoAfterEvent(args.Surgery, args.Step); + // TODO: Make this serialized on a per surgery step basis, and also add penalties based on ghetto tools. + var duration = 2f; + if (TryComp(user, out SurgerySpeedModifierComponent? surgerySpeedMod) + && surgerySpeedMod is not null) + duration = duration / surgerySpeedMod.SpeedModifier; + + var doAfter = new DoAfterArgs(EntityManager, user, TimeSpan.FromSeconds(duration), ev, body, part) + { + BreakOnMove = true, + BreakOnHandChange = true, + BreakOnDamage = true, + BreakOnDropItem = true, + }; + _doAfter.TryStartDoAfter(doAfter); + } + + private (Entity Surgery, int Step)? GetNextStep(EntityUid body, EntityUid part, Entity surgery, List requirements) + { + if (!Resolve(surgery, ref surgery.Comp)) + return null; + + if (requirements.Contains(surgery)) + throw new ArgumentException($"Surgery {surgery} has a requirement loop: {string.Join(", ", requirements)}"); + + requirements.Add(surgery); + + if (surgery.Comp.Requirement is { } requirementId && + GetSingleton(requirementId) is { } requirement && + GetNextStep(body, part, requirement, requirements) is { } requiredNext) + { + return requiredNext; + } + + for (var i = 0; i < surgery.Comp.Steps.Count; i++) + { + var surgeryStep = surgery.Comp.Steps[i]; + if (!IsStepComplete(body, part, surgeryStep, surgery)) + return ((surgery, surgery.Comp), i); + } + + return null; + } + + public (Entity Surgery, int Step)? GetNextStep(EntityUid body, EntityUid part, EntityUid surgery) + { + return GetNextStep(body, part, surgery, new List()); + } + + public bool PreviousStepsComplete(EntityUid body, EntityUid part, Entity surgery, EntProtoId step) + { + // TODO RMC14 use index instead of the prototype id + if (surgery.Comp.Requirement is { } requirement) + { + if (GetSingleton(requirement) is not { } requiredEnt || + !TryComp(requiredEnt, out SurgeryComponent? requiredComp) || + !PreviousStepsComplete(body, part, (requiredEnt, requiredComp), step)) + { + return false; + } + } + + foreach (var surgeryStep in surgery.Comp.Steps) + { + if (surgeryStep == step) + break; + + if (!IsStepComplete(body, part, surgeryStep, surgery)) + return false; + } + + return true; + } + + public bool CanPerformStep(EntityUid user, EntityUid body, EntityUid part, + EntityUid step, bool doPopup, out string? popup, out StepInvalidReason reason, + out HashSet? validTools) + { + var type = BodyPartType.Other; + if (TryComp(part, out BodyPartComponent? partComp)) + { + type = partComp.PartType; + } + + var slot = type switch + { + BodyPartType.Head => SlotFlags.HEAD, + BodyPartType.Torso => SlotFlags.OUTERCLOTHING | SlotFlags.INNERCLOTHING, + BodyPartType.Arm => SlotFlags.OUTERCLOTHING | SlotFlags.INNERCLOTHING, + BodyPartType.Hand => SlotFlags.GLOVES, + BodyPartType.Leg => SlotFlags.OUTERCLOTHING | SlotFlags.LEGS, + BodyPartType.Foot => SlotFlags.FEET, + BodyPartType.Tail => SlotFlags.NONE, + BodyPartType.Other => SlotFlags.NONE, + _ => SlotFlags.NONE + }; + + var check = new SurgeryCanPerformStepEvent(user, body, GetTools(user), slot); + RaiseLocalEvent(step, ref check); + popup = check.Popup; + validTools = check.ValidTools; + + if (check.Invalid != StepInvalidReason.None) + { + if (doPopup && check.Popup != null) + _popup.PopupEntity(check.Popup, user, PopupType.SmallCaution); + + reason = check.Invalid; + return false; + } + + reason = default; + return true; + } + + public bool CanPerformStep(EntityUid user, EntityUid body, EntityUid part, EntityUid step, bool doPopup) + { + return CanPerformStep(user, body, part, step, doPopup, out _, out _, out _); + } + + public bool IsStepComplete(EntityUid body, EntityUid part, EntProtoId step, EntityUid surgery) + { + if (GetSingleton(step) is not { } stepEnt) + return false; + + var ev = new SurgeryStepCompleteCheckEvent(body, part, surgery); + RaiseLocalEvent(stepEnt, ref ev); + + return !ev.Cancelled; + } + + private bool AnyHaveComp(List tools, IComponent component, out EntityUid withComp) + { + foreach (var tool in tools) + { + if (HasComp(tool, component.GetType())) + { + withComp = tool; + return true; + } + } + + withComp = default; + return false; + } +} diff --git a/Content.Shared/Backmen/Surgery/SharedSurgerySystem.cs b/Content.Shared/Backmen/Surgery/SharedSurgerySystem.cs new file mode 100644 index 00000000000..16f622820ea --- /dev/null +++ b/Content.Shared/Backmen/Surgery/SharedSurgerySystem.cs @@ -0,0 +1,261 @@ +using System.Linq; +using Content.Shared.Backmen.Surgery.Steps.Parts; +using Content.Shared.Medical.Surgery.Conditions; +using Content.Shared.Body.Systems; +using Content.Shared.Body.Part; +using Content.Shared.Damage; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Body.Components; +using Content.Shared.Buckle.Components; +using Content.Shared.DoAfter; +using Content.Shared.Mobs.Systems; +using Content.Shared.GameTicking; +using Content.Shared.Hands.EntitySystems; +using Content.Shared.Interaction; +using Content.Shared.Inventory; +using Content.Shared.Popups; +using Content.Shared.Standing; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Map; +using Robust.Shared.Network; +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; + +namespace Content.Shared.Backmen.Surgery; + +public abstract partial class SharedSurgerySystem : EntitySystem +{ + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly IComponentFactory _compFactory = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; + [Dependency] private readonly SharedHandsSystem _hands = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly SharedBodySystem _body = default!; + [Dependency] private readonly INetManager _net = default!; + [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly IPrototypeManager _prototypes = default!; + [Dependency] private readonly RotateToFaceSystem _rotateToFace = default!; + [Dependency] private readonly StandingStateSystem _standing = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; + + private readonly Dictionary _surgeries = new(); + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnRoundRestartCleanup); + + SubscribeLocalEvent(OnTargetDoAfter); + + SubscribeLocalEvent(OnCloseIncisionValid); + //SubscribeLocalEvent(OnLarvaValid); + SubscribeLocalEvent(OnPartConditionValid); + SubscribeLocalEvent(OnOrganConditionValid); + SubscribeLocalEvent(OnWoundedValid); + SubscribeLocalEvent(OnPartRemovedConditionValid); + SubscribeLocalEvent(OnPartPresentConditionValid); + + //SubscribeLocalEvent(OnRemoveLarva); + + InitializeSteps(); + } + + private void OnRoundRestartCleanup(RoundRestartCleanupEvent ev) + { + _surgeries.Clear(); + } + + private void OnTargetDoAfter(Entity ent, ref SurgeryDoAfterEvent args) + { + if (args.Cancelled || + args.Handled || + args.Target is not { } target || + !IsSurgeryValid(ent, target, args.Surgery, args.Step, out var surgery, out var part, out var step) || + !PreviousStepsComplete(ent, part, surgery, args.Step) || + !CanPerformStep(args.User, ent, part, step, false)) + { + Log.Warning($"{ToPrettyString(args.User)} tried to start invalid surgery."); + return; + } + + var ev = new SurgeryStepEvent(args.User, ent, part, GetTools(args.User), surgery); + RaiseLocalEvent(step, ref ev); + + RefreshUI(ent); + } + + private void OnCloseIncisionValid(Entity ent, ref SurgeryValidEvent args) + { + if (!HasComp(args.Part) || + !HasComp(args.Part) || + !HasComp(args.Part) || + !HasComp(args.Part) || + !HasComp(args.Part)) + { + args.Cancelled = true; + } + } + + private void OnWoundedValid(Entity ent, ref SurgeryValidEvent args) + { + if (!TryComp(args.Body, out DamageableComponent? damageable) + || !TryComp(args.Part, out BodyPartComponent? bodyPart) + || damageable.TotalDamage <= 0 + && bodyPart.Integrity == 100 + && !HasComp(args.Part)) + args.Cancelled = true; + } + + /*private void OnLarvaValid(Entity ent, ref SurgeryValidEvent args) + { + if (!TryComp(args.Body, out VictimInfectedComponent? infected)) + args.Cancelled = true; + + // The larva has fully developed and surgery is now impossible + if (infected != null && infected.SpawnedLarva != null) + args.Cancelled = true; + }*/ + private void OnPartConditionValid(Entity ent, ref SurgeryValidEvent args) + { + if (!TryComp(args.Part, out var part)) + { + args.Cancelled = true; + return; + } + + var typeMatch = part.PartType == ent.Comp.Part; + var symmetryMatch = ent.Comp.Symmetry == null || part.Symmetry == ent.Comp.Symmetry; + var valid = typeMatch && symmetryMatch; + + if (ent.Comp.Inverse ? valid : !valid) + args.Cancelled = true; + } + + private void OnOrganConditionValid(Entity ent, ref SurgeryValidEvent args) + { + if (!TryComp(args.Part, out var partComp) + || partComp.Body != args.Body + || ent.Comp.Organ == null) + { + args.Cancelled = true; + return; + } + + foreach (var reg in ent.Comp.Organ.Values) + { + if (_body.TryGetBodyPartOrgans(args.Part, reg.Component.GetType(), out var organs) + && organs != null + && organs.Count > 0) + { + if (ent.Comp.Inverse + && (!ent.Comp.Reattaching + || ent.Comp.Reattaching + && !HasComp(args.Part))) + args.Cancelled = true; + } + else if (!ent.Comp.Inverse) + args.Cancelled = true; + } + } + + private void OnPartRemovedConditionValid(Entity ent, ref SurgeryValidEvent args) + { + if (!TryComp(args.Part, out _) + || _body.GetBodyChildrenOfType(args.Body, ent.Comp.Part, symmetry: ent.Comp.Symmetry).Any() + && !HasComp(args.Part)) + args.Cancelled = true; + } + + private void OnPartPresentConditionValid(Entity ent, ref SurgeryValidEvent args) + { + if (args.Part == EntityUid.Invalid + || !HasComp(args.Part)) + args.Cancelled = true; + } + + /*private void OnRemoveLarva(Entity ent, ref SurgeryCompletedEvent args) + { + RemCompDeferred(ent); + }*/ + + protected bool IsSurgeryValid(EntityUid body, EntityUid targetPart, EntProtoId surgery, EntProtoId stepId, + out Entity surgeryEnt, out EntityUid part, out EntityUid step) + { + surgeryEnt = default; + part = default; + step = default; + if (!HasComp(body) || + !IsLyingDown(body) || + GetSingleton(surgery) is not { } surgeryEntId || + !TryComp(surgeryEntId, out SurgeryComponent? surgeryComp) || + !surgeryComp.Steps.Contains(stepId) || + GetSingleton(stepId) is not { } stepEnt) + { + return false; + } + if (!HasComp(targetPart) && !HasComp(targetPart)) + { + return false; + } + var ev = new SurgeryValidEvent(body, targetPart); + if (_timing.IsFirstTimePredicted) + { + RaiseLocalEvent(stepEnt, ref ev); + RaiseLocalEvent(surgeryEntId, ref ev); + } + + if (ev.Cancelled) + return false; + + surgeryEnt = (surgeryEntId, surgeryComp); + part = targetPart; + step = stepEnt; + return true; + } + + public EntityUid? GetSingleton(EntProtoId surgeryOrStep) + { + if (!_prototypes.HasIndex(surgeryOrStep)) + return null; + + // This (for now) assumes that surgery entity data remains unchanged between client + // and server + // if it does not you get the bullet + if (!_surgeries.TryGetValue(surgeryOrStep, out var ent) || TerminatingOrDeleted(ent)) + { + ent = Spawn(surgeryOrStep, MapCoordinates.Nullspace); + _surgeries[surgeryOrStep] = ent; + } + + return ent; + } + + private List GetTools(EntityUid surgeon) + { + return _hands.EnumerateHeld(surgeon).ToList(); + } + + public bool IsLyingDown(EntityUid entity) + { + if (_standing.IsDown(entity)) + return true; + + if (TryComp(entity, out BuckleComponent? buckle) && + TryComp(buckle.BuckledTo, out StrapComponent? strap)) + { + var rotation = strap.Rotation; + if (rotation.GetCardinalDir() is Direction.West or Direction.East) + return true; + } + + return false; + } + + protected virtual void RefreshUI(EntityUid body) + { + } +} diff --git a/Content.Shared/Backmen/Surgery/StepInvalidReason.cs b/Content.Shared/Backmen/Surgery/StepInvalidReason.cs new file mode 100644 index 00000000000..d0d0709f812 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/StepInvalidReason.cs @@ -0,0 +1,10 @@ +namespace Content.Shared.Backmen.Surgery; + +public enum StepInvalidReason +{ + None, + MissingSkills, + NeedsOperatingTable, + Armor, + MissingTool, +} diff --git a/Content.Shared/Backmen/Surgery/Steps/Parts/BleedersClampedComponent.cs b/Content.Shared/Backmen/Surgery/Steps/Parts/BleedersClampedComponent.cs new file mode 100644 index 00000000000..12978f06aa8 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/Parts/BleedersClampedComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Steps.Parts; + +[RegisterComponent, NetworkedComponent] +public sealed partial class BleedersClampedComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Steps/Parts/BodyPartReattachedComponent.cs b/Content.Shared/Backmen/Surgery/Steps/Parts/BodyPartReattachedComponent.cs new file mode 100644 index 00000000000..a8fd0e93d23 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/Parts/BodyPartReattachedComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Steps.Parts; + +[RegisterComponent, NetworkedComponent] +public sealed partial class BodyPartReattachedComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Steps/Parts/BodyPartSawedComponent.cs b/Content.Shared/Backmen/Surgery/Steps/Parts/BodyPartSawedComponent.cs new file mode 100644 index 00000000000..ba22b042b9b --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/Parts/BodyPartSawedComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Steps.Parts; + +[RegisterComponent, NetworkedComponent] +public sealed partial class BodyPartSawedComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Steps/Parts/IncisionOpenComponent.cs b/Content.Shared/Backmen/Surgery/Steps/Parts/IncisionOpenComponent.cs new file mode 100644 index 00000000000..c7da946df7f --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/Parts/IncisionOpenComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Steps.Parts; + +[RegisterComponent, NetworkedComponent] +public sealed partial class IncisionOpenComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Steps/Parts/InternalBleedersClampedComponent.cs b/Content.Shared/Backmen/Surgery/Steps/Parts/InternalBleedersClampedComponent.cs new file mode 100644 index 00000000000..4167a836040 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/Parts/InternalBleedersClampedComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Steps.Parts; + +[RegisterComponent, NetworkedComponent] +public sealed partial class InternalBleedersClampedComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Steps/Parts/OrganReattachedComponent.cs b/Content.Shared/Backmen/Surgery/Steps/Parts/OrganReattachedComponent.cs new file mode 100644 index 00000000000..fe446dc3c9c --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/Parts/OrganReattachedComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Steps.Parts; + +[RegisterComponent, NetworkedComponent] +public sealed partial class OrganReattachedComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Steps/Parts/PartRemovedComponent.cs b/Content.Shared/Backmen/Surgery/Steps/Parts/PartRemovedComponent.cs new file mode 100644 index 00000000000..bf3c5c722d3 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/Parts/PartRemovedComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Steps.Parts; + +[RegisterComponent, NetworkedComponent] +public sealed partial class PartsRemovedComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Steps/Parts/RibcageOpenComponent.cs b/Content.Shared/Backmen/Surgery/Steps/Parts/RibcageOpenComponent.cs new file mode 100644 index 00000000000..c159c9b52a8 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/Parts/RibcageOpenComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Steps.Parts; + +[RegisterComponent, NetworkedComponent] +public sealed partial class RibcageOpenComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Steps/Parts/RibcageSawedComponent.cs b/Content.Shared/Backmen/Surgery/Steps/Parts/RibcageSawedComponent.cs new file mode 100644 index 00000000000..0927d8a9335 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/Parts/RibcageSawedComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Steps.Parts; + +[RegisterComponent, NetworkedComponent] +public sealed partial class RibcageSawedComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Steps/Parts/SkinRetractedComponent.cs b/Content.Shared/Backmen/Surgery/Steps/Parts/SkinRetractedComponent.cs new file mode 100644 index 00000000000..dd5247e05a0 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/Parts/SkinRetractedComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Steps.Parts; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SkinRetractedComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Steps/SurgeryAddOrganStepComponent.cs b/Content.Shared/Backmen/Surgery/Steps/SurgeryAddOrganStepComponent.cs new file mode 100644 index 00000000000..e67bad1b623 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/SurgeryAddOrganStepComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Steps; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryAddOrganStepComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Steps/SurgeryAddPartStepComponent.cs b/Content.Shared/Backmen/Surgery/Steps/SurgeryAddPartStepComponent.cs new file mode 100644 index 00000000000..0229552ae8a --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/SurgeryAddPartStepComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Medical.Surgery.Steps; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryAddPartStepComponent : Component; \ No newline at end of file diff --git a/Content.Shared/Backmen/Surgery/Steps/SurgeryCanPerformStepEvent.cs b/Content.Shared/Backmen/Surgery/Steps/SurgeryCanPerformStepEvent.cs new file mode 100644 index 00000000000..e89a05efac9 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/SurgeryCanPerformStepEvent.cs @@ -0,0 +1,14 @@ +using Content.Shared.Inventory; + +namespace Content.Shared.Backmen.Surgery.Steps; + +[ByRefEvent] +public record struct SurgeryCanPerformStepEvent( + EntityUid User, + EntityUid Body, + List Tools, + SlotFlags TargetSlots, + string? Popup = null, + StepInvalidReason Invalid = StepInvalidReason.None, + HashSet? ValidTools = null +) : IInventoryRelayEvent; diff --git a/Content.Shared/Backmen/Surgery/Steps/SurgeryCutLarvaRootsStepComponent.cs b/Content.Shared/Backmen/Surgery/Steps/SurgeryCutLarvaRootsStepComponent.cs new file mode 100644 index 00000000000..75972676c29 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/SurgeryCutLarvaRootsStepComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Steps; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryCutLarvaRootsStepComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Steps/SurgeryRemoveOrganStepComponent.cs b/Content.Shared/Backmen/Surgery/Steps/SurgeryRemoveOrganStepComponent.cs new file mode 100644 index 00000000000..3f66533a08f --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/SurgeryRemoveOrganStepComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Steps; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryRemoveOrganStepComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Steps/SurgeryRemovePartStepComponent.cs b/Content.Shared/Backmen/Surgery/Steps/SurgeryRemovePartStepComponent.cs new file mode 100644 index 00000000000..c58582d2d38 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/SurgeryRemovePartStepComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Steps; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryRemovePartStepComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Steps/SurgeryStepCompleteCheckEvent.cs b/Content.Shared/Backmen/Surgery/Steps/SurgeryStepCompleteCheckEvent.cs new file mode 100644 index 00000000000..ce6f67011ef --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/SurgeryStepCompleteCheckEvent.cs @@ -0,0 +1,4 @@ +namespace Content.Shared.Backmen.Surgery.Steps; + +[ByRefEvent] +public record struct SurgeryStepCompleteCheckEvent(EntityUid Body, EntityUid Part, EntityUid Surgery, bool Cancelled = false); diff --git a/Content.Shared/Backmen/Surgery/Steps/SurgeryStepComponent.cs b/Content.Shared/Backmen/Surgery/Steps/SurgeryStepComponent.cs new file mode 100644 index 00000000000..b9356bf01cc --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Steps/SurgeryStepComponent.cs @@ -0,0 +1,22 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Backmen.Surgery.Steps; + +[RegisterComponent, NetworkedComponent] +[Prototype("SurgerySteps")] +public sealed partial class SurgeryStepComponent : Component +{ + + [DataField] + public ComponentRegistry? Tool; + + [DataField] + public ComponentRegistry? Add; + + [DataField] + public ComponentRegistry? Remove; + + [DataField] + public ComponentRegistry? BodyRemove; +} diff --git a/Content.Shared/Backmen/Surgery/SurgeryComponent.cs b/Content.Shared/Backmen/Surgery/SurgeryComponent.cs new file mode 100644 index 00000000000..1d13731ff88 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/SurgeryComponent.cs @@ -0,0 +1,18 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Backmen.Surgery; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Prototype("Surgeries")] +public sealed partial class SurgeryComponent : Component +{ + [DataField, AutoNetworkedField] + public int Priority; + + [DataField, AutoNetworkedField] + public EntProtoId? Requirement; + + [DataField(required: true), AutoNetworkedField] + public List Steps = new(); +} diff --git a/Content.Shared/Backmen/Surgery/SurgeryDoAfterEvent.cs b/Content.Shared/Backmen/Surgery/SurgeryDoAfterEvent.cs new file mode 100644 index 00000000000..0b27ed8c548 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/SurgeryDoAfterEvent.cs @@ -0,0 +1,18 @@ +using Content.Shared.DoAfter; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; + +namespace Content.Shared.Backmen.Surgery; + +[Serializable, NetSerializable] +public sealed partial class SurgeryDoAfterEvent : SimpleDoAfterEvent +{ + public readonly EntProtoId Surgery; + public readonly EntProtoId Step; + + public SurgeryDoAfterEvent(EntProtoId surgery, EntProtoId step) + { + Surgery = surgery; + Step = step; + } +} diff --git a/Content.Shared/Backmen/Surgery/SurgerySpeedModifierComponent.cs b/Content.Shared/Backmen/Surgery/SurgerySpeedModifierComponent.cs new file mode 100644 index 00000000000..4f8702c920c --- /dev/null +++ b/Content.Shared/Backmen/Surgery/SurgerySpeedModifierComponent.cs @@ -0,0 +1,11 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Backmen.Surgery; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgerySpeedModifierComponent : Component +{ + [DataField] + public float SpeedModifier = 1.5f; +} diff --git a/Content.Shared/Backmen/Surgery/SurgeryStepDamageEvent.cs b/Content.Shared/Backmen/Surgery/SurgeryStepDamageEvent.cs new file mode 100644 index 00000000000..c8864acec89 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/SurgeryStepDamageEvent.cs @@ -0,0 +1,9 @@ +using Content.Shared.Damage; + +namespace Content.Shared.Backmen.Surgery; + +/// +/// Raised on the target entity. +/// +[ByRefEvent] +public record struct SurgeryStepDamageEvent(EntityUid User, EntityUid Body, EntityUid Part, EntityUid Surgery, DamageSpecifier Damage, float PartMultiplier); diff --git a/Content.Shared/Backmen/Surgery/SurgeryStepEvent.cs b/Content.Shared/Backmen/Surgery/SurgeryStepEvent.cs new file mode 100644 index 00000000000..bb986f683f4 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/SurgeryStepEvent.cs @@ -0,0 +1,7 @@ +namespace Content.Shared.Backmen.Surgery; + +/// +/// Raised on the step entity. +/// +[ByRefEvent] +public record struct SurgeryStepEvent(EntityUid User, EntityUid Body, EntityUid Part, List Tools, EntityUid Surgery); diff --git a/Content.Shared/Backmen/Surgery/SurgeryTargetComponent.cs b/Content.Shared/Backmen/Surgery/SurgeryTargetComponent.cs new file mode 100644 index 00000000000..bdfa6a11829 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/SurgeryTargetComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryTargetComponent : Component +{ + [DataField] + public bool CanOperate = true; +} diff --git a/Content.Shared/Backmen/Surgery/SurgeryUI.cs b/Content.Shared/Backmen/Surgery/SurgeryUI.cs new file mode 100644 index 00000000000..1e8320522a1 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/SurgeryUI.cs @@ -0,0 +1,27 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; + +namespace Content.Shared.Backmen.Surgery; + +[Serializable, NetSerializable] +public enum SurgeryUIKey +{ + Key +} + +[Serializable, NetSerializable] +public sealed class SurgeryBuiState(Dictionary> choices) : BoundUserInterfaceState +{ + public readonly Dictionary> Choices = choices; +} + +[Serializable, NetSerializable] +public sealed class SurgeryStepChosenBuiMsg(NetEntity part, EntProtoId surgery, EntProtoId step, bool isBody) : BoundUserInterfaceMessage +{ + public readonly NetEntity Part = part; + public readonly EntProtoId Surgery = surgery; + public readonly EntProtoId Step = step; + + // Used as a marker for whether or not we're hijacking surgery by applying it on the body itself. + public readonly bool IsBody = isBody; +} diff --git a/Content.Shared/Backmen/Surgery/Tools/BoneGelComponent.cs b/Content.Shared/Backmen/Surgery/Tools/BoneGelComponent.cs new file mode 100644 index 00000000000..0348852ad15 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Tools/BoneGelComponent.cs @@ -0,0 +1,11 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Tools; + +[RegisterComponent, NetworkedComponent] +public sealed partial class BoneGelComponent : Component, ISurgeryToolComponent +{ + public string ToolName => "bone gel"; + + public bool? Used { get; set; } = null; +} diff --git a/Content.Shared/Backmen/Surgery/Tools/BoneSawComponent.cs b/Content.Shared/Backmen/Surgery/Tools/BoneSawComponent.cs new file mode 100644 index 00000000000..17e9ab149c5 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Tools/BoneSawComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Tools; + +[RegisterComponent, NetworkedComponent] +public sealed partial class BoneSawComponent : Component, ISurgeryToolComponent +{ + public string ToolName => "a bone saw"; + public bool? Used { get; set; } = null; +} diff --git a/Content.Shared/Backmen/Surgery/Tools/BoneSetterComponent.cs b/Content.Shared/Backmen/Surgery/Tools/BoneSetterComponent.cs new file mode 100644 index 00000000000..7c71ff19100 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Tools/BoneSetterComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Tools; + +[RegisterComponent, NetworkedComponent] +public sealed partial class BoneSetterComponent : Component; diff --git a/Content.Shared/Backmen/Surgery/Tools/CauteryComponent.cs b/Content.Shared/Backmen/Surgery/Tools/CauteryComponent.cs new file mode 100644 index 00000000000..a4dc6ade3b5 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Tools/CauteryComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Tools; + +[RegisterComponent, NetworkedComponent] +public sealed partial class CauteryComponent : Component, ISurgeryToolComponent +{ + public string ToolName => "a cautery"; + public bool? Used { get; set; } = null; +} diff --git a/Content.Shared/Backmen/Surgery/Tools/HemostatComponent.cs b/Content.Shared/Backmen/Surgery/Tools/HemostatComponent.cs new file mode 100644 index 00000000000..c83c2bde510 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Tools/HemostatComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Tools; + +[RegisterComponent, NetworkedComponent] +public sealed partial class HemostatComponent : Component, ISurgeryToolComponent +{ + public string ToolName => "a hemostat"; + public bool? Used { get; set; } = null; +} diff --git a/Content.Shared/Backmen/Surgery/Tools/ISurgeryToolComponent.cs b/Content.Shared/Backmen/Surgery/Tools/ISurgeryToolComponent.cs new file mode 100644 index 00000000000..c61236dd303 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Tools/ISurgeryToolComponent.cs @@ -0,0 +1,11 @@ +namespace Content.Shared.Backmen.Surgery.Tools; + +public interface ISurgeryToolComponent +{ + [DataField] + public string ToolName { get; } + + // Mostly intended for discardable or non-reusable tools. + [DataField] + public bool? Used { get; set; } +} diff --git a/Content.Shared/Backmen/Surgery/Tools/RetractorComponent.cs b/Content.Shared/Backmen/Surgery/Tools/RetractorComponent.cs new file mode 100644 index 00000000000..49d917253dd --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Tools/RetractorComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Tools; + +[RegisterComponent, NetworkedComponent] +public sealed partial class RetractorComponent : Component, ISurgeryToolComponent +{ + public string ToolName => "a retractor"; + public bool? Used { get; set; } = null; +} diff --git a/Content.Shared/Backmen/Surgery/Tools/ScalpelComponent.cs b/Content.Shared/Backmen/Surgery/Tools/ScalpelComponent.cs new file mode 100644 index 00000000000..5d9e95c78fb --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Tools/ScalpelComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Tools; + +[RegisterComponent, NetworkedComponent] +public sealed partial class ScalpelComponent : Component, ISurgeryToolComponent +{ + public string ToolName => "a scalpel"; + public bool? Used { get; set; } = null; +} diff --git a/Content.Shared/Backmen/Surgery/Tools/SurgeryToolComponent.cs b/Content.Shared/Backmen/Surgery/Tools/SurgeryToolComponent.cs new file mode 100644 index 00000000000..3a4f65de1dc --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Tools/SurgeryToolComponent.cs @@ -0,0 +1,16 @@ +using Robust.Shared.Audio; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Backmen.Surgery.Tools; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class SurgeryToolComponent : Component +{ + + [DataField, AutoNetworkedField] + public SoundSpecifier? StartSound; + + [DataField, AutoNetworkedField] + public SoundSpecifier? EndSound; +} diff --git a/Content.Shared/Backmen/Surgery/Tools/SurgicalDrillComponent.cs b/Content.Shared/Backmen/Surgery/Tools/SurgicalDrillComponent.cs new file mode 100644 index 00000000000..75feb380326 --- /dev/null +++ b/Content.Shared/Backmen/Surgery/Tools/SurgicalDrillComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Backmen.Surgery.Tools; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgicalDrillComponent : Component, ISurgeryToolComponent +{ + public string ToolName => "a surgical drill"; + public bool? Used { get; set; } = null; +} diff --git a/Content.Shared/Backmen/Targeting/Events.cs b/Content.Shared/Backmen/Targeting/Events.cs new file mode 100644 index 00000000000..0de87477379 --- /dev/null +++ b/Content.Shared/Backmen/Targeting/Events.cs @@ -0,0 +1,38 @@ +using Content.Shared.Targeting; +using Robust.Shared.Serialization; + +namespace Content.Shared.Targeting.Events; + +[Serializable, NetSerializable] +public sealed class TargetChangeEvent : EntityEventArgs +{ + public NetEntity Uid { get; } + public TargetBodyPart BodyPart { get; } + public TargetChangeEvent(NetEntity uid, TargetBodyPart bodyPart) + { + Uid = uid; + BodyPart = bodyPart; + } +} + +[Serializable, NetSerializable] +public sealed class TargetIntegrityChangeEvent : EntityEventArgs +{ + public NetEntity Uid { get; } + public bool RefreshUi { get; } + public TargetIntegrityChangeEvent(NetEntity uid, bool refreshUi = true) + { + Uid = uid; + RefreshUi = refreshUi; + } +} + +public sealed class RefreshInventorySlotsEvent : EntityEventArgs +{ + public string SlotName { get; } + + public RefreshInventorySlotsEvent(string slotName) + { + SlotName = slotName; + } +} \ No newline at end of file diff --git a/Content.Shared/Backmen/Targeting/SharedTargetingSystem.cs b/Content.Shared/Backmen/Targeting/SharedTargetingSystem.cs new file mode 100644 index 00000000000..9d79622da6f --- /dev/null +++ b/Content.Shared/Backmen/Targeting/SharedTargetingSystem.cs @@ -0,0 +1,10 @@ +namespace Content.Shared.Targeting; +public abstract class SharedTargetingSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + } + + +} \ No newline at end of file diff --git a/Content.Shared/Backmen/Targeting/TargetBodyPart.cs b/Content.Shared/Backmen/Targeting/TargetBodyPart.cs new file mode 100644 index 00000000000..06082357142 --- /dev/null +++ b/Content.Shared/Backmen/Targeting/TargetBodyPart.cs @@ -0,0 +1,10 @@ +namespace Content.Shared.Targeting; +public enum TargetBodyPart +{ + Head, + Torso, + LeftArm, + RightArm, + LeftLeg, + RightLeg +} \ No newline at end of file diff --git a/Content.Shared/Backmen/Targeting/TargetIntegrity.cs b/Content.Shared/Backmen/Targeting/TargetIntegrity.cs new file mode 100644 index 00000000000..9b4515fcfae --- /dev/null +++ b/Content.Shared/Backmen/Targeting/TargetIntegrity.cs @@ -0,0 +1,13 @@ +namespace Content.Shared.Targeting; +public enum TargetIntegrity +{ + Healthy = 0, + LightlyWounded = 1, + SomewhatWounded = 2, + ModeratelyWounded = 3, + HeavilyWounded = 4, + CriticallyWounded = 5, + Severed = 6, + Dead = 7, + Disabled = 8, +} \ No newline at end of file diff --git a/Content.Shared/Backmen/Targeting/TargetingComponent.cs b/Content.Shared/Backmen/Targeting/TargetingComponent.cs new file mode 100644 index 00000000000..8a1cd97853e --- /dev/null +++ b/Content.Shared/Backmen/Targeting/TargetingComponent.cs @@ -0,0 +1,49 @@ +using Robust.Shared.Audio; +using Robust.Shared.GameObjects; +using Robust.Shared.GameStates; + +namespace Content.Shared.Targeting; + +/// +/// Controls entity limb targeting for actions. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class TargetingComponent : Component +{ + [ViewVariables, AutoNetworkedField] + public TargetBodyPart Target = TargetBodyPart.Torso; + + /// + /// What odds does the entity have of targeting each body part? + /// + [DataField] + public Dictionary TargetOdds = new() + { + { TargetBodyPart.Head, 0.1f }, + { TargetBodyPart.Torso, 0.4f }, + { TargetBodyPart.LeftArm, 0.125f }, + { TargetBodyPart.RightArm, 0.125f }, + { TargetBodyPart.LeftLeg, 0.125f }, + { TargetBodyPart.RightLeg, 0.125f } + }; + + /// + /// What is the current integrity of each body part? + /// + [ViewVariables, AutoNetworkedField] + public Dictionary BodyStatus = new() + { + { TargetBodyPart.Head, TargetIntegrity.Healthy }, + { TargetBodyPart.Torso, TargetIntegrity.Healthy }, + { TargetBodyPart.LeftArm, TargetIntegrity.Healthy }, + { TargetBodyPart.RightArm, TargetIntegrity.Healthy }, + { TargetBodyPart.LeftLeg, TargetIntegrity.Healthy }, + { TargetBodyPart.RightLeg, TargetIntegrity.Healthy } + }; + + /// + /// What noise does the entity play when swapping targets? + /// + [DataField] + public string SwapSound = "/Audio/Effects/toggleoncombat.ogg"; +} \ No newline at end of file diff --git a/Content.Shared/Body/Organ/OrganComponent.cs b/Content.Shared/Body/Organ/OrganComponent.cs index 3048927b5fb..67442312cd3 100644 --- a/Content.Shared/Body/Organ/OrganComponent.cs +++ b/Content.Shared/Body/Organ/OrganComponent.cs @@ -1,16 +1,33 @@ +using Content.Shared.Backmen.Surgery.Tools; using Content.Shared.Body.Systems; -using Robust.Shared.Containers; using Robust.Shared.GameStates; namespace Content.Shared.Body.Organ; [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedBodySystem))] -public sealed partial class OrganComponent : Component +public sealed partial class OrganComponent : Component, ISurgeryToolComponent { /// /// Relevant body this organ is attached to. /// [DataField, AutoNetworkedField] public EntityUid? Body; + + /// + /// Shitcodey solution to not being able to know what name corresponds to each organ's slot ID + /// without referencing the prototype or hardcoding. + /// + + [DataField] + public string SlotId = ""; + + [DataField] + public string ToolName { get; set; } = "An organ"; + + /// + /// If true, the organ will not heal an entity when transplanted into them. + /// + [DataField, AutoNetworkedField] + public bool? Used { get; set; } = false; } diff --git a/Content.Shared/Body/Part/BodyPartComponent.cs b/Content.Shared/Body/Part/BodyPartComponent.cs index c4e65c06a3f..ff78d3a88fe 100644 --- a/Content.Shared/Body/Part/BodyPartComponent.cs +++ b/Content.Shared/Body/Part/BodyPartComponent.cs @@ -1,4 +1,6 @@ -using Content.Shared.Body.Components; +using Content.Shared.Backmen.Surgery.Tools; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Body.Components; using Content.Shared.Body.Systems; using Robust.Shared.Containers; using Robust.Shared.GameStates; @@ -8,7 +10,7 @@ namespace Content.Shared.Body.Part; [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedBodySystem))] -public sealed partial class BodyPartComponent : Component +public sealed partial class BodyPartComponent : Component, ISurgeryToolComponent { // Need to set this on container changes as it may be several transform parents up the hierarchy. /// @@ -17,6 +19,12 @@ public sealed partial class BodyPartComponent : Component [DataField, AutoNetworkedField] public EntityUid? Body; + [DataField, AutoNetworkedField] + public EntityUid? OriginalBody; + + [DataField, AutoNetworkedField] + public BodyPartSlot? ParentSlot; + [DataField, AutoNetworkedField] public BodyPartType PartType = BodyPartType.Other; @@ -31,6 +39,12 @@ public sealed partial class BodyPartComponent : Component [DataField, AutoNetworkedField] public BodyPartSymmetry Symmetry = BodyPartSymmetry.None; + [DataField] + public string ToolName { get; set; } = "A body part"; + + [DataField, AutoNetworkedField] + public bool? Used { get; set; } = null; + /// /// Child body parts attached to this body part. /// @@ -43,6 +57,41 @@ public sealed partial class BodyPartComponent : Component [DataField, AutoNetworkedField] public Dictionary Organs = new(); + /// + /// How much health the body part has until it pops out. + /// + [DataField, AutoNetworkedField] + public float Integrity = 100f; + + /// + /// Whether this body part is enabled or not. + /// + [DataField, AutoNetworkedField] + public bool Enabled = true; + + /// + /// How long it takes to run another self heal tick on the body part. + /// + [DataField("healingTime")] + public float HealingTime = 30; + + /// + /// How long it has been since the last self heal tick on the body part. + /// + public float HealingTimer = 0; + + /// + /// How much health to heal on the body part per tick. + /// + [DataField("selfHealingAmount")] + public float SelfHealingAmount = 5; + + [DataField] + public string ContainerName { get; set; } = "part_slot"; + + [DataField, AutoNetworkedField] + public ItemSlot ItemInsertionSlot = new(); + /// /// These are only for VV/Debug do not use these for gameplay/systems /// diff --git a/Content.Shared/Body/Part/BodyPartEvents.cs b/Content.Shared/Body/Part/BodyPartEvents.cs index 0d8d2c8a268..f4444121e1d 100644 --- a/Content.Shared/Body/Part/BodyPartEvents.cs +++ b/Content.Shared/Body/Part/BodyPartEvents.cs @@ -5,3 +5,12 @@ namespace Content.Shared.Body.Part; [ByRefEvent] public readonly record struct BodyPartRemovedEvent(string Slot, Entity Part); + +[ByRefEvent] +public readonly record struct BodyPartEnableChangedEvent(bool Enabled); + +[ByRefEvent] +public readonly record struct BodyPartEnabledEvent(Entity Part); + +[ByRefEvent] +public readonly record struct BodyPartDisabledEvent(Entity Part); diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Body.cs b/Content.Shared/Body/Systems/SharedBodySystem.Body.cs index 250f90db8f3..fb59d99fa7c 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Body.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Body.cs @@ -4,16 +4,20 @@ using Content.Shared.Body.Organ; using Content.Shared.Body.Part; using Content.Shared.Body.Prototypes; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Damage; using Content.Shared.DragDrop; using Content.Shared.Gibbing.Components; using Content.Shared.Gibbing.Events; using Content.Shared.Gibbing.Systems; using Content.Shared.Inventory; +using Content.Shared.Standing; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Utility; +using Robust.Shared.Timing; namespace Content.Shared.Body.Systems; @@ -27,9 +31,10 @@ public partial class SharedBodySystem */ [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly ItemSlotsSystem _slots = default!; [Dependency] private readonly GibbingSystem _gibbingSystem = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!; - + [Dependency] private readonly IGameTiming _gameTiming = default!; private const float GibletLaunchImpulse = 8; private const float GibletLaunchImpulseVariance = 3; @@ -42,6 +47,8 @@ private void InitializeBody() SubscribeLocalEvent(OnBodyInit); SubscribeLocalEvent(OnBodyMapInit); SubscribeLocalEvent(OnBodyCanDrag); + SubscribeLocalEvent(OnDamageChanged); + SubscribeLocalEvent(OnStandAttempt); } private void OnBodyInserted(Entity ent, ref EntInsertedIntoContainerMessage args) @@ -116,7 +123,6 @@ private void MapInitBody(EntityUid bodyEntity, BodyPrototype prototype) var rootPart = Comp(rootPartUid); rootPart.Body = bodyEntity; Dirty(rootPartUid, rootPart); - // Setup the rest of the body entities. SetupOrgans((rootPartUid, rootPart), protoRoot.Organs); MapInitParts(rootPartUid, prototype); @@ -127,6 +133,32 @@ private void OnBodyCanDrag(Entity ent, ref CanDragEvent args) args.Handled = true; } + private void OnStandAttempt(Entity ent, ref StandAttemptEvent args) + { + if (ent.Comp.LegEntities.Count == 0) + args.Cancel(); + } + + private void OnDamageChanged(Entity ent, ref DamageChangedEvent args) + { + if (args.PartMultiplier == 0 + || ent.Comp is null + || args.TargetPart is null + || args.DamageDelta is null + || !args.DamageIncreased + && !args.DamageDecreased) + return; + + var (targetType, targetSymmetry) = ConvertTargetBodyPart(args.TargetPart.Value); + Logger.Debug($"Applying damage to {ToPrettyString(ent)} with {ent.Comp} and {args} {targetType} {targetSymmetry}"); + foreach (var part in GetBodyChildrenOfType(ent, targetType, ent.Comp) + .Where(part => part.Component.Symmetry == targetSymmetry)) + { + if (_gameTiming.IsFirstTimePredicted) + ApplyPartDamage(part, args.DamageDelta, targetType, args.TargetPart.Value, args.CanSever, args.PartMultiplier); + } + } + /// /// Sets up all of the relevant body parts for a particular body entity and root part. /// @@ -168,6 +200,7 @@ private void MapInitParts(EntityUid rootPartId, BodyPrototype prototype) var childPartComponent = Comp(childPart); var partSlot = CreatePartSlot(parentEntity, connection, childPartComponent.PartType, parentPartComponent); + childPartComponent.ParentSlot = partSlot; var cont = Containers.GetContainer(parentEntity, GetPartSlotContainerId(connection)); if (partSlot is null || !Containers.Insert(childPart, cont)) @@ -233,11 +266,11 @@ public IEnumerable GetBodyContainers( { if (id is null || !Resolve(id.Value, ref body, logMissing: false) + || body is null + || body.RootContainer == default || body.RootContainer.ContainedEntity is null || !Resolve(body.RootContainer.ContainedEntity.Value, ref rootPart)) - { yield break; - } foreach (var child in GetBodyPartChildren(body.RootContainer.ContainedEntity.Value, rootPart)) { @@ -309,8 +342,8 @@ public virtual HashSet GibBody( { _gibbingSystem.TryGibEntityWithRef(bodyId, part.Id, GibType.Gib, GibContentsOption.Skip, ref gibs, - playAudio: false, launchGibs:true, launchDirection:splatDirection, launchImpulse: GibletLaunchImpulse * splatModifier, - launchImpulseVariance:GibletLaunchImpulseVariance, launchCone: splatCone); + playAudio: false, launchGibs: true, launchDirection: splatDirection, launchImpulse: GibletLaunchImpulse * splatModifier, + launchImpulseVariance: GibletLaunchImpulseVariance, launchCone: splatCone); if (!gibOrgans) continue; @@ -319,7 +352,7 @@ public virtual HashSet GibBody( { _gibbingSystem.TryGibEntityWithRef(bodyId, organ.Id, GibType.Drop, GibContentsOption.Skip, ref gibs, playAudio: false, launchImpulse: GibletLaunchImpulse * splatModifier, - launchImpulseVariance:GibletLaunchImpulseVariance, launchCone: splatCone); + launchImpulseVariance: GibletLaunchImpulseVariance, launchCone: splatCone); } } @@ -335,4 +368,31 @@ public virtual HashSet GibBody( _audioSystem.PlayPredicted(gibSoundOverride, bodyTransform.Coordinates, null); return gibs; } + + public virtual HashSet GibPart( + EntityUid partId, + BodyPartComponent? part = null, + bool launchGibs = true, + Vector2? splatDirection = null, + float splatModifier = 1, + Angle splatCone = default, + SoundSpecifier? gibSoundOverride = null) + { + var gibs = new HashSet(); + + _gibbingSystem.TryGibEntityWithRef(partId, partId, GibType.Gib, GibContentsOption.Drop, ref gibs, + playAudio: true, launchGibs: true, launchDirection: splatDirection, launchImpulse: GibletLaunchImpulse * splatModifier, + launchImpulseVariance: GibletLaunchImpulseVariance, launchCone: splatCone); + + if (TryComp(partId, out var inventory)) + { + foreach (var item in _inventory.GetHandOrInventoryEntities(partId)) + { + SharedTransform.AttachToGridOrMap(item); + gibs.Add(item); + } + } + _audioSystem.PlayPredicted(gibSoundOverride, Transform(partId).Coordinates, null); + return gibs; + } } diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Organs.cs b/Content.Shared/Body/Systems/SharedBodySystem.Organs.cs index f83dd50c998..7511536de45 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Organs.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Organs.cs @@ -209,4 +209,15 @@ public bool TryGetBodyOrganEntityComps( comps = null; return false; } + + public bool TrySetOrganUsed(EntityUid organId, bool used, OrganComponent? organ = null) + { + if (!Resolve(organId, ref organ) + || organ.Used == true) + return false; + + organ.Used = true; + Dirty(organId, organ); + return true; + } } diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs b/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs index 0917197e29f..e105568327b 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs @@ -1,28 +1,57 @@ -using System.Diagnostics.CodeAnalysis; -using System.Linq; using Content.Shared.Body.Components; using Content.Shared.Body.Events; using Content.Shared.Body.Organ; using Content.Shared.Body.Part; using Content.Shared.Damage; using Content.Shared.Damage.Prototypes; +using Content.Shared.Hands.Components; +using Content.Shared.Hands.EntitySystems; +using Content.Shared.Inventory; using Content.Shared.Movement.Components; +using Content.Shared.Random; +using Content.Shared.Targeting.Events; using Robust.Shared.Containers; using Robust.Shared.Utility; +using System.Diagnostics.CodeAnalysis; +using System.Linq; namespace Content.Shared.Body.Systems; public partial class SharedBodySystem { + [Dependency] private readonly SharedContainerSystem _containerSystem = default!; + [Dependency] private readonly SharedHandsSystem _handsSystem = default!; + [Dependency] private readonly RandomHelperSystem _randomHelper = default!; + [Dependency] private readonly InventorySystem _inventorySystem = default!; private void InitializeParts() { // TODO: This doesn't handle comp removal on child ents. // If you modify this also see the Body partial for root parts. + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnBodyPartRemove); SubscribeLocalEvent(OnBodyPartInserted); SubscribeLocalEvent(OnBodyPartRemoved); + SubscribeLocalEvent(OnAmputateAttempt); + SubscribeLocalEvent(OnPartEnableChanged); } + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + if (ent.Comp.PartType == BodyPartType.Torso) + { + _slots.AddItemSlot(ent, ent.Comp.ContainerName, ent.Comp.ItemInsertionSlot); + Dirty(ent, ent.Comp); + } + } + + private void OnBodyPartRemove(Entity ent, ref ComponentRemove args) + { + if (ent.Comp.PartType == BodyPartType.Torso) + { + _slots.RemoveItemSlot(ent, ent.Comp.ItemInsertionSlot); + } + } private void OnBodyPartInserted(Entity ent, ref EntInsertedIntoContainerMessage args) { // Body part inserted into another body part. @@ -47,7 +76,6 @@ private void OnBodyPartRemoved(Entity ent, ref EntRemovedFrom // Body part removed from another body part. var removedUid = args.Entity; var slotId = args.Container.ID; - DebugTools.Assert(!TryComp(removedUid, out BodyPartComponent? b) || b.Body == ent.Comp.Body); DebugTools.Assert(!TryComp(removedUid, out OrganComponent? o) || o.Body == ent.Comp.Body); @@ -93,6 +121,8 @@ private void RecursiveBodyUpdate(Entity ent, EntityUid? bodyU } } + // The code for RemovePartEffect() should live here, because it literally is the point of this recursive function. + // But the debug asserts at the top plus existing tests need refactoring for this. So we'll be lazy. foreach (var slotId in ent.Comp.Children.Keys) { if (!Containers.TryGetContainer(ent, GetPartSlotContainerId(slotId), out var container)) @@ -127,15 +157,48 @@ protected virtual void RemovePart( { Resolve(bodyEnt, ref bodyEnt.Comp, logMissing: false); Dirty(partEnt, partEnt.Comp); - partEnt.Comp.Body = null; + partEnt.Comp.ParentSlot = null; + partEnt.Comp.OriginalBody = partEnt.Comp.Body; var ev = new BodyPartRemovedEvent(slotId, partEnt); RaiseLocalEvent(bodyEnt, ref ev); - - RemoveLeg(partEnt, bodyEnt); + //RemoveLeg(partEnt, bodyEnt); + RemovePartEffect(partEnt, bodyEnt); PartRemoveDamage(bodyEnt, partEnt); } + protected virtual void DropPart(Entity partEnt) + { + // We check for whether or not the arm, leg or head is being dropped, in which case + // If theres just one, that means we'll remove the container slots. + if (partEnt.Comp.Body is not null + && TryGetPartSlotContainerName(partEnt.Comp.PartType, out var containerNames) + && GetBodyPartCount(partEnt.Comp.Body.Value, partEnt.Comp.PartType) == 1) + { + foreach (var containerName in containerNames) + { + _inventorySystem.SetSlotStatus(partEnt.Comp.Body.Value, containerName, true); + var ev = new RefreshInventorySlotsEvent(containerName); + RaiseLocalEvent(partEnt.Comp.Body.Value, ev); + } + } + + // We then detach the part, which will kickstart EntRemovedFromContainer events. + if (TryComp(partEnt, out TransformComponent? transform) && _gameTiming.IsFirstTimePredicted) + { + var ev = new BodyPartEnableChangedEvent(false); + RaiseLocalEvent(partEnt, ref ev); + SharedTransform.AttachToGridOrMap(partEnt, transform); + _randomHelper.RandomOffset(partEnt, 0.5f); + } + + } + + private void OnAmputateAttempt(Entity partEnt, ref AmputateAttemptEvent args) + { + DropPart(partEnt); + } + private void AddLeg(Entity legEnt, Entity bodyEnt) { if (!Resolve(bodyEnt, ref bodyEnt.Comp, logMissing: false)) @@ -159,12 +222,33 @@ private void RemoveLeg(Entity legEnt, Entity bodyEnt.Comp.LegEntities.Remove(legEnt); UpdateMovementSpeed(bodyEnt); Dirty(bodyEnt, bodyEnt.Comp); + Standing.Down(bodyEnt); + } + } + + // TODO: Refactor this crap. + private void RemovePartEffect(Entity partEnt, Entity bodyEnt) + { + if (!Resolve(bodyEnt, ref bodyEnt.Comp, logMissing: false)) + return; - if (!bodyEnt.Comp.LegEntities.Any()) + if (partEnt.Comp.Children.Any()) + { + foreach (var slotId in partEnt.Comp.Children.Keys) { - Standing.Down(bodyEnt); - } + if (Containers.TryGetContainer(partEnt, GetPartSlotContainerId(slotId), out var container) && + container is ContainerSlot slot && + slot.ContainedEntity is { } childEntity && + TryComp(childEntity, out BodyPartComponent? childPart)) + { + var ev = new BodyPartEnableChangedEvent(false); + RaiseLocalEvent(childEntity, ref ev); + DropPart((childEntity, childPart)); + } + }; + Dirty(bodyEnt, bodyEnt.Comp); } + } private void PartRemoveDamage(Entity bodyEnt, Entity partEnt) @@ -177,12 +261,77 @@ private void PartRemoveDamage(Entity bodyEnt, Entity("Bloodloss"), 300); Damageable.TryChangeDamage(bodyEnt, damage); } } + private void OnPartEnableChanged(Entity partEnt, ref BodyPartEnableChangedEvent args) + { + partEnt.Comp.Enabled = args.Enabled; + Dirty(partEnt, partEnt.Comp); + + if (args.Enabled) + EnablePart(partEnt); + else + DisablePart(partEnt); + } + + private void EnablePart(Entity partEnt) + { + if (!TryComp(partEnt.Comp.Body, out BodyComponent? body)) + return; + + // I hate having to hardcode these checks so much. + if (partEnt.Comp.PartType == BodyPartType.Leg) + { + AddLeg(partEnt, (partEnt.Comp.Body.Value, body)); + } + + if (partEnt.Comp.PartType == BodyPartType.Arm) + { + var hand = GetBodyChildrenOfType(partEnt.Comp.Body.Value, BodyPartType.Hand, symmetry: partEnt.Comp.Symmetry).FirstOrDefault(); + if (hand != default) + { + var ev = new BodyPartEnabledEvent(hand); + RaiseLocalEvent(partEnt.Comp.Body.Value, ref ev); + } + } + + if (partEnt.Comp.PartType == BodyPartType.Hand) + { + var ev = new BodyPartEnabledEvent(partEnt); + RaiseLocalEvent(partEnt.Comp.Body.Value, ref ev); + } + } + + private void DisablePart(Entity partEnt) + { + if (!TryComp(partEnt.Comp.Body, out BodyComponent? body)) + return; + + if (partEnt.Comp.PartType == BodyPartType.Leg) + { + RemoveLeg(partEnt, (partEnt.Comp.Body.Value, body)); + } + + if (partEnt.Comp.PartType == BodyPartType.Arm) + { + var hand = GetBodyChildrenOfType(partEnt.Comp.Body.Value, BodyPartType.Hand, symmetry: partEnt.Comp.Symmetry).FirstOrDefault(); + if (hand != default) + { + var ev = new BodyPartDisabledEvent(hand); + RaiseLocalEvent(partEnt.Comp.Body.Value, ref ev); + } + } + + if (partEnt.Comp.PartType == BodyPartType.Hand) + { + var ev = new BodyPartDisabledEvent(partEnt); + RaiseLocalEvent(partEnt.Comp.Body.Value, ref ev); + } + } + /// /// Tries to get the parent body part to this if applicable. /// Doesn't validate if it's a part of body system. @@ -438,12 +587,14 @@ public bool AttachPart( return false; } + if (!Containers.TryGetContainer(parentPartId, GetPartSlotContainerId(slot.Id), out var container)) { DebugTools.Assert($"Unable to find body slot {slot.Id} for {ToPrettyString(parentPartId)}"); return false; } + part.ParentSlot = slot; return Containers.Insert(partId, container); } @@ -656,11 +807,12 @@ public bool BodyHasChild( public IEnumerable<(EntityUid Id, BodyPartComponent Component)> GetBodyChildrenOfType( EntityUid bodyId, BodyPartType type, - BodyComponent? body = null) + BodyComponent? body = null, + BodyPartSymmetry? symmetry = null) { foreach (var part in GetBodyChildren(bodyId, body)) { - if (part.Component.PartType == type) + if (part.Component.PartType == type && (symmetry == null || part.Component.Symmetry == symmetry)) yield return part; } } @@ -722,6 +874,48 @@ public bool TryGetBodyPartOrganComponents( return false; } + /// + /// Tries to get a list of ValueTuples of EntityUid and OrganComponent on each organ + /// in the given part. + /// + /// The part entity id to check on. + /// The type of component to check for. + /// The part to check for organs on. + /// Whether any were found. + /// + /// This method is somewhat of a copout to the fact that we can't use reflection to generically + /// get the type of a component on runtime due to sandboxing. So we simply do a HasComp check for each organ. + /// + public bool TryGetBodyPartOrgans( + EntityUid uid, + Type type, + [NotNullWhen(true)] out List<(EntityUid Id, OrganComponent Organ)>? organs, + BodyPartComponent? part = null) + { + if (!Resolve(uid, ref part)) + { + organs = null; + return false; + } + + var list = new List<(EntityUid Id, OrganComponent Organ)>(); + + foreach (var organ in GetPartOrgans(uid, part)) + { + if (HasComp(organ.Id, type)) + list.Add((organ.Id, organ.Component)); + } + + if (list.Count != 0) + { + organs = list; + return true; + } + + organs = null; + return false; + } + /// /// Gets the parent body part and all immediate child body parts for the partId. /// @@ -790,5 +984,31 @@ public bool TryGetBodyPartAdjacentPartsComponents( return false; } + private bool TryGetPartSlotContainerName(BodyPartType partType, out HashSet containerNames) + { + containerNames = partType switch + { + BodyPartType.Arm => new() { "gloves" }, + BodyPartType.Leg => new() { "shoes" }, + BodyPartType.Head => new() { "eyes", "ears", "head", "mask" }, + _ => new() + }; + return containerNames.Count > 0; + } + + public int GetBodyPartCount(EntityUid bodyId, BodyPartType partType, BodyComponent? body = null) + { + if (!Resolve(bodyId, ref body, logMissing: false)) + return 0; + + int count = 0; + foreach (var part in GetBodyChildren(bodyId, body)) + { + if (part.Component.PartType == partType) + count++; + } + return count; + } + #endregion } diff --git a/Content.Shared/Body/Systems/SharedBodySystem.cs b/Content.Shared/Body/Systems/SharedBodySystem.cs index a45966fcc37..2238224a80c 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.cs @@ -28,7 +28,7 @@ public abstract partial class SharedBodySystem : EntitySystem /// public const string OrganSlotContainerIdPrefix = "body_organ_slot_"; - [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IGameTiming _timing = default!; [Dependency] protected readonly IPrototypeManager Prototypes = default!; [Dependency] protected readonly DamageableSystem Damageable = default!; [Dependency] protected readonly MovementSpeedModifierSystem Movement = default!; diff --git a/Content.Shared/Damage/Systems/DamageableSystem.cs b/Content.Shared/Damage/Systems/DamageableSystem.cs index 3c3e1b736df..da85d7a5f52 100644 --- a/Content.Shared/Damage/Systems/DamageableSystem.cs +++ b/Content.Shared/Damage/Systems/DamageableSystem.cs @@ -7,9 +7,11 @@ using Content.Shared.Mobs.Systems; using Content.Shared.Radiation.Events; using Content.Shared.Rejuvenate; +using Content.Shared.Targeting; using Robust.Shared.GameStates; using Robust.Shared.Network; using Robust.Shared.Prototypes; +using Robust.Shared.Random; using Robust.Shared.Utility; namespace Content.Shared.Damage @@ -20,7 +22,7 @@ public sealed class DamageableSystem : EntitySystem [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly INetManager _netMan = default!; [Dependency] private readonly MobThresholdSystem _mobThreshold = default!; - + [Dependency] private readonly IRobustRandom _random = default!; private EntityQuery _appearanceQuery; private EntityQuery _damageableQuery; private EntityQuery _mindContainerQuery; @@ -97,10 +99,26 @@ public void SetDamage(EntityUid uid, DamageableComponent damageable, DamageSpeci /// The damage changed event is used by other systems, such as damage thresholds. /// public void DamageChanged(EntityUid uid, DamageableComponent component, DamageSpecifier? damageDelta = null, - bool interruptsDoAfters = true, EntityUid? origin = null) + bool interruptsDoAfters = true, EntityUid? origin = null, bool canSever = true, float partMultiplier = 1.00f) { + TargetBodyPart? targetPart = null; component.Damage.GetDamagePerGroup(_prototypeManager, component.DamagePerGroup); component.TotalDamage = component.Damage.GetTotal(); + // If our target has a TargetingComponent, that means they will take limb damage + // And if their attacker also has one, then we use that part. + if (TryComp(uid, out var target)) + { + if (origin.HasValue && TryComp(origin.Value, out var targeter)) + { + targetPart = targeter.Target; + } + else + { + targetPart = GetRandomBodyPart(uid, target); + } + } + + Dirty(uid, component); if (_appearanceQuery.TryGetComponent(uid, out var appearance) && damageDelta != null) @@ -108,7 +126,7 @@ public void DamageChanged(EntityUid uid, DamageableComponent component, DamageSp var data = new DamageVisualizerGroupData(component.DamagePerGroup.Keys.ToList()); _appearance.SetData(uid, DamageVisualizerKeys.DamageUpdateGroups, data, appearance); } - RaiseLocalEvent(uid, new DamageChangedEvent(component, damageDelta, interruptsDoAfters, origin)); + RaiseLocalEvent(uid, new DamageChangedEvent(component, damageDelta, interruptsDoAfters, origin, targetPart, canSever, partMultiplier)); } /// @@ -124,7 +142,8 @@ public void DamageChanged(EntityUid uid, DamageableComponent component, DamageSp /// null if the user had no applicable components that can take damage. /// public DamageSpecifier? TryChangeDamage(EntityUid? uid, DamageSpecifier damage, bool ignoreResistances = false, - bool interruptsDoAfters = true, DamageableComponent? damageable = null, EntityUid? origin = null) + bool interruptsDoAfters = true, DamageableComponent? damageable = null, EntityUid? origin = null, + bool? canSever = true, float? partMultiplier = 1.00f) { if (!uid.HasValue || !_damageableQuery.Resolve(uid.Value, ref damageable, false)) { @@ -153,7 +172,6 @@ public void DamageChanged(EntityUid uid, DamageableComponent component, DamageSp // use a local private field instead of creating a new dictionary here.. damage = DamageSpecifier.ApplyModifierSet(damage, modifierSet); } - var ev = new DamageModifyEvent(damage, origin); RaiseLocalEvent(uid.Value, ev); damage = ev.Damage; @@ -186,7 +204,7 @@ public void DamageChanged(EntityUid uid, DamageableComponent component, DamageSp } if (delta.DamageDict.Count > 0) - DamageChanged(uid.Value, damageable, delta, interruptsDoAfters, origin); + DamageChanged(uid.Value, damageable, delta, interruptsDoAfters, origin, canSever ?? true, partMultiplier ?? 1.00f); return delta; } @@ -280,6 +298,24 @@ private void DamageableHandleState(EntityUid uid, DamageableComponent component, DamageChanged(uid, component, delta); } } + + public TargetBodyPart? GetRandomBodyPart(EntityUid uid, TargetingComponent? target = null) + { + if (!Resolve(uid, ref target)) + return null; + + var totalWeight = target.TargetOdds.Values.Sum(); + var randomValue = _random.NextFloat() * totalWeight; + + foreach (var (part, weight) in target.TargetOdds) + { + if (randomValue <= weight) + return part; + randomValue -= weight; + } + + return TargetBodyPart.Torso; // Default to torso if something goes wrong + } } /// @@ -331,10 +367,15 @@ public sealed class DamageChangedEvent : EntityEventArgs public readonly DamageSpecifier? DamageDelta; /// - /// Was any of the damage change dealing damage, or was it all healing? + /// Was any of the change dealing damage? /// public readonly bool DamageIncreased; + /// + /// Was any of the change healing? + /// + public readonly bool DamageDecreased; + /// /// Does this event interrupt DoAfters? /// Note: As provided in the constructor, this *does not* account for DamageIncreased. @@ -347,12 +388,30 @@ public sealed class DamageChangedEvent : EntityEventArgs /// public readonly EntityUid? Origin; - public DamageChangedEvent(DamageableComponent damageable, DamageSpecifier? damageDelta, bool interruptsDoAfters, EntityUid? origin) + /// + /// How much do we multiply this damage by for part damage? + /// + public readonly float PartMultiplier; + + /// + /// Can this damage event sever parts? + /// + public readonly bool CanSever; + + /// + /// What part of this entity is going to take damage? + /// + public readonly TargetBodyPart? TargetPart; + + public DamageChangedEvent(DamageableComponent damageable, DamageSpecifier? damageDelta, bool interruptsDoAfters, + EntityUid? origin, TargetBodyPart? targetPart = null, bool canSever = true, float partMultiplier = 1.00f) { Damageable = damageable; DamageDelta = damageDelta; Origin = origin; - + TargetPart = targetPart; + CanSever = canSever; + PartMultiplier = partMultiplier; if (DamageDelta == null) return; @@ -363,6 +422,11 @@ public DamageChangedEvent(DamageableComponent damageable, DamageSpecifier? damag DamageIncreased = true; break; } + else if (damageChange < 0) + { + DamageDecreased = true; + break; + } } InterruptsDoAfters = interruptsDoAfters && DamageIncreased; } diff --git a/Content.Shared/Hands/Components/HandsComponent.cs b/Content.Shared/Hands/Components/HandsComponent.cs index f218455c0bb..318f9f512e9 100644 --- a/Content.Shared/Hands/Components/HandsComponent.cs +++ b/Content.Shared/Hands/Components/HandsComponent.cs @@ -30,6 +30,7 @@ public sealed partial class HandsComponent : Component /// /// List of hand-names. These are keys for . The order of this list determines the order in which hands are iterated over. /// + [ViewVariables] public List SortedHands = new(); /// diff --git a/Content.Shared/Input/ContentKeyFunctions.cs b/Content.Shared/Input/ContentKeyFunctions.cs index 863d9da970f..46f8afe4cd5 100644 --- a/Content.Shared/Input/ContentKeyFunctions.cs +++ b/Content.Shared/Input/ContentKeyFunctions.cs @@ -59,6 +59,12 @@ public static class ContentKeyFunctions public static readonly BoundKeyFunction ZoomOut = "ZoomOut"; public static readonly BoundKeyFunction ZoomIn = "ZoomIn"; public static readonly BoundKeyFunction ResetZoom = "ResetZoom"; + public static readonly BoundKeyFunction TargetHead = "TargetHead"; + public static readonly BoundKeyFunction TargetTorso = "TargetTorso"; + public static readonly BoundKeyFunction TargetLeftArm = "TargetLeftArm"; + public static readonly BoundKeyFunction TargetRightArm = "TargetRightArm"; + public static readonly BoundKeyFunction TargetLeftLeg = "TargetLeftLeg"; + public static readonly BoundKeyFunction TargetRightLeg = "TargetRightLeg"; public static readonly BoundKeyFunction ArcadeUp = "ArcadeUp"; public static readonly BoundKeyFunction ArcadeDown = "ArcadeDown"; diff --git a/Content.Shared/Inventory/InventoryComponent.cs b/Content.Shared/Inventory/InventoryComponent.cs index 629cf1169c4..db761ad693b 100644 --- a/Content.Shared/Inventory/InventoryComponent.cs +++ b/Content.Shared/Inventory/InventoryComponent.cs @@ -15,6 +15,7 @@ public sealed partial class InventoryComponent : Component [DataField("speciesId")] public string? SpeciesId { get; set; } public SlotDefinition[] Slots = Array.Empty(); + public ContainerSlot[] Containers = Array.Empty(); [DataField] diff --git a/Content.Shared/Inventory/InventorySystem.Slots.cs b/Content.Shared/Inventory/InventorySystem.Slots.cs index 2522dd5d0a3..dbaea2a5ec3 100644 --- a/Content.Shared/Inventory/InventorySystem.Slots.cs +++ b/Content.Shared/Inventory/InventorySystem.Slots.cs @@ -1,17 +1,19 @@ using System.Diagnostics.CodeAnalysis; using Content.Shared.Inventory.Events; using Content.Shared.Storage; +using Content.Shared.Random; using Robust.Shared.Containers; using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.Manager; using Robust.Shared.Utility; namespace Content.Shared.Inventory; - public partial class InventorySystem : EntitySystem { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IViewVariablesManager _vvm = default!; - + [Dependency] private readonly RandomHelperSystem _randomHelper = default!; + [Dependency] private readonly ISerializationManager _serializationManager = default!; private void InitializeSlots() { SubscribeLocalEvent(OnInit); @@ -57,7 +59,8 @@ protected virtual void OnInit(EntityUid uid, InventoryComponent component, Compo if (!_prototypeManager.TryIndex(component.TemplateId, out InventoryTemplatePrototype? invTemplate)) return; - component.Slots = invTemplate.Slots; + _serializationManager.CopyTo(invTemplate.Slots, ref component.Slots, notNullableOverride: true); + component.Containers = new ContainerSlot[component.Slots.Length]; for (var i = 0; i < component.Containers.Length; i++) { @@ -115,7 +118,7 @@ public bool TryGetSlot(EntityUid uid, string slot, [NotNullWhen(true)] out SlotD foreach (var slotDef in inventory.Slots) { - if (!slotDef.Name.Equals(slot)) + if (!slotDef.Name.Equals(slot) || slotDef.Disabled) continue; slotDefinition = slotDef; return true; @@ -170,6 +173,39 @@ private IEnumerable ListViewVariablesSlots(EntityUid uid, InventoryCompo } } + public void SetSlotStatus(EntityUid uid, string slotName, bool isDisabled, InventoryComponent? inventory = null) + { + if (!Resolve(uid, ref inventory)) + return; + + foreach (var slot in inventory.Slots) + { + if (slot.Name != slotName) + continue; + + + if (!TryGetSlotContainer(uid, slotName, out var container, out _, inventory)) + break; + + if (isDisabled) + { + if (container.ContainedEntity is { } entityUid && TryComp(entityUid, out TransformComponent? transform) && _gameTiming.IsFirstTimePredicted) + { + _transform.AttachToGridOrMap(entityUid, transform); + _randomHelper.RandomOffset(entityUid, 0.5f); + } + _containerSystem.ShutdownContainer(container); + } + else + _containerSystem.EnsureContainer(uid, slotName); + + slot.Disabled = isDisabled; + break; + } + + Dirty(uid, inventory); + } + /// /// Enumerator for iterating over an inventory's slot containers. Also has methods that skip empty containers. /// It should be safe to add or remove items while enumerating. @@ -203,7 +239,7 @@ public bool MoveNext([NotNullWhen(true)] out ContainerSlot? container) var i = _nextIdx++; var slot = _slots[i]; - if ((slot.SlotFlags & _flags) == 0) + if ((slot.SlotFlags & _flags) == 0 || slot.Disabled) continue; container = _containers[i]; @@ -221,7 +257,7 @@ public bool NextItem(out EntityUid item) var i = _nextIdx++; var slot = _slots[i]; - if ((slot.SlotFlags & _flags) == 0) + if ((slot.SlotFlags & _flags) == 0 || slot.Disabled) continue; var container = _containers[i]; diff --git a/Content.Shared/Inventory/InventoryTemplatePrototype.cs b/Content.Shared/Inventory/InventoryTemplatePrototype.cs index a4d77767e37..cc70a842314 100644 --- a/Content.Shared/Inventory/InventoryTemplatePrototype.cs +++ b/Content.Shared/Inventory/InventoryTemplatePrototype.cs @@ -55,4 +55,9 @@ public sealed partial class SlotDefinition /// Entity blacklist for CanEquip checks. /// [DataField("blacklist")] public EntityWhitelist? Blacklist = null; + + /// + /// Is this slot disabled? Could be due to severing or other reasons. + /// + [DataField("disabled")] public bool Disabled = false; } diff --git a/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs b/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs index 212c03475cf..df158d52c3f 100644 --- a/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs +++ b/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs @@ -90,6 +90,12 @@ public sealed partial class MeleeWeaponComponent : Component [ViewVariables(VVAccess.ReadWrite), DataField] public FixedPoint2 ClickDamageModifier = FixedPoint2.New(1); + /// + /// Part damage is multiplied by this amount for single-target attacks + /// + [DataField, AutoNetworkedField] + public float ClickPartDamageMultiplier = 1.00f; + // TODO: Temporarily 1.5 until interactionoutline is adjusted to use melee, then probably drop to 1.2 /// /// Nearest edge range to hit an entity. @@ -97,6 +103,24 @@ public sealed partial class MeleeWeaponComponent : Component [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] public float Range = 1.5f; + /// + /// Attack range for heavy swings + /// + [DataField, AutoNetworkedField] + public float HeavyRangeModifier = 1f; + + /// + /// Weapon damage is multiplied by this amount for heavy swings + /// + [DataField, AutoNetworkedField] + public float HeavyDamageBaseModifier = 1.2f; + + /// + /// Part damage is multiplied by this amount for heavy swings + /// + [DataField, AutoNetworkedField] + public float HeavyPartDamageMultiplier = 0.5f; + /// /// Total width of the angle for wide attacks. /// diff --git a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs index bc19235cd39..872458ef110 100644 --- a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs +++ b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs @@ -509,7 +509,7 @@ protected virtual void DoLightAttack(EntityUid user, LightAttackEvent ev, Entity RaiseLocalEvent(target.Value, attackedEvent); var modifiedDamage = DamageSpecifier.ApplyModifierSets(damage + hitEvent.BonusDamage + attackedEvent.BonusDamage, hitEvent.ModifiersList); - var damageResult = Damageable.TryChangeDamage(target, modifiedDamage, origin:user, ignoreResistances:resistanceBypass); + var damageResult = Damageable.TryChangeDamage(target, modifiedDamage, origin: user, ignoreResistances:resistanceBypass, partMultiplier: component.ClickPartDamageMultiplier); if (damageResult is {Empty: false}) { @@ -654,7 +654,7 @@ private bool DoHeavyAttack(EntityUid user, HeavyAttackEvent ev, EntityUid meleeU RaiseLocalEvent(entity, attackedEvent); var modifiedDamage = DamageSpecifier.ApplyModifierSets(damage + hitEvent.BonusDamage + attackedEvent.BonusDamage, hitEvent.ModifiersList); - var damageResult = Damageable.TryChangeDamage(entity, modifiedDamage, origin:user); + var damageResult = Damageable.TryChangeDamage(entity, modifiedDamage, origin: user, partMultiplier: component.HeavyPartDamageMultiplier); if (damageResult != null && damageResult.GetTotal() > FixedPoint2.Zero) { diff --git a/Resources/Audio/Medical/Surgery/attributions.yml b/Resources/Audio/Medical/Surgery/attributions.yml new file mode 100644 index 00000000000..c88a3e0b70f --- /dev/null +++ b/Resources/Audio/Medical/Surgery/attributions.yml @@ -0,0 +1,49 @@ +- files: ["cautery1.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Taken from cmss13" + source: "https://github.com/cmss13-devs/cmss13/blob/fae73dfa5aedb0a253de04b60085ed8a178d3bf7/sound/surgery/cautery1.ogg" + +- files: ["cautery2.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Taken from cmss13" + source: "https://github.com/cmss13-devs/cmss13/blob/fae73dfa5aedb0a253de04b60085ed8a178d3bf7/sound/surgery/cautery2.ogg" + +- files: ["hemostat.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Taken from cmss13" + source: "https://github.com/cmss13-devs/cmss13/blob/fae73dfa5aedb0a253de04b60085ed8a178d3bf7/sound/surgery/hemostat.ogg" + +- files: ["organ1.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Taken from cmss13" + source: "https://github.com/cmss13-devs/cmss13/blob/fae73dfa5aedb0a253de04b60085ed8a178d3bf7/sound/surgery/organ1.ogg" + +- files: ["organ2.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Taken from cmss13" + source: "https://github.com/cmss13-devs/cmss13/blob/fae73dfa5aedb0a253de04b60085ed8a178d3bf7/sound/surgery/organ2.ogg" + +- files: ["retractor1.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Taken from cmss13" + source: "https://github.com/cmss13-devs/cmss13/blob/fae73dfa5aedb0a253de04b60085ed8a178d3bf7/sound/surgery/retractor1.ogg" + +- files: ["retractor2.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Taken from cmss13" + source: "https://github.com/cmss13-devs/cmss13/blob/fae73dfa5aedb0a253de04b60085ed8a178d3bf7/sound/surgery/retractor2.ogg" + +- files: ["saw.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Taken from cmss13" + source: "https://github.com/cmss13-devs/cmss13/blob/fae73dfa5aedb0a253de04b60085ed8a178d3bf7/sound/surgery/saw.ogg" + +- files: ["scalpel1.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Taken from cmss13" + source: "https://github.com/cmss13-devs/cmss13/blob/fae73dfa5aedb0a253de04b60085ed8a178d3bf7/sound/surgery/scalpel1.ogg" + +- files: ["scalpel2.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Taken from cmss13" + source: "https://github.com/cmss13-devs/cmss13/blob/fae73dfa5aedb0a253de04b60085ed8a178d3bf7/sound/surgery/scalpel2.ogg" \ No newline at end of file diff --git a/Resources/Audio/Medical/Surgery/cautery1.ogg b/Resources/Audio/Medical/Surgery/cautery1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..fbd9f2b4d86257e87ec704b2138249f9c60efe65 GIT binary patch literal 34770 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 literal 0 HcmV?d00001 diff --git a/Resources/Audio/Medical/Surgery/cautery2.ogg b/Resources/Audio/Medical/Surgery/cautery2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..cc91e9f3ce679bfaf1aae3ea05bd2e10be827a49 GIT binary patch literal 16854 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�L!ICar2S(AT0m!2gadm}(y$<_sa2T&)z z8=l_y{P4aAd2$8qoMi?^q}6%%_C_3zTya&@x%oO54$1>&dzz5a7aO=Q-f&^hqz@47 zx)w0eM#tGM8cC24Pr5pL||ibPeBiio2)|C|ITk1j|%_Kv#{ zAKew~h78*cPcRD?AG79|yijtSXE|MD9-nBvai*u6IF&>JTCMU{eml60*9enPy_Mf* zB7sg97@Kpz^9X>>_NUj|8D{7El36zqqp82VPP*m{xYoTo#0n_mbgInxMU<*_2pDMue_Uc|Ox_j}QE+wp(!UEK_~#tEK^ari1>#&awq zm&29+o$y1mVt&W3pVzIBM!Wm$W>b-!j!i)O@;3_{e}>v@_}8-VQfxly1;T5q#H$aF ztLW;d8N;^W>a!BuwgX7LwJJAQfNS&39J-|)SGuAi?TCRMS2>r6?TW@de%Jg^U8(N8 zhy1TA?^zV9KZ|el$KjBrfos@QdeVh0ye1cXUEv{h=3OR|6okU8>tB~A5BIZyO^**& z`Q(T6r$q0_F_?}>HhNwJA77o&PkYZcz$&t_SXQG#AB$wJA%N_#gY^U~dWup4lNqN9 z2s=PyJ+=4T@reW;-kXOxsDV{VO2u`uNDSbxup+Cqh0LF`r{m+(wQJMsA^zcK-A~?j zSx=OyC>MIjVVmN=+kG%A-K+KF67dsj5xe2OJ}UoxW1M)Z#A2(fyQ=%&0H{#f2&8qhsB3VEOoB zVNrlErjW1~GHmEA*3~fPIp))_2pA zChReztaJuOWJl{@Ii%oxK1uvckg#ZhS!R*_>rvEfg+Q7_yV*oC+0&Uj*g#$cRzs+L@0*T(XOWT{nz_3f@h(-L`zoe8iIVmp7Sqym zaxUCe2$8@8Nm@AzK&kv5~d_F#>r=A0sz0TtAd%DCP_tyt0C?${?cF(->NhAwE#xTf|U`0ab zftr|Bcj9Z#1yWI{`hwETF> z#PL_~vvB56Gh{p_mpTlJ15((s&Pvm~StiiP^51+fFuYHUCRgZnICkVRYoWphBo-g; zU6Pz-7e!4@>KSWBDU9Jf&5IEkrP+GiAE0fhoS!*O8ng ze)iSMVeq73Ym2VIGC3+_CFJ!N6u?3&<$aix90t%O;CpjZ(RzN9lSg}blT^_vW|w8u zd^~EOO7k;_&-bHo#o!NG&NqYkEyA37$}DWdIagnnOuTsfPp}hH+Mx#yqsA}ix5-{^ z<@?s#aJ|w`l(Hd`2>E7mbN!sUm)rBJ_{@%bhuDa*YSzzPX7D3zHv$bm_A)A#=z6SD zJe7k2bF@R^ZOQhd?izFeXV!!);NmyMr+4yZte}rwioZF=fH(vMz;DkM0eh&8H1EGs im7s%^w+g>CQ2zPU`nKnPtADk++-EmIg8xSL=lMVXV@?kM literal 0 HcmV?d00001 diff --git a/Resources/Audio/Medical/Surgery/organ1.ogg b/Resources/Audio/Medical/Surgery/organ1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..37eaffc1a34ceb6bd5978d4fdadf3cf006889a82 GIT binary patch literal 18912 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 literal 0 HcmV?d00001 diff --git a/Resources/Audio/Medical/Surgery/organ2.ogg b/Resources/Audio/Medical/Surgery/organ2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..43b22f8354cee8f7a6eea1df9eb312f57dee36b8 GIT binary patch literal 18946 zcmbTe1yohR+c&xo9J))o1cXB$IHVw5qGwCwKG9FyE>VhI=x2PJDD5W@nM40 z$12JiQjayn(ZT#v8D%vY@qeXCN;1kC;&&}cscFcmYluV8{&gBA{a6bE+*N`rGIaTl zMr#59ApjUK!|>zG7W6iMkJpx29m1XB}O5P zK@?yTOyktcSeWjF&0du4ht1c^;IGKHn-`}nx?7YRDZ0m2Gb)Y4RWmNH2%pk2{@9AH z|JHd}WIO#o3D)0nFo1oLMyE6(l*YVc9|9{#b^=-b8x{lL3l0-_8bc~qNjgwTGc?Am z@`F>AL|}|xMqNWm6TDpYwcSi-++1heymXQS^%}f%8UpoZ1NAQh4Jm^DbN}>OxxBmo z4xIr4WHX5*uERdur~0ra@&PpHW*SzQ%{FP@KZOli%HWa zIzlzlSR0Fz)BbAEW|(pv)FrGxr7JsSG}U=n4mUObU+y(=8b*2XI9NuxosQp4X$aP{ z98bk4o_hhlt23IqRn$ld=0fAsSZfdSrorYAMOzO2EGwGpJv^Nr4QzQnWP^L zVcnJe@8%;3>dkPLqC3Nn!7CEoh?KE_F^q32?{;ccDjMvIc1d=@He>bfE!Xrg6kYDwbAB-_eR=T|3Sk*}#KxiJ;7b4o_=l4-8cha~Bn1E?Ts3T1V7%He zY%5x=AHGSWCNEN$u0AY+NgL1)N6+vlgyqwy55szB0tTfv)BQ)K*Z_c`9RmJIvms1m z076z^)q!~=4xvEGqCg@uLTWlgqBN6$7(xiBYG@9SXijNpF5FYntYc9kQBpe7&?J%3 zB-5NoRMM=q9YL7RX=pCp)10a^UAX71o#?v4ucQM$PJ>j}nM5z-w5@*fe^@Dz{$(Yo zIa4Q~>Y}NtX{w{4spDpc^szD$bG;&eE!~>k`iWx}uV%^8Tt%X&+1X>%QZB;oNU>DEauYwCdoF z+El*Z?YQ5>`?df!P*A$pRNT~Lx8LMASZ7OCY~BsMpaGMrFi{y zZEzg6NcT*=%fKqzhi&E8{UC$!pCTjnG>zbE)ppciS@$W2grRU`zIiIx(~|PElG6Pu zJB}}9`_ihKUit~9D?<7@L`*atp?4Z#uMgz3Fkp@)of8aW#yb{O9u4Iq}nK)|Ca5Mu!Y}_v9_P z;>UHZin}Lu!-+hUKvGYwidjtL^MOd};aoJW>UDF0Db(kaNeSo)za2tIHMF zf~@lM?kUK_>qzzN;L|kV8+pWfaM7Q`66)go?NxcL zmbF!RH`q8!K81pOW$is{JNOoryk+@adbZ-zsm}7{)01iu zAi>zSbt?7E_x~EXkrh|>v{Ct8(lD6jpcE!c?XU<8)-^4H$&!Chft{;M%Nhm)N5KWg9e>>xT`9B+f{mwx1v~-0 zxSIi-chD*GDf~w%@<@#d@8?s1ddVj>24zd(j4#bjX*?{&1`BvD&khSDl$T@42SaOY z8Ze%-8I6BI19s@&JYs-rgbNR1aM9pnCkjxMXDxmQO0?V+G===GL0zlznpsKA^1x|6 z1s2d0%*wwe>vDjhHQ1qpzw-zS5RCyyQsjc|ikK4`4T|j0Ai$ZCCIFwkJKY~&8j}p{ z2KcQS6af=LX^;TMdpZ7Kk{>^QM^KaBWdO@y`7U>acr|PQV0Qo`qED(O&VDi3;GBs9 zyuO<=mo4DqpQU~}M*ik)yl*>!2%5#n_Z7(mmo5pW{}&8l1Xv3z;g3+s=J z`O`*a0yCfy*KVa+%Yy{#p+*2$M8g0+p;F5TvQl8NBTW7d!j}OQV>mpB)F=$To&FdT z)|Cv#I0Y1Up$GVpy^BA>K?3;L4H87QY3`DA=g9vKO#VBE_5U)6Vld7k(gMHM-4xWA z|DtkP;=hl^Hvb9Ilm9*bkC^?xqxb()PS3g=G`ato0FrIk7{DzCwboN%7!?lZ-53e+ z!9edzGT38u+JGR~PF?`0o}9<>B5W+6mB3)2`G6iBuPdM8tft1!lAm}tbxi8YbAh}u zSn{XUtiV=8G4pFC@0yyGdIrm%)_u$nl&ne=Z&j@{z+k620DJ?HT)|Ji2h$?greL3Obaxq?SJ*+pG*HWEzBIS3`PqY8Qb3+ z3z)-o>lkStKZ$JHlU6{hPyLyc5^o%8dWsy^94w z6Ggq7g_(AkbNlbxAii~?KDX$V2Yhh>z;V`UA2!{~(3KvLs1OkCL}Z|fw*&aOL;^D4gfwA+$;Y~1BPB@&KkCy|+3VXo93WxK; zSXo(k_~39J0XX=C04u@a{M_8UJUnn-0bcGKnz5mo*#xZTI$aPZgTb2>(fE(tDXo8q zz2Fz7O*gLg33+-{(0NnR0ob?Ihy=(Dz0PGCZ~7U{mMKcOEj2Y0hZZgnv93`4%dpTA z?R)FcVc`rilke4t*YB@9T>Qq;tQR#xiCx8Gsl!)q&2^%gA`s=Dex5T#KcVZ)fO*en zbGYW)CSfwcvK^le<0T%|6=!(5n+k}T!`){SRNgLLHohM9wDB1sd1hYFPhzrAh^0I! zPy9q7PBT{Bs$zLp|5uW5c+n^-zmjtWxvsZcTsyO@Sk7P^dpA1o5f`RbVTL3D@W?EF z;G%jA-4Rn^miS>+xrYU><-iasvxzb<>hbC0wy4EhhGO#aZDi}M$=1LNF9F-e;Fq5k zY&SfopK2V|kV%V3Q>%6A`Ano7T&1*U43ZQC{030W@>MSLpJzAzJTQIDIrL2A> zch=Fz`Fc8X@m0xdcasY3EWha!72mNsS3V-i;clX*N+$~u=Ov>F;e(%K86F`Ddr(?& zoFEnt&j$CkxzW>6E%zly!Ed_SJXu?;Yqq4UmH zTwd}Y4SVifowd@p*%oH8vKp6s){CpL_4k+U6f%DqK~7QjUdEk!d!VqA(%YuSYfhCktOgui(x}zfh?9iBW{IaX6MQlvBKiWrvxpaccScNsh3M{8B z)>5b!*yJ+7p&a9_gcW?htNZIGIBp`Gh}@ux4EQiNevE zwV$Npn!4`m5R#IDgI_A`HUBIVsz!i=ZVIFE7_z}OV!HqH4s9|(N``~~m`LMR(ckPX z36;YW-mJ21BA%cm+s~BN#8@i_lX~?}vwqZ~o{{3Hh>;yfJtiU@>g*uuyr?}ydmm(o zJySI-s~@bC__18+ITi{t*?B3^8=>&mmm;|@R@pcwwR2q+5b1Ol>*wo_Z{qgq?z>%k zp)gZ+4M*C1bx=7CqYT;mdBImJyA~$#>b=E6YG_=HTF=YQ4*_vS7jR;{#9aWFvf_;~ zZ&ELz=MVmE-*G9IPI|=Co-QAS&@aPt%5`3qN^{2g!42 zM^t03FiCmZL ztXV-QS|YC1?mrop(YkS_zl9&GXsMxa`SB*Y&DQm;8D3;{gDiVXlx+tW)gbm}P9aa=(*B--g!U)>BwDzI2p0U-C-EzOH$D3r`3RP>!y&3$ zyQ}&*Ie%OkDSo;#$#<<`(qcS9zbZ?LO01Ass-eVZRE=5R&8tyt(ptx0&9?J5+c@!4gZ?m2=xz6`wI7ZQWMHo90I2t+v zYrAL2a&nl@#=dN?v4;9$D>gPJ@=&qYuWvl^;k&hNbn_Ltbjm0cSJ= zg3V?J-^mWh^5T-PTu4wQUN>_q5NNP7e$mcB#*;P%4oypTr9H=g1Vy9RqQ0RRP`0$W zI)nOcV7DW#K7qEGB;h5@7R2%NWmTXE-ix;1^nU6WT)+kNhC%^@|9%fPp&Z@Lqy~-y zUc)!SkoHIM(m&C0S zd@*kHGv}*90M0R>qT?buxV#<5?oFmrx3hIneea&E3Ki`Z3H*iYrye!gV7pOjgwhIu zlHugWtO?SS1`Ov>QIKlkZp%?g(|l=e&{a0}b1bY|p~K4_VLu}r(Bob7ha;+fYXIRu z!tHV=n@s-8C-h=f`(+EAdONj{D^>($mqD(>NmnDLsanq+LPaT-o>}22>hgqj#NIr}BRYR*Qt#RInB4c83g$RvNeS*7 zQg`M+!_Zuhrs}L_ss>-!@OAte+hhWD#v@5ig?g?YOoFH*)VGwV2NVNAJq3E6-f(t!s})qi%k-qxiVp&!dTaDT2X{kqP; z{uY@|cY5Z5+n`YU+!+l)_M6&wxGug(hF+c+_c!<}t_5n(!j zMie&{l02-awq89$bDK^QAt`oUz(hyqHs^wgdPdykq0)wIm3X(@sYmo|7yNYHerD?(;x)|aJ$^NXLcNGW7mcyb95v~~ z3}l<*SS6pOs4P0=XWYA04k{q90B$IJetv1N*S&IlKX`z|vOug^`R*6{?NWK3%Xu|S zYMq|9i#`7onqc~ZDPEUu`~5g97*CFOo?`7fvlxC61gG z`vb1{Z;wNVm+T9wi3F%f(U7gx4-j|bE5g|ylV}7`*k$$LV`rHOKG%1GU*LrS(Wh^U-aeTJw6UwZD>;V z#dW-1S7d@CF%$}^ILJ5e`*djBLf9+Tqh(pvb!N}Uj2Ww9Wl$-^ zOA_9GkwqhkhH)@Sos2G!b1INf{6Qu~MbDbmbpOZcq%P_hixwJihKp=YC18~O61tID zp5b{8$kV2pcPY+H&+RV0fxV#%DMs!CXUlcd%7v{rD8LOalH^x4^K+^`F0+X<3 z6r*Z5N5ZV+(FpPL?Vb`R5pynU(TC)J#yw?b0QKU_qWS#9L4JU#%Vv_7Bqj8A?(stDbP)bTQsEDrpf*-b@4 zIrG(+o})hhE3-pL__(g{b=1?SWhMZ?C8{8x^Y;iiQIt8prIke6MossM!fx(uyp2Zl zJ#|ZIE@#_F=N{XAB6>;4g#Dkrf9wAS7*N6NkNcK@E)O@HhaJYw#sTBw=jMU)u(GkU zbMf)Q9jPdM-UsY#>^ywzY~0*DtQ_p@tS}xPZZ0@4H%}Ye15P$J zc0PVM3=ZNAyl@bffU)xOoDm}9@aod}k%>6db8bMdUq6oWojn3o#VO9X zxIc}%?Y|zu0Ccc%@!EDgQJTqo45M!2AjS8bJcH5sD79~$_L`1N-gg;|wPBu}3ClIy zyr2(z0)RHv6M^~N&IFg4yt+l2RpWS6Ut~6CYIb=gD=2s%>@s6S>+yY;%U|A`+LyfO zlKVG=D{{Oi&iaPZPCN%HsSi*)%)XmeUReDmJ$w`tUCEc+*>c3RRwS{eu-7(^D+n5u z;rOYUxg8s3H+r;H4$6+u#UMNK*)Ma&%8_1V9ho3vSo{{cqXMD9L-JD-(&v$Lh~E-fTK6C%D(QAAdK%1ehT{y=)`pe9g?<9v>yB z8T^A6J_+z-Rz?)Y)inRH`FS&5IUN_)m3(q}H0e>a+Tso%C~qG#UoJ6uqKuQ70JqCZ& zpO#W8Eh@$U%s!d^Y(;tPYg&-G6(qQC7bEXbF|9GQ z#Ru!AM*2{b-f`Q$K_Kw#Km=6`t3ue+{Miv3KUsh`3WNXtyV18Ksv@R>-Ah~~FXWMU zlMibUGJQ{VO3VK=@`Ce08}+Yed985LCjum_+2ah|MRa6Ih{Ka5dfUPaqciN9N;u;v zKqmA0jUd{PDjAL5WHwtL$5Gaw4VBMx(iig+C z!Vo5*s$ao34y89A4w91Ukz{ci{9;xMDv>4cBb%_GWIhhWDzW(Vq)=m22Z#VfRJ=*e zKFs6+=XlSq;L%}LVs*t;aZI}az)XgmAj6G2V&LO>R=5O+5ynI8bX>QJO#;eyDs9Vy zbI1sAIyNm;pEm=#D4Z-l8*y(l#i%718X?21Xc~l=)b;%0B7g<}bsR`P z+FX4$cs4Sx(Q9GHsZ-S~99&a9X;}pj14($ts3&8yJk{@vsQyn7e%IT|%O*F`nN#rh zW89ER1XT%BYdwn14T={Y+ zyqYxe$Iq#ij)auk_J>V}k49J1+-I${!x-jiz>r4b1DF2y$yc%Eq`+_pIr+oXU{i5`dy-MSo%pIqmVRU};2Q+>rodB^R|ETe3H zvOS_??3Ci}*mme|%)Z%Q^!58G8bAysLfRkbO&m&e^l({(ugF0t#b_>Grp%+$zZOdT zJW3^X9BW15xU$-ibo-~x8qb%OM%Gi^1fXaYVSkmUs zlcbk1{cYGU+P#)J5tQx%sGPwngEft}>HwwR<8Q&Tn>!rrjGiHu$QLFqpCph=7p0ev zmhWL5pc_#Gq?AbgF1Gq6VR|=b9&p|H{nbK`B$4|!>mW}7vc8+aa-Tv2H&CJyDwgrM zx5D^+L+v6QR4?MkJv1!KCRw^7F<&`lGOtY`5Ve)qb(q`<@L8g^yo%BNlx>~ zdn9VY6T`dYxx@SkN`vLjY#9~f>xXzKiN1~64-6zt=RgiN%iOecsjQcO%U5A_jp>tz z399QFxe*3Ak z{&LBH5ezjC0S8FvnI<6EK(P8m-0jV?{>fHSv}kAO>6Q1^r>2&shMt&XY638PpXlot z^@N0`r}7gw5R2J;Jy3ura0G<^q?d>i`q-ghHpeMhih>IUj5ZWQtns5aJ}4Rvke>rB zIhgfdY(7P0bZ&>GgSri+IC_0Vuc-dPw~~|3u}J*wSrrI2sw|=hp+g%A(ZMfBKqN z|1`pESBfI@hYelbO5d^okQ>q!>gM`%iGsvF?;{j3!ne%k-;(2p(I`u6bJUsAgi`DR z==mTXq+}JfigEkAp-i>22G>!vpyU=7R;-cJOelt^*k zN0P*SXg{&>&e+*JENUXkNG@wa)2F_b?!WauzYMc@?>(?OpaI5&j{V+x^|I+;q&g(j zp0G+$ru8^OyeBBg%XKFEYD@DW_7-ar`Z@t8WyOQ`KKj57+0{j6UXtFIMUqv z>`=1;VfSD|MNo)HmA??y7-8EOO&tFC9qCe$ zMY(+uC`c7?4Bz~19&iZhH(CsCzkC1+M zwE_oT`hOJ$f!0CWiWP8^OBWSqWqI!^qkGa0gC>uRJ1&{<-3Q=fxUO50I*0b{Jz zDs}S9KYo|z@IF&2DAn!hvsL)K5cX?gMpyUQ-i2GYVIq3A_q4UrOWohBY1)<`6#uj3 z0H=GsD@p3r{1cmbnRDMtBO26g_aa8M!wWP#UJ4uj-xq}VLg}Bh9^C6exgo7+{^VBQ zuhdRs`@-vGd+zb=_S4*8ViDbG?CKWKRyoh zW~6&b&Gl8zcWQwI0pF(q*|m-WmCN7l?c!Rz6{N$rag7pxExrS>j0*d~KXbplM%&xw zF0jT?Y?e)_-iUM;HkgPEd`8HB3{dcUCo1>i7l<&syEU==_#O9*uHkJb3Ota3u-+Vz zk?#Al;e16i;3pe5SEjnzE0sZmjyBeyAA97e2bgWiHGOVLSZFx&^(d8OP=c)QBjQ!~ zBkp~D^m?khVdZIprkuM+bExnWZp~*8=&Es`WbW*nbJaTcg1MHxmvDS%6%j>cjl9|s zy+bE?B67<6cEj2el7@{|7|PA>vzqaVZzw8C=abDu);MNU%`_x+vHn=9Fjs11>+F+k zKdM+t->be4aKQ=j!JV86J<{=B=?>vSZNjwBcNp6R1k0)9g-Jet1{fJR3%sp+UPlFM zVfd!_=zZw&W&}eVm*AM;v1S5!!0PKG?tGmBc zi=%u8BHun@vSXwMBQEZJLJM*^_|*P10sTmQtmOs#XVJ{D7+T7A(lgu@<$}ZF79o4` z+fs#9Vd2bBA`Pe%*{^#nJb~Yee}5vzlO2GHBC!q#D>CLPU%$k`#(&6juYuTxzQRrX z-7-$|Y1Qf}O7PG+l|?#m>U}_nOnH`S!>wHLTLY^dRf_oGjC_kxg$cfuw z$_JlXN6FDM@sFT5<}U&Hz15v$jhOt+lWac(0|bHQlYNkd>W%e8YCl*_vW!WX<(MDA zXG>1$-1?b1Mo@6;7S$s}Kxek!Fmy5s`Lob5|B>9h$zz{J~o<+!NnVw=O?VcDq+7 z=aX18c68n+yd3S_gSvt1sHr}C8VdDrHTbL(1G zFdj$pQ<99oRgd-GcrNf5UCPQZ+V)3uju;w zs(9TAxL{lCT`M5IPNc^A+4RR$Fu-pGJ601R8<;E2wpkI-SHwE4DAZyv=x&4_wwA=d z!Wj;t;<}Qs7Vo2FK{J{ATw`os25z`uBH^_dIJtbet80_#8NkeHW1OYZl0~Y}aE}j_ zPlwKV=|g$Zm*q{dD|FfbF5YeEh4E-z;Hmm(a<_tH;1}eHgs5HNIa;k;%}wXTMWB)~ z;~#x5Y~r~&qwfM~=4b#enh)!Un)(8_X?7g8mIQ4pHZ?(eljQ2`K0m9RY~_hk6aNrVwo}$94ib*Oo%=6K`vfw#`3)6VmYAS7=(2@}_PLj-;e=T)L|v;z_#Svue*E~21nUMY z0rob}()QQMk{*%;OzgOt zIJCbz(B9uXzB!7j%d}0pM{uLSuHYQ$HEeFC_QZ)50HGxQYv#Q2`^Hkn$I*II z_VXoTs?u+BJeTRu__bXrWcWp2{EjRlX7ELa61ACi(>c*AO4(7_7NUpy4psPxD@DW4 zX)n4Dks5TbexocC^;kj@>4HqZn}c(Y@tVsOgN`iwGh7LDFTO=&(Z z{Np)_5%{NCx1e9AOpRL^y2n^vMaN{a-ZxR95CEJUhG$XnyYKVsSwjr893;2Cf4L^% z=Xd`++<(O2xi;bpq8*uBCjFX^;&DNNRjkwyb(aZGWE|?HVL$J9jQ3}%VB4Ah`hD4o zU}bJ@o6f|7GI`M?^Ho;A5&8}m2yD@1X1aEVKp!|rP1JZ5Nuv||%93a$j5vv{|87O6 zpSJV7c$YN9TQ~Zwf>xcc9UYt|DbJyE7FNj-8!j$#R>$rG34L9HyIvkq`DQJwGfD5cNqBn_&3TSPoQxHc<|DBZgVtAybID0Af7Na=Ap0q3^UVLa5 z0(VCpR5pg`*1B8gy{e#i&=`KrPl`<)Z#emXY1f~u<=9Bm(biwL?X0}0@jal@!v^)! zMrg`Pcc4NTgI;-#=8x`&I{r#wWhEr^<=P_Ev{27{{ayh>TIh$YPZyeW;2}tGjsAXK zKtEoBDbfGX7?00`SO4{doU)l~O2y-qk2pgZ%26|JrE9E162I?5fFUS2mB1Dra}P;; zs=X322RtCG*1x!(FcHfnElyG0)VWm*pJvaIV!6_gRSaM+CJSH2{SJ4QVkR_M7m|ty zGpc#>y;?*@P-<3-qnU{g7?r=^#{KKsQRv6Msl{%GA(n_2ivr{ftv!~OlBf?XH+xQM{qtj z*5;J5cN{09Dq8Zp6VIkx9NEj678RHUF9y%>cr8#sZ{{(YQ5o@mJaOX=l;Sr-gv@C} z*ryWM8$Cu{J{J|Avi(T1RXtcQ=Bs*kAH8J@ z>|ihKL`t1Vz{O(C7d%`I@Xl~6$nwV`mi+_#Y($ZoK<+(H)^b-_9i_-`^V#={*jWxo zjHA=WTVz1&xniQ1QSd@iDp6a|VDd+)K-^S5eyZ4ed7^~$K@;v2Mc*qT;=9!=kxhim z6@O#}L-L>!cvRv#cq}~sLpbrNhs2}bSwFljD|}KLK7cVfA#wosQz5mPgt{+=AM7Fr z9$PC%8C=X0aRv~G425sL!DML4*dVMZ%-i0~q$@U{{@m#o0vzs?Xv^=dDG~J83-(}m zJIB2_*EPo55{II>hh8wxk_7w7bQd!44J; z?QNeXLn9VL%ut_mNHTCb8K`xt0URByA) z{v@xR9n;GlVHH--_+#UH?2O>1#kxDwQ*V}te*Lqq4Q|Q(vcNQ0DJ{9^*+;=8y2U+w z{YNk&#~}9v%NM|e-Ug*b1ROqSLzytPnTjxIC=orjCF(%%qb;Ln`Praw^vj(Q2xU5o z@PJR$*PhtZGw(lQGAUErR}_f;&`|R4e$tF~XP7<~RSTM^F_NUryEsy)9k6$ne-u-= z_!U`+-%l>oP;QwhVbpR(^$iFUjRfI9v3xvK)dYim{X7)O@M!$Y7fEC_s3=*vQq^sT z==AfG+kUO|1I&0nCW-SH2*&`w?wTxF{}7at4tG?z2C3~eR)6CBN`Zc%{~H(cBhbxn zX+D(pFK%;ILk`Qe2T$2htAwxm|>`i z9H10?JLZ!*?R-d}?=n*rmsq+^iO=d#^UK{cLyIu_1t+ zS@6M;yp_l^*0NU~^l6rP_2y!Y72^iCjf~&njC}XeA1c;jEP4MAhnp$0GrXDGNDB4R zwUAoZ)qzpsIJ)?V~*h0X0F)WT>XS#U&vQ7Jt08QwHlZq{e zP0>RJ$W+4iQ`l~lFBU*U&O@}Z)Y^RW_~@!y>!)F1t#(`HpihPA!Pu#K2 z7w$vO@;tkG1EGTZk6z2qQ&*W*E2uFY@l{v_Osc+Oc5$`TJbC7;)lTi26;da6jiuAy zztOi@a4@{)*S4MXa)9*P$_V>U?o})tx53PwS*IuO(M-HN@_Apq_sCknSn7NkC&GmD zNx^+CQ}ne~71Ig0s9YicoFC||c0b*|1T*_(=b)5LA5qSbCUHys)Z2#8bEqZkO9Cnl zZN&oh*oi$S8r9MpS4p|~BeG!A`=|##ZSN8?+LvPA`9Kvi`EOgEz0uQRr2-E;wPnS) z1yizV<^HCZM0>YhonA>LQ_warYt2ng=dwDW*zc{Oo=#&(P`Zc)q74r7WJ_ht_p1B; zBv8epkNuMHdNN{I*VvXdUo7hR$>oc=KR$SlM6Mn8B>?VNxKp_eY5qwM>#~@^2gt-q zi8*IHBTif_eHACuRm~R4Q3!q;6%n0Kt`VH50NL6l5E?R{V-2Pko0e$J%;fK{Uigkv zNLjP4tBu=69n89L2G6F;x;)lx{@QMv zfqHL6h0DzYMsCCU9-BPY^gq-Dbl~ryY49raXYuN6C7pWS{*VLMg(W{QIdHb+WBmh3_*s@D z-OCegallBFskUh8O2T}#X2?Mm(>h2MW|fi6O`m=z4J3)!%JY6KH=OaeWm4!UGTyT# z4;p(u7R~MsdU-eC(&CRbJ^hVXf-Is|2`u)SUZ8YC-um6DPwL!Loned{WFL*3uzc;U z3bdCEw|-2X8>p9b?{4&e9Q^ra``cthY1Ee#;Tq+kM+?#u))d>Ra$U;I^*1E@mGSp< zEk(B`XYqv`K449pw>-Ml9qyB}5<*g|z)KY8xV6Hwd&z5*BCQeC^qC=4i<*vKa%IQn%2z6l{ddX&|J6@ zS&2Q6eVX$}13Z1z#%h~H`CA>^3EV|wnFcsT_A3wZ5_u+`Qs+s93!MTYbvP<0jc-uS zD3E$7@1iLEvB$00-#sE6Ot+Qb*Hw2PRPPM-=_9wM8dV{+MgR1a1Vpn-XY=z(qhHeY zzeU?gSe5^d^*&z#ulgao5=t@}2*4RK|3n9&6#hJYDox2)rbg?2^i?Vi2xp!W zr%tb4TMs?*^WAof(P;!+#3(Bib;;k?#Ec^re&0dvqUGNqvf{gcK3LTLelNdDY(Ova zRg=QLqU|BDWdM2#l3XmN&S)+Decz3DbvEfS-7B0oVTXM*Z#ezeKNwJ1iKBTMzQf-+ z8sGx{;ttTG%zytD;qJE0oLR{XQUHFov_>zb*~o&F0Q7ke90)Lh)#8T?5Xh=+df zuH@ttAxrz#CXY&q$(QB-fU2uLt0h^HE(_yLrY%BWYg=}x-z0Wp!w-SEOfn|0N zMxiZ$Le0fz?jZci$GgQn<|XQtG=!O`qLo6Znnt#tP4+as8u*B!c_XMrbzgUQ$l@vb zea311fHEsYDtjdwh@g_IU|QX}Fbh%bYdXKv^xJNHR8UoBJy>~S`eM1QI@{FWaIw`K zFB-&1D)ywwDEmFUYI|);M*|Ve_6~rKSyE}St7Z<(* zlu%RO(@xunNHvvaE9}Jn-pRKQubkK$ZM?T;#eUNetm64Va4C_FK^YQ1NWKIwv0{u$ z5-x6j#C(v*KgYFINEb|f$a`)m&F-2J+5Iaxp0bpW_J*cH>r1q<_v74pa2tW9A23~F zVjWe76;C8`Kkb^6P#LC zA!GKKY(UvLh56cm-q@4W=~TMK$qdvtcCSxV%2$+rG`*gC(P#!G{>bGo(LfvHQmZQz zpSc^?8Mu7@YSxr`yUG+A=reyNmxyh>$XrWtK{yv)xWxbT_OY~Fni(pyOIquq;t4Cm zBmAz8(MxDxVz#}foE6rUTyy4ZX?AcPJ0YfN7~JLS&i95+k#U=Q%B|1CJ;#2%wzdQi z;K?r<+5z)xeJe5_CQ|;h>*zo=eERXMzT8Ol-$rkOuC64N7Fgc~FQN5mhn2E<>Uw2> zVyu977c96uu7q6EW|KZ2TkR@)UC_93{^i#jyDVjQ!%SvNv{dGO^5&^36cAWuq-*{b zOZTD6-tN{}vUoKR_XnRM*{=esHuMq0ve{6dss^j&pdY!PP0$Ft2tYWOO(l0_qY@S! z{Tn~}9e8r=(A(C-YzY_PUnL184Z&EwbS( zmZGpkO78sH>U*NfmZ*CaTG((ddyyoqH6gfrgAC1#tE(i!PA#pMMwc?Wn);-hhT-S_ z__-sxdS<7!9QVo<>QiP+LoWWLJ8ao+$*%dm+;M;rh#<)b`eH+4oah@E4BHB0G2nFN z6J&WY-3I#Pj@LGc)(v=vs1uYy^obR(=ntjJ%D?`<{Wb4;mg~cyyFEBJbiBZ0OS#+Jh@azTLj3y#? z*sHv9{%zmQu%MBJ;a}>RHMgsl_8)wdXuIuD-m7~d4B8I2CfA0aGh&djIlaE~W^VS6 zS5wMlY_hNA8)wGdwm8!I@Rk3wDWRo#{06Z-lOb~ct|JJOz$fmlY z;=E(gEA^>G!r59K^P{>8yIWQ#sp&0>^nYBo@Q<6#i3bz3KD>v-JD!ihI_ z&dfM(+c?KK;p02j3wcj|Tn$oaTDst#w$U~zy|sNN%o;yW7O#E4dX9->gKz_%T-uXg zk=wsrcyYSx%BkI*$5!ZL;N&zsH1xx=$Q9N(T7J$wJXFHu{<>gvBv<$J17AiRtIrP2=;!B5Pu#hes&dW!{+dk_y^Io<-evnzs&Cp*xF%wgPOS`6L;E_x{OI}|+5gt{f6M>1 z^Ph?Psd@kT&BCG!bL5L>AA480XTD%p+BVBGQ6YY|wjPXEbh1x`*HnivwRX+=mlvqD z^p>d!@A)t8oolp?`_DhP$t;i~u3MVt(G4qpl3{Fgl~>d%f3cZ)YEOzmCa-t^m* zp|oFWir8|E{px#^E?@Yns;==Z{hCx-n5KF~*y%Ss2mM~m(e=69Tq1OO)&Y)vsef*s z%NIDnvMg3JZ5a=P!#me!3|goE)*YRmqx-FP3vg88_aE82qN|vy56}HpR}wM%#4JOt zhVNX*Wz~L{uSh=KUA1Bh`?lvwo*(SPq;HuWGu!4P_3JI$sRAZ`dDCrw7$Pp@a5C_b F2>=m?oZkQd literal 0 HcmV?d00001 diff --git a/Resources/Audio/Medical/Surgery/retractor1.ogg b/Resources/Audio/Medical/Surgery/retractor1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..70625c961cf982d3bdb93e106b91fd4a410211d1 GIT binary patch literal 11537 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 literal 0 HcmV?d00001 diff --git a/Resources/Audio/Medical/Surgery/retractor2.ogg b/Resources/Audio/Medical/Surgery/retractor2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..94548ec2504ae8da2ab7c9bc7348f2284491a6ef GIT binary patch literal 9915 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 literal 0 HcmV?d00001 diff --git a/Resources/Audio/Medical/Surgery/scalpel2.ogg b/Resources/Audio/Medical/Surgery/scalpel2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..7335f3d9cefa069550ecbac001fea9e997b21f8e GIT binary patch literal 13098 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/head.rsi/head_1.png b/Resources/Textures/Interface/Targeting/Status/head.rsi/head_1.png new file mode 100644 index 0000000000000000000000000000000000000000..0ba1a77dfd9a8755f1793921a8c583cd40f5767e GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#L2(R|S1>Hw%aC5m zU{Q1NJy43VB*-tA!Qt7BG$2RY)5S4FV`6fGf;0!$f=`lDMFLq{rc4c(${{H&C=}py k`Ou3;9{af68ILkB%>2r9ye>3(0#F-+r>mdKI;Vst0Ak1|qyPW_ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/head.rsi/head_2.png b/Resources/Textures/Interface/Targeting/Status/head.rsi/head_2.png new file mode 100644 index 0000000000000000000000000000000000000000..1cb55b4fe97f7c31bd11c3a899fd4ef2feb8b6bf GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#aX}0#CNu0^#!#BV zQ215e11QB<666=m;PC858jz#y>EaloF)=woL7IbW!6(V7B7v+eQ>F$?<&cyX6bf*< keCWj^kA2+kj7J$5W`1QlUKg4?0jQ0^)78&qol`;+04^XV`Tzg` literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/head.rsi/head_3.png b/Resources/Textures/Interface/Targeting/Status/head.rsi/head_3.png new file mode 100644 index 0000000000000000000000000000000000000000..d797b40a16129e062c7a105896b1d9a0784102be GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#aSjYC3K{m+F_ii- zOeop$4k*P~666=m;PC858jz#y>EaloF)=woL7IbW!6(V7B7v+eQ>F$?<&cyX6bf*< keCWj^kA2+kj7J$5W`1QlUKg4?0jQ0^)78&qol`;+087s&WdHyG literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/head.rsi/head_4.png b/Resources/Textures/Interface/Targeting/Status/head.rsi/head_4.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc1678ce5dacc75e2bbeea26616cf509326c462 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#aY_s;Y#8=BF_daD zq*%T<1C(Mc3GxeOaCmkj4am{FVdQ&MBb@0Pj^MSO5S3 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/head.rsi/head_5.png b/Resources/Textures/Interface/Targeting/Status/head.rsi/head_5.png new file mode 100644 index 0000000000000000000000000000000000000000..f6caf62d4058d5de67d165425d3c4759984dfec1 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#aV!ig*ctY+F_f|} z#J_VB1xhiN1o;IsI6S+N2IOdax;TbtOiWHtkmlf8@JVv2NFZy=l&JwzIV7b8g#w%| kAA0e~V;{FW<532NnO~WX*M%le0BU3KboFyt=akR{0DB!I`v3p{ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/head.rsi/head_6.png b/Resources/Textures/Interface/Targeting/Status/head.rsi/head_6.png new file mode 100644 index 0000000000000000000000000000000000000000..74b58c642bbb81375ac68067edc66aaa7dad4983 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#dU|@n!NGBHaaLAV z*XF-v1xhiN1o;IsI6S+N2IOdax;TbtOiWHtkmlf8@JVv2NFZy=l&JwzIV7b8g#w%| kAA0e~V;{FW<532NnO~WX*M%le0BU3KboFyt=akR{01!?lxBvhE literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/head.rsi/head_7.png b/Resources/Textures/Interface/Targeting/Status/head.rsi/head_7.png new file mode 100644 index 0000000000000000000000000000000000000000..74b58c642bbb81375ac68067edc66aaa7dad4983 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#dU|@n!NGBHaaLAV z*XF-v1xhiN1o;IsI6S+N2IOdax;TbtOiWHtkmlf8@JVv2NFZy=l&JwzIV7b8g#w%| kAA0e~V;{FW<532NnO~WX*M%le0BU3KboFyt=akR{01!?lxBvhE literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/head.rsi/head_8.png b/Resources/Textures/Interface/Targeting/Status/head.rsi/head_8.png new file mode 100644 index 0000000000000000000000000000000000000000..4d024c61f7f2c0bc5fd3e850e0d7af7d2eb1c05f GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvi2$DvSBC!#3m6#m^z?#*gHJFp z#Kpz^XJD|hvJ(B-yc4K~u_VYZn8D%MjWi&~(9^{+L}Oxdf`T-M=7LW%eR={|Lwx22 zPSsf6wt$PHot1k*mZ96_Ln?6|`?%d1k1{X>JZ4Fr_DE+JP&0$4tDnm{r-UW|Q%fr_ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/head.rsi/meta.json b/Resources/Textures/Interface/Targeting/Status/head.rsi/meta.json new file mode 100644 index 00000000000..2c34f86c28e --- /dev/null +++ b/Resources/Textures/Interface/Targeting/Status/head.rsi/meta.json @@ -0,0 +1,38 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c7e14784b35b1a136351c396d3a546f461ee2451", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "head_0" + }, + { + "name": "head_1" + }, + { + "name": "head_2" + }, + { + "name": "head_3" + }, + { + "name": "head_4" + }, + { + "name": "head_5" + }, + { + "name": "head_6" + }, + { + "name": "head_7" + }, + { + "name": "head_8" + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_0.png b/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_0.png new file mode 100644 index 0000000000000000000000000000000000000000..f2b97eeda697695a796b1eb2a4aa1751d662a0f3 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$efSBC!#vH|7lS#y7wPPG9F zGL{7S1v5B2yO9RusCl|LhDc0JPFSFs&|)}4CZUJZ;F!>iSw1tAJbB#I*qmEtom1vv YI5m^$U;DrEWS|ZPPgg&ebxsLQ080)cuK)l5 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_1.png b/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_1.png new file mode 100644 index 0000000000000000000000000000000000000000..98883b555e6bf659bc87263c25a0f03334fcc4a7 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$efSBC!#L2(R|S1|lK#%=)= zWGo5t3ubV5b|VeQQS)?h43U_coUlMMp~Y~9OhON*!7-s3vwUVKdGffau{pQQI;YIT YaB3#gzxIFS$v_zopr06?}Pi2wiq literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_2.png b/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_2.png new file mode 100644 index 0000000000000000000000000000000000000000..057cf12cafc318736f864ad97b45ca1388f812db GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$efSBC!#aX}0#CNsoToaY7# zGL{7S1v5B2yO9RusCl|LhDc0JPFSFs&|)}4CZUJZ;F!>iSw1tAJbB#I*qmEtom1vv YI5m^$U;DrEWS|ZPPgg&ebxsLQ04E(HH~;_u literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_3.png b/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_3.png new file mode 100644 index 0000000000000000000000000000000000000000..e225fda639d074c48f39d7af14645e80db93a762 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$efSBC!#aSjYC3K_HnX0-za z8B2ovf*Bm1-ADs+)I41rLnNjqCoIrRXfd22lhDIya7<{%ET0)lo;+@9Y|bsS&MEUS YoSMn>ul-+nGEfJDr>mdKI;Vst0Q@B(u>b%7 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_4.png b/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_4.png new file mode 100644 index 0000000000000000000000000000000000000000..4d250735a89fb6352f649c27e01caf05074eedd1 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$efSBC!#aY_s;Y#4e>`yT-X z8B2ovf*Bm1-ADs+)I41rLnNjqCoIrRXfd22lhDIya7<{%ET0)lo;+@9Y|bsS&MEUS YoSMn>ul-+nGEfJDr>mdKI;Vst03y&LH2?qr literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_5.png b/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_5.png new file mode 100644 index 0000000000000000000000000000000000000000..0f31b3bfccd2704b0466c733725947a505de73b5 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$efSBC!#aV!ig*ctw@?WzL` zGL{7S1v5B2yO9RusCl|LhDc0JPFSFs&|)}4CZUJZ;F!>iSw1tAJbB#I*qmEtom1vv YI5m^$U;DrEWS|ZPPgg&ebxsLQ01Qqc>;M1& literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_6.png b/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_6.png new file mode 100644 index 0000000000000000000000000000000000000000..32cd12440e347c6ab3f3855f79d80c6040e541b0 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$efSBC!#dU|@n!NIHN#8?0Y z8B2ovf*Bm1-ADs+)I41rLnNjqCoIrRXfd22lhDIya7<{%ET0)lo;+@9Y|bsS&MEUS YoSMn>ul-+nGEfJDr>mdKI;Vst0213F{Qv*} literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_7.png b/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_7.png new file mode 100644 index 0000000000000000000000000000000000000000..32cd12440e347c6ab3f3855f79d80c6040e541b0 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$efSBC!#dU|@n!NIHN#8?0Y z8B2ovf*Bm1-ADs+)I41rLnNjqCoIrRXfd22lhDIya7<{%ET0)lo;+@9Y|bsS&MEUS YoSMn>ul-+nGEfJDr>mdKI;Vst0213F{Qv*} literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_8.png b/Resources/Textures/Interface/Targeting/Status/leftarm.rsi/leftarm_8.png new file mode 100644 index 0000000000000000000000000000000000000000..b89bb2c20ed36a6d04a83f94fd01f5d39d6e8c44 GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#dU|>%7#Mokejdx oqnNV^BaiMmiKq**Mo$REGT1Io3ER%MEs z90Q6omIV0)GdMiEkp|M?>Eak7F*P|sVvz#RF^y)!ZGwk08jQB7IY_P+d$5&_VRD VttzemWC7JOc)I$ztaD0e0ssR&A*KKT literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_2.png b/Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_2.png new file mode 100644 index 0000000000000000000000000000000000000000..4439c85a05fcf19719e7b8540f07b01fc1a633c2 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@o&cW^SBC!#D<(6<1u^Vh#xOy5 z%PpWdV@Z%-FoVOh8)+aNo-U3d5>t~CBo-;~9Mfnv+$MN9qrqsKnuFwOu?Jh(7?!uP VTUA>B$pWfn@O1TaS?83{1ON;}AmdKI;Vst0BV&Vj{pDw literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_4.png b/Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_4.png new file mode 100644 index 0000000000000000000000000000000000000000..8c0cc64f9b17f7a9b22cede1174aaf7a3c79b131 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@o&cW^SBC!#D{L6zlo<9pF(@=l zzY7#+ED7=pW^j0RBMqd()5S4FVrp`N#3BWrV;aqd+XN41G#G7DbC6su_FyX;!}3;k Ut4ixXSwOW6p00i_>zopr0JQKRsQ>@~ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_5.png b/Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_5.png new file mode 100644 index 0000000000000000000000000000000000000000..3db84b2482a52630e260960e2a124f2dc7a6379e GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@o&cW^SBC!#E7%$0SQz%QF(_^B z2nLEXmIV0)GdMiEkp|M?>Eak7F*P|sVvz#RF^y)!ZGwk08jQB7IY_P+d$5&_VRmdKI;Vst0OcAXQUCw| literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_7.png b/Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_7.png new file mode 100644 index 0000000000000000000000000000000000000000..aafd9842ef1308b1569f035e6f8e60776a9b0ff9 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@o&cW^SBC!#!NI|LdU|njaS5;f z*aF2FOM?7@862M7NCWBcba4!kn3|j*u}FdEm`1bVHo?Og4MyA493)qZJ=n^|u)LMs Us?z#T7EmpNr>mdKI;Vst0OcAXQUCw| literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_8.png b/Resources/Textures/Interface/Targeting/Status/leftleg.rsi/leftleg_8.png new file mode 100644 index 0000000000000000000000000000000000000000..9652d363d4e3a77b75ac59c34cd02bf8efad1407 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvi2$DvSBC!#Cm0xlgM$|^0GSMW zdU|njaWfehUV1N@0#w6T666=m;PC858jz#!>EaloF)=wog4KlC=~M=j)~XDq#6=lQ vsjo7a6kRen9Yi@ooPvd-r25X!{K3GWD9y@vy8p~HpjHM?S3j3^P6FVdQ&MBb@03s(L9{>OV literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_1.png b/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_1.png new file mode 100644 index 0000000000000000000000000000000000000000..e1c0b4c09e9dff60347b577dcfa52a4952ffd2f8 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$efSBC!#L2(R|S1|lK#%=)= zWGo5t3ubV5b|VeQQS)?h43U_coUlMKp~dh<0*|JIGWW6+%^pL>=8Y_K4+=PxstYkO Y7+zt1SMe}33#fy^)78&qol`;+02j|7`2YX_ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_2.png b/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_2.png new file mode 100644 index 0000000000000000000000000000000000000000..5c9f675a1d3bef15838aa8b94aa7e893d69f8a80 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$efSBC!#aX}0#CNsoToaY7# zGL{7S1v5B2yO9RusCl|LhDc0JPFSFr&|-Kafk#t9nR{7^W{)9b^G24r2L&8T)rFWC Y46iW1t9Tfi1=PXd>FVdQ&MBb@0RAT+r~m)} literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_3.png b/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_3.png new file mode 100644 index 0000000000000000000000000000000000000000..6ccdf982379ce4699d92ebc32b06925e01e9cc44 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$efSBC!#aSjYC3K_HnX0-za z8B2ovf*Bm1-ADs+)I41rLnNjqCoE7*XfeEzz@sUl%)Kl{v&WFJc_Yi*g8~kv>OxEm YhF6&1RXhyM0_tG!boFyt=akR{0MkAoApigX literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_4.png b/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_4.png new file mode 100644 index 0000000000000000000000000000000000000000..e38f50c34398173df04c74001538f80b980e20a3 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$efSBC!#aY_s;Y#4e>`yT-X z8B2ovf*Bm1-ADs+)I41rLnNjqCoE7*XfeEzz@sUl%)Kl{v&WFJc_Yi*g8~kv>OxEm YhF6&1RXhyM0_tG!boFyt=akR{0QuS=r2qf` literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_5.png b/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_5.png new file mode 100644 index 0000000000000000000000000000000000000000..1e0b6a768f90d91fadb12c2462df0acfb2e8d0fc GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$efSBC!#aV!ig*ctw@?WzL` zGL{7S1v5B2yO9RusCl|LhDc0JPFSFr&|-Kafk#t9nR{7^W{)9b^G24r2L&8T)rFWC Y46iW1t9Tfi1=PXd>FVdQ&MBb@0OMF7TmS$7 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_6.png b/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_6.png new file mode 100644 index 0000000000000000000000000000000000000000..90b26a759b44a62c17f1d58b5240f36d718d4781 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$efSBC!#dU|@n!NIHN#8?0Y z8B2ovf*Bm1-ADs+)I41rLnNjqCoE7*XfeEzz@sUl%)Kl{v&WFJc_Yi*g8~kv>OxEm YhF6&1RXhyM0_tG!boFyt=akR{0O{o*Z2$lO literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_7.png b/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_7.png new file mode 100644 index 0000000000000000000000000000000000000000..90b26a759b44a62c17f1d58b5240f36d718d4781 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$efSBC!#dU|@n!NIHN#8?0Y z8B2ovf*Bm1-ADs+)I41rLnNjqCoE7*XfeEzz@sUl%)Kl{v&WFJc_Yi*g8~kv>OxEm YhF6&1RXhyM0_tG!boFyt=akR{0O{o*Z2$lO literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_8.png b/Resources/Textures/Interface/Targeting/Status/rightarm.rsi/rightarm_8.png new file mode 100644 index 0000000000000000000000000000000000000000..126b5e0cd08d00f028d341f13fcf17f5f5bb6d12 GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#dU|>b7#MPelh&wy$fJYD@<);T3K0RStaA&&q6 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_1.png b/Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_1.png new file mode 100644 index 0000000000000000000000000000000000000000..014fa1c76717419605c11d66c7c0a8f5c3e0d760 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@o&cW^SBC!#L2(R|S1>Hw%aHOg zcPUVuu_VYZn8D%MjWm!BPZ!4!iK)p65|bJVS$j4zAG_f+;~-bE$3cljiYz)z46B&f V)RQ`0p8?e}c)I$ztaD0e0ssy+Aszq# literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_2.png b/Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_2.png new file mode 100644 index 0000000000000000000000000000000000000000..6e52faa7d228c21d46cf147703cbf15e7a05000a GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@o&cW^SBC!#aX}0#CNu0^#&D&$ zhzBUnSQ6wH%;50sMjA+mr;B5V#MI;jiAfEGtUViPelh&wy$fJYD@<);T3K0RZOgAdCP2 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_3.png b/Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_3.png new file mode 100644 index 0000000000000000000000000000000000000000..e527d36568475c0d02d88f253e3d87d142e48ba4 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@o&cW^SBC!#aSjYC3K{m+F?^Jm z{|PA0SQ6wH%;50sMjA+mr;B5V#MI;jiAfEGtUViPelh&wy$fJYD@<);T3K0RRO-Aq4;c literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_4.png b/Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_4.png new file mode 100644 index 0000000000000000000000000000000000000000..f988d5c494ff2379cc63a0d69d1c9a99ad600513 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@o&cW^SBC!#aY_s;Y#8=BF>G+V zYYY@;ED7=pW^j0RBMqd()5S4FVrp`N#H5Bo)}D>b$8I>yILMXkaZqBBB8v_a!zv~= U^`uVMXF#zopr0I^vg;s5{u literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_5.png b/Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_5.png new file mode 100644 index 0000000000000000000000000000000000000000..3b06ca0bf24107207ee8673f82b56b39d9b5dd55 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@o&cW^SBC!#aV!ig*ctY+F`V7K zwFD^6SQ6wH%;50sMjA+mr;B5V#MI;jiAfEGtUViPelh&wy$fJYD@<);T3K0RXl9AN~LU literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_6.png b/Resources/Textures/Interface/Targeting/Status/rightleg.rsi/rightleg_6.png new file mode 100644 index 0000000000000000000000000000000000000000..88368e0b007e87d73b923ae66161ba0b38b99d41 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@o&cW^SBC!#dU|@n!NGBHabMim zn*zldOM?7@862M7NCWBcba4!kn3|j*F{z=DwPz#qu^Ub^4ss=X9F$n3$fComdKI;Vst0LXmdKI;Vst0LX#gF+^ixa)Jcw7RH`aTq~G#Rq6Z=>zI!@O1TaS?83{1OW5lDMkPQ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/torso.rsi/meta.json b/Resources/Textures/Interface/Targeting/Status/torso.rsi/meta.json new file mode 100644 index 00000000000..491f5a0dfc2 --- /dev/null +++ b/Resources/Textures/Interface/Targeting/Status/torso.rsi/meta.json @@ -0,0 +1,38 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c7e14784b35b1a136351c396d3a546f461ee2451", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "torso_0" + }, + { + "name": "torso_1" + }, + { + "name": "torso_2" + }, + { + "name": "torso_3" + }, + { + "name": "torso_4" + }, + { + "name": "torso_5" + }, + { + "name": "torso_6" + }, + { + "name": "torso_7" + }, + { + "name": "torso_8" + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_0.png b/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_0.png new file mode 100644 index 0000000000000000000000000000000000000000..0ccc014503c5ed150a4846c769d47f0d7e08c7ae GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#vH|7lS#!0DRw*a+ zH|=S?50qjo3GxeOaCmkj4al+bba4#Pn3$X(k>udv>B->gaPvk4qw9eiH*PTO=PF@z zThO4?$>inbwSq}cPp@xn#2WG=;&_)z4*}Q$iB}IvOpS literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_1.png b/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_1.png new file mode 100644 index 0000000000000000000000000000000000000000..4bda9828e7428e911d08e5458785e2405f3c0320 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#L2(R|S1>Hw%aC5m zU{Q1NJy43VB*-tA!Qt7BG$6;y)5S4FV`6fGM3RGtrzeA}!_6BJjIIZ6+_=H8pR0t? zZ9#)lCzF?#*9s;*J-xmaeyL97*2=pMJYZ+2XJI?ath4wh&=dwwS3j3^P6EaloF)=woBFVwS)04r~;pUA9M%M#3Zrotl&sD-@$XbOX;tDnm{r-UW|(poHn literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_3.png b/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_3.png new file mode 100644 index 0000000000000000000000000000000000000000..262e5601785815a4a9adc34325e05524106ef688 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#aSjYC3K{m+F_ii- zOeop$4k*P~666=m;PC858jxe<>EaloF)=woBFVwS)04r~;pUA9M%M#3Zrotl&sD-@$XbOX;tDnm{r-UW|_D(GA literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_4.png b/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_4.png new file mode 100644 index 0000000000000000000000000000000000000000..627d16dccbb9e284fad67a10aa47c6de0865de81 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#aY_s;Y#8=BF_daD zq*%T<1C(Mc3GxeOaCmkj4al+bba4#Pn3$X(k>udv>B->gaPvk4qw9eiH*PTO=PF@z zThO4?$>inbwSq}cPp@xn#2WG=;&_)z4*}Q$iB}iXbcC literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_5.png b/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_5.png new file mode 100644 index 0000000000000000000000000000000000000000..64ab60165f46603c7e4296f059d5a583bf4b6ed3 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#aV!ig*ctY+F_f|} z#J_VB1xhiN1o;IsI6S+N2IN?Ix;TbtOiWIYNOJJ-^ki^#xOpRj(e=QM8#fsCbCoc< zEoe~cWb*RzTEV2Jr`NZ_FV(5sT6x!j2kZ>>ENn-abr$~wn!@1e>gTe~DWM4f0d*>a literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_6.png b/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_6.png new file mode 100644 index 0000000000000000000000000000000000000000..c7d377ffb2c9bdff113ca9abdfc878d85e7a2405 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#dU|@n!NGBHaaLAV z*XF-v1xhiN1o;IsI6S+N2IN?Ix;TbtOiWIYNOJJ-^ki^#xOpRj(e=QM8#fsCbCoc< yEoe~cWb*RzTEPS~s&9o~s#CeO@~#69*cs|s*p4#mEdB{Jg~8L+&t;ucLK6V6sw_YN literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_7.png b/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_7.png new file mode 100644 index 0000000000000000000000000000000000000000..c7d377ffb2c9bdff113ca9abdfc878d85e7a2405 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4SBC!#dU|@n!NGBHaaLAV z*XF-v1xhiN1o;IsI6S+N2IN?Ix;TbtOiWIYNOJJ-^ki^#xOpRj(e=QM8#fsCbCoc< yEoe~cWb*RzTEPS~s&9o~s#CeO@~#69*cs|s*p4#mEdB{Jg~8L+&t;ucLK6V6sw_YN literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_8.png b/Resources/Textures/Interface/Targeting/Status/torso.rsi/torso_8.png new file mode 100644 index 0000000000000000000000000000000000000000..bf0f5a312b1cfa4393069cda51b94a14850e5c7b GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvi2$DvSBC!#3m6!JgM&{nFzD&& z{byi^i;J_eveLMzz8R>7u_VYZn8D%MjWi&~%hSa%L}Oxdf<%&oN90LHR|ivFA4XRN zT^& Z!@?FWud}f^K0s3$JYD@<);T3K0RS=iF{JwbW=c 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Machines/limbgrower.rsi/limbgrower_openpanel.png b/Resources/Textures/Structures/Machines/limbgrower.rsi/limbgrower_openpanel.png new file mode 100644 index 0000000000000000000000000000000000000000..cc174c7d8b9612da38c3952579702f93c9c01961 GIT binary patch literal 3981 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Machines/limbgrower.rsi/limbgrower_unfill.png b/Resources/Textures/Structures/Machines/limbgrower.rsi/limbgrower_unfill.png new file mode 100644 index 0000000000000000000000000000000000000000..6aa57f247e2a662abf1fa970c6cc3a0d8688aff1 GIT binary patch literal 9104 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 HE(!k!t;RL{ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Machines/limbgrower.rsi/meta.json b/Resources/Textures/Structures/Machines/limbgrower.rsi/meta.json new file mode 100644 index 00000000000..a1f2b51b28e --- /dev/null +++ b/Resources/Textures/Structures/Machines/limbgrower.rsi/meta.json @@ -0,0 +1,85 @@ +{ + "version": 1, + "license": "GNU AGPL v3", + "copyright": "Taken from /tg/station at commit 85c26c1", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "limbgrower_fill", + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "limbgrower_unfill", + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "limbgrower_openpanel", + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "limbgrower_idleoff", + "delays": [ + [ + 0.3, + 0.3, + 0.3, + 0.3 + ] + ] + }, + { + "name": "limbgrower_idleon", + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "limbgrower_panelopen" + } + ] +} diff --git a/Resources/keybinds.yml b/Resources/keybinds.yml index 3b8158b7c7a..5f0ef2753a9 100644 --- a/Resources/keybinds.yml +++ b/Resources/keybinds.yml @@ -70,21 +70,27 @@ binds: - function: CameraRotateLeft type: State key: NumpadNum7 + mod1: Control - function: CameraRotateRight type: State key: NumpadNum9 + mod1: Control - function: CameraReset type: State key: NumpadNum8 + mod1: Control - function: ZoomOut type: State key: NumpadNum4 + mod1: Control - function: ZoomIn type: State key: NumpadNum6 + mod1: Control - function: ResetZoom type: State key: NumpadNum5 + mod1: Control # Misc - function: ShowEscapeMenu type: State @@ -584,3 +590,22 @@ binds: type: State key: MouseRight canFocus: true +# Targeting +- function: TargetHead + type: State + key: NumpadNum8 +- function: TargetTorso + type: State + key: NumpadNum5 +- function: TargetLeftArm + type: State + key: NumpadNum6 +- function: TargetRightArm + type: State + key: NumpadNum4 +- function: TargetLeftLeg + type: State + key: NumpadNum3 +- function: TargetRightLeg + type: State + key: NumpadNum1 From 67d262bcbde838cb1254fe843226960b570e2ab1 Mon Sep 17 00:00:00 2001 From: Roudenn Date: Tue, 29 Oct 2024 18:01:23 +0300 Subject: [PATCH 02/16] Fixes fix locale --- Content.Client/Backmen/Surgery/SurgeryBui.cs | 14 ++--- .../Backmen/Surgery/SurgeryWindow.xaml | 6 +- .../ru-RU/backmen/surgery/surgery-items.ftl | 33 ++++++++++ .../backmen/surgery/surgery-operations.ftl | 61 +++++++++++++++++++ .../ru-RU/backmen/surgery/surgery-ui.ftl | 19 ++++++ .../_Backmen/Entities/Surgery/surgeries.yml | 34 +++++++++-- .../Entities/Surgery/surgery_steps.yml | 32 +++++++++- 7 files changed, 182 insertions(+), 17 deletions(-) create mode 100644 Resources/Locale/ru-RU/backmen/surgery/surgery-items.ftl create mode 100644 Resources/Locale/ru-RU/backmen/surgery/surgery-operations.ftl create mode 100644 Resources/Locale/ru-RU/backmen/surgery/surgery-ui.ftl diff --git a/Content.Client/Backmen/Surgery/SurgeryBui.cs b/Content.Client/Backmen/Surgery/SurgeryBui.cs index 10bd64e5e0a..f75c3fa1426 100644 --- a/Content.Client/Backmen/Surgery/SurgeryBui.cs +++ b/Content.Client/Backmen/Surgery/SurgeryBui.cs @@ -76,7 +76,7 @@ private void Update(SurgeryBuiState state) { _window = new SurgeryWindow(); _window.OnClose += Close; - _window.Title = "Surgery"; + _window.Title = Loc.GetString("surgery-ui-window-title"); _window.PartsButton.OnPressed += _ => { @@ -246,7 +246,7 @@ private void OnSurgeryPressed(Entity surgery, NetEntity netPar var msg = new FormattedMessage(); var surgeryName = _entities.GetComponent(requirement).EntityName; - msg.AddMarkup($"[bold]Requires: {surgeryName}[/bold]"); + msg.AddMarkup($"[bold]{Loc.GetString("surgery-ui-window-require")}: {surgeryName}[/bold]"); label.Set(msg, null); _window.Steps.AddChild(label); @@ -368,16 +368,16 @@ private void RefreshUI() switch (reason) { case StepInvalidReason.MissingSkills: - stepName.AddMarkup(" [color=red](Missing surgery skill)[/color]"); + stepName.AddMarkup($" [color=red]{Loc.GetString("surgery-ui-window-steps-error-skills")}[/color]"); break; case StepInvalidReason.NeedsOperatingTable: - stepName.AddMarkup(" [color=red](Needs operating table)[/color]"); + stepName.AddMarkup($" [color=red]{Loc.GetString("surgery-ui-window-steps-error-table")}[/color]"); break; case StepInvalidReason.Armor: - stepName.AddMarkup(" [color=red](Remove their armor!)[/color]"); + stepName.AddMarkup($" [color=red]{Loc.GetString("surgery-ui-window-steps-error-armor")}[/color]"); break; case StepInvalidReason.MissingTool: - stepName.AddMarkup(" [color=red](Missing tool)[/color]"); + stepName.AddMarkup($" [color=red]{Loc.GetString("surgery-ui-window-steps-error-tools")}[/color]"); break; } } @@ -406,7 +406,7 @@ private void UpdateDisabledPanel() _window.DisabledPanel.Visible = true; var text = new FormattedMessage(); - text.AddMarkup("[color=red][font size=16]They need to be lying down![/font][/color]"); + text.AddMarkup($"[color=red][font size=16]{Loc.GetString("surgery-ui-window-steps-error-laying")}[/font][/color]"); _window.DisabledLabel.SetMessage(text); _window.DisabledPanel.MouseFilter = MouseFilterMode.Stop; } diff --git a/Content.Client/Backmen/Surgery/SurgeryWindow.xaml b/Content.Client/Backmen/Surgery/SurgeryWindow.xaml index af19d46ef6d..103ce02232e 100644 --- a/Content.Client/Backmen/Surgery/SurgeryWindow.xaml +++ b/Content.Client/Backmen/Surgery/SurgeryWindow.xaml @@ -6,11 +6,11 @@ MinSize="400 400"> -