diff --git a/Content.Server/Palmtree/Surgery/SurgerySystem.cs b/Content.Server/Palmtree/Surgery/SurgerySystem.cs index 7f658ae7c20..57bab4257ae 100644 --- a/Content.Server/Palmtree/Surgery/SurgerySystem.cs +++ b/Content.Server/Palmtree/Surgery/SurgerySystem.cs @@ -4,6 +4,7 @@ using Content.Server.Body.Systems; using Content.Server.Popups; using Content.Server.Mind; +using Content.Shared.Inventory; using Content.Shared.Atmos.Rotting; using Content.Shared.Palmtree.Surgery; using Content.Shared.Interaction; @@ -63,7 +64,7 @@ public class PSurgerySystem : SharedSurgerySystem [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 InventorySystem _inventory = default!; [Dependency] private readonly SharedRottingSystem _rot = default!; [Dependency] private readonly BloodstreamSystem _blood = default!; [Dependency] private readonly IGameTiming _timing = default!; @@ -241,6 +242,8 @@ private void OnProcedureFinished(EntityUid uid, PSurgeryToolComponent tool, Surg } private void OnAfterInteract(EntityUid uid, PSurgeryToolComponent tool, AfterInteractEvent args) // Turn this into FTL strings later { + int surgeryTimeMultiplier = 1; + bool messageShown = false; // Avoid pop up stacking 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 { @@ -248,29 +251,45 @@ private void OnAfterInteract(EntityUid uid, PSurgeryToolComponent tool, AfterInt } 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)) + if (_inventory.TryGetSlotEntity((EntityUid) args.Target, "outerClothing", out var outer) || _inventory.TryGetSlotEntity((EntityUid) args.Target, "jumpsuit", out var jumpsuit)) { - _popupSystem.PopupEntity("The patient must be laying down and asleep!", args.User, PopupType.Small); + _popupSystem.PopupEntity("Remove the patient's clothes first!", args.User, PopupType.MediumCaution); return; } - if (!TryComp(args.Target, out SleepingComponent? sleep) && !_mobState.IsIncapacitated((EntityUid) args.Target, patientState)) + if (args.User == args.Target) // I've reordered the checks so that the most important modifiers are warned about first. { - _popupSystem.PopupEntity("The patient must be asleep!", args.User, PopupType.Small); - return; + if (!messageShown) + { + _popupSystem.PopupEntity("You begin operating yourself, this isn't exactly ideal.", args.User, PopupType.MediumCaution); + messageShown = true; + } + surgeryTimeMultiplier += 3; } - if (args.User == args.Target) + if (!_standing.IsDown((EntityUid) args.Target)) { - _popupSystem.PopupEntity("You cannot operate yourself!", args.User, PopupType.Small); - return; + if (!messageShown) + { + _popupSystem.PopupEntity("The patient should be laying down!", args.User, PopupType.MediumCaution); + messageShown = true; + } + surgeryTimeMultiplier += 3; + } + if (!TryComp(args.Target, out SleepingComponent? sleep) && !_mobState.IsIncapacitated((EntityUid) args.Target, patientState)) + { + if (!messageShown) + { + _popupSystem.PopupEntity("You begin the procedure with them awake, this is gonna hurt.", args.User, PopupType.MediumCaution); + messageShown = true; + } + surgeryTimeMultiplier += 1; } - var doAfterEventArgs = new DoAfterArgs(EntityManager, args.User, tool.useDelay, new SurgeryDoAfterEvent(), uid, target: args.Target) + var doAfterEventArgs = new DoAfterArgs(EntityManager, args.User, tool.useDelay * surgeryTimeMultiplier, new SurgeryDoAfterEvent(), uid, target: args.Target) { NeedHand = true, - //BreakOnMove = true, - //BreakOnWeightlessMove = true, + BreakOnUserMove = true, + BreakOnTargetMove = true, }; _audio.PlayPvs(tool.audioStart, args.User); _doAfter.TryStartDoAfter(doAfterEventArgs); diff --git a/Resources/Prototypes/Guidebook/medical.yml b/Resources/Prototypes/Guidebook/medical.yml index 95a4f1ca75f..cbacb9c4932 100644 --- a/Resources/Prototypes/Guidebook/medical.yml +++ b/Resources/Prototypes/Guidebook/medical.yml @@ -7,6 +7,7 @@ - Chemist - Cloning - Cryogenics + - Surgery # Syndicate change - type: guideEntry id: Medical Doctor @@ -48,3 +49,9 @@ id: AdvancedBrute name: guide-entry-brute text: "/ServerInfo/Guidebook/Medical/AdvancedBrute.xml" +# Syndicate change start +- type: guideEntry + id: Surgery + name: Surgery + text: "/ServerInfo/Palmtree/Medical/Surgery.xml" +# Syndicate change end diff --git a/Resources/ServerInfo/Palmtree/Medical/Surgery.xml b/Resources/ServerInfo/Palmtree/Medical/Surgery.xml new file mode 100644 index 00000000000..cd51e5a5045 --- /dev/null +++ b/Resources/ServerInfo/Palmtree/Medical/Surgery.xml @@ -0,0 +1,48 @@ + +# Surgery +Let's say that whatever patient arrives from the station straight into medbay is in a really bad shape. You have several options, clone them if they're dead, apply a mix of chemicals, topical medicine or even use the cryo tube with cryoxadone. There is a downside to those options however, all of them require specific external resources that aren't exactly abundant and a constantly running power supply. + +That's where surgery comes in, it will allow you to treat the basic damages of your patients easily (albeit not as effective as every other method above) and it will even allow you to bring people who have rotted for long periods of time back to life. + + + + + + + + + + +## The Basics +Performing surgery is done by steps, some steps are static while others are interchangeable, meaning they can be done alongside a more advanced procedure. + +Every procedure starts with an incision and ends with cauterization, if you screw up at any point you can cauterize the patient and try again. The most basic procedure is tend wounds, it is done by using a hemostat at any point during the surgery, doing so also clamps the bleeders to stop your patient from bleeding out. + + + + + +## Procedure conditions +Poor condition modifiers stacks and makes each step get progressively slower, the worst case scenario is if you were to do surgery on yourself while standing up and awake, and the best case scenario would be if you were doing surgery on someone else while they are laying down and sedated. + +You also need to undress people before performing surgery. + +## Transplants +If someone dies and doesn't get revived in time, their heart rot and soon does the rest of their organs, which get manifested in different types of damages (asphyxiation for lungs and poison for liver), lucky you, you should be prepared by now to deal exactly with that, these sorts of procedures should be done in this exact order, and the only tool you may optionally use during it is the hemostat to stop the patient from bleeding if they start to. + +In other words, if you can't shock someone due to rot you give them a new heart, if you can't shock someone due to excessive asphyxiation give them new lungs and if you can't shock someone because of poison give them a new liver. + + + + + + + +Additionally, you can also use the phantomlink card instead of an organ during that step to transfer someone's mind from and into the body being operated. The phantomlink can also be inserted in borgs! + + + +## Getting organs +Currently the only transplantable organs are Interdyne's bio-synthetic organs, you can get them by buying a crate of them at cargo. + +