diff --git a/Content.Server/Palmtree/CookieClicker/Components/CookieClickerComponent.cs b/Content.Server/Palmtree/CookieClicker/Components/CookieClickerComponent.cs new file mode 100644 index 00000000000..fa98b07567d --- /dev/null +++ b/Content.Server/Palmtree/CookieClicker/Components/CookieClickerComponent.cs @@ -0,0 +1,10 @@ +namespace Content.Server.Palmtree.CookieClicker +{ + [RegisterComponent] + public partial class ClickCounterComponent : Component + { + [DataField("count")] + [ViewVariables(VVAccess.ReadWrite)] + public int count = 0; + } +} diff --git a/Content.Server/Palmtree/CookieClicker/Components/IncrementorComponent.cs b/Content.Server/Palmtree/CookieClicker/Components/IncrementorComponent.cs new file mode 100644 index 00000000000..c5b0f6d5268 --- /dev/null +++ b/Content.Server/Palmtree/CookieClicker/Components/IncrementorComponent.cs @@ -0,0 +1,6 @@ +namespace Content.Server.Palmtree.CookieClicker +{ + [RegisterComponent] + public partial class IncrementorComponent : Component {} + +} diff --git a/Content.Server/Palmtree/CookieClicker/CookieClickerSystem.cs b/Content.Server/Palmtree/CookieClicker/CookieClickerSystem.cs new file mode 100644 index 00000000000..af21ef61038 --- /dev/null +++ b/Content.Server/Palmtree/CookieClicker/CookieClickerSystem.cs @@ -0,0 +1,22 @@ +using Content.Server.Palmtree.CookieClicker; +using Content.Shared.Interaction; + +namespace Content.Server.Palmtree.CookieClicker.CounterSystem +{ + public class CookieClickerSystem : EntitySystem + { + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnAfterInteract); + } + private void OnAfterInteract(EntityUid uid, IncrementorComponent component, AfterInteractEvent args) + { + if (!args.CanReach || args.Target == null || args.User == args.Target || !TryComp(args.Target, out ClickCounterComponent? counter)) + { + return; + } + counter.count++; + } + } +} diff --git a/Content.Server/Palmtree/Surgery/Components/MindExchangerComponent.cs b/Content.Server/Palmtree/Surgery/Components/MindExchangerComponent.cs new file mode 100644 index 00000000000..9f888ccdb36 --- /dev/null +++ b/Content.Server/Palmtree/Surgery/Components/MindExchangerComponent.cs @@ -0,0 +1,14 @@ +namespace Content.Server.Palmtree.Surgery +{ + [RegisterComponent] + public partial class MindExchangerComponent : Component + { + [DataField("Mind")] + [ViewVariables(VVAccess.ReadWrite)] + public EntityUid mind = default!; + + [DataField("ContainsMind")] + [ViewVariables(VVAccess.ReadWrite)] + public bool occupied = false; + } +} \ No newline at end of file diff --git a/Content.Server/Palmtree/Surgery/Components/TendWoundComponent.cs b/Content.Server/Palmtree/Surgery/Components/TendWoundComponent.cs new file mode 100644 index 00000000000..4c2795db171 --- /dev/null +++ b/Content.Server/Palmtree/Surgery/Components/TendWoundComponent.cs @@ -0,0 +1,12 @@ +using Content.Shared.Damage; + +namespace Content.Server.Palmtree.Surgery +{ + [RegisterComponent] + public partial class PTendWoundsComponent : Component + { + [DataField("healThisMuch", required: true)] // Sorry I can't stop making silly names + [ViewVariables(VVAccess.ReadWrite)] + public DamageSpecifier healThisMuch = default!; + } +} \ No newline at end of file diff --git a/Content.Server/Palmtree/Surgery/Components/ValidPatientComponent.cs b/Content.Server/Palmtree/Surgery/Components/ValidPatientComponent.cs new file mode 100644 index 00000000000..eac01a88e1e --- /dev/null +++ b/Content.Server/Palmtree/Surgery/Components/ValidPatientComponent.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; + +namespace Content.Server.Palmtree.Surgery +{ + [RegisterComponent] + public partial class PPatientComponent : Component //"PPatient" because wizden might add surgery down the line, so I'm doing this to avoid conflicts. + {// I'll make this better later with a proper list of steps, I just need a first version for now + [DataField("incised")] + [ViewVariables(VVAccess.ReadWrite)] + public bool incised = false; + + [DataField("retracted")] + [ViewVariables(VVAccess.ReadWrite)] + public bool retracted = false; + + [DataField("clamped")] + [ViewVariables(VVAccess.ReadWrite)] + public bool clamped = false; + + public List procedures = new List(); + } +} diff --git a/Content.Server/Palmtree/Surgery/Components/ValidSurgeryToolComponent.cs b/Content.Server/Palmtree/Surgery/Components/ValidSurgeryToolComponent.cs new file mode 100644 index 00000000000..e3f4b21f59c --- /dev/null +++ b/Content.Server/Palmtree/Surgery/Components/ValidSurgeryToolComponent.cs @@ -0,0 +1,37 @@ +using Content.Shared.Damage; +using Robust.Shared.Audio; + +namespace Content.Server.Palmtree.Surgery +{ + [RegisterComponent] + public partial class PSurgeryToolComponent : Component + { + [DataField("kind")] + [ViewVariables(VVAccess.ReadWrite)] + public string kind = "scalpel"; + + [DataField("infectionDamage")] + [ViewVariables(VVAccess.ReadWrite)] + public float infectionDamage = 1.0f; + + [DataField("useDelay")] + [ViewVariables(VVAccess.ReadWrite)] + public float useDelay = 3.0f; + + [DataField("bleedAmountOnUse")] + [ViewVariables(VVAccess.ReadWrite)] + public float bleedAmountOnUse = 0.0f; // Cutting tools usually are the ones that cause bleed + + [DataField("damageOnUse", required: true)] // Tools damage the patient on use except in special cases. + [ViewVariables(VVAccess.ReadWrite)] + public DamageSpecifier damageOnUse = default!; + + [DataField("audioStart")] + [ViewVariables(VVAccess.ReadWrite)] + public SoundSpecifier? audioStart = null; + + [DataField("audioEnd")] + [ViewVariables(VVAccess.ReadWrite)] + public SoundSpecifier? audioEnd = null; + } +} diff --git a/Content.Server/Palmtree/Surgery/SurgerySystem.cs b/Content.Server/Palmtree/Surgery/SurgerySystem.cs new file mode 100644 index 00000000000..59adfd4e01c --- /dev/null +++ b/Content.Server/Palmtree/Surgery/SurgerySystem.cs @@ -0,0 +1,253 @@ +using System.Collections.Generic; +using System.Linq; +using Content.Server.Palmtree.Surgery; +using Content.Server.Body.Systems; +using Content.Server.Popups; +using Content.Server.Mind; +using Content.Shared.Atmos.Rotting; +using Content.Shared.Palmtree.Surgery; +using Content.Shared.Interaction; +using Content.Shared.Popups; +using Content.Shared.Damage; +using Content.Shared.DoAfter; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; +//using Content.Shared.Players; +using Content.Shared.Standing; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Components; +using Content.Shared.Mobs.Systems; +using Content.Shared.Bed.Sleep; +using Robust.Server.Player; +using Robust.Shared.Audio; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Player; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +// It's all very crude at the moment, but it actually works now. + +/* + * PalmtreeMed surgery by TropicalOwl + * The current code is grotesque, stuff is hardcoded and it looks nothing like how I want it to actually look like in the final version. + * Additionally please do note this was programmed by someone who had very little contact with C# prior to this, if anyone want to make improvements or rework this, don't need to ask for permission, I'm not gonna pretend I know what I'm doing. + * + * This is also a port from a non-ee code, so stuff might break as well. + * You've been warned + * + * On the plus side, it's VERY easy to remove this from the game if someone comes and makes a better system. + */ + + + +namespace Content.Server.Palmtree.Surgery.SurgerySystem +{ + public class PSurgerySystem : SharedSurgerySystem + { + // These procedures can be prototypes later, for now I'll hardcode them because I have no idea how to do it otherwise. + // Remind me to try and make them prototypes later, please! + Dictionary procedures = new Dictionary + { + {"TendWounds", new string[]{"scalpel"}}, + {"FilterBlood", new string[]{"scalpel", "retractor", "saw"}}, + {"SawBones", new string[]{"scalpel", "retractor"}}, // This comes before letting people saw bones + {"BrainTransfer", new string[]{"scalpel", "retractor", "saw"}}, + {"ReduceRotting", new string[]{"scalpel", "retractor"}}, + {"InsertAugment", new string[]{"scapel", "retractor", "saw"}}, // This procedure is used for augments and implants + {"RemoveAugment", new string[]{"scalpel", "retractor", "saw", "drill"}} // This procedure removes a person's augments, breaking them + }; + + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly DamageableSystem _damageableSystem = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedMindSystem _sharedmind = default!; + [Dependency] private readonly MindSystem _mind = default!; + [Dependency] private readonly StandingStateSystem _standing = default!; + //[Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private readonly SharedRottingSystem _rot = default!; + [Dependency] private readonly BloodstreamSystem _blood = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnAfterInteract); + SubscribeLocalEvent(OnProcedureFinished); + } + private void OnProcedureFinished(EntityUid uid, PSurgeryToolComponent tool, SurgeryDoAfterEvent args) + { + if (args.Cancelled || args.Target == null || !TryComp(args.Target, out PPatientComponent? patient)) return; + if (patient.procedures.Count == 0) + { + if (tool.kind == "scalpel") + { + _popupSystem.PopupEntity("You successfully perform an incision!", args.User, PopupType.Small); + patient.procedures.Add("scalpel"); + _damageableSystem.TryChangeDamage(args.Target, tool.damageOnUse, true, origin: uid); + _blood.TryModifyBleedAmount((EntityUid) args.Target, tool.bleedAmountOnUse); + _audio.PlayPvs(tool.audioEnd, args.User); + } + else + { + _popupSystem.PopupEntity("Perform an incision first!", args.User, PopupType.Small); + } + } + else + { // Procedure checks go here + bool repeatableProcedure = false; // If it is repeatable it won't add to the "crafting" of the surgery + bool damageOnFinish = true; // Check if it will damage the target by the damage specified in the prototypes + bool failedProcedure = false; // Check if it has failed. + switch(tool.kind) + { + case "scalpel": + _popupSystem.PopupEntity("You perform an incision!", args.User, PopupType.Small); + break; + case "hemostat": + repeatableProcedure = true; // You can pinch people over and over + _popupSystem.PopupEntity("You clamp the patient's bleeders!", args.User, PopupType.Small); + break; + case "retractor": + _popupSystem.PopupEntity("You retract the patient's skin!", args.User, PopupType.Small); + break; + case "saw": + if (patient.procedures.SequenceEqual(procedures["SawBones"])) + { + _popupSystem.PopupEntity("You saw the patient's bones!", args.User, PopupType.Small); + } + else + { + _popupSystem.PopupEntity("You can't saw your patient's bones right now!", args.User, PopupType.Small); + failedProcedure = true; + } + break; + case "cautery": + patient.procedures.Clear(); + repeatableProcedure = true; // You can just burn people over and over with a cautery, yeah. + break; + case "brainlink": + if (patient.procedures.SequenceEqual(procedures["BrainTransfer"])) + { + bool targetHasMind = _sharedmind.TryGetMind((EntityUid) args.Target, out var targetMindId, out var targetMind); + if (targetHasMind) + { + _mind.TransferTo(targetMindId, uid, mind: targetMind); + } + } + else + { + failedProcedure = true; + _popupSystem.PopupEntity("You can't take the patient's mind right now.", args.User, PopupType.Small); + } + break; + case "phantomlink": // Upgraded version of the ghost shell, can only be admin spawned + if (patient.procedures.SequenceEqual(procedures["BrainTransfer"])) + { + bool targetHasMind = _sharedmind.TryGetMind((EntityUid) args.Target, out var targetMindId, out var targetMind); + bool deviceHasMind = _sharedmind.TryGetMind(uid, out var deviceMindId, out var deviceMind); + if (targetHasMind && deviceHasMind) + { + failedProcedure = true; + _popupSystem.PopupEntity("You can't take the patient's mind right now, your link is occupied.", args.User, PopupType.Small); + } + else + { + if (targetHasMind) + { + _mind.TransferTo(targetMindId, uid, mind: targetMind); + } + if (deviceHasMind) + { + _mind.TransferTo(deviceMindId, args.Target, mind: deviceMind); + } + } + } + else + { + failedProcedure = true; + _popupSystem.PopupEntity("You can't take the patient's mind right now.", args.User, PopupType.Small); + } + break; + case "bloodfilter": + if (patient.procedures.Contains("retractor")) + { + _popupSystem.PopupEntity("You filter the contaminants from the subject's blood.", args.User, PopupType.Small); + repeatableProcedure = true; + } + else + { + _popupSystem.PopupEntity("You can't filter the patient's blood right now.", args.User, PopupType.Small); + failedProcedure = true; + } + break; + case "antirot": + if (patient.procedures.Contains("retractor")) + { + _popupSystem.PopupEntity("You spray the anti-rot on the patient.", args.User, PopupType.Small); + _rot.ReduceAccumulator((EntityUid) args.Target, TimeSpan.FromSeconds(120)); + repeatableProcedure = true; + } + else + { + _popupSystem.PopupEntity("You can't use the spray right now.", args.User, PopupType.Small); + failedProcedure = true; + } + break; + default: + _popupSystem.PopupEntity("If you see this, contact TropicalOwl and tell which tool you used when seeing this, this is an error message.", args.User, PopupType.Small); + break; + } + if (failedProcedure) + { + return; + } + if (!repeatableProcedure) + { + patient.procedures.Add(tool.kind); + } + if (damageOnFinish) + { + _damageableSystem.TryChangeDamage(args.Target, tool.damageOnUse, true, origin: uid); + _blood.TryModifyBleedAmount((EntityUid) args.Target, tool.bleedAmountOnUse); + } + _audio.PlayPvs(tool.audioEnd, args.User); + } + } + private void OnAfterInteract(EntityUid uid, PSurgeryToolComponent tool, AfterInteractEvent args) // Turn this into FTL strings later + { + bool patientHasState = TryComp(args.Target, out MobStateComponent? patientState); + if (!args.CanReach || args.Target == null) // We already check if target is null, it's okay to perform direct conversion to non-nullable + { + return; + } + if (!TryComp(args.Target, out PPatientComponent? patient) && patientHasState) + { + _popupSystem.PopupEntity("You cannot perform surgery on this!", args.User, PopupType.Small); + return; + } + if (!_standing.IsDown((EntityUid) args.Target)) + { + _popupSystem.PopupEntity("The patient must be laying down and asleep!", args.User, PopupType.Small); + return; + } + if (!TryComp(args.Target, out SleepingComponent? sleep) && !_mobState.IsIncapacitated((EntityUid) args.Target, patientState)) + { + _popupSystem.PopupEntity("The patient must be asleep!", args.User, PopupType.Small); + return; + } + if (args.User == args.Target) + { + _popupSystem.PopupEntity("You cannot operate yourself!", args.User, PopupType.Small); + return; + } + var doAfterEventArgs = new DoAfterArgs(EntityManager, args.User, tool.useDelay, new SurgeryDoAfterEvent(), uid, target: args.Target) + { + NeedHand = true, + //BreakOnMove = true, + //BreakOnWeightlessMove = true, + }; + _audio.PlayPvs(tool.audioStart, args.User); + _doAfter.TryStartDoAfter(doAfterEventArgs); + } + } +} diff --git a/Content.Shared/Palmtree/Surgery/SharedSurgery.cs b/Content.Shared/Palmtree/Surgery/SharedSurgery.cs new file mode 100644 index 00000000000..11b85e34fac --- /dev/null +++ b/Content.Shared/Palmtree/Surgery/SharedSurgery.cs @@ -0,0 +1,11 @@ +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; + +namespace Content.Shared.Palmtree.Surgery +{ + public abstract partial class SharedSurgerySystem : EntitySystem + { + [Serializable, NetSerializable] + protected sealed partial class SurgeryDoAfterEvent : SimpleDoAfterEvent {} + } +} diff --git a/Resources/Audio/Palmtree/Items/Medical/cautery1.ogg b/Resources/Audio/Palmtree/Items/Medical/cautery1.ogg new file mode 100644 index 00000000000..7c4ae1f76c2 Binary files /dev/null and b/Resources/Audio/Palmtree/Items/Medical/cautery1.ogg differ diff --git a/Resources/Audio/Palmtree/Items/Medical/cautery2.ogg b/Resources/Audio/Palmtree/Items/Medical/cautery2.ogg new file mode 100644 index 00000000000..5e5eebfd15e Binary files /dev/null and b/Resources/Audio/Palmtree/Items/Medical/cautery2.ogg differ diff --git a/Resources/Audio/Palmtree/Items/Medical/hemostat1.ogg b/Resources/Audio/Palmtree/Items/Medical/hemostat1.ogg new file mode 100644 index 00000000000..bb8bb2ad69d Binary files /dev/null and b/Resources/Audio/Palmtree/Items/Medical/hemostat1.ogg differ diff --git a/Resources/Audio/Palmtree/Items/Medical/organ1.ogg b/Resources/Audio/Palmtree/Items/Medical/organ1.ogg new file mode 100644 index 00000000000..7001052287d Binary files /dev/null and b/Resources/Audio/Palmtree/Items/Medical/organ1.ogg differ diff --git a/Resources/Audio/Palmtree/Items/Medical/organ2.ogg b/Resources/Audio/Palmtree/Items/Medical/organ2.ogg new file mode 100644 index 00000000000..9c181850c71 Binary files /dev/null and b/Resources/Audio/Palmtree/Items/Medical/organ2.ogg differ diff --git a/Resources/Audio/Palmtree/Items/Medical/retractor1.ogg b/Resources/Audio/Palmtree/Items/Medical/retractor1.ogg new file mode 100644 index 00000000000..770abc53da0 Binary files /dev/null and b/Resources/Audio/Palmtree/Items/Medical/retractor1.ogg differ diff --git a/Resources/Audio/Palmtree/Items/Medical/retractor2.ogg b/Resources/Audio/Palmtree/Items/Medical/retractor2.ogg new file mode 100644 index 00000000000..7361df272f3 Binary files /dev/null and b/Resources/Audio/Palmtree/Items/Medical/retractor2.ogg differ diff --git a/Resources/Audio/Palmtree/Items/Medical/saw.ogg b/Resources/Audio/Palmtree/Items/Medical/saw.ogg new file mode 100644 index 00000000000..3f6cec239aa Binary files /dev/null and b/Resources/Audio/Palmtree/Items/Medical/saw.ogg differ diff --git a/Resources/Audio/Palmtree/Items/Medical/scalpel1.ogg b/Resources/Audio/Palmtree/Items/Medical/scalpel1.ogg new file mode 100644 index 00000000000..8f0dc6f0d4a Binary files /dev/null and b/Resources/Audio/Palmtree/Items/Medical/scalpel1.ogg differ diff --git a/Resources/Audio/Palmtree/Items/Medical/scalpel2.ogg b/Resources/Audio/Palmtree/Items/Medical/scalpel2.ogg new file mode 100644 index 00000000000..31d891a2eb3 Binary files /dev/null and b/Resources/Audio/Palmtree/Items/Medical/scalpel2.ogg differ diff --git a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml index c07b0eccf19..90aa624ddad 100644 --- a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml +++ b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml @@ -12,6 +12,7 @@ - id: Cautery - id: Retractor - id: Scalpel + - id: SurgeryItemBloodFilter - type: entity id: ClothingBackpackDuffelCBURNFilled diff --git a/Resources/Prototypes/Catalog/Fills/Crates/medical.yml b/Resources/Prototypes/Catalog/Fills/Crates/medical.yml index 8b1f7fade32..bfeb54b5599 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/medical.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/medical.yml @@ -68,6 +68,7 @@ - id: Saw - id: Hemostat - id: ClothingMaskSterile + - id: SurgeryItemBloodFilter - type: entity id: CrateMedicalScrubs diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 29234ea34cf..646f5340ddd 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -1211,6 +1211,7 @@ description: The genetic bipedal ancestor of... Uh... Something. Yeah, there's definitely something on the station that descended from whatever this is. abstract: true components: + - type: PPatient - type: CombatMode - type: Inventory templateId: monkey diff --git a/Resources/Prototypes/Entities/Mobs/Species/human.yml b/Resources/Prototypes/Entities/Mobs/Species/human.yml index ac373725ce4..7a1cfdceef0 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/human.yml @@ -5,6 +5,7 @@ name: Urist McHands abstract: true components: + - type: PPatient # Allows this mob to receive operations - type: Hunger - type: Icon # It will not have an icon in the adminspawn menu without this. Body parts seem fine for whatever reason. sprite: Mobs/Species/Human/parts.rsi diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/surgery.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/surgery.yml index c81768da4d3..5b0c31eaf73 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/surgery.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/surgery.yml @@ -20,6 +20,17 @@ parent: BaseToolSurgery description: A surgical tool used to cauterize open wounds. components: + - type: PSurgeryTool # Palmtree change - I don't need to explain this one, do I? + useDelay: 1 + kind: cautery + audioStart: + path: "/Audio/Palmtree/Items/Medical/cautery1.ogg" + audioEnd: + path: "/Audio/Palmtree/Items/Medical/cautery2.ogg" + bleedAmountOnUse: -15 + damageOnUse: + types: + Heat: 1 # Burns! - type: Sprite sprite: Objects/Specific/Medical/Surgery/cautery.rsi state: cautery @@ -72,6 +83,15 @@ parent: BaseToolSurgery description: A surgical tool used to make incisions into flesh. components: + - type: PSurgeryTool # Palmtree change - I don't need to explain this one, do I? + kind: scalpel + audioStart: + path: "/Audio/Palmtree/Items/Medical/scalpel1.ogg" + audioEnd: + path: "/Audio/Palmtree/Items/Medical/scalpel2.ogg" + damageOnUse: + types: + Slash: 15 # Chop chop - type: Sharp butcherDelayModifier: 1.5 # Butchering with a scalpel, regardless of the type, will take 50% longer - type: Utensil @@ -149,6 +169,15 @@ parent: BaseToolSurgery description: A surgical tool used to hold open incisions. components: + - type: PSurgeryTool # Palmtree change - I don't need to explain this one, do I? + kind: retractor + audioStart: + path: "/Audio/Palmtree/Items/Medical/retractor1.ogg" + audioEnd: + path: "/Audio/Palmtree/Items/Medical/retractor2.ogg" + damageOnUse: # Ow it pinches + types: + Blunt: 5 - type: Sprite sprite: Objects/Specific/Medical/Surgery/scissors.rsi state: retractor @@ -162,6 +191,18 @@ parent: Retractor description: A surgical tool used to compress blood vessels to prevent bleeding. components: + - type: PSurgeryTool # Palmtree change - I don't need to explain this one, do I? + useDelay: 1 + kind: hemostat # Even if the hemostat is in the same category as a retractor, it is used for different things. + audioStart: + path: "/Audio/Palmtree/Items/Medical/hemostat1.ogg" + audioEnd: + path: "/Audio/Palmtree/Items/Medical/hemostat1.ogg" + damageOnUse: # Ow it pinches + groups: + Brute: -9 + Burn: -12 + bleedAmountOnUse: -15 - type: Sprite state: hemostat - type: Item @@ -182,6 +223,15 @@ parent: BaseToolSurgery description: For cutting wood and other objects to pieces. Or sawing bones, in case of emergency. components: + - type: PSurgeryTool # Palmtree change - I don't need to explain this one, do I? + audioStart: + path: "/Audio/Palmtree/Items/Medical/scalpel1.ogg" + audioEnd: + path: "/Audio/Palmtree/Items/Medical/scalpel2.ogg" + kind: saw + damageOnUse: + types: + Blunt: 30 # Having your bones affected gotta hurt a lot - type: Sharp - type: Utensil types: @@ -245,6 +295,11 @@ parent: Saw description: For heavy duty cutting. components: + - type: PSurgeryTool + audioStart: + path: "/Audio/Palmtree/Items/Medical/saw1.ogg" + audioEnd: + path: "/Audio/Palmtree/Items/Medical/scalpel2.ogg" - type: Sprite state: electric - type: Item diff --git a/Resources/Prototypes/Palmtree/Entities/Objects/Specific/Medical/surgery.yml b/Resources/Prototypes/Palmtree/Entities/Objects/Specific/Medical/surgery.yml new file mode 100644 index 00000000000..cd867136239 --- /dev/null +++ b/Resources/Prototypes/Palmtree/Entities/Objects/Specific/Medical/surgery.yml @@ -0,0 +1,49 @@ +- type: entity + name: blood filter + parent: BaseItem + id: SurgeryItemBloodFilter + description: A surgical tool to perform dialysis on a poisoned patient. + components: + - type: Sprite + sprite: Palmtree/Objects/Specific/Medical/surgery.rsi + state: bloodfilter + - type: Item + storedRotation: 90 + - type: PSurgeryTool # Palmtree change - I don't need to explain this one, do I? + audioStart: + path: "/Audio/Effects/beep1.ogg" + audioEnd: + path: "/Audio/Effects/double_beep.ogg" + kind: bloodfilter + damageOnUse: + types: + Poison: -15 + useDelay: 3 + - type: Tag + tags: + - SurgeryTool + +- type: entity + name: anti-rot spray + parent: BaseItem + id: SurgeryItemAntiRot + description: A surgical spray used to reduce rot with a NT patented compound. May be toxic. + components: + - type: Sprite + sprite: Palmtree/Objects/Specific/Medical/surgery.rsi + state: antirot + - type: Item + storedRotation: 90 + - type: PSurgeryTool # Palmtree change - I don't need to explain this one, do I? + useDelay: 1 + audioStart: + path: "/Audio/Effects/spray3.ogg" + audioEnd: + path: "/Audio/Effects/spray2.ogg" + kind: antirot + damageOnUse: + types: + Poison: 5 + - type: Tag + tags: + - SurgeryTool diff --git a/Resources/Textures/Palmtree/Objects/Specific/Medical/surgery.rsi/antirot.png b/Resources/Textures/Palmtree/Objects/Specific/Medical/surgery.rsi/antirot.png new file mode 100644 index 00000000000..5baf82854f0 Binary files /dev/null and b/Resources/Textures/Palmtree/Objects/Specific/Medical/surgery.rsi/antirot.png differ diff --git a/Resources/Textures/Palmtree/Objects/Specific/Medical/surgery.rsi/bloodfilter.png b/Resources/Textures/Palmtree/Objects/Specific/Medical/surgery.rsi/bloodfilter.png new file mode 100644 index 00000000000..d390661b0b0 Binary files /dev/null and b/Resources/Textures/Palmtree/Objects/Specific/Medical/surgery.rsi/bloodfilter.png differ diff --git a/Resources/Textures/Palmtree/Objects/Specific/Medical/surgery.rsi/meta.json b/Resources/Textures/Palmtree/Objects/Specific/Medical/surgery.rsi/meta.json new file mode 100644 index 00000000000..72e18463b04 --- /dev/null +++ b/Resources/Textures/Palmtree/Objects/Specific/Medical/surgery.rsi/meta.json @@ -0,0 +1,17 @@ +{ + "version": 1, + "license": "GPL-3.0", + "copyright": "Taken from TGstation", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "bloodfilter" + }, + { + "name": "antirot" + } + ] +}