Files
wwdpublic/Content.Server/_Goobstation/MedicalPatch/MedicalPatchSystem.cs
Will-Oliver-Br 07d2610a86 Port Medical Patches (#2185)
Port medical patches from
[Goob-Station](https://github.com/Goob-Station/Goob-Station).
Prs:
https://github.com/space-wizards/space-station-14/pull/30230
https://github.com/Goob-Station/Goob-Station/pull/493
https://github.com/Goob-Station/Goob-Station/pull/663
https://github.com/Goob-Station/Goob-Station/pull/1086
https://github.com/Goob-Station/Goob-Station/pull/1072
https://github.com/Goob-Station/Goob-Station/pull/1243
https://github.com/Goob-Station/Goob-Station/pull/1246
https://github.com/Goob-Station/Goob-Station/pull/1707

---

<details><summary><h1>Media</h1></summary>
<p>

![Captura de tela 2025-04-06
132934](https://github.com/user-attachments/assets/914fc728-b4cd-452f-9f71-1300d836895a)

</p>
</details>

---

🆑 deltanedas, jorgun, fishbait_x, Huffs-The-Frezone, Teapug, Speebr0,
CerberusWolfie, yglop, botanySupremist, Will-Oliver-Br
- add: Added medical patches
- add: Added a guidebook entry for medical patches.

---------

Signed-off-by: Will-Oliver-Br <164823659+Will-Oliver-Br@users.noreply.github.com>
Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com>
Co-authored-by: fishbait <gnesse@gmail.com>
Co-authored-by: unknown <Administrator@DESKTOP-PMRIVVA.kommune.indresogn.no>
Co-authored-by: Fishbait <Fishbait@git.ml>
Co-authored-by: Theapug <159912420+Teapug@users.noreply.github.com>
Co-authored-by: Speebro <100388782+Speebr0@users.noreply.github.com>
Co-authored-by: Speebro <speebro@notreal.com>
Co-authored-by: John Willis <143434770+CerberusWolfie@users.noreply.github.com>
Co-authored-by: yglop <95057024+yglop@users.noreply.github.com>
Co-authored-by: botanySupremist <160211017+botanySupremist@users.noreply.github.com>
Co-authored-by: botanySupremist <definitelyrealBotSupremist@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-07-20 13:21:18 +10:00

140 lines
5.6 KiB
C#

using Content.Shared.Administration.Logs;
using Content.Server.Medical.Components;
using Content.Server.Popups;
using Content.Shared.FixedPoint;
using Content.Shared.Sticky;
using Content.Shared.Sticky.Systems;
using Content.Shared.Sticky.Components;
using Robust.Shared.Timing;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Chemistry;
using Content.Server.Polymorph.Systems;
using Content.Shared.Database;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
namespace Content.Server.Medical;
public sealed class MedicalPatchSystem : EntitySystem
{
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly StickySystem _stickySystem = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainers = default!;
[Dependency] private readonly ReactiveSystem _reactiveSystem = default!;
[Dependency] protected readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MedicalPatchComponent, EntityUnstuckEvent>(OnUnstuck);
SubscribeLocalEvent<MedicalPatchComponent, EntityStuckEvent>(OnStuck);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
if (!_timing.IsFirstTimePredicted)
return;
foreach (var comp in EntityManager.EntityQuery<MedicalPatchComponent>())
{
if (_timing.CurTime < comp.NextUpdate)
continue;
var uid = comp.Owner; // TODO update thsi to the
if (!TryComp<StickyComponent>(uid, out var stickycomp))
continue;
if (stickycomp.StuckTo == null)
continue;
comp.NextUpdate = _timing.CurTime + TimeSpan.FromSeconds(comp.UpdateTime);
Cycle(uid, comp);
}
}
public void Cycle(EntityUid uid, MedicalPatchComponent component)
{
if (!TryInject(uid, component, component.TransferAmount))
{
if (!TryComp<StickyComponent>(uid, out var stickycomp))
return;
_stickySystem.UnstickFromEntity((uid, stickycomp), uid);
}
}
public bool TryInject(EntityUid uid, MedicalPatchComponent component, FixedPoint2 transferAmount)
{
if (!TryComp<StickyComponent>(uid, out var stickycomp))
return false;
if (stickycomp.StuckTo == null)
return false;
var target = (EntityUid) stickycomp.StuckTo;
if (!_solutionContainers.TryGetSolution(uid, component.SolutionName, out var medicalPatchSoln, out var medicalPatchSolution) || medicalPatchSolution.Volume == 0)
{
//Solution Empty
return false;
}
if (!_solutionContainers.TryGetInjectableSolution(target, out var targetSoln, out var targetSolution))
{
//_popupSystem.PopupEntity(Loc.GetString("Medical Patch cant find a bloodsystem"), target);
return false;
}
var realTransferAmount = FixedPoint2.Min(transferAmount, targetSolution.AvailableVolume);
if (realTransferAmount <= 0)
{
_popupSystem.PopupEntity(Loc.GetString("No room to inject"), target);
return true;
}
var removedSolution = _solutionContainers.SplitSolution(medicalPatchSoln.Value, realTransferAmount);
if (!targetSolution.CanAddSolution(removedSolution))
return true;
_reactiveSystem.DoEntityReaction(target, removedSolution, ReactionMethod.Injection);
_solutionContainers.TryAddSolution(targetSoln.Value, removedSolution);
return true;
}
public void OnStuck(EntityUid uid, MedicalPatchComponent component, ref EntityStuckEvent args)
{
if (!_solutionContainers.TryGetSolution(uid, component.SolutionName, out var medicalPatchSoln, out var medicalPatchSolution))
return;
//Logg the Patch stick to.
_adminLogger.Add(LogType.ForceFeed, $"{EntityManager.ToPrettyString(args.User):user} stuck a patch on {EntityManager.ToPrettyString(args.Target):target} using {EntityManager.ToPrettyString(uid):using} containing {SharedSolutionContainerSystem.ToPrettyString(medicalPatchSolution):medicalPatchSolution}");
if (component.InjectAmmountOnAttatch > 0)
{
if (!TryInject(uid, component, component.InjectAmmountOnAttatch))
return;
}
if (component.InjectPercentageOnAttatch > 0)
{
if (medicalPatchSolution.Volume == 0)
return;
if (!TryInject(uid, component, medicalPatchSolution.Volume * (component.InjectPercentageOnAttatch / 100)))
return;
}
}
public void OnUnstuck(EntityUid uid, MedicalPatchComponent component, ref EntityUnstuckEvent args)
{
if (component.SingleUse)
{
if (component.TrashObject!=null)
{
var coordinates = Transform(uid).Coordinates;
var finisher = Spawn(component.TrashObject, coordinates);
// If the user is holding the item
if (_hands.IsHolding(args.User, uid, out var hand))
{
Del(uid);
// Put the Medicalpatch in the user's hand
_hands.TryPickup(args.User, finisher, hand);
return;
}
}
QueueDel(uid);
}
}
}