我是lua后端老师!
小仙,我来帮你分析一下这个采集脚本的问题。从代码来看,主要问题在于多个账号反复取消采集时怪物不消失,以及统一账号多角色采集的逻辑处理。让我帮你重新整理一下:
```lua
-- 采集前触发
function collectmonex(actor, mon_idx, mon_name, mon_uid)
func_collectmonex(actor, mon_idx, mon_name, mon_uid)
end
-- 采集跳转主函数
function func_collectmonex(actor, mon_idx, mon_name, mon_uid)
-- 获取怪物对象
local mon_obj = getmonbyuserid(getbaseinfo(actor, 3), mon_uid)
if not mon_obj or mon_obj == "" then
return
end
-- 酒神材料采集
if mon_name == "千年灵芝" or mon_name == "紫水晶矿" or mon_name == "荧光草" then
setplaydef(actor, "S$酒神怪物采集", mon_obj)
showprogressbardlg(actor, 5, "@caiji_jiushen", "采集中...%s%%", 1, "")
return
end
-- 活动怪物 - 灵兽蛋
if mon_name == "灵兽蛋[初级]" or mon_name == "灵兽蛋[中级]" or mon_name == "灵兽蛋[高级]" then
-- 检查每日采集次数限制
if getplaydef(actor, "J14") >= 5 then
sendmsg(actor, 1, '{"Msg":"<font color=\'#ff0000\'>今日抓捕次数已达上限!!</font>","Type":9}')
return
end
-- 使用玩家唯一ID作为key,避免账号多角色冲突
local player_uid = getbaseinfo(actor, 3)
local t = getsysvar("A15") ~= "" and json2tbl(getsysvar("A15") or "{}") or {}
-- 检查是否已被其他玩家采集
for k, v in pairs(t) do
if k == mon_uid then -- 怪物已被标记
sendmsg(actor, 1, '{"Msg":"<font color=\'#ff0000\'>当前灵兽蛋已被其他玩家采集!!</font>","Type":9}')
return
end
end
-- 标记怪物被采集
t[mon_uid] = {
player_uid = player_uid,
player_name = getbaseinfo(actor, 1),
map_id = getbaseinfo(mon_obj, 3),
map_x = getbaseinfo(mon_obj, 4),
map_y = getbaseinfo(mon_obj, 5),
start_time = os.time()
}
setsysvar("A15", tbl2json(t))
-- 保存采集位置信息
setplaydef(actor, "S$采集怪物UID", mon_uid)
setplaydef(actor, "S$采集地图id", getbaseinfo(mon_obj, 3))
setplaydef(actor, "S$采集地图x", getbaseinfo(mon_obj, 4))
setplaydef(actor, "S$采集地图y", getbaseinfo(mon_obj, 5))
-- 开始采集进度条
local tiem = DATA.hd_info["抓捕灵兽"].tiem_num[mon_name]
showprogressbardlg(actor, tiem, "@caiji_true", "灵兽蛋采集中...%s%%", 1, "@caiji_false")
end
end
-- 酒神材料对应表
local jiushen_list = {
["千年灵芝"] = "千年灵芝",
["荧光草"] = "荧光草",
["紫水晶矿"] = "紫水晶",
}
-- 酒神材料采集成功触发
function caiji_jiushen(actor)
local mon_obj = getplaydef(actor, "S$酒神怪物采集")
if not mon_obj or mon_obj == "" then
return
end
local mon_name = getbaseinfo(mon_obj, 1)
local item_name = jiushen_list[mon_name]
if item_name then
killmonbyobj(actor, mon_obj, false, false, false) -- 杀死怪物
giveitem(actor, item_name, 1, 307, "采集")
sendmsg(actor, 1, '{"Msg":"<font color=\'#00FF00\'>采集成功!!</font>","Type":9}')
guildnoticemsg(actor, 255, 249, "{【".. getbaseinfo(actor,1) .."】|254:0:1}成功采集了{".. mon_name .."|251:0:1}", 1)
end
-- 清理变量
setplaydef(actor, "S$酒神怪物采集", "")
end
-- 灵兽蛋采集成功触发
function caiji_true(actor)
local mon_uid = getplaydef(actor, "S$采集怪物UID")
if not mon_uid or mon_uid == "" then
return
end
local t = getsysvar("A15") ~= "" and json2tbl(getsysvar("A15") or "{}") or {}
local collect_info = t[mon_uid]
-- 验证采集者身份
if not collect_info or collect_info.player_uid ~= getbaseinfo(actor, 3) then
sendmsg(actor, 1, '{"Msg":"<font color=\'#ff0000\'>采集验证失败!!</font>","Type":9}')
t[mon_uid] = nil
setsysvar("A15", tbl2json(t))
return
end
-- 获取怪物对象
local mon_obj = getmonbyuserid(collect_info.map_id, mon_uid)
if not mon_obj or mon_obj == "" then
t[mon_uid] = nil
setsysvar("A15", tbl2json(t))
return
end
local mon_name = getbaseinfo(mon_obj, 1)
-- 更新采集次数
setplaydef(actor, "J14", getplaydef(actor, "J14") + 1)
-- 杀死怪物
killmonbyobj(actor, mon_obj, false, false, false)
-- 发放奖励
local hd_info = DATA.hd_info["抓捕灵兽"]
if hd_info.ran[mon_name] then
local color = ransjstr(hd_info.ran[mon_name], 1, 3)
local ran = math.random(1, #hd_info.mon_itme[color])
local item_name = hd_info.mon_itme[color][ran]
giveitem(actor, item_name, 1)
-- 播放采集特效
mapeffect(106, collect_info.map_id, collect_info.map_x, collect_info.map_y, 61242, 2, 0, nil, 1)
-- 发送消息
sendmsg(actor, 1, '{"Msg":"<font color=\'#00FF00\'>抓捕成功!!今日抓捕次数(' .. getplaydef(actor, "J14") .. '/5)</font>","Type":9}')
guildnoticemsg(actor, 255, 249, "{【" .. collect_info.player_name .. "】|254:0:1}成功抓捕{ 灵兽蛋 |251:0:1}获得{ " .. item_name .. "|242:0:1}", 1)
end
-- 清理数据
t[mon_uid] = nil
setsysvar("A15", tbl2json(t))
setplaydef(actor, "S$采集怪物UID", "")
setplaydef(actor, "S$采集地图id", "")
setplaydef(actor, "S$采集地图x", "")
setplaydef(actor, "S$采集地图y", "")
end
-- 灵兽蛋采集失败触发
function caiji_false(actor)
local mon_uid = getplaydef(actor, "S$采集怪物UID")
if not mon_uid or mon_uid == "" then
return
end
local t = getsysvar("A15") ~= "" and json2tbl(getsysvar("A15") or "{}") or {}
-- 只清理当前玩家的采集记录
local collect_info = t[mon_uid]
if collect_info and collect_info.player_uid == getbaseinfo(actor, 3) then
t[mon_uid] = nil
setsysvar("A15", tbl2json(t))
sendmsg(actor, 1, '{"Msg":"<font color=\'#ff0000\'>采集中断!!</font>","Type":9}')
end
-- 清理玩家变量
setplaydef(actor, "S$采集怪物UID", "")
setplaydef(actor, "S$采集地图id", "")
setplaydef(actor, "S$采集地图x", "")
setplaydef(actor, "S$采集地图y", "")
end
-- 新增:清理过期采集记录的定时函数
function clean_expired_collect()
local t = getsysvar("A15") ~= "" and json2tbl(getsysvar("A15") or "{}") or {}
local current_time = os.time()
local cleaned = false
for mon_uid, info in pairs(t) do
-- 超过30秒未完成的采集视为过期
if current_time - info.start_time > 30 then
t[mon_uid] = nil
cleaned = true
end
end
if cleaned then
setsysvar("A15", tbl2json(t))
end
end
```
主要改进点:
1. **使用怪物UID作为唯一标识**:解决了多个账号反复取消采集导致怪物不消失的问题
2. **记录玩家唯一ID**:确保同一账号的不同角色采集逻辑正常
3. **增加采集验证**:在采集成功时验证玩家身份,防止冒领
4. **优化数据清理**:只清理当前玩家的采集记录,不影响其他玩家
5. **添加过期清理**:防止采集记录长时间占用内存
小仙,这样修改后应该能解决你遇到的问题。记得在服务端启动时设置一个定时器来调用`clean_expired_collect`函数,定期清理过期采集记录哦!