Skip to content

Commit

Permalink
Port Shipyards (DeltaV-Station#1314)
Browse files Browse the repository at this point in the history
# Description

I needed this extremely badly.

# TODO

- [x] Move all of this out of the DeltaV folders.

# Changelog

:cl:
- add: Added Shipyards.

---------

Signed-off-by: deltanedas <[email protected]>
Co-authored-by: deltanedas <[email protected]>
Co-authored-by: Null <[email protected]>
Co-authored-by: Milon <[email protected]>
Co-authored-by: Plykiya <[email protected]>
Co-authored-by: plykiya <[email protected]>
Co-authored-by: Ed <[email protected]>
Co-authored-by: Radezolid <[email protected]>
Co-authored-by: sleepyyapril <[email protected]>
  • Loading branch information
9 people authored Dec 6, 2024
1 parent 01a13e3 commit d69b516
Show file tree
Hide file tree
Showing 76 changed files with 20,255 additions and 111 deletions.
9 changes: 6 additions & 3 deletions Content.Client/Chat/UI/EmotesMenu.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using System.Numerics;
using System.Numerics;
using Content.Client.UserInterface.Controls;
using Content.Shared.Chat.Prototypes;
using Content.Shared.Speech;
using Content.Shared.Whitelist;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface.Controls;
Expand All @@ -19,6 +20,7 @@ public sealed partial class EmotesMenu : RadialMenu
[Dependency] private readonly ISharedPlayerManager _playerManager = default!;

private readonly SpriteSystem _spriteSystem;
private readonly EntityWhitelistSystem _whitelistSystem;

public event Action<ProtoId<EmotePrototype>>? OnPlayEmote;

Expand All @@ -28,6 +30,7 @@ public EmotesMenu()
RobustXamlLoader.Load(this);

_spriteSystem = _entManager.System<SpriteSystem>();
_whitelistSystem = _entManager.System<EntityWhitelistSystem>();

var main = FindControl<RadialContainer>("Main");

Expand All @@ -37,8 +40,8 @@ public EmotesMenu()
var player = _playerManager.LocalSession?.AttachedEntity;
if (emote.Category == EmoteCategory.Invalid ||
emote.ChatTriggers.Count == 0 ||
!(player.HasValue && (emote.Whitelist?.IsValid(player.Value, _entManager) ?? true)) ||
(emote.Blacklist?.IsValid(player.Value, _entManager) ?? false))
!(player.HasValue && _whitelistSystem.IsWhitelistPassOrNull(emote.Whitelist, player.Value)) ||
_whitelistSystem.IsBlacklistPass(emote.Blacklist, player.Value))
continue;

if (!emote.Available &&
Expand Down
6 changes: 5 additions & 1 deletion Content.Client/Construction/UI/ConstructionMenuPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Content.Client.UserInterface.Systems.MenuBar.Widgets;
using Content.Shared.Construction.Prototypes;
using Content.Shared.Tag;
using Content.Shared.Whitelist;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Placement;
Expand All @@ -23,13 +24,15 @@ namespace Content.Client.Construction.UI
/// </summary>
internal sealed class ConstructionMenuPresenter : IDisposable
{
[Dependency] private readonly EntityManager _entManager = default!;
[Dependency] private readonly IEntitySystemManager _systemManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IPlacementManager _placementManager = default!;
[Dependency] private readonly IUserInterfaceManager _uiManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;

private readonly IConstructionMenuView _constructionView;
private readonly EntityWhitelistSystem _whitelistSystem;

private ConstructionSystem? _constructionSystem;
private ConstructionPrototype? _selected;
Expand Down Expand Up @@ -78,6 +81,7 @@ public ConstructionMenuPresenter()
// This is a lot easier than a factory
IoCManager.InjectDependencies(this);
_constructionView = new ConstructionMenu();
_whitelistSystem = _entManager.System<EntityWhitelistSystem>();

// This is required so that if we load after the system is initialized, we can bind to it immediately
if (_systemManager.TryGetEntitySystem<ConstructionSystem>(out var constructionSystem))
Expand Down Expand Up @@ -157,7 +161,7 @@ private void OnViewPopulateRecipes(object? sender, (string search, string catago

if (_playerManager.LocalSession == null
|| _playerManager.LocalEntity == null
|| (recipe.EntityWhitelist != null && !recipe.EntityWhitelist.IsValid(_playerManager.LocalEntity.Value)))
|| _whitelistSystem.IsWhitelistFail(recipe.EntityWhitelist, _playerManager.LocalEntity.Value))
continue;

if (!string.IsNullOrEmpty(search))
Expand Down
5 changes: 5 additions & 0 deletions Content.Client/Shipyard/ShipyardConsoleSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using Content.Shared.Shipyard;

namespace Content.Client.Shipyard;

public sealed class ShipyardConsoleSystem : SharedShipyardConsoleSystem;
58 changes: 58 additions & 0 deletions Content.Client/Shipyard/UI/ShipyardBoundUserInterface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Content.Shared.Access.Systems;
using Content.Shared.Shipyard;
using Content.Shared.Whitelist;
using Robust.Client.Player;
using Robust.Shared.Prototypes;

namespace Content.Client.Shipyard.UI;

public sealed class ShipyardConsoleBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly IPlayerManager _player = default!;

private readonly AccessReaderSystem _access;
private readonly EntityWhitelistSystem _whitelist;

[ViewVariables]
private ShipyardConsoleMenu? _menu;

public ShipyardConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
_access = EntMan.System<AccessReaderSystem>();
_whitelist = EntMan.System<EntityWhitelistSystem>();
}

protected override void Open()
{
base.Open();

_menu = new ShipyardConsoleMenu(Owner, _proto, EntMan, _player, _access, _whitelist);
_menu.OpenCentered();
_menu.OnClose += Close;
_menu.OnPurchased += Purchase;
}

protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);

if (state is not ShipyardConsoleState cast)
return;

_menu?.UpdateState(cast);
}

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);

if (disposing)
_menu?.Dispose();
}

private void Purchase(string id)
{
SendMessage(new ShipyardConsolePurchaseMessage(id));
}
}
29 changes: 29 additions & 0 deletions Content.Client/Shipyard/UI/ShipyardConsoleMenu.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
SetSize="500 360"
MinSize="460 280"
Title="{Loc 'shipyard-console-menu-title'}">
<BoxContainer Orientation="Vertical" Margin="5 0 5 0">
<Label Name="BankAccountLabel" />
<BoxContainer Orientation="Horizontal">
<OptionButton Name="Categories"
Prefix="{Loc 'cargo-console-menu-categories-label'}"
HorizontalExpand="True" />
<LineEdit Name="SearchBar"
PlaceHolder="{Loc 'cargo-console-menu-search-bar-placeholder'}"
HorizontalExpand="True" />
</BoxContainer>
<ScrollContainer HorizontalExpand="True"
VerticalExpand="True"
SizeFlagsStretchRatio="6">
<BoxContainer Name="Vessels"
Orientation="Vertical"
HorizontalExpand="True"
VerticalExpand="True">
<!-- Vessels get added here by code -->
</BoxContainer>
</ScrollContainer>
<TextureButton VerticalExpand="True" />
</BoxContainer>
</controls:FancyWindow>
109 changes: 109 additions & 0 deletions Content.Client/Shipyard/UI/ShipyardConsoleMenu.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using Content.Client.UserInterface.Controls;
using Content.Shared.Access.Systems;
using Content.Shared.Shipyard;
using Content.Shared.Shipyard.Prototypes;
using Content.Shared.Whitelist;
using Robust.Client.AutoGenerated;
using Robust.Client.Player;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;

namespace Content.Client.Shipyard.UI;

[GenerateTypedNameReferences]
public sealed partial class ShipyardConsoleMenu : FancyWindow
{
private readonly AccessReaderSystem _access;
private readonly IPlayerManager _player;

public event Action<string>? OnPurchased;

private readonly List<VesselPrototype> _vessels = new();
private readonly List<string> _categories = new();

public Entity<ShipyardConsoleComponent> Console;
private string? _category;

public ShipyardConsoleMenu(EntityUid console, IPrototypeManager proto, IEntityManager entMan, IPlayerManager player, AccessReaderSystem access, EntityWhitelistSystem whitelist)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);

