workplace init
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
using Content.Shared._CP14.Workplace;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client._CP14.Workplace;
|
||||
|
||||
public sealed class CP14WorkplaceBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
private CP14WorkplaceWindow? _window;
|
||||
|
||||
public CP14WorkplaceBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = this.CreateWindow<CP14WorkplaceWindow>();
|
||||
|
||||
_window.OnCraft += entry => SendMessage(new CP14WorkplaceCraftMessage(entry.Recipe));
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case CP14WorkplaceState recipesState:
|
||||
_window?.UpdateState(recipesState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<Control xmlns="https://spacestation14.io">
|
||||
<Button Name="Button">
|
||||
<GridContainer Columns="2">
|
||||
<EntityPrototypeView Name="View"
|
||||
Margin="0,0,4,0"
|
||||
MinSize="48 48"
|
||||
MaxSize="48 48"
|
||||
Scale="2,2"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalExpand="True"/>
|
||||
<Label Name="Name"/>
|
||||
</GridContainer>
|
||||
</Button>
|
||||
</Control>
|
||||
@@ -0,0 +1,53 @@
|
||||
using Content.Shared._CP14.Workplace;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client._CP14.Workplace;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CP14WorkplaceRecipeControl : Control
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
|
||||
public event Action<CP14WorkplaceRecipeEntry, EntityPrototype>? OnSelect;
|
||||
|
||||
private readonly EntityPrototype _recipePrototype;
|
||||
private readonly bool _craftable;
|
||||
|
||||
public CP14WorkplaceRecipeControl(CP14WorkplaceRecipeEntry entry)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_recipePrototype = _prototype.Index(entry.Recipe);
|
||||
_craftable = entry.Craftable;
|
||||
|
||||
Button.OnPressed += _ => OnSelect?.Invoke(entry, _recipePrototype);
|
||||
|
||||
UpdateColor();
|
||||
//UpdateName();
|
||||
UpdateView();
|
||||
}
|
||||
|
||||
private void UpdateColor()
|
||||
{
|
||||
if (_craftable)
|
||||
return;
|
||||
|
||||
Button.ModulateSelfOverride = Color.FromHex("#302622");
|
||||
}
|
||||
|
||||
private void UpdateName()
|
||||
{
|
||||
//var result = _recipePrototype;
|
||||
//var counter = _recipePrototype.ResultCount > 1 ? $" x{_recipePrototype.ResultCount}" : "";
|
||||
//Name.Text = $"{Loc.GetString(result.Name)} {counter}" ;
|
||||
}
|
||||
|
||||
private void UpdateView()
|
||||
{
|
||||
View.SetPrototype(_recipePrototype);
|
||||
}
|
||||
}
|
||||
72
Content.Client/_CP14/Workplace/CP14WorkplaceWindow.xaml
Normal file
72
Content.Client/_CP14/Workplace/CP14WorkplaceWindow.xaml
Normal file
@@ -0,0 +1,72 @@
|
||||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
Title="{Loc 'cp14-workbench-ui-title'}"
|
||||
SetSize="700 500"
|
||||
MinSize="700 300">
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<!-- Main -->
|
||||
<BoxContainer HorizontalExpand="True" VerticalExpand="True" Orientation="Horizontal">
|
||||
<!-- Product list (left side UI) -->
|
||||
<BoxContainer MinWidth="350" HorizontalExpand="True" Orientation="Vertical" Margin="0 0 10 0">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<!-- Search Bar -->
|
||||
<LineEdit Name="SearchBar" Margin="4" PlaceHolder="Search" HorizontalExpand="True" />
|
||||
<OptionButton Name="OptionCategories" Access="Public" MinSize="130 0"/>
|
||||
</BoxContainer>
|
||||
<!-- Crafts container -->
|
||||
<ScrollContainer HorizontalExpand="True" VerticalExpand="True" MinSize="0 200">
|
||||
<BoxContainer Name="CraftsContainer" Orientation="Vertical" HorizontalExpand="True" />
|
||||
</ScrollContainer>
|
||||
</BoxContainer>
|
||||
|
||||
<!-- Craft view (right side UI) -->
|
||||
<BoxContainer MinWidth="350" Orientation="Vertical" HorizontalExpand="True"
|
||||
VerticalExpand="True">
|
||||
<PanelContainer HorizontalExpand="True" VerticalExpand="True">
|
||||
<!-- Background -->
|
||||
<PanelContainer.PanelOverride>
|
||||
<graphics:StyleBoxFlat BackgroundColor="#41332f" />
|
||||
</PanelContainer.PanelOverride>
|
||||
|
||||
<!-- Content -->
|
||||
<BoxContainer HorizontalExpand="True" VerticalExpand="True" Orientation="Vertical">
|
||||
<!-- Item info -->
|
||||
<!-- icon -->
|
||||
<EntityPrototypeView Name="ItemView"
|
||||
Scale="2,2"
|
||||
Margin="8"
|
||||
MinSize="96 96"
|
||||
MaxSize="96 96"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<!-- name & description -->
|
||||
<BoxContainer Margin="5 0 0 0" HorizontalExpand="True" VerticalExpand="True"
|
||||
Orientation="Vertical">
|
||||
<RichTextLabel Name="ItemName" Margin="5" />
|
||||
<RichTextLabel Name="ItemDescription" Margin="5" />
|
||||
</BoxContainer>
|
||||
|
||||
<controls:HLine Color="#404040" Thickness="2" Margin="0 5" />
|
||||
|
||||
<!-- Required title -->
|
||||
<Label Margin="5 0 0 0" Text="{Loc 'cp14-workbench-recipe-list'}" />
|
||||
|
||||
<!-- Craft requirements content -->
|
||||
<!-- Added by code -->
|
||||
<BoxContainer
|
||||
Margin="5 0 0 0"
|
||||
Name="ItemRequirements"
|
||||
Orientation="Vertical" VerticalExpand="True"
|
||||
HorizontalExpand="True" />
|
||||
|
||||
<controls:HLine Color="#404040" Thickness="5" Margin="0 5" />
|
||||
|
||||
<!-- Craft button -->
|
||||
<Button Name="CraftButton" Text="{Loc 'cp14-workbench-craft'}" />
|
||||
</BoxContainer>
|
||||
</PanelContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
170
Content.Client/_CP14/Workplace/CP14WorkplaceWindow.xaml.cs
Normal file
170
Content.Client/_CP14/Workplace/CP14WorkplaceWindow.xaml.cs
Normal file
@@ -0,0 +1,170 @@
|
||||
using Content.Shared._CP14.Workplace;
|
||||
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._CP14.Workplace;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CP14WorkplaceWindow : DefaultWindow
|
||||
{
|
||||
private const int AllCategoryId = -1;
|
||||
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly ILogManager _log = default!;
|
||||
|
||||
public event Action<CP14WorkplaceRecipeEntry>? OnCraft;
|
||||
|
||||
private readonly Dictionary<int, LocId> _categories = new();
|
||||
|
||||
private CP14WorkplaceState? _cachedState;
|
||||
private CP14WorkplaceRecipeEntry? _selectedEntry;
|
||||
private string _searchFilter = string.Empty;
|
||||
|
||||
private ISawmill Sawmill { get; init; }
|
||||
|
||||
public CP14WorkplaceWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
Sawmill = _log.GetSawmill("cp14_workplace_window");
|
||||
|
||||
SearchBar.OnTextChanged += OnSearchChanged;
|
||||
CraftButton.OnPressed += OnCraftPressed;
|
||||
OptionCategories.OnItemSelected += OnCategoryItemSelected;
|
||||
}
|
||||
|
||||
public void UpdateRecipesVisibility()
|
||||
{
|
||||
if (_cachedState is null)
|
||||
return;
|
||||
|
||||
CraftsContainer.RemoveAllChildren();
|
||||
|
||||
var recipes = new List<CP14WorkplaceRecipeEntry>();
|
||||
foreach (var entry in _cachedState.Recipes)
|
||||
{
|
||||
if (!_prototype.TryIndex(entry.Recipe, out var indexedEntry))
|
||||
{
|
||||
Sawmill.Error($"No recipe prototype {entry.Recipe} retrieved from cache found");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ProcessSearchFilter(indexedEntry))
|
||||
continue;
|
||||
|
||||
if (!ProcessSearchCategoryFilter(indexedEntry))
|
||||
continue;
|
||||
|
||||
recipes.Add(entry);
|
||||
}
|
||||
|
||||
foreach (var recipe in recipes)
|
||||
{
|
||||
var control = new CP14WorkplaceRecipeControl(recipe);
|
||||
control.OnSelect += RecipeSelect;
|
||||
|
||||
CraftsContainer.AddChild(control);
|
||||
}
|
||||
|
||||
if (_selectedEntry is not null && !recipes.Contains(_selectedEntry.Value))
|
||||
RecipeSelectNull();
|
||||
}
|
||||
|
||||
public void UpdateState(CP14WorkplaceState state)
|
||||
{
|
||||
_cachedState = state;
|
||||
|
||||
_categories.Clear();
|
||||
OptionCategories.Clear();
|
||||
OptionCategories.AddItem(Loc.GetString("cp14-recipe-category-all"), AllCategoryId);
|
||||
|
||||
var categories = new List<LocId>();
|
||||
var count = 0;
|
||||
|
||||
foreach (var recipe in state.Recipes)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSearchChanged(LineEdit.LineEditEventArgs _)
|
||||
{
|
||||
_searchFilter = SearchBar.Text.Trim().ToLowerInvariant();
|
||||
UpdateRecipesVisibility();
|
||||
}
|
||||
|
||||
private bool ProcessSearchFilter(EntityPrototype indexedEntry)
|
||||
{
|
||||
if (_searchFilter == string.Empty)
|
||||
return true;
|
||||
|
||||
return indexedEntry.Name.Contains(_searchFilter);
|
||||
}
|
||||
|
||||
private bool ProcessSearchCategoryFilter(EntityPrototype indexedEntry)
|
||||
{
|
||||
// If we are searching through all categories, we simply skip the current filter
|
||||
if (OptionCategories.SelectedId == AllCategoryId)
|
||||
return true;
|
||||
|
||||
if (!_categories.TryGetValue(OptionCategories.SelectedId, out var selectedCategory))
|
||||
{
|
||||
Sawmill.Error($"Non-existent {OptionCategories.SelectedId} category id selected. Filter skipped");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!indexedEntry.Components.TryGetValue(CP14WorkplaceRecipeComponent.CompName, out var compData) || compData.Component is not CP14WorkplaceRecipeComponent recipeComp)
|
||||
return false;
|
||||
|
||||
if (recipeComp.Category is null)
|
||||
return false;
|
||||
|
||||
return recipeComp.Category == selectedCategory;
|
||||
}
|
||||
|
||||
private void OnCraftPressed(BaseButton.ButtonEventArgs _)
|
||||
{
|
||||
if (_selectedEntry is null)
|
||||
return;
|
||||
|
||||
OnCraft?.Invoke(_selectedEntry.Value);
|
||||
}
|
||||
|
||||
private void OnCategoryItemSelected(OptionButton.ItemSelectedEventArgs obj)
|
||||
{
|
||||
OptionCategories.SelectId(obj.Id);
|
||||
UpdateRecipesVisibility();
|
||||
}
|
||||
|
||||
private void RecipeSelect(CP14WorkplaceRecipeEntry entry, EntityPrototype recipe)
|
||||
{
|
||||
_selectedEntry = entry;
|
||||
|
||||
ItemView.SetPrototype(recipe);
|
||||
ItemName.Text = recipe.Name;
|
||||
ItemDescription.Text = recipe.Description;
|
||||
ItemRequirements.RemoveAllChildren();
|
||||
|
||||
//foreach (var requirement in recipe.Requirements)
|
||||
//{
|
||||
// ItemRequirements.AddChild(new CP14WorkbenchRequirementControl(requirement));
|
||||
//}
|
||||
|
||||
CraftButton.Disabled = !entry.Craftable;
|
||||
}
|
||||
|
||||
private void RecipeSelectNull()
|
||||
{
|
||||
_selectedEntry = null;
|
||||
|
||||
ItemView.SetPrototype(null);
|
||||
ItemName.Text = string.Empty;
|
||||
ItemDescription.Text = string.Empty;
|
||||
ItemRequirements.RemoveAllChildren();
|
||||
CraftButton.Disabled = true;
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server._CP14.Workbench;
|
||||
|
||||
public sealed partial class CP14WorkbenchSystem : CP14SharedWorkbenchSystem
|
||||
public sealed partial class CP14WorkbenchSystem : Shared._CP14.Workplace.CP14SharedWorkbenchSystem
|
||||
{
|
||||
[Dependency] private readonly AudioSystem _audio = default!;
|
||||
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||
|
||||
65
Content.Server/_CP14/Workplace/CP14WorkplaceSystem.cs
Normal file
65
Content.Server/_CP14/Workplace/CP14WorkplaceSystem.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using Content.Shared._CP14.Workplace;
|
||||
using Content.Shared.UserInterface;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.Workplace;
|
||||
|
||||
public sealed partial class CP14WorkplaceSystem : CP14SharedWorkbenchSystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypeReload);
|
||||
SubscribeLocalEvent<CP14WorkplaceComponent, MapInitEvent>(OnMapInit);
|
||||
SubscribeLocalEvent<CP14WorkplaceComponent, BeforeActivatableUIOpenEvent>(OnBeforeUIOpen);
|
||||
}
|
||||
|
||||
private void OnPrototypeReload(PrototypesReloadedEventArgs ev)
|
||||
{
|
||||
if (!ev.WasModified<EntityPrototype>())
|
||||
return;
|
||||
|
||||
var query = EntityQueryEnumerator<CP14WorkplaceComponent>();
|
||||
while (query.MoveNext(out var uid, out var workplace))
|
||||
{
|
||||
CacheWorkplaceRecipes((uid, workplace));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMapInit(Entity<CP14WorkplaceComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
CacheWorkplaceRecipes(ent);
|
||||
}
|
||||
|
||||
private void OnBeforeUIOpen(Entity<CP14WorkplaceComponent> ent, ref BeforeActivatableUIOpenEvent args)
|
||||
{
|
||||
UpdateUIState(ent, args.User);
|
||||
}
|
||||
|
||||
|
||||
private void UpdateUIState(Entity<CP14WorkplaceComponent> entity, EntityUid user)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void CacheWorkplaceRecipes(Entity<CP14WorkplaceComponent> entity)
|
||||
{
|
||||
entity.Comp.CachedRecipes.Clear();
|
||||
|
||||
var allEnts = _proto.EnumeratePrototypes<EntityPrototype>();
|
||||
|
||||
foreach (var recipe in allEnts)
|
||||
{
|
||||
if (!recipe.Components.TryGetComponent(CP14WorkplaceRecipeComponent.CompName, out var compData) || compData is not CP14WorkplaceRecipeComponent recipeComp)
|
||||
continue;
|
||||
|
||||
if (!entity.Comp.Tags.Contains(recipeComp.Tag))
|
||||
continue;
|
||||
|
||||
entity.Comp.CachedRecipes.Add(recipe);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace Content.Shared._CP14.Workplace;
|
||||
|
||||
public abstract partial class CP14SharedWorkbenchSystem : EntitySystem
|
||||
{
|
||||
}
|
||||
24
Content.Shared/_CP14/Workplace/CP14WorkplaceComponent.cs
Normal file
24
Content.Shared/_CP14/Workplace/CP14WorkplaceComponent.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Workplace;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class CP14WorkplaceComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Recipes matching these tags will be available for use on this workplace
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public HashSet<ProtoId<TagPrototype>> Tags = new();
|
||||
|
||||
/// <summary>
|
||||
/// The cached list of recipes available for crafting at this workstation.
|
||||
/// Cached when initializing a workstation or reloading prototypes
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public HashSet<EntProtoId> CachedRecipes = new();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Workplace;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class CP14WorkplaceRecipeComponent : Component
|
||||
{
|
||||
public const string CompName = "CP14WorkplaceRecipe";
|
||||
|
||||
/// <summary>
|
||||
/// Recipes matching these tags will be available for use on this workplace
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public ProtoId<TagPrototype> Tag;
|
||||
|
||||
/// <summary>
|
||||
/// Recipes will be organized by category if LocId matches
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public LocId? Category;
|
||||
}
|
||||
28
Content.Shared/_CP14/Workplace/CP14WorkplaceUI.cs
Normal file
28
Content.Shared/_CP14/Workplace/CP14WorkplaceUI.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.Workplace;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum CP14WorkplaceUiKey
|
||||
{
|
||||
Key,
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CP14WorkplaceCraftMessage(EntProtoId recipe) : BoundUserInterfaceMessage
|
||||
{
|
||||
public readonly EntProtoId Recipe = recipe;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CP14WorkplaceState(List<CP14WorkplaceRecipeEntry> recipes) : BoundUserInterfaceState
|
||||
{
|
||||
public readonly List<CP14WorkplaceRecipeEntry> Recipes = recipes;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public readonly record struct CP14WorkplaceRecipeEntry(
|
||||
EntProtoId Recipe,
|
||||
bool Craftable
|
||||
);
|
||||
@@ -0,0 +1,26 @@
|
||||
- type: entity
|
||||
parent:
|
||||
- BaseStructure
|
||||
id: CP14BaseWorkplace
|
||||
categories: [ ForkFiltered ]
|
||||
abstract: true
|
||||
components:
|
||||
- type: Sprite
|
||||
snapCardinals: true
|
||||
sprite: _CP14/Structures/Furniture/workbench.rsi
|
||||
state: filler
|
||||
- type: Icon
|
||||
sprite: _CP14/Structures/Furniture/workbench.rsi
|
||||
state: filler
|
||||
- type: ActivatableUI
|
||||
key: enum.CP14WorkplaceUiKey.Key
|
||||
requiresComplex: true
|
||||
singleUser: true
|
||||
- type: Climbable
|
||||
- type: Clickable
|
||||
- type: InteractionOutline
|
||||
- type: PlaceableSurface
|
||||
- type: UserInterface
|
||||
interfaces:
|
||||
enum.CP14WorkplaceUiKey.Key:
|
||||
type: CP14WorkplaceBoundUserInterface
|
||||
6
Resources/Prototypes/_CP14/Recipes/Workplace/debug.yml
Normal file
6
Resources/Prototypes/_CP14/Recipes/Workplace/debug.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
- type: entity
|
||||
id: CP14BaseWorkplaceRecipe
|
||||
abstract: true
|
||||
components:
|
||||
- type: CP14WorkplaceRecipe
|
||||
tag: CP14RecipeMeltingFurnace
|
||||
Reference in New Issue
Block a user