169 lines
4.8 KiB
GDScript
169 lines
4.8 KiB
GDScript
extends Node
|
|
## 离线角色显示属性测试
|
|
## Feature: godot-ai-town-game, Property 23: 离线角色显示
|
|
|
|
const TEST_ITERATIONS = 50
|
|
|
|
# 测试结果统计
|
|
var test_results = {
|
|
"passed": 0,
|
|
"failed": 0,
|
|
"errors": []
|
|
}
|
|
|
|
func _ready():
|
|
print("\n=== Property Test: Offline Character Display ===")
|
|
await test_property_offline_character_display()
|
|
print_results()
|
|
print("=== Property Test Completed ===\n")
|
|
|
|
## Feature: godot-ai-town-game, Property 23: 离线角色显示
|
|
func test_property_offline_character_display():
|
|
"""
|
|
属性测试:离线角色显示
|
|
对于任意玩家进入游戏场景时,系统应该显示所有离线玩家的角色作为 NPC
|
|
|
|
验证需求: 11.2
|
|
"""
|
|
print("\n[Property Test] Testing offline character display...")
|
|
print("Running ", TEST_ITERATIONS, " iterations...")
|
|
|
|
for i in range(TEST_ITERATIONS):
|
|
# 创建世界管理器和角色容器
|
|
var world_manager = WorldManager.new()
|
|
var character_container = Node2D.new()
|
|
character_container.name = "CharacterContainer"
|
|
|
|
add_child(world_manager)
|
|
add_child(character_container)
|
|
|
|
world_manager.set_character_container(character_container)
|
|
|
|
await get_tree().process_frame
|
|
|
|
# 生成随机数量的离线角色
|
|
var num_offline_characters = randi() % 5 + 1 # 1-5 个离线角色
|
|
var spawned_characters = []
|
|
|
|
for j in range(num_offline_characters):
|
|
var character_data = _generate_offline_character_data(j)
|
|
var character = world_manager.spawn_character(character_data, false)
|
|
|
|
if character:
|
|
spawned_characters.append({
|
|
"id": character_data[CharacterData.FIELD_ID],
|
|
"character": character
|
|
})
|
|
|
|
await get_tree().process_frame
|
|
|
|
# 验证所有离线角色都被正确显示为 NPC
|
|
var all_displayed = true
|
|
var display_errors = []
|
|
|
|
for char_info in spawned_characters:
|
|
var char_id = char_info["id"]
|
|
var character = char_info["character"]
|
|
|
|
# 检查角色是否在场景树中
|
|
if not is_instance_valid(character):
|
|
all_displayed = false
|
|
display_errors.append({
|
|
"character_id": char_id,
|
|
"error": "character_not_valid"
|
|
})
|
|
continue
|
|
|
|
if not character.is_inside_tree():
|
|
all_displayed = false
|
|
display_errors.append({
|
|
"character_id": char_id,
|
|
"error": "not_in_scene_tree"
|
|
})
|
|
continue
|
|
|
|
# 检查角色是否标记为离线
|
|
if character.is_online:
|
|
all_displayed = false
|
|
display_errors.append({
|
|
"character_id": char_id,
|
|
"error": "marked_as_online_instead_of_offline"
|
|
})
|
|
continue
|
|
|
|
# 检查角色是否可见(离线角色应该作为 NPC 显示)
|
|
if not character.visible:
|
|
all_displayed = false
|
|
display_errors.append({
|
|
"character_id": char_id,
|
|
"error": "not_visible"
|
|
})
|
|
|
|
# 验证离线角色仍然存在于世界中(不应被移除)
|
|
var managed_char = world_manager.get_character(char_id)
|
|
if not managed_char:
|
|
all_displayed = false
|
|
display_errors.append({
|
|
"character_id": char_id,
|
|
"error": "not_managed_by_world_manager"
|
|
})
|
|
|
|
# 验证世界管理器中记录的角色数量
|
|
var managed_characters = world_manager.get_all_characters()
|
|
if managed_characters.size() != num_offline_characters:
|
|
all_displayed = false
|
|
display_errors.append({
|
|
"error": "character_count_mismatch",
|
|
"expected": num_offline_characters,
|
|
"actual": managed_characters.size()
|
|
})
|
|
|
|
if all_displayed:
|
|
test_results["passed"] += 1
|
|
else:
|
|
test_results["failed"] += 1
|
|
test_results["errors"].append({
|
|
"iteration": i + 1,
|
|
"num_characters": num_offline_characters,
|
|
"errors": display_errors
|
|
})
|
|
|
|
# 清理
|
|
world_manager.clear_all_characters()
|
|
world_manager.queue_free()
|
|
character_container.queue_free()
|
|
await get_tree().process_frame
|
|
|
|
func _generate_offline_character_data(index: int) -> Dictionary:
|
|
"""生成离线角色数据"""
|
|
var character_data = CharacterData.create(
|
|
"OfflinePlayer" + str(index),
|
|
"owner_" + str(index),
|
|
Vector2(randf_range(100, 900), randf_range(100, 700))
|
|
)
|
|
|
|
# 确保角色标记为离线
|
|
character_data[CharacterData.FIELD_IS_ONLINE] = false
|
|
|
|
# 设置最后在线时间(模拟之前在线过)
|
|
character_data[CharacterData.FIELD_LAST_SEEN] = Time.get_unix_time_from_system() - randf_range(3600, 86400)
|
|
|
|
return character_data
|
|
|
|
func print_results():
|
|
"""打印测试结果"""
|
|
print("\n=== Test Results ===")
|
|
print("Total iterations: ", TEST_ITERATIONS)
|
|
print("Passed: ", test_results["passed"])
|
|
print("Failed: ", test_results["failed"])
|
|
|
|
if test_results["failed"] > 0:
|
|
print("\n❌ FAILED: Some iterations failed")
|
|
print("First 5 errors:")
|
|
for i in range(min(5, test_results["errors"].size())):
|
|
var error = test_results["errors"][i]
|
|
print(" Error ", i + 1, ": ", error)
|
|
else:
|
|
print("\n✅ PASSED: All offline characters displayed correctly as NPCs")
|
|
print("Property 23 validated: Offline characters persist in the world as NPCs")
|