传奇闯关地图脚本制作:单人限时、动态刷怪与多层接力机制详解

来源: 作者: 点击:
在传奇服务端中实现一个结构严谨的闯关副本,核心在于利用全局变量(G)和人物变量(HUMAN)来精确控制玩家状态、地图占用情况以及怪物刷新逻辑。你需要创建三个核心脚本文件:一个用于进入前的条件检查(QManage.txt),一个用于处理每层内部逻辑的公共脚本(QFunction-0.txt),以及一个专门负责动态刷怪的触发脚本(通常也放在QFunction-0.txt)。所有脚本文件均需放置在服务端D:MirServerMir200EnvirMarket_def目录下。

核心逻辑与变量设计
首先明确你的需求:
地图独占:每层地图(如701-710)同一时间只能有一个人。
接力机制:玩家A进入701后,701被锁定;当A进入702,701自动解锁,允许玩家B进入。
限时踢出:玩家在任意一层停留超过30分钟,自动传送回土城。
动态刷怪:只要有玩家进入某层,该层立即刷新一个BOSS。

为实现这些,我们定义以下全局变量(G):
G701OCCUPY 到 G710OCCUPY:值为0表示地图空闲,1表示已被占用。
G701MONSTER 到 G710MONSTER:值为0表示无怪,1表示已刷怪。

同时,每个玩家需要记录自己的当前层数和进入时间:
C_LAYER (HUMAN):记录玩家当前所在的层数(701-710)。
C_ENTER_TIME (HUMAN):记录玩家进入当前层的时间戳。

进入入口脚本(QManage.txt)
这是玩家点击入口NPC时触发的脚本。假设入口NPC名为“闯关使者”,位于比奇省(0)坐标(333,333)。

; 文件路径: D:MirServerMir200EnvirMarket_defQManage.txt
[@main]
IF
CHECKLEVELEX > 30 ; 假设需要30级以上
ACT
goto @CheckFirstLayer
ELSEACT
SENDMSG 6 等级不足30级,无法挑战!
BREAK

[@CheckFirstLayer]
; 检查第一层是否空闲
IF
EQUAL G701OCCUPY 0
ACT
; 锁定第一层
MOV G701OCCUPY 1
; 记录玩家信息
MOV C_LAYER 701
CALC C_ENTER_TIME UNIXTIME
; 传送玩家到第一层
MAPMOVE 701 50 50
; 触发第一层刷怪
CALL [701层脚本] @SpawnMonster
ELSEACT
SENDMSG 6 第一层正在被其他玩家挑战,请稍后再试。
BREAK

公共处理脚本(QFunction-0.txt)
此文件处理玩家移动、死亡、超时等事件,并管理各层的进入逻辑。

; 文件路径: D:MirServerMir200EnvirMarket_defQFunction-0.txt

; ========== 玩家进入新地图事件 ==========
[@MapEnter]
; 检查是否进入了闯关地图
IF
EQUAL MAP 701
ACT
goto @HandleLayer701
IF
EQUAL MAP 702
ACT
goto @HandleLayer702
; ... 以此类推,为703到710都写上类似的判断 ...

[@HandleLayer701]
; 验证玩家是否是从入口或上一层合法进入
IF
EQUAL C_LAYER 701
ACT
; 什么也不做,正常流程
ELSEACT
; 非法进入,踢回土城
MAPMOVE 3 333 333
SENDMSG 6 非法闯入!
BREAK

; ========== 玩家点击下一层NPC事件 ==========
; 假设每层NPC命令为 [@NextLayer_701], [@NextLayer_702] ...
[@NextLayer_701]
; 检查是否有BOSS存活
IF
CHECKMONCOUNT 祖玛教主 701 > 0
ACT
SENDMSG 6 请先击败本层的BOSS!
BREAK
ELSEACT
; 解锁当前层
MOV G701OCCUPY 0
; 清除当前层的怪物标记
MOV G701MONSTER 0
; 准备进入下一层
MOV C_LAYER 702
CALC C_ENTER_TIME UNIXTIME
; 检查下一层是否空闲
IF
EQUAL G702OCCUPY 0
ACT
; 锁定下一层
MOV G702OCCUPY 1
MAPMOVE 702 50 50
CALL [702层脚本] @SpawnMonster
ELSEACT
; 理论上不会发生,但作为保险
SENDMSG 6 下一层异常,请联系管理员。
MAPMOVE 3 333 333
BREAK

; ========== 定时器:检查超时 ==========
; 在[@Setup]中启动一个全局定时器,每60秒检查一次
[@Setup]
TimerRecall 60 @CheckTimeout

[@CheckTimeout]
; 遍历所有在线玩家(通过脚本难以直接遍历,通常由引擎支持)
; 这里用伪代码表示逻辑,实际需依赖引擎的定时检测功能
; 对于每个玩家:
; #IF
; CALC DIFF_TIME UNIXTIME - C_ENTER_TIME
; LARGE DIFF_TIME 1800 ; 1800秒=30分钟
; #ACT
; SENDMSG 6 挑战超时!
; MAPMOVE 3 333 333 ; 传回土城
; ; 解锁其占用的地图
; #IF
; EQUAL C_LAYER 701
; MOV G701OCCUPY 0
; MOV G701MONSTER 0
; ; ... 以此类推处理702-710 ...
; BREAK

; ========== 动态刷怪脚本 ==========
[701层脚本]
[@SpawnMonster]
; 检查是否已经有怪
IF
EQUAL G701MONSTER 0
ACT
; 刷新BOSS
MONSPAWN 祖玛教主 50 50 1 701
; 标记已刷怪
MOV G701MONSTER 1
BREAK

[702层脚本]
[@SpawnMonster]
IF
EQUAL G702MONSTER 0
ACT
MONSPAWN 赤月恶魔 50 50 1 702
MOV G702MONSTER 1
BREAK

; ... 为703到710重复上述[XX层脚本]结构 ...

关键点说明与补充
定时器实现:[@CheckTimeout]部分的逻辑在标准M2引擎中无法直接遍历所有玩家。你需要使用支持“玩家循环”功能的引擎(如GOM、GEE),或者在Robot.txt中编写一个机器人,让它每60秒执行一次对所有在线玩家的超时检查。
怪物死亡事件:你可能还需要在QFunction-0.txt中添加[@KillMon]事件,当BOSS被击杀时,可以给玩家发送提示或增加积分,但这不影响核心流程。
退出处理:如果玩家在闯关中途关闭客户端,他占用的地图将永远被锁定。为解决此问题,必须依赖上述的超时检查机制,确保长时间无活动的玩家被踢出并释放地图。
脚本放置:所有提到的[@main]、[@NextLayer_XXX]等标签都写在QManage.txt中。所有[@MapEnter]、[@Setup]、[@CheckTimeout]以及[XX层脚本]都写在QFunction-0.txt中。

按照以上结构编写脚本,即可实现你所要求的复杂闯关逻辑。核心在于利用全局变量作为“锁”,确保每层地图的独占性,并通过CALL命令触发各层独立的刷怪逻辑。