Compare commits

..
2 Commits
5 changed files with 68 additions and 11 deletions

No files matched your search

+1 -1
View File
@@ -19,7 +19,7 @@ tools/rpg_editor/redo = Redo
tools/rpg_editor/redo_tip = Redo (Ctrl+Y) tools/rpg_editor/redo_tip = Redo (Ctrl+Y)
tools/rpg_editor/play = Play tools/rpg_editor/play = Play
tools/rpg_editor/play_tip = Save and walk the map from its spawn in the running game tools/rpg_editor/play_tip = Save and walk the map from its spawn in the running game
tools/rpg_editor/play_no_scene = Scene "{0}" is not loaded yet: reload the mods (Ctrl+Shift+R) after creating a map. tools/rpg_editor/play_no_scene = The game does not know scene "{0}": check scenes/{0}.json in the map's mod.
tools/rpg_editor/scene_created = scene {0} created tools/rpg_editor/scene_created = scene {0} created
tools/rpg_editor/section_palette = Palette tools/rpg_editor/section_palette = Palette
tools/rpg_editor/section_map = Map tools/rpg_editor/section_map = Map
+1 -1
View File
@@ -19,7 +19,7 @@ tools/rpg_editor/redo = Вернуть
tools/rpg_editor/redo_tip = Вернуть отменённое (Ctrl+Y) tools/rpg_editor/redo_tip = Вернуть отменённое (Ctrl+Y)
tools/rpg_editor/play = Играть tools/rpg_editor/play = Играть
tools/rpg_editor/play_tip = Сохранить и пройтись по карте от точки появления в запущенной игре tools/rpg_editor/play_tip = Сохранить и пройтись по карте от точки появления в запущенной игре
tools/rpg_editor/play_no_scene = Сцена «{0}» ещё не загружена: после создания карты перезагрузите моды (Ctrl+Shift+R). tools/rpg_editor/play_no_scene = Игра не знает сцену «{0}»: проверьте файл scenes/{0}.json в моде карты.
tools/rpg_editor/scene_created = создана сцена {0} tools/rpg_editor/scene_created = создана сцена {0}
tools/rpg_editor/section_palette = Палитра tools/rpg_editor/section_palette = Палитра
tools/rpg_editor/section_map = Карта tools/rpg_editor/section_map = Карта
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

