Tool windows: - Every editor (scenario, scene builder, map, interactive objects, lighting, catalog export) is rebuilt on the interface ToolWindow chrome and the denser ToolTheme: header with title/close, status bar, Ctrl+S, dirty-state confirmation. - Shared building blocks in src/Common: ToolUi (rows, buttons, sections), CollapsibleSection, FilteredList, ModFileSelector, DragHandle and BackgroundCanvas (scene background with pan/zoom). - The map, interactive and light editors draw on canvases (MapEditorCanvas, InteractiveEditorCanvas, LightEditorCanvas) instead of one Control "handle" node per object; the *Handle classes are removed. - Scenario editor: tab data model (TabData), automatic graph layout (ScenarioGraphLayout), file tree/info/thumbnail panel updates. - Services: ModFileService (mod file listing and writing), SceneBackgroundService; MapFileService/ModResourceService follow. - Catalog export: per-language name/description editing. - Locale (en/ru) regrouped under tools/*; unused keys removed. Novel Editor: - collections/novel_editor.json: a "game" whose entry scene is an authoring workspace over the novel engine and the story content. - NovelEditorHub (scenes/novel_editor_hub.tscn) lists every installed tool through IToolProvider.AddMenuButton; ToolsInitializer registers it as the logical scene "novel_editor".
46 lines
1.7 KiB
C#
46 lines
1.7 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text.Json;
|
|
using Cthangover.Core.Mods;
|
|
using Cthangover.Mods.Map;
|
|
using Cthangover.Core.Utils;
|
|
|
|
namespace Cthangover.Tools.Services
|
|
{
|
|
/// <summary>
|
|
/// (De)serialisation of world map zone files (<c>mods/<mod>/map/*.json</c>)
|
|
/// for the map editor. File access itself goes through
|
|
/// <see cref="ModFileService"/>.
|
|
/// </summary>
|
|
public static class MapFileService
|
|
{
|
|
/// <summary>Folder of map zone files inside a mod.</summary>
|
|
public const string MapDir = "map";
|
|
|
|
/// <summary>
|
|
/// Parses the standard <c>{"Items": [...]}</c> envelope into zones.
|
|
/// Throws <see cref="JsonException"/> on malformed JSON so the editor
|
|
/// can show the error instead of silently opening an empty map.
|
|
/// </summary>
|
|
public static List<MapZone> ParseZones(string json)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(json))
|
|
return new List<MapZone>();
|
|
|
|
var data = JsonSerializer.Deserialize<FileData<MapZone>>(json, JsonOptionsProvider.ReadOptions);
|
|
return data?.Items ?? new List<MapZone>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Serialises zones into the standard envelope with indentation and
|
|
/// without null fields, so hand-editing the result stays pleasant and
|
|
/// optional properties such as <c>label_pos</c> only appear when used.
|
|
/// </summary>
|
|
public static string BuildJson(IEnumerable<MapZone> zones)
|
|
{
|
|
var data = new FileData<MapZone> { Items = zones?.ToList() ?? new List<MapZone>() };
|
|
return JsonSerializer.Serialize(data, JsonOptionsProvider.WriteIndentedIgnoreNullOptions);
|
|
}
|
|
}
|
|
}
|