Skip to content

Commit 0cffc5f

Browse files
authored
Allow Smellers to smell Scent bearers directly (#5544)
## Short description <!-- What do you propose to change with your PR? --> Allow a Smeller to smell someone directly if they have a Scent. ## Why we need to add this <!-- What is the reason for adding these changes? Please post links to Discussions as well as Bug Reports here. Please describe how this will change the game balance. --> It made the most sense to do this. The current way you smell someone directly is by hugging them and then smelling yourself. Very weird and unintuitive action. This turned out to be more effort than I had anticipated, and I was gonna bundle this in with a few extra things like an olfactory implant. Turns out these are all a bit chunky so I'm gonna part these out for easier review and handling. ## Media (Video/Screenshots) <!-- If your PR contains in-game changes you must provide screenshots/videos of the changes. --> <img width="635" height="324" alt="image" src="https://github.com/user-attachments/assets/40fb71b2-77cc-43b0-87d0-8127ebdaffa6" /> ## Checks <!-- check boxes for faster reviewing of your PR --> - [X] I do not require assistance to complete the PR. - [X] Before posting/requesting review of a PR, I have verified that the changes work. - [X] I have added screenshots/videos of the changes, or this PR does not change in-game mechanics. - [X] I affirm that my changes are licensed under the [MIT License](https://github.com/ss14Starlight/space-station-14/blob/Starlight/LICENSE.TXT) and grant permission for use in this repository under its conditions. **Changelog** :cl: Sparlight - add: Individuals that can smell can now smell anything with a scent directly now, in addition to the scent traces left behind on them. <!-- If you want the players to know about changes made in this PR, specify them using the template outside the comment. Short and informative. :cl: STARLIGHT TEAM - add: Added Starlight. - remove: Removed SS13. - tweak: Changed SS14. - fix: Fixed Rinary. -->
1 parent 2d09600 commit 0cffc5f

5 files changed

Lines changed: 55 additions & 18 deletions

File tree

Content.Client/_Starlight/Scent/ScentSniffBoundUserInterface.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ protected override void UpdateState(BoundUserInterfaceState state)
3131
if (_window == null || state is not ScentSniffBoundUserInterfaceState cast)
3232
return;
3333

34-
_window.UpdateEntries(cast.Entries);
34+
_window.UpdateEntries(cast.Entries, cast.OwnScentId);
3535
}
3636
}

Content.Client/_Starlight/Scent/ScentSniffMenu.xaml.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
using System.Numerics;
2+
using Content.Client.Administration.UI.CustomControls;
13
using Content.Client.Message;
24
using Content.Shared._Starlight.Scent;
35
using Robust.Client.AutoGenerated;
6+
using Robust.Client.UserInterface;
47
using Robust.Client.UserInterface.Controls;
58
using Robust.Client.UserInterface.CustomControls;
69
using Robust.Client.UserInterface.XAML;
@@ -19,13 +22,30 @@ public ScentSniffMenu()
1922
RobustXamlLoader.Load(this);
2023
}
2124

