Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ protected override void UpdateState(BoundUserInterfaceState state)
if (_window == null || state is not ScentSniffBoundUserInterfaceState cast)
return;

_window.UpdateEntries(cast.Entries);
_window.UpdateEntries(cast.Entries, cast.OwnScentId);
}
}
24 changes: 22 additions & 2 deletions Content.Client/_Starlight/Scent/ScentSniffMenu.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System.Numerics;
using Content.Client.Administration.UI.CustomControls;
using Content.Client.Message;
using Content.Shared._Starlight.Scent;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
Expand All @@ -19,13 +22,30 @@ public ScentSniffMenu()
RobustXamlLoader.Load(this);
}

public void UpdateEntries(List<ScentTraceEntry> entries)
public void UpdateEntries(List<ScentTraceEntry> entries, string? ownScentId)
{
Rows.RemoveAllChildren();

if (ownScentId is { } ownId)
{
var ownRow = new ContainerButton
{
ToolTip = Loc.GetString("scent-sniff-window-track-own-tooltip"),
HorizontalExpand = true,
};
ownRow.AddStyleClass(ContainerButton.StyleClassButton);
ownRow.AddChild(new Label { Text = Loc.GetString("scent-sniff-window-track-own") });
ownRow.OnPressed += _ => OnTrackPressed?.Invoke(ownId);
Rows.AddChild(ownRow);

Rows.AddChild(new HSeparator());
Rows.AddChild(new Control { MinSize = new Vector2(0, 10) });
}

if (entries.Count == 0)
{
Rows.AddChild(new Label { Text = Loc.GetString("scent-sniff-window-empty") });
var emptyKey = ownScentId != null ? "scent-sniff-window-empty-traces" : "scent-sniff-window-empty";
Rows.AddChild(new Label { Text = Loc.GetString(emptyKey) });
return;
}

Expand Down
37 changes: 23 additions & 14 deletions Content.Server/_Starlight/Scent/Systems/ScentSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ private void OnSniffObjectAction(Entity<SmellerComponent> ent, ref SniffObjectAc
if (trace != null)
PruneExpiredTraces(trace);

if (trace == null || trace.Scents.Count == 0)
var hasOwnScent = TryComp<ScentComponent>(args.Target, out var targetScent) && targetScent.ScentId != null;

if ((trace == null || trace.Scents.Count == 0) && !hasOwnScent)
{
_popup.PopupEntity(Loc.GetString("scent-sniff-no-scents", ("target", Name(args.Target))), args.Target, ent.Owner);
args.Handled = true;
Expand All @@ -126,23 +128,27 @@ private void OnSniffObjectDoAfter(EntityUid uid, SmellerComponent component, Sni
if (args.Handled || args.Cancelled || args.Args.Target is not { } target)
return;

if (!TryComp<ScentTraceComponent>(target, out var trace))
return;

PruneExpiredTraces(trace);
TryComp<ScentTraceComponent>(target, out var trace);
if (trace != null)
PruneExpiredTraces(trace);

var now = _timing.CurTime;
var entries = new List<ScentTraceEntry>(trace.Scents.Count);
foreach (var (scentId, info) in trace.Scents)
var entries = new List<ScentTraceEntry>(trace?.Scents.Count ?? 0);
if (trace != null)
{
var speciesName = Loc.GetString("scent-species-non-humanoid");
if (info.Species != null && _prototype.TryIndex<SpeciesPrototype>(info.Species, out var species))
speciesName = Loc.GetString(species.Name);
foreach (var (scentId, info) in trace.Scents)
{
var speciesName = Loc.GetString("scent-species-non-humanoid");
if (info.Species != null && _prototype.TryIndex<SpeciesPrototype>(info.Species, out var species))
speciesName = Loc.GetString(species.Name);

var age = (float)(now - info.LastTouched).TotalSeconds;
entries.Add(new ScentTraceEntry(scentId, GetFreshness(age, trace.TraceLifetime), speciesName));
var age = (float)(now - info.LastTouched).TotalSeconds;
entries.Add(new ScentTraceEntry(scentId, GetFreshness(age, trace.TraceLifetime), speciesName));
}
}

var ownScentId = TryComp<ScentComponent>(target, out var targetScent) ? targetScent.ScentId : null;

if (!_ui.TryOpenUi(uid, ScentSniffUiKey.Key, uid))
{
Log.Warning($"{ToPrettyString(uid)} has SmellerComponent but couldn't open ScentSniffUiKey - " +
Expand All @@ -151,7 +157,7 @@ private void OnSniffObjectDoAfter(EntityUid uid, SmellerComponent component, Sni
}

component.SniffTarget = target;
_ui.SetUiState(uid, ScentSniffUiKey.Key, new ScentSniffBoundUserInterfaceState(entries));
_ui.SetUiState(uid, ScentSniffUiKey.Key, new ScentSniffBoundUserInterfaceState(entries, ownScentId));

args.Handled = true;
}
Expand Down Expand Up @@ -191,7 +197,10 @@ private void OnTrackMessage(EntityUid uid, SmellerComponent component, ScentSnif
if (!_transform.InRange(xform.Coordinates, targetXform.Coordinates, component.SniffRange))
return;

if (!TryComp<ScentTraceComponent>(target, out var trace) || !trace.Scents.ContainsKey(args.ScentId))
var isOwnScent = TryComp<ScentComponent>(target, out var targetScent) && targetScent.ScentId == args.ScentId;
var isTracedScent = TryComp<ScentTraceComponent>(target, out var trace) && trace.Scents.ContainsKey(args.ScentId);

if (!isOwnScent && !isTracedScent)
return;

SetTrackedScent((uid, component), args.ScentId, target);
Expand Down
7 changes: 6 additions & 1 deletion Content.Shared/_Starlight/Scent/ScentSniffUi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,14 @@ public sealed class ScentSniffBoundUserInterfaceState : BoundUserInterfaceState
{
public readonly List<ScentTraceEntry> Entries;

public ScentSniffBoundUserInterfaceState(List<ScentTraceEntry> entries)
// The target's own current scent, if it has ScentComponent. Always offered as a pinned
// option above the trace list, separately from whatever traces were found on it.
public readonly string? OwnScentId;

public ScentSniffBoundUserInterfaceState(List<ScentTraceEntry> entries, string? ownScentId)
{
Entries = entries;
OwnScentId = ownScentId;
}
}

Expand Down
3 changes: 3 additions & 0 deletions Resources/Locale/en-US/_Starlight/scent/scent.ftl
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
scent-sniff-window-title = Scent Trace
scent-sniff-window-empty = No scents detected.
scent-sniff-window-empty-traces = No other scent traces detected.
scent-sniff-window-entry-id = [color={$color}]Scent ({$id}...)[/color]
scent-sniff-window-entry-detail = [color={$color}]{$species} - {$freshness}[/color]
scent-sniff-window-track-tooltip = Click to track this scent
scent-sniff-window-tracking-popup = You start tracking this scent.
scent-sniff-window-track-own = Track this creature's scent directly
scent-sniff-window-track-own-tooltip = Track this individual's scent directly.

scent-species-non-humanoid = Non-Humanoid

Expand Down
Loading