* delete skill trees
* Revert "delete skill trees"
This reverts commit 9d7fae73c4.
* learning refactor
* UI tweaks
* sword mastery skill
* telegraphy
* rapier mastery
* research table ui
* finish studing
* polish UI researching
* pyrokinetic
* more skill tree working
* heat adapt
* alchemist and metamagic update
* skill multiple effects support + metamagic bugg manapool
* impossible 😢
* skimitar gaming
* skimidi
* blacksmithing branch
* remove research restrictions
* remove species magic buff
* fix loc
* Update thaumaturgy.yml
* pip
* Delete skill_tree.yml
236 lines
7.1 KiB
C#
236 lines
7.1 KiB
C#
using Content.Client._CP14.Workbench;
|
|
using Content.Shared._CP14.Skill;
|
|
using Content.Shared._CP14.Skill.Prototypes;
|
|
using Content.Shared._CP14.Skill.Restrictions;
|
|
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;
|
|
|
|
namespace Content.Client._CP14.ResearchTable;
|
|
|
|
[GenerateTypedNameReferences]
|
|
public sealed partial class CP14ResearchTableWindow : DefaultWindow
|
|
{
|
|
private const int AllCategoryId = -1;
|
|
|
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
|
[Dependency] private readonly ILogManager _log = default!;
|
|
[Dependency] private readonly IEntityManager _entity = default!;
|
|
|
|
private readonly SpriteSystem _sprite;
|
|
private readonly CP14SharedSkillSystem _skillSystem;
|
|
|
|
public event Action<CP14ResearchUiEntry>? OnResearch;
|
|
|
|
private readonly Dictionary<int, LocId> _categories = new();
|
|
|
|
private CP14ResearchTableUiState? _cachedState;
|
|
private CP14ResearchUiEntry? _selectedEntry;
|
|
private string _searchFilter = string.Empty;
|
|
|
|
private ISawmill Sawmill { get; init; }
|
|
|
|
public CP14ResearchTableWindow()
|
|
{
|
|
RobustXamlLoader.Load(this);
|
|
IoCManager.InjectDependencies(this);
|
|
|
|
_sprite = _entity.System<SpriteSystem>();
|
|
_skillSystem = _entity.System<CP14SharedSkillSystem>();
|
|
|
|
Sawmill = _log.GetSawmill("cp14_research_table_window");
|
|
|
|
SearchBar.OnTextChanged += OnSearchChanged;
|
|
CraftButton.OnPressed += OnCraftPressed;
|
|
OptionCategories.OnItemSelected += OnCategoryItemSelected;
|
|
}
|
|
|
|
public void UpdateRecipesVisibility()
|
|
{
|
|
if (_cachedState is null)
|
|
return;
|
|
|
|
CraftsContainer.RemoveAllChildren();
|
|
|
|
var recipes = new List<CP14ResearchUiEntry>();
|
|
foreach (var entry in _cachedState.Skills)
|
|
{
|
|
if (!_prototype.TryIndex(entry.ProtoId, out var indexedEntry))
|
|
{
|
|
Sawmill.Error($"No recipe prototype {entry.ProtoId} retrieved from cache found");
|
|
continue;
|
|
}
|
|
|
|
if (!ProcessSearchFilter(indexedEntry))
|
|
continue;
|
|
|
|
if (!ProcessSearchCategoryFilter(indexedEntry))
|
|
continue;
|
|
|
|
recipes.Add(entry);
|
|
}
|
|
|
|
recipes.Sort(CP14ResearchUiEntry.CompareTo);
|
|
|
|
foreach (var recipe in recipes)
|
|
{
|
|
var control = new CP14ResearchRecipeControl(recipe);
|
|
control.OnResearch += RecipeSelect;
|
|
|
|
CraftsContainer.AddChild(control);
|
|
}
|
|
|
|
if (_selectedEntry is not null && !recipes.Contains(_selectedEntry.Value))
|
|
RecipeSelectNull();
|
|
}
|
|
|
|
public void UpdateState(CP14ResearchTableUiState 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 skill in recipesState.Skills)
|
|
{
|
|
if (!_prototype.TryIndex(skill.ProtoId, out var indexedSkill))
|
|
continue;
|
|
|
|
if (!_prototype.TryIndex(indexedSkill.Tree, out var indexedTree))
|
|
continue;
|
|
|
|
if (categories.Contains(indexedTree.Name))
|
|
continue;
|
|
|
|
categories.Add(indexedTree.Name);
|
|
}
|
|
|
|
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;
|
|
|
|
OnResearch?.Invoke(_selectedEntry.Value);
|
|
}
|
|
|
|
private void OnCategoryItemSelected(OptionButton.ItemSelectedEventArgs obj)
|
|
{
|
|
OptionCategories.SelectId(obj.Id);
|
|
UpdateRecipesVisibility();
|
|
}
|
|
|
|
private bool ProcessSearchFilter(CP14SkillPrototype indexedEntry)
|
|
{
|
|
if (_searchFilter == string.Empty)
|
|
return true;
|
|
|
|
return Loc.GetString(_skillSystem.GetSkillName(indexedEntry)).Contains(_searchFilter);
|
|
}
|
|
|
|
private bool ProcessSearchCategoryFilter(CP14SkillPrototype 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 (!_prototype.TryIndex(indexedEntry.Tree, out var indexedTree))
|
|
{
|
|
Sawmill.Error($"Non-existent {indexedEntry.Tree} category prototype id. Filter skipped");
|
|
return true;
|
|
}
|
|
|
|
return indexedTree.Name == selectedCategory;
|
|
}
|
|
|
|
private void RecipeSelect(CP14ResearchTableUiState recipesState)
|
|
{
|
|
foreach (var skill in recipesState.Skills)
|
|
{
|
|
RecipeSelect(skill, _prototype.Index(skill.ProtoId));
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void RecipeSelect(CP14ResearchUiEntry cachedEntry)
|
|
{
|
|
if (_cachedState is null)
|
|
return;
|
|
|
|
if (_cachedState.Skills.Contains(cachedEntry))
|
|
{
|
|
Sawmill.Warning($"The selected cache option {cachedEntry} isn't found in recipes");
|
|
return;
|
|
}
|
|
|
|
RecipeSelect(cachedEntry, _prototype.Index(cachedEntry.ProtoId));
|
|
}
|
|
|
|
private void RecipeSelect(CP14ResearchUiEntry entry, CP14SkillPrototype skill)
|
|
{
|
|
_selectedEntry = entry;
|
|
|
|
ItemView.Texture = _sprite.Frame0(skill.Icon);
|
|
ItemName.Text = _skillSystem.GetSkillName(skill);
|
|
ItemDescription.Text = _skillSystem.GetSkillDescription(skill);
|
|
ItemRequirements.RemoveAllChildren();
|
|
|
|
foreach (var restriction in skill.Restrictions)
|
|
{
|
|
switch (restriction)
|
|
{
|
|
case Researched researched:
|
|
foreach (var requirement in researched.Requirements)
|
|
{
|
|
ItemRequirements.AddChild(new CP14WorkbenchRequirementControl(requirement));
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
CraftButton.Disabled = !entry.Craftable;
|
|
}
|
|
|
|
private void RecipeSelectNull()
|
|
{
|
|
_selectedEntry = null;
|
|
|
|
ItemView.Texture = null;
|
|
ItemName.Text = string.Empty;
|
|
ItemDescription.Text = string.Empty;
|
|
ItemRequirements.RemoveAllChildren();
|
|
CraftButton.Disabled = true;
|
|
}
|
|
}
|