22-
public void UpdateEntries(List<ScentTraceEntry> entries)
25+
public void UpdateEntries(List<ScentTraceEntry> entries, string? ownScentId)
2326
{
2427
Rows.RemoveAllChildren();
2528

29+
if (ownScentId is { } ownId)
30+
{
31+
var ownRow = new ContainerButton
32+
{
33+
ToolTip = Loc.GetString("scent-sniff-window-track-own-tooltip"),
34+
HorizontalExpand = true,
35+
};
36+
ownRow.AddStyleClass(ContainerButton.StyleClassButton);
37+
ownRow.AddChild(new Label { Text = Loc.GetString("scent-sniff-window-track-own") });
38+
ownRow.OnPressed += _ => OnTrackPressed?.Invoke(ownId);
39+
Rows.AddChild(ownRow);
40+
41+
Rows.AddChild(new HSeparator());
42+
Rows.AddChild(new Control { MinSize = new Vector2(0, 10) });
43+
}
44+
2645
if (entries.Count == 0)
2746
{
28-
Rows.AddChild(new Label { Text = Loc.GetString("scent-sniff-window-empty") });
47+
var emptyKey = ownScentId != null ? "scent-sniff-window-empty-traces" : "scent-sniff-window-empty";
48+
Rows.AddChild(new Label { Text = Loc.GetString(emptyKey) });
2949
return;
3050
}
3151

Content.Server/_Starlight/Scent/Systems/ScentSystem.cs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ private void OnSniffObjectAction(Entity<SmellerComponent> ent, ref SniffObjectAc
101101
if (trace != null)
102102
PruneExpiredTraces(trace);
103103

104-
if (trace == null || trace.Scents.Count == 0)
104+
var hasOwnScent = TryComp<ScentComponent>(args.Target, out var targetScent) && targetScent.ScentId != null;
105+
106+
if ((trace == null || trace.Scents.Count == 0) && !hasOwnScent)
105107
{
106108
_popup.PopupEntity(Loc.GetString("scent-sniff-no-scents", ("target", Name(args.Target))), args.Target, ent.Owner);
107109
args.Handled = true;
@@ -126,23 +128,27 @@ private void OnSniffObjectDoAfter(EntityUid uid, SmellerComponent component, Sni
126128
if (args.Handled || args.Cancelled || args.Args.Target is not { } target)
127129
return;
128130

129-
if (!TryComp<ScentTraceComponent>(target, out var trace))
130-
return;
131-
132-
PruneExpiredTraces(trace);
131+
TryComp<ScentTraceComponent>(target, out var trace);
132+
if (trace != null)
133+
PruneExpiredTraces(trace);
133134

134135
var now = _timing.CurTime;
135-
var entries = new List<ScentTraceEntry>(trace.Scents.Count);
136-
foreach (var (scentId, info) in trace.Scents)
136+
var entries = new List<ScentTraceEntry>(trace?.Scents.Count ?? 0);
137+
if (trace != null)
137138
{
138-
var speciesName = Loc.GetString("scent-species-non-humanoid");
139-
if (info.Species != null && _prototype.TryIndex<SpeciesPrototype>(info.Species, out var species))
140-
speciesName = Loc.GetString(species.Name);
139+
foreach (var (scentId, info) in trace.Scents)
140+
{
141+
var speciesName = Loc.GetString("scent-species-non-humanoid");
142+
if (info.Species != null && _prototype.TryIndex<SpeciesPrototype>(info.Species, out var species))
143+
speciesName = Loc.GetString(species.Name);
141144

142-
var age = (float)(now - info.LastTouched).TotalSeconds;
143-
entries.Add(new ScentTraceEntry(scentId, GetFreshness(age, trace.TraceLifetime), speciesName));
145+
var age = (float)(now - info.LastTouched).TotalSeconds;
146+
entries.Add(new ScentTraceEntry(scentId, GetFreshness(age, trace.TraceLifetime), speciesName));
147+
}
144148
}
145149

150+
var ownScentId = TryComp<ScentComponent>(target, out var targetScent) ? targetScent.ScentId : null;
151+
146152
if (!_ui.TryOpenUi(uid, ScentSniffUiKey.Key, uid))
147153
{
148154
Log.Warning($"{ToPrettyString(uid)} has SmellerComponent but couldn't open ScentSniffUiKey - " +
@@ -151,7 +157,7 @@ private void OnSniffObjectDoAfter(EntityUid uid, SmellerComponent component, Sni
151157
}
152158

153159
component.SniffTarget = target;
154-
_ui.SetUiState(uid, ScentSniffUiKey.Key, new ScentSniffBoundUserInterfaceState(entries));
160+
_ui.SetUiState(uid, ScentSniffUiKey.Key, new ScentSniffBoundUserInterfaceState(entries, ownScentId));
155161

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

194-
if (!TryComp<ScentTraceComponent>(target, out var trace) || !trace.Scents.ContainsKey(args.ScentId))
200+
var isOwnScent = TryComp<ScentComponent>(target, out var targetScent) && targetScent.ScentId == args.ScentId;
201+
var isTracedScent = TryComp<ScentTraceComponent>(target, out var trace) && trace.Scents.ContainsKey(args.ScentId);
202+
203+
if (!isOwnScent && !isTracedScent)
195204
return;
196205

197206
SetTrackedScent((uid, component), args.ScentId, target);

Content.Shared/_Starlight/Scent/ScentSniffUi.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,14 @@ public sealed class ScentSniffBoundUserInterfaceState : BoundUserInterfaceState
4545
{
4646
public readonly List<ScentTraceEntry> Entries;
4747

48-
public ScentSniffBoundUserInterfaceState(List<ScentTraceEntry> entries)
48+
// The target's own current scent, if it has ScentComponent. Always offered as a pinned
49+
// option above the trace list, separately from whatever traces were found on it.
50+
public readonly string? OwnScentId;
51+
52+
public ScentSniffBoundUserInterfaceState(List<ScentTraceEntry> entries, string? ownScentId)
4953
{
5054
Entries = entries;
55+
OwnScentId = ownScentId;
5156
}
5257
}
5358

Resources/Locale/en-US/_Starlight/scent/scent.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
scent-sniff-window-title = Scent Trace
22
scent-sniff-window-empty = No scents detected.
3+
scent-sniff-window-empty-traces = No other scent traces detected.
34
scent-sniff-window-entry-id = [color={$color}]Scent ({$id}...)[/color]
45
scent-sniff-window-entry-detail = [color={$color}]{$species} - {$freshness}[/color]
56
scent-sniff-window-track-tooltip = Click to track this scent
67
scent-sniff-window-tracking-popup = You start tracking this scent.
8+
scent-sniff-window-track-own = Track this creature's scent directly
9+
scent-sniff-window-track-own-tooltip = Track this individual's scent directly.
710
811
scent-species-non-humanoid = Non-Humanoid
912

0 commit comments

Comments
 (0)