# dungeon_ranking_system.gd —— Metin2 40250 地牢信息面板与最速通关记录系统 1:1 # 对照 40250 服务端与客户端 dungeon_info.cpp, dungeon.cpp, uidungeoninfo.py class_name DungeonRankingSystem extends RefCounted signal record_updated(dungeon_id: String, fastest_time: float, total_clears: int) signal new_fastest_record(dungeon_id: String, new_time: float, old_time: float) # 40250 官方经典地牢登记表 const DUNGEON_REGISTRY: Dictionary = { "demon_tower": { "name": "恶魔之塔", "min_level": 40, "ticket_vnum": 0, "ticket_count": 0, "ticket_name": "无", "cooldown_seconds": 0.0 }, "spider_dungeon_3": { "name": "蜘蛛洞穴三层", "min_level": 50, "ticket_vnum": 30327, "ticket_count": 1, "ticket_name": "蜘蛛钥匙", "cooldown_seconds": 1800.0 # 30 分钟 }, "dragon_lair": { "name": "冰龙贝兰巢穴", "min_level": 75, "ticket_vnum": 30179, "ticket_count": 3, "ticket_name": "扭曲钥匙", "cooldown_seconds": 3600.0 # 60 分钟 }, "devils_catacomb": { "name": "地下墓穴", "min_level": 75, "ticket_vnum": 30311, "ticket_count": 1, "ticket_name": "灵魂水晶钥匙", "cooldown_seconds": 3600.0 # 60 分钟 } } # 个人通关数据字典: dungeon_id -> Dictionary var dungeon_records: Dictionary = {} func _init() -> void: for d_id in DUNGEON_REGISTRY.keys(): dungeon_records[d_id] = { "total_clears": 0, "fastest_clear_time": 999999.0, # 初始极大值 "highest_peak_damage": 0, "last_clear_timestamp": 0.0 } # 记录通关结算 func record_clear( dungeon_id: String, clear_time_sec: float, peak_damage: int, current_timestamp: float = 0.0 ) -> Dictionary: if not DUNGEON_REGISTRY.has(dungeon_id): return {"ok": false, "reason": "INVALID_DUNGEON_ID", "msg": "未知的地牢!"} var rec = dungeon_records[dungeon_id] rec["total_clears"] += 1 rec["last_clear_timestamp"] = current_timestamp # 检查并更新最高单次输出伤害 if peak_damage > int(rec["highest_peak_damage"]): rec["highest_peak_damage"] = peak_damage # 检查是否刷新最速通关记录 var is_new_record := false var old_time: float = float(rec["fastest_clear_time"]) if clear_time_sec < old_time: is_new_record = true rec["fastest_clear_time"] = clear_time_sec new_fastest_record.emit(dungeon_id, clear_time_sec, old_time) record_updated.emit(dungeon_id, rec["fastest_clear_time"], rec["total_clears"]) var dname: String = DUNGEON_REGISTRY[dungeon_id]["name"] return { "ok": true, "dungeon_id": dungeon_id, "dungeon_name": dname, "clear_time": clear_time_sec, "is_new_record": is_new_record, "fastest_time": rec["fastest_clear_time"], "total_clears": rec["total_clears"], "highest_peak_damage": rec["highest_peak_damage"], "msg": "【%s】通关成功!耗时 %.1f 秒%s!" % [dname, clear_time_sec, " (刷新最快纪录!)" if is_new_record else ""] } # 获取地牢详情与入场/冷却状态 func get_dungeon_info(dungeon_id: String, current_timestamp: float = 0.0) -> Dictionary: if not DUNGEON_REGISTRY.has(dungeon_id): return {"ok": false, "reason": "INVALID_DUNGEON_ID"} var cfg = DUNGEON_REGISTRY[dungeon_id] var rec = dungeon_records[dungeon_id] # 判定冷却时间 var cd_sec: float = float(cfg["cooldown_seconds"]) var last_ts: float = float(rec["last_clear_timestamp"]) var elapsed := current_timestamp - last_ts var is_on_cooldown := (cd_sec > 0.0 and last_ts > 0.0 and elapsed < cd_sec) var remaining_cd := maxf(0.0, cd_sec - elapsed) if is_on_cooldown else 0.0 return { "ok": true, "dungeon_id": dungeon_id, "name": cfg["name"], "min_level": cfg["min_level"], "ticket_vnum": cfg["ticket_vnum"], "ticket_count": cfg["ticket_count"], "ticket_name": cfg["ticket_name"], "is_on_cooldown": is_on_cooldown, "remaining_cooldown": remaining_cd, "total_clears": rec["total_clears"], "fastest_clear_time": rec["fastest_clear_time"] if rec["fastest_clear_time"] < 999999.0 else 0.0, "highest_peak_damage": rec["highest_peak_damage"] } # 获取全部地牢摘要速览列表 func get_all_dungeon_summaries(current_timestamp: float = 0.0) -> Array: var list: Array = [] for d_id in DUNGEON_REGISTRY.keys(): list.append(get_dungeon_info(d_id, current_timestamp)) return list