# test_spider_dungeon_key_parity.gd —— 40250 蜘蛛洞穴通行证与蛛后巢穴密匙系统 1:1 回归测试套件 extends SceneTree const SpiderDungeonKeySystem = preload("res://spider_dungeon_key_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_spider_dungeon_key_parity (Direction 4: Spider Dungeon Key 1:1) ===") _test_passage_ticket_entry() _test_arachnid_key_crafting() _test_baroness_lair_and_boss_fight() _test_lair_timeout() _test_serialization() _finish() func _test_passage_ticket_entry() -> void: print("\n--- Test 1: Passage Ticket (71095) Entry to SD2 & SD3 ---") var sys := SpiderDungeonKeySystem.new() var inv: Array = [ {"vnum": SpiderDungeonKeySystem.VNUM_PASSAGE_TICKET, "name": "蛛洞通行证", "count": 2} ] # 1. Level too low (< 40 for SD2) var res_low = sys.enter_spider_dungeon(2, 35, inv) _assert(res_low["ok"] == false, "Entry rejected: level 35 < 40") _assert(res_low["reason"] == "LEVEL_TOO_LOW", "Reason is LEVEL_TOO_LOW") var entry_sig := {"fired": false, "floor": 0, "map": ""} sys.ticket_consumed_entry_granted.connect(func(f: int, m: String): entry_sig["fired"] = true entry_sig["floor"] = f entry_sig["map"] = m ) # 2. Enter SD2 (Lv 45) var res_sd2 = sys.enter_spider_dungeon(2, 45, inv) _assert(res_sd2["ok"] == true, "Entered SD2 successfully") _assert(inv[0]["count"] == 1, "Ticket count decremented 2 -> 1") _assert(entry_sig["fired"] == true, "ticket_consumed_entry_granted signal emitted") _assert(entry_sig["floor"] == 2 and entry_sig["map"] == "Spider_Dungeon_2", "Floor 2 reported") # 3. Enter SD3 (Lv 55) var res_sd3 = sys.enter_spider_dungeon(3, 55, inv) _assert(res_sd3["ok"] == true, "Entered SD3 successfully") _assert(inv[0] == null, "Last ticket consumed completely") _assert(entry_sig["floor"] == 3 and entry_sig["map"] == "Spider_Dungeon_3", "Floor 3 reported") # 4. Attempt enter without ticket var res_no_ticket = sys.enter_spider_dungeon(2, 50, inv) _assert(res_no_ticket["ok"] == false, "Entry rejected without ticket") _assert(res_no_ticket["reason"] == "NO_PASSAGE_TICKET", "Reason is NO_PASSAGE_TICKET") func _test_arachnid_key_crafting() -> void: print("\n--- Test 2: Crafting Arachnid Key (30324) at Scholar Uriel ---") var sys := SpiderDungeonKeySystem.new() var player_gold := {"gold": 100000} var inv: Array = [ {"vnum": SpiderDungeonKeySystem.VNUM_SPIDER_POISON_SACK, "name": "蜘蛛毒囊", "count": 1}, {"vnum": SpiderDungeonKeySystem.VNUM_SPIDER_EGG_SACK, "name": "蜘蛛卵囊", "count": 1}, {"vnum": SpiderDungeonKeySystem.VNUM_SPIDER_EYES, "name": "蜘蛛眼睛", "count": 1}, {"vnum": SpiderDungeonKeySystem.VNUM_SPIDER_LEGS, "name": "蜘蛛腿", "count": 1} ] var craft_sig := {"fired": false, "count": 0} sys.arachnid_key_crafted.connect(func(c: int): craft_sig["fired"] = true craft_sig["count"] = c ) # 1. Missing Gold test player_gold["gold"] = 1000 var res_no_gold = sys.craft_arachnid_key(inv, player_gold) _assert(res_no_gold["ok"] == false, "Crafting rejected: gold 1000 < 50000") _assert(res_no_gold["reason"] == "NOT_ENOUGH_GOLD", "Reason is NOT_ENOUGH_GOLD") # 2. Successful craft with 50,000 gold player_gold["gold"] = 80000 var res_craft = sys.craft_arachnid_key(inv, player_gold) _assert(res_craft["ok"] == true, "Crafted Arachnid Key successfully") _assert(player_gold["gold"] == 30000, "50,000 gold deducted (80000 -> 30000)") _assert(craft_sig["fired"] == true, "arachnid_key_crafted signal emitted") # Verify key exists in inventory var key_found := false for it in inv: if it != null and int(it.get("vnum", 0)) == SpiderDungeonKeySystem.VNUM_ARACHNID_KEY: key_found = true break _assert(key_found == true, "Arachnid Key (30324) generated in inventory") func _test_baroness_lair_and_boss_fight() -> void: print("\n--- Test 3: Baroness Lair Entry, Boss Slay & Rewards ---") var sys := SpiderDungeonKeySystem.new() var inv: Array = [ {"vnum": SpiderDungeonKeySystem.VNUM_ARACHNID_KEY, "name": "蛛网密匙", "count": 1}, null, null, null ] var open_sig := {"fired": false, "dur": 0.0} sys.baroness_lair_opened.connect(func(d: float): open_sig["fired"] = true open_sig["dur"] = d ) var slay_sig := {"fired": false, "drops": []} sys.baroness_slain.connect(func(d: Array): slay_sig["fired"] = true slay_sig["drops"] = d ) # 1. Open Lair with key var res_open = sys.open_baroness_lair(55, inv) _assert(res_open["ok"] == true, "Baroness Lair opened") _assert(sys.is_lair_active == true, "Lair is active") _assert(sys.baroness_alive == true, "Spider Baroness is alive") _assert(inv[0] == null, "Arachnid key consumed") _assert(open_sig["fired"] == true, "baroness_lair_opened signal emitted") _assert(open_sig["dur"] == 1200.0, "Lair duration is 1200s (20 min)") # 2. Slay Baroness var res_slay = sys.slay_baroness(inv) _assert(res_slay["ok"] == true, "Baroness defeated") _assert(sys.is_lair_active == false, "Lair closed after victory") _assert(slay_sig["fired"] == true, "baroness_slain signal emitted") # Check drops in inventory var chest_found := false for it in inv: if it != null and int(it.get("vnum", 0)) == SpiderDungeonKeySystem.VNUM_CHEST_BARONESS: chest_found = true break _assert(chest_found == true, "King Spider Chest (50181) received in inventory") func _test_lair_timeout() -> void: print("\n--- Test 4: Lair Timeout Failure ---") var sys := SpiderDungeonKeySystem.new() var inv: Array = [ {"vnum": SpiderDungeonKeySystem.VNUM_ARACHNID_KEY, "name": "蛛网密匙", "count": 1} ] sys.open_baroness_lair(55, inv) var close_sig := {"fired": false, "succ": true} sys.lair_closed.connect(func(s: bool): close_sig["fired"] = true close_sig["succ"] = s ) # Advance time by 1200s sys.update(1200.0) _assert(sys.is_lair_active == false, "Lair closed upon timeout") _assert(close_sig["fired"] == true, "lair_closed signal emitted") _assert(close_sig["succ"] == false, "Failed challenge due to timeout") func _test_serialization() -> void: print("\n--- Test 5: Serialization & Restoration ---") var sys1 := SpiderDungeonKeySystem.new() var inv: Array = [ {"vnum": SpiderDungeonKeySystem.VNUM_ARACHNID_KEY, "name": "蛛网密匙", "count": 1} ] sys1.open_baroness_lair(55, inv) sys1.update(300.0) # 900s left var data = sys1.serialize() _assert(data["is_lair_active"] == true, "Serialized is_lair_active") var sys2 := SpiderDungeonKeySystem.new() sys2.deserialize(data) _assert(sys2.is_lair_active == true, "Restored is_lair_active") _assert(sys2.baroness_alive == true, "Restored baroness_alive") _assert(is_equal_approx(sys2.lair_time_remaining, 900.0), "Restored time remaining 900s") func _finish() -> void: print("\n=======================================================") print("Spider Dungeon Key Parity Tests: %d Passed, %d Failed" % [_passed, _failed]) print("=======================================================\n") if _failed > 0: quit(1) else: quit(0)