main cult

This commit is contained in:
EnefFlow
2024-01-27 15:19:52 +03:00
committed by Aviu00
parent 6310813ce6
commit 4fab8188f0
429 changed files with 12281 additions and 9 deletions

View File

@@ -0,0 +1,86 @@
using System.Numerics;
using Content.Shared.Humanoid;
using Content.Shared.White.Cult;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Client._White.Cult;
public sealed class CultHudOverlay : Overlay
{
private readonly IEntityManager _entityManager;
private readonly SharedTransformSystem _transformSystem;
public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowFOV;
protected override void Draw(in OverlayDrawArgs args)
{
var handle = args.WorldHandle;
var rotation = args.Viewport.Eye?.Rotation ?? Angle.Zero;
var spriteQuery = _entityManager.GetEntityQuery<SpriteComponent>();
var xformQuery = _entityManager.GetEntityQuery<TransformComponent>();
const float scale = 1f;
var scaleMatrix = Matrix3.CreateScale(new Vector2(scale, scale));
var rotationMatrix = Matrix3.CreateRotation(-rotation);
foreach (var cultist in _entityManager.EntityQuery<CultistComponent>(true))
{
if (!xformQuery.TryGetComponent(cultist.Owner, out var xform) ||
xform.MapID != args.MapId)
{
continue;
}
var worldPosition = _transformSystem.GetWorldPosition(xform);
var worldMatrix = Matrix3.CreateTranslation(worldPosition);
Matrix3.Multiply(scaleMatrix, worldMatrix, out var scaledWorld);
Matrix3.Multiply(rotationMatrix, scaledWorld, out var matty);
handle.SetTransform(matty);
var cultistIcon = new SpriteSpecifier.Rsi(new ResPath("/Textures/White/Cult/cult_hud.rsi"), "cult");
var iconTexture = _entityManager.EntitySysManager.GetEntitySystem<SpriteSystem>().Frame0(cultistIcon);
float yOffset;
float xOffset;
if (spriteQuery.TryGetComponent(cultist.Owner, out var sprite))
{
yOffset = sprite.Bounds.Height - 10f; //sprite.Bounds.Height + 7f;
xOffset = sprite.Bounds.Width - 40f; //sprite.Bounds.Width + 7f;
}
else
{
yOffset = 1f;
xOffset = 1f;
}
// Position above the entity (we've already applied the matrix transform to the entity itself)
// Offset by the texture size for every do_after we have.
var position = new Vector2(xOffset / EyeManager.PixelsPerMeter, yOffset / EyeManager.PixelsPerMeter);
// Draw the underlying bar texture
if (sprite != null && !sprite.ContainerOccluded)
{
handle.DrawTexture(iconTexture, position);
}
}
handle.UseShader(null);
handle.SetTransform(Matrix3.Identity);
}
public CultHudOverlay(IEntityManager entityManager)
{
_entityManager = entityManager;
_transformSystem = _entityManager.EntitySysManager.GetEntitySystem<SharedTransformSystem>();
}
}

View File

@@ -0,0 +1,65 @@
using System.Numerics;
using Robust.Client.GameObjects;
using Robust.Shared.Random;
using Robust.Shared.Utility;
namespace Content.Client._White.Cult;
public sealed class CultPentagramSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _robustRandom = default!;
private const string Rsi = "White/Cult/pentagram.rsi";
private static readonly string[] States =
{
"halo1",
"halo2",
"halo3",
"halo4",
"halo5",
"halo6"
};
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<PentagramComponent, ComponentStartup>(PentagramAdded);
SubscribeLocalEvent<PentagramComponent, ComponentShutdown>(PentagramRemoved);
}
private void PentagramAdded(EntityUid uid, PentagramComponent component, ComponentStartup args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite))
return;
if (sprite.LayerMapTryGet(PentagramKey.Key, out var _))
return;
var adj = sprite.Bounds.Height / 2 + ((1.0f/32) * 10.0f);
var randomIndex = _robustRandom.Next(0, States.Length);
var randomState = States[randomIndex];
var layer = sprite.AddLayer(new SpriteSpecifier.Rsi(new ResPath(Rsi), randomState));
sprite.LayerMapSet(PentagramKey.Key, layer);
sprite.LayerSetOffset(layer, new Vector2(0.0f, adj));
}
private void PentagramRemoved(EntityUid uid, PentagramComponent component, ComponentShutdown args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite))
return;
if (!sprite.LayerMapTryGet(PentagramKey.Key, out var layer))
return;
sprite.RemoveLayer(layer);
}
private enum PentagramKey
{
Key
}
}

View File

@@ -0,0 +1,40 @@
using Content.Shared.White.Cult.Items;
using Robust.Client.GameObjects;
namespace Content.Client._White.Cult.Items.VeilShifter;
public sealed class VeilVisualizerSystem : VisualizerSystem<VeilVisualsComponent>
{
private const string StateOn = "icon-on";
private const string StateOff = "icon";
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<VoidTeleportComponent, ComponentInit>(OnInit);
}
private void OnInit(EntityUid uid, VoidTeleportComponent component, ComponentInit args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite)
|| !AppearanceSystem.TryGetData<bool>(uid, VeilVisuals.Activated, out var activated))
return;
sprite.LayerSetState(VeilVisualsLayers.Activated, activated ? StateOn : StateOff);
}
protected override void OnAppearanceChange(EntityUid uid, VeilVisualsComponent component, ref AppearanceChangeEvent args)
{
if (args.Sprite == null
|| !AppearanceSystem.TryGetData<bool>(uid, VeilVisuals.Activated, out var activated))
return;
args.Sprite.LayerSetState(VeilVisualsLayers.Activated, activated ? component.StateOn : component.StateOff);
}
}
public enum VeilVisualsLayers : byte
{
Activated
}

View File

@@ -0,0 +1,13 @@
namespace Content.Client._White.Cult.Items.VeilShifter;
[RegisterComponent]
public sealed partial class VeilVisualsComponent : Component
{
[DataField("stateOn")]
[ViewVariables(VVAccess.ReadWrite)]
public string? StateOn = "icon-on";
[DataField("stateOff")]
[ViewVariables(VVAccess.ReadWrite)]
public string? StateOff = "icon";
}

View File

@@ -0,0 +1,23 @@
using Content.Shared.White.Cult.Items;
using Robust.Client.GameObjects;
namespace Content.Client._White.Cult.Items.VoidTorch;
public sealed class VoidTorchVisualizerSystem : VisualizerSystem<VoidTorchVisualsComponent>
{
protected override void OnAppearanceChange(EntityUid uid, VoidTorchVisualsComponent component, ref AppearanceChangeEvent args)
{
base.OnAppearanceChange(uid, component, ref args);
if (args.Sprite == null
|| !AppearanceSystem.TryGetData<bool>(uid, VoidTorchVisuals.Activated, out var activated))
return;
args.Sprite.LayerSetState(VoidTorchVisualsLayers.Activated, activated ? component.StateOn : component.StateOff);
}
}
public enum VoidTorchVisualsLayers : byte
{
Activated
}

View File

@@ -0,0 +1,13 @@
namespace Content.Client._White.Cult.Items.VoidTorch;
[RegisterComponent]
public sealed partial class VoidTorchVisualsComponent : Component
{
[DataField("stateOn")]
[ViewVariables(VVAccess.ReadWrite)]
public string? StateOn = "icon-on";
[DataField("stateOff")]
[ViewVariables(VVAccess.ReadWrite)]
public string? StateOff = "icon";
}

View File

@@ -0,0 +1,6 @@
namespace Content.Client._White.Cult;
public enum NarsieLayer
{
Default
}

View File

@@ -0,0 +1,69 @@
using Content.Shared.White.Cult;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
namespace Content.Client._White.Cult;
public sealed class NarsieVisualizer : VisualizerSystem<NarsieComponent>
{
[Dependency] private readonly AnimationPlayerSystem _animationSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<NarsieComponent, AnimationCompletedEvent>(OnAnimationCompleted);
}
private void OnAnimationCompleted(EntityUid uid, NarsieComponent component, AnimationCompletedEvent args)
{
SetDefaultState(Comp<SpriteComponent>(uid));
}
protected override void OnAppearanceChange(EntityUid uid, NarsieComponent component, ref AppearanceChangeEvent args)
{
base.OnAppearanceChange(uid, component, ref args);
if(args.Sprite == null) return;
if (!args.AppearanceData.TryGetValue(NarsieVisualState.VisualState, out var narsieVisualsObject) || narsieVisualsObject is not NarsieVisuals narsieVisual)
return;
switch (narsieVisual)
{
case NarsieVisuals.Spawning:
PlaySpawnAnimation(uid);
break;
case NarsieVisuals.Spawned:
if(_animationSystem.HasRunningAnimation(uid, "narsie_spawn")) break;
SetDefaultState(args.Sprite);
break;
}
}
private void PlaySpawnAnimation(EntityUid uid)
{
_animationSystem.Play(uid, NarsieSpawnAnimation, "narsie_spawn");
}
private void SetDefaultState(SpriteComponent component)
{
component.LayerSetVisible(NarsieLayer.Default, true);
component.LayerSetState(NarsieLayer.Default, new RSI.StateId("narsie"));
component.LayerSetAutoAnimated(NarsieLayer.Default, true);
}
private static readonly Animation NarsieSpawnAnimation = new()
{
Length = TimeSpan.FromSeconds(3.5),
AnimationTracks =
{
new AnimationTrackSpriteFlick()
{
LayerKey = NarsieLayer.Default,
KeyFrames = {new AnimationTrackSpriteFlick.KeyFrame(new RSI.StateId("narsie_spawn_anim"), 0f)}
}
}
};
}

View File

@@ -0,0 +1,9 @@
using Content.Shared.White.Cult.Pentagram;
using Robust.Shared.GameStates;
namespace Content.Client._White.Cult;
[NetworkedComponent, RegisterComponent]
public sealed partial class PentagramComponent : SharedPentagramComponent
{
}

View File

@@ -0,0 +1,40 @@
using Content.Shared.White.Cult.Pylon;
using Robust.Client.GameObjects;
namespace Content.Client._White.Cult.Pylon;
public sealed class PylonVisualizerSystem : VisualizerSystem<PylonVisualsComponent>
{
private const string StateOn = "pylon";
private const string StateOff = "pylon_off";
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SharedPylonComponent, ComponentInit>(OnInit);
}
private void OnInit(EntityUid uid, SharedPylonComponent component, ComponentInit args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite)
|| !AppearanceSystem.TryGetData<bool>(uid, PylonVisualsLayers.Activated, out var activated))
return;
sprite.LayerSetState(PylonVisualsLayers.Activated, activated ? StateOn : StateOff);
}
protected override void OnAppearanceChange(EntityUid uid, PylonVisualsComponent component, ref AppearanceChangeEvent args)
{
if (args.Sprite == null
|| !AppearanceSystem.TryGetData<bool>(uid, PylonVisuals.Activated, out var activated))
return;
args.Sprite.LayerSetState(PylonVisualsLayers.Activated, activated ? component.StateOn : component.StateOff);
}
}
public enum PylonVisualsLayers : byte
{
Activated
}

View File

@@ -0,0 +1,15 @@
using Content.Client.Storage.Visualizers;
namespace Content.Client._White.Cult.Pylon;
[RegisterComponent]
public sealed partial class PylonVisualsComponent : Component
{
[DataField("stateOn")]
[ViewVariables(VVAccess.ReadWrite)]
public string? StateOn = "pylon";
[DataField("stateOff")]
[ViewVariables(VVAccess.ReadWrite)]
public string? StateOff = "pylon_off";
}

View File

@@ -0,0 +1,48 @@
using Content.Shared.White.Cult;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
namespace Content.Client._White.Cult;
public sealed class ShowCultHudSystem : EntitySystem
{
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IOverlayManager _overlayManager = default!;
private Overlay _overlay = default!;
public override void Initialize()
{
SubscribeLocalEvent<CultistComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<CultistComponent, ComponentRemove>(OnComponentRemoved);
SubscribeLocalEvent<CultistComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<CultistComponent, PlayerDetachedEvent>(OnPlayerDetached);
_overlay = new CultHudOverlay(EntityManager);
}
private void OnComponentInit(EntityUid uid, CultistComponent component, ComponentInit args)
{
if (_player.LocalPlayer?.ControlledEntity != uid) return;
_overlayManager.AddOverlay(_overlay);
}
private void OnComponentRemoved(EntityUid uid, CultistComponent component, ComponentRemove args)
{
if (_player.LocalPlayer?.ControlledEntity != uid) return;
_overlayManager.RemoveOverlay(_overlay);
}
private void OnPlayerAttached(EntityUid uid, CultistComponent component, PlayerAttachedEvent args)
{
_overlayManager.AddOverlay(_overlay);
}
private void OnPlayerDetached(EntityUid uid, CultistComponent component, PlayerDetachedEvent args)
{
_overlayManager.RemoveOverlay(_overlay);
}
}

View File

@@ -0,0 +1,23 @@
using Content.Shared.White.Cult;
using Robust.Client.GameObjects;
namespace Content.Client._White.Cult.Structures;
public sealed class CultCraftStructureVisualizerSystem : VisualizerSystem<CultCraftStructureVisualsComponent>
{
protected override void OnAppearanceChange(EntityUid uid, CultCraftStructureVisualsComponent component, ref AppearanceChangeEvent args)
{
base.OnAppearanceChange(uid, component, ref args);
if (args.Sprite == null
|| !AppearanceSystem.TryGetData<bool>(uid, CultCraftStructureVisuals.Activated, out var activated))
return;
args.Sprite.LayerSetState(CultCraftStructureVisualsLayers.Activated, activated ? component.StateOn : component.StateOff);
}
}
public enum CultCraftStructureVisualsLayers : byte
{
Activated
}

View File

@@ -0,0 +1,13 @@
namespace Content.Client._White.Cult.Structures;
[RegisterComponent]
public sealed partial class CultCraftStructureVisualsComponent : Component
{
[DataField("stateOn")]
[ViewVariables(VVAccess.ReadWrite)]
public string? StateOn = "icon";
[DataField("stateOff")]
[ViewVariables(VVAccess.ReadWrite)]
public string? StateOff = "icon-off";
}

View File

@@ -0,0 +1,56 @@
using Content.Shared.White.Cult.UI;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Client._White.Cult.UI.Altar;
[UsedImplicitly]
public sealed class AltarBUI : BoundUserInterface
{
private AltarWindow? _window;
public AltarBUI(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
}
protected override void Open()
{
base.Open();
_window = new AltarWindow();
_window.OnClose += Close;
_window.OnItemSelected += OnItemSelected;
}
private void OnItemSelected(string item)
{
var evt = new AltarBuyRequest(item);
SendMessage(evt);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_window?.Dispose();
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is AltarListingBUIState listingState)
{
_window?.SetListing(listingState.Items);
}
else if(state is AltarTimerBUIState timerState)
{
_window?.SetTimer(timerState.NextTimeUse);
}
}
}

View File

@@ -0,0 +1,9 @@
<Control SetSize="50 50" MaxSize="50 50" xmlns="https://spacestation14.io"
xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client">
<PanelContainer>
<PanelContainer.PanelOverride>
<graphics:StyleBoxFlat BackgroundColor="#000000FF" />
</PanelContainer.PanelOverride>
<TextureButton Name="BuyListingButton" Access="Public" HorizontalAlignment="Center" VerticalAlignment="Center" SetSize="48 48" MaxSize="48 48"/>
</PanelContainer>
</Control>

View File

@@ -0,0 +1,21 @@
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
namespace Content.Client._White.Cult.UI.Altar;
[GenerateTypedNameReferences]
public partial class AltarListingControl : Control
{
public AltarListingControl(EntityPrototype prototype, Texture icon, Action<string>? clickAction)
{
RobustXamlLoader.Load(this);
ToolTip = $"{prototype.Name}\n{prototype.Description}";
BuyListingButton.TextureNormal = icon;
BuyListingButton.OnButtonDown += _ => clickAction?.Invoke(prototype.ID);
}
}

View File

@@ -0,0 +1,7 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="{Loc agent-id-menu-title}">
<RichTextLabel Name="TimerLabel"></RichTextLabel>
<BoxContainer Name="ListingContainer" Orientation="Horizontal" SeparationOverride="4" MinWidth="150">
</BoxContainer>
</DefaultWindow>

View File

@@ -0,0 +1,92 @@
using Content.Client.GameTicking.Managers;
using Content.Client.TextScreen;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Client._White.Cult.UI.Altar;
[GenerateTypedNameReferences]
public partial class AltarWindow : DefaultWindow
{
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly SpriteSystem _spriteSystem = default!;
[Dependency] private readonly PrototypeManager _prototypeManager = default!;
public event Action<string>? OnItemSelected;
private TimeSpan? _nextTimeUse = null!;
private List<AltarListingControl> _listingControls = new();
public AltarWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
if (_nextTimeUse == null) return;
var remainingTime = _nextTimeUse.Value - _gameTiming.CurTime;
if (remainingTime.TotalSeconds < 0)
{
remainingTime = TimeSpan.Zero;
}
var remainingTimeText = TextScreenSystem.TimeToString(remainingTime);
TimerLabel.SetMessage(remainingTimeText);
}
public void SetListing(List<string> prototypes)
{
foreach (var prototypeId in prototypes)
{
var prototype = _prototypeManager.Index<EntityPrototype>(prototypeId);
if(prototype == null) return;
var prototypeIcon = _spriteSystem.GetPrototypeIcon(prototype).Default;
AddListingControl(prototype);
}
}
public void AddListingControl(EntityPrototype entityPrototype)
{
var icon = _spriteSystem.GetPrototypeIcon(entityPrototype).Default;
var control = new AltarListingControl(entityPrototype, icon, OnItemSelected);
ListingContainer.AddChild(control);
_listingControls.Add(control);
}
public void SetTimer(TimeSpan? timer)
{
_nextTimeUse = timer;
if (timer == null)
{
TimerLabel.SetMessage("Алтарь готов к использованию");
SetListingButtonsState(true);
return;
}
SetListingButtonsState(false);
}
private void SetListingButtonsState(bool enabled)
{
foreach (var listingControl in _listingControls)
{
listingControl.BuyListingButton.Disabled = enabled;
}
}
}

View File

@@ -0,0 +1,52 @@
using System.Linq;
using Content.Client._White.UserInterface.Radial;
using Content.Shared.White.Cult.Runes.Components;
using Content.Shared.White.Cult.UI;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes;
namespace Content.Client._White.Cult.UI.ConstructSelector;
public sealed class ConstructSelectorBui : BoundUserInterface
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
private SpriteSystem _spriteSystem = default!;
private bool _selected;
public ConstructSelectorBui(EntityUid owner, Enum uiKey) : base(owner, uiKey) { }
protected override void Open()
{
base.Open();
_spriteSystem = _entityManager.EntitySysManager.GetEntitySystem<SpriteSystem>();
var shellComponent = _entityManager.GetComponent<ConstructShellComponent>(Owner);
var shellSelector = new RadialContainer();
shellSelector.Closed += () =>
{
if(_selected) return;
SendMessage(new ConstructFormSelectedEvent(shellComponent.ConstructForms.First()));
};
foreach (var form in shellComponent.ConstructForms)
{
var formPrototype = _prototypeManager.Index<EntityPrototype>(form);
var button = shellSelector.AddButton(formPrototype.Name, _spriteSystem.GetPrototypeIcon(formPrototype).Default);
button.Controller.OnPressed += _ =>
{
_selected = true;
SendMessage(new ConstructFormSelectedEvent(form));
shellSelector.Close();
};
}
shellSelector.OpenCentered();
}
}

View File

@@ -0,0 +1,89 @@
using Content.Client._White.UserInterface.Radial;
using Content.Shared.White.Cult;
using Content.Shared.White.Cult.UI;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes;
namespace Content.Client._White.Cult.UI.CultistFactory;
public sealed class CultistFactoryBUI : BoundUserInterface
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
private RadialContainer? _radialContainer;
private bool _updated = false;
public CultistFactoryBUI(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
}
private void ResetUI()
{
_radialContainer?.Close();
_radialContainer = null;
_updated = false;
}
protected override void Open()
{
base.Open();
if (_radialContainer != null)
ResetUI();
_radialContainer = new RadialContainer();
if (State != null)
UpdateState(State);
}
private void PopulateRadial(IReadOnlyCollection<string> ids)
{
foreach (var id in ids)
{
if (!_prototypeManager.TryIndex<CultistFactoryProductionPrototype>(id, out var prototype))
return;
if (_radialContainer == null)
continue;
var button = _radialContainer.AddButton(prototype.Name, prototype.Icon);
button.Controller.OnPressed += _ =>
{
Select(id);
};
}
}
private void Select(string id)
{
SendMessage(new CultistFactoryItemSelectedMessage(id));
ResetUI();
Close();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
ResetUI();
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (_updated)
return;
if (state is CultistFactoryBUIState newState)
{
PopulateRadial(newState.Ids);
}
if (_radialContainer == null)
return;
_radialContainer?.OpenAttachedLocalPlayer();
_updated = true;
}
}

View File

@@ -0,0 +1,54 @@
using Content.Shared.White.Cult.UI;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes;
namespace Content.Client._White.Cult.UI.ListViewSelector;
public sealed class ListViewSelectorBUI : BoundUserInterface
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
private ListViewSelectorWindow? _window;
public ListViewSelectorBUI(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
}
protected override void Open()
{
base.Open();
_window = new ListViewSelectorWindow(_prototypeManager);
_window.OpenCentered();
_window.OnClose += Close;
_window.ItemSelected += (item, index) =>
{
var msg = new ListViewItemSelectedMessage(item, index);
SendMessage(msg);
};
if(State != null)
UpdateState(State);
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is ListViewBUIState newState)
{
_window?.PopulateList(newState.Items, newState.IsUsingPrototypes);
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_window?.Close();
}
}

View File

