# test_combat_status_effect_parity.gd —— Metin2 40250 战斗状态异常与负面减益 1:1 测试套件 extends SceneTree const CombatStatusEffectSystem = preload("res://combat_status_effect_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_combat_status_effect_parity (Direction 2: Combat Status Effects 1:1) ===") test_stun_and_immunity() test_slow_and_immunity() test_poison_mechanics_and_regen_block() test_fire_damage_ticks() test_cure_and_serialization() print("\n=======================================================") print("Combat Status Effect Tests: %d Passed, %d Failed" % [_passed, _failed]) print("=======================================================\n") if _failed > 0: quit(1) else: quit(0) func test_stun_and_immunity() -> void: print("\n--- Test 1: Stun & IMMUNE_STUN (40250 1:1) ---") var system = CombatStatusEffectSystem.new() var attacker = {"id": 1, "is_pc": true, "stun_pct": 20} var victim_normal = {"id": 101, "is_pc": false, "immune_stun": false} var victim_shielded = {"id": 102, "is_pc": false, "immune_stun": true} # 1. 普通怪物被击中眩晕 (PvE 4秒) var res = system.try_apply_normal_attack_effects(attacker, victim_normal, {"stun_pct_roll": 10}) _assert(res["applied"].has(CombatStatusEffectSystem.EFFECT_STUN), "Applied stun to normal monster") _assert(system.is_stunned(101) == true, "Target 101 is stunned") # 2. 携带免疫眩晕盾牌的目标 (IMMUNE_STUN) -> 100% 抵抗 res = system.try_apply_normal_attack_effects(attacker, victim_shielded, {"stun_pct_roll": 5}) _assert(not res["applied"].has(CombatStatusEffectSystem.EFFECT_STUN), "Stun avoided") _assert(res["resisted"].has("immune_stun"), "Resisted via immune_stun") _assert(system.is_stunned(102) == false, "Target 102 is not stunned") func test_slow_and_immunity() -> void: print("\n--- Test 2: Slow & IMMUNE_SLOW (40250 1:1) ---") var system = CombatStatusEffectSystem.new() var attacker = {"id": 1, "slow_pct": 15} var victim_normal = {"id": 201, "immune_slow": false} var victim_immune = {"id": 202, "immune_slow": true} # 1. 成功施加减速 var res = system.try_apply_normal_attack_effects(attacker, victim_normal, {"slow_pct_roll": 10}) _assert(res["applied"].has(CombatStatusEffectSystem.EFFECT_SLOW), "Applied slow") _assert(system.get_slow_reduction(201) == 30, "Speed reduced by 30 points") # 2. 免疫减速抵抗 res = system.try_apply_normal_attack_effects(attacker, victim_immune, {"slow_pct_roll": 5}) _assert(res["resisted"].has("immune_slow"), "Resisted via immune_slow") _assert(system.get_slow_reduction(202) == 0, "No speed reduction") func test_poison_mechanics_and_regen_block() -> void: print("\n--- Test 3: Poison Damage, HP Regen Block & Monster Single Poison (40250 1:1) ---") var system = CombatStatusEffectSystem.new() var attacker = {"id": 1, "is_pc": true, "level": 50, "poison_pct": 100} var monster = {"id": 301, "is_pc": false, "level": 50, "max_hp": 2000, "hp": 2000, "has_been_poisoned": false} # 1. 成功施加中毒 var res = system.try_apply_normal_attack_effects(attacker, monster, {"poison_pct_roll": 50}) _assert(res["applied"].has(CombatStatusEffectSystem.EFFECT_POISON), "Applied poison") _assert(system.has_effect(301, CombatStatusEffectSystem.EFFECT_POISON) == true, "Monster has poison effect") _assert(system.is_natural_hp_regen_blocked(301) == true, "Poison blocks natural HP regen") _assert(monster["has_been_poisoned"] == true, "Monster recorded has_been_poisoned") # 2. 心跳更新 3 秒触发跳毒 (5% of 2000 = 100 伤害) var targets_map = {301: monster} system.update(3.0, targets_map) _assert(monster["hp"] == 1900, "HP reduced from 2000 to 1900 after first poison tick") # 3. 怪物在解除中毒后不再被第二次中毒 (40250 char_resist.cpp: m_bHasPoisoned && !IsPC()) system.clear_effect(301, CombatStatusEffectSystem.EFFECT_POISON) res = system.try_apply_normal_attack_effects(attacker, monster, {"poison_pct_roll": 10}) _assert(not res["applied"].has(CombatStatusEffectSystem.EFFECT_POISON), "Monster rejected second poison") _assert(res["resisted"].has("poison_already_poisoned_once"), "Resisted as monster poisoned once") func test_fire_damage_ticks() -> void: print("\n--- Test 4: Fire Burn Damage Ticks (40250 1:1) ---") var system = CombatStatusEffectSystem.new() var victim = {"id": 401, "hp": 500} var targets_map = {401: victim} # 施加烈焰灼烧: 3 次跳伤,每次 60 点 system.apply_fire(401, 3, 60) _assert(system.has_effect(401, CombatStatusEffectSystem.EFFECT_FIRE) == true, "Has fire effect") # 经过 3 秒 system.update(3.0, targets_map) _assert(victim["hp"] == 440, "HP dropped by 60 to 440") # 经过 6 秒 (跳完剩余 2 次,共 180 伤害,生命为 500 - 180 = 320) system.update(6.0, targets_map) _assert(victim["hp"] == 320, "HP dropped to 320") _assert(system.has_effect(401, CombatStatusEffectSystem.EFFECT_FIRE) == false, "Fire effect expired") func test_cure_and_serialization() -> void: print("\n--- Test 5: Curing & State Serialization ---") var system = CombatStatusEffectSystem.new() system.apply_stun(501, 4.0) var victim = {"id": 502, "max_hp": 1000, "hp": 1000} system.apply_poison(victim) _assert(system.has_effect(502, CombatStatusEffectSystem.EFFECT_POISON) == true, "Poison active") # 使用解毒药剂清除中毒 var cleared = system.clear_effect(502, CombatStatusEffectSystem.EFFECT_POISON) _assert(cleared == true, "Poison cleared via antidote") _assert(system.has_effect(502, CombatStatusEffectSystem.EFFECT_POISON) == false, "No longer poisoned") var data = system.serialize() var restored = CombatStatusEffectSystem.new() restored.deserialize(data) _assert(restored.is_stunned(501) == true, "Restored stun effect")