+9 -7
View File
@@ -27,7 +27,9 @@ namespace Cthangover.Tools.RpgEditor
/// (Ctrl+Z / Ctrl+Y); Ctrl+S saves. A new file becomes a map filled with the /// (Ctrl+Z / Ctrl+Y); Ctrl+S saves. A new file becomes a map filled with the
/// first tile of the first tileset, and the first save also writes /// first tile of the first tileset, and the first save also writes
/// <c>scenes/&lt;id&gt;.json</c> when the mod has no such scene, because the /// <c>scenes/&lt;id&gt;.json</c> when the mod has no such scene, because the
/// map id is the scene name. /// map id is the scene name; the game re-reads its scenes right away
/// (<see cref="SceneManager.ReloadContent"/>), so "Play" works on a new map
/// without a mod reload.
/// <para/> /// <para/>
/// After a save the map is put into the running game's map cache, and a /// After a save the map is put into the running game's map cache, and a
/// world showing it is remounted, so the edit is visible at once; "Play" /// world showing it is remounted, so the edit is visible at once; "Play"
@@ -36,7 +38,6 @@ namespace Cthangover.Tools.RpgEditor
public partial class RpgMapEditorWindow : ToolWindow public partial class RpgMapEditorWindow : ToolWindow
{ {
private const string MapDir = "maps"; private const string MapDir = "maps";
private const string SceneDir = "scenes";
private readonly RpgTextures textures = new(); private readonly RpgTextures textures = new();
private readonly Dictionary<RpgEditLayer, Button> layerButtons = new(); private readonly Dictionary<RpgEditLayer, Button> layerButtons = new();
@@ -254,6 +255,8 @@ namespace Cthangover.Tools.RpgEditor
} }
var sceneNote = isNew ? EnsureScene() : null; var sceneNote = isNew ? EnsureScene() : null;
if (sceneNote != null)
SceneManager.ReloadContent();
isNew = false; isNew = false;
MarkClean(); MarkClean();
PublishToGame(json); PublishToGame(json);
@@ -264,12 +267,11 @@ namespace Cthangover.Tools.RpgEditor
/// <summary>Writes <c>scenes/&lt;id&gt;.json</c> for a new map when the mod has none; returns a status suffix.</summary> /// <summary>Writes <c>scenes/&lt;id&gt;.json</c> for a new map when the mod has none; returns a status suffix.</summary>
private string EnsureScene() private string EnsureScene()
{ {
var scenePath = SceneDir + "/" + document.Map.ID + ".json"; var scene = new SceneFileEntry { ModId = modId, Name = document.Map.ID, RelativePath = SceneFileEntry.PathFor(document.Map.ID) };
if (!string.IsNullOrEmpty(ModFileService.ReadText(modId, scenePath))) if (!string.IsNullOrEmpty(ModFileService.ReadText(modId, scene.RelativePath)))
return null; return null;
var json = "{\n \"name\": \"" + document.Map.ID + "\",\n \"defaultAmbient\": \"\"\n}\n"; return SceneFileService.Write(scene)
return ModFileService.WriteText(modId, scenePath, json) ? " · " + string.Format(ToolUi.Tr("tools/rpg_editor/scene_created"), scene.RelativePath)
? " · " + string.Format(ToolUi.Tr("tools/rpg_editor/scene_created"), scenePath)
: null; : null;
} }
+57 -2
View File
@@ -1,9 +1,13 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using Cthangover.Core.Bootstrap; using Cthangover.Core.Bootstrap;
using Cthangover.Core.Scenes;
using Cthangover.Core.Utils; using Cthangover.Core.Utils;
using Cthangover.Mods.Interface.Tool; using Cthangover.Mods.Interface.Tool;
using Cthangover.Mods.Rpg; using Cthangover.Mods.Rpg;
using Cthangover.Tools.Common;
using Cthangover.Tools.Services;
using Godot; using Godot;
namespace Cthangover.Tools.RpgEditor.Tests namespace Cthangover.Tools.RpgEditor.Tests
@@ -11,8 +15,10 @@ namespace Cthangover.Tools.RpgEditor.Tests
/// <summary> /// <summary>
/// Drives the RPG map editor through its controls like an author: layer /// Drives the RPG map editor through its controls like an author: layer
/// buttons are pressed, the palette and the canvas get mouse events through /// buttons are pressed, the palette and the canvas get mouse events through
/// their <c>gui_input</c> signal, Ctrl+Z goes into the window. The window is /// their <c>gui_input</c> signal, Ctrl+Z goes into the window. That window is
/// freed at the end without saving, so the demo maps never change. /// freed without saving, so the demo maps never change. A second window then
/// creates a new map through the file selector's "+" and saves it: the game must
/// know the map's scene at once (no mod reload); its files are deleted again.
/// Result line: <c>[TEST_RESULT] name=rpg_editor_edit passed=N failed=M</c>. /// Result line: <c>[TEST_RESULT] name=rpg_editor_edit passed=N failed=M</c>.
/// </summary> /// </summary>
public partial class RpgEditorTestDriver : Node public partial class RpgEditorTestDriver : Node
@@ -20,6 +26,7 @@ namespace Cthangover.Tools.RpgEditor.Tests
private const float TickSeconds = 0.15f; private const float TickSeconds = 0.15f;
private const float TimeoutSeconds = 60f; private const float TimeoutSeconds = 60f;
private const int RockTile = 11; private const int RockTile = 11;
private const string NewMap = "zz_editor_test_map";
private static readonly Vector2I PaintCell = new(3, 5); private static readonly Vector2I PaintCell = new(3, 5);
private static readonly Vector2I EventCell = new(2, 6); private static readonly Vector2I EventCell = new(2, 6);
@@ -32,6 +39,7 @@ namespace Cthangover.Tools.RpgEditor.Tests
private RpgMapEditorWindow window; private RpgMapEditorWindow window;
private RpgMapEditorCanvas canvas; private RpgMapEditorCanvas canvas;
private int eventsBefore; private int eventsBefore;
private string newMapMod;
/// <summary>Creates the driver; <paramref name="shotsDir"/> null disables screenshots.</summary> /// <summary>Creates the driver; <paramref name="shotsDir"/> null disables screenshots.</summary>
public RpgEditorTestDriver(string shotsDir) public RpgEditorTestDriver(string shotsDir)
@@ -115,11 +123,58 @@ namespace Cthangover.Tools.RpgEditor.Tests
case 4: case 4:
Shot("collision"); Shot("collision");
window.QueueFree(); window.QueueFree();
window = ToolWindow.Open<RpgMapEditorWindow>();
step++;
return;
case 5:
canvas = window.FindChildren("*", "", true, false).OfType<RpgMapEditorCanvas>().FirstOrDefault();
if (canvas?.Document == null)
return;
newMapMod = Selector().CurrentMod;
DeleteNewMapFiles();
Selector().FindChildren("*", "", true, false).OfType<Button>().First(b => b.Text == "+").EmitSignal(BaseButton.SignalName.Pressed);
step++;
return;
case 6:
var dialog = window.FindChildren("*", "", true, false).OfType<ConfirmationDialog>().FirstOrDefault();
if (dialog == null)
return;
dialog.FindChildren("*", "", true, false).OfType<LineEdit>().First().Text = NewMap;
dialog.EmitSignal(AcceptDialog.SignalName.Confirmed);
step++;
return;
case 7:
if (canvas.Document?.Map?.ID != NewMap)
return;
try
{
Press("tools/common/save");
Check(File.Exists(ModFileService.GetWritablePath(newMapMod, "scenes/" + NewMap + ".json")), "the first save of a new map writes its scene");
Check(GetTree().Root.GetNodeOrNull<SceneManager>("SceneManager")?.HasScene(NewMap) == true, "the game knows the new map's scene without a mod reload");
}
finally
{
window.QueueFree();
DeleteNewMapFiles();
SceneManager.ReloadContent();
}
Finish(); Finish();
return; return;
} }
} }
private ModFileSelector Selector() => window.FindChildren("*", "", true, false).OfType<ModFileSelector>().First();
private void DeleteNewMapFiles()
{
foreach (var file in new[] { "maps/" + NewMap + ".json", "scenes/" + NewMap + ".json" })
{
var path = ModFileService.GetWritablePath(newMapMod, file);
if (path != null && File.Exists(path))
File.Delete(path);
}
}
private void Press(string key) private void Press(string key)
{ {
var text = TranslationServer.Translate(key); var text = TranslationServer.Translate(key);