这段脚本出现死循环的根源在于结构写法错误,连续堆叠多组独立#if,末尾直接GOTO回自身标签,同时#ELSEACT只绑定最后一组#if,前面每一组条件只要满足就执行扣除发放,执行完成之后不会跳出流程,固定跳转回[@使一级回收]再次从头扫描,背包只要还有一件符合条件的装备,就会反复进入扫描逻辑持续回收,直到装备清空,即便装备清空,#ELSEACT里同样写了GOTO跳转,提示文字弹出之后又再次回到本标签,对话框不会关闭,指令持续反复运行,形成无法自行停止的死循环。连续并排#if属于独立条件,不是互斥分支,引擎会从上往下依次判断每一条装备,只要对应物品存在就执行take和give,不会在处理完一件之后停止扫描,这也是单次点击会一次性扫完全部装备的原因,搭配末尾无条件回跳,循环无法终止。
解决思路分为两种,第一种是单条循环扫描,处理一件装备之后回到标签继续扫描,但是装备全部检测完毕之后终止跳转,不再回跳;第二种是一次性遍历背包所有目标装备,全部处理完成之后统一提示,直接结束流程,不再反复跳转,第二种更适合一键回收功能,也是大部分回收NPC采用的方案。原脚本的#ELSEACT归属逻辑是关键,多#if连续书写时,#ELSEACT仅仅匹配离它最近的最后一个#if,前面所有#if的条件都不会触发这个else分支,装备不全的时候提示判断完全失效,这是第二个问题。
优先推荐一次性批量回收写法,去掉脚本内部的GOTO自跳转,改用变量标记是否有回收动作,每一类装备单独判断,所有装备遍历结束之后,根据变量判断输出提示,全程只扫描一轮,不会循环跳转。
[@使一级回收]
#ACT
SETVAR $HAVE_RECYCLE 0
#IF
CHECKITEM 骨玉权杖 1
#ACT
TAKE 骨玉权杖 1
GIVE 金币 20000
CHANGEEXP + 2000
SETVAR $HAVE_RECYCLE 1
#IF
CHECKITEM 无极棍 1
#ACT
TAKE 无极棍 1
GIVE 金币 20000
CHANGEEXP + 2000
SETVAR $HAVE_RECYCLE 1
#IF
CHECKITEM 力量戒指 1
#ACT
TAKE 力量戒指 1
GIVE 金币 20000
CHANGEEXP + 2000
SETVAR $HAVE_RECYCLE 1
#IF
CHECKITEM 骑士手镯 1
#ACT
TAKE 骑士手镯 1
GIVE 金币 20000
CHANGEEXP + 2000
SETVAR $HAVE_RECYCLE 1
#IF
CHECKITEM 阎罗手套 1
#ACT
TAKE 阎罗手套 1
GIVE 金币 20000
CHANGEEXP + 2000
SETVAR $HAVE_RECYCLE 1
#IF
CHECKITEM 泰坦戒指 1
#ACT
TAKE 泰坦戒指 1
GIVE 金币 20000
CHANGEEXP + 2000
SETVAR $HAVE_RECYCLE 1
#IF
CHECKITEM 三眼手镯 1
#ACT
TAKE 三眼手镯 1
GIVE 金币 20000
CHANGEEXP + 2000
SETVAR $HAVE_RECYCLE 1
#IF
CHECKITEM 绿色项链 1
#ACT
TAKE 绿色项链 1
GIVE 金币 20000
CHANGEEXP + 2000
SETVAR $HAVE_RECYCLE 1
#IF
CHECKITEM 灵魂项链 1
#ACT
TAKE 灵魂项链 1
GIVE 金币 20000
CHANGEEXP + 2000
SETVAR $HAVE_RECYCLE 1
#IF
CHECKITEM 紫碧螺 1
#ACT
TAKE 紫碧螺 1
GIVE 金币 20000
CHANGEEXP + 2000
SETVAR $HAVE_RECYCLE 1
#IF
CHECKITEM 龙之手镯 1
#ACT
TAKE 龙之手镯 1
GIVE 金币 20000
CHANGEEXP + 2000
SETVAR $HAVE_RECYCLE 1
#IF
CHECKITEM 恶魔铃铛 1
#ACT
TAKE 恶魔铃铛 1
GIVE 金币 20000
CHANGEEXP + 2000
SETVAR $HAVE_RECYCLE 1
#IF
EQUAL $HAVE_RECYCLE 1
#ACT
SENDMSG 6 〖提示〗恭喜您回收成功。
#ELSEACT
SENDMSG 5 〖提示〗对不起,您没有祖玛系装备!
#ACT
CLOSE
这个版本去掉了所有GOTO @使一级回收,点击一次按钮只完整遍历一次清单内的装备,存在的装备全部扣除发放奖励,不存在的直接跳过,依靠自定义变量$HAVE_RECYCLE记录本次操作有没有成功回收物品,遍历全部装备之后再根据变量输出两种提示,执行完成使用CLOSE关闭对话框,不会产生循环。这个写法的特点是一次点击一次性清空背包里清单内所有符合条件装备,适合一键批量回收需求,也是使用频率最高的方案。
如果想要做成单次只回收一件,剩下装备保留在背包,需要玩家反复点击按钮继续回收,就采用互斥判断写法,使用#ELSEIF串联,从上往下匹配,匹配到第一件装备之后执行回收,不再继续向下判断其他装备,没有任何装备匹配才进入提示分支,同样删除自跳转GOTO。
[@使一级回收]
#IF
CHECKITEM 骨玉权杖 1
#ACT
TAKE 骨玉权杖 1
GIVE 金币 20000
CHANGEEXP + 2000
SENDMSG 6 〖提示〗骨玉权杖回收成功。
#ELSEIF
CHECKITEM 无极棍 1
#ACT
TAKE 无极棍 1
GIVE 金币 20000
CHANGEEXP + 2000
SENDMSG 6 〖提示〗无极棍回收成功。
#ELSEIF
CHECKITEM 力量戒指 1
#ACT
TAKE 力量戒指 1
GIVE 金币 20000
CHANGEEXP + 2000
SENDMSG 6 〖提示〗力量戒指回收成功。
#ELSEIF
CHECKITEM 骑士手镯 1
#ACT
TAKE 骑士手镯 1
GIVE 金币 20000
CHANGEEXP + 2000
SENDMSG 6 〖提示〗骑士手镯回收成功。
#ELSEIF
CHECKITEM 阎罗手套 1
#ACT
TAKE 阎罗手套 1
GIVE 阎罗手套 1
GIVE 金币 20000
CHANGEEXP + 2000
SENDMSG 6 〖提示〗阎罗手套回收成功。
#ELSEIF
CHECKITEM 泰坦戒指 1
#ACT
TAKE 泰坦戒指 1
GIVE 金币 20000
CHANGEEXP + 2000
SENDMSG 6 〖提示〗泰坦戒指回收成功。
#ELSEIF
CHECKITEM 三眼手镯 1
#ACT
TAKE 三眼手镯 1
GIVE 金币 20000
CHANGEEXP + 2000
SENDMSG 6 〖提示〗三眼手镯回收成功。
#ELSEIF
CHECKITEM 绿色项链 1
#ACT
TAKE 绿色项链 1
GIVE 金币 20000
CHANGEEXP + 2000
SENDMSG 6 〖提示〗绿色项链回收成功。
#ELSEIF
CHECKITEM 灵魂项链 1
#ACT
TAKE 灵魂项链 1
GIVE 金币 20000
CHANGEEXP + 2000
SENDMSG 6 〖提示〗灵魂项链回收成功。
#ELSEIF
CHECKITEM 紫碧螺 1
#ACT
TAKE 紫碧螺 1
GIVE 金币 20000
CHANGEEXP + 2000
SENDMSG 6 〖提示〗紫碧螺回收成功。
#ELSEIF
CHECKITEM 龙之手镯 1
#ACT
TAKE 龙之手镯 1
GIVE 金币 20000
CHANGEEXP + 2000
SENDMSG 6 〖提示〗龙之手镯回收成功。
#ELSEIF
CHECKITEM 恶魔铃铛 1
#ACT
TAKE 恶魔铃铛 1
GIVE 金币 20000
CHANGEEXP + 2000
SENDMSG 6 〖提示〗恶魔铃铛回收成功。
#ELSEACT
SENDMSG 5 〖提示〗对不起,您没有祖玛系装备!
#ACT
CLOSE
#ELSEIF是顺序互斥分支,引擎找到第一条满足条件的装备就执行对应回收,后面所有分支直接跳过,不会一次性扫完全部装备,适合单条回收模式。
很多制作者会想要保留自动循环扫描,但是需要增加终止条件,这种写法不推荐在NPC点击标签内使用,容易造成M2卡死,如果一定要实现点击之后自动循环扫空背包,需要把循环逻辑放到机器人或者单独标记分支,增加空包判定,不建议直接在NPC按钮标签内部写GOTO自循环。NPC对话标签属于同步交互逻辑,持续自跳转占用主线执行线程,装备数量多的时候会出现角色卡顿、M2日志疯狂刷屏,严重会造成服务端卡死。
额外的细节问题,原脚本没有背包空格检测,如果发放金币和经验之外附带物品奖励,背包空间不足会导致give指令执行失败,回收扣除已经完成但是奖励发不出,增加CHECKBAG空格检测可以规避这个问题。物品名称要和数据库完全一致,空格、符号差别会造成检测失效。批量回收版本在GOM、GEE引擎都可以直接使用,变量写法兼容,HERO引擎没有自定义变量,可以改用标记分组或者全局标记替换变量逻辑。
调试的时候,修改脚本保存之后执行重载NPC命令,在M2日志面板观察执行记录,查看take和give指令是否正常触发,日志里持续重复输出回收提示就是循环没有处理干净的表现。区分清楚并排#if和#ELSEIF的区别,并排#if为独立判断,互不干扰,#ELSEIF是互斥分支,匹配一条就终止,这是编写回收类脚本最核心的语法要点。
传奇一键回收脚本死循环成因分支重构循环终止与分批检测写法讲解
来源:
作者:
点击:

