Item editor: items of a mod in a searchable list, name/description in every language, price, icon, types, use action; GUI suite items_editor_edit

This commit is contained in:
cthangover committed 2026-10-23 19:09:45 +02:00
commit 138b0f689d
11 files changed
+423

No files matched your search

+20
View File
@@ -0,0 +1,20 @@
using Cthangover.Core.UI.Tool;
namespace Cthangover.Tools.ItemsEditor
{
/// <summary>In-game toolbar button of the item editor, so an item can be fixed while playing.</summary>
public class ItemEditorToolBoxButton : IToolBoxButton
{
/// <summary>Matches <see cref="ItemEditorToolProvider.Id"/>.</summary>
public string ToolId => "items_editor";
/// <summary>No icon: the button shows its label.</summary>
public string IconPath => "";
/// <summary>Button label key.</summary>
public string LocaleKey => "tools/items_editor/title";
/// <summary>Always shown.</summary>
public bool IsVisible() => true;
}
}
+26
View File
@@ -0,0 +1,26 @@
using Cthangover.Core.UI.Tool;
using Cthangover.Mods.Interface.Tool;
using Godot;
namespace Cthangover.Tools.ItemsEditor
{
/// <summary>
/// Registers the item editor as a tool: it appears in the main menu's tool
/// block, the novel editor hub and (with <see cref="ItemEditorToolBoxButton"/>)
/// the in-game toolbar.
/// </summary>
public class ItemEditorToolProvider : IToolProvider
{
/// <summary>Tool id.</summary>
public string Id => "items_editor";
/// <summary>Display name key.</summary>
public string LocaleKey => "tools/items_editor/title";
/// <summary>Creates the window.</summary>
public Window CreateWindow() => new ItemEditorWindow();
/// <summary>Adds the launcher button to the main menu's tool block.</summary>
public void AddMenuButton(Container container) => ToolMenuButton.Attach(container, this);
}
}
+52
View File
@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Nodes;
using Cthangover.Core.Factories.Impls;
using Cthangover.Core.Items;
using Cthangover.Tools.EntityEditor;
namespace Cthangover.Tools.ItemsEditor
{
/// <summary>
/// Editor of items (<c>"Kind": "item"</c>, <see cref="ItemInfo"/>): name and
/// description in every language of the mod, price, picture in the
/// <c>items</c> group (the inventory icon), item types and the use action
/// offered from the actions the loaded mods register. Fields of other mods'
/// item C# (<c>heal</c>, <c>verb</c>…) are "other fields" of the base window.
/// New items go to <c>items/&lt;mod&gt;.json</c>.
/// </summary>
public partial class ItemEditorWindow : EntityEditorWindow
{
/// <summary>Builds the window and opens the first mod that has items.</summary>
public ItemEditorWindow() : base("tools/items_editor/title", "item", "items", Fields())
{
}
private static List<EntityField> Fields() => new()
{
new EntityField { Key = "Name", LabelKey = "tools/items_editor/name", Kind = EntityFieldKind.LocaleText, KeyPattern = "items/{0}/name" },
new EntityField { Key = "Description", LabelKey = "tools/items_editor/description", Kind = EntityFieldKind.LocaleText, KeyPattern = "items/{0}/desc" },
new EntityField { Key = "Cost", LabelKey = "tools/items_editor/cost", TooltipKey = "tools/items_editor/cost_tip", Kind = EntityFieldKind.Integer },
new EntityField { Key = "Sprite", LabelKey = "tools/items_editor/sprite", TooltipKey = "tools/items_editor/sprite_tip", Kind = EntityFieldKind.Picture, Group = "items" },
new EntityField { Key = "ItemType", LabelKey = "tools/items_editor/type", TooltipKey = "tools/items_editor/type_tip", Kind = EntityFieldKind.Flags, Options = ItemTypes },
new EntityField { Key = "ItemAction", LabelKey = "tools/items_editor/action", TooltipKey = "tools/items_editor/action_tip", Kind = EntityFieldKind.Choice, Options = Actions }
};
private static IEnumerable<string> ItemTypes() => Enum.GetNames(typeof(ItemType)).Where(n => n != nameof(ItemType.None));
private static IEnumerable<string> Actions() => new[] { "null" }.Concat(ItemActionFactory.Instance.Ids.OrderBy(id => id, StringComparer.Ordinal));
/// <summary>A resource worth one coin with no use action; the picture is the author's to pick.</summary>
protected override JsonObject CreateEntity(string id) => new()
{
["Id"] = id,
["Cost"] = 1,
["ItemType"] = nameof(ItemType.Resource),
["ItemAction"] = "null"
};
/// <summary><c>&lt;mod&gt;/new_item</c>, the folder-style ids items use.</summary>
protected override string NewIdBase(string mod) => mod + "/new_item";
}
}