diff --git a/Content.Client/_DV/CosmicCult/CosmicCultSystem.cs b/Content.Client/_DV/CosmicCult/CosmicCultSystem.cs new file mode 100644 index 0000000000..e849fdfcaa --- /dev/null +++ b/Content.Client/_DV/CosmicCult/CosmicCultSystem.cs @@ -0,0 +1,189 @@ +using Content.Shared._DV.CosmicCult.Components; +using Content.Shared._DV.CosmicCult; +using Content.Shared.StatusIcon.Components; +using Robust.Shared.Prototypes; +using Robust.Client.GameObjects; +using Robust.Shared.Utility; +using Content.Shared._DV.CosmicCult.Components.Examine; +using System.Numerics; +using Timer = Robust.Shared.Timing.Timer; +using Robust.Client.Audio; +using Robust.Shared.Audio; +using Content.Client.Alerts; +using Content.Client.UserInterface.Systems.Alerts.Controls; + +namespace Content.Client._DV.CosmicCult; + +public sealed partial class CosmicCultSystem : SharedCosmicCultSystem +{ + [Dependency] private readonly AudioSystem _audio = default!; + [Dependency] private readonly IPrototypeManager _prototype = default!; + + private readonly ResPath _rsiPath = new("/Textures/_DV/CosmicCult/Effects/ability_siphonvfx.rsi"); + + private readonly SoundSpecifier _siphonSFX = new SoundPathSpecifier("/Audio/_DV/CosmicCult/ability_siphon.ogg"); + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnAscendedInfectionAdded); + SubscribeLocalEvent(OnAscendedInfectionRemoved); + + SubscribeLocalEvent(OnAscendedAuraAdded); + SubscribeLocalEvent(OnAscendedAuraRemoved); + + SubscribeLocalEvent(OnCosmicStarMarkAdded); + SubscribeLocalEvent(OnCosmicStarMarkRemoved); + + SubscribeLocalEvent(OnCosmicImpositionAdded); + SubscribeLocalEvent(OnCosmicImpositionRemoved); + + SubscribeLocalEvent(GetCosmicCultIcon); + SubscribeLocalEvent(GetCosmicCultLeadIcon); + SubscribeLocalEvent(GetCosmicSSDIcon); + + SubscribeNetworkEvent(OnSiphon); + SubscribeLocalEvent(OnUpdateAlert); + } + + #region Siphon Visuals + private void OnSiphon(CosmicSiphonIndicatorEvent args) + { + var ent = GetEntity(args.Target); + if (!TryComp(ent, out var sprite)) + return; + var layer = sprite.AddLayer(new SpriteSpecifier.Rsi(_rsiPath, "vfx")); + sprite.LayerMapSet(CultSiphonedVisuals.Key, layer); + sprite.LayerSetOffset(layer, new Vector2(0, 0.8f)); + sprite.LayerSetScale(layer, new Vector2(0.65f, 0.65f)); + sprite.LayerSetShader(layer, "unshaded"); + + Timer.Spawn(TimeSpan.FromSeconds(2), () => sprite.RemoveLayer(CultSiphonedVisuals.Key)); + _audio.PlayLocal(_siphonSFX, ent, ent, AudioParams.Default.WithVariation(0.1f)); + } + + private void OnUpdateAlert(Entity ent, ref UpdateAlertSpriteEvent args) + { + if (args.Alert.ID != ent.Comp.EntropyAlert) + return; + var entropy = Math.Clamp(ent.Comp.EntropyStored, 0, 14); + var sprite = args.SpriteViewEnt.Comp; + sprite.LayerSetState(AlertVisualLayers.Base, $"base{entropy}"); + sprite.LayerSetState(CultAlertVisualLayers.Counter, $"num{entropy}"); + } + #endregion + + #region Layer Additions + private void OnAscendedInfectionAdded(Entity uid, ref ComponentStartup args) + { + if (!TryComp(uid, out var sprite) || sprite.LayerMapTryGet(AscendedInfectionKey.Key, out _)) + return; + + var layer = sprite.AddLayer(uid.Comp.Sprite); + + sprite.LayerMapSet(AscendedInfectionKey.Key, layer); + sprite.LayerSetShader(layer, "unshaded"); + } + + private void OnAscendedAuraAdded(Entity uid, ref ComponentStartup args) + { + if (!TryComp(uid, out var sprite) || sprite.LayerMapTryGet(AscendedAuraKey.Key, out _)) + return; + + var layer = sprite.AddLayer(uid.Comp.Sprite); + + sprite.LayerMapSet(AscendedAuraKey.Key, layer); + sprite.LayerSetShader(layer, "unshaded"); + } + + private void OnCosmicStarMarkAdded(Entity uid, ref ComponentStartup args) + { + if (!TryComp(uid, out var sprite) || sprite.LayerMapTryGet(CosmicRevealedKey.Key, out _)) + return; + + var layer = sprite.AddLayer(uid.Comp.Sprite); + sprite.LayerMapSet(CosmicRevealedKey.Key, layer); + sprite.LayerSetShader(layer, "unshaded"); + + //offset the mark if the mob has an offset comp, needed for taller species like Thaven + if (TryComp(uid, out var offset)) + { + sprite.LayerSetOffset(CosmicRevealedKey.Key, offset.Offset); + } + } + + private void OnCosmicImpositionAdded(Entity uid, ref ComponentStartup args) + { + if (!TryComp(uid, out var sprite) || sprite.LayerMapTryGet(CosmicImposingKey.Key, out _)) + return; + + var layer = sprite.AddLayer(uid.Comp.Sprite); + + sprite.LayerMapSet(CosmicImposingKey.Key, layer); + sprite.LayerSetShader(layer, "unshaded"); + } + #endregion + + #region Layer Removals + private void OnAscendedInfectionRemoved(Entity uid, ref ComponentShutdown args) + { + if (!TryComp(uid, out var sprite)) + return; + + sprite.RemoveLayer(AscendedInfectionKey.Key); + } + + private void OnAscendedAuraRemoved(Entity uid, ref ComponentShutdown args) + { + if (!TryComp(uid, out var sprite)) + return; + + sprite.RemoveLayer(AscendedAuraKey.Key); + } + + private void OnCosmicStarMarkRemoved(Entity uid, ref ComponentShutdown args) + { + if (!TryComp(uid, out var sprite)) + return; + + sprite.RemoveLayer(CosmicRevealedKey.Key); + } + + private void OnCosmicImpositionRemoved(Entity uid, ref ComponentShutdown args) + { + if (!TryComp(uid, out var sprite)) + return; + + sprite.RemoveLayer(CosmicImposingKey.Key); + } + #endregion + + #region Icons + private void GetCosmicCultIcon(Entity ent, ref GetStatusIconsEvent args) + { + if (HasComp(ent)) + return; + + if (_prototype.TryIndex(ent.Comp.StatusIcon, out var iconPrototype)) + args.StatusIcons.Add(iconPrototype); + } + + private void GetCosmicCultLeadIcon(Entity ent, ref GetStatusIconsEvent args) + { + if (_prototype.TryIndex(ent.Comp.StatusIcon, out var iconPrototype)) + args.StatusIcons.Add(iconPrototype); + } + + private void GetCosmicSSDIcon(Entity ent, ref GetStatusIconsEvent args) + { + if (_prototype.TryIndex(ent.Comp.StatusIcon, out var iconPrototype)) + args.StatusIcons.Add(iconPrototype); + } + #endregion +} + +public enum CultSiphonedVisuals : byte +{ + Key +} diff --git a/Content.Client/_DV/CosmicCult/MonumentSystem.cs b/Content.Client/_DV/CosmicCult/MonumentSystem.cs new file mode 100644 index 0000000000..f21b0b7f28 --- /dev/null +++ b/Content.Client/_DV/CosmicCult/MonumentSystem.cs @@ -0,0 +1,5 @@ +using Content.Shared._DV.CosmicCult; + +namespace Content.Client._DV.CosmicCult; + +public sealed class MonumentSystem : SharedMonumentSystem; diff --git a/Content.Client/_DV/CosmicCult/MonumentVisualsSystem.cs b/Content.Client/_DV/CosmicCult/MonumentVisualsSystem.cs new file mode 100644 index 0000000000..15d5e6fd17 --- /dev/null +++ b/Content.Client/_DV/CosmicCult/MonumentVisualsSystem.cs @@ -0,0 +1,44 @@ +using Robust.Client.GameObjects; +using Content.Shared._DV.CosmicCult.Components; + +namespace Content.Client._DV.CosmicCult; + +/// +/// Visualizer for The Monument of the Cosmic Cult. +/// +public sealed class MonumentVisualizerSystem : EntitySystem +{ + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnAppearanceChanged); + } + + private void OnAppearanceChanged(Entity ent, ref AppearanceChangeEvent args) + { + if (args.Sprite == null) + return; + args.Sprite.LayerMapTryGet(MonumentVisualLayers.TransformLayer, out var transformLayer); + args.Sprite.LayerMapTryGet(MonumentVisualLayers.MonumentLayer, out var baseLayer); + _appearance.TryGetData(ent, MonumentVisuals.Transforming, out var transforming, args.Component); + _appearance.TryGetData(ent, MonumentVisuals.Tier3, out var tier3, args.Component); + if (!tier3) + args.Sprite.LayerSetState(transformLayer, "transform-stage2"); + else + args.Sprite.LayerSetState(transformLayer, "transform-stage3"); + if (transforming && HasComp(ent)) + { + args.Sprite.LayerSetAnimationTime(transformLayer, 0f); + args.Sprite.LayerSetVisible(transformLayer, true); + args.Sprite.LayerSetVisible(baseLayer, false); + } + else + { + args.Sprite.LayerSetVisible(transformLayer, false); + args.Sprite.LayerSetVisible(baseLayer, true); + } + } +} diff --git a/Content.Client/_DV/CosmicCult/UI/CosmicConvertedEui.cs b/Content.Client/_DV/CosmicCult/UI/CosmicConvertedEui.cs new file mode 100644 index 0000000000..503cdfd51d --- /dev/null +++ b/Content.Client/_DV/CosmicCult/UI/CosmicConvertedEui.cs @@ -0,0 +1,25 @@ +using Content.Client.Eui; + +namespace Content.Client._DV.CosmicCult.UI; + +public sealed class CosmicConvertedEui : BaseEui +{ + private readonly CosmicConvertedMenu _menu; + + public CosmicConvertedEui() + { + _menu = new CosmicConvertedMenu(); + } + + public override void Opened() + { + _menu.OpenCentered(); + } + + public override void Closed() + { + base.Closed(); + + _menu.Close(); + } +} diff --git a/Content.Client/_DV/CosmicCult/UI/CosmicConvertedMenu.xaml b/Content.Client/_DV/CosmicCult/UI/CosmicConvertedMenu.xaml new file mode 100644 index 0000000000..3a97b7cd88 --- /dev/null +++ b/Content.Client/_DV/CosmicCult/UI/CosmicConvertedMenu.xaml @@ -0,0 +1,11 @@ + + +