fix: 装备属性面板避让逻辑 + 多项功能更新

- item_tooltip_view.gd: 新增 avoid_rect 属性,tooltip 与装备窗口重叠时自动推到左侧
- inventory_ui.gd: 悬停装备时传入窗口矩形作为避让区域
- 包含其他累积的功能开发和测试文件
This commit is contained in:
shen
2026-09-21 16:38:59 -07:00
parent 1522a8a1a1
commit c93894313a
5498 changed files with 4558004 additions and 1442 deletions
+22 -2
View File
@@ -7,6 +7,7 @@ const GameScene = preload("res://game_scene.gd")
const Fixtures = preload("res://gamescene_test.gd")
const PlayerView = preload("res://ui/player_view.gd")
const MobView = preload("res://ui/mob_view.gd")
const UiAssets = preload("res://ui/ui_assets.gd")
const Metrics = preload("res://testing/playable_metrics.gd")
class ScenarioClient extends Fixtures.FakeClient:
signal warp(pos: Vector3, same_server: bool)
@@ -172,9 +173,28 @@ func run() -> void:
check(report.memory.gpu_memory_kib == null, "GPU memory is reported unavailable, never 0")
print("SCENARIO_METRICS frames=%d long=%d unattributed=%d severe=%s" % [summary.frames, summary.long_frames.size(),
report.unattributed_long_frames, summary.severe_by_phase])
scene.free()
client.free()
# Mirror the reference Destroy order: stop world presentation, explicitly
# unload native map resources, then let SceneTree release the node graph at
# a frame boundary. Direct free() while active animation/map callbacks are
# still queued made this regression report PASS and then exit with SIGSEGV.
client.world_reset.emit()
if scene.world and is_instance_valid(scene.world) and scene.world.has_method("unload_map"):
scene.world.call("unload_map")
# Keep both nodes attached until queue_free runs. Removing a node before
# queue_free can bypass SceneTree's recursive child teardown and make the
# leak report look like a native-world ownership failure.
scene.queue_free()
client.queue_free()
await process_frame
await process_frame
# Match the explicit resource-manager teardown used by the short model
# regressions before asking SceneTree/Godot to terminate the process.
if ClassDB.class_exists("Metin2Model"):
Metin2Model.clear_texture_cache()
if ClassDB.class_exists("Metin2AnimPlayer"):
Metin2AnimPlayer.clear_clip_cache()
MobView.clear_cache()
UiAssets.clear_cache()
report["failures"] = failures
report["duration_seconds"] = (Time.get_ticks_msec() - run_start) / 1000.0
FileAccess.open(output.path_join("report.json"), FileAccess.WRITE).store_string(JSON.stringify(report, "\t"))