# test_consumables_parity.gd —— 验证方向 4:日月神水自充能、龙神特药与传送卷轴 40250 1:1 对齐 extends SceneTree const ConsumableSystem = preload("res://consumable_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_consumables_parity (Direction 4: Consumables & Scrolls 1:1) ===") test_elixir_identification() test_elixir_toggle_active() test_elixir_recovery_and_exhaustion() test_dragon_god_potions() test_town_and_return_scrolls() print("\n=== SUMMARY: %d passed, %d failed ===" % [_passed, _failed]) if _failed > 0: printerr("TEST FAILED!") quit(1) else: print("ALL TESTS PASSED!") quit(0) func test_elixir_identification() -> void: print("\n--- Test 1: Sun & Moon Elixirs Identification ---") _assert(ConsumableSystem.is_elixir(72723), "72723 (Sun Elixir S) is an elixir") _assert(ConsumableSystem.is_hp_elixir(72723), "72723 is an HP elixir") _assert(not ConsumableSystem.is_sp_elixir(72723), "72723 is not an SP elixir") _assert(ConsumableSystem.is_elixir(72728), "72728 (Moon Elixir M) is an elixir") _assert(ConsumableSystem.is_sp_elixir(72728), "72728 is an SP elixir") _assert(not ConsumableSystem.is_hp_elixir(72728), "72728 is not an HP elixir") _assert(not ConsumableSystem.is_elixir(27001), "27001 Red Potion is not an elixir") _assert(ConsumableSystem.is_dragon_god_potion(71027), "71027 is Dragon God Potion") _assert(not ConsumableSystem.is_dragon_god_potion(72723), "Elixir is not Dragon God Potion") func test_elixir_toggle_active() -> void: print("\n--- Test 2: Sun/Moon Elixir Toggle Active (40250 char_item.cpp:3950) ---") var elixir_hp := {"vnum": 72723, "sockets": [0, 0, 0]} # Initially inactive var toggle1 := ConsumableSystem.toggle_elixir(elixir_hp) _assert(toggle1.ok and toggle1.active, "1st click activates HP elixir") _assert(elixir_hp.sockets[0] == 1, "Socket 0 is set to 1 (Active)") _assert(toggle1.affect_type == ConsumableSystem.AFFECT_AUTO_HP_RECOVERY, "Affect type is AFFECT_AUTO_HP_RECOVERY (534)") _assert(elixir_hp.sockets[2] == 1000000, "Initialized capacity to 1,000,000 HP") # 2nd click deactivates var toggle2 := ConsumableSystem.toggle_elixir(elixir_hp) _assert(toggle2.ok and not toggle2.active, "2nd click deactivates HP elixir") _assert(elixir_hp.sockets[0] == 0, "Socket 0 is set to 0 (Inactive)") func test_elixir_recovery_and_exhaustion() -> void: print("\n--- Test 3: Auto Recovery Tick & Capacity Depletion (40250 char_item.cpp:7326) ---") # Elixir with 500 capacity, initially active var small_elixir := {"vnum": 72723, "sockets": [1, 0, 500]} # Player at 800/1000 HP (needs 200) var tick1 := ConsumableSystem.process_elixir_recovery(small_elixir, 800, 1000) _assert(tick1.recovered == 200, "Recovered 200 HP to full") _assert(not tick1.exhausted, "Elixir not exhausted yet") _assert(small_elixir.sockets[1] == 200, "Used amount increased to 200") _assert(tick1.remaining == 300, "Remaining capacity is 300") # Player at 1000/1000 HP (full HP) var tick_full := ConsumableSystem.process_elixir_recovery(small_elixir, 1000, 1000) _assert(tick_full.recovered == 0, "No recovery when already at full HP") _assert(small_elixir.sockets[1] == 200, "Used amount unchanged") # Player at 600/1000 HP (needs 400, but only 300 left in elixir) var tick_deplete := ConsumableSystem.process_elixir_recovery(small_elixir, 600, 1000) _assert(tick_deplete.recovered == 300, "Recovered all remaining 300 HP") _assert(tick_deplete.exhausted, "Elixir is now exhausted (used >= capacity)") _assert(small_elixir.sockets[1] == 500, "Used amount reached full 500") func test_dragon_god_potions() -> void: print("\n--- Test 4: Dragon God Potions Buff Specs (71027..71030) ---") var p_att := ConsumableSystem.use_dragon_god_potion(ConsumableSystem.VNUM_DRAGON_GOD_ATTACK) _assert(p_att.ok and p_att.bonus_type == "POINT_ATT_BONUS" and p_att.bonus_value == 15, "Dragon God Attack gives +15% attack bonus") _assert(p_att.duration == 1800.0, "Dragon God Attack lasts 1800 seconds (30 minutes)") var p_def := ConsumableSystem.use_dragon_god_potion(ConsumableSystem.VNUM_DRAGON_GOD_DEFENSE) _assert(p_def.ok and p_def.bonus_type == "POINT_DEF_BONUS" and p_def.bonus_value == 15, "Dragon God Defense gives +15% defense bonus") var p_life := ConsumableSystem.use_dragon_god_potion(ConsumableSystem.VNUM_DRAGON_GOD_LIFE) _assert(p_life.ok and p_life.bonus_type == "POINT_MAX_HP_PCT" and p_life.bonus_value == 20, "Dragon God Life gives +20% HP bonus") var p_mana := ConsumableSystem.use_dragon_god_potion(ConsumableSystem.VNUM_DRAGON_GOD_MANA) _assert(p_mana.ok and p_mana.bonus_type == "POINT_MAX_SP_PCT" and p_mana.bonus_value == 20, "Dragon God Mana gives +20% SP bonus") func test_town_and_return_scrolls() -> void: print("\n--- Test 5: Town Scroll (22001) & Return Scroll (22010) ---") # Town Scroll 22001 var dummy_item := {"vnum": ConsumableSystem.VNUM_TOWN_SCROLL} var res_town := ConsumableSystem.use_warp_scroll(ConsumableSystem.VNUM_TOWN_SCROLL, dummy_item, 100.0, 200.0) _assert(res_town.ok and res_town.action == "TOWN_WARP" and res_town.consumed, "Town scroll triggers town warp and is consumed") # Return Scroll 22010 (Empty) -> Records current coordinate (1234, 5678) var return_scroll := {"vnum": ConsumableSystem.VNUM_RETURN_SCROLL, "sockets": [0, 0, 0]} var res_rec := ConsumableSystem.use_warp_scroll(ConsumableSystem.VNUM_RETURN_SCROLL, return_scroll, 1234.0, 5678.0, 2) _assert(res_rec.ok and res_rec.action == "RECORDED", "Empty return scroll records coordinate") _assert(not res_rec.consumed, "Recording coordinate does not consume the scroll") _assert(return_scroll.sockets[0] == 1234 and return_scroll.sockets[1] == 5678 and return_scroll.sockets[2] == 2, "Recorded coordinates saved into sockets [1234, 5678, map 2]") # Return Scroll 22010 (Recorded) -> Warps and is consumed var res_warp := ConsumableSystem.use_warp_scroll(ConsumableSystem.VNUM_RETURN_SCROLL, return_scroll, 999.0, 888.0, 1) _assert(res_warp.ok and res_warp.action == "WARP_TO_COORDS", "Recorded return scroll warps to saved location") _assert(res_warp.consumed, "Using recorded return scroll consumes the scroll") _assert(res_warp.target_x == 1234 and res_warp.target_y == 5678 and res_warp.target_map == 2, "Target coordinates match recorded values")