Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Localizable craftmenu #32339

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 51 additions & 11 deletions Content.Client/Construction/ConstructionSystem.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Client.Popups;
using Content.Shared.Construction;
using Content.Shared.Construction.Prototypes;
using Content.Shared.Construction.Steps;
using Content.Shared.Examine;
using Content.Shared.Input;
using Content.Shared.Interaction;
using Content.Shared.Prototypes;
using Content.Shared.Wall;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Client.Utility;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;

namespace Content.Client.Construction
{
Expand All @@ -32,14 +35,20 @@ public sealed class ConstructionSystem : SharedConstructionSystem

private readonly Dictionary<int, EntityUid> _ghosts = new();
private readonly Dictionary<string, ConstructionGuide> _guideCache = new();
private Dictionary<string, string>? _recipeMetadataCache;

public bool CraftingEnabled { get; private set; }

public bool IsRecipesCacheWarmed { get; private set; }

/// <inheritdoc />
public override void Initialize()
{
base.Initialize();

SubscribeNetworkEvent<ResponseConstructionRecipes>(OnResponseConstructionRecipes);
RaiseNetworkEvent(new RequestConstructionRecipes());

UpdatesOutsidePrediction = true;
SubscribeLocalEvent<LocalPlayerAttachedEvent>(HandlePlayerAttached);
SubscribeNetworkEvent<AckStructureConstructionMessage>(HandleAckStructure);
Expand All @@ -57,6 +66,45 @@ public override void Initialize()
SubscribeLocalEvent<ConstructionGhostComponent, ExaminedEvent>(HandleConstructionGhostExamined);
}

public event EventHandler? OnConstructionRecipesUpdated;
private void OnResponseConstructionRecipes(ResponseConstructionRecipes ev)
{
if (_recipeMetadataCache is null)
{
_recipeMetadataCache = new();

foreach (var (constructionProtoId, targetProtoId) in ev.Metadata)
{
if (!_prototypeManager.TryIndex(constructionProtoId, out ConstructionPrototype? recipe))
continue;

if (!_prototypeManager.TryIndex(targetProtoId, out var proto))
continue;

var name = recipe.NameLocId.HasValue ? Loc.GetString(recipe.NameLocId) : proto.Name;
var desc = recipe.DescLocId.HasValue ? Loc.GetString(recipe.DescLocId) : proto.Description;

recipe.Name = name;
recipe.Description = desc;

_recipeMetadataCache.Add(constructionProtoId, targetProtoId);
}

IsRecipesCacheWarmed = true;
}

OnConstructionRecipesUpdated?.Invoke(this, EventArgs.Empty);
}

public bool TryGetRecipePrototype(string constructionProtoId, [NotNullWhen(true)] out string? targetProtoId)
{
if (_recipeMetadataCache is not null && _recipeMetadataCache.TryGetValue(constructionProtoId, out targetProtoId))
return true;

targetProtoId = null;
return false;
}

private void OnConstructionGuideReceived(ResponseConstructionGuide ev)
{
_guideCache[ev.ConstructionId] = ev.Guide;
Expand Down Expand Up @@ -89,7 +137,7 @@ private void HandleConstructionGhostExamined(EntityUid uid, ConstructionGhostCom
{
args.PushMarkup(Loc.GetString(
"construction-ghost-examine-message",
("name", component.Prototype.Name)));
("name", component.Prototype.Name!)));

if (!_prototypeManager.TryIndex(component.Prototype.Graph, out ConstructionGraphPrototype? graph))
return;
Expand Down Expand Up @@ -210,14 +258,6 @@ public bool TrySpawnGhost(
var sprite = EntityManager.GetComponent<SpriteComponent>(ghost.Value);
sprite.Color = new Color(48, 255, 48, 128);

for (int i = 0; i < prototype.Layers.Count; i++)
{
sprite.AddBlankLayer(i); // There is no way to actually check if this already exists, so we blindly insert a new one
sprite.LayerSetSprite(i, prototype.Layers[i]);
sprite.LayerSetShader(i, "unshaded");
sprite.LayerSetVisible(i, true);
}

if (prototype.CanBuildInImpassable)
EnsureComp<WallMountComponent>(ghost.Value).Arc = new(Math.Tau);

Expand Down
7 changes: 4 additions & 3 deletions Content.Client/Construction/UI/ConstructionMenu.xaml
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
<DefaultWindow xmlns="https://spacestation14.io">
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.4" Margin="0 0 5 0">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="0 0 0 5">
<LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True"/>
<OptionButton Name="OptionCategories" Access="Public" MinSize="130 0"/>
</BoxContainer>
<ItemList Name="Recipes" Access="Public" SelectMode="Single" VerticalExpand="True"/>
<controls:ListContainer Name="Recipes" Access="Public" Group="True" Toggle="True" VerticalExpand="True" />
</BoxContainer>
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.6">
<Button Name="FavoriteButton" Visible="false" HorizontalExpand="False"
HorizontalAlignment="Right" Margin="0 0 0 15"/>
<Control>
<BoxContainer Orientation="Vertical" HorizontalExpand="True" Margin="0 0 0 5">
<BoxContainer Orientation="Horizontal" Align="Center">
<TextureRect Name="TargetTexture" HorizontalAlignment="Right" Stretch="Keep" Margin="0 0 10 0"/>
<EntityPrototypeView Name="TargetTexture" HorizontalAlignment="Right" Stretch="Fill" Margin="0 0 10 0"/>
<BoxContainer Orientation="Vertical">
<RichTextLabel Name="TargetName"/>
<RichTextLabel Name="TargetDesc"/>
Expand Down
53 changes: 44 additions & 9 deletions Content.Client/Construction/UI/ConstructionMenu.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Numerics;
using Content.Client.UserInterface.Controls;
using Content.Shared.Construction.Prototypes;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
Expand All @@ -8,6 +10,7 @@
using Robust.Shared.Graphics;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Prototypes;


namespace Content.Client.Construction.UI
Expand All @@ -27,18 +30,18 @@ public interface IConstructionMenuView : IDisposable
bool EraseButtonPressed { get; set; }
bool BuildButtonPressed { get; set; }

ItemList Recipes { get; }
ListContainer Recipes { get; }
ItemList RecipeStepList { get; }

event EventHandler<(string search, string catagory)> PopulateRecipes;
event EventHandler<ItemList.Item?> RecipeSelected;
event EventHandler<ConstructionMenu.ConstructionMenuListData?> RecipeSelected;
event EventHandler RecipeFavorited;
event EventHandler<bool> BuildButtonToggled;
event EventHandler<bool> EraseButtonToggled;
event EventHandler ClearAllGhosts;

void ClearRecipeInfo();
void SetRecipeInfo(string name, string description, Texture iconTexture, bool isItem, bool isFavorite);
void SetRecipeInfo(string name, string description, EntityPrototype? targetPrototype, bool isItem, bool isFavorite);
void ResetPlacement();

#region Window Control
Expand Down Expand Up @@ -82,8 +85,38 @@ public ConstructionMenu()
Title = Loc.GetString("construction-menu-title");

BuildButton.Text = Loc.GetString("construction-menu-place-ghost");
Recipes.OnItemSelected += obj => RecipeSelected?.Invoke(this, obj.ItemList[obj.ItemIndex]);
Recipes.OnItemDeselected += _ => RecipeSelected?.Invoke(this, null);
Recipes.ItemPressed += (_, data) => RecipeSelected?.Invoke(this, data as ConstructionMenuListData);
Recipes.NoItemSelected += () => RecipeSelected?.Invoke(this, null);
Recipes.GenerateItem += (data, button) =>
{
if (data is not ConstructionMenuListData (var prototype, var targetPrototype))
return;

var entProtoView = new EntityPrototypeView()
{
SetSize = new(32f),
Stretch = SpriteView.StretchMode.Fill,
Scale = new(2),
Margin = new(0, 2),
};
entProtoView.SetPrototype(targetPrototype);

var label = new Label()
{
Text = prototype.Suffix && targetPrototype.EditorSuffix is not null
? $"{prototype.Name} [{targetPrototype.EditorSuffix.ToLower()}]"
: prototype.Name,
Margin = new(5, 0),
};

var box = new BoxContainer();
box.AddChild(entProtoView);
box.AddChild(label);

button.AddChild(box);
button.ToolTip = prototype.Description;
button.AddStyleClass(ListContainer.StyleClassListContainerButton);
};

SearchBar.OnTextChanged += _ =>
PopulateRecipes?.Invoke(this, (SearchBar.Text, Categories[OptionCategories.SelectedId]));
Expand All @@ -106,7 +139,7 @@ public ConstructionMenu()

public event EventHandler? ClearAllGhosts;
public event EventHandler<(string search, string catagory)>? PopulateRecipes;
public event EventHandler<ItemList.Item?>? RecipeSelected;
public event EventHandler<ConstructionMenuListData?>? RecipeSelected;
public event EventHandler? RecipeFavorited;
public event EventHandler<bool>? BuildButtonToggled;
public event EventHandler<bool>? EraseButtonToggled;
Expand All @@ -118,13 +151,13 @@ public void ResetPlacement()
}

public void SetRecipeInfo(
string name, string description, Texture iconTexture, bool isItem, bool isFavorite)
string name, string description, EntityPrototype? targetPrototype, bool isItem, bool isFavorite)
{
BuildButton.Disabled = false;
BuildButton.Text = Loc.GetString(isItem ? "construction-menu-place-ghost" : "construction-menu-craft");
TargetName.SetMessage(name);
TargetDesc.SetMessage(description);
TargetTexture.Texture = iconTexture;
TargetTexture.SetPrototype(targetPrototype?.ID);
FavoriteButton.Visible = true;
FavoriteButton.Text = Loc.GetString(
isFavorite ? "construction-add-favorite-button" : "construction-remove-from-favorite-button");
Expand All @@ -135,9 +168,11 @@ public void ClearRecipeInfo()
BuildButton.Disabled = true;
TargetName.SetMessage(string.Empty);
TargetDesc.SetMessage(string.Empty);
TargetTexture.Texture = null;
TargetTexture.SetPrototype(null);
FavoriteButton.Visible = false;
RecipeStepList.Clear();
}

public sealed record ConstructionMenuListData(ConstructionPrototype Prototype, EntityPrototype TargetPrototype) : ListData;
}
}
Loading