Bugfixes + QoL (#1218)

* fix keyring

* fix #1209

* fix #1116

* fix water, test reenable ambient loop

* recipe categories in workbecnhes

* Update CP14StoreWindow.xaml

* refactor: review

* Update CP14WorkbenchWindow.xaml.cs

* Update SharedCP14MagicEnergySystem.cs

* categorizize all recipes + some UI fix

* Update round_end.yml

---------

Co-authored-by: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com>
This commit is contained in:
Ed
2025-04-25 13:39:20 +03:00
committed by GitHub
parent 4bb614981f
commit 62cdf9e1c5
28 changed files with 416 additions and 86 deletions

View File

@@ -43,14 +43,11 @@ public sealed partial class ContentAudioSystem
private void CP14UpdateAmbientLoops()
{
return; //DISABLED UNTIL CLIENT ERROR SPAM FIXED
if (_timing.CurTime <= _nextUpdateTime)
return;
_nextUpdateTime = _timing.CurTime + _updateFrequency;
if (_state.CurrentState is not GameplayState)
return;

View File

@@ -170,7 +170,6 @@ public sealed class CP14ClientModularCraftSystem : CP14SharedModularCraftSystem
var defaultKey = $"cp14-modular-clothing-layer-{args.Slot}";
var counterPart = 0;
foreach (var part in start.Comp.InstalledParts)
{
var indexedPart = _proto.Index(part);
@@ -180,7 +179,7 @@ public sealed class CP14ClientModularCraftSystem : CP14SharedModularCraftSystem
var i = 0;
foreach (var layer in layers)
{
var key = $"{defaultKey}-{counterPart}-{i}";
var key = $"{defaultKey}-{indexedPart.ID}-{i}";
args.Layers.Add((key, layer));
i++;
}
@@ -210,7 +209,7 @@ public sealed class CP14ClientModularCraftSystem : CP14SharedModularCraftSystem
Color = indexedPart.Color,
};
var key = $"{defaultKey}-{counterPart}-default";
var key = $"{defaultKey}-{indexedPart.ID}-default";
args.Layers.Add((key, defaultLayer));
}
}

View File

@@ -7,7 +7,7 @@
<BoxContainer Orientation="Horizontal">
<BoxContainer HorizontalExpand="True" VerticalExpand="True" Orientation="Horizontal">
<!-- Product list (left side UI) -->
<TabContainer SizeFlagsStretchRatio="0.5" Name="Tabs" HorizontalExpand="True" VerticalExpand="True" MinSize="0 200">
<TabContainer MinWidth="400" Name="Tabs" HorizontalExpand="True" VerticalExpand="True" MinSize="0 200">
<ScrollContainer HorizontalExpand="True" VerticalExpand="True" MinSize="0 200">
<BoxContainer Name="BuyProductsContainer" Orientation="Vertical" HorizontalExpand="True"/>
</ScrollContainer>
@@ -16,7 +16,7 @@
</ScrollContainer>
</TabContainer>
<!-- Station trading data (right side UI) -->
<BoxContainer SizeFlagsStretchRatio="0.5" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" Margin="0 0 10 0">
<BoxContainer MinWidth="400" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" Margin="0 0 10 0">
<controls:StripeBack>
<PanelContainer>
<Label Text="{Loc 'cp14-store-ui-order'}" Align="Center" Margin="0 5 0 3"/>

View File

@@ -12,9 +12,6 @@ public sealed class CP14WorkbenchBoundUserInterface : BoundUserInterface
{
private CP14WorkbenchWindow? _window;
[ViewVariables]
private string _search = string.Empty;
public CP14WorkbenchBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}
@@ -26,12 +23,6 @@ public sealed class CP14WorkbenchBoundUserInterface : BoundUserInterface
_window = this.CreateWindow<CP14WorkbenchWindow>();
_window.OnCraft += entry => SendMessage(new CP14WorkbenchUiCraftMessage(entry.ProtoId));
_window.OnTextUpdated += search =>
{
_search = search.Trim().ToLowerInvariant();
_window.UpdateFilter(_search);
};
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -41,7 +32,7 @@ public sealed class CP14WorkbenchBoundUserInterface : BoundUserInterface
switch (state)
{
case CP14WorkbenchUiRecipesState recipesState:
_window?.UpdateRecipes(recipesState, _search);
_window?.UpdateState(recipesState);
break;
}
}

View File

@@ -8,9 +8,12 @@
<!-- Main -->
<BoxContainer HorizontalExpand="True" VerticalExpand="True" Orientation="Horizontal">
<!-- Product list (left side UI) -->
<BoxContainer SizeFlagsStretchRatio="0.5" HorizontalExpand="True" Orientation="Vertical" Margin="0 0 10 0">
<!-- Search Bar -->
<LineEdit Name="SearchBar" Margin="4" PlaceHolder="Search" HorizontalExpand="True" />
<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" />
@@ -18,7 +21,7 @@
</BoxContainer>
<!-- Craft view (right side UI) -->
<BoxContainer SizeFlagsStretchRatio="0.5" Orientation="Vertical" HorizontalExpand="True"
<BoxContainer MinWidth="350" Orientation="Vertical" HorizontalExpand="True"
VerticalExpand="True">
<PanelContainer HorizontalExpand="True" VerticalExpand="True">
<!-- Background -->

View File

@@ -6,7 +6,7 @@
using Content.Shared._CP14.Workbench;
using Content.Shared._CP14.Workbench.Prototypes;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
@@ -16,86 +16,167 @@ namespace Content.Client._CP14.Workbench;
[GenerateTypedNameReferences]
public sealed partial class CP14WorkbenchWindow : DefaultWindow
{
[Dependency] private readonly IEntityManager _entity = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
private const int AllCategoryId = -1;
private CP14WorkbenchUiRecipesState? _cachedState;
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly ILogManager _log = default!;
public event Action<CP14WorkbenchUiRecipesEntry>? OnCraft;
public event Action<string>? OnTextUpdated;
private readonly Dictionary<int, LocId> _categories = new();
private CP14WorkbenchUiRecipesState? _cachedState;
private CP14WorkbenchUiRecipesEntry? _selectedEntry;
private string _searchFilter = string.Empty;
private ISawmill Sawmill { get; init; }
public CP14WorkbenchWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
SearchBar.OnTextChanged += _ =>
{
OnTextUpdated?.Invoke(SearchBar.Text);
};
CraftButton.OnPressed += _ =>
{
if (_selectedEntry is null)
return;
Sawmill = _log.GetSawmill("cp14_workbench_window");
OnCraft?.Invoke(_selectedEntry.Value);
};
SearchBar.OnTextChanged += OnSearchChanged;
CraftButton.OnPressed += OnCraftPressed;
OptionCategories.OnItemSelected += OnCategoryItemSelected;
}
public void UpdateFilter(string? search)
public void UpdateRecipesVisibility()
{
if (_cachedState is null)
return;
UpdateRecipes(_cachedState, search);
}
public void UpdateRecipes(CP14WorkbenchUiRecipesState recipesState, string? search = null)
{
_cachedState = recipesState;
CraftsContainer.RemoveAllChildren();
List<CP14WorkbenchUiRecipesEntry> uncraftableList = new();
foreach (var entry in recipesState.Recipes)
var recipes = new List<CP14WorkbenchUiRecipesEntry>();
foreach (var entry in _cachedState.Recipes)
{
if (search is not null && search != "")
if (!_prototype.TryIndex(entry.ProtoId, out var indexedEntry))
{
if (!_prototype.TryIndex(entry.ProtoId, out var indexedEntry))
continue;
if (!_prototype.TryIndex(indexedEntry.Result, out var indexedResult))
continue;
if (!indexedResult.Name.Contains(search))
continue;
Sawmill.Error($"No recipe prototype {entry.ProtoId} retrieved from cache found");
continue;
}
if (entry.Craftable)
{
var control = new CP14WorkbenchRecipeControl(entry);
control.OnSelect += RecipeSelect;
CraftsContainer.AddChild(control);
}
else
uncraftableList.Add(entry);
if (!ProcessSearchFilter(entry, indexedEntry))
continue;
if (!ProcessSearchCategoryFilter(indexedEntry))
continue;
recipes.Add(entry);
}
foreach (var entry in uncraftableList)
recipes.Sort(CP14WorkbenchUiRecipesEntry.CompareTo);
foreach (var recipe in recipes)
{
var control = new CP14WorkbenchRecipeControl(entry);
var control = new CP14WorkbenchRecipeControl(recipe);
control.OnSelect += RecipeSelect;
CraftsContainer.AddChild(control);
}
if (_selectedEntry is not null && recipesState.Recipes.Contains(_selectedEntry.Value))
RecipeSelectNull();
}
public void UpdateState(CP14WorkbenchUiRecipesState recipesState)
{
_cachedState = recipesState;
_categories.Clear();
OptionCategories.Clear();
OptionCategories.AddItem(Loc.GetString("cp14-recipe-category-all"), AllCategoryId);
var categories = new List<LocId>();
var count = 0;
foreach (var entry in recipesState.Recipes)
{
RecipeSelect(_selectedEntry.Value, _prototype.Index(_selectedEntry.Value.ProtoId));
return;
if (!_prototype.TryIndex(entry.ProtoId, out var indexedEntry))
continue;
// Populate categories
if (indexedEntry.Category is null)
continue;
if (!_prototype.TryIndex(indexedEntry.Category, out var indexedCategory))
continue;
if (categories.Contains(indexedCategory.Name))
continue;
categories.Add(indexedCategory.Name);
}
RecipeSelect(recipesState);
categories.Sort((a, b) => string.Compare(Loc.GetString(a), Loc.GetString(b), StringComparison.Ordinal));
foreach (var category in categories)
{
OptionCategories.AddItem(Loc.GetString(category), count);
_categories.Add(count, category);
count++;
}
UpdateRecipesVisibility();
}
private void OnSearchChanged(LineEdit.LineEditEventArgs _)
{
_searchFilter = SearchBar.Text.Trim().ToLowerInvariant();
UpdateRecipesVisibility();
}
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 bool ProcessSearchFilter(CP14WorkbenchUiRecipesEntry entry, CP14WorkbenchRecipePrototype indexedEntry)
{
if (_searchFilter == string.Empty)
return true;
// Skip the iteration, because the desired result does not match the filter
if (_prototype.TryIndex(indexedEntry.Result, out var indexedResult))
return indexedResult.Name.Contains(_searchFilter);
Sawmill.Error($"No result entity prototype {entry.ProtoId} retrieved from cache found");
return false;
}
private bool ProcessSearchCategoryFilter(CP14WorkbenchRecipePrototype 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.Category is null)
return false;
if (!_prototype.TryIndex(indexedEntry.Category, out var indexedCategory))
{
Sawmill.Error($"Non-existent {indexedEntry.Category} category prototype id. Filter skipped");
return true;
}
return indexedCategory.Name == selectedCategory;
}
private void RecipeSelect(CP14WorkbenchUiRecipesState recipesState)
@@ -107,17 +188,32 @@ public sealed partial class CP14WorkbenchWindow : DefaultWindow
}
}
private void RecipeSelect(CP14WorkbenchUiRecipesEntry cachedEntry)
{
if (_cachedState is null)
return;
if (_cachedState.Recipes.Contains(cachedEntry))
{
Sawmill.Warning($"The selected cache option {cachedEntry} isn't found in recipes");
return;
}
RecipeSelect(cachedEntry, _prototype.Index(cachedEntry.ProtoId));
}
private void RecipeSelect(CP14WorkbenchUiRecipesEntry entry, CP14WorkbenchRecipePrototype recipe)
{
_selectedEntry = entry;
var result = _prototype.Index(recipe.Result);
// TODO: Make it through the localization?
var counter = recipe.ResultCount > 1 ? $" x{recipe.ResultCount}" : string.Empty;
ItemView.SetPrototype(recipe.Result);
var counter = recipe.ResultCount > 1 ? $" x{recipe.ResultCount}" : "";
ItemName.Text = result.Name + counter;
ItemDescription.Text = result.Description;
ItemRequirements.RemoveAllChildren();
foreach (var requirement in recipe.Requirements)
@@ -127,4 +223,14 @@ public sealed partial class CP14WorkbenchWindow : DefaultWindow
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;
}
}