# test_compass_treasure_hunt_parity.gd —— 40250 魔石地脉探测罗盘与寻宝系统 1:1 回归测试套件 extends SceneTree const CompassTreasureHuntSystem = preload("res://compass_treasure_hunt_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_compass_treasure_hunt_parity (Direction 4: Compass Treasure Hunt 1:1) ===") _test_compass_scanning_and_charges() _test_excavation_at_dowsing_node() _test_key_opening() _finish() func _test_compass_scanning_and_charges() -> void: print("\n--- Test 1: Compass Scanning & 6-Charge Depletion ---") var sys := CompassTreasureHuntSystem.new() var inv: Array = [ {"vnum": CompassTreasureHuntSystem.VNUM_COMPASS_OF_METIN, "name": "魔石探测罗盘", "charges": 6} ] var player_pos := Vector2(0, 0) var metins: Array = [ {"name": "战斗魔石", "pos": Vector2(300, 300)}, {"name": "嫉妒魔石", "pos": Vector2(10, 10)}, # dist ~14.14m (VERY_CLOSE) {"name": "阴影魔石", "pos": Vector2(150, 20)} ] var scan_sig := {"fired": false, "target": "", "dist": 0.0, "prox": "", "charges": 0} sys.compass_scanned.connect(func(t: String, d: float, _a: float, p: String, c: int): scan_sig["fired"] = true scan_sig["target"] = t scan_sig["dist"] = d scan_sig["prox"] = p scan_sig["charges"] = c ) # Scan 1 var res1 = sys.scan_nearest_metin(player_pos, metins, inv, 0) _assert(res1["ok"] == true, "Compass scan 1 succeeded") _assert(res1["target_name"] == "嫉妒魔石", "Nearest metin is 嫉妒魔石") _assert(res1["proximity"] == CompassTreasureHuntSystem.PROXIMITY_VERY_CLOSE, "Proximity is VERY_CLOSE (< 20m)") _assert(res1["charges_left"] == 5, "Charges left is 5") _assert(scan_sig["fired"] == true, "compass_scanned signal emitted") # Deplete remaining 5 charges for i in range(4): sys.scan_nearest_metin(player_pos, metins, inv, 0) _assert(inv[0]["charges"] == 1, "1 charge remaining before last use") # 6th scan consumes the compass completely var res6 = sys.scan_nearest_metin(player_pos, metins, inv, 0) _assert(res6["ok"] == true, "6th scan succeeded") _assert(res6["charges_left"] == 0, "0 charges left") _assert(inv[0] == null, "Compass destroyed after 6 charges (slot 0 is null)") func _test_excavation_at_dowsing_node() -> void: print("\n--- Test 2: Treasure Excavation Nearby (< 5m) ---") var sys := CompassTreasureHuntSystem.new() var inv: Array = [null, null, null] var nodes: Array = [ {"pos": Vector2(50, 50), "is_gold": true}, {"pos": Vector2(200, 200), "is_gold": false} ] # 1. Player is far away at (0, 0) var res_far = sys.excavate_treasure(Vector2(0, 0), nodes, inv) _assert(res_far["ok"] == false, "Excavation rejected when > 5m") _assert(res_far["reason"] == "NO_TREASURE_NEARBY", "Reason is NO_TREASURE_NEARBY") var exc_sig := {"fired": false, "vnum": 0, "name": ""} sys.treasure_excavated.connect(func(v: int, n: String): exc_sig["fired"] = true exc_sig["vnum"] = v exc_sig["name"] = n ) # 2. Player approaches to (51, 50) -> dist is 1m <= 5m var res_succ = sys.excavate_treasure(Vector2(51, 50), nodes, inv) _assert(res_succ["ok"] == true, "Excavation succeeded") _assert(inv[0] != null and inv[0]["vnum"] == CompassTreasureHuntSystem.VNUM_GOLD_CHEST, "Golden Chest placed into slot 0") _assert(exc_sig["fired"] == true, "treasure_excavated signal emitted") _assert(nodes.size() == 1, "Excavated node removed from map") func _test_key_opening() -> void: print("\n--- Test 3: Golden/Silver Key Chest Opening ---") var sys := CompassTreasureHuntSystem.new() var inv: Array = [ {"vnum": CompassTreasureHuntSystem.VNUM_GOLD_CHEST, "name": "黄金宝箱"}, {"vnum": CompassTreasureHuntSystem.VNUM_SILVER_KEY, "name": "白银钥匙", "count": 1}, {"vnum": CompassTreasureHuntSystem.VNUM_GOLD_KEY, "name": "黄金钥匙", "count": 1}, null, null, null ] # 1. Open Golden Chest with Silver Key -> mismatch var res_mismatch = sys.open_treasure_chest(0, 1, inv) _assert(res_mismatch["ok"] == false, "Key mismatch rejected") _assert(res_mismatch["reason"] == "KEY_MISMATCH", "Reason is KEY_MISMATCH") var open_sig := {"fired": false, "rewards": []} sys.treasure_opened.connect(func(_n: String, rew: Array): open_sig["fired"] = true open_sig["rewards"] = rew ) # 2. Open Golden Chest with Golden Key (slot 0 & slot 2) var res_succ = sys.open_treasure_chest(0, 2, inv) var chest_remains = false var key_remains = false for it in inv: if it != null: if int(it.get("vnum", 0)) == CompassTreasureHuntSystem.VNUM_GOLD_CHEST: chest_remains = true elif int(it.get("vnum", 0)) == CompassTreasureHuntSystem.VNUM_GOLD_KEY: key_remains = true _assert(not chest_remains, "Chest consumed") _assert(not key_remains, "Key consumed") _assert(open_sig["fired"] == true, "treasure_opened signal emitted") _assert(open_sig["rewards"].size() == 3, "Received 3 rare rewards") # Check blessing scroll in inventory var scroll_found := false for it in inv: if it != null and int(it.get("vnum", 0)) == 25040: scroll_found = true break _assert(scroll_found == true, "Blessing Scroll found in rewards") func _finish() -> void: print("\n=======================================================") print("Compass & Treasure Hunt Parity Tests: %d Passed, %d Failed" % [_passed, _failed]) print("=======================================================\n") if _failed > 0: quit(1) else: quit(0)