diff --git a/Content.Client/Entry/EntryPoint.cs b/Content.Client/Entry/EntryPoint.cs index 2266b30c515..3e53d492cc7 100644 --- a/Content.Client/Entry/EntryPoint.cs +++ b/Content.Client/Entry/EntryPoint.cs @@ -128,6 +128,9 @@ public override void Init() _prototypeManager.RegisterIgnore("ghostRoleRaffleDecider"); _prototypeManager.RegisterIgnore("codewordGenerator"); _prototypeManager.RegisterIgnore("codewordFaction"); + _prototypeManager.RegisterIgnore("narsiAbilityPrototype"); //RPSX + _prototypeManager.RegisterIgnore("narsiRitualCategory"); //RPSX + _prototypeManager.RegisterIgnore("narsiRitual"); //RPSX _componentFactory.GenerateNetIds(); _adminManager.Initialize(); diff --git a/Content.Client/_RPSX/DarkForces/Desecrated/PontificVisualizerSystem.cs b/Content.Client/_RPSX/DarkForces/Desecrated/PontificVisualizerSystem.cs new file mode 100644 index 00000000000..3780273c009 --- /dev/null +++ b/Content.Client/_RPSX/DarkForces/Desecrated/PontificVisualizerSystem.cs @@ -0,0 +1,21 @@ +using Content.Shared.RPSX.DarkForces.Desecrated.Pontific; +using Robust.Client.GameObjects; +using Robust.Shared.GameObjects; + +namespace Content.Client.RPSX.DarkForces.Desecrated; +public sealed class PontificDamageStateVisualizerSystem : VisualizerSystem +{ + protected override void OnAppearanceChange( + EntityUid uid, PontificVisualsComponent component, ref AppearanceChangeEvent args + ) + { + var sprite = args.Sprite; + if (sprite == null || !AppearanceSystem.TryGetData(uid, PontificStateVisuals.State, out var pontificState, args.Component)) + return; + + sprite.LayerSetVisible(PontificVisualLayers.Base, pontificState == PontificState.Base); + sprite.LayerSetVisible(PontificVisualLayers.Dead, pontificState == PontificState.Dead); + sprite.LayerSetVisible(PontificVisualLayers.Flame, pontificState == PontificState.Flame); + // sprite.LayerSetVisible(PontificVisualLayers.Prayer, pontificState == PontificState.Prayer); + } +} diff --git a/Content.Client/_RPSX/DarkForces/Desecrated/PontificVisualsComponent.cs b/Content.Client/_RPSX/DarkForces/Desecrated/PontificVisualsComponent.cs new file mode 100644 index 00000000000..c07301a043f --- /dev/null +++ b/Content.Client/_RPSX/DarkForces/Desecrated/PontificVisualsComponent.cs @@ -0,0 +1,17 @@ +using Robust.Shared.GameObjects; + +namespace Content.Client.RPSX.DarkForces.Desecrated; + +[RegisterComponent] +public sealed partial class PontificVisualsComponent : Component +{ + +} + +public enum PontificVisualLayers : byte +{ + Base, + Dead, + Flame, + Prayer +} diff --git a/Content.Client/_RPSX/DarkForces/Narsi/Buildings/Altar/Abilities/NarsiAbilitiesBoundInterface.cs b/Content.Client/_RPSX/DarkForces/Narsi/Buildings/Altar/Abilities/NarsiAbilitiesBoundInterface.cs new file mode 100644 index 00000000000..132c157e474 --- /dev/null +++ b/Content.Client/_RPSX/DarkForces/Narsi/Buildings/Altar/Abilities/NarsiAbilitiesBoundInterface.cs @@ -0,0 +1,53 @@ +using System; +using Content.Shared.RPSX.DarkForces.Narsi.Buildings.Altar.Abilities; +using Robust.Shared.GameObjects; + +namespace Content.Client.RPSX.DarkForces.Narsi.Buildings.Altar.Abilities; + +public sealed class NarsiAbilitiesBoundInterface : BoundUserInterface +{ + private NarsiAbilitiesWindow? _window; + + public NarsiAbilitiesBoundInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) + { + } + + protected override void Open() + { + base.Open(); + + _window?.Dispose(); + _window = new NarsiAbilitiesWindow(this); + _window.OnClose += Close; + _window.OpenCentered(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (disposing) + { + _window?.Dispose(); + } + } + + protected override void UpdateState(BoundUserInterfaceState state) + { + base.UpdateState(state); + + if (state is not NarsiAbilitiesState abilitiesState || _window == null) + return; + + _window.UpdateState(abilitiesState); + } + + public void OnAbilityOpen(string id) + { + SendMessage(new NarsiAbilityOpenMessage(id)); + } + + public void OnAbilityLearn(string id) + { + SendMessage(new NarsiAbilityLearnMessage(id)); + } +} diff --git a/Content.Client/_RPSX/DarkForces/Narsi/Buildings/Altar/Abilities/NarsiAbilitiesWindow.xaml b/Content.Client/_RPSX/DarkForces/Narsi/Buildings/Altar/Abilities/NarsiAbilitiesWindow.xaml new file mode 100644 index 00000000000..55118ab34d9 --- /dev/null +++ b/Content.Client/_RPSX/DarkForces/Narsi/Buildings/Altar/Abilities/NarsiAbilitiesWindow.xaml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content.Client/_RPSX/DarkForces/Narsi/Buildings/Altar/Abilities/NarsiAbilitiesWindow.xaml.cs b/Content.Client/_RPSX/DarkForces/Narsi/Buildings/Altar/Abilities/NarsiAbilitiesWindow.xaml.cs new file mode 100644 index 00000000000..6aad5000d73 --- /dev/null +++ b/Content.Client/_RPSX/DarkForces/Narsi/Buildings/Altar/Abilities/NarsiAbilitiesWindow.xaml.cs @@ -0,0 +1,74 @@ +using System.Collections.Generic; +using Content.Client.UserInterface.Controls; +using Content.Shared.RPSX.DarkForces.Narsi.Buildings.Altar.Abilities; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Utility; + +namespace Content.Client.RPSX.DarkForces.Narsi.Buildings.Altar.Abilities; + +[GenerateTypedNameReferences] +public sealed partial class NarsiAbilitiesWindow : FancyWindow +{ + private readonly NarsiAbilitiesBoundInterface _bui; + + public NarsiAbilitiesWindow(NarsiAbilitiesBoundInterface bui) + { + RobustXamlLoader.Load(this); + _bui = bui; + + Description.SetMessage(FormattedMessage.EscapeText("Способности культистов - ключ к призыву Нар'Си.\nСпособности могут быть полезны в различных ситуациях, таких как: защита, нападение, проникновение.\nКаждая способность имеет три уровня, описание которых вы можете увидеть здесь.\nЧтобы прокачивать способности, нужно получить Очки Крови, которые выдаются за задания культа")); + SetupSplitContainer(); + } + + private void SetupSplitContainer() + { + SplitContainer.ResizeMode = SplitContainer.SplitResizeMode.RespectChildrenMinSize; + SplitContainer.SplitWidth = 2; + SplitContainer.SplitEdgeSeparation = 1f; + SplitContainer.StretchDirection = SplitContainer.SplitStretchDirection.TopLeft; + } + + public void UpdateState(NarsiAbilitiesState state) + { + ClosedAbilities.RemoveAllChildren(); + OpenedAbilities.RemoveAllChildren(); + + AddToControl(OpenedAbilities, state.OpenedAbilities, state.BloodScore, false, state.IsLeader); + AddToControl(ClosedAbilities, state.ClosedAbilities, state.BloodScore, true, state.IsLeader); + } + + private void AddToControl(BoxContainer container, List items, int bloodScore, bool isClosed, bool isLeader) + { + foreach (var item in items) + { + var control = new NarsiAbilityControl( + id: item.Id, + name: item.Name, + description: item.Description, + levelDescription: item.LevelDescription, + level: item.Level, + requiredBloodScore: item.RequiredBloodScore, + icon: item.Icon, + buttonState: GetButtonState(isClosed, isLeader, bloodScore, item.RequiredBloodScore), + bui: _bui + ); + container.AddChild(control); + } + } + + private NarsiAbilityControl.ButtonState GetButtonState(bool isClosed, bool isLeader, int bloodScore, int requiredBloodScore) + { + if (!isClosed) + return NarsiAbilityControl.ButtonState.Learn; + + if (bloodScore < requiredBloodScore) + return NarsiAbilityControl.ButtonState.ClosedNotEnoughPoints; + + if (isLeader) + return NarsiAbilityControl.ButtonState.ClosedLeader; + + return NarsiAbilityControl.ButtonState.ClosedNotLeader; + } +} diff --git a/Content.Client/_RPSX/DarkForces/Narsi/Buildings/Altar/Abilities/NarsiAbilityControl.xaml b/Content.Client/_RPSX/DarkForces/Narsi/Buildings/Altar/Abilities/NarsiAbilityControl.xaml new file mode 100644 index 00000000000..ff67f3dfe2e --- /dev/null +++ b/Content.Client/_RPSX/DarkForces/Narsi/Buildings/Altar/Abilities/NarsiAbilityControl.xaml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + +