Files
wwdpublic/Content.Server/Forensics/Systems/ScentTrackerSystem.cs
FoxxoTrystan d9a04690a4 Vulpkanin Update (#715)
![WarningTrystan](https://github.com/user-attachments/assets/958f868b-11b9-48f0-80ab-13d9ff243f06)
<!--
This is a semi-strict format, you can add/remove sections as needed but
the order/format should be kept the same
Remove these comments before submitting
-->

# Description

<!--
Explain this PR in as much detail as applicable

Some example prompts to consider:
How might this affect the game? The codebase?
What might be some alternatives to this?
How/Who does this benefit/hurt [the game/codebase]?
-->

This PR is the rework regarding the unique feature for vulpkanins, this
is mostly due to the "FORCED" Issue by VM:
https://github.com/Simple-Station/Einstein-Engines/issues/711

This PR will mostly add the new features that will mostly make
Vulpkanins unique.

For Vulpkanin Stats changed please check this PR:
https://github.com/Simple-Station/Einstein-Engines/pull/713

- Flash Damge: Flashable has 2 new variables "EyeDamageChance" (Float)
and "EyeDamage" (int), those are default to 0 but if changed could give
a chance from 0 to 1 to give EyeDamage from the EyeDamage Value, this is
not fixed to vulpkanin and can be added to anything with the "Flashable"
Component.
- ScentTracker: Add a new Forensics type "Scent", scent will spread on
everything you wear and only the ent with the "ScentTrackerSystem" can
track a scent, tracking a scent will leave an effect on those who has or
the item with the scent, scent can be cleaned away with soap or you can
compleatly generate a new scent of a person by cleaning yourself, note:
someone with a scent does not mean his the one making that scent, they
may just have an item with the scent in their bag!
- Vulpkanins Screams: I have 5 Fox Screams that need to be edited and
need to be added in-game for vulpkanins with a lisence, just need to
have the time to do it and this PR seem the perfect place for it.

---

# TODO

<!--
A list of everything you have to do before this PR is "complete"
You probably won't have to complete everything before merging but it's
good to leave future references
-->

- [x] Flash Damage
- [x] Scent System
- [x] ScentTracker System
- [x] Vulpkanin Screams

---

<!--
This is default collapsed, readers click to expand it and see all your
media
The PR media section can get very large at times, so this is a good way
to keep it clean
The title is written using HTML tags
The title must be within the <summary> tags or you won't see it
-->

<details><summary><h1>Media</h1></summary>
<p>


![image](https://github.com/user-attachments/assets/3bd60c0f-2528-4be7-a52d-defe2990c475)

![image](https://github.com/user-attachments/assets/6756b6af-3f76-4faa-9fbd-c35964b267b3)

![image](https://github.com/user-attachments/assets/b4ff84a2-64eb-4985-876b-d3e93fc8bd12)

![image](https://github.com/user-attachments/assets/dd4b47ea-ae39-44c3-b5a2-27ee68703857)

</p>
</details>

---

# Changelog

<!--
You can add an author after the `🆑` to change the name that appears
in the changelog (ex: `🆑 Death`)
Leaving it blank will default to your GitHub display name
This includes all available types for the changelog
-->

🆑 FoxxoTrystan
- add: Forensics Scent Type and Vulpkanins can now track scents, better
keep yourself clean!
- tweak: Vulpkanins eyes are sensetive, please dont flash them with
lights as this could damage them.
- add: Vulpkanins now has their own screams!

---------

Signed-off-by: FoxxoTrystan <45297731+FoxxoTrystan@users.noreply.github.com>
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
Co-authored-by: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com>
2024-08-15 03:11:05 -04:00

131 lines
4.9 KiB
C#

using Content.Server.Popups;
using Content.Shared.DoAfter;
using Content.Shared.Verbs;
using Content.Shared.Forensics;
using Content.Shared.Examine;
using Robust.Shared.Utility;
using Content.Shared.IdentityManagement;
namespace Content.Server.Forensics
{
public sealed class ScentTrackerSystem : EntitySystem
{
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
public override void Initialize()
{
SubscribeLocalEvent<ScentTrackerComponent, GetVerbsEvent<InnateVerb>>(AddVerbs);
SubscribeLocalEvent<ScentTrackerComponent, ScentTrackerDoAfterEvent>(TrackScentDoAfter);
SubscribeLocalEvent<ForensicsComponent, ExaminedEvent>((uid, _, args) => OnExamine(uid, args));
}
private void AddVerbs(EntityUid uid, ScentTrackerComponent component, GetVerbsEvent<InnateVerb> args)
{
TrackScentVerb(uid, component, args);
StopTrackScentVerb(uid, component, args);
}
private void TrackScentVerb(EntityUid uid, ScentTrackerComponent component, GetVerbsEvent<InnateVerb> args)
{
if (!args.CanInteract
|| !args.CanAccess
|| args.User == args.Target)
return;
InnateVerb verbTrackScent = new()
{
Act = () => AttemptTrackScent(uid, args.Target, component),
Text = Loc.GetString("track-scent"),
Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/VerbIcons/psionic_invisibility.png")),
Priority = 1
};
args.Verbs.Add(verbTrackScent);
}
private void AttemptTrackScent(EntityUid user, EntityUid target, ScentTrackerComponent component)
{
if (!HasComp<ScentTrackerComponent>(user))
return;
var doAfterEventArgs = new DoAfterArgs(EntityManager, user, component.SniffDelay, new ScentTrackerDoAfterEvent(), user, target: target)
{
BreakOnUserMove = true,
BreakOnDamage = true,
BreakOnTargetMove = true
};
_popupSystem.PopupEntity(Loc.GetString("start-tracking-scent", ("user", Identity.Name(user, EntityManager)), ("target", Identity.Name(target, EntityManager))), user);
_doAfterSystem.TryStartDoAfter(doAfterEventArgs);
}
private void TrackScentDoAfter(Entity<ScentTrackerComponent> entity, ref ScentTrackerDoAfterEvent args)
{
if (args.Handled
|| args.Cancelled
|| args.Args.Target == null)
return;
TrackScent(args.Args.User, args.Args.Target.Value);
args.Handled = true;
}
private void StopTrackScentVerb(EntityUid uid, ScentTrackerComponent component, GetVerbsEvent<InnateVerb> args)
{
if (args.User != args.Target
|| component.Scent == string.Empty)
return;
InnateVerb verbStopTrackScent = new()
{
Act = () => StopTrackScent(uid, component),
Text = Loc.GetString("stop-track-scent"),
Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/VerbIcons/psionic_invisibility.png")),
Priority = 2
};
args.Verbs.Add(verbStopTrackScent);
}
private void OnExamine(EntityUid uid, ExaminedEvent args)
{
if (!TryComp<ScentTrackerComponent>(args.Examiner, out var component)
|| !TryComp<ForensicsComponent>(args.Examined, out var forcomp))
return;
if (forcomp.Scent != string.Empty && component.Scent == forcomp.Scent)
args.PushMarkup(Loc.GetString("examined-scent"), -1);
}
#region Utilities
public void TrackScent(EntityUid uid, EntityUid target)
{
if (!TryComp<ScentTrackerComponent>(uid, out var component)
|| !TryComp<ForensicsComponent>(target, out var forcomp))
return;
if (forcomp.Scent != string.Empty)
{
component.Scent = forcomp.Scent;
_popupSystem.PopupEntity(Loc.GetString("tracking-scent", ("target", Identity.Name(target, EntityManager))), uid, uid);
}
else
_popupSystem.PopupEntity(Loc.GetString("no-scent"), uid, uid);
Dirty(uid, component);
}
public void StopTrackScent(EntityUid uid, ScentTrackerComponent component)
{
if (!HasComp<ScentTrackerComponent>(uid))
return;
component.Scent = string.Empty;
_popupSystem.PopupEntity(Loc.GetString("stopped-tracking-scent"), uid, uid);
Dirty(uid, component);
}
#endregion
}
}