怎么记录玩家24小时打到的货币
🤖 回答引擎: 后端Lua |
🕒 时间: 2026-04-20 01:25:17 |
👁️ 阅读: 15
道友你好,我是lua后端老师!
小仙,这个问题问得好,记录玩家24小时内的货币获取量,是很多游戏里做活跃度统计、排行榜或者防沉迷系统的基础。在996引擎里,我们可以通过组合使用触发器和变量系统来实现。
核心思路是:在玩家**获得货币**的瞬间(比如打怪爆出、任务奖励等),将数量记录到一个**每日重置的变量**里。
这里给你一个完整的实现方案,主要分为两步:
### 第一步:在 QF(QuestDiary\QFunction-0.txt)中设置触发器
我们需要在玩家**获得经验**的触发器中记录,因为打怪获得货币通常伴随着经验获取。注意:**脚本直接使用`changeexp`添加的经验不会触发此接口**,但打怪、任务等正常途径获得的经验会触发。
在QF中添加或找到 `[@GetExp]` 段落,并加入Lua调用:
```lua
[@GetExp]
#IF
#ACT
-- 调用Lua脚本,将玩家对象actor和本次获得的经验值(由引擎传入)传递过去
-- 我们在这个Lua脚本里处理货币记录
callscript GetExpRecordMoney.lua <$param1> <$param2>
```
### 第二步:编写Lua脚本 (`GetExpRecordMoney.lua`)
这个脚本是核心,负责检查并累加货币。我们假设你想记录“金币”(货币ID为1)的获取量。
```lua
-- GetExpRecordMoney.lua
-- 功能:记录玩家24小时内通过打怪等方式获得的金币总量
-- 参数 actor: 玩家对象
-- 参数 exp: 本次获得的经验值(此处我们更关注伴随的货币,但exp参数保留以备他用)
local actor = arg[1] -- 获取第一个参数,玩家对象
-- local exp = tonumber(arg[2]) or 0 -- 第二个参数是经验值,本例暂不需要
-- 首先,我们需要一个机制来判断“今天”是否已经重置过记录。
-- 我们可以使用一个按日期变化的“标记”变量。
local todayMark = tostring(os.date("%Y%m%d")) -- 生成今日标记,例如 "20250420"
local lastRecordMark = getplayvar(actor, "MoneyRecordMark") -- 读取玩家上次记录的日期标记
-- 关键判断:如果上次记录的标记不是今天,说明是新的一天,需要清零累计值
if lastRecordMark ~= todayMark then
-- 重置今日货币累计值为0,并更新日期标记
setplayvar(actor, "TodayMoneyGained", "0")
setplayvar(actor, "MoneyRecordMark", todayMark)
release_print("玩家" .. actor .. "新的一天,货币记录已重置。")
end
-- 假设我们通过某种方式,知道了本次打怪获得了多少金币。
-- 注意:[@GetExp]触发时,引擎并不会直接告诉你获得了多少货币。
-- 因此,通常我们需要在另一个地方记录货币,比如“拾取物品前触发”[@PickUpItemFrontEx]。
-- 但为了给你一个清晰的思路,这里假设我们有一个方法能获取到本次金币增加值(例如从其他系统变量或估算)。
-- 更常见的做法是在“货币改变触发”[@MoneyChangeX]中处理,其中X是货币ID。
-- 以下是伪代码,展示如何累加:
-- local currentGained = tonumber(getplayvar(actor, "TodayMoneyGained")) or 0
-- local thisTimeMoney = 100 -- 这里应该是你计算出的本次实际获得金币数
-- local newTotal = currentGained + thisTimeMoney
-- setplayvar(actor, "TodayMoneyGained", tostring(newTotal))
-- release_print("玩家" .. actor .. "今日累计获得金币更新为:" .. newTotal)
```
### 更准确的实现:使用货币改变触发
实际上,更精准的方法是使用引擎提供的 **`[@MoneyChangeX]`** 触发器(X为货币ID)。当指定ID的货币数量发生变化时,此触发会被调用。
1. **在QF中配置触发器**(例如记录金币,ID为1):
```lua
[@MoneyChange1]
#IF
#ACT
-- 调用Lua脚本,传入玩家对象和改变的数量(引擎可能通过参数传递,具体需查证,这里假设通过变量获取)
-- 通常需要结合其他函数获取变动值,这里展示调用思路
callscript RecordDailyMoney.lua <$param1>
```
2. **编写 `RecordDailyMoney.lua`**:
```lua
-- RecordDailyMoney.lua
-- 记录玩家每日货币获取(以金币ID=1为例)
local actor = arg[1]
local todayMark = tostring(os.date("%Y%m%d"))
local lastRecordMark = getplayvar(actor, "GoldRecordMark")
if lastRecordMark ~= todayMark then
setplayvar(actor, "DailyGoldGained", "0")
setplayvar(actor, "GoldRecordMark", todayMark)
end
-- 注意:此触发在货币“改变”时即触发,包括增加和减少。
-- 我们需要判断这次变动是增加还是减少。通常需要结合其他逻辑或使用引擎提供的变动值参数。
-- 这里假设我们能获取到本次变动的正值(增加量)。
-- local changeAmount = getplayvar(actor, "tmp_GoldChange") -- 假设变动值已暂存在某变量
-- 由于直接获取变动值较复杂,一种实践方法是:在给与货币的脚本操作(如giveitem给与货币物品)后,主动调用此累加逻辑。
-- 因此,更可靠的方案是:在你所有“给予玩家货币”的脚本处(如怪物爆出、任务奖励脚本),
-- 不要直接使用giveitem,而是封装一个自己的函数,在其中既给与货币,又调用下面的累加函数。
```
### 推荐方案:封装自定义给予货币函数
这是最清晰、最可控的方式。创建一个公共Lua函数文件,比如 `CommonGiveMoney.lua`:
```lua
-- CommonGiveMoney.lua
-- 自定义给予货币函数,并记录每日获取量
function GiveMoneyAndRecord(actor, moneyId, amount, reason)
-- actor: 玩家对象
-- moneyId: 货币ID
-- amount: 给予数量
-- reason: 原因,文本,用于日志
-- 1. 给予货币
changemoney(actor, moneyId, "+", amount, reason, true)
-- 2. 仅当货币ID为1(金币)时,进行每日记录(可按需扩展)
if moneyId == 1 then
local todayMark = tostring(os.date("%Y%m%d"))
local lastMark = getplayvar(actor, "DailyGoldMark")
if lastMark ~= todayMark then
setplayvar(actor, "DailyGoldGained", "0")
setplayvar(actor, "DailyGoldMark", todayMark)
end
local currentTotal = tonumber(getplayvar(actor, "DailyGoldGained")) or 0
local newTotal = currentTotal + amount
setplayvar(actor, "DailyGoldGained", tostring(newTotal))
release_print(string.format("玩家[%s]因[%s]获得金币%d,今日累计:%d", actor, reason, amount, newTotal))
end
end
-- 在其他脚本中,调用此函数代替 changemoney
-- 例如:callscript CommonGiveMoney.lua GiveMoneyAndRecord <$param1> 1 1000 "击杀怪物"
```
### 如何查询?
当你想查看或使用这个24小时累计值时,比如在NPC脚本中:
```lua
[@main]
你好,我可以查看你今日的努力成果。\
<查看今日赚取金币/@viewMoney>\
[@viewMoney]
#IF
#ACT
-- 获取玩家今日金币获取量
local todayGold = getplayvar(<$param1>, "DailyGoldGained")
-- 注意:<$param1> 在NPC对话中可能不是玩家对象,通常用 <$USERNAME> 或通过其他方式获取actor。
-- 正确写法通常需要在QF的[@clicknpc]触发里调用Lua,并传递actor。
-- 这里展示Lua函数内的逻辑:
local actor = ... -- 从参数获取玩家对象
local gold = tonumber(getplayvar(actor, "DailyGoldGained")) or 0
sendmsg(actor, "您今日通过奋斗赚取了 " .. gold .. " 金币!", 1)
```
**总结一下关键点:**
1. **选择记录点**:最准确的是在**所有给予货币的源头**进行记录,推荐封装自定义函数。
2. **每日重置**:利用 `os.date(“%Y%m%d”)` 生成日期标记,与玩家变量中存储的标记对比,不同则清零累计值。
3. **使用变量**:`setplayvar` 和 `getplayvar` 用于存储和读取玩家的累计值。
4. **注意触发器的限制**:`[@GetExp]` 不适用于脚本添加的经验;`[@MoneyChangeX]` 能捕获所有变动但需区分增减。
小仙,你先从封装一个 `GiveMoneyAndRecord` 函数开始实践吧,这是最稳妥的方法。过程中有不明白的,随时可以再来问我,或者请教我师傅浮生梦尊师!
← 返回问答库