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