# test_classic_pet_parity.gd —— 40250 经典封印宠物系统 1:1 回归测试套件 extends SceneTree const ClassicPetSystem = preload("res://classic_pet_system.gd") var _passed := 0 var _failed := 0 func _assert(cond: bool, msg: String) -> void: if cond: _passed += 1 print(" [PASS] %s" % msg) else: _failed += 1 printerr(" [FAIL] %s" % msg) func _init() -> void: print("\n=== Running test_classic_pet_parity (Direction 1: Classic Pet System 1:1) ===") _test_summon_and_buff_application() _test_auto_unsummon_previous_pet() _test_dungeon_only_buff_condition() _test_follow_and_teleport_ai() _test_serialization() _finish() func _test_summon_and_buff_application() -> void: print("\n--- Test 1: Summon & Buff Injection/Removal ---") var sys := ClassicPetSystem.new() var player := {"max_hp": 5000, "attack_pct": 0, "defense_pct": 0} var seal_firedrake := {"vnum": ClassicPetSystem.SEAL_BABY_FIREDRAKE} var summon_sig := {"fired": false, "vnum": 0, "name": ""} sys.pet_summoned.connect(func(v: int, n: String, _b: Dictionary): summon_sig["fired"] = true summon_sig["vnum"] = v summon_sig["name"] = n ) var unsummon_sig := {"fired": false, "vnum": 0} sys.pet_unsummoned.connect(func(v: int, _n: String): unsummon_sig["fired"] = true unsummon_sig["vnum"] = v ) # Summon Baby Firedrake var res = sys.summon_pet(seal_firedrake, player, false, Vector2.ZERO) _assert(res["ok"] == true, "Summon succeeded") _assert(sys.is_summoned == true, "System reports pet is summoned") _assert(sys.active_mob_vnum == ClassicPetSystem.MOB_BABY_FIREDRAKE, "Mob vnum is 34005") _assert(player["max_hp"] == 6500, "HP increased by 1500 (5000 -> 6500)") _assert(player["attack_pct"] == 15, "Attack pct increased by 15%") _assert(summon_sig["fired"] == true, "pet_summoned signal emitted") # Unsummon var un_res = sys.unsummon_pet(player) _assert(un_res["ok"] == true, "Unsummon succeeded") _assert(sys.is_summoned == false, "System reports pet unsummoned") _assert(player["max_hp"] == 5000, "HP reversed back to 5000") _assert(player["attack_pct"] == 0, "Attack pct reversed back to 0%") _assert(unsummon_sig["fired"] == true, "pet_unsummoned signal emitted") func _test_auto_unsummon_previous_pet() -> void: print("\n--- Test 2: Auto Unsummon Previous Pet When Summoning New ---") var sys := ClassicPetSystem.new() var player := {"monster_damage_pct": 0, "defense_pct": 0, "max_hp": 10000} # 1. Summon Boar (+15% monster damage) sys.summon_pet({"vnum": ClassicPetSystem.SEAL_BABY_BOAR}, player, false) _assert(player["monster_damage_pct"] == 15, "Boar buff applied (+15% monster dmg)") # 2. Directly summon Ice Phoenix (+15% def, +1500 HP) sys.summon_pet({"vnum": ClassicPetSystem.SEAL_ICE_PHOENIX}, player, false) _assert(sys.active_mob_vnum == ClassicPetSystem.MOB_ICE_PHOENIX, "Now Ice Phoenix is active") _assert(player["monster_damage_pct"] == 0, "Previous Boar buff cleared") _assert(player["defense_pct"] == 15, "Phoenix defense buff applied (+15%)") _assert(player["max_hp"] == 11500, "Phoenix HP buff applied (+1500)") func _test_dungeon_only_buff_condition() -> void: print("\n--- Test 3: 40250 Dungeon-Only Buff Validation (Baby Azrael) ---") var sys := ClassicPetSystem.new() var seal_azrael := {"vnum": ClassicPetSystem.SEAL_BABY_AZRAEL} # In normal field map (not in dungeon) var player1 := {"max_hp": 5000, "dungeon_attack_pct": 0} sys.summon_pet(seal_azrael, player1, false) _assert(player1["max_hp"] == 6000, "Azrael standard HP (+1000) applied in field") _assert(player1["dungeon_attack_pct"] == 0, "Dungeon attack buff not applied outside dungeon") sys.unsummon_pet(player1) # Inside dungeon var player2 := {"max_hp": 5000, "dungeon_attack_pct": 0} sys.summon_pet(seal_azrael, player2, true) _assert(player2["max_hp"] == 6000, "Azrael standard HP (+1000) applied in dungeon") _assert(player2["dungeon_attack_pct"] == 20, "Dungeon attack buff (+20%) successfully applied in dungeon") sys.unsummon_pet(player2) _assert(player2["dungeon_attack_pct"] == 0, "Dungeon buff cleared after unsummon") func _test_follow_and_teleport_ai() -> void: print("\n--- Test 4: Follow AI (Idle, Follow, Teleport) ---") var sys := ClassicPetSystem.new() var dummy_stats := {} sys.summon_pet({"vnum": ClassicPetSystem.SEAL_BABY_BOAR}, dummy_stats, false, Vector2(0, 0)) # Owner is at (1, 0) -> dist is 1.5 - 1.0 = 0.5 (< 2.0 MIN_FOLLOW_DIST) var ai_idle = sys.update_follow_ai(Vector2(1.0, 0.0), 0.1) _assert(ai_idle["action"] == "idle", "AI stays idle when within 2.0m") # Owner walks away to (8, 0) -> dist > 2.0m var ai_follow = sys.update_follow_ai(Vector2(8.0, 0.0), 0.5) _assert(ai_follow["action"] == "follow", "AI follows owner when distance > 2.0m") # Owner warps/runs far away to (100, 100) -> dist > 15.0m var move_sig := {"fired": false, "teleport": false} sys.pet_moved.connect(func(_pos: Vector2, is_tele: bool): move_sig["fired"] = true move_sig["teleport"] = is_tele ) var ai_tele = sys.update_follow_ai(Vector2(100.0, 100.0), 0.1) _assert(ai_tele["action"] == "teleport", "AI teleports when distance > 15.0m") _assert(move_sig["teleport"] == true, "pet_moved signal reported teleport") func _test_serialization() -> void: print("\n--- Test 5: State Serialization & Restoration ---") var sys1 := ClassicPetSystem.new() var dummy_stats := {"max_hp": 5000} sys1.summon_pet({"vnum": ClassicPetSystem.SEAL_BABY_FIREDRAKE}, dummy_stats, false, Vector2(10, 20)) var data = sys1.serialize() _assert(data["is_summoned"] == true, "Serialized is_summoned") _assert(data["active_mob_vnum"] == ClassicPetSystem.MOB_BABY_FIREDRAKE, "Serialized mob vnum") _assert(data["active_seal_vnum"] == ClassicPetSystem.SEAL_BABY_FIREDRAKE, "Serialized seal vnum") var sys2 := ClassicPetSystem.new() sys2.deserialize(data) _assert(sys2.is_summoned == true, "Restored is_summoned") _assert(sys2.active_mob_vnum == ClassicPetSystem.MOB_BABY_FIREDRAKE, "Restored mob vnum") _assert(sys2.active_pet_name == "幼火龙", "Restored pet name") func _finish() -> void: print("\n=======================================================") print("Classic Pet System Parity Tests: %d Passed, %d Failed" % [_passed, _failed]) print("=======================================================\n") if _failed > 0: quit(1) else: quit(0)