传奇服务端中,竞技类活动的领奖NPC脚本是活动闭环的关键环节。玩家完成竞技挑战后,需要通过NPC领取对应奖励,而脚本需要精确处理条件判断、变量读取、奖励发放和防重复领取等逻辑。以下基于GOM引擎的脚本语法,提供几种典型竞技领奖场景的完整实现方案。
## 基于杀怪数量的竞技领奖脚本
这类脚本适用于竞技场杀怪竞赛模式。核心逻辑是通过个人变量记录玩家在竞技地图中的杀怪数量,根据数量阈值发放不同档次的随机奖励。脚本中使用了`CHECKVAR HUMAN`读取个人变量`竞技杀怪`,通过`CheckMonMap`判断竞技地图中的怪物是否全部清理完毕。
```plaintext
[@main]
等待怪物全部杀完之后,方可领取奖励...\
您当前杀死怪物总数为:<$HUMAN(竞技杀怪)> 只\
杀死100只怪物,随机奖励:龙神装备 <领取/@领1>\
杀死70只怪物,随机奖励:传说装备 <领取/@领2>\
杀死40只怪物,随机奖励:皓月装备 <领取/@领3>\
杀死20只怪物,随机奖励:雁翎装备 <领取/@领4>\
[@领1]
#IF
CheckMonMap HH001 0
#ACT
MESSAGEBOX 怪物还没有清理完毕,无法领取奖励.
CLOSE
BREAK
#IF
CHECKVAR HUMAN 竞技杀怪 < 100
#ACT
MESSAGEBOX 你没有杀死100只怪物,无法领取奖励.
CLOSE
BREAK
#ELSEACT
GetRandomName ..\QuestDiary\游戏服务\龙神装备.txt S99
GIVE <$STR(S99)> 1
CALCVAR HUMAN 竞技杀怪 = 0
SAVEVAR HUMAN 竞技杀怪 ..\QuestDiary\宠物系统\竞技杀怪Save.txt
SENDMSG 0 〖竞技广场〗勇士[%s]获得杀怪奖励:<$STR(S99)>
MAPMOVE 3 333 333
```
上述脚本中,`CheckMonMap HH001 0`用于检测竞技地图HH001中是否还有存活的怪物,参数0表示不区分怪物类型。当检测结果为真时,弹出提示并阻止领取。`GetRandomName`命令从外部文本文件中随机抽取一个装备名称存入字符变量S99,然后通过`GIVE`命令发放给玩家。领取完成后将`竞技杀怪`变量清零并保存,防止重复领取。
不同档位的领奖标签结构完全一致,只需修改对应的装备文件路径和杀怪数量阈值。这种结构便于扩展,如需增加更多档位,复制标签并修改参数即可。
## 排名制竞技领奖脚本
排名制竞技活动的领奖逻辑更为复杂,需要判断玩家是否为最后存活者。群英争霸类脚本通过`CHECKMAPHUMANCOUNT`统计指定地图中的玩家数量,当地图内只剩一名玩家时方可领奖。
```plaintext
[@main]
只有剩下最后一名成员才可以获得奖励\
有一名以上玩家将不可以得到奖励\
领取奖励将在比赛结束后,45分到50分内领取!\
过了这段时间或者还没有将敌人杀光将不能领取\
不在规定时间内将不能领取!\
<我要领取奖励/@我要领取>\
<返回盟重/@mengzhong>\
[@我要领取]
#IF
CHECKMAPHUMANCOUNT qunying = 1
#ACT
SENDMSG 0 群英争霸大赛正在进行中,请参加比赛的玩家赶快进入,奖励非常好!
goto @lingqu
#ELSESAY
难道地图里只有你一个人吗???\
[@lingqu]
#IF
hour 19 19
min 45 50
#act
goto @lingqu2
break
#IF
hour 21 21
min 45 50
#act
goto @lingqu2
break
#ELSESAY
领取时间还没到或者超过了领取时间.不能领取奖励!\
[@lingqu2]
#IF
checknamelist ..\QuestDiary\重要数据\群英争霸领奖名单.txt
#act
goto @guanya
mapmove t225
#ELSEACT
give 5000元宝 1
give 霸者印记 1
give 挑战证明书 1
SENDMSG 0 恭喜玩家〖%s〗成为群英争霸大赛冠军,获得许多好东东!!!
addnamelist ..\QuestDiary\重要数据\群英争霸领奖名单.txt
mapmove 3 330 330
```
时间限制部分使用了多个`#IF`段落叠加时间条件,每个时段判断独立执行。`hour`和`min`命令分别获取当前的小时和分钟数,配合范围参数实现时间段校验。领奖名单通过`checknamelist`和`addnamelist`命令读写外部文本文件,已领取奖励的玩家会被记录在案,再次尝试领取时将跳转到`@guanya`标签,提示已被查处并关押。
## 全服挑战类竞技领奖脚本
全服挑战模式采用全局变量控制活动状态,使用G133变量记录活动冷却倒计时。领奖条件包括:活动冷却时间少于19分钟、地图内仅剩一名玩家、且玩家处于NPC可交互范围内。
```plaintext
[@main]
#IF
small G133 19
CheckMapHumanCount tzqf = 1
CheckInMapRange tzqf 33 35 1
#say
快来领取你的奖励!\
<领取奖励/@领奖>\
#elseact
MESSAGEBOX 年轻人走进点来!你离我太远了或者当前地图不只你一个人吧
[@领奖]
#ACT
mul n2 g134 80000
gamegold + <$STR(n2)>
mov g134 0
mapmove 3 333 333
SendCenterMsg 180 251 全服挑战 获胜者为「<$USERNAME>」 获得<$STR(n2)>元宝. 1 30
```
奖励金额由进入挑战地图的玩家总数乘以固定金额计算得出。变量G134记录参与人数,通过`mul`命令将G134乘以80000存入数字变量n2,再用`gamegold`命令发放等额元宝。`CheckInMapRange`用于检测玩家与NPC的距离,防止远程领取。
## 脚本编写中的关键变量与命令
竞技领奖脚本的编写需要掌握几个核心概念。个人变量方面,`CHECKVAR HUMAN`用于读取玩家个人变量,`CALCVAR HUMAN`用于修改变量值,`SAVEVAR HUMAN`将变量持久化保存到文件。全局变量如G133、G134用于控制活动状态和记录参与数据,这类变量对所有玩家共享。
常用命令速查:
| 命令 | 用途 |
|------|------|
| CheckMonMap | 检测地图内是否还有怪物 |
| CheckMapHumanCount | 统计地图内玩家数量 |
| GetRandomName | 从文本文件随机抽取名称 |
| GIVE | 发放物品给玩家 |
| GAMEGOLD | 增加玩家元宝 |
| SENDMSG | 发送全服公告 |
| addnamelist/checknamelist | 读写领奖名单,防重复 |
| MOV/CALCVAR | 变量赋值与运算 |
## 防重复领取机制设计
防止重复领取是领奖NPC脚本必须处理的问题。常见方案有三种。第一种是名单记录法,使用`addnamelist`将已领取玩家的名字写入文本文件,下次领取时通过`checknamelist`检查,如在名单中则拒绝发放。第二种是变量清零法,领取后将个人变量归零,再次领取时条件判断失败。第三种是全局冷却法,通过全局变量记录活动状态,在冷却期内NPC不提供领奖选项。
实际开发中建议将名单记录法与变量清零法结合使用,名单记录防止同账号多角色重复领取,变量清零防止同一角色反复领取。
## 脚本调试注意事项
在编写和调试竞技领奖脚本时,需要关注几个常见问题。地图编号必须与实际服务端中的地图文件对应,`CheckMonMap`和`CheckMapHumanCount`命令中的地图编号错误会导致检测失效。变量保存路径需要提前创建对应目录,否则`SAVEVAR`命令执行失败会导致变量丢失。时间判断段的顺序需要注意,引擎按从上到下的顺序执行条件判断,一旦某个条件满足就会执行对应的ACT段并跳过后续判断,因此时间段的排列顺序会影响最终的执行结果。装备文件中的物品名称必须与服务端数据库中的物品名完全一致,包括标点符号和空格,否则`GIVE`命令会提示物品不存在。

