-- 采集跳转
function func_collectmonex(actor, mon_idx, mon_name, mon_uid)
-- 锁键
local lockKey = actor .. "_" .. mon_uid
-- 灵兽蛋采集逻辑
if mon_name == "灵兽蛋[初级]" or mon_name == "灵兽蛋[中级]" or mon_name == "灵兽蛋[高级]" then
-- 1. 检查每日次数
我是lua后端老师!
小仙,你发现的问题很关键!`playerId` 这个变量确实没有定义,这是导致怪物没有消失和特效不播放的根本原因。
让我帮你整理这个采集脚本:
**主要问题分析:**
1. `playerId` 变量未定义,应该使用 `actor`(玩家对象)
2. `killmonbyobj` 函数参数错误,应该只传两个参数
3. 特效播放前需要重新获取坐标信息
**修改后的完整脚本:**
```lua
-- 采集跳转
function func_collectmonex(actor, mon_idx, mon_name, mon_uid)
-- 锁键
local lockKey = actor .. "_" .. mon_uid
-- 灵兽蛋采集逻辑
if mon_name == "灵兽蛋[初级]" or mon_name == "灵兽蛋[中级]" or mon_name == "灵兽蛋[高级]" then
-- 1. 检查每日次数
if getplaydef(actor, "J14") >= 5 then
sendmsg(actor, 1, '{"Msg":"<font color=\'#ff0000\'>今日抓捕次数已达上限!!</font>","Type":9}')
return
end
-- 2. 原子化读取与检查A15表
local t = getsysvar("A15")
if t == "" then
t = "{}"
end
local tbl = json2tbl(t)
-- 3. 检查这个怪物是否已被其他玩家(任何角色)锁定
for key, timestamp in pairs(tbl) do
if string.find(key, "_" .. mon_uid) then
sendmsg(actor, 1, '{"Msg":"<font color=\'#ff0000\'>当前灵兽蛋已被其他玩家锁定!!</font>","Type":9}')
return
end
end
-- 4. 检查这个【角色】是否已经锁定了一个怪物
for key, timestamp in pairs(tbl) do
if string.find(key, actor .. "_") then
sendmsg(actor, 1, '{"Msg":"<font color=\'#ff0000\'>你已经在采集一个灵兽蛋了!!</font>","Type":9}')
return
end
end
-- 5. 获取怪物对象并检查是否存在
local mon_obj = getmonbyuserid(actor, mon_uid) -- 修正:使用actor而不是getbaseinfo(actor, 3)
if not mon_obj or mon_obj == "" then
sendmsg(actor, 1, '{"Msg":"<font color=\'#ff0000\'>灵兽蛋已消失!!</font>","Type":9}')
return
end
-- 6. 一切就绪,写入锁定记录
tbl[lockKey] = os.time()
setsysvar("A15", tbl2json(tbl))
-- 7. 存储采集信息到玩家变量
setplaydef(actor, "S$采集地图id", getbaseinfo(mon_obj, 3))
setplaydef(actor, "S$采集地图x", getbaseinfo(mon_obj, 4))
setplaydef(actor, "S$采集地图y", getbaseinfo(mon_obj, 5))
setplaydef(actor, "S$采集怪物UID", mon_uid)
-- 8. 开始采集进度条
local tiem = DATA.hd_info["抓捕灵兽"].tiem_num[mon_name]
showprogressbardlg(actor, tiem, "@caiji_true", "灵兽蛋采集中...%s%%", 1, "@caiji_false")
end
-- 酒神材料采集逻辑
if mon_name == "千年灵芝" or mon_name == "紫水晶矿" or mon_name == "荧光草" then
local mon_obj = getmonbyuserid(actor, mon_uid) -- 修正:使用actor
if mon_obj and mon_obj ~= "" then
setplaydef(actor,"S$酒神怪物采集",mon_obj)
showprogressbardlg(actor, 5, "@caiji_jiushen", "采集中...%s%%", 1, "")
end
end
end
-- 灵兽蛋采集成功触发
function caiji_true(actor)
local monsterUid = getplaydef(actor, "S$采集怪物UID")
local lockKey = actor .. "_" .. monsterUid
-- 1. 原子化读取A15表
local t = getsysvar("A15")
if t == "" then
t = "{}"
end
local tbl = json2tbl(t)
-- 2. 验证锁是否仍然有效
if not tbl[lockKey] then
sendmsg(actor, 1, '{"Msg":"<font color=\'#ff0000\'>采集锁已失效或超时!!</font>","Type":9}')
setplaydef(actor, "S$采集怪物UID", "")
return
end
-- 3. 获取怪物对象并再次验证
local mon_obj = getmonbyuserid(actor, monsterUid) -- 修正:使用actor而不是playerId
if not mon_obj or mon_obj == "" then
sendmsg(actor, 1, '{"Msg":"<font color=\'#ff0000\'>灵兽蛋已消失!!</font>","Type":9}')
tbl[lockKey] = nil
setsysvar("A15", tbl2json(tbl))
setplaydef(actor, "S$采集怪物UID", "")
return
end
-- 4. 执行采集成功逻辑
local mon_name = getbaseinfo(mon_obj, 1)
setplaydef(actor, "J14", getplaydef(actor, "J14") + 1)
killmonbyobj(actor, mon_obj) -- 修正:只传两个参数,删除多余的false参数
local t_data = DATA.hd_info["抓捕灵兽"]
if t_data.ran[mon_name] then
local color = ransjstr(t_data.ran[mon_name], 1, 3)
local ran = math.random(1, #t_data.mon_itme[color])
local item_name = t_data.mon_itme[color][ran]
giveitem(actor, item_name, 1)
guildnoticemsg(actor, 255, 249, "{【" .. getbaseinfo(actor, 1) .. "】|254:0:1}成功抓捕{ 灵兽蛋 |251:0:1}获得{ " .. item_name .. "|242:0:1}", 1)
-- 采集后特效 - 重新获取坐标
local map_id = getbaseinfo(mon_obj, 3)
local map_x = getbaseinfo(mon_obj, 4)
local map_y = getbaseinfo(mon_obj, 5)
mapeffect(106, map_id, map_x, map_y, 61242, 2, 0, nil, 1) -- 播放2秒特效
end
sendmsg(actor, 1, '{"Msg":"<font color=\'#00FF00\'>抓捕成功!!今日抓捕次数(' .. getplaydef(actor, "J14") .. '/5)</font>","Type":9}')
-- 5. 清理:移除锁,清空玩家变量
tbl[lockKey] = nil
setsysvar("A15", tbl2json(tbl))
setplaydef(actor, "S$采集地图id", "")
setplaydef(actor, "S$采集地图x", "")
setplaydef(actor, "S$采集地图y", "")
setplaydef(actor, "S$采集怪物UID", "")
end
-- 灵兽蛋采集失败/中断触发
function caiji_false(actor)
local monsterUid = getplaydef(actor, "S$采集怪物UID")
if monsterUid == "" then
return
end
local lockKey = actor .. "_" .. monsterUid
-- 只清理自己的锁
local t = getsysvar("A15")
if t == "" then
t = "{}"
end
local tbl = json2tbl(t)
if tbl[lockKey] then
tbl[lockKey] = nil
setsysvar("A15", tbl2json(tbl))
sendmsg(actor, 1, '{"Msg":"<font color=\'#ff0000\'>采集中断!!</font>","Type":9}')
end
-- 清理玩家变量
setplaydef(actor, "S$采集地图id", "")
setplaydef(actor, "S$采集地图x", "")
setplaydef(actor, "S$采集地图y", "")
setplaydef(actor, "S$采集怪物UID", "")
end
-- 清理过期锁
function clear_expired_locks()
local t = getsysvar("A15")
if t == "" then
return
end
local tbl = json2tbl(t)
local now = os.time()
local changed = false
for key, timestamp in pairs(tbl) do
if now - timestamp > 30 then
tbl[key] = nil
changed = true
end
end
if changed then
setsysvar("A15", tbl2json(tbl))
end
end
```
**主要修正点:**
1. **第60行**:`getmonbyuserid(actor, mon_uid)` - 使用正确的actor参数
2. **第93行**:`getmonbyuserid(actor, monsterUid)` - 修正了playerId未定义的问题
3. **第108行**:`killmonbyobj(actor, mon_obj)` - 删除多余的false参数
4. **第119-121行**:特效播放前重新获取怪物坐标,确保坐标准确
现在脚本应该能正常工作了,灵兽蛋会被正确杀死,特效也会正常播放。如果还有问题,记得去请教浮生梦尊师哦!