diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs index 6ede3ec25f..8dd132d791 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Components/ShadowkinDarkSwapPowerComponent.cs @@ -1,7 +1,21 @@ -namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; +using Content.Server.NPC.Components; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; + +namespace Content.Server.SimpleStation14.Species.Shadowkin.Components; [RegisterComponent] public sealed partial class ShadowkinDarkSwapPowerComponent : Component { + /// + /// Factions temporarily deleted from the entity while swapped + /// + public List SuppressedFactions = new(); + + /// + /// Factions temporarily added to the entity while swapped + /// + [DataField("factions", customTypeSerializer: typeof(PrototypeIdListSerializer))] + public List AddedFactions = new() { "ShadowkinDarkFriendly" }; + public EntityUid? ActionShadowkinDarkSwap { get; set; } } diff --git a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs index 8e6fcee028..0f38d6b8e6 100644 --- a/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs +++ b/Content.Server/SimpleStation14/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs @@ -1,5 +1,7 @@ -using Content.Server.Ghost.Components; +using System.Linq; using Content.Server.Magic; +using Content.Server.NPC.Components; +using Content.Server.NPC.Systems; using Content.Server.SimpleStation14.Species.Shadowkin.Components; using Content.Server.SimpleStation14.Species.Shadowkin.Events; using Content.Server.Visible; @@ -16,6 +18,7 @@ using Robust.Shared.Audio; using Robust.Shared.Prototypes; + namespace Content.Server.SimpleStation14.Species.Shadowkin.Systems; public sealed class ShadowkinDarkSwapSystem : EntitySystem @@ -30,6 +33,7 @@ public sealed class ShadowkinDarkSwapSystem : EntitySystem [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly MagicSystem _magic = default!; + [Dependency] private readonly NpcFactionSystem _factions = default!; public override void Initialize() { @@ -44,12 +48,10 @@ public override void Initialize() SubscribeLocalEvent(OnInvisShutdown); } - private void Startup(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentStartup args) { var componentActionShadowkinDarkSwap = component.ActionShadowkinDarkSwap; _actions.AddAction(uid, ref componentActionShadowkinDarkSwap, "ActionShadowkinDarkSwap"); - // _actions.AddAction(uid, "ActionShadowkinDarkSwap"); } private void Shutdown(EntityUid uid, ShadowkinDarkSwapPowerComponent component, ComponentShutdown args) @@ -76,6 +78,7 @@ private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, args.Performer, !hasComp, !hasComp, + !hasComp, true, args.StaminaCostOn, args.PowerCostOn, @@ -87,13 +90,16 @@ private void DarkSwap(EntityUid uid, ShadowkinDarkSwapPowerComponent component, args.VolumeOff, args ); + _magic.Speak(args, false); } + public void SetDarkened( EntityUid performer, bool addComp, bool invisible, + bool pacify, bool darken, float staminaCostOn, float powerCostOn, @@ -110,13 +116,18 @@ public void SetDarkened( RaiseLocalEvent(ev); if (ev.Cancelled) return; + if (addComp) { var comp = _entity.EnsureComponent(performer); comp.Invisible = invisible; + comp.Pacify = pacify; comp.Darken = darken; + RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, true)); + _audio.PlayPvs(soundOn, performer, AudioParams.Default.WithVolume(volumeOn)); + _power.TryAddPowerLevel(performer, -powerCostOn); _stamina.TakeStaminaDamage(performer, staminaCostOn); } @@ -124,64 +135,130 @@ public void SetDarkened( { _entity.RemoveComponent(performer); RaiseNetworkEvent(new ShadowkinDarkSwappedEvent(performer, false)); + _audio.PlayPvs(soundOff, performer, AudioParams.Default.WithVolume(volumeOff)); + _power.TryAddPowerLevel(performer, -powerCostOff); _stamina.TakeStaminaDamage(performer, staminaCostOff); } + if (args != null) args.Handled = true; } + private void OnInvisStartup(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentStartup args) { - EnsureComp(uid); + if (component.Pacify) + EnsureComp(uid); + if (component.Invisible) - SetCanSeeInvisibility(uid, true); + { + SetVisibility(uid, true); + SuppressFactions(uid, true); + } } private void OnInvisShutdown(EntityUid uid, ShadowkinDarkSwappedComponent component, ComponentShutdown args) { RemComp(uid); + if (component.Invisible) - SetCanSeeInvisibility(uid, false); + { + SetVisibility(uid, false); + SuppressFactions(uid, false); + } + component.Darken = false; + foreach (var light in component.DarkenedLights.ToArray()) { if (!_entity.TryGetComponent(light, out var pointLight) || !_entity.TryGetComponent(light, out var shadowkinLight)) continue; + _darken.ResetLight(pointLight, shadowkinLight); } + component.DarkenedLights.Clear(); } // Commented out eye and ghost stuff until ported - public void SetCanSeeInvisibility(EntityUid uid, bool set) + public void SetVisibility(EntityUid uid, bool set) { - var visibility = _entity.EnsureComponent(uid); - if (set) + // We require the visibility component for this to work + var visibility = EnsureComp(uid); + + if (set) // Invisible { + // Allow the entity to see DarkSwapped entities /*if (_entity.TryGetComponent(uid, out EyeComponent? eye)) - { - eye.VisibilityMask |= (uint) VisibilityFlags.DarkSwapInvisibility; - }*/ + eye.VisibilityMask |= (uint) VisibilityFlags.DarkSwapInvisibility;*/ + + // Make other entities unable to see the entity unless also DarkSwapped _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); + + // If not a ghost, add a stealth shader to the entity if (!_entity.TryGetComponent(uid, out var _)) _stealth.SetVisibility(uid, 0.8f, _entity.EnsureComponent(uid)); } - else + else // Visible { + // Remove the ability to see DarkSwapped entities /*if (_entity.TryGetComponent(uid, out EyeComponent? eye)) - { - // eye.VisibilityMask &= ~(uint) VisibilityFlags.DarkSwapInvisibility; - }*/ + eye.VisibilityMask &= ~(uint) VisibilityFlags.DarkSwapInvisibility;*/ + + // Make other entities able to see the entity again _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.DarkSwapInvisibility, false); _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid); - if (!_entity.TryGetComponent(uid, out var _)) - _entity.RemoveComponent(uid); + + // Remove the stealth shader from the entity + if (!_entity.TryGetComponent(uid, out _)) + _stealth.SetVisibility(uid, 1f, _entity.EnsureComponent(uid)); + } + } + + /// + /// Remove existing factions on the entity and move them to the power component to add back when removed from The Dark + /// + /// Entity to modify factions for + /// Add or remove the factions + public void SuppressFactions(EntityUid uid, bool set) + { + // We require the power component to keep track of the factions + if (!_entity.TryGetComponent(uid, out var component)) + return; + + if (set) + { + if (!_entity.TryGetComponent(uid, out var factions)) + return; + + // Copy the suppressed factions to the power component + component.SuppressedFactions = factions.Factions.ToList(); + + // Remove the factions from the entity + foreach (var faction in factions.Factions) + _factions.RemoveFaction(uid, faction); + + // Add status factions for The Dark to the entity + foreach (var faction in component.AddedFactions) + _factions.AddFaction(uid, faction); + } + else + { + // Remove the status factions from the entity + foreach (var faction in component.AddedFactions) + _factions.RemoveFaction(uid, faction); + + // Add the factions back to the entity + foreach (var faction in component.SuppressedFactions) + _factions.AddFaction(uid, faction); + + component.SuppressedFactions.Clear(); } } } diff --git a/Resources/Prototypes/SimpleStation14/factions.yml b/Resources/Prototypes/SimpleStation14/factions.yml new file mode 100644 index 0000000000..340a8ed8da --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/factions.yml @@ -0,0 +1,9 @@ +- type: npcFaction + id: ShadowkinDarkHostile + hostile: + - ShadowkinDarkFriendly + +- type: npcFaction + id: ShadowkinDarkFriendly + hostile: + - ShadowkinDarkHostile