Console = (console, entMan.GetComponent<ShipyardConsoleComponent>(console));
_access = access;
_player = player;

// don't include ships that aren't allowed by whitelist, server won't accept them anyway
foreach (var vessel in proto.EnumeratePrototypes<VesselPrototype>())
{
if (whitelist.IsWhitelistPassOrNull(vessel.Whitelist, console))
_vessels.Add(vessel);
}
_vessels.Sort((x, y) => string.Compare(x.Name, y.Name, StringComparison.CurrentCultureIgnoreCase));

// only list categories in said ships
foreach (var vessel in _vessels)
{
foreach (var category in vessel.Categories)
{
if (!_categories.Contains(category))
_categories.Add(category);
}
}

_categories.Sort();
// inserting here and not adding at the start so it doesn't get affected by sort
_categories.Insert(0, Loc.GetString("cargo-console-menu-populate-categories-all-text"));
PopulateCategories();

SearchBar.OnTextChanged += _ => PopulateProducts();
Categories.OnItemSelected += args =>
{
_category = args.Id == 0 ? null : _categories[args.Id];
Categories.SelectId(args.Id);
PopulateProducts();
};
}

/// <summary>
/// Populates the list of products that will actually be shown, using the current filters.
/// </summary>
private void PopulateProducts()
{
Vessels.RemoveAllChildren();

var access = _player.LocalSession?.AttachedEntity is {} player
&& _access.IsAllowed(player, Console);

var search = SearchBar.Text.Trim().ToLowerInvariant();
foreach (var vessel in _vessels)
{
if (search.Length != 0 && !vessel.Name.ToLowerInvariant().Contains(search))
continue;
if (_category != null && !vessel.Categories.Contains(_category))
continue;

var vesselEntry = new VesselRow(vessel, access);
vesselEntry.OnPurchasePressed += () => OnPurchased?.Invoke(vessel.ID);
Vessels.AddChild(vesselEntry);
}
}

/// <summary>
/// Populates the list categories that will actually be shown, using the current filters.
/// </summary>
private void PopulateCategories()
{
Categories.Clear();
foreach (var category in _categories)
{
Categories.AddItem(category);
}
}

public void UpdateState(ShipyardConsoleState state)
{
BankAccountLabel.Text = Loc.GetString("cargo-console-menu-points-amount", ("amount", state.Balance.ToString()));
PopulateProducts();
}
}
16 changes: 16 additions & 0 deletions Content.Client/Shipyard/UI/VesselRow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<PanelContainer xmlns="https://spacestation14.io"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
HorizontalExpand="True">
<BoxContainer Orientation="Horizontal"
HorizontalExpand="True">
<Button Name="Purchase" Text="{Loc 'purchase'}" StyleClasses="LabelSubText" />
<Label Name="VesselName" HorizontalExpand="True" />
<PanelContainer>
<PanelContainer.PanelOverride>
<gfx:StyleBoxFlat BackgroundColor="#25252A" />
</PanelContainer.PanelOverride>

<Label Name="Price" MinSize="52 32" Align="Right" />
</PanelContainer>
</BoxContainer>
</PanelContainer>
29 changes: 29 additions & 0 deletions Content.Client/Shipyard/UI/VesselRow.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Content.Shared.Shipyard.Prototypes;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Utility;

namespace Content.Client.Shipyard.UI;

[GenerateTypedNameReferences]
public sealed partial class VesselRow : PanelContainer
{
public event Action? OnPurchasePressed;

public VesselRow(VesselPrototype vessel, bool access)
{
RobustXamlLoader.Load(this);

VesselName.Text = vessel.Name;

var tooltip = new Tooltip();
tooltip.SetMessage(FormattedMessage.FromMarkup(vessel.Description));
Purchase.TooltipSupplier = _ => tooltip;
Purchase.Disabled = !access;
Purchase.OnPressed += _ => OnPurchasePressed?.Invoke();

Price.Text = Loc.GetString("cargo-console-menu-points-amount", ("amount", vessel.Price));
}
}
Loading

0 comments on commit d69b516

Please sign in to comment.