Phase 14 - Organized directories.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
extends SceneTree
|
||||
|
||||
const IO := preload("res://scripts/stage_scene_io.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const IO := preload("res://scripts/stage/stage_scene_io.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
|
||||
const FIXTURE_PATH := "user://cli_fixture.scene"
|
||||
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
extends SceneTree
|
||||
|
||||
const CONTENT_PATHS := preload("res://scripts/shared/content_paths.gd")
|
||||
const CLI_LAUNCHER := preload("res://scripts/tools/cli_scene_launcher.gd")
|
||||
const STAGE_SCENE_IO := preload("res://scripts/stage/stage_scene_io.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
|
||||
const LEGACY_STAGE_PATH: String = "res://tests/.phase14_legacy_paths.scene"
|
||||
const RESAVED_STAGE_PATH: String = "res://tests/.phase14_resaved_paths_resaved.scene"
|
||||
|
||||
var _checks: int = 0
|
||||
var _failures: int = 0
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
call_deferred("_run")
|
||||
|
||||
|
||||
func _run() -> void:
|
||||
_test_path_mapping()
|
||||
_test_moved_stage_file_paths()
|
||||
await _test_legacy_stage_round_trip()
|
||||
_cleanup()
|
||||
print("RESULT: %d checks, %d failures" % [_checks, _failures])
|
||||
quit(1 if _failures > 0 else 0)
|
||||
|
||||
|
||||
func _expect(condition: bool, message: String) -> void:
|
||||
_checks += 1
|
||||
if condition:
|
||||
print("PASS: " + message)
|
||||
else:
|
||||
_failures += 1
|
||||
push_error("Content path test failed: " + message)
|
||||
|
||||
|
||||
func _test_path_mapping() -> void:
|
||||
_expect(CONTENT_PATHS.canonicalize("res://stickmen/basic.stk") == "res://content/stickmen/basic.stk", "legacy stickman resource paths map into content")
|
||||
_expect(CONTENT_PATHS.canonicalize("res://props/briefcase.prop") == "res://content/props/briefcase.prop", "legacy prop resource paths map into content")
|
||||
_expect(CONTENT_PATHS.canonicalize("res://game_scenes/bend.scene") == "res://content/stages/bend.scene", "legacy stage resource paths map into content")
|
||||
_expect(CONTENT_PATHS.canonicalize("res://unmanaged/asset.stk") == "res://unmanaged/asset.stk", "unknown resource paths pass through")
|
||||
_expect(CONTENT_PATHS.canonicalize("user://stickmen/basic.stk") == "user://stickmen/basic.stk", "user-selected paths pass through")
|
||||
_expect(CONTENT_PATHS.canonicalize("/tmp/external/stickmen/basic.stk") == "/tmp/external/stickmen/basic.stk", "external absolute paths pass through")
|
||||
var project_root: String = ProjectSettings.globalize_path("res://").trim_suffix("/")
|
||||
var old_absolute: String = project_root.path_join("stickmen/basic.stk")
|
||||
var new_absolute: String = project_root.path_join("content/stickmen/basic.stk")
|
||||
_expect(CONTENT_PATHS.canonicalize(old_absolute) == new_absolute, "legacy absolute paths inside the project migrate in place")
|
||||
var cli_result: Dictionary = CLI_LAUNCHER.parse(["--scene", "res://game_scenes/bend.scene"])
|
||||
_expect(String(cli_result.get("scene_path", "")) == "res://content/stages/bend.scene", "CLI stage paths migrate before playback")
|
||||
|
||||
|
||||
func _test_moved_stage_file_paths() -> void:
|
||||
var result: Dictionary = STAGE_SCENE_IO.read_file("res://game_scenes/bend.scene")
|
||||
_expect(bool(result.get("ok", false)), "stage IO opens a stage through its previous project path")
|
||||
|
||||
|
||||
func _test_legacy_stage_round_trip() -> void:
|
||||
_cleanup()
|
||||
var legacy_data: Dictionary = {
|
||||
"version": STAGE_SCENE_IO.FILE_VERSION,
|
||||
"scene_name": "Legacy Asset Paths",
|
||||
"camera": {"position": {"x": 0.0, "y": -400.0}, "zoom": 0.5},
|
||||
"objects": [
|
||||
{
|
||||
"file_id": "stickman_1",
|
||||
"type": "stickman",
|
||||
"position": {"x": 0.0, "y": 0.0},
|
||||
"rotation": 0.0,
|
||||
"stk_path": "res://stickmen/test.stk",
|
||||
"action_queue": [],
|
||||
},
|
||||
{
|
||||
"file_id": "prop_1",
|
||||
"stage_object_id": "prop_1",
|
||||
"type": "prop",
|
||||
"position": {"x": 180.0, "y": 0.0},
|
||||
"rotation": 0.0,
|
||||
"asset_id": "res://props/briefcase.prop",
|
||||
"scale": {"x": 1.0, "y": 1.0},
|
||||
"material_preset": 1,
|
||||
},
|
||||
],
|
||||
"event_rules": [],
|
||||
"metadata": {},
|
||||
}
|
||||
_expect(bool(STAGE_SCENE_IO.write_file_safe(LEGACY_STAGE_PATH, legacy_data).get("ok", false)), "legacy stage fixture writes")
|
||||
var stage: Node2D = STAGE_SCENE.instantiate() as Node2D
|
||||
root.add_child(stage)
|
||||
await process_frame
|
||||
var loaded: bool = bool(stage.call("_load_scene_from_path", LEGACY_STAGE_PATH))
|
||||
_expect(loaded, "legacy stage with moved stickman and prop assets loads")
|
||||
var world: Node = stage.get("_world") as Node
|
||||
_expect(world != null and world.get_child_count() == 2, "both moved assets are present after load")
|
||||
var scene_data: Dictionary = stage.call("_collect_scene_data", false) as Dictionary
|
||||
var objects: Array = scene_data.get("objects", [])
|
||||
var saved_stickman_path: String = ""
|
||||
var saved_prop_path: String = ""
|
||||
for value: Variant in objects:
|
||||
if not value is Dictionary:
|
||||
continue
|
||||
var entry: Dictionary = value as Dictionary
|
||||
if String(entry.get("type", "")) == "stickman":
|
||||
saved_stickman_path = String(entry.get("stk_path", ""))
|
||||
elif String(entry.get("type", "")) == "prop":
|
||||
saved_prop_path = String(entry.get("asset_id", ""))
|
||||
_expect(saved_stickman_path == "res://content/stickmen/test.stk", "resaved stickman reference uses the canonical path")
|
||||
_expect(saved_prop_path == "res://content/props/briefcase.prop", "resaved prop reference uses the canonical path")
|
||||
_expect(bool(STAGE_SCENE_IO.write_file_safe(RESAVED_STAGE_PATH, scene_data).get("ok", false)), "canonical stage document resaves")
|
||||
var reread: Dictionary = STAGE_SCENE_IO.read_file(RESAVED_STAGE_PATH)
|
||||
_expect(bool(reread.get("ok", false)), "resaved stage document reads successfully")
|
||||
var current_path: String = String(stage.get("_current_scene_path"))
|
||||
_expect(current_path == LEGACY_STAGE_PATH, "unmanaged stage document path remains unchanged")
|
||||
stage.queue_free()
|
||||
await process_frame
|
||||
|
||||
|
||||
func _cleanup() -> void:
|
||||
for path: String in [LEGACY_STAGE_PATH, RESAVED_STAGE_PATH]:
|
||||
if FileAccess.file_exists(path):
|
||||
DirAccess.remove_absolute(ProjectSettings.globalize_path(path))
|
||||
@@ -0,0 +1 @@
|
||||
uid://biayrtuu3udms
|
||||
@@ -1,13 +1,13 @@
|
||||
extends SceneTree
|
||||
|
||||
const PROP_LIBRARY := preload("res://scripts/prop_library.gd")
|
||||
const STAGE_SPAWNER := preload("res://scripts/stage_spawner.gd")
|
||||
const PROP_BLOCK := preload("res://scripts/prop_block.gd")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage_selection.gd")
|
||||
const THUMBNAIL_CACHE := preload("res://scripts/thumbnails/thumbnail_cache.gd")
|
||||
const PROP_FILE := preload("res://scripts/prop_file.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const MISSING_PROP_PLACEHOLDER := preload("res://scripts/missing_prop_placeholder.gd")
|
||||
const PROP_LIBRARY := preload("res://scripts/props/prop_library.gd")
|
||||
const STAGE_SPAWNER := preload("res://scripts/stage/stage_spawner.gd")
|
||||
const PROP_BLOCK := preload("res://scripts/props/prop_block.gd")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage/stage_selection.gd")
|
||||
const THUMBNAIL_CACHE := preload("res://scripts/shared/thumbnails/thumbnail_cache.gd")
|
||||
const PROP_FILE := preload("res://scripts/editors/prop/prop_file.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const MISSING_PROP_PLACEHOLDER := preload("res://scripts/props/missing_prop_placeholder.gd")
|
||||
|
||||
const TEMP_PROP_PATH := "user://phase10_custom_integration.prop"
|
||||
|
||||
@@ -23,7 +23,7 @@ func _run() -> void:
|
||||
_check(builtins.size() == 4, "built-in templates remain four entries")
|
||||
var entries: Array[Dictionary] = PROP_LIBRARY.scan()
|
||||
_check(entries.size() == 8, "scan returns built-ins and checked-in custom props")
|
||||
var entry: Dictionary = PROP_LIBRARY.get_entry("res://props/briefcase.prop")
|
||||
var entry: Dictionary = PROP_LIBRARY.get_entry("res://content/props/briefcase.prop")
|
||||
_check(not entry.is_empty() and bool(entry.get("is_custom", false)), "custom path resolves without selector scan")
|
||||
_check((entry.get("shapes", []) as Array).size() > 1, "custom entry preserves the full shape stack")
|
||||
var hull: PackedVector2Array = entry.get("collision_hull", PackedVector2Array())
|
||||
@@ -31,7 +31,7 @@ func _run() -> void:
|
||||
var world: Node2D = Node2D.new()
|
||||
root.add_child(world)
|
||||
var spawner: StageSpawner = STAGE_SPAWNER.new(world)
|
||||
var prop: PropBlock = spawner.spawn_prop_asset("res://props/briefcase.prop", Vector2(100, 50))
|
||||
var prop: PropBlock = spawner.spawn_prop_asset("res://content/props/briefcase.prop", Vector2(100, 50))
|
||||
_check(prop != null and prop.has_custom_shapes(), "spawner creates layered custom PropBlock")
|
||||
if prop != null:
|
||||
var visuals: Node2D = prop.get_node_or_null(NodePath("Visuals")) as Node2D
|
||||
@@ -41,7 +41,7 @@ func _run() -> void:
|
||||
var aabb: Rect2 = STAGE_SELECTION.get_world_aabb(prop)
|
||||
_check(aabb.size.x > 0.0 and aabb.size.y > 0.0, "selection bounds include custom visuals")
|
||||
var cache: ThumbnailCache = THUMBNAIL_CACHE.new()
|
||||
_check(cache.prop_file_png("res://props/briefcase.prop") != cache.prop_file_png("user://briefcase.prop"), "thumbnail keys include complete canonical path")
|
||||
_check(cache.prop_file_png("res://content/props/briefcase.prop") != cache.prop_file_png("user://briefcase.prop"), "thumbnail keys include complete canonical path")
|
||||
world.queue_free()
|
||||
await process_frame
|
||||
await _test_authored_visual_values()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
extends SceneTree
|
||||
|
||||
const PROP_CANVAS := preload("res://scripts/prop_canvas.gd")
|
||||
const PROP_ANCHORS := preload("res://scripts/prop_anchor_data.gd")
|
||||
const STAGE_GIZMOS := preload("res://scripts/stage_gizmos.gd")
|
||||
const PROP_BLOCK := preload("res://scripts/prop_block.gd")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage_selection.gd")
|
||||
const PROP_CANVAS := preload("res://scripts/editors/prop/prop_canvas.gd")
|
||||
const PROP_ANCHORS := preload("res://scripts/props/prop_anchor_data.gd")
|
||||
const STAGE_GIZMOS := preload("res://scripts/stage/stage_gizmos.gd")
|
||||
const PROP_BLOCK := preload("res://scripts/props/prop_block.gd")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage/stage_selection.gd")
|
||||
|
||||
var failures: int = 0
|
||||
var checks: int = 0
|
||||
|
||||
@@ -19,15 +19,15 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const STICKMAN_LIBRARY := preload("res://scripts/stickman_library.gd")
|
||||
const PROP_LIBRARY := preload("res://scripts/prop_library.gd")
|
||||
const THUMBNAIL_CACHE := preload("res://scripts/thumbnails/thumbnail_cache.gd")
|
||||
const ASSET_SELECTOR := preload("res://scripts/asset_selector.gd")
|
||||
const STAGE_SPAWNER := preload("res://scripts/stage_spawner.gd")
|
||||
const PROP_BLOCK := preload("res://scripts/prop_block.gd")
|
||||
const RIG := preload("res://scripts/stickman_rig.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const ASSET_SELECTOR_SCENE := preload("res://scenes/asset_selector.tscn")
|
||||
const STICKMAN_LIBRARY := preload("res://scripts/characters/stickman/stickman_library.gd")
|
||||
const PROP_LIBRARY := preload("res://scripts/props/prop_library.gd")
|
||||
const THUMBNAIL_CACHE := preload("res://scripts/shared/thumbnails/thumbnail_cache.gd")
|
||||
const ASSET_SELECTOR := preload("res://scripts/shared/ui/asset_selector.gd")
|
||||
const STAGE_SPAWNER := preload("res://scripts/stage/stage_spawner.gd")
|
||||
const PROP_BLOCK := preload("res://scripts/props/prop_block.gd")
|
||||
const RIG := preload("res://scripts/characters/stickman/stickman_rig.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const ASSET_SELECTOR_SCENE := preload("res://scenes/stage/asset_selector.tscn")
|
||||
|
||||
const TEST_DIR := "user://phase3b_test"
|
||||
|
||||
@@ -83,7 +83,7 @@ func _test_scan() -> void:
|
||||
_check(String(_by_path(entries, "break.stk")["name"]) == "break",
|
||||
"break.stk falls back to filename basename")
|
||||
_check(not _by_path(entries, "basic.stk").is_empty(), "basic.stk entry has data")
|
||||
var found: Dictionary = lib.find_by_path("res://stickmen/basic.stk")
|
||||
var found: Dictionary = lib.find_by_path("res://content/stickmen/basic.stk")
|
||||
_check(not found.is_empty() and String(found["name"]) == "Basic",
|
||||
"find_by_path resolves basic.stk")
|
||||
|
||||
@@ -109,11 +109,11 @@ func _test_make_entry() -> void:
|
||||
print("")
|
||||
print("--- make_entry() ---")
|
||||
var lib = STICKMAN_LIBRARY.new()
|
||||
var entry := lib.make_entry("res://stickmen/basic.stk")
|
||||
var entry := lib.make_entry("res://content/stickmen/basic.stk")
|
||||
_check(not entry.is_empty(), "make_entry on valid path returns an entry")
|
||||
_check(String(entry["name"]) == "Basic", "make_entry name == 'Basic'")
|
||||
_check(not (entry["data"] as Dictionary).is_empty(), "make_entry carries parsed data")
|
||||
_check(lib.make_entry("res://stickmen/does_not_exist.stk").is_empty(),
|
||||
_check(lib.make_entry("res://content/stickmen/does_not_exist.stk").is_empty(),
|
||||
"make_entry on missing path returns {}")
|
||||
_ensure_test_dir()
|
||||
_write_file(TEST_DIR + "/bad.stk", "nope nope")
|
||||
@@ -153,7 +153,7 @@ func _test_spawner_registry() -> void:
|
||||
_check(not ids.has("crate") and not ids.has("ball"),
|
||||
"crate/ball registry entries removed")
|
||||
_check(spawner.get_selected_prop_id() == "crate", "default selected_prop_id == 'crate'")
|
||||
_check(spawner.get_selected_stickman_path() == "res://stickmen/test.stk",
|
||||
_check(spawner.get_selected_stickman_path() == "res://content/stickmen/test.stk",
|
||||
"default selected_stickman_path == test.stk")
|
||||
world.queue_free()
|
||||
|
||||
@@ -183,7 +183,7 @@ func _test_spawn_stickman() -> void:
|
||||
var world := Node2D.new()
|
||||
root.add_child(world)
|
||||
var spawner = STAGE_SPAWNER.new(world)
|
||||
spawner.selected_stickman_path = "res://stickmen/basic.stk"
|
||||
spawner.selected_stickman_path = "res://content/stickmen/basic.stk"
|
||||
var rig: Node2D = spawner.spawn("stickman", Vector2.ZERO)
|
||||
_check(rig != null, "stickman spawns from basic.stk")
|
||||
_check(rig is RIG, "basic.stk spawns a StickmanRig")
|
||||
@@ -194,8 +194,8 @@ func _test_thumbnail_cache() -> void:
|
||||
print("")
|
||||
print("--- ThumbnailCache key/png formatting ---")
|
||||
var cache = THUMBNAIL_CACHE.new()
|
||||
var mtime: int = FileAccess.get_modified_time("res://stickmen/test.stk")
|
||||
var key := cache.stickman_key("res://stickmen/test.stk")
|
||||
var mtime: int = FileAccess.get_modified_time("res://content/stickmen/test.stk")
|
||||
var key := cache.stickman_key("res://content/stickmen/test.stk")
|
||||
_check(key == "test_%d" % mtime, "stickman_key embeds basename + mtime (got '%s')" % key)
|
||||
_check(cache.stickman_png(key) == "user://thumbnails/stickmen/" + key + ".png",
|
||||
"stickman_png path formatting (got '%s')" % cache.stickman_png(key))
|
||||
@@ -226,8 +226,8 @@ func _test_pagination() -> void:
|
||||
func _test_scene_loads() -> void:
|
||||
print("")
|
||||
print("--- Scene load checks ---")
|
||||
_check(load("res://scenes/sandbox_stage.tscn") != null, "sandbox_stage.tscn loads")
|
||||
_check(load("res://scenes/asset_selector.tscn") != null, "asset_selector.tscn loads")
|
||||
_check(load("res://scenes/stage/sandbox_stage.tscn") != null, "sandbox_stage.tscn loads")
|
||||
_check(load("res://scenes/stage/asset_selector.tscn") != null, "asset_selector.tscn loads")
|
||||
var selector: AssetSelector = ASSET_SELECTOR_SCENE.instantiate() as AssetSelector
|
||||
_check(selector != null, "asset_selector.tscn instantiates as AssetSelector")
|
||||
root.add_child(selector)
|
||||
|
||||
@@ -55,8 +55,8 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const ASSET_SELECTOR_SCENE := preload("res://scenes/asset_selector.tscn")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const ASSET_SELECTOR_SCENE := preload("res://scenes/stage/asset_selector.tscn")
|
||||
|
||||
## Button stylebox states the old pre-highlight could have overridden on a cell.
|
||||
const BUTTON_STYLEBOX_STATES: Array[String] = [
|
||||
@@ -235,7 +235,7 @@ func _test_bug4_selector_prehighlight_removed() -> void:
|
||||
_check(sel.get("_selected_id") == null, "member _selected_id removed")
|
||||
|
||||
# Source-presence: none of the deleted tokens may lurk in the script.
|
||||
var file := FileAccess.open("res://scripts/asset_selector.gd", FileAccess.READ)
|
||||
var file := FileAccess.open("res://scripts/shared/ui/asset_selector.gd", FileAccess.READ)
|
||||
_check(file != null, "asset_selector.gd is readable")
|
||||
if file != null:
|
||||
var text := file.get_as_text()
|
||||
@@ -271,7 +271,7 @@ func _test_bug4_stage_grid_no_prehighlight() -> void:
|
||||
var stage := _new_stage()
|
||||
|
||||
# Selected file missing -> fall-back-to-first-entry still runs before open().
|
||||
stage._spawner.selected_stickman_path = "res://stickmen/does_not_exist.stk"
|
||||
stage._spawner.selected_stickman_path = "res://content/stickmen/does_not_exist.stk"
|
||||
stage._open_selector("stickman")
|
||||
_check(stage._selector_open, "stage selector opens from a palette toggle")
|
||||
_check(stage._spawner.get_selected_stickman_path().ends_with("basic.stk"),
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
|
||||
var _checks := 0
|
||||
var _failures := 0
|
||||
|
||||
@@ -31,15 +31,15 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const ACTION_REGISTRY := preload("res://scripts/action_registry.gd")
|
||||
const TRIGGER_REGISTRY := preload("res://scripts/trigger_registry.gd")
|
||||
const QUEUE_PANEL_SCENE := preload("res://scenes/queue_panel.tscn")
|
||||
const RULE_PANEL_SCENE := preload("res://scenes/rule_panel.tscn")
|
||||
const ACTION_EDITOR_SCENE := preload("res://scenes/action_editor.tscn")
|
||||
const RULE_EDITOR_SCENE := preload("res://scenes/rule_editor.tscn")
|
||||
const WAYPOINT_CONTEXT := preload("res://scripts/waypoint_context.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage_selection.gd")
|
||||
const ACTION_REGISTRY := preload("res://scripts/stage/action_registry.gd")
|
||||
const TRIGGER_REGISTRY := preload("res://scripts/stage/trigger_registry.gd")
|
||||
const QUEUE_PANEL_SCENE := preload("res://scenes/editors/stage/queue_panel.tscn")
|
||||
const RULE_PANEL_SCENE := preload("res://scenes/editors/stage/rule_panel.tscn")
|
||||
const ACTION_EDITOR_SCENE := preload("res://scenes/editors/stage/action_editor.tscn")
|
||||
const RULE_EDITOR_SCENE := preload("res://scenes/editors/stage/rule_editor.tscn")
|
||||
const WAYPOINT_CONTEXT := preload("res://scripts/stage/waypoint_context.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage/stage_selection.gd")
|
||||
|
||||
var _checks := 0
|
||||
var _failures := 0
|
||||
@@ -207,10 +207,10 @@ func _test_rule_action_converters() -> void:
|
||||
func _test_scene_shells() -> void:
|
||||
print("")
|
||||
print("--- Phase 3c scene shells load + _ready ---")
|
||||
_check(load("res://scenes/queue_panel.tscn") != null, "queue_panel.tscn loads")
|
||||
_check(load("res://scenes/rule_panel.tscn") != null, "rule_panel.tscn loads")
|
||||
_check(load("res://scenes/action_editor.tscn") != null, "action_editor.tscn loads")
|
||||
_check(load("res://scenes/rule_editor.tscn") != null, "rule_editor.tscn loads")
|
||||
_check(load("res://scenes/editors/stage/queue_panel.tscn") != null, "queue_panel.tscn loads")
|
||||
_check(load("res://scenes/editors/stage/rule_panel.tscn") != null, "rule_panel.tscn loads")
|
||||
_check(load("res://scenes/editors/stage/action_editor.tscn") != null, "action_editor.tscn loads")
|
||||
_check(load("res://scenes/editors/stage/rule_editor.tscn") != null, "rule_editor.tscn loads")
|
||||
|
||||
var qp: QueuePanel = QUEUE_PANEL_SCENE.instantiate()
|
||||
root.add_child(qp)
|
||||
|
||||
@@ -70,8 +70,8 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const RIG := preload("res://scripts/stickman_rig.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const RIG := preload("res://scripts/characters/stickman/stickman_rig.gd")
|
||||
|
||||
## Physics frames per measurement block (head-mirror stability sample).
|
||||
const SAMPLE_FRAMES := 50
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
|
||||
var _checks := 0
|
||||
var _failures := 0
|
||||
|
||||
@@ -2,12 +2,12 @@ extends SceneTree
|
||||
## Focused Phase 4 Final Bugs regression checks. Run with the project console
|
||||
## executable and `--headless --script res://tests/test_phase4_final_bugs.gd`.
|
||||
|
||||
const ACTION_REGISTRY := preload("res://scripts/action_registry.gd")
|
||||
const GIZMOS := preload("res://scripts/stage_gizmos.gd")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage_selection.gd")
|
||||
const ACTION_EDITOR_SCENE := preload("res://scenes/action_editor.tscn")
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const STICKMAN_FACTORY := preload("res://scripts/stickman_factory.gd")
|
||||
const ACTION_REGISTRY := preload("res://scripts/stage/action_registry.gd")
|
||||
const GIZMOS := preload("res://scripts/stage/stage_gizmos.gd")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage/stage_selection.gd")
|
||||
const ACTION_EDITOR_SCENE := preload("res://scenes/editors/stage/action_editor.tscn")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const STICKMAN_FACTORY := preload("res://scripts/characters/stickman/stickman_factory.gd")
|
||||
|
||||
var _checks: int = 0
|
||||
var _failures: int = 0
|
||||
@@ -312,15 +312,15 @@ func _test_stop_clears_head_reaction() -> void:
|
||||
|
||||
|
||||
func _test_source_contracts() -> void:
|
||||
var stage_source: String = FileAccess.get_file_as_string("res://scripts/sandbox_stage.gd")
|
||||
var rig_source: String = FileAccess.get_file_as_string("res://scripts/stickman_rig.gd")
|
||||
var ragdoll_source: String = FileAccess.get_file_as_string("res://scripts/stickman_ragdoll.gd")
|
||||
var stage_source: String = FileAccess.get_file_as_string("res://scripts/editors/stage/sandbox_stage.gd")
|
||||
var rig_source: String = FileAccess.get_file_as_string("res://scripts/characters/stickman/stickman_rig.gd")
|
||||
var ragdoll_source: String = FileAccess.get_file_as_string("res://scripts/characters/stickman/stickman_ragdoll.gd")
|
||||
_check(stage_source.contains("TERRAIN_DRAG_THRESHOLD_PX"), "terrain uses a drag threshold")
|
||||
_check(stage_source.contains("PhysicsServer2D.body_set_state"), "frozen prop commits synchronize physics")
|
||||
_check(stage_source.contains("transform_started.connect"), "gizmo start cancels deferred restoration")
|
||||
_check(stage_source.contains("if current_mode != StageMode.PLAY:"), "collision callbacks are gated to PLAY mode")
|
||||
_check(stage_source.contains("_speak_stop_current_check") and stage_source.contains("\"stop_current\": _speak_stop_current_check.button_pressed"), "legacy rule speak persists stop-current")
|
||||
var runner_source: String = FileAccess.get_file_as_string("res://scripts/stickman_action_runner.gd")
|
||||
var runner_source: String = FileAccess.get_file_as_string("res://scripts/characters/stickman/stickman_action_runner.gd")
|
||||
_check(runner_source.contains("_primary_speech") and runner_source.contains("_overlay_speech"), "runner separates primary and overlay speech")
|
||||
_check(rig_source.contains("_sync_speech_bubble_mirror"), "rig counter-mirrors LEFT speech")
|
||||
_check(rig_source.contains("initialize_spawn_pose_from_skeleton"), "rig captures factory spawn pose")
|
||||
|
||||
@@ -40,11 +40,11 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage_selection.gd")
|
||||
const TERRAIN_BLOCK := preload("res://scripts/terrain_block.gd")
|
||||
const OVERLAY_SCRIPT := preload("res://scripts/stage_placement_overlay.gd")
|
||||
const RIG := preload("res://scripts/stickman_rig.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage/stage_selection.gd")
|
||||
const TERRAIN_BLOCK := preload("res://scripts/terrain/terrain_block.gd")
|
||||
const OVERLAY_SCRIPT := preload("res://scripts/stage/stage_placement_overlay.gd")
|
||||
const RIG := preload("res://scripts/characters/stickman/stickman_rig.gd")
|
||||
|
||||
# The Ground registry template is authored 200x32 but StageSpawner sanitizes
|
||||
# every terrain polygon onto the 16px TERRAIN_GRID_SIZE before placement, so the
|
||||
@@ -297,7 +297,7 @@ func _test_bug2_overlay_clear() -> void:
|
||||
# Source-presence check: clear_terrain_guide() and clear_action() must both
|
||||
# call queue_redraw() so the erased line is removed (Godot 4.4 exposes no
|
||||
# is_queued_for_redraw(), so this is the headless-observable regression).
|
||||
var file := FileAccess.open("res://scripts/stage_placement_overlay.gd", FileAccess.READ)
|
||||
var file := FileAccess.open("res://scripts/stage/stage_placement_overlay.gd", FileAccess.READ)
|
||||
_check(file != null, "stage_placement_overlay.gd is readable")
|
||||
if file != null:
|
||||
var text := file.get_as_text()
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
# * After Back the rule-builder state is IDLE/empty AND _action_popup is
|
||||
# visible again (PopupMenu.visible IS observable headless).
|
||||
#
|
||||
# Bug 3 (head mirror jitter): scenes/stickman_rig.tscn's Head LookAt modification is a
|
||||
# Bug 3 (head mirror jitter): scenes/characters/stickman/stickman_rig.tscn's Head LookAt modification is a
|
||||
# full-range (-180..180), non-inverted, non-local-space constraint.
|
||||
# * Constraint flags/band are asserted directly on the instantiated rig.
|
||||
# * The Head marker is settled at the walk-left pose (-100,-614), then
|
||||
@@ -47,9 +47,9 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const RIG := preload("res://scripts/stickman_rig.gd")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage_selection.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const RIG := preload("res://scripts/characters/stickman/stickman_rig.gd")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage/stage_selection.gd")
|
||||
|
||||
# Physics frames / thresholds for the Bug 3 head-jitter measurement.
|
||||
const WARMUP_FRAMES := 30
|
||||
@@ -145,7 +145,7 @@ func _test_bug1_gizmo_draw_guard_source() -> void:
|
||||
# Drawing output is not observable headless, so assert the guard that makes
|
||||
# a deleted-but-still-referenced hover node disappear from the draw pass.
|
||||
# This mirrors the source-presence checks used elsewhere in the repo.
|
||||
var file := FileAccess.open("res://scripts/stage_gizmos.gd", FileAccess.READ)
|
||||
var file := FileAccess.open("res://scripts/stage/stage_gizmos.gd", FileAccess.READ)
|
||||
_check(file != null, "stage_gizmos.gd is readable")
|
||||
if file != null:
|
||||
var text := file.get_as_text()
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const TERRAIN_UTILS := preload("res://scripts/terrain_utils.gd")
|
||||
const STAGE_SPAWNER := preload("res://scripts/stage_spawner.gd")
|
||||
const TRIGGER_AREA := preload("res://scripts/trigger_area.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const TERRAIN_UTILS := preload("res://scripts/terrain/terrain_utils.gd")
|
||||
const STAGE_SPAWNER := preload("res://scripts/stage/stage_spawner.gd")
|
||||
const TRIGGER_AREA := preload("res://scripts/stage/trigger_area.gd")
|
||||
|
||||
var _checks := 0
|
||||
var _failures := 0
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const STAGE_SPAWNER := preload("res://scripts/stage_spawner.gd")
|
||||
const TERRAIN_UTILS := preload("res://scripts/terrain_utils.gd")
|
||||
const PROP_BLOCK := preload("res://scripts/prop_block.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const STAGE_SPAWNER := preload("res://scripts/stage/stage_spawner.gd")
|
||||
const TERRAIN_UTILS := preload("res://scripts/terrain/terrain_utils.gd")
|
||||
const PROP_BLOCK := preload("res://scripts/props/prop_block.gd")
|
||||
|
||||
var _checks := 0
|
||||
var _failures := 0
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
# live mouse position on every hop, so the menus could land far away from
|
||||
# the stickman whose action popup opened the session.
|
||||
#
|
||||
# Fix: scripts/sandbox_stage.gd now keeps session anchor state
|
||||
# Fix: scripts/editors/stage/sandbox_stage.gd now keeps session anchor state
|
||||
# `_popup_anchor: Rect2i` / `_popup_anchor_set: bool` plus helpers
|
||||
# `_set_popup_anchor(rect)`, `_clear_popup_anchor()`, and
|
||||
# `_popup_anchor_rect()` (self-records from `_mouse_popup_rect()` when
|
||||
@@ -43,8 +43,8 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage_selection.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage/stage_selection.gd")
|
||||
|
||||
var _checks := 0
|
||||
var _failures := 0
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const TERRAIN_UTILS := preload("res://scripts/terrain_utils.gd")
|
||||
const STAGE_SPAWNER := preload("res://scripts/stage_spawner.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const TERRAIN_UTILS := preload("res://scripts/terrain/terrain_utils.gd")
|
||||
const STAGE_SPAWNER := preload("res://scripts/stage/stage_spawner.gd")
|
||||
|
||||
var _checks := 0
|
||||
var _failures := 0
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const TERRAIN_BLOCK := preload("res://scripts/terrain_block.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const TERRAIN_BLOCK := preload("res://scripts/terrain/terrain_block.gd")
|
||||
|
||||
var _checks := 0
|
||||
var _failures := 0
|
||||
@@ -93,7 +93,7 @@ func _run() -> void:
|
||||
|
||||
|
||||
func _spawn_crate(world: Node2D, pos: Vector2) -> Node2D:
|
||||
var crate = preload("res://scripts/prop_block.gd").new()
|
||||
var crate = preload("res://scripts/props/prop_block.gd").new()
|
||||
crate.name = "Crate"
|
||||
crate.polygon_points = PackedVector2Array([
|
||||
Vector2(-24, -24), Vector2(24, -24), Vector2(24, 24), Vector2(-24, 24),
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const RIG := preload("res://scripts/stickman_rig.gd")
|
||||
const LOCOMOTION := preload("res://scripts/stickman_locomotion.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const RIG := preload("res://scripts/characters/stickman/stickman_rig.gd")
|
||||
const LOCOMOTION := preload("res://scripts/characters/stickman/stickman_locomotion.gd")
|
||||
|
||||
const SETTLE_FRAMES := 60
|
||||
const MAX_FRAMES := 300
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const STICKMAN_RIG := preload("res://scripts/stickman_rig.gd")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage_selection.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const STICKMAN_RIG := preload("res://scripts/characters/stickman/stickman_rig.gd")
|
||||
const STAGE_SELECTION := preload("res://scripts/stage/stage_selection.gd")
|
||||
|
||||
var _checks: int = 0
|
||||
var _failures: int = 0
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
extends SceneTree
|
||||
|
||||
const IO := preload("res://scripts/stage_scene_io.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const MISSING_PLACEHOLDER := preload("res://scripts/missing_stickman_placeholder.gd")
|
||||
const IO := preload("res://scripts/stage/stage_scene_io.gd")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const MISSING_PLACEHOLDER := preload("res://scripts/characters/stickman/missing_stickman_placeholder.gd")
|
||||
|
||||
var _checks := 0
|
||||
var _failures := 0
|
||||
@@ -145,7 +145,7 @@ func _test_stage_round_trip_and_file_state() -> void:
|
||||
area.size = Vector2(160.0, 80.0)
|
||||
area.scale = Vector2(1.2, 0.8)
|
||||
stage._finalize_placed_node(area)
|
||||
var rig: StickmanRig = stage._spawner.spawn_stickman_asset("res://stickmen/test.stk", Vector2(-100.0, -385.0))
|
||||
var rig: StickmanRig = stage._spawner.spawn_stickman_asset("res://content/stickmen/test.stk", Vector2(-100.0, -385.0))
|
||||
rig.set_facing_profile(StickmanRig.FacingProfile.LEFT)
|
||||
rig.queue_action({"type": "wait", "duration": 0.25})
|
||||
stage._finalize_placed_node(rig)
|
||||
@@ -180,7 +180,7 @@ func _test_stage_round_trip_and_file_state() -> void:
|
||||
var loaded_area := stage._world.get_child(2) as TriggerArea
|
||||
_expect(loaded_area != null and loaded_area.size == Vector2(160.0, 80.0) and loaded_area.scale.is_equal_approx(Vector2(1.2, 0.8)), "area size and scale survive")
|
||||
var loaded_rig := stage._world.get_child(3) as StickmanRig
|
||||
_expect(loaded_rig != null and loaded_rig.source_stk_path == "res://stickmen/test.stk" and loaded_rig.get_facing_profile() == StickmanRig.FacingProfile.LEFT, "stickman provenance and facing survive")
|
||||
_expect(loaded_rig != null and loaded_rig.source_stk_path == "res://content/stickmen/test.stk" and loaded_rig.get_facing_profile() == StickmanRig.FacingProfile.LEFT, "stickman provenance and facing survive")
|
||||
_expect(absf((loaded_rig.global_transform * Transform2D.FLIP_X).get_rotation()) < 0.01, "LEFT-facing rig loads with one mirror and canonical rotation")
|
||||
_expect(loaded_rig.get_queue().size() == 1 and stage._event_rules.size() == 1, "queue and rule survive")
|
||||
var loaded_trigger: Dictionary = stage._event_rules[0]["trigger"]
|
||||
|
||||
@@ -3,9 +3,9 @@ extends SceneTree
|
||||
## Focused deterministic regression checks for the Phase 6a terrain controller.
|
||||
## Runtime terrain/ramp integration remains covered by the existing stage suites.
|
||||
|
||||
const RIG_SCENE := preload("res://scenes/stickman_rig.tscn")
|
||||
const RIG := preload("res://scripts/stickman_rig.gd")
|
||||
const LOC := preload("res://scripts/stickman_locomotion.gd")
|
||||
const RIG_SCENE := preload("res://scenes/characters/stickman/stickman_rig.tscn")
|
||||
const RIG := preload("res://scripts/characters/stickman/stickman_rig.gd")
|
||||
const LOC := preload("res://scripts/characters/stickman/stickman_locomotion.gd")
|
||||
|
||||
var _checks: int = 0
|
||||
var _failures: int = 0
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
extends SceneTree
|
||||
|
||||
const SPAWNER := preload("res://scripts/stage_spawner.gd")
|
||||
const CARD := preload("res://scripts/ui/asset_card.gd")
|
||||
const SPAWNER := preload("res://scripts/stage/stage_spawner.gd")
|
||||
const CARD := preload("res://scripts/shared/ui/asset_card.gd")
|
||||
var _failures: int = 0
|
||||
|
||||
func _init() -> void:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
extends SceneTree
|
||||
|
||||
const THEME_SCRIPT := preload("res://scripts/sandbox_theme.gd")
|
||||
const THEME_SCRIPT := preload("res://scripts/stage/sandbox_theme.gd")
|
||||
var _failures: int = 0
|
||||
|
||||
func _init() -> void:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
var _failures: int = 0
|
||||
|
||||
func _initialize() -> void:
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
extends SceneTree
|
||||
|
||||
const COLOR_SWATCH := preload("res://scripts/ui/color_swatch_selector.gd")
|
||||
const SIZE_TOGGLE := preload("res://scripts/ui/preset_size_toggle.gd")
|
||||
const FONT_PICKER := preload("res://scripts/ui/font_preset_picker.gd")
|
||||
const EMOJI_GRID := preload("res://scripts/ui/emoji_quick_grid.gd")
|
||||
const COLOR_SWATCH := preload("res://scripts/shared/ui/color_swatch_selector.gd")
|
||||
const SIZE_TOGGLE := preload("res://scripts/shared/ui/preset_size_toggle.gd")
|
||||
const FONT_PICKER := preload("res://scripts/shared/ui/font_preset_picker.gd")
|
||||
const EMOJI_GRID := preload("res://scripts/shared/ui/emoji_quick_grid.gd")
|
||||
var _failures: int = 0
|
||||
|
||||
func _init() -> void:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const BONE_PATHS: Array[String] = [
|
||||
"Skeleton2D/Torso/Head",
|
||||
"Skeleton2D/Torso/LeftUpperArm",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
extends SceneTree
|
||||
|
||||
const STAGE_SCENE := preload("res://scenes/sandbox_stage.tscn")
|
||||
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
||||
const WALK_PHASES: Array[float] = [0.0, 0.08, 0.16, 0.24, 0.32, 0.40, 0.48, 0.56, 0.64, 0.72]
|
||||
const SETTLE_FRAMES := 30
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
extends SceneTree
|
||||
|
||||
const RIG_SCENE_PATH := "res://scenes/stickman_rig.tscn"
|
||||
const RIG_SCENE_PATH := "res://scenes/characters/stickman/stickman_rig.tscn"
|
||||
const EXPECTED_UID := "uid://dr5ef3l2var2s"
|
||||
|
||||
var _checks := 0
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
extends SceneTree
|
||||
## Phase 9a editor-only regression: anchor schema, alignment math, and preview isolation.
|
||||
|
||||
const ANCHORS := preload("res://scripts/prop_anchor_data.gd")
|
||||
const PROP_FILE := preload("res://scripts/prop_file.gd")
|
||||
const PREVIEW_SCENE := preload("res://scenes/prop_attach_preview.tscn")
|
||||
const EDITOR_SCENE := preload("res://scenes/prop_editor.tscn")
|
||||
const OVERLAY := preload("res://scripts/prop_anchor_overlay.gd")
|
||||
const ANCHORS := preload("res://scripts/props/prop_anchor_data.gd")
|
||||
const PROP_FILE := preload("res://scripts/editors/prop/prop_file.gd")
|
||||
const PREVIEW_SCENE := preload("res://scenes/editors/prop/prop_attach_preview.tscn")
|
||||
const EDITOR_SCENE := preload("res://scenes/editors/prop/prop_editor.tscn")
|
||||
const OVERLAY := preload("res://scripts/props/prop_anchor_overlay.gd")
|
||||
|
||||
var _checks: int = 0
|
||||
var _failures: int = 0
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
extends SceneTree
|
||||
## Phase 9b regression: canonical origin presentation, bounds, centering, and save threshold.
|
||||
|
||||
const ANCHORS := preload("res://scripts/prop_anchor_data.gd")
|
||||
const CANVAS_SCRIPT := preload("res://scripts/prop_canvas.gd")
|
||||
const EDITOR := preload("res://scripts/prop_editor.gd")
|
||||
const ANCHORS := preload("res://scripts/props/prop_anchor_data.gd")
|
||||
const CANVAS_SCRIPT := preload("res://scripts/editors/prop/prop_canvas.gd")
|
||||
const EDITOR := preload("res://scripts/editors/prop/prop_editor.gd")
|
||||
|
||||
var _checks: int = 0
|
||||
var _failures: int = 0
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
extends SceneTree
|
||||
|
||||
const THEME := preload("res://scripts/prop_theme.gd")
|
||||
const CANVAS_SCENE := preload("res://scenes/prop_editor.tscn")
|
||||
const PREVIEW_SCENE := preload("res://scenes/prop_attach_preview.tscn")
|
||||
const PROP_FILE := preload("res://scripts/prop_file.gd")
|
||||
const THEME := preload("res://scripts/editors/prop/prop_theme.gd")
|
||||
const CANVAS_SCENE := preload("res://scenes/editors/prop/prop_editor.tscn")
|
||||
const PREVIEW_SCENE := preload("res://scenes/editors/prop/prop_attach_preview.tscn")
|
||||
const PROP_FILE := preload("res://scripts/editors/prop/prop_file.gd")
|
||||
|
||||
var _failed: int = 0
|
||||
var _count: int = 0
|
||||
@@ -92,7 +92,7 @@ func _run() -> void:
|
||||
var main_split := editor.get("_main_layout") as HSplitContainer
|
||||
var inspector := editor.get("_inspector_column") as PanelContainer
|
||||
_check("inspector starts at minimum usable width", main_split != null and inspector != null and inspector.size.x >= inspector.get_combined_minimum_size().x)
|
||||
var eye_data: Dictionary = PROP_FILE.load("res://props/eye.prop")
|
||||
var eye_data: Dictionary = PROP_FILE.load("res://content/props/eye.prop")
|
||||
_check("eye prop fixture is available", not eye_data.is_empty())
|
||||
editor.call("_apply_json_data", eye_data)
|
||||
editor.size = Vector2(1200.0, 600.0)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const PROP_CANVAS := preload("res://scripts/prop_canvas.gd")
|
||||
const PROP_CANVAS := preload("res://scripts/editors/prop/prop_canvas.gd")
|
||||
|
||||
var _checks: int = 0
|
||||
var _failures: int = 0
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const PROP_FILE := preload("res://scripts/prop_file.gd")
|
||||
const PROP_BLOCK := preload("res://scripts/prop_block.gd")
|
||||
const TERRAIN_UTILS := preload("res://scripts/terrain_utils.gd")
|
||||
const PROP_FILE := preload("res://scripts/editors/prop/prop_file.gd")
|
||||
const PROP_BLOCK := preload("res://scripts/props/prop_block.gd")
|
||||
const TERRAIN_UTILS := preload("res://scripts/terrain/terrain_utils.gd")
|
||||
|
||||
var _checks: int = 0
|
||||
var _failures: int = 0
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const PROP_EDITOR := preload("res://scripts/prop_editor.gd")
|
||||
const PROP_FILE := preload("res://scripts/prop_file.gd")
|
||||
const PROP_EDITOR := preload("res://scripts/editors/prop/prop_editor.gd")
|
||||
const PROP_FILE := preload("res://scripts/editors/prop/prop_file.gd")
|
||||
|
||||
var _checks: int = 0
|
||||
var _failures: int = 0
|
||||
@@ -43,10 +43,10 @@ func check(label: String, condition: bool) -> void:
|
||||
func _test_window_title() -> void:
|
||||
check("untitled no path no dirty", PROP_EDITOR.build_window_title("", "", false) == "Untitled")
|
||||
check("name dirty", PROP_EDITOR.build_window_title("My Crate", "", true) == "My Crate *")
|
||||
check("name path clean", PROP_EDITOR.build_window_title("My Crate", "res://props/mycrate.prop", false) == "My Crate — mycrate.prop")
|
||||
check("untitled path dirty", PROP_EDITOR.build_window_title("", "res://props/mycrate.prop", true) == "Untitled — mycrate.prop *")
|
||||
check("name path clean", PROP_EDITOR.build_window_title("My Crate", "res://content/props/mycrate.prop", false) == "My Crate — mycrate.prop")
|
||||
check("untitled path dirty", PROP_EDITOR.build_window_title("", "res://content/props/mycrate.prop", true) == "Untitled — mycrate.prop *")
|
||||
check("whitespace name falls back", PROP_EDITOR.build_window_title(" ", "", false) == "Untitled")
|
||||
check("extension kept in title", PROP_EDITOR.build_window_title("X", "res://props/ball.prop", false).ends_with("ball.prop"))
|
||||
check("extension kept in title", PROP_EDITOR.build_window_title("X", "res://content/props/ball.prop", false).ends_with("ball.prop"))
|
||||
|
||||
|
||||
func _test_mode_button_text() -> void:
|
||||
@@ -80,11 +80,11 @@ func _test_save_safe() -> void:
|
||||
|
||||
|
||||
func _test_recent_list() -> void:
|
||||
var list: Array = PROP_EDITOR.update_recent_list([], "res://props/a.prop", 5)
|
||||
check("recent empty list inserts", list == ["res://props/a.prop"])
|
||||
list = PROP_EDITOR.update_recent_list(["res://props/b.prop", "res://props/a.prop"], "res://props/a.prop", 5)
|
||||
check("recent dedupe moves to front", list == ["res://props/a.prop", "res://props/b.prop"])
|
||||
list = PROP_EDITOR.update_recent_list(["res://props/b.prop", "res://props/c.prop"], "res://props/a.prop", 5)
|
||||
check("recent insert keeps most-recent-first", list == ["res://props/a.prop", "res://props/b.prop", "res://props/c.prop"])
|
||||
list = PROP_EDITOR.update_recent_list(["res://props/b.prop", "res://props/c.prop", "res://props/d.prop", "res://props/e.prop", "res://props/f.prop"], "res://props/a.prop", 5)
|
||||
check("recent trims to max", list.size() == 5 and list[0] == "res://props/a.prop" and list[4] == "res://props/e.prop")
|
||||
var list: Array = PROP_EDITOR.update_recent_list([], "res://content/props/a.prop", 5)
|
||||
check("recent empty list inserts", list == ["res://content/props/a.prop"])
|
||||
list = PROP_EDITOR.update_recent_list(["res://content/props/b.prop", "res://content/props/a.prop"], "res://content/props/a.prop", 5)
|
||||
check("recent dedupe moves to front", list == ["res://content/props/a.prop", "res://content/props/b.prop"])
|
||||
list = PROP_EDITOR.update_recent_list(["res://content/props/b.prop", "res://content/props/c.prop"], "res://content/props/a.prop", 5)
|
||||
check("recent insert keeps most-recent-first", list == ["res://content/props/a.prop", "res://content/props/b.prop", "res://content/props/c.prop"])
|
||||
list = PROP_EDITOR.update_recent_list(["res://content/props/b.prop", "res://content/props/c.prop", "res://content/props/d.prop", "res://content/props/e.prop", "res://content/props/f.prop"], "res://content/props/a.prop", 5)
|
||||
check("recent trims to max", list.size() == 5 and list[0] == "res://content/props/a.prop" and list[4] == "res://content/props/e.prop")
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const PROP_THEME := preload("res://scripts/prop_theme.gd")
|
||||
const PROP_BLOCK := preload("res://scripts/prop_block.gd")
|
||||
const PROP_THEME := preload("res://scripts/editors/prop/prop_theme.gd")
|
||||
const PROP_BLOCK := preload("res://scripts/props/prop_block.gd")
|
||||
|
||||
var _checks: int = 0
|
||||
var _failures: int = 0
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const THUMBNAIL_CACHE := preload("res://scripts/thumbnails/thumbnail_cache.gd")
|
||||
const THUMBNAIL_CACHE := preload("res://scripts/shared/thumbnails/thumbnail_cache.gd")
|
||||
|
||||
var _checks: int = 0
|
||||
var _failures: int = 0
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# test_text_baseline_fix.gd
|
||||
# Headless regression test for two text-baseline drawing fixes:
|
||||
# 1. scripts/stickman_speech_bubble.gd _draw() text baseline now includes
|
||||
# 1. scripts/speech/stickman_speech_bubble.gd _draw() text baseline now includes
|
||||
# font.get_ascent(FONT_SIZE) so glyphs sit inside the bubble rect.
|
||||
# 2. scripts/stage_director_visuals.gd _draw_rule() rule-label baseline now
|
||||
# 2. scripts/stage/stage_director_visuals.gd _draw_rule() rule-label baseline now
|
||||
# includes font.get_ascent(font_size) so white text sits on the dark rect.
|
||||
#
|
||||
# The math is replicated against the real ThemeDB.fallback_font using each
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
extends SceneTree
|
||||
|
||||
const SpeechBubbleScript := preload("res://scripts/stickman_speech_bubble.gd")
|
||||
const StageDirectorVisualsScript := preload("res://scripts/stage_director_visuals.gd")
|
||||
const SpeechBubbleScript := preload("res://scripts/speech/stickman_speech_bubble.gd")
|
||||
const StageDirectorVisualsScript := preload("res://scripts/stage/stage_director_visuals.gd")
|
||||
|
||||
# Inline constants from stage_director_visuals.gd's _draw_rule() (they are not
|
||||
# named constants there). RULE_LABEL_FONT_SIZE_PX is read from the script.
|
||||
|
||||
Reference in New Issue
Block a user