using Content.Shared._DV.CosmicCult.Components; using Content.Shared._DV.CosmicCult; using Content.Shared.Clothing; using Content.Shared.Hands; using Content.Shared.IdentityManagement.Components; using Content.Shared.Inventory.Events; 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!; [Dependency] private readonly SpriteSystem _sprite = 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((uid, _, _) => UpdateSubtleMarkVisibility(uid)); SubscribeLocalEvent((uid, _, _) => UpdateSubtleMarkVisibility(uid)); SubscribeLocalEvent((uid, _, _) => UpdateSubtleMarkVisibility(uid)); SubscribeLocalEvent((uid, _, _) => UpdateSubtleMarkVisibility(uid)); SubscribeLocalEvent((uid, _, _) => UpdateSubtleMarkVisibility(uid)); SubscribeLocalEvent(OnCosmicStarMarkAdded); SubscribeLocalEvent(OnCosmicStarMarkRemoved); SubscribeLocalEvent(OnCosmicSubtleMarkAdded); SubscribeLocalEvent(OnCosmicSubtleMarkRemoved); 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((ent, sprite), new SpriteSpecifier.Rsi(_rsiPath, "vfx")); _sprite.LayerMapSet((ent, sprite), CultSiphonedVisuals.Key, layer); _sprite.LayerSetOffset((ent, sprite), layer, new Vector2(0, 0.8f)); _sprite.LayerSetScale((ent, sprite), layer, new Vector2(0.65f, 0.65f)); sprite.LayerSetShader(layer, "unshaded"); Timer.Spawn(TimeSpan.FromSeconds(2), () => _sprite.RemoveLayer((ent, sprite), 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.LayerSetRsiState((ent, sprite), AlertVisualLayers.Base, $"base{entropy}"); _sprite.LayerSetRsiState((ent, sprite), CultAlertVisualLayers.Counter, $"num{entropy}"); } #endregion #region Layer Additions private void OnCosmicStarMarkAdded(Entity uid, ref ComponentStartup args) { if (!TryComp(uid, out var sprite) || _sprite.LayerMapTryGet((uid, sprite), CosmicRevealedKey.Key, out _, false)) return; var layer = _sprite.AddLayer((uid, sprite), uid.Comp.Sprite); _sprite.LayerMapSet((uid, sprite), 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((uid, sprite), CosmicRevealedKey.Key, offset.Offset); _sprite.LayerSetRsiState((uid, sprite), layer, offset.StarState); } } private void OnCosmicSubtleMarkAdded(Entity uid, ref ComponentStartup args) { if (!TryComp(uid, out var sprite) || _sprite.LayerMapTryGet((uid, sprite), CosmicRevealedKey.Key, out _, false)) return; var layer = _sprite.AddLayer((uid, sprite), uid.Comp.Sprite); _sprite.LayerMapSet((uid, sprite), CosmicRevealedKey.Key, layer); sprite.LayerSetShader(layer, "unshaded"); UpdateSubtleMarkVisibility(uid); //I am NOT accounting for IPCs here. If you want it, do it yourself. You guys wanted them to be able to look like any other species, not me. //Also there's probably a better solution but meh, this works. if (TryComp(uid, out var offset)) { _sprite.LayerSetOffset((uid, sprite), CosmicRevealedKey.Key, offset.Offset); _sprite.LayerSetRsiState((uid, sprite), layer, offset.SubtleState); } } private void OnCosmicImpositionAdded(Entity uid, ref ComponentStartup args) { if (!TryComp(uid, out var sprite) || _sprite.LayerMapTryGet((uid, sprite), CosmicImposingKey.Key, out _, false)) return; var layer = _sprite.AddLayer((uid, sprite), uid.Comp.Sprite); _sprite.LayerMapSet((uid, sprite), CosmicImposingKey.Key, layer); sprite.LayerSetShader(layer, "unshaded"); } #endregion #region Layer Removals private void OnCosmicStarMarkRemoved(Entity uid, ref ComponentShutdown args) { if (!TryComp(uid, out var sprite)) return; _sprite.RemoveLayer((uid, sprite), CosmicRevealedKey.Key); } private void OnCosmicSubtleMarkRemoved(Entity uid, ref ComponentShutdown args) { if (!TryComp(uid, out var sprite)) return; _sprite.RemoveLayer((uid, sprite), CosmicRevealedKey.Key); } private void OnCosmicImpositionRemoved(Entity uid, ref ComponentShutdown args) { if (!TryComp(uid, out var sprite)) return; _sprite.RemoveLayer((uid, sprite), 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 #region Mark updates private void UpdateSubtleMarkVisibility(EntityUid uid) { if (!TryComp(uid, out var sprite) || !_sprite.LayerMapTryGet((uid, sprite), CosmicRevealedKey.Key, out var layer, false)) return; if (!TryComp(uid, out var markComp)) return; var ev = new SeeIdentityAttemptEvent(); RaiseLocalEvent(uid, ev); var eyesCovered = ev.TotalCoverage.HasFlag(IdentityBlockerCoverage.EYES); _sprite.LayerSetVisible((uid, sprite), layer, !eyesCovered); } #endregion } public enum CultSiphonedVisuals : byte { Key }