在一个地图内 玩家持有宝箱180秒将获得奖励
1:有人持有宝箱后开启全区倒计时: "xxx玩家 持有宝箱 继续持有180秒后获得奖励!"
2: 持有宝箱玩家下限 切换地图 宝箱重新放置回原地图 其他玩家持有后重新开启全区倒计时
3: 倒计时结束玩家获得一个金条并收回宝箱
4: 如果22:00 活动结束 没有玩家持有宝箱180秒, 则检测现在持有宝箱的玩家获得1个金条并收走宝箱
🤖 回答引擎: 后端Lua |
🕒 时间: 2026-06-06 11:34:05 |
👁️ 阅读: 13
我是lua后端老师!
小仙,你这个宝箱活动设计得很有意思啊!我来帮你一步步实现这个功能。我们先从核心逻辑开始,需要用到地图定时器和全局公告功能。
首先,我们需要在QF脚本中设置几个触发点:
```lua
-- QFunction-0.txt 中的触发
[@login]
#IF
#ACT
-- 玩家登录时检查是否持有宝箱
callscript "宝箱活动.lua" "checkBoxHolder" <$USERNAME>
[@leavemap]
#IF
#ACT
-- 玩家离开地图时检查
callscript "宝箱活动.lua" "leaveMapCheck" <$USERNAME>
[@playoffline]
#IF
#ACT
-- 玩家下线时检查
callscript "宝箱活动.lua" "offlineCheck" <$USERNAME>
-- 22:00活动结束触发(需要设置全局定时器)
[@ontimerex(22_00)]
#ACT
callscript "宝箱活动.lua" "activityEnd"
```
现在创建宝箱活动的主脚本:
```lua
-- 宝箱活动.lua
local BOX_ITEM_NAME = "宝箱" -- 宝箱物品名称
local REWARD_ITEM = "金条" -- 奖励物品
local HOLD_TIME = 180 -- 持有时间180秒
local ACTIVITY_END_HOUR = 22 -- 活动结束时间22点
-- 全局变量存储当前持有者信息
local currentHolder = nil
local startTime = nil
local mapID = "3" -- 宝箱初始地图ID
local posX = 330 -- 宝箱初始坐标X
local posY = 330 -- 宝箱初始坐标Y
-- 检查玩家是否持有宝箱
function checkBoxHolder(playerName)
local player = getplayerbyname(playerName)
if not player then return end
if hasitem(player, BOX_ITEM_NAME) > 0 then
if currentHolder == nil then
currentHolder = playerName
startTime = os.time()
startCountdown(playerName)
end
end
end
-- 开始全区倒计时
function startCountdown(holderName)
-- 发送全区公告
sendcentermsg(nil, 180, 251, holderName.."玩家 持有宝箱 继续持有180秒后获得奖励!", 1, HOLD_TIME, "@giveReward")
-- 设置180秒后触发奖励
setenvirontimer(mapID, 1, HOLD_TIME, "@giveReward,"..holderName)
end
-- 给予奖励(倒计时结束或活动结束)
function giveReward(sysobj, holderName)
local player = getplayerbyname(holderName)
if not player then
-- 玩家不在线,宝箱放回原地图
resetBox()
return
end
-- 检查玩家是否还持有宝箱
if hasitem(player, BOX_ITEM_NAME) > 0 then
-- 给予金条奖励
giveitem(player, REWARD_ITEM, 1)
-- 收回宝箱
takeitem(player, BOX_ITEM_NAME, 1)
-- 发送奖励公告
sendcentermsg(nil, 180, 251, holderName.."成功持有宝箱180秒,获得金条奖励!", 1, 10)
end
-- 重置持有者信息
currentHolder = nil
startTime = nil
end
-- 玩家离开地图检查
function leaveMapCheck(playerName)
if currentHolder == playerName then
local player = getplayerbyname(playerName)
if player and hasitem(player, BOX_ITEM_NAME) > 0 then
-- 收回宝箱并放回原地图
takeitem(player, BOX_ITEM_NAME, 1)
resetBox()
sendcentermsg(nil, 180, 251, playerName.."离开地图,宝箱已重置!", 1, 10)
end
end
end
-- 玩家下线检查
function offlineCheck(playerName)
if currentHolder == playerName then
-- 宝箱放回原地图
resetBox()
sendcentermsg(nil, 180, 251, playerName.."已下线,宝箱已重置!", 1, 10)
end
end
-- 重置宝箱到原地图
function resetBox()
-- 清除当前持有者信息
currentHolder = nil
startTime = nil
-- 关闭之前的定时器
if hasenvirtimer(mapID, "1") then
setenvirofftimer(mapID, 1)
end
-- 在地图上生成宝箱
local items = {
[BOX_ITEM_NAME] = 1
}
local data = {
["map"] = mapID,
["source"] = 1, -- GM生成
["player"] = "系统"
}
gendropitem(mapID, nil, posX, posY, tbl2json(items), tbl2json(data))
end
-- 活动结束处理
function activityEnd()
-- 关闭倒计时定时器
if hasenvirtimer(mapID, "1") then
setenvirofftimer(mapID, 1)
end
if currentHolder then
local player = getplayerbyname(currentHolder)
if player and hasitem(player, BOX_ITEM_NAME) > 0 then
-- 给予金条奖励
giveitem(player, REWARD_ITEM, 1)
-- 收回宝箱
takeitem(player, BOX_ITEM_NAME, 1)
sendcentermsg(nil, 180, 251, "活动结束,"..currentHolder.."获得宝箱持有奖励!", 1, 10)
else
-- 持有者不在线或没有宝箱,重置宝箱
resetBox()
end
else
-- 没有人持有宝箱,检查地图上是否有宝箱并清理
clearitemmap(mapID, posX, posY, 10, BOX_ITEM_NAME)
-- 重新放置宝箱
resetBox()
end
-- 重置变量
currentHolder = nil
startTime = nil
end
-- 初始化函数(服务端启动时调用)
function initActivity()
-- 清理地图上的旧宝箱
clearitemmap(mapID, posX, posY, 10, BOX_ITEM_NAME)
-- 放置初始宝箱
resetBox()
end
-- 在QF的startup触发中调用初始化
-- [@startup]
-- #ACT
-- callscript "宝箱活动.lua" "initActivity"
```
**关键点说明:**
1. **全局公告**:使用`sendcentermsg`发送全区倒计时公告,`flag=1`表示发送给所有人
2. **地图定时器**:使用`setenvirontimer`设置180秒的倒计时,结束时触发`giveReward`函数
3. **持有者检查**:通过`hasitem`函数检查玩家是否持有宝箱
4. **宝箱重置**:使用`gendropitem`在地图上生成宝箱,`clearitemmap`清理旧宝箱
5. **定时器管理**:使用`hasenvirtimer`检查定时器是否存在,`setenvirofftimer`关闭定时器
**使用步骤:**
1. 在QF的`startup`触发中调用`initActivity()`初始化宝箱
2. 设置22:00的全局定时器`ontimerex(22_00)`触发活动结束
3. 配置好登录、离开地图、下线等触发点
小仙,这个脚本实现了你的所有需求,如果有不懂的地方可以随时问我!记得测试时先用测试物品,别把珍贵的金条给错啦~
← 返回问答库