@@ -0,0 +1,9 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="{Loc runes-window-title}"
MinWidth="350"
MinHeight="400">
<ScrollContainer HorizontalExpand="True" VerticalExpand="True">
<BoxContainer Name="ItemsContainer" Orientation="Vertical"></BoxContainer>
</ScrollContainer>
</DefaultWindow>

View File

@@ -0,0 +1,45 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
namespace Content.Client._White.Cult.UI.ListViewSelector;
[GenerateTypedNameReferences]
public partial class ListViewSelectorWindow : DefaultWindow
{
public Action<string, int>? ItemSelected;
private readonly IPrototypeManager _prototypeManager;
public ListViewSelectorWindow(IPrototypeManager prototypeManager)
{
RobustXamlLoader.Load(this);
_prototypeManager = prototypeManager;
}
public void PopulateList(List<string> items, bool isPrototypes)
{
ItemsContainer.RemoveAllChildren();
foreach (var item in items)
{
var button = new Button();
var itemName = Loc.GetString($"ent-{item}");
if (isPrototypes)
{
if(_prototypeManager.TryIndex<EntityPrototype>(item, out var itemPrototype))
{
itemName = itemPrototype.Name;
}
}
button.Text = itemName;
button.OnPressed += _ => ItemSelected?.Invoke(item, items.IndexOf(item));
ItemsContainer.AddChild(button);
}
}
}

View File

@@ -0,0 +1,45 @@
using Content.Shared.White.Cult.UI;
using Robust.Client.GameObjects;
namespace Content.Client._White.Cult.UI.NameSelector;
public sealed class NameSelectorBUI : BoundUserInterface
{
public NameSelectorBUI(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}
private NameSelectorWindow? _window;
protected override void Open()
{
base.Open();
_window = new();
_window.OpenCentered();
_window.OnNameChange += OnNameSelected;
_window.OnClose += Close;
}
private void OnNameSelected(string name)
{
SendMessage(new NameSelectorMessage(name));
}
protected override void UpdateState(BoundUserInterfaceState state)
{
if (state is not NameSelectorBuiState cast || _window == null)
{
return;
}
_window.UpdateState(cast.Name);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
_window?.Close();
}
}

View File

@@ -0,0 +1,9 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Time to choose..">
<BoxContainer Orientation="Vertical">
<Label Text="Задайте название для метки." />
<LineEdit Name="NameSelector" HorizontalExpand="True" />
<Button Name="NameSelectorSet" Text="Принять" />
</BoxContainer>
</DefaultWindow>

View File

@@ -0,0 +1,26 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
namespace Content.Client._White.Cult.UI.NameSelector;
[GenerateTypedNameReferences]
public sealed partial class NameSelectorWindow: DefaultWindow
{
public Action<string>? OnNameChange;
public NameSelectorWindow()
{
RobustXamlLoader.Load(this);
NameSelectorSet.OnPressed += _ =>
{
OnNameChange!(NameSelector.Text);
};
}
public void UpdateState(string name)
{
NameSelector.Text = name;
}
}

View File

@@ -0,0 +1,44 @@
using Content.Client._White.UserInterface.Radial;
using Content.Shared.White.Cult;
using Content.Shared.White.Cult.Components;
using Robust.Client.GameObjects;
using Robust.Client.Utility;
namespace Content.Client._White.Cult.UI.SpellSelector;
public sealed class SpellSelectorBUI : BoundUserInterface
{
private RadialContainer? _radialContainer;
public SpellSelectorBUI(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
}
protected override void Open()
{
base.Open();
_radialContainer = new RadialContainer();
_radialContainer.Closed += Close;
foreach (var action in CultistComponent.CultistActions)
{
var button = _radialContainer.AddButton(action.DisplayName, action.Icon?.Frame0());
button.Controller.OnPressed += _ =>
{
SendMessage(new CultEmpowerSelectedBuiMessage(action));
Close();
};
}
_radialContainer.OpenAttachedLocalPlayer();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
_radialContainer?.Close();
}
}

View File

@@ -0,0 +1,129 @@
using Content.Client._White.UserInterface.Radial;
using Content.Client.Construction;
using Content.Shared.Construction.Prototypes;
using Content.Shared.Popups;
using Content.Shared.White.Cult.Structures;
using Robust.Client.GameObjects;
using Robust.Client.Placement;
using Robust.Client.Player;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
namespace Content.Client._White.Cult.UI.StructureRadial;
public sealed class StructureCraftBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IPlacementManager _placement = default!;
[Dependency] private readonly IEntitySystemManager _systemManager = default!;
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IEntityManager _entMan = default!;
private RadialContainer? _radialContainer;
public StructureCraftBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
}
private void CreateUI()
{
if (_radialContainer != null)
ResetUI();
_radialContainer = new RadialContainer();
foreach (var prototype in _prototypeManager.EnumeratePrototypes<CultStructurePrototype>())
{
var radialButton = _radialContainer.AddButton(prototype.StructureName, prototype.Icon);
radialButton.Controller.OnPressed += _ =>
{
Select(prototype.StructureId);
};
}
_radialContainer.OpenAttachedLocalPlayer();
}
private void ResetUI()
{
_radialContainer?.Close();
_radialContainer = null;
}
protected override void Open()
{
base.Open();
CreateUI();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
ResetUI();
}
private void Select(string id)
{
CreateBlueprint(id);
ResetUI();
Close();
}
private void CreateBlueprint(string id)
{
var newObj = new PlacementInformation
{
Range = 2,
IsTile = false,
EntityType = id,
PlacementOption = "SnapgridCenter"
};
_prototypeManager.TryIndex<ConstructionPrototype>(id, out var construct);
if (construct == null)
return;
var player = _player.LocalPlayer?.ControlledEntity;
if (player == null)
return;
if (construct.ID == "CultPylon" && CheckForStructure(player, id))
{
var popup = _entMan.System<SharedPopupSystem>();
popup.PopupClient(Loc.GetString("cult-structure-craft-another-structure-nearby"), player.Value, player.Value);
return;
}
var constructSystem = _systemManager.GetEntitySystem<ConstructionSystem>();
var hijack = new ConstructionPlacementHijack(constructSystem, construct);
_placement.BeginPlacing(newObj, hijack);
}
private bool CheckForStructure(EntityUid? uid, string id)
{
if (uid == null)
return false;
if (!_entMan.TryGetComponent<TransformComponent>(uid, out var transform))
return false;
var lookupSystem = _entMan.System<EntityLookupSystem>();
var entities = lookupSystem.GetEntitiesInRange(transform.Coordinates, 15f);
foreach (var ent in entities)
{
if (!_entMan.TryGetComponent<MetaDataComponent>(ent, out var metadata))
continue;
if (metadata.EntityPrototype?.ID == id)
return true;
}
return false;
}
}

View File

@@ -0,0 +1,9 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="{Loc 'Choose'}"
MinWidth="300"
MinHeight="400">
<ScrollContainer HorizontalExpand="True" VerticalExpand="True">
<BoxContainer Name="ItemsContainer" Orientation="Vertical"></BoxContainer>
</ScrollContainer>
</DefaultWindow>

View File

@@ -0,0 +1,36 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
namespace Content.Client._White.Cult.UI.SummonCultistList;
[GenerateTypedNameReferences]
public partial class SummonCultistListWindow : DefaultWindow
{
public Action<int, int>? ItemSelected;
public SummonCultistListWindow()
{
RobustXamlLoader.Load(this);
}
public void PopulateList(List<int> items, List<string> labels)
{
ItemsContainer.RemoveAllChildren();
var count = Math.Min(items.Count, labels.Count);
for (var i = 0; i < count; i++)
{
var item = items[i];
var button = new Button();
button.Text = labels[i];
button.OnPressed += _ => ItemSelected?.Invoke(item, items.IndexOf(item));
ItemsContainer.AddChild(button);
}
}
}

View File

@@ -0,0 +1,43 @@
using Content.Shared.White.Cult.UI;
using Robust.Client.GameObjects;
namespace Content.Client._White.Cult.UI.SummonCultistList;
public sealed class SummonCultistListWindowBUI : BoundUserInterface
{
private SummonCultistListWindow? _window;
public SummonCultistListWindowBUI(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
}
protected override void Open()
{
base.Open();
_window = new();
_window.OpenCentered();
_window.OnClose += Close;
_window.ItemSelected += (item, index) =>
{
var msg = new SummonCultistListWindowItemSelectedMessage(item, index);
SendMessage(msg);
_window.Close();
};
if (State != null)
UpdateState(State);
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is SummonCultistListWindowBUIState newState)
{
_window?.PopulateList(newState.Items, newState.Label);
}
}
}

View File

@@ -0,0 +1,9 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="{Loc 'Teleport to'}"
MinWidth="300"
MinHeight="400">
<ScrollContainer HorizontalExpand="True" VerticalExpand="True">
<BoxContainer Name="ItemsContainer" Orientation="Vertical"></BoxContainer>
</ScrollContainer>
</DefaultWindow>

View File

@@ -0,0 +1,41 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
namespace Content.Client._White.Cult.UI.TeleportRunesList;
[GenerateTypedNameReferences]
public partial class TeleportRunesListWindow : DefaultWindow
{
public Action<int, int>? ItemSelected;
public TeleportRunesListWindow()
{
RobustXamlLoader.Load(this);
}
public void PopulateList(List<int> items, List<string> labels)
{
ItemsContainer.RemoveAllChildren();
var count = Math.Min(items.Count, labels.Count);
for (var i = 0; i < count; i++)
{
var item = items[i];
var button = new Button();
button.Text = labels[i];
button.OnPressed += _ => ItemSelected?.Invoke(item, items.IndexOf(item));
ItemsContainer.AddChild(button);
}
}
public void Clear()
{
ItemsContainer.RemoveAllChildren();
}
}

View File

@@ -0,0 +1,43 @@
using Content.Shared.White.Cult.UI;
using Robust.Client.GameObjects;
namespace Content.Client._White.Cult.UI.TeleportRunesList;
public sealed class TeleportRunesListWindowBUI : BoundUserInterface
{
private TeleportRunesListWindow? _window;
public TeleportRunesListWindowBUI(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
}
protected override void Open()
{
base.Open();
_window = new();
_window.OpenCentered();
_window.OnClose += Close;
_window.ItemSelected += (item, index) =>
{
var msg = new TeleportRunesListWindowItemSelectedMessage(item, index);
SendMessage(msg);
_window.Close();
};
if (State != null)
UpdateState(State);
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is TeleportRunesListWindowBUIState newState)
{
_window?.PopulateList(newState.Items, newState.Label);
}
}
}

View File

@@ -0,0 +1,41 @@
using System.Linq;
using Content.Client.Eui;
using Content.Client._White.Cult.UI.TeleportRunesList;
using Content.Shared.Eui;
using Content.Shared.White.Cult.UI;
namespace Content.Client._White.Cult.UI.TeleportSpell;
public sealed class TeleportSpellEui : BaseEui
{
private TeleportRunesListWindow _window;
public TeleportSpellEui()
{
_window = new TeleportRunesListWindow();
}
public override void Opened()
{
_window.OpenCentered();
_window.ItemSelected += (index, _) => SendMessage(new TeleportSpellTargetRuneSelected(){RuneUid = index});
_window.OnClose += () => SendMessage(new CloseEuiMessage());
base.Opened();
}
public override void Closed()
{
base.Closed();
_window.Close();
}
public override void HandleState(EuiStateBase state)
{
if(state is not TeleportSpellEuiState cast) return;
_window.Clear();
_window.PopulateList(cast.Runes.Keys.ToList(), cast.Runes.Values.ToList());
}
}

View File

@@ -0,0 +1,9 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="{Loc 'cult-torch-window-title'}"
MinWidth="300"
MinHeight="400">
<ScrollContainer HorizontalExpand="True" VerticalExpand="True">
<BoxContainer Name="ItemsContainer" Orientation="Vertical"></BoxContainer>
</ScrollContainer>
</DefaultWindow>

View File

@@ -0,0 +1,35 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
namespace Content.Client._White.Cult.UI.Torch;
[GenerateTypedNameReferences]
public partial class TorchWindow : DefaultWindow
{
public Action<string, string>? ItemSelected;
public TorchWindow()
{
RobustXamlLoader.Load(this);
}
public void PopulateList(Dictionary<string, string> items)
{
ItemsContainer.RemoveAllChildren();
foreach (var item in items.Keys)
{
var button = new Button();
var itemName = items[item];
button.Text = itemName;
button.OnPressed += _ => ItemSelected?.Invoke(item, items[item]);
ItemsContainer.AddChild(button);
}
}
}

View File

@@ -0,0 +1,47 @@
using System.Data;
using Content.Shared.White.Cult.Items;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes;
namespace Content.Client._White.Cult.UI.Torch;
public sealed class TorchWindowBUI : BoundUserInterface
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
private TorchWindow? _window;
public TorchWindowBUI(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
}
protected override void Open()
{
base.Open();
_window = new();
_window.OpenCentered();
_window.OnClose += Close;
_window.ItemSelected += (uid, item) =>
{
var msg = new TorchWindowItemSelectedMessage(uid, item);
SendMessage(msg);
_window.Close();
};
if (State != null)
UpdateState(State);
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is TorchWindowBUIState newState)
{
_window?.PopulateList(newState.Items);
}
}
}