diff --git a/Content.Client/Revenant/RevenantRegenModifierSystem.cs b/Content.Client/Revenant/RevenantRegenModifierSystem.cs index c75fc6d6cd4eeb..1fc08ab0ac337c 100644 --- a/Content.Client/Revenant/RevenantRegenModifierSystem.cs +++ b/Content.Client/Revenant/RevenantRegenModifierSystem.cs @@ -1,16 +1,46 @@ +using System.Numerics; using Content.Client.Alerts; using Content.Shared.Revenant; using Content.Shared.Revenant.Components; +using Robust.Client.GameObjects; +using Robust.Client.Player; +using Robust.Shared.Map; +using Robust.Shared.Prototypes; +using Robust.Shared.Utility; +using Timer = Robust.Shared.Timing.Timer; namespace Content.Client.Revenant; public sealed class RevenantRegenModifierSystem : EntitySystem { + [Dependency] private readonly SpriteSystem _sprite = default!; + + private readonly SpriteSpecifier _witnessIndicator = new SpriteSpecifier.Texture(new ResPath("Interface/Actions/scream.png")); + public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnUpdateAlert); + SubscribeNetworkEvent(OnWitnesses); + } + + private void OnWitnesses(RevenantHauntWitnessEvent args) + { + foreach (var witness in args.Witnesses) + { + var ent = GetEntity(witness); + if (TryComp(ent, out var sprite)) + { + var layerID = sprite.AddLayer(_witnessIndicator); + if (sprite.TryGetLayer(layerID, out var layer)) + { + layer.Offset = new Vector2(0, 0.8f); + layer.Scale = new Vector2(0.65f, 0.65f); + } + Timer.Spawn(TimeSpan.FromSeconds(5), () => sprite.RemoveLayer(layerID)); + } + } } private void OnUpdateAlert(Entity ent, ref UpdateAlertSpriteEvent args) diff --git a/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs b/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs index 13ab8c21869de4..a30b47304ae1ba 100644 --- a/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs +++ b/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs @@ -37,6 +37,8 @@ using Content.Shared.Flash.Components; using Content.Shared.Flash; using Robust.Shared.Audio.Systems; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; namespace Content.Server.Revenant.EntitySystems; @@ -252,9 +254,7 @@ private void OnHauntAction(EntityUid uid, RevenantComponent comp, RevenantHauntA if (!HasComp(ent) || !HasComp(ent) || HasComp(ent)) return true; - var haunted = _interact.InRangeUnobstructed((uid, Transform(uid)), (ent, Transform(ent)), range: 0, collisionMask: CollisionGroup.Impassable); - Log.Debug($"{ent} haunted: {haunted}"); - return !haunted; + return !_interact.InRangeUnobstructed((uid, Transform(uid)), (ent, Transform(ent)), range: 0, collisionMask: CollisionGroup.Impassable); }); var witnesses = new HashSet(witnessAndRevenantFilter.RemovePlayerByAttachedEntity(uid).Recipients.Select(ply => GetNetEntity(ply.AttachedEntity!.Value))); @@ -271,18 +271,18 @@ private void OnHauntAction(EntityUid uid, RevenantComponent comp, RevenantHauntA ); } - - // TODO: Maybe an eyeball icon above witnesses on the revenant's client - - // TODO: Modify TryAddStatusEffect to add a premade instance of the component - if (witnesses.Count > 0 && _statusEffects.TryAddStatusEffect(uid, RevenantEssenceRegen, comp.HauntEssenceRegenDuration, true)) + if (witnesses.Count > 0 && _statusEffects.TryAddStatusEffect(uid, + RevenantEssenceRegen, + comp.HauntEssenceRegenDuration, + true, + component: new RevenantRegenModifierComponent(witnesses) + )) { + if (_mind.TryGetMind(uid, out var _, out var mind) && mind.Session != null) + RaiseNetworkEvent(new RevenantHauntWitnessEvent(witnesses), mind.Session); + _store.TryAddCurrency(new Dictionary { {comp.StolenEssenceCurrencyPrototype, comp.HauntStolenEssencePerWitness * witnesses.Count} }, uid); - - var regen = Comp(uid); - regen.Witnesses = witnesses; - Dirty(uid, regen); } } diff --git a/Content.Shared/Revenant/Components/RevenantRegenModifierComponent.cs b/Content.Shared/Revenant/Components/RevenantRegenModifierComponent.cs index 07087961420be6..0bc8b436715a92 100644 --- a/Content.Shared/Revenant/Components/RevenantRegenModifierComponent.cs +++ b/Content.Shared/Revenant/Components/RevenantRegenModifierComponent.cs @@ -8,8 +8,17 @@ namespace Content.Shared.Revenant.Components; public sealed partial class RevenantRegenModifierComponent : Component { [ViewVariables, AutoNetworkedField] - public HashSet Witnesses = new(); + public HashSet Witnesses; [DataField] public ProtoId Alert = "EssenceRegen"; + + public RevenantRegenModifierComponent(HashSet witnesses) + { + Witnesses = witnesses; + } + + public RevenantRegenModifierComponent() : this(new()) + { + } } \ No newline at end of file diff --git a/Content.Shared/Revenant/SharedRevenant.cs b/Content.Shared/Revenant/SharedRevenant.cs index d6eceb51fb54af..b073dcc8d598fd 100644 --- a/Content.Shared/Revenant/SharedRevenant.cs +++ b/Content.Shared/Revenant/SharedRevenant.cs @@ -74,6 +74,21 @@ public sealed partial class RevenantAnimateEvent : EntityTargetActionEvent { } +[Serializable, NetSerializable] +public sealed partial class RevenantHauntWitnessEvent : EntityEventArgs +{ + public HashSet Witnesses = new(); + + public RevenantHauntWitnessEvent(HashSet witnesses) + { + Witnesses = witnesses; + } + + public RevenantHauntWitnessEvent() : this(new()) + { + } +} + [Serializable, NetSerializable] public sealed partial class ExorciseRevenantDoAfterEvent : SimpleDoAfterEvent { diff --git a/Content.Shared/StatusEffect/StatusEffectsSystem.cs b/Content.Shared/StatusEffect/StatusEffectsSystem.cs index 000d3f3cc396d9..b5764e6e9acfd2 100644 --- a/Content.Shared/StatusEffect/StatusEffectsSystem.cs +++ b/Content.Shared/StatusEffect/StatusEffectsSystem.cs @@ -144,6 +144,22 @@ public bool TryAddStatusEffect(EntityUid uid, string key, TimeSpan time, bool re return false; } + public bool TryAddStatusEffect(EntityUid uid, string key, TimeSpan time, bool refresh, Component component, + StatusEffectsComponent? status = null) + { + if (!Resolve(uid, ref status, false)) + return false; + + if (TryAddStatusEffect(uid, key, time, refresh, status)) + { + EntityManager.AddComponent(uid, component, true); + status.ActiveEffects[key].RelevantComponent = _componentFactory.GetComponentName(component.GetType()); + return true; + } + + return false; + } + /// /// Tries to add a status effect to an entity with a certain timer. ///