Add more DNA interactions (#21989)
* Add more DNA interactions * remove unused import * update based on feedback * Add event for chemistrysystem.injector * move event to shared; transfer dna to implanter * doafter and interaction event fixes * add BreakOnHandChange * doh * use events instead of updating component directly * Add DataFields to ForensicScannerComponent fields * Convert most events to system api call
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Server.DoAfter;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Forensics;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared.Weapons.Melee.Events;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.Forensics
|
||||
@@ -8,11 +16,19 @@ namespace Content.Server.Forensics
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||
[Dependency] private readonly TagSystem _tagSystem = default!;
|
||||
[Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<FingerprintComponent, ContactInteractionEvent>(OnInteract);
|
||||
SubscribeLocalEvent<FingerprintComponent, MapInitEvent>(OnFingerprintInit);
|
||||
SubscribeLocalEvent<DnaComponent, MapInitEvent>(OnDNAInit);
|
||||
|
||||
SubscribeLocalEvent<DnaComponent, BeingGibbedEvent>(OnBeingGibbed);
|
||||
SubscribeLocalEvent<ForensicsComponent, MeleeHitEvent>(OnMeleeHit);
|
||||
SubscribeLocalEvent<ForensicsComponent, AfterInteractEvent>(OnAfterInteract);
|
||||
SubscribeLocalEvent<ForensicsComponent, CleanForensicsDoAfterEvent>(OnCleanForensicsDoAfter);
|
||||
SubscribeLocalEvent<DnaComponent, TransferDnaEvent>(OnTransferDnaEvent);
|
||||
}
|
||||
|
||||
private void OnInteract(EntityUid uid, FingerprintComponent component, ContactInteractionEvent args)
|
||||
@@ -30,6 +46,79 @@ namespace Content.Server.Forensics
|
||||
component.DNA = GenerateDNA();
|
||||
}
|
||||
|
||||
private void OnBeingGibbed(EntityUid uid, DnaComponent component, BeingGibbedEvent args)
|
||||
{
|
||||
foreach(EntityUid part in args.GibbedParts)
|
||||
{
|
||||
var partComp = EnsureComp<ForensicsComponent>(part);
|
||||
partComp.DNAs.Add(component.DNA);
|
||||
partComp.CanDnaBeCleaned = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMeleeHit(EntityUid uid, ForensicsComponent component, MeleeHitEvent args)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if(TryComp<DnaComponent>(hitEntity, out var hitEntityComp))
|
||||
component.DNAs.Add(hitEntityComp.DNA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAfterInteract(EntityUid uid, ForensicsComponent component, AfterInteractEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (!_tagSystem.HasTag(args.Used, "CleansForensics"))
|
||||
return;
|
||||
|
||||
if((component.DNAs.Count > 0 && component.CanDnaBeCleaned) || (component.Fingerprints.Count + component.Fibers.Count > 0))
|
||||
{
|
||||
var doAfterArgs = new DoAfterArgs(EntityManager, args.User, component.CleanDelay, new CleanForensicsDoAfterEvent(), uid, target: args.Target, used: args.Used)
|
||||
{
|
||||
BreakOnHandChange = true,
|
||||
NeedHand = true,
|
||||
BreakOnDamage = true,
|
||||
BreakOnTargetMove = true,
|
||||
MovementThreshold = 0.01f,
|
||||
DistanceThreshold = component.CleanDistance,
|
||||
};
|
||||
|
||||
|
||||
_doAfterSystem.TryStartDoAfter(doAfterArgs);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCleanForensicsDoAfter(EntityUid uid, ForensicsComponent component, CleanForensicsDoAfterEvent args)
|
||||
{
|
||||
if (args.Handled || args.Cancelled || args.Args.Target == null)
|
||||
return;
|
||||
|
||||
if (!TryComp<ForensicsComponent>(args.Target, out var targetComp))
|
||||
return;
|
||||
|
||||
targetComp.Fibers = new();
|
||||
targetComp.Fingerprints = new();
|
||||
|
||||
if (targetComp.CanDnaBeCleaned)
|
||||
targetComp.DNAs = new();
|
||||
|
||||
// leave behind evidence it was cleaned
|
||||
if (TryComp<FiberComponent>(args.Used, out var fiber))
|
||||
targetComp.Fibers.Add(string.IsNullOrEmpty(fiber.FiberColor) ? Loc.GetString("forensic-fibers", ("material", fiber.FiberMaterial)) : Loc.GetString("forensic-fibers-colored", ("color", fiber.FiberColor), ("material", fiber.FiberMaterial)));
|
||||
|
||||
if (TryComp<ResidueComponent>(args.Used, out var residue))
|
||||
targetComp.Residues.Add(string.IsNullOrEmpty(residue.ResidueColor) ? Loc.GetString("forensic-residue", ("adjective", residue.ResidueAdjective)) : Loc.GetString("forensic-residue-colored", ("color", residue.ResidueColor), ("adjective", residue.ResidueAdjective)));
|
||||
}
|
||||
|
||||
public string GenerateFingerprint()
|
||||
{
|
||||
var fingerprint = new byte[16];
|
||||
@@ -64,5 +153,31 @@ namespace Content.Server.Forensics
|
||||
if (TryComp<FingerprintComponent>(user, out var fingerprint))
|
||||
component.Fingerprints.Add(fingerprint.Fingerprint ?? "");
|
||||
}
|
||||
|
||||
private void OnTransferDnaEvent(EntityUid uid, DnaComponent component, ref TransferDnaEvent args)
|
||||
{
|
||||
var recipientComp = EnsureComp<ForensicsComponent>(args.Recipient);
|
||||
recipientComp.DNAs.Add(component.DNA);
|
||||
recipientComp.CanDnaBeCleaned = args.CanDnaBeCleaned;
|
||||
}
|
||||
|
||||
#region Public API
|
||||
|
||||
/// <summary>
|
||||
/// Transfer DNA from one entity onto the forensics of another
|
||||
/// </summary>
|
||||
/// <param name="recipient">The entity receiving the DNA</param>
|
||||
/// <param name="donor">The entity applying its DNA</param>
|
||||
/// <param name="canDnaBeCleaned">If this DNA be cleaned off of the recipient. e.g. cleaning a knife vs cleaning a puddle of blood</param>
|
||||
public void TransferDna(EntityUid recipient, EntityUid donor, bool canDnaBeCleaned = true)
|
||||
{
|
||||
if (TryComp<DnaComponent>(donor, out var donorComp))
|
||||
{
|
||||
EnsureComp<ForensicsComponent>(recipient, out var recipientComp);
|
||||
recipientComp.DNAs.Add(donorComp.DNA);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user