-
Notifications
You must be signed in to change notification settings - Fork 395
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add surgical cleanliness and sanitation
- Loading branch information
1 parent
4a6ff66
commit 1798497
Showing
19 changed files
with
416 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using Content.Shared._DV.Surgery; | ||
|
||
namespace Content.Client._DV.Surgery; | ||
|
||
/// <summary>This gets the examine tooltip and sanitize verb predicted on the client so there's no pop-in after latency</summary> | ||
public sealed class SurgeryCleanSystem : SharedSurgeryCleanSystem | ||
{ | ||
public override bool TryStartCleaning(Entity<SurgeryCleansDirtComponent> ent, EntityUid user, EntityUid target) | ||
{ | ||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
using Content.Server.DoAfter; | ||
using Content.Server.Popups; | ||
using Content.Shared._DV.Surgery; | ||
using Content.Shared.DoAfter; | ||
using Content.Shared.Forensics; | ||
using Content.Shared.Interaction; | ||
using Content.Shared.Popups; | ||
|
||
namespace Content.Server._DV.Surgery; | ||
|
||
/// <summary>Responsible for handling the visual appearance of and sanitzation of items that can get dirty from surgery</summary> | ||
public sealed class SurgeryCleanSystem : SharedSurgeryCleanSystem | ||
{ | ||
[Dependency] private readonly PopupSystem _popup = default!; | ||
[Dependency] private readonly DoAfterSystem _doAfter = default!; | ||
|
||
public override void Initialize() | ||
{ | ||
base.Initialize(); | ||
|
||
SubscribeLocalEvent<SurgeryCleansDirtComponent, AfterInteractEvent>(OnAfterInteract); | ||
SubscribeLocalEvent<SurgeryCleansDirtComponent, SurgeryCleanDirtDoAfterEvent>(FinishCleaning); | ||
|
||
SubscribeLocalEvent<SurgeryDirtinessComponent, SurgeryCleanedEvent>(OnCleanDirt); | ||
SubscribeLocalEvent<SurgeryCrossContaminationComponent, SurgeryCleanedEvent>(OnCleanDNA); | ||
} | ||
|
||
private void OnAfterInteract(Entity<SurgeryCleansDirtComponent> ent, ref AfterInteractEvent args) | ||
{ | ||
if (args.Handled || !args.CanReach || args.Target == null) | ||
return; | ||
|
||
args.Handled = TryStartCleaning(ent, args.User, args.Target.Value); | ||
} | ||
|
||
public override bool TryStartCleaning(Entity<SurgeryCleansDirtComponent> ent, EntityUid user, EntityUid target) | ||
{ | ||
var isDirty = (TryComp<SurgeryDirtinessComponent>(target, out var dirtiness) && dirtiness.Dirtiness > 0); | ||
var isContaminated = (TryComp<SurgeryCrossContaminationComponent>(target, out var contamination) && contamination.DNAs.Count > 0); | ||
|
||
if (!(isDirty || isContaminated)) | ||
{ | ||
_popup.PopupEntity(Loc.GetString("sanitization-cannot-clean", ("target", target)), user, user, PopupType.MediumCaution); | ||
return false; | ||
} | ||
|
||
var cleanDelay = ent.Comp.CleanDelay; | ||
var doAfterArgs = new DoAfterArgs(EntityManager, user, cleanDelay, new SurgeryCleanDirtDoAfterEvent(), ent, target: target, used: ent) | ||
{ | ||
NeedHand = true, | ||
BreakOnDamage = true, | ||
BreakOnMove = true, | ||
MovementThreshold = 0.01f, | ||
DistanceThreshold = 1f, | ||
}; | ||
|
||
_doAfter.TryStartDoAfter(doAfterArgs); | ||
_popup.PopupEntity(Loc.GetString("sanitization-cleaning", ("target", target)), user, user); | ||
|
||
return true; | ||
} | ||
|
||
private void FinishCleaning(Entity<SurgeryCleansDirtComponent> ent, ref SurgeryCleanDirtDoAfterEvent args) | ||
{ | ||
if (args.Handled || args.Cancelled || args.Args.Target == null) | ||
return; | ||
|
||
var ev = new SurgeryCleanedEvent(); | ||
RaiseLocalEvent(args.Args.Target.Value, ref ev); | ||
|
||
// daisychain to forensics because if you sterilise something youve almost definitely scrubbed all dna and fibers off of it | ||
var daisyChainEvent = new CleanForensicsDoAfterEvent() { DoAfter = args.DoAfter }; | ||
RaiseLocalEvent(ent.Owner, daisyChainEvent); | ||
} | ||
|
||
private void OnCleanDirt(Entity<SurgeryDirtinessComponent> ent, ref SurgeryCleanedEvent args) | ||
{ | ||
ent.Comp.Dirtiness = 0; | ||
Dirty(ent); | ||
} | ||
|
||
private void OnCleanDNA(Entity<SurgeryCrossContaminationComponent> ent, ref SurgeryCleanedEvent args) | ||
{ | ||
ent.Comp.DNAs.Clear(); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
Content.Server/_DV/Surgery/SurgeryCrossContaminationComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace Content.Server._DV.Surgery; | ||
|
||
/// <summary>Component that allows an entity to be cross contamined from being used in surgery</summary> | ||
[RegisterComponent] | ||
public sealed partial class SurgeryCrossContaminationComponent : Component | ||
{ | ||
/// <summary>Patient DNAs that are present on this dirtied tool</summary> | ||
[DataField] | ||
public HashSet<string> DNAs = new(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
using Content.Shared.Examine; | ||
using Content.Shared.Verbs; | ||
using Robust.Shared.Utility; | ||
|
||
namespace Content.Shared._DV.Surgery; | ||
|
||
public abstract class SharedSurgeryCleanSystem : EntitySystem | ||
{ | ||
public override void Initialize() | ||
{ | ||
base.Initialize(); | ||
|
||
SubscribeLocalEvent<SurgeryDirtinessComponent, ExaminedEvent>(OnDirtyExamined); | ||
SubscribeLocalEvent<SurgeryCleansDirtComponent, GetVerbsEvent<UtilityVerb>>(OnUtilityVerb); | ||
} | ||
|
||
private void OnUtilityVerb(Entity<SurgeryCleansDirtComponent> ent, ref GetVerbsEvent<UtilityVerb> args) | ||
{ | ||
if (!args.CanInteract || !args.CanAccess) | ||
return; | ||
|
||
var user = args.User; | ||
var target = args.Target; | ||
|
||
var verb = new UtilityVerb() | ||
{ | ||
Act = () => TryStartCleaning(ent, user, target), | ||
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/bubbles.svg.192dpi.png")), | ||
Text = Loc.GetString(Loc.GetString("sanitization-verb-text")), | ||
Message = Loc.GetString(Loc.GetString("sanitization-verb-message")), | ||
// we daisychain to forensics here so we shouldn't leave forensic traces of our own | ||
DoContactInteraction = false | ||
}; | ||
|
||
args.Verbs.Add(verb); | ||
} | ||
|
||
private void OnDirtyExamined(Entity<SurgeryDirtinessComponent> ent, ref ExaminedEvent args) | ||
{ | ||
var description = ent.Comp.Dirtiness.Int() switch { | ||
<= 0 => "surgery-cleanliness-0", | ||
<= 20 => "surgery-cleanliness-1", | ||
<= 40 => "surgery-cleanliness-2", | ||
<= 60 => "surgery-cleanliness-3", | ||
<= 80 => "surgery-cleanliness-4", | ||
_ => "surgery-cleanliness-5", | ||
}; | ||
|
||
args.PushMarkup(Loc.GetString(description)); | ||
} | ||
|
||
public abstract bool TryStartCleaning(Entity<SurgeryCleansDirtComponent> ent, EntityUid user, EntityUid target); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
using Content.Shared.DoAfter; | ||
using Robust.Shared.Serialization; | ||
|
||
namespace Content.Shared._DV.Surgery; | ||
|
||
[Serializable, NetSerializable] | ||
public sealed partial class SurgeryCleanDirtDoAfterEvent : SimpleDoAfterEvent; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
namespace Content.Shared._DV.Surgery; | ||
|
||
/// <summary>Event fired when an object is sterilised for surgery</summary> | ||
[ByRefEvent] | ||
public record struct SurgeryCleanedEvent; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using Robust.Shared.GameStates; | ||
|
||
namespace Content.Shared._DV.Surgery; | ||
|
||
/// <summary> | ||
/// For items that can clean up surgical dirtiness | ||
/// </summary> | ||
[RegisterComponent, NetworkedComponent] | ||
public sealed partial class SurgeryCleansDirtComponent : Component | ||
{ | ||
/// <summary> | ||
/// How long it takes to wipe prints/blood/etc. off of things using this entity | ||
/// </summary> | ||
[DataField] | ||
public float CleanDelay = 24.0f; | ||
} |
30 changes: 30 additions & 0 deletions
30
Content.Shared/_DV/Surgery/SurgeryContaminableComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
using Content.Shared._Shitmed.Medical.Surgery; | ||
using Content.Shared.FixedPoint; | ||
using Robust.Shared.GameStates; | ||
|
||
namespace Content.Shared._DV.Surgery; | ||
|
||
/// <summary>Component that indicates how an entity should respond to unsanitary surgery conditions</summary> | ||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedSurgerySystem))] | ||
public sealed partial class SurgeryContaminableComponent : Component | ||
{ | ||
/// <summary>How much cross contamination should increase dirtiness per incompatible DNA</summary> | ||
[DataField] | ||
public FixedPoint2 CrossContaminationDirtinessLevel = 40.0; | ||
|
||
/// <summary>The level of dirtiness above which toxin damage will be dealt</summary> | ||
[DataField] | ||
public FixedPoint2 DirtinessThreshold = 50.0; | ||
|
||
/// <summary>The base amount of toxin damage to deal above the threshold</summary> | ||
[DataField] | ||
public FixedPoint2 BaseDamage = 2.0; | ||
|
||
/// <summary>The inverse of the coefficient to scale the toxin damage by</summary> | ||
[DataField] | ||
public FixedPoint2 InverseDamageCoefficient = 250.0; | ||
|
||
/// <summary>The upper limit on how much toxin damage can be dealt in a single step</summary> | ||
[DataField] | ||
public FixedPoint2 ToxinStepLimit = 15.0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using Content.Shared._Shitmed.Medical.Surgery; | ||
using Content.Shared.FixedPoint; | ||
using Robust.Shared.GameStates; | ||
|
||
namespace Content.Shared._DV.Surgery; | ||
|
||
/// <summary>Component that allows an entity to take on dirtiness from being used in surgery</summary> | ||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedSurgeryCleanSystem), typeof(SharedSurgerySystem))] | ||
public sealed partial class SurgeryDirtinessComponent : Component | ||
{ | ||
/// <summary>The level of dirtiness this component represents; above 50 is usually where consequences start to happen</summary> | ||
[DataField] | ||
[AutoNetworkedField] | ||
public FixedPoint2 Dirtiness = 0.0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
using Robust.Shared.Prototypes; | ||
|
||
namespace Content.Shared._DV.Surgery; | ||
|
||
/// <summary>Handled by the server when a surgery step is completed in order to deal with sanitization concerns</summary> | ||
[ByRefEvent] | ||
public record struct SurgeryDirtinessEvent(EntityUid User, EntityUid Part, List<EntityUid> Tools, EntityUid Step); |
Oops, something went wrong.