diff --git a/Content.Client/_Wega/BloodCult/BloodCultSystem.cs b/Content.Client/_Wega/BloodCult/BloodCultSystem.cs new file mode 100644 index 0000000000..1ce2472b15 --- /dev/null +++ b/Content.Client/_Wega/BloodCult/BloodCultSystem.cs @@ -0,0 +1,109 @@ + +using System.Numerics; +using Content.Shared.Blood.Cult; +using Content.Shared.Blood.Cult.Components; +using Content.Shared.StatusIcon.Components; +using Robust.Client.GameObjects; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Robust.Shared.Utility; + +namespace Content.Client.Blood.Cult +{ + public sealed class BloodCultSystem : SharedBloodCultSystem + { + [Dependency] private readonly AppearanceSystem _appearance = default!; + [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly SpriteSystem _sprite = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnRuneAppearanceChanged); + SubscribeLocalEvent(OnRuneAppearanceChanged); + SubscribeLocalEvent(GetCultistIcons); + SubscribeLocalEvent(GetHalo); + SubscribeLocalEvent(RemoveHalo); + SubscribeLocalEvent(OnSoulStoneAppearanceChanged); + } + + private void OnRuneAppearanceChanged(Entity entity, ref AppearanceChangeEvent args) + { + if (!_appearance.TryGetData(entity, RuneColorVisuals.Color, out Color color)) + return; + + _sprite.SetColor(entity.Owner, color); + } + + private void OnRuneAppearanceChanged(Entity entity, ref AppearanceChangeEvent args) + { + if (!_appearance.TryGetData(entity, RuneColorVisuals.Color, out Color color)) + return; + + _sprite.SetColor(entity.Owner, color); + } + + private void GetCultistIcons(Entity ent, ref GetStatusIconsEvent args) + { + var iconPrototype = _prototype.Index(ent.Comp.StatusIcon); + args.StatusIcons.Add(iconPrototype); + } + + private void GetHalo(EntityUid uid, PentagramDisplayComponent component, ComponentStartup args) + { + if (!TryComp(uid, out var sprite)) + return; + + if (_sprite.LayerMapTryGet(uid, PentagramKey.Halo, out _, true)) + return; + + var haloVariant = _random.Next(1, 6); + var haloState = $"halo{haloVariant}"; + + var bounds = _sprite.GetLocalBounds((uid, sprite)); + var adj = bounds.Height / 2 + 1.0f / 32 * 6.0f; + + var layerData = new PrototypeLayerData + { + Shader = "unshaded", + RsiPath = "_Wega/Interface/Misc/bloodcult_halo.rsi", + State = haloState, + Offset = new Vector2(0.0f, adj) + }; + + var layer = _sprite.AddLayer(uid, layerData, null); + _sprite.LayerMapSet(uid, PentagramKey.Halo, layer); + } + + private void RemoveHalo(EntityUid uid, PentagramDisplayComponent component, ComponentShutdown args) + { + if (_sprite.LayerMapTryGet(uid, PentagramKey.Halo, out var layer, true)) + { + _sprite.RemoveLayer(uid, layer); + } + } + + private void OnSoulStoneAppearanceChanged(EntityUid uid, StoneSoulComponent component, ref AppearanceChangeEvent args) + { + if (!_appearance.TryGetData(uid, StoneSoulVisuals.HasSoul, out bool hasSoul)) + hasSoul = false; + + _sprite.LayerSetVisible(uid, StoneSoulVisualLayers.Soul, hasSoul); + if (!hasSoul) + { + _sprite.LayerSetVisible(uid, StoneSoulVisualLayers.Base, true); + } + else + { + _sprite.LayerSetVisible(uid, StoneSoulVisualLayers.Base, false); + } + } + + private enum PentagramKey + { + Halo + } + } +} diff --git a/Content.Client/_Wega/BloodCult/Ui/BloodConstructMenu.xaml b/Content.Client/_Wega/BloodCult/Ui/BloodConstructMenu.xaml new file mode 100644 index 0000000000..5acb1720ab --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/BloodConstructMenu.xaml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content.Client/_Wega/BloodCult/Ui/BloodConstructMenu.xaml.cs b/Content.Client/_Wega/BloodCult/Ui/BloodConstructMenu.xaml.cs new file mode 100644 index 0000000000..81c261e10f --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/BloodConstructMenu.xaml.cs @@ -0,0 +1,49 @@ +using Content.Client.UserInterface.Controls; +using Content.Shared.Blood.Cult; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Player; + +namespace Content.Client.Select.Construct.UI; + +[GenerateTypedNameReferences] +public sealed partial class BloodConstructMenu : RadialMenu +{ + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IEntityNetworkManager _entityNetworkManager = default!; + [Dependency] private readonly ISharedPlayerManager _playerManager = default!; + + public event Action? OnSelectConstruct; + private NetEntity _constructUid; + private NetEntity _mindUid; + + public BloodConstructMenu() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + + InitializeButtons(); + } + + private void InitializeButtons() + { + BloodJuggernautButton.OnButtonUp += _ => HandleRitesSelection("MobConstructJuggernaut"); + BloodWraithButton.OnButtonUp += _ => HandleRitesSelection("MobConstructWraith"); + BloodArtificerButton.OnButtonUp += _ => HandleRitesSelection("MobConstructArtificer"); + BloodProteonButton.OnButtonUp += _ => HandleRitesSelection("MobConstructProteon"); + } + + public void SetData(NetEntity constructUid, NetEntity mindUid) + { + _constructUid = constructUid; + _mindUid = mindUid; + } + + private void HandleRitesSelection(string constructName) + { + OnSelectConstruct?.Invoke(constructName); + var netEntity = _entityManager.GetNetEntity(_playerManager.LocalSession?.AttachedEntity ?? EntityUid.Invalid); + _entityNetworkManager.SendSystemNetworkMessage(new BloodConstructMenuClosedEvent(netEntity, _constructUid, _mindUid, constructName)); + Close(); + } +} diff --git a/Content.Client/_Wega/BloodCult/Ui/BloodConstructUIController.cs b/Content.Client/_Wega/BloodCult/Ui/BloodConstructUIController.cs new file mode 100644 index 0000000000..94dad53fe3 --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/BloodConstructUIController.cs @@ -0,0 +1,52 @@ +using Content.Shared.Blood.Cult; +using Robust.Client.Player; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controllers; +using Timer = Robust.Shared.Timing.Timer; + +namespace Content.Client.Select.Construct.UI +{ + public sealed class BloodConstructMenuUIController : UIController + { + [Dependency] private readonly IUserInterfaceManager _uiManager = default!; + [Dependency] private readonly IEntityManager _entityManager = default!; + + private BloodConstructMenu? _menu; + + public override void Initialize() + { + base.Initialize(); + SubscribeNetworkEvent(OnConstructMenuReceived); + } + + private void OnConstructMenuReceived(OpenConstructMenuEvent args, EntitySessionEventArgs eventArgs) + { + var session = IoCManager.Resolve().LocalSession; + var userEntity = _entityManager.GetEntity(args.Uid); + + if (session?.AttachedEntity.HasValue == true && session.AttachedEntity.Value == userEntity) + { + if (_menu is null) + { + _menu = _uiManager.CreateWindow(); + + _menu.SetData(args.ConstructUid, args.Mind); + + _menu.OpenCentered(); + } + else + { + _menu.OpenCentered(); + } + + Timer.Spawn(30000, () => + { + if (_menu != null) + { + _menu.Close(); + } + }); + } + } + } +} diff --git a/Content.Client/_Wega/BloodCult/Ui/BloodMagicMenu.xaml b/Content.Client/_Wega/BloodCult/Ui/BloodMagicMenu.xaml new file mode 100644 index 0000000000..05f96f511d --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/BloodMagicMenu.xaml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content.Client/_Wega/BloodCult/Ui/BloodMagicMenu.xaml.cs b/Content.Client/_Wega/BloodCult/Ui/BloodMagicMenu.xaml.cs new file mode 100644 index 0000000000..c18c4038fc --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/BloodMagicMenu.xaml.cs @@ -0,0 +1,48 @@ +using Content.Client.UserInterface.Controls; +using Content.Shared.Blood.Cult; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Player; + +namespace Content.Client.Blood.Magic.UI; + +[GenerateTypedNameReferences] +public sealed partial class BloodMagicMenu : RadialMenu +{ + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IEntityNetworkManager _entityNetworkManager = default!; + [Dependency] private readonly ISharedPlayerManager _playerManager = default!; + + public event Action? OnSelectSpell; + + public BloodMagicMenu() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + + InitializeButtons(); + } + + private void InitializeButtons() + { + StunButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultStun"); + TeleportButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultTeleport"); + ElectromagneticPulseButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultElectromagneticPulse"); + ShadowShacklesButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultShadowShackles"); + TwistedConstructionButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultTwistedConstruction"); + SummonEquipmentButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultSummonEquipment"); + SummonDaggerButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultSummonDagger"); + HallucinationsButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultHallucinations"); + ConcealPresenceButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultConcealPresence"); + BloodRitesButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultBloodRites"); + } + + private void HandleSpellSelection(string spellName) + { + OnSelectSpell?.Invoke(spellName); + var netEntity = _entityManager.GetNetEntity(_playerManager.LocalSession?.AttachedEntity ?? EntityUid.Invalid); + _entityNetworkManager.SendSystemNetworkMessage(new BloodMagicMenuClosedEvent(netEntity, spellName)); + Close(); + } +} + diff --git a/Content.Client/_Wega/BloodCult/Ui/BloodMagicUIController.cs b/Content.Client/_Wega/BloodCult/Ui/BloodMagicUIController.cs new file mode 100644 index 0000000000..49721973ff --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/BloodMagicUIController.cs @@ -0,0 +1,45 @@ +using Content.Shared.Blood.Cult; +using Robust.Client.Player; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controllers; + +namespace Content.Client.Blood.Magic.UI +{ + public sealed class BloodMagicMenuUIController : UIController + { + [Dependency] private readonly IUserInterfaceManager _uiManager = default!; + [Dependency] private readonly IEntityManager _entityManager = default!; + + private BloodMagicMenu? _menu; + + public override void Initialize() + { + base.Initialize(); + SubscribeNetworkEvent(OnBloodMagicMenuReceived); + } + + private void OnBloodMagicMenuReceived(BloodMagicPressedEvent args, EntitySessionEventArgs eventArgs) + { + var session = IoCManager.Resolve().LocalSession; + var userEntity = _entityManager.GetEntity(args.Uid); + if (session?.AttachedEntity.HasValue == true && session.AttachedEntity.Value == userEntity) + { + if (_menu is null) + { + _menu = _uiManager.CreateWindow(); + _menu.OnClose += OnMenuClosed; + _menu.OpenCentered(); + } + else + { + _menu.OpenCentered(); + } + } + } + + private void OnMenuClosed() + { + _menu = null; + } + } +} diff --git a/Content.Client/_Wega/BloodCult/Ui/BloodRitesMenu.xaml b/Content.Client/_Wega/BloodCult/Ui/BloodRitesMenu.xaml new file mode 100644 index 0000000000..f943415e73 --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/BloodRitesMenu.xaml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content.Client/_Wega/BloodCult/Ui/BloodRitesMenu.xaml.cs b/Content.Client/_Wega/BloodCult/Ui/BloodRitesMenu.xaml.cs new file mode 100644 index 0000000000..1d6f22ead8 --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/BloodRitesMenu.xaml.cs @@ -0,0 +1,42 @@ +using Content.Client.UserInterface.Controls; +using Content.Shared.Blood.Cult; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Player; + +namespace Content.Client.Blood.Rites.UI; + +[GenerateTypedNameReferences] +public sealed partial class BloodRitesMenu : RadialMenu +{ + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IEntityNetworkManager _entityNetworkManager = default!; + [Dependency] private readonly ISharedPlayerManager _playerManager = default!; + + public event Action? OnSelectRites; + + public BloodRitesMenu() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + + InitializeButtons(); + } + + private void InitializeButtons() + { + BloodOrbButton.OnButtonUp += _ => HandleRitesSelection("ActionBloodCultOrb"); + BloodRechargeButton.OnButtonUp += _ => HandleRitesSelection("ActionBloodCultRecharge"); + BloodSpearButton.OnButtonUp += _ => HandleRitesSelection("ActionBloodCultSpear"); + BloodBoltBarrageButton.OnButtonUp += _ => HandleRitesSelection("ActionBloodCultBoltBarrage"); + } + + private void HandleRitesSelection(string ritesName) + { + OnSelectRites?.Invoke(ritesName); + var netEntity = _entityManager.GetNetEntity(_playerManager.LocalSession?.AttachedEntity ?? EntityUid.Invalid); + _entityNetworkManager.SendSystemNetworkMessage(new BloodRitesMenuClosedEvent(netEntity, ritesName)); + Close(); + } +} + diff --git a/Content.Client/_Wega/BloodCult/Ui/BloodRitesUIController.cs b/Content.Client/_Wega/BloodCult/Ui/BloodRitesUIController.cs new file mode 100644 index 0000000000..104175b056 --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/BloodRitesUIController.cs @@ -0,0 +1,45 @@ +using Content.Shared.Blood.Cult; +using Robust.Client.Player; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controllers; + +namespace Content.Client.Blood.Rites.UI +{ + public sealed class BloodRitesMenuUIController : UIController + { + [Dependency] private readonly IUserInterfaceManager _uiManager = default!; + [Dependency] private readonly IEntityManager _entityManager = default!; + + private BloodRitesMenu? _menu; + + public override void Initialize() + { + base.Initialize(); + SubscribeNetworkEvent(OnBloodMagicMenuReceived); + } + + private void OnBloodMagicMenuReceived(BloodRitesPressedEvent args, EntitySessionEventArgs eventArgs) + { + var session = IoCManager.Resolve().LocalSession; + var userEntity = _entityManager.GetEntity(args.Uid); + if (session?.AttachedEntity.HasValue == true && session.AttachedEntity.Value == userEntity) + { + if (_menu is null) + { + _menu = _uiManager.CreateWindow(); + _menu.OnClose += OnMenuClosed; + _menu.OpenCentered(); + } + else + { + _menu.OpenCentered(); + } + } + } + + private void OnMenuClosed() + { + _menu = null; + } + } +} diff --git a/Content.Client/_Wega/BloodCult/Ui/BloodStructureMenu.xaml b/Content.Client/_Wega/BloodCult/Ui/BloodStructureMenu.xaml new file mode 100644 index 0000000000..ab3b82e370 --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/BloodStructureMenu.xaml @@ -0,0 +1,14 @@ + + + + + + diff --git a/Content.Client/_Wega/BloodCult/Ui/BloodStructureMenu.xaml.cs b/Content.Client/_Wega/BloodCult/Ui/BloodStructureMenu.xaml.cs new file mode 100644 index 0000000000..6ed14c0591 --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/BloodStructureMenu.xaml.cs @@ -0,0 +1,82 @@ +using System.Numerics; +using Content.Client.UserInterface.Controls; +using Content.Shared.Blood.Cult; +using Content.Shared.Blood.Cult.Components; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Player; +using Robust.Shared.Prototypes; + +namespace Content.Client.Structure.UI; + +[GenerateTypedNameReferences] +public sealed partial class BloodStructureMenu : RadialMenu +{ + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IEntityNetworkManager _entityNetworkManager = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly ISharedPlayerManager _playerManager = default!; + + public event Action? OnSelectItem; + private NetEntity _structure; + + public BloodStructureMenu() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + } + + public void SetData(NetEntity structure) + { + _structure = structure; + InitializeButtons(); + } + + private void InitializeButtons() + { + var structure = _entityManager.GetEntity(_structure); + if (!_entityManager.TryGetComponent(structure, out var structureComp) + || structureComp.StructureGear.Count == 0) + return; + + foreach (var prototypeId in structureComp.StructureGear) + { + if (!_prototypeManager.TryIndex(prototypeId, out var prototype)) + continue; + + var button = new RadialMenuButton + { + ToolTip = prototype.Name, + SetSize = new Vector2(64, 64), + }; + + button.StyleClasses.Add("RadialMenuButton"); + + var entityView = new EntityPrototypeView + { + Scale = new Vector2(2, 2), + SetSize = new Vector2(64, 64), + Margin = new Thickness(4) + }; + entityView.SetPrototype(prototype.ID); + + button.AddChild(entityView); + + button.OnPressed += _ => + { + HandleItemSelection(prototype.ID); + }; + + Main.AddChild(button); + } + } + + private void HandleItemSelection(string name) + { + OnSelectItem?.Invoke(name); + var netEntity = _entityManager.GetNetEntity(_playerManager.LocalSession?.AttachedEntity ?? EntityUid.Invalid); + _entityNetworkManager.SendSystemNetworkMessage(new BloodStructureMenuClosedEvent(netEntity, name, _structure)); + Close(); + } +} diff --git a/Content.Client/_Wega/BloodCult/Ui/BloodStructureUIController.cs b/Content.Client/_Wega/BloodCult/Ui/BloodStructureUIController.cs new file mode 100644 index 0000000000..7807859b33 --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/BloodStructureUIController.cs @@ -0,0 +1,57 @@ +using Content.Shared.Blood.Cult; +using Robust.Client.Player; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controllers; +using Timer = Robust.Shared.Timing.Timer; + +namespace Content.Client.Structure.UI +{ + public sealed class BloodStructureMenuUIController : UIController + { + [Dependency] private readonly IUserInterfaceManager _uiManager = default!; + [Dependency] private readonly IEntityManager _entityManager = default!; + + private BloodStructureMenu? _menu; + + public override void Initialize() + { + base.Initialize(); + SubscribeNetworkEvent(OnStructureMenuReceived); + } + + private void OnStructureMenuReceived(OpenStructureMenuEvent args, EntitySessionEventArgs eventArgs) + { + var session = IoCManager.Resolve().LocalSession; + var userEntity = _entityManager.GetEntity(args.Uid); + if (session?.AttachedEntity.HasValue == true && session.AttachedEntity.Value == userEntity) + { + if (_menu is null) + { + _menu = _uiManager.CreateWindow(); + _menu.OnClose += OnMenuClosed; + + _menu.SetData(args.Structure); + + _menu.OpenCentered(); + } + else + { + _menu.OpenCentered(); + } + + Timer.Spawn(30000, () => + { + if (_menu != null) + { + _menu.Close(); + } + }); + } + } + + private void OnMenuClosed() + { + _menu = null; + } + } +} diff --git a/Content.Client/_Wega/BloodCult/Ui/EmpoweringRuneMenu.xaml b/Content.Client/_Wega/BloodCult/Ui/EmpoweringRuneMenu.xaml new file mode 100644 index 0000000000..4c49f3253a --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/EmpoweringRuneMenu.xaml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content.Client/_Wega/BloodCult/Ui/RunesMenu.xaml b/Content.Client/_Wega/BloodCult/Ui/RunesMenu.xaml new file mode 100644 index 0000000000..dd85b9490a --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/RunesMenu.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + diff --git a/Content.Client/_Wega/BloodCult/Ui/RunesMenu.xaml.cs b/Content.Client/_Wega/BloodCult/Ui/RunesMenu.xaml.cs new file mode 100644 index 0000000000..33213acbcd --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/RunesMenu.xaml.cs @@ -0,0 +1,162 @@ +using System.Numerics; +using Content.Client.UserInterface.Controls; +using Content.Shared.Blood.Cult; +using Content.Shared.Blood.Cult.Components; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.CustomControls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Player; + +namespace Content.Client.Runes.Panel.Ui; + +public sealed partial class RunesPanelMenu : DefaultWindow +{ + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IEntityNetworkManager _entityNetworkManager = default!; + [Dependency] private readonly ISharedPlayerManager _playerManager = default!; + + public event Action? OnRuneSelected; + public BoxContainer RunesContainer => this.FindControl("RunesContainer"); + + public RunesPanelMenu() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + + InitializeRunes(); + } + + private void InitializeRunes() + { + AddRuneButton(Loc.GetString("offering-rune"), "BloodRuneOffering"); + AddRuneButton(Loc.GetString("teleport-rune"), "BloodRuneTeleport"); + AddRuneButton(Loc.GetString("empowering-rune"), "BloodRuneEmpowering"); + AddRuneButton(Loc.GetString("revive-rune"), "BloodRuneRevive"); + AddRuneButton(Loc.GetString("barrier-rune"), "BloodRuneBarrier"); + AddRuneButton(Loc.GetString("summoning-rune"), "BloodRuneSummoning"); + AddRuneButton(Loc.GetString("bloodboil-rune"), "BloodRuneBloodBoil"); + AddRuneButton(Loc.GetString("spiritrealm-rune"), "BloodRuneSpiritealm"); + AddRuneButton(Loc.GetString("ritual-dimensional-rending-rune"), "BloodRuneRitualDimensionalRending"); + } + + private void AddRuneButton(string runeName, string protoId) + { + var button = new Button + { + Text = runeName, + MinSize = new Vector2(300, 32), + MaxSize = new Vector2(300, 32), + HorizontalAlignment = HAlignment.Center, + VerticalAlignment = VAlignment.Center, + }; + + button.OnPressed += _ => HandleRuneSelection(protoId); + + RunesContainer.AddChild(button); + } + + private void HandleRuneSelection(string protoId) + { + OnRuneSelected?.Invoke(protoId); + var netEntity = _entityManager.GetNetEntity(_playerManager.LocalSession?.AttachedEntity ?? EntityUid.Invalid); + _entityNetworkManager.SendSystemNetworkMessage(new RuneSelectEvent(netEntity, protoId)); + Close(); + } + + public new void Close() + { + base.Close(); + } +} + +[GenerateTypedNameReferences] +public sealed partial class EmpoweringRuneMenu : RadialMenu +{ + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IEntityNetworkManager _entityNetworkManager = default!; + [Dependency] private readonly ISharedPlayerManager _playerManager = default!; + + public event Action? OnSelectSpell; + + public EmpoweringRuneMenu() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + + InitializeButtons(); + } + + private void InitializeButtons() + { + StunButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultStun"); + TeleportButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultTeleport"); + ElectromagneticPulseButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultElectromagneticPulse"); + ShadowShacklesButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultShadowShackles"); + TwistedConstructionButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultTwistedConstruction"); + SummonEquipmentButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultSummonEquipment"); + SummonDaggerButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultSummonDagger"); + HallucinationsButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultHallucinations"); + ConcealPresenceButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultConcealPresence"); + BloodRitesButton.OnButtonUp += _ => HandleSpellSelection("ActionBloodCultBloodRites"); + } + + private void HandleSpellSelection(string spellName) + { + OnSelectSpell?.Invoke(spellName); + var netEntity = _entityManager.GetNetEntity(_playerManager.LocalSession?.AttachedEntity ?? EntityUid.Invalid); + _entityNetworkManager.SendSystemNetworkMessage(new EmpoweringRuneMenuClosedEvent(netEntity, spellName)); + Close(); + } +} + +public sealed partial class SummoningRunePanelMenu : DefaultWindow +{ + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IEntityNetworkManager _entityNetworkManager = default!; + [Dependency] private readonly ISharedPlayerManager _playerManager = default!; + + public BoxContainer CultistsContainer => this.FindControl("CultistsContainer"); + + public SummoningRunePanelMenu() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + + InitializeButtons(); + } + + private void InitializeButtons() + { + var cultistQuery = _entityManager.EntityQueryEnumerator(); + while (cultistQuery.MoveNext(out var uid, out _, out var metaData)) + { + var entityName = metaData.EntityName; + AddCultistButton(entityName, uid); + } + } + + private void AddCultistButton(string cultistName, EntityUid cultistUid) + { + var button = new Button + { + Text = cultistName, + HorizontalAlignment = HAlignment.Center, + VerticalAlignment = VAlignment.Center, + MinSize = new Vector2(300, 32), + MaxSize = new Vector2(300, 32) + }; + + button.OnPressed += _ => HandleCultistSelection(cultistUid); + + CultistsContainer.AddChild(button); + } + + private void HandleCultistSelection(EntityUid cultistUid) + { + var netTargerEntity = _entityManager.GetNetEntity(cultistUid); + var netEntity = _entityManager.GetNetEntity(_playerManager.LocalSession?.AttachedEntity ?? EntityUid.Invalid); + _entityNetworkManager.SendSystemNetworkMessage(new SummoningSelectedEvent(netEntity, netTargerEntity)); + Close(); + } +} diff --git a/Content.Client/_Wega/BloodCult/Ui/RunesMenuUIController.cs b/Content.Client/_Wega/BloodCult/Ui/RunesMenuUIController.cs new file mode 100644 index 0000000000..3d57eea8c1 --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/RunesMenuUIController.cs @@ -0,0 +1,144 @@ +using Content.Shared.Blood.Cult; +using Robust.Client.Player; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controllers; +using Timer = Robust.Shared.Timing.Timer; + +namespace Content.Client.Runes.Panel.Ui +{ + public sealed class RunesMenuUIController : UIController + { + [Dependency] private readonly IUserInterfaceManager _uiManager = default!; + [Dependency] private readonly IEntityManager _entityManager = default!; + + private RunesPanelMenu? _panel; + + public override void Initialize() + { + base.Initialize(); + + SubscribeNetworkEvent(OnRunesMenuReceived); + } + + private void OnRunesMenuReceived(RunesMenuOpenedEvent args, EntitySessionEventArgs eventArgs) + { + var session = IoCManager.Resolve().LocalSession; + var userEntity = _entityManager.GetEntity(args.Uid); + if (session?.AttachedEntity.HasValue == true && session.AttachedEntity.Value == userEntity) + { + if (_panel is null) + { + _panel = _uiManager.CreateWindow(); + _panel.OnClose += OnMenuClosed; + _panel.OpenCentered(); + } + else + { + _panel.OpenCentered(); + } + } + } + + private void OnMenuClosed() + { + _panel = null; + } + } + + public sealed class EmpoweringRuneMenuUIController : UIController + { + [Dependency] private readonly IUserInterfaceManager _uiManager = default!; + [Dependency] private readonly IEntityManager _entityManager = default!; + + private EmpoweringRuneMenu? _menu; + private bool _menuDisposed = false; + + public override void Initialize() + { + base.Initialize(); + + SubscribeNetworkEvent(OnRuneMenuReceived); + } + + private void OnRuneMenuReceived(EmpoweringRuneMenuOpenedEvent args, EntitySessionEventArgs eventArgs) + { + var session = IoCManager.Resolve().LocalSession; + var userEntity = _entityManager.GetEntity(args.Uid); + if (session?.AttachedEntity.HasValue == true && session.AttachedEntity.Value == userEntity) + { + if (_menu is null) + { + _menu = _uiManager.CreateWindow(); + _menu.OnClose += OnMenuClosed; + _menu.OpenCentered(); + } + else + { + _menu.OpenCentered(); + } + } + + Timer.Spawn(30000, () => + { + if (_menu != null && !_menuDisposed) + { + _menu.Close(); + } + }); + } + + private void OnMenuClosed() + { + _menuDisposed = true; + _menu = null; + } + + } + + public sealed class SummoningRuneMenuUIController : UIController + { + [Dependency] private readonly IUserInterfaceManager _uiManager = default!; + [Dependency] private readonly IEntityManager _entityManager = default!; + + private SummoningRunePanelMenu? _panel; + + public override void Initialize() + { + base.Initialize(); + + SubscribeNetworkEvent(OnRuneMenuReceived); + } + + private void OnRuneMenuReceived(SummoningRuneMenuOpenedEvent args, EntitySessionEventArgs eventArgs) + { + var session = IoCManager.Resolve().LocalSession; + var userEntity = _entityManager.GetEntity(args.Uid); + if (session?.AttachedEntity.HasValue == true && session.AttachedEntity.Value == userEntity) + { + if (_panel is null) + { + _panel = _uiManager.CreateWindow(); + _panel.OnClose += OnMenuClosed; + _panel.OpenCentered(); + } + else + { + _panel.OpenCentered(); + } + + Timer.Spawn(30000, () => + { + if (_panel != null) + { + _panel.Close(); + } + }); + } + } + + private void OnMenuClosed() + { + _panel = null; + } + } +} diff --git a/Content.Client/_Wega/BloodCult/Ui/SummoningRuneMenu.xaml b/Content.Client/_Wega/BloodCult/Ui/SummoningRuneMenu.xaml new file mode 100644 index 0000000000..da5f6502ef --- /dev/null +++ b/Content.Client/_Wega/BloodCult/Ui/SummoningRuneMenu.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + +