diff --git a/Content.Server/Forensics/Systems/ForensicsSystem.cs b/Content.Server/Forensics/Systems/ForensicsSystem.cs index 1445e253f3..3304330aca 100644 --- a/Content.Server/Forensics/Systems/ForensicsSystem.cs +++ b/Content.Server/Forensics/Systems/ForensicsSystem.cs @@ -3,6 +3,7 @@ using Content.Server.DoAfter; using Content.Server.Fluids.EntitySystems; using Content.Server.Forensics.Components; using Content.Server.Popups; +using Content.Shared.Popups; using Content.Shared.Chemistry.Components; using Content.Shared.DoAfter; using Content.Shared.Forensics; @@ -11,6 +12,7 @@ using Content.Shared.Interaction.Events; using Content.Shared.Inventory; using Content.Shared.Weapons.Melee.Events; using Robust.Shared.Random; +using Content.Shared.Verbs; namespace Content.Server.Forensics { @@ -32,6 +34,8 @@ namespace Content.Server.Forensics SubscribeLocalEvent(OnAfterInteract, after: new[] { typeof(AbsorbentSystem) }); SubscribeLocalEvent(OnCleanForensicsDoAfter); SubscribeLocalEvent(OnTransferDnaEvent); + SubscribeLocalEvent>(OnUtilityVerb); + } private void OnInteract(EntityUid uid, FingerprintComponent component, ContactInteractionEvent args) @@ -51,7 +55,7 @@ namespace Content.Server.Forensics private void OnBeingGibbed(EntityUid uid, DnaComponent component, BeingGibbedEvent args) { - foreach(EntityUid part in args.GibbedParts) + foreach (EntityUid part in args.GibbedParts) { var partComp = EnsureComp(part); partComp.DNAs.Add(component.DNA); @@ -61,13 +65,13 @@ namespace Content.Server.Forensics private void OnMeleeHit(EntityUid uid, ForensicsComponent component, MeleeHitEvent args) { - if((args.BaseDamage.DamageDict.TryGetValue("Blunt", out var bluntDamage) && bluntDamage.Value > 0) || + if ((args.BaseDamage.DamageDict.TryGetValue("Blunt", out var bluntDamage) && bluntDamage.Value > 0) || (args.BaseDamage.DamageDict.TryGetValue("Slash", out var slashDamage) && slashDamage.Value > 0) || (args.BaseDamage.DamageDict.TryGetValue("Piercing", out var pierceDamage) && pierceDamage.Value > 0)) { - foreach(EntityUid hitEntity in args.HitEntities) + foreach (EntityUid hitEntity in args.HitEntities) { - if(TryComp(hitEntity, out var hitEntityComp)) + if (TryComp(hitEntity, out var hitEntityComp)) component.DNAs.Add(hitEntityComp.DNA); } } @@ -101,17 +105,58 @@ namespace Content.Server.Forensics } } - private void OnAfterInteract(EntityUid uid, CleansForensicsComponent component, AfterInteractEvent args) + private void OnAfterInteract(Entity cleanForensicsEntity, ref AfterInteractEvent args) { - if (args.Handled || !args.CanReach) + if (args.Handled || !args.CanReach || args.Target == null) return; - if (!TryComp(args.Target, out var forensicsComp)) + args.Handled = TryStartCleaning(cleanForensicsEntity, args.User, args.Target.Value); + } + + private void OnUtilityVerb(Entity entity, ref GetVerbsEvent args) + { + if (!args.CanInteract || !args.CanAccess) return; - if((forensicsComp.DNAs.Count > 0 && forensicsComp.CanDnaBeCleaned) || (forensicsComp.Fingerprints.Count + forensicsComp.Fibers.Count > 0)) + // These need to be set outside for the anonymous method! + var user = args.User; + var target = args.Target; + + var verb = new UtilityVerb() { - var doAfterArgs = new DoAfterArgs(EntityManager, args.User, component.CleanDelay, new CleanForensicsDoAfterEvent(), uid, target: args.Target, used: args.Used) + Act = () => TryStartCleaning(entity, user, target), + IconEntity = GetNetEntity(entity), + Text = Loc.GetString(Loc.GetString("forensics-verb-text")), + Message = Loc.GetString(Loc.GetString("forensics-verb-message")), + // This is important because if its true using the cleaning device will count as touching the object. + DoContactInteraction = false + }; + + args.Verbs.Add(verb); + } + + /// + /// Attempts to clean the given item with the given CleansForensics entity. + /// + /// The entity that is being used to clean the target. + /// The user that is using the cleanForensicsEntity. + /// The target of the forensics clean. + /// True if the target can be cleaned and has some sort of DNA or fingerprints / fibers and false otherwise. + public bool TryStartCleaning(Entity cleanForensicsEntity, EntityUid user, EntityUid target) + { + if (!TryComp(target, out var forensicsComp)) + { + _popupSystem.PopupEntity(Loc.GetString("forensics-cleaning-cannot-clean", ("target", target)), user, user, PopupType.MediumCaution); + return false; + } + + var totalPrintsAndFibers = forensicsComp.Fingerprints.Count + forensicsComp.Fibers.Count; + var hasRemovableDNA = forensicsComp.DNAs.Count > 0 && forensicsComp.CanDnaBeCleaned; + + if (hasRemovableDNA || totalPrintsAndFibers > 0) + { + var cleanDelay = cleanForensicsEntity.Comp.CleanDelay; + var doAfterArgs = new DoAfterArgs(EntityManager, user, cleanDelay, new CleanForensicsDoAfterEvent(), cleanForensicsEntity, target: target, used: cleanForensicsEntity) { BreakOnHandChange = true, NeedHand = true, @@ -122,10 +167,17 @@ namespace Content.Server.Forensics }; _doAfterSystem.TryStartDoAfter(doAfterArgs); - _popupSystem.PopupEntity(Loc.GetString("forensics-cleaning", ("target", args.Target)), args.User, args.User); - args.Handled = true; + _popupSystem.PopupEntity(Loc.GetString("forensics-cleaning", ("target", target)), user, user); + + return true; } + else + { + _popupSystem.PopupEntity(Loc.GetString("forensics-cleaning-cannot-clean", ("target", target)), user, user, PopupType.MediumCaution); + return false; + } + } private void OnCleanForensicsDoAfter(EntityUid uid, ForensicsComponent component, CleanForensicsDoAfterEvent args) diff --git a/Resources/Locale/en-US/forensics/forensics.ftl b/Resources/Locale/en-US/forensics/forensics.ftl index 957cc444a8..29e2db8f78 100644 --- a/Resources/Locale/en-US/forensics/forensics.ftl +++ b/Resources/Locale/en-US/forensics/forensics.ftl @@ -20,9 +20,11 @@ forensic-scanner-printer-not-ready = Printer is not ready yet. forensic-scanner-verb-text = Scan forensic-scanner-verb-message = Perform a forensic scan - - forensic-pad-fingerprint-name = {$entity}'s fingerprints forensic-pad-gloves-name = fibers from {$entity} -forensics-cleaning = You begin cleaning the evidence off of {THE($target)}... \ No newline at end of file +forensics-verb-text = Remove evidence +forensics-verb-message = Remove fingerprints and DNA residues from the object! +forensics-cleaning = You begin cleaning the evidence off of {THE($target)}... + +forensics-cleaning-cannot-clean = There is nothing cleanable on {THE($target)}! \ No newline at end of file