先说清楚一件事:以下写的是LegendofMir2系列(LEG/GOM/GEE/HERO类)服务端的脚本级思路,属于你自己搭建的单机或授权服务端内部脚本开发,不是外挂、不是客户端注入、不是第三方工具。在自己的服务端里改脚本是正常运维;拿去动别人服务器、做破坏用途一律不沾。
一、全服玩家等级清零:不用M2操作,纯脚本自动完成
你的需求拆开是五条硬约束:
1.不通过M2手动操作(不用GM界面点)
2.不走“返回角色/退出游戏”流程
3.活动失败→自动触发
4.全服在线玩家直接清零
5.身上装备先脱下、再放回背包,不能丢、不能消失
1.触发入口:活动失败的那一刻
活动一般用Robot(机器人定时器)或NPC事件驱动。假设是活动时间到/条件不满足导致失败,在失败逻辑里调用一个统一入口:
QuestDiary写法(LEG/GOM通用):
[@活动失败处理]
#CALL[\系统\全服清零.txt]@开始清零
失败判定写在机器人或活动NPC里,一旦成立就#CALL这个文件,全程不碰M2。
2.遍历全服在线玩家
服务端要“拿到所有在线角色对象”,不同引擎API不同,但思路一致:先取在线人数→按索引取Human对象→逐个处理。
GOM/GEE类(支持Human对象数组):
[@开始清零]
#IF
#ACT
;1.先记录全服角色,避免遍历中对象失效
SetInt($G(清零总数))=<$ONLINECOUNT>
SetInt($G(清零索引))=0
[@清零循环]
#IF
CheckInt($G(清零索引))<CheckInt($G(清零总数))
#ACT
;取第N个在线玩家对象
GetOnlineHuman<$G(清零索引)>$H(当前玩家)
;执行单角色清零
#CALL[\系统\单角色清零.txt]@执行
;索引+1
CalcInt($G(清零索引))+1
;循环
#GOTO[@清零循环]
#ELSEACT
;全部处理完,发全服公告
SENDMSG0活动失败!全服等级已清零,装备已收回背包。
HERO引擎(lua插件写法):
functionOnActivityFail()
localplayers=M2.GetOnlinePlayers()
for_Humaninipairs(players)do
StripAndReset(Human)
end
M2.SendMsg(0"活动失败!全服等级已清零,装备已收回背包。")
end
M2.GetOnlinePlayers()和M2.SendMsg按你引擎的实际API名替换,HERO里通常叫GetAllPlayer/GameServer.SendBroadCastMsg。
3.单角色清零核心:脱装备→放背包→清等级
关键顺序不能反:先卸装再清零,且卸装前先判背包空格。
单角色清零脚本(GOM类):
[@执行]
#IF
#ACT
;1.把身上13个装备位全部卸到背包
;引擎命令一般为:TakeOffToBag装备位
;装备位:0武器1衣服2头盔3项链4左戒指5右戒指6左手镯7右手镯8腰带9鞋子10宝石11披风12面罩
SetInt($H(当前玩家)(卸装位))=0
[@卸装循环]
#IF
CheckInt($H(当前玩家)(卸装位))<13
#ACT
;脱下该位装备,放回背包;背包满则自动掉落地面(可配置)
TakeOffToBag<$H(当前玩家)><$H(当前玩家)(卸装位)>
CalcInt($H(当前玩家)(卸装位))+1
#GOTO[@卸装循环]
#ELSEACT
;2.卸完再清零
;清等级(保留1级,传奇不允许0级)
SetLevel<$H(当前玩家)>1
;清经验(经验归零,避免自动升级)
SetExp<$H(当前玩家)>0
;清技能等级(按需,成长任务会重做)
ClearSkill<$H(当前玩家)>
;清任务变量(成长任务/副本任务进度重置)
ClearQuestFlag<$H(当前玩家)>
;回满血蓝(避免清零后残血死)
FullHp<$H(当前玩家)>
FullMp<$H(当前玩家)>
;提示该玩家
SendSysMsg<$H(当前玩家)>活动失败,你的等级已被清零,装备已收回。
HEROlua对应:
functionStripAndReset(Human)
--卸全部装备到背包
foridx=012do
Human:TakeOffToBag(idx)
end
Human:SetLevel(1)
Human:SetExp(0)
Human:ClearSkill()
Human:ClearQuestFlag()
Human:FullHp()
Human:FullMp()
Human:SysMsg("活动失败,等级已清零,装备已收回。")
end
4.几个必须处理的坑
①背包满导致装备消失
清零前先判背包空格数,不足就:
•清掉背包里的垃圾白装(按重量/价值过滤)
•或临时扩展背包(部分引擎支持SetBagSize)
•或把装备直接存进仓库(DepotSave),活动后再发
推荐做法:先GetBagFree(Human)拿到空格,空格<13就先清垃圾再卸装。
②马匹/英雄/宝宝装备
如果有英雄系统,英雄身上也要脱:
TakeOffHeroAll<$H(当前玩家)>
宝宝(道士神兽)直接消失即可,召唤物不算装备。
③元宝/金币/仓库要不要清
等级清零通常只清等级+经验+技能+任务进度,不动金币元宝仓库。你可按需加:
;清金币(保留1000做路费)
SetGold<$H(当前玩家)>1000
别清成0,否则玩家连回城卷都买不起,直接卡死。
④玩家正在交易/在商店/在副本
遍历处理时若玩家处于“不可操作”状态,TakeOffToBag会失败。做法:
•先踢出交易/商店界面(CancelTrade/CloseShop)
•副本中的玩家标记“待清零”,等他回主城再执行(用变量记录,回城事件里补处理)
•或强制召回:MoveTo<$H(当前玩家)>3330330(回土城再处理)
⑤跨线/微端
单线遍历只能清本线。多线要在中心服/网关层广播“清零指令”,各线收到后各自遍历本线在线角色。脚本里加一层:
;线1处理完向线2发消息
SendCrossMsg2CLEAR_ALL_LEVEL
各线Robot监听该消息并触发自己的清零流程。
5.完整触发链路
活动失败判定
→Robot定时器/NPC事件
→#CALL全服清零.txt@开始清零
→遍历在线玩家
→每个玩家:判背包空格→清垃圾→卸13件装备到背包→清等级/经验/技能/任务→回血蓝→发提示
→遍历完发全服公告
→(跨线)广播各线重复上述
全程不打开M2,不踢线不返回角色,玩家原地直接被清零。
二、任务系统:任务栏闪烁+任务窗口分类
传奇原版没有“任务栏闪烁”和“成长/副本分类”这种客户端UI,要实现得靠两部分配合:
•服务端:任务数据、接/交逻辑、进度存储
•客户端/插件:任务栏图标闪烁、分类窗口(需要支持自定义UI的引擎,如GEE、HERO、翎风)
下面按“脚本能控制的程度”分层给方案。
1.服务端:任务数据结构与分类
QuestDiary里按文件夹分类(这是“任务分类”的服务端根基):
\Envir\QuestDiary\
成长任务\
每日签到.txt
升级任务.txt
转生任务.txt
副本任务\
祖玛副本.txt
赤月副本.txt
火龙副本.txt
活动任务\
攻城预热.txt
节日收集.txt
每个任务文件统一模板:
;=====成长任务:升级到35级=====
[@main]
#IF
ISACCEPT成长_升级35
#ACT
#SAY
任务进度:<$\QUEST(成长_升级35)>/35
<继续升级/@close>
#ELSEACT
#SAY
<接受任务:升级到35级/@accept>
[@accept]
#IF
#ACT
ACCEPTQUEST成长_升级35
SetInt(<$HUMAN(成长_升级35)>)=0
SENDMSG0已接受成长任务【升级到35级】!
;=====进度更新(在升级事件里调用)=====
[@升级回调]
#IF
ISACCEPT成长_升级35
CheckLevelEx>=35
#ACT
COMPLETEQUEST成长_升级35
GiveItem祝福油1
SENDMSG0成长任务【升级到35级】已完成,奖励已发放!
任务分类标识用前缀:成长_副本_活动_,后面客户端按前缀自动归类。
2.任务进度存储
•玩家变量:SetInt(<$HUMAN(成长_升级35)>)——存进度,重启不丢
•任务接受标记:ISACCEPT任务名——引擎内置命令
•任务完成标记:COMPLETEQUEST任务名——控制能否重复领取
不要用全局变量存进度,否则全服共用一个进度,A完成B也领奖。
3.任务栏闪烁(客户端层)
传奇客户端右下角“任务”图标闪烁,本质是:服务端推一个状态标志→客户端检测到有新任务/可交任务→图标开始闪。
方案A:引擎自带任务系统(GEE/HERO推荐)
这些引擎内部已有任务栏,脚本只要正确调用ACCEPTQUEST/COMPLETEQUEST,客户端自动:
•新任务可接→图标亮
•任务可交→图标闪
•任务栏里按“当前/已完成/可接”分组
你要做的只是在接/交任务时保证命令成对调用,别漏COMPLETEQUEST。
方案B:自定义闪烁(通用,支持插件引擎)
用客户端插件监听一个自定义封包,服务端在任务状态变化时发送:
服务端(lua插件):
functionNotifyQuestFlash(HumanquestType)
--questType:1成长2副本3活动
Human:SendCustomPacket(0xABquestType)
end
客户端(支持luaUI的引擎):
RegisterPacket(0xABfunction(type)
TaskWindow:SetFlash(true)
TaskWindow:SetType(type)--1/2/3对应三个分类页
end)
客户端收到0xAB就让任务栏图标SetFlash(true)开始闪烁,并切到对应分类页。
方案C:无客户端修改,纯服务端替代(LEG老引擎)
老引擎改不了客户端UI,就用NPC头顶感叹号+屏幕提示模拟:
•任务可接:NPC头顶显示!(服务端SetNpcTitle)
•任务可交:NPC头顶显示?
•玩家打开任务NPC时,#SAY里列出分类清单(见下)
4.任务窗口:分类显示
纯脚本的分类清单(NPC对话框,LEG/GOM通用):
[@任务列表]
#ACT
#SAY
\【成长任务】\\
<升级到35级:<$\QUEST(成长_升级35)>/35/@成长_升级>\\
<转生任务:<$\QUEST(成长_转生)>/1/@成长_转生>\\
\【副本任务】\\
<祖玛副本:<$\QUEST(副本_祖玛)>/10/@副本_祖玛>\\
<赤月副本:<$\QUEST(副本_赤月)>/5/@副本_赤月>\\
\【活动任务】\\
<攻城预热/@活动_攻城>\\
<返回/@main>
带客户端UI的分类(GEE/HERO):在插件里维护一个任务表,按类型分组渲染:
localQuestDB={
[1]={--成长
{name="升级到35级"cur=Human:GetVar("成长_升级35")max=35state=...}
{name="转生任务"cur=...max=1}
}
[2]={--副本
{name="祖玛副本"cur=...max=10}
}
[3]={--活动
{name="攻城预热"cur=...max=1}
}
}
客户端按1/2/3渲染成三个Tab,任务栏图标按state(可接/进行中/可交)决定闪不闪、什么颜色。
5.闪烁触发时机汇总
要让玩家“及时看到闪”,在这几个节点调用通知:
•接任务成功→闪(新任务)
•任务进度满(可交)→闪(提示交任务)
•交任务领奖→闪(切到下一个)
•活动开启/新日常刷新→闪(可接任务出现)
•副本通关结算→更新进度,满则闪
统一封装一个函数最省事:
functionUpdateQuest(HumanquestName)
localdef=QuestDef[questName]
localcur=Human:GetVar(questName)
ifcur>=def.maxandnotHuman:IsComplete(questName)then
Human:SetComplete(questNametrue)
NotifyQuestFlash(Humandef.type)--可交,闪
elseifnotHuman:IsAccept(questName)anddef.autoAcceptthen
Human:Accept(questName)
NotifyQuestFlash(Humandef.type)--新任务,闪
end
end
6.任务系统完整链路
服务端QuestDiary按成长/副本/活动分文件夹
→接任务:ACCEPTQUEST+SetInt(HUMAN(进度))
→进度更新:升级/杀怪/副本结算事件→SetInt+UpdateQuest
→满进度:COMPLETEQUEST+NotifyQuestFlash(类型)
→交任务:GiveItem+开下一环
→客户端收到0xAB→任务栏闪+切分类Tab
→玩家打开任务窗口→按1/2/3渲染列表
三、两个功能的联动
你这个场景里,两个需求其实是同一个活动系统的两头:
活动失败→全服清零→同时重置所有任务进度
[@活动失败处理]
#CALL[\系统\全服清零.txt]@开始清零
#CALL[\系统\任务重置.txt]@重置全部任务
任务重置脚本:
[@重置全部任务]
#IF
#ACT
SetInt($G(任务索引))=0
[@任务循环]
#IF
CheckInt($G(任务索引))<CheckInt($G(任务总数))
#ACT
GetOnlineHuman<$G(任务索引)>$H(当前玩家)
;清掉三类任务进度变量(按你实际任务名遍历)
ResetQuest<$H(当前玩家)>成长_升级35
ResetQuest<$H(当前玩家)>成长_转生
ResetQuest<$H(当前玩家)>副本_祖玛
ResetQuest<$H(当前玩家)>副本_赤月
ResetQuest<$H(当前玩家)>活动_攻城
;重新开放“成长任务·第一章”作为新一轮起点
ACCEPTQUEST<$H(当前玩家)>成长_第一章
NotifyQuestFlash<$H(当前玩家)>1
CalcInt($G(任务索引))+1
#GOTO[@任务循环]
这样一次活动失败:等级清零+装备回收+任务进度归零+任务栏自动闪(新的一轮成长任务可接),玩家不用下线不用返回角色,原地直接重新开始。
四、调试与排错清单
清零脚本常见翻车点:
•TakeOffToBag后装备消失→背包满,先清空格
•清零后玩家卡死/掉线→没清交易状态、没回血蓝
•跨线只清了一半→没做中心服广播
•英雄装备没脱→加TakeOffHeroAll
•技能没清导致等级1但技能满级→ClearSkill必须调用
•金币元宝一起清了→玩家无法买药,留基础路费
任务系统常见翻车点:
•图标不闪→客户端没注册0xAB封包/引擎自带任务开关没开
•分类错乱→任务名前缀不统一,脚本按前缀分组时匹配失败
•进度不更新→升级/杀怪事件里没调UpdateQuest
•重复领奖→没判ISACCEPT/COMPLETEQUEST,玩家点两次发两份
•任务栏显示旧数据→客户端没在Notify时刷新列表,要主动调RefreshTaskWindow
调试方法:
•先拿1个测试号跑通,再放开全服
•清零前SENDMSG打印“即将清零人数=$G(清零总数)”
•单角色处理完打印“已处理:H(当前玩家)等级LEVEL”
•任务系统先写1个成长任务跑通接受→进度→完成→闪烁→领奖,再复制到其他任务
•所有变量名建一张表统一管理,避免成长_升级35和成长_升35这种拼写差
五、命令对照速查(按引擎)
功能LEG/GOMHEROlua
取在线人数<$ONLINECOUNT>M2:GetOnlineCount()
取在线玩家GetOnlineHumanN$H(x)M2:GetOnlinePlayers()
设等级SetLevelHuman1Human:SetLevel(1)
清经验SetExpHuman0Human:SetExp(0)
卸装备到背包TakeOffToBagHuman位Human:TakeOffToBag(idx)
清技能ClearSkillHumanHuman:ClearSkill()
背包空格GetBagFreeHumanHuman:GetBagFree()
接任务ACCEPTQUEST任务名Human:Accept(name)
交任务COMPLETEQUEST任务名Human:Complete(name)
发公告SENDMSG0文本M2:SendMsg(0text)
引擎不同命令名一定对一遍文档,GameGold/AddGameGold/Human:AddGameGold这类在三个引擎里写法完全不同的命令,照抄必崩。
把“全服清零”理解成遍历+卸装+清属性三步,把“任务系统”理解成分类存储+进度回调+客户端闪烁四块,剩下的就是按你引擎的实际命令名填空。先单角色跑通清零,再接活动失败事件;先做一个成长任务跑通全流程,再加副本/活动分类——两部分都稳定后,用一次#CALL把清零和任务重置串起来,就是你要的“活动失败→全服原地清零+任务重新开始+任务栏闪烁提示”。
一、全服玩家等级清零:不用M2操作,纯脚本自动完成
你的需求拆开是五条硬约束:
1.不通过M2手动操作(不用GM界面点)
2.不走“返回角色/退出游戏”流程
3.活动失败→自动触发
4.全服在线玩家直接清零
5.身上装备先脱下、再放回背包,不能丢、不能消失
1.触发入口:活动失败的那一刻
活动一般用Robot(机器人定时器)或NPC事件驱动。假设是活动时间到/条件不满足导致失败,在失败逻辑里调用一个统一入口:
QuestDiary写法(LEG/GOM通用):
[@活动失败处理]
#CALL[\系统\全服清零.txt]@开始清零
失败判定写在机器人或活动NPC里,一旦成立就#CALL这个文件,全程不碰M2。
2.遍历全服在线玩家
服务端要“拿到所有在线角色对象”,不同引擎API不同,但思路一致:先取在线人数→按索引取Human对象→逐个处理。
GOM/GEE类(支持Human对象数组):
[@开始清零]
#IF
#ACT
;1.先记录全服角色,避免遍历中对象失效
SetInt($G(清零总数))=<$ONLINECOUNT>
SetInt($G(清零索引))=0
[@清零循环]
#IF
CheckInt($G(清零索引))<CheckInt($G(清零总数))
#ACT
;取第N个在线玩家对象
GetOnlineHuman<$G(清零索引)>$H(当前玩家)
;执行单角色清零
#CALL[\系统\单角色清零.txt]@执行
;索引+1
CalcInt($G(清零索引))+1
;循环
#GOTO[@清零循环]
#ELSEACT
;全部处理完,发全服公告
SENDMSG0活动失败!全服等级已清零,装备已收回背包。
HERO引擎(lua插件写法):
functionOnActivityFail()
localplayers=M2.GetOnlinePlayers()
for_Humaninipairs(players)do
StripAndReset(Human)
end
M2.SendMsg(0"活动失败!全服等级已清零,装备已收回背包。")
end
M2.GetOnlinePlayers()和M2.SendMsg按你引擎的实际API名替换,HERO里通常叫GetAllPlayer/GameServer.SendBroadCastMsg。
3.单角色清零核心:脱装备→放背包→清等级
关键顺序不能反:先卸装再清零,且卸装前先判背包空格。
单角色清零脚本(GOM类):
[@执行]
#IF
#ACT
;1.把身上13个装备位全部卸到背包
;引擎命令一般为:TakeOffToBag装备位
;装备位:0武器1衣服2头盔3项链4左戒指5右戒指6左手镯7右手镯8腰带9鞋子10宝石11披风12面罩
SetInt($H(当前玩家)(卸装位))=0
[@卸装循环]
#IF
CheckInt($H(当前玩家)(卸装位))<13
#ACT
;脱下该位装备,放回背包;背包满则自动掉落地面(可配置)
TakeOffToBag<$H(当前玩家)><$H(当前玩家)(卸装位)>
CalcInt($H(当前玩家)(卸装位))+1
#GOTO[@卸装循环]
#ELSEACT
;2.卸完再清零
;清等级(保留1级,传奇不允许0级)
SetLevel<$H(当前玩家)>1
;清经验(经验归零,避免自动升级)
SetExp<$H(当前玩家)>0
;清技能等级(按需,成长任务会重做)
ClearSkill<$H(当前玩家)>
;清任务变量(成长任务/副本任务进度重置)
ClearQuestFlag<$H(当前玩家)>
;回满血蓝(避免清零后残血死)
FullHp<$H(当前玩家)>
FullMp<$H(当前玩家)>
;提示该玩家
SendSysMsg<$H(当前玩家)>活动失败,你的等级已被清零,装备已收回。
HEROlua对应:
functionStripAndReset(Human)
--卸全部装备到背包
foridx=012do
Human:TakeOffToBag(idx)
end
Human:SetLevel(1)
Human:SetExp(0)
Human:ClearSkill()
Human:ClearQuestFlag()
Human:FullHp()
Human:FullMp()
Human:SysMsg("活动失败,等级已清零,装备已收回。")
end
4.几个必须处理的坑
①背包满导致装备消失
清零前先判背包空格数,不足就:
•清掉背包里的垃圾白装(按重量/价值过滤)
•或临时扩展背包(部分引擎支持SetBagSize)
•或把装备直接存进仓库(DepotSave),活动后再发
推荐做法:先GetBagFree(Human)拿到空格,空格<13就先清垃圾再卸装。
②马匹/英雄/宝宝装备
如果有英雄系统,英雄身上也要脱:
TakeOffHeroAll<$H(当前玩家)>
宝宝(道士神兽)直接消失即可,召唤物不算装备。
③元宝/金币/仓库要不要清
等级清零通常只清等级+经验+技能+任务进度,不动金币元宝仓库。你可按需加:
;清金币(保留1000做路费)
SetGold<$H(当前玩家)>1000
别清成0,否则玩家连回城卷都买不起,直接卡死。
④玩家正在交易/在商店/在副本
遍历处理时若玩家处于“不可操作”状态,TakeOffToBag会失败。做法:
•先踢出交易/商店界面(CancelTrade/CloseShop)
•副本中的玩家标记“待清零”,等他回主城再执行(用变量记录,回城事件里补处理)
•或强制召回:MoveTo<$H(当前玩家)>3330330(回土城再处理)
⑤跨线/微端
单线遍历只能清本线。多线要在中心服/网关层广播“清零指令”,各线收到后各自遍历本线在线角色。脚本里加一层:
;线1处理完向线2发消息
SendCrossMsg2CLEAR_ALL_LEVEL
各线Robot监听该消息并触发自己的清零流程。
5.完整触发链路
活动失败判定
→Robot定时器/NPC事件
→#CALL全服清零.txt@开始清零
→遍历在线玩家
→每个玩家:判背包空格→清垃圾→卸13件装备到背包→清等级/经验/技能/任务→回血蓝→发提示
→遍历完发全服公告
→(跨线)广播各线重复上述
全程不打开M2,不踢线不返回角色,玩家原地直接被清零。
二、任务系统:任务栏闪烁+任务窗口分类
传奇原版没有“任务栏闪烁”和“成长/副本分类”这种客户端UI,要实现得靠两部分配合:
•服务端:任务数据、接/交逻辑、进度存储
•客户端/插件:任务栏图标闪烁、分类窗口(需要支持自定义UI的引擎,如GEE、HERO、翎风)
下面按“脚本能控制的程度”分层给方案。
1.服务端:任务数据结构与分类
QuestDiary里按文件夹分类(这是“任务分类”的服务端根基):
\Envir\QuestDiary\
成长任务\
每日签到.txt
升级任务.txt
转生任务.txt
副本任务\
祖玛副本.txt
赤月副本.txt
火龙副本.txt
活动任务\
攻城预热.txt
节日收集.txt
每个任务文件统一模板:
;=====成长任务:升级到35级=====
[@main]
#IF
ISACCEPT成长_升级35
#ACT
#SAY
任务进度:<$\QUEST(成长_升级35)>/35
<继续升级/@close>
#ELSEACT
#SAY
<接受任务:升级到35级/@accept>
[@accept]
#IF
#ACT
ACCEPTQUEST成长_升级35
SetInt(<$HUMAN(成长_升级35)>)=0
SENDMSG0已接受成长任务【升级到35级】!
;=====进度更新(在升级事件里调用)=====
[@升级回调]
#IF
ISACCEPT成长_升级35
CheckLevelEx>=35
#ACT
COMPLETEQUEST成长_升级35
GiveItem祝福油1
SENDMSG0成长任务【升级到35级】已完成,奖励已发放!
任务分类标识用前缀:成长_副本_活动_,后面客户端按前缀自动归类。
2.任务进度存储
•玩家变量:SetInt(<$HUMAN(成长_升级35)>)——存进度,重启不丢
•任务接受标记:ISACCEPT任务名——引擎内置命令
•任务完成标记:COMPLETEQUEST任务名——控制能否重复领取
不要用全局变量存进度,否则全服共用一个进度,A完成B也领奖。
3.任务栏闪烁(客户端层)
传奇客户端右下角“任务”图标闪烁,本质是:服务端推一个状态标志→客户端检测到有新任务/可交任务→图标开始闪。
方案A:引擎自带任务系统(GEE/HERO推荐)
这些引擎内部已有任务栏,脚本只要正确调用ACCEPTQUEST/COMPLETEQUEST,客户端自动:
•新任务可接→图标亮
•任务可交→图标闪
•任务栏里按“当前/已完成/可接”分组
你要做的只是在接/交任务时保证命令成对调用,别漏COMPLETEQUEST。
方案B:自定义闪烁(通用,支持插件引擎)
用客户端插件监听一个自定义封包,服务端在任务状态变化时发送:
服务端(lua插件):
functionNotifyQuestFlash(HumanquestType)
--questType:1成长2副本3活动
Human:SendCustomPacket(0xABquestType)
end
客户端(支持luaUI的引擎):
RegisterPacket(0xABfunction(type)
TaskWindow:SetFlash(true)
TaskWindow:SetType(type)--1/2/3对应三个分类页
end)
客户端收到0xAB就让任务栏图标SetFlash(true)开始闪烁,并切到对应分类页。
方案C:无客户端修改,纯服务端替代(LEG老引擎)
老引擎改不了客户端UI,就用NPC头顶感叹号+屏幕提示模拟:
•任务可接:NPC头顶显示!(服务端SetNpcTitle)
•任务可交:NPC头顶显示?
•玩家打开任务NPC时,#SAY里列出分类清单(见下)
4.任务窗口:分类显示
纯脚本的分类清单(NPC对话框,LEG/GOM通用):
[@任务列表]
#ACT
#SAY
\【成长任务】\\
<升级到35级:<$\QUEST(成长_升级35)>/35/@成长_升级>\\
<转生任务:<$\QUEST(成长_转生)>/1/@成长_转生>\\
\【副本任务】\\
<祖玛副本:<$\QUEST(副本_祖玛)>/10/@副本_祖玛>\\
<赤月副本:<$\QUEST(副本_赤月)>/5/@副本_赤月>\\
\【活动任务】\\
<攻城预热/@活动_攻城>\\
<返回/@main>
带客户端UI的分类(GEE/HERO):在插件里维护一个任务表,按类型分组渲染:
localQuestDB={
[1]={--成长
{name="升级到35级"cur=Human:GetVar("成长_升级35")max=35state=...}
{name="转生任务"cur=...max=1}
}
[2]={--副本
{name="祖玛副本"cur=...max=10}
}
[3]={--活动
{name="攻城预热"cur=...max=1}
}
}
客户端按1/2/3渲染成三个Tab,任务栏图标按state(可接/进行中/可交)决定闪不闪、什么颜色。
5.闪烁触发时机汇总
要让玩家“及时看到闪”,在这几个节点调用通知:
•接任务成功→闪(新任务)
•任务进度满(可交)→闪(提示交任务)
•交任务领奖→闪(切到下一个)
•活动开启/新日常刷新→闪(可接任务出现)
•副本通关结算→更新进度,满则闪
统一封装一个函数最省事:
functionUpdateQuest(HumanquestName)
localdef=QuestDef[questName]
localcur=Human:GetVar(questName)
ifcur>=def.maxandnotHuman:IsComplete(questName)then
Human:SetComplete(questNametrue)
NotifyQuestFlash(Humandef.type)--可交,闪
elseifnotHuman:IsAccept(questName)anddef.autoAcceptthen
Human:Accept(questName)
NotifyQuestFlash(Humandef.type)--新任务,闪
end
end
6.任务系统完整链路
服务端QuestDiary按成长/副本/活动分文件夹
→接任务:ACCEPTQUEST+SetInt(HUMAN(进度))
→进度更新:升级/杀怪/副本结算事件→SetInt+UpdateQuest
→满进度:COMPLETEQUEST+NotifyQuestFlash(类型)
→交任务:GiveItem+开下一环
→客户端收到0xAB→任务栏闪+切分类Tab
→玩家打开任务窗口→按1/2/3渲染列表
三、两个功能的联动
你这个场景里,两个需求其实是同一个活动系统的两头:
活动失败→全服清零→同时重置所有任务进度
[@活动失败处理]
#CALL[\系统\全服清零.txt]@开始清零
#CALL[\系统\任务重置.txt]@重置全部任务
任务重置脚本:
[@重置全部任务]
#IF
#ACT
SetInt($G(任务索引))=0
[@任务循环]
#IF
CheckInt($G(任务索引))<CheckInt($G(任务总数))
#ACT
GetOnlineHuman<$G(任务索引)>$H(当前玩家)
;清掉三类任务进度变量(按你实际任务名遍历)
ResetQuest<$H(当前玩家)>成长_升级35
ResetQuest<$H(当前玩家)>成长_转生
ResetQuest<$H(当前玩家)>副本_祖玛
ResetQuest<$H(当前玩家)>副本_赤月
ResetQuest<$H(当前玩家)>活动_攻城
;重新开放“成长任务·第一章”作为新一轮起点
ACCEPTQUEST<$H(当前玩家)>成长_第一章
NotifyQuestFlash<$H(当前玩家)>1
CalcInt($G(任务索引))+1
#GOTO[@任务循环]
这样一次活动失败:等级清零+装备回收+任务进度归零+任务栏自动闪(新的一轮成长任务可接),玩家不用下线不用返回角色,原地直接重新开始。
四、调试与排错清单
清零脚本常见翻车点:
•TakeOffToBag后装备消失→背包满,先清空格
•清零后玩家卡死/掉线→没清交易状态、没回血蓝
•跨线只清了一半→没做中心服广播
•英雄装备没脱→加TakeOffHeroAll
•技能没清导致等级1但技能满级→ClearSkill必须调用
•金币元宝一起清了→玩家无法买药,留基础路费
任务系统常见翻车点:
•图标不闪→客户端没注册0xAB封包/引擎自带任务开关没开
•分类错乱→任务名前缀不统一,脚本按前缀分组时匹配失败
•进度不更新→升级/杀怪事件里没调UpdateQuest
•重复领奖→没判ISACCEPT/COMPLETEQUEST,玩家点两次发两份
•任务栏显示旧数据→客户端没在Notify时刷新列表,要主动调RefreshTaskWindow
调试方法:
•先拿1个测试号跑通,再放开全服
•清零前SENDMSG打印“即将清零人数=$G(清零总数)”
•单角色处理完打印“已处理:H(当前玩家)等级LEVEL”
•任务系统先写1个成长任务跑通接受→进度→完成→闪烁→领奖,再复制到其他任务
•所有变量名建一张表统一管理,避免成长_升级35和成长_升35这种拼写差
五、命令对照速查(按引擎)
功能LEG/GOMHEROlua
取在线人数<$ONLINECOUNT>M2:GetOnlineCount()
取在线玩家GetOnlineHumanN$H(x)M2:GetOnlinePlayers()
设等级SetLevelHuman1Human:SetLevel(1)
清经验SetExpHuman0Human:SetExp(0)
卸装备到背包TakeOffToBagHuman位Human:TakeOffToBag(idx)
清技能ClearSkillHumanHuman:ClearSkill()
背包空格GetBagFreeHumanHuman:GetBagFree()
接任务ACCEPTQUEST任务名Human:Accept(name)
交任务COMPLETEQUEST任务名Human:Complete(name)
发公告SENDMSG0文本M2:SendMsg(0text)
引擎不同命令名一定对一遍文档,GameGold/AddGameGold/Human:AddGameGold这类在三个引擎里写法完全不同的命令,照抄必崩。
把“全服清零”理解成遍历+卸装+清属性三步,把“任务系统”理解成分类存储+进度回调+客户端闪烁四块,剩下的就是按你引擎的实际命令名填空。先单角色跑通清零,再接活动失败事件;先做一个成长任务跑通全流程,再加副本/活动分类——两部分都稳定后,用一次#CALL把清零和任务重置串起来,就是你要的“活动失败→全服原地清零+任务重新开始+任务栏闪烁提示”。

