# flame_dungeon_razador_system.gd —— Metin2 40250 经典红龙烈焰神殿与拉扎多尔炼狱试炼 1:1 # 对照 40250 服务端 flame_dungeon.start.1.script, quest/flame_dungeon*, char_item.cpp class_name FlameDungeonRazadorSystem extends RefCounted signal dungeon_entered(time_limit: float) signal stage_advanced(new_stage: int, stage_desc: String) signal altar_lit(altars_lit: int, total_altars: int) signal razador_spawned(mob_vnum: int) signal razador_slain(drop_rewards: Array) signal dungeon_completed() signal dungeon_failed(reason: String) const NPC_AM_HEH_WATCHER := 20385 # 烈焰守望者 (Am-heh Watcher) const MIN_ENTRY_LEVEL := 100 # 进入等级门槛 100 级 const VNUM_TICKET_71095 := 71095 # 通行证 const VNUM_TICKET_71130 := 71130 # 烈焰通行证 const MOB_RAZADOR := 6091 # 烈焰魔王拉扎多尔 (Razador) const VNUM_RAZADOR_CHEST := 50186 # 拉扎多尔宝箱 const DUNGEON_TIME_LIMIT := 2700.0 # 45 分钟 (2700 秒) # 7 大炼狱阶段定义 const STAGES_DESC: Array = [ "阶段 1: 清剿外围烈焰魔群", "阶段 2: 寻觅正确齿轮诛灭引火者", "阶段 3: 破灭炼狱灭世魔石", "阶段 4: 诛灭四极炼狱护法", "阶段 5: 使用真·玛阿特之石点燃五方火盆", "阶段 6: 击碎烈焰火轮魔石", "阶段 7: 进军神殿核心,决战烈焰魔王拉扎多尔!" ] var is_active: bool = false var current_stage: int = 1 var time_remaining: float = 0.0 var altars_lit_count: int = 0 var razador_alive: bool = false # 检票进入烈焰神殿 (40250 flame_dungeon.start.1.script) func enter_dungeon(player_level: int, inventory: Array) -> Dictionary: if is_active: return {"ok": false, "reason": "DUNGEON_ALREADY_ACTIVE", "msg": "神殿试炼已在进行中!"} if player_level < MIN_ENTRY_LEVEL: return { "ok": false, "reason": "LEVEL_TOO_LOW", "msg": "实力不足!开启拉扎多尔烈焰试炼需角色达到 %d 级。" % MIN_ENTRY_LEVEL } # 检查并消耗 1 张通行证 (71095 或 71130) var ticket_slot := -1 for i in range(inventory.size()): if inventory[i] != null: var v := int(inventory[i].get("vnum", 0)) if v == VNUM_TICKET_71095 or v == VNUM_TICKET_71130: ticket_slot = i break if ticket_slot == -1: return {"ok": false, "reason": "NO_ENTRY_TICKET", "msg": "守望者拦住了去路!需要持有【烈焰通行证】(71095/71130)。"} var t_item: Dictionary = inventory[ticket_slot] var cnt := int(t_item.get("count", 1)) if cnt > 1: t_item["count"] = cnt - 1 else: inventory[ticket_slot] = null is_active = true current_stage = 1 time_remaining = DUNGEON_TIME_LIMIT altars_lit_count = 0 razador_alive = false dungeon_entered.emit(DUNGEON_TIME_LIMIT) stage_advanced.emit(1, STAGES_DESC[0]) return { "ok": true, "time_limit": DUNGEON_TIME_LIMIT, "stage": 1, "stage_desc": STAGES_DESC[0], "msg": "通行证校验通过!烈焰之门轰然开启,限时 45 分钟挑战拉扎多尔!" } # 推进阶段目标 func advance_stage() -> Dictionary: if not is_active: return {"ok": false, "reason": "DUNGEON_NOT_ACTIVE"} if current_stage < 7: current_stage += 1 var desc: String = STAGES_DESC[current_stage - 1] if current_stage == 7: # 召唤最终首领拉扎多尔 razador_alive = true razador_spawned.emit(MOB_RAZADOR) stage_advanced.emit(current_stage, desc) return { "ok": true, "current_stage": current_stage, "stage_desc": desc, "msg": "试炼突破!开启【%s】。" % desc } return {"ok": false, "reason": "ALREADY_AT_FINAL_STAGE"} # 阶段 5 点燃玛阿特火盆 func light_fire_altar() -> Dictionary: if not is_active or current_stage != 5: return {"ok": false, "reason": "NOT_IN_ALTAR_STAGE"} altars_lit_count = mini(5, altars_lit_count + 1) altar_lit.emit(altars_lit_count, 5) if altars_lit_count >= 5: # 5 座火盆全部点燃,自动迈入第 6 阶段 advance_stage() return { "ok": true, "altars_lit": 5, "stage_cleared": true, "msg": "五方火盆全部燃起纯阳烈焰!封印解除,进入下一阶段!" } return { "ok": true, "altars_lit": altars_lit_count, "stage_cleared": false, "msg": "成功点燃 1 座火盆!当前进度:(%d / 5)。" % [altars_lit_count] } # 斩杀烈焰魔王拉扎多尔 func slay_razador(inventory: Array) -> Dictionary: if not is_active or not razador_alive: return {"ok": false, "reason": "RAZADOR_NOT_ALIVE"} razador_alive = false var rewards: Array = [ {"vnum": VNUM_RAZADOR_CHEST, "name": "拉扎多尔宝箱", "count": 1}, {"vnum": 25040, "name": "祝福卷轴", "count": 3}, {"vnum": 51501, "name": "龙石炼金原石", "count": 2} ] for drop in rewards: for i in range(inventory.size()): if inventory[i] == null: inventory[i] = drop.duplicate(true) break razador_slain.emit(rewards) # 通关副本 is_active = false time_remaining = 0.0 dungeon_completed.emit() return { "ok": true, "rewards": rewards, "msg": "伟大的征服!烈焰魔王拉扎多尔陨落!斩获【拉扎多尔宝箱】!" } # 逻辑心跳更新 func update(delta: float) -> void: if not is_active: return time_remaining -= delta if time_remaining <= 0.0: is_active = false razador_alive = false dungeon_failed.emit("TIMEOUT") # 序列化 func serialize() -> Dictionary: return { "is_active": is_active, "current_stage": current_stage, "time_remaining": time_remaining, "altars_lit_count": altars_lit_count, "razador_alive": razador_alive } # 反序列化 func deserialize(data: Dictionary) -> void: is_active = bool(data.get("is_active", false)) current_stage = int(data.get("current_stage", 1)) time_remaining = float(data.get("time_remaining", 0.0)) altars_lit_count = int(data.get("altars_lit_count", 0)) razador_alive = bool(data.get("razador_alive", false))