Skip to content

Commit

Permalink
ScentClient/Networking
Browse files Browse the repository at this point in the history
  • Loading branch information
FoxxoTrystan committed Aug 13, 2024
1 parent 2aa411f commit ada5e27
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 36 deletions.
36 changes: 36 additions & 0 deletions Content.Client/Forensics/ScentTrackerSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Content.Shared.Forensics;
using Robust.Shared.Random;
using Robust.Shared.Timing;
using Robust.Client.Player;

namespace Content.Client.Forensics
{
public sealed class ScentTrackerSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;

public override void Update(float frameTime)
{
base.Update(frameTime);

var query = AllEntityQuery<ForensicsComponent>();
while (query.MoveNext(out var uid, out var comp))
{
if (TryComp<ScentTrackerComponent>(_playerManager.LocalEntity, out var scentcomp))
{
if (scentcomp.Scent != string.Empty && scentcomp.Scent == comp.Scent)
{
if (_timing.CurTime > comp.TargetTime)
{
comp.TargetTime = _timing.CurTime + TimeSpan.FromSeconds(1.0f);
Spawn("ScentTrackEffect", _transform.GetMapCoordinates(uid).Offset(_random.NextVector2(0.25f)));
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using System.Numerics;
using Content.Server.Forensics;
using Content.Shared.Forensics;
using Content.Server.Stack;
using Content.Shared.Prototypes;
using Content.Shared.Stacks;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
using Content.Server.Administration.Commands;

namespace Content.Server.Destructible.Thresholds.Behaviors
{
Expand Down Expand Up @@ -85,6 +86,7 @@ public void TransferForensics(EntityUid spawned, DestructibleSystem system, Enti

if (!system.Random.Prob(0.4f))
return;

comp.Fingerprints = forensicsComponent.Fingerprints;
comp.Fibers = forensicsComponent.Fibers;
}
Expand Down
41 changes: 24 additions & 17 deletions Content.Server/Forensics/Systems/ForensicsSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,17 @@ private void OnFingerprintInit(EntityUid uid, FingerprintComponent component, Ma
private void OnDNAInit(EntityUid uid, DnaComponent component, MapInitEvent args)
{
component.DNA = GenerateDNA();

}

private void OnScentInit(EntityUid uid, ScentComponent component, MapInitEvent args)
{
component.Scent = GenerateFingerprint(length: 5);

var updatecomp = EnsureComp<ForensicsComponent>(uid);
updatecomp.Scent = component.Scent;

Dirty(uid, updatecomp);
}

private void OnBeingGibbed(EntityUid uid, DnaComponent component, BeingGibbedEvent args)
Expand All @@ -75,6 +81,7 @@ private void OnBeingGibbed(EntityUid uid, DnaComponent component, BeingGibbedEve
var partComp = EnsureComp<ForensicsComponent>(part);
partComp.DNAs.Add(component.DNA);
partComp.CanDnaBeCleaned = false;
Dirty(part, partComp);
}
}

Expand All @@ -90,11 +97,13 @@ private void OnMeleeHit(EntityUid uid, ForensicsComponent component, MeleeHitEve
component.DNAs.Add(hitEntityComp.DNA);
}
}
Dirty(uid, component);
}

private void OnRehydrated(Entity<ForensicsComponent> ent, ref GotRehydratedEvent args)
{
CopyForensicsFrom(ent.Comp, args.Target);
Dirty(args.Target, ent.Comp);
}

/// <summary>
Expand Down Expand Up @@ -178,6 +187,7 @@ private void OnCleanForensicsDoAfter(EntityUid uid, ForensicsComponent component

if (TryComp<ScentComponent>(args.Target, out var scentComp))
scentComp.Scent = GenerateFingerprint(length: 5);
// TODO: Replace all currently weared items to this scent.

if (!TryComp<ForensicsComponent>(args.Target, out var targetComp))
return;
Expand All @@ -195,6 +205,8 @@ private void OnCleanForensicsDoAfter(EntityUid uid, ForensicsComponent component

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)));

Dirty(uid, component);
}

public string GenerateFingerprint(int length = 16)
Expand Down Expand Up @@ -234,10 +246,16 @@ private void ApplyEvidence(EntityUid user, EntityUid target)
}

if (HasComp<FingerprintMaskComponent>(gloves))
{
Dirty(target, component);
return;
}
}
if (TryComp<FingerprintComponent>(user, out var fingerprint))
{
component.Fingerprints.Add(fingerprint.Fingerprint ?? "");
Dirty(target, component);
}
}

private void ApplyScent(EntityUid user, EntityUid target)
Expand All @@ -248,13 +266,17 @@ private void ApplyScent(EntityUid user, EntityUid target)
var component = EnsureComp<ForensicsComponent>(target);
if (TryComp<ScentComponent>(user, out var scent))
component.Scent = scent.Scent;

Dirty(target, component);
}

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;

Dirty(args.Recipient, recipientComp);
}

#region Public API
Expand All @@ -272,24 +294,9 @@ public void TransferDna(EntityUid recipient, EntityUid donor, bool canDnaBeClean
EnsureComp<ForensicsComponent>(recipient, out var recipientComp);
recipientComp.DNAs.Add(donorComp.DNA);
recipientComp.CanDnaBeCleaned = canDnaBeCleaned;
}
}

/// <summary>
/// Get the Scent of a entity, if generating a scent, this will be prioritized.
/// </summary>
/// <param name="uid">The entity to get the scent</param>
public string GetScent(EntityUid uid)
{
var scent = string.Empty;

if (TryComp<ForensicsComponent>(uid, out var forensicsComp))
scent = forensicsComp.Scent;

if (TryComp<ScentComponent>(uid, out var scentComp))
scent = scentComp.Scent;

return scent;
Dirty(recipient, recipientComp);
}
}

#endregion
Expand Down
20 changes: 12 additions & 8 deletions Content.Server/Forensics/Systems/ScentTrackerSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ public sealed class ScentTrackerSystem : EntitySystem
{
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly ForensicsSystem _forensicsSystem = default!;
public override void Initialize()
{
SubscribeLocalEvent<ScentTrackerComponent, GetVerbsEvent<InnateVerb>>(AddVerbs);
SubscribeLocalEvent<ScentTrackerComponent, ScentTrackerDoAfterEvent>(TrackScentDoAfter);
SubscribeLocalEvent<ForensicsComponent, ExaminedEvent>((uid, _, args) => OnExamine(uid, args));
SubscribeLocalEvent<ScentComponent, ExaminedEvent>((uid, _, args) => OnExamine(uid, args));
}

private void AddVerbs(EntityUid uid, ScentTrackerComponent component, GetVerbsEvent<InnateVerb> args)
Expand Down Expand Up @@ -88,7 +86,10 @@ private void OnExamine(EntityUid uid, ExaminedEvent args)
if (!TryComp<ScentTrackerComponent>(args.Examiner, out var component))
return;

if (component.Scent == _forensicsSystem.GetScent(args.Examined))
if (!TryComp<ForensicsComponent>(args.Examined, out var forcomp))
return;

if (forcomp.Scent != string.Empty && component.Scent == forcomp.Scent)
args.PushMarkup(Loc.GetString("examined-scent"));
}

Expand All @@ -98,18 +99,20 @@ public void TrackScent(EntityUid uid, EntityUid target)
if (!TryComp<ScentTrackerComponent>(uid, out var component))
return;

var scenttotrack = _forensicsSystem.GetScent(target);
if (!TryComp<ForensicsComponent>(target, out var forcomp))
return;

if (scenttotrack != string.Empty)
if (forcomp.Scent != string.Empty)
{
component.Scent = scenttotrack;
component.Scent = forcomp.Scent;
_popupSystem.PopupEntity(Loc.GetString("tracking-scent", ("target", Identity.Name(target, EntityManager))), uid, uid);
// TODO ClientOverlay Scent Tracking
}
else
{
_popupSystem.PopupEntity(Loc.GetString("no-scent"), uid, uid);
}

Dirty(uid, component);
}

public void StopTrackScent(EntityUid uid, ScentTrackerComponent component)
Expand All @@ -119,7 +122,8 @@ public void StopTrackScent(EntityUid uid, ScentTrackerComponent component)

component.Scent = string.Empty;
_popupSystem.PopupEntity(Loc.GetString("stopped-tracking-scent"), uid, uid);
// TODO ClientOverlay Scent Tracking - Stop

Dirty(uid, component);
}

#endregion
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
namespace Content.Server.Forensics
using Robust.Shared.GameStates;

namespace Content.Shared.Forensics
{
[RegisterComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class ForensicsComponent : Component
{
[DataField("fingerprints")]
[DataField("fingerprints"), AutoNetworkedField]
public HashSet<string> Fingerprints = new();

[DataField("fibers")]
[DataField("fibers"), AutoNetworkedField]
public HashSet<string> Fibers = new();

[DataField("dnas")]
[DataField("dnas"), AutoNetworkedField]
public HashSet<string> DNAs = new();

[DataField("scent")]
[DataField("scent"), AutoNetworkedField]
public string Scent = String.Empty;

[DataField("residues")]
[DataField("residues"), AutoNetworkedField]
public HashSet<string> Residues = new();

/// <summary>
Expand All @@ -30,5 +32,11 @@ public sealed partial class ForensicsComponent : Component
/// </summary>
[DataField("canDnaBeCleaned")]
public bool CanDnaBeCleaned = true;

/// <summary>
/// Moment in time next effect will be spawned
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public TimeSpan TargetTime = TimeSpan.Zero;
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
namespace Content.Server.Forensics
using Robust.Shared.GameStates;

namespace Content.Shared.Forensics
{
[RegisterComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class ScentTrackerComponent : Component
{
/// <summary>
/// The currently tracked scent.
/// </summary>
[DataField("scent")]
[DataField("scent"), AutoNetworkedField]
public string Scent = String.Empty;

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,22 @@
- type: GuideHelp
guides:
- Forensics

- type: entity
id: ScentTrackEffect
noSpawn: true
components:
- type: TimedDespawn
lifetime: 1
- type: Sprite
noRot: true
drawdepth: Effects
sprite: Effects/chemsmoke.rsi
state: chemsmoke
scale: "0.08, 0.08"
color: "#ffff00"
- type: EffectVisuals
- type: Tag
tags:
- HideContextMenu
- type: AnimationPlayer

0 comments on commit ada5e27

Please sign in to comment.