传奇GM可控NPC竞价拍卖脚本编写全流程详解

来源: 作者: 点击:
该脚本核心是实现“GM预设拍卖物品、价格规则、时间范围→NPC作为拍卖载体→玩家竞价→GM全程可控”的闭环,核心依赖传奇服务端脚本体系(Dialog.txt、QFunction-0.txt、变量存储),以下是通用实操方案,含GM控制模块、NPC交互、竞价逻辑完整代码。

一、脚本核心逻辑与前置准备

1. 核心逻辑拆解

GM端:通过专属指令/界面设置拍卖物品(ID/名称)、底价、最低加价幅度、封顶价(可选)、拍卖时长;NPC端:展示拍卖信息、接收玩家竞价、实时播报竞价状态;核心规则:到点自动成交/GM可手动终止,竞价失败返还金币,成交后物品发放给最高价玩家。

2. 前置准备

(1)确认文件权限:确保可编辑Dialog.txt(NPC对话脚本)、QFunction-0.txt(核心逻辑脚本),新增拍卖变量存储文件(如AuctionVar.txt,用于记录拍卖状态)。

(2)定义关键标识:预留NPCID(如拍卖专员ID=601)、GM指令前缀(如@SetAuction)、拍卖状态变量(AuctionStatus:0=未开启,1=进行中,2=已结束)。

(3)语法适配:以下案例采用主流#IF/#ACT/#ELSE语法,不同版本服务端可微调指令(如部分版本变量存储用SetVar/SaveVar,部分用WriteFile)。

二、完整脚本编写步骤(分3大模块)

模块1:GM控制模块(设置拍卖参数、启停拍卖)

功能:GM通过指令设置拍卖物品、价格、时间,支持手动终止拍卖,核心代码写在QFunction-0.txt。

// GM设置拍卖参数指令(格式:@SetAuction 物品ID 底价 最低加价 时长(分) 封顶价(可选))
[@SetAuction]
#IF
CheckAdminLevel 3 // 校验GM权限(3为高级GM,可按需调整权限等级)
CheckStrLen <$PARAM> 10 // 校验参数长度(避免空参数)
#ACT
// 解析参数:$PARAM1=物品ID,$PARAM2=底价,$PARAM3=最低加价,$PARAM4=时长,$PARAM5=封顶价
SetVar AuctionItemID <$PARAM1> // 存储拍卖物品ID
SetVar AuctionBasePrice <$PARAM2> // 存储底价
SetVar AuctionAddPrice <$PARAM3> // 存储最低加价幅度
SetVar AuctionTime <$PARAM4> // 存储拍卖时长(单位:分)
SetVar AuctionTopPrice <$PARAM5> // 存储封顶价(0=无封顶)
SetVar AuctionStatus 1 // 开启拍卖状态
SetVar AuctionNowPrice <$PARAM2> // 当前竞价价初始化为底价
SetVar AuctionWinner 0 // 初始获胜者ID为0(无)
// 计算拍卖结束时间(当前时间+时长,单位:秒)
GetTime AuctionStartTime // 记录开始时间
SetVar AuctionEndTime <$AuctionStartTime> + <$PARAM4> * 60
// 发送全服公告
SendBroadCast 2 【拍卖开启】GM已开启NPC竞价拍卖,物品ID:<$PARAM1>,底价:<$PARAM2>金币,时长:<$PARAM4>分!
SaveVar // 保存所有拍卖变量到AuctionVar.txt
#ELSE
SendMsg 6 权限不足或参数格式错误!正确格式:@SetAuction 物品ID 底价 最低加价 时长 封顶价
#ENDIF

// GM手动终止拍卖指令
[@StopAuction]
#IF
CheckAdminLevel 3
CheckVar AuctionStatus 1 // 校验拍卖处于进行中
#ACT
SetVar AuctionStatus 2 // 标记拍卖结束
// 判定成交:若有获胜者则发放物品,否则流拍
#IF
CheckVarNotEqual AuctionWinner 0
#ACT
GiveItem <$AuctionItemID> 1 <$AuctionWinner> // 给获胜者发放物品
SendBroadCast 2 【拍卖终止】物品ID<$AuctionItemID>拍卖终止,获胜者:<$AuctionWinner>,成交价格:<$AuctionNowPrice>金币!
#ELSE
SendBroadCast 2 【拍卖终止】物品ID<$AuctionItemID>流拍,无玩家参与竞价!
#ENDIF
SaveVar
#ELSE
SendMsg 6 权限不足或当前无进行中的拍卖!
#ENDIF

模块2:NPC交互模块(展示信息、接收玩家竞价)

功能:NPC“拍卖专员”(ID=601)展示当前拍卖状态,玩家点击参与竞价,核心代码写在Dialog.txt。

// 拍卖专员NPC对话脚本(NPCID=601)
[@Dialog601]
#IF
CheckVar AuctionStatus 0 // 拍卖未开启
#ACT
Say 当前无正在进行的拍卖,敬请期待!\
<离开/@exit>
#ELSEIF
CheckVar AuctionStatus 1 // 拍卖进行中
#ACT
// 读取拍卖变量,展示当前信息
LoadVar // 加载AuctionVar.txt中的变量
Say 【当前拍卖中】\
Say 物品ID:<$AuctionItemID> 当前竞价:<$AuctionNowPrice>金币\
Say 最低加价:<$AuctionAddPrice>金币 剩余时间:<$AuctionEndTime - $CURRENTTIME>/60 分\
Say 封顶价:<$IIf($AuctionTopPrice>0,$AuctionTopPrice,无)>\
<参与竞价/@JoinAuction>\
<离开/@exit>
#ELSE
#ACT
Say 上一轮拍卖已结束,获胜者:<$IIf($AuctionWinner>0,$AuctionWinner,无)>\
<离开/@exit>
#ENDIF

模块3:竞价核心模块(玩家加价、价格校验、状态更新)

功能:处理玩家竞价请求,校验金币是否充足、加价是否符合规则,更新当前最高价,核心代码写在QFunction-0.txt。

// 玩家参与竞价脚本
[@JoinAuction]
#IF
CheckVar AuctionStatus 1 // 校验拍卖进行中
CheckGold <$AuctionNowPrice + $AuctionAddPrice> // 校验金币≥当前价+最低加价
#ACT
// 扣除竞价金币(成交前先冻结,失败返还)
GoldDeduct <$AuctionNowPrice + $AuctionAddPrice>
// 更新当前竞价价和获胜者
SetVar AuctionNowPrice <$AuctionNowPrice + $AuctionAddPrice>
SetVar AuctionWinner <$USERID> // 记录当前玩家ID为获胜者
// 校验是否达到封顶价
#IF
CheckVar AuctionTopPrice > 0
CheckVar AuctionNowPrice >= <$AuctionTopPrice>
#ACT
SetVar AuctionStatus 2 // 触发封顶成交
SendBroadCast 2 【竞价封顶】玩家<$USERNAME>以封顶价<$AuctionTopPrice>金币竞得物品ID<$AuctionItemID>!
GiveItem <$AuctionItemID> 1 <$USERID>
SaveVar
Goto @Dialog601
#ELSE
#ACT
// 播报当前竞价状态
SendBroadCast 3 玩家<$USERNAME>加价<$AuctionAddPrice>金币,当前最高价:<$AuctionNowPrice>金币!
SaveVar
SendMsg 6 竞价成功,当前最高价已更新为<$AuctionNowPrice>金币!
Goto @Dialog601
#ENDIF
#ELSE
#ACT
SendMsg 6 金币不足(需>=$AuctionNowPrice + $AuctionAddPrice金币)或当前无进行中的拍卖!
Goto @Dialog601
#ENDIF

// 拍卖时间自动结束脚本(定时触发,每10秒检测一次)
[@Timer10000]
#IF
CheckVar AuctionStatus 1 // 拍卖进行中
CheckTime >= <$AuctionEndTime> // 当前时间≥结束时间
#ACT
SetVar AuctionStatus 2 // 标记拍卖结束
#IF
CheckVarNotEqual AuctionWinner 0
#ACT
GiveItem <$AuctionItemID> 1 <$AuctionWinner> // 发放物品
SendBroadCast 2 【拍卖结束】物品ID<$AuctionItemID>拍卖结束,玩家<$AuctionWinner>以<$AuctionNowPrice>金币成交!
#ELSE
SendBroadCast 2 【拍卖结束】物品ID<$AuctionItemID>流拍,无玩家参与竞价!
#ENDIF
SaveVar
#ENDIF

三、关键要点与常见问题解决

1. 关键编写要点

(1)变量持久化:所有拍卖变量(物品ID、价格、状态)需用SaveVar/LoadVar指令读写,避免服务端重启后数据丢失。

(2)权限严格校验:GM控制指令必须添加CheckAdminLevel,防止普通玩家篡改拍卖参数。

(3)金币冻结机制:玩家竞价时先扣除金币,若后续被其他玩家超越,需添加“返还金币”逻辑(可在新玩家竞价成功后,给上一任获胜者返还金币)。

(4)时间精准性:定时检测间隔(如10秒)不宜过短(增加服务器负载)或过长(导致结束延迟),建议5-10秒。

2. 常见问题解决

(1)GM设置参数后无反应:检查参数格式(如物品ID是否为数字)、权限等级是否正确(CheckAdminLevel数值)、变量是否保存(SaveVar指令是否添加)。

(2)玩家竞价后金币扣除但未更新状态:校验AuctionNowPrice变量是否正确赋值、SaveVar是否执行,排查语法错误(如括号不匹配、变量名拼写错误)。

(3)拍卖结束后物品未发放:检查GiveItem指令格式(正确格式:GiveItem 物品ID 数量 玩家ID)、获胜者ID(AuctionWinner)是否正确记录。

(4)无法手动终止拍卖:校验AuctionStatus变量是否为1(进行中),StopAuction脚本中CheckVar条件是否正确。

四、脚本拓展方向

(1)多物品同时拍卖:新增拍卖场次变量(AuctionID),支持GM开启多场拍卖,NPC界面展示多场次选项。

(2)竞价记录展示:添加[@ShowAuctionLog]脚本,玩家可查看历史竞价记录(用户名、加价金额、时间)。

(3)流拍物品处理:GM可设置流拍后物品返还给自己或自动存入指定仓库,添加对应GiveItem/StoreItem指令即可。

(4)短信提醒:玩家竞价被超越时,发送系统提示(SendMsg)告知,提升参与感。