-- 幸运转轮后端逻辑
local xingyunzhuanlun = {}
local frameToValue = {1, 0, -1, 1, 5, 0, 3, -1} -- 索引1~8 对应 帧0~7
local frameToText = {"+1", "0", "-1", "+1", "+5", "0", "+3", "-1"} -- 索引1~8 对应 帧0~7
-- 每个帧的选中概率(1-100百分比)
local frameProbability = {19, 16, 5,
🤖 回答引擎: 后端Lua |
🕒 时间: 2026-03-08 16:45:01 |
👁️ 阅读: 9
我是lua后端老师!
小仙,我看了你的代码,问题出在第230行的 `release_print` 函数中。错误信息提示 `bad argument #2 to 'format' (number expected, got nil)`,这意味着 `stopFrame` 变量在 `arg2 ~= nil` 这个判断分支里是 `nil` 值。
让我帮你分析一下问题所在:
```lua
-- 问题分析:
-- 你的代码结构是这样的:
function xingyunzhuanlun.link(actor, msgid, arg1, arg2, arg3, sMsg)
-- ... 前面的代码 ...
-- 普通转动
if arg2 == 0 then
local stopFrame = xingyunzhuanlun.getRandomFrameByProbability()
-- 这里定义了 stopFrame
-- 高级转动
elseif arg2 == 1 then
local stopFrame = xingyunzhuanlun.getRandomFrameByProbability()
-- 这里也定义了 stopFrame
end -- 注意:这里有一个 end 结束了 if-elseif 结构
-- 后端发送停止帧给前端
if arg2 ~= nil then -- 这个 if 是在 link 函数内部的,但它在 if-elseif 结构的外面
local resp = {
stopFrame = stopFrame, -- 问题所在:这里的 stopFrame 是 nil
luckChange = value, -- value 也是 nil
isAdvanced = (arg2 == 1)
}
-- ... 后面的代码 ...
end
end -- 这是 link 函数的结束
```
**问题原因:**
1. `stopFrame` 和 `value` 变量是在 `arg2 == 0` 和 `arg2 == 1` 这两个分支内部定义的(使用 `local` 关键字)
2. Lua 的局部变量作用域只在定义它的代码块内有效
3. 当代码执行到 `if arg2 ~= nil then` 这个判断时,之前的 `stopFrame` 和 `value` 已经超出了作用域,所以是 `nil`
**解决方案:**
将发送给前端的代码移到每个转动类型的分支内部:
```lua
function xingyunzhuanlun.link(actor, msgid, arg1, arg2, arg3, sMsg)
if not cfg_xingyunzhuanlun or not next(cfg_xingyunzhuanlun) then
return
end
-- 获取当前幸运值(从U31变量获取)
local oldLuckValue = xingyunzhuanlun.getU31Value(actor)
release_print(string.format("【后端】玩家旧幸运值(U31): %d", oldLuckValue))
-- 显示概率分布表
xingyunzhuanlun.showProbabilityTable()
-- 普通转动
if arg2 == 0 then
release_print("【操作类型】: 普通转动")
local currentGold = querymoney(actor, 1) or 0
currentGold = tonumber(currentGold) or 0
local normalCost = 250000
-- 检查金币是否足够
if currentGold < normalCost then
sendMsg(actor, "金币不足,无法进行普通转动")
return
end
-- 扣除金币
changemoney(actor, 1, "-", normalCost, "转轮扣除", true)
release_print(string.format("扣除金币: %d", normalCost))
-- 根据概率随机选择停止帧
local stopFrame = xingyunzhuanlun.getRandomFrameByProbability()
local value = frameToValue[stopFrame + 1] or 0
local frameDesc = frameToText[stopFrame + 1] or "未知"
release_print(string.format("【随机结果】帧%d: 值=%d, 描述=%s", stopFrame, value, frameDesc))
-- 计算新幸运值
local newLuckValue = oldLuckValue + value
if newLuckValue < 0 then
newLuckValue = 0
end
release_print(string.format("【幸运值计算】: %d + %d = %d", oldLuckValue, value, newLuckValue))
-- 更新幸运值到U31变量
newLuckValue = xingyunzhuanlun.setU31Value(actor, newLuckValue)
-- 发送消息给玩家
sendMsg(actor, string.format("普通转动:幸运值%s,当前幸运值:%d", frameDesc, newLuckValue))
-- 更新属性加成
xingyunzhuanlun.updateAttributes(actor, newLuckValue)
-- 后端发送停止帧给前端(放在普通转动分支内部)
local resp = {
stopFrame = stopFrame, -- 停止帧(0-7)
luckChange = value, -- 幸运值变化
isAdvanced = (arg2 == 1) -- 是否是高级转动
}
local respStr = tbl2json(resp)
release_print(string.format("【发送给前端】stopFrame=%d, luckChange=%d, isAdvanced=%s",
stopFrame, value, tostring(arg2 == 1)))
sendMsg(actor, 58004, 0, 0, 0, respStr)
-- 高级转动
elseif arg2 == 1 then
release_print("【操作类型】: 高级转动")
local currentGold = querymoney(actor, 1) or 0
currentGold = tonumber(currentGold) or 0
local goldCost = 250000
local currentIngot = querymoney(actor, 2) or 0
currentIngot = tonumber(currentIngot) or 0
local ingotCost = 20000
-- 检查金币和元宝是否足够
if currentGold < goldCost then
sendMsg(actor, "金币不足,无法进行高级转动")
return
end
if currentIngot < ingotCost then
sendMsg(actor, "元宝不足,无法进行高级转动")
return
end
-- 同时扣除金币和元宝
changemoney(actor, 1, "-", goldCost, "转轮扣除", true)
changemoney(actor, 2, "-", ingotCost, "转轮扣除", true)
release_print(string.format("扣除金币: %d, 扣除元宝: %d", goldCost, ingotCost))
-- 高级转动:负数不扣幸运值
local stopFrame = xingyunzhuanlun.getRandomFrameByProbability()
local value = frameToValue[stopFrame + 1] or 0
local frameDesc = frameToText[stopFrame + 1] or "未知"
-- 高级转动特殊处理:负数转为0
if value < 0 then
value = 0
end
release_print(string.format("【高级转动随机结果】帧%d: 值=%d, 描述=%s", stopFrame, value, frameDesc))
-- 计算新幸运值
local newLuckValue = oldLuckValue + value
release_print(string.format("【高级转动幸运值计算】: %d + %d = %d", oldLuckValue, value, newLuckValue))
-- 更新幸运值到U31变量
newLuckValue = xingyunzhuanlun.setU31Value(actor, newLuckValue)
-- 发送消息给玩家
sendMsg(actor, string.format("高级转动:幸运值%s,当前幸运值:%d", frameDesc, newLuckValue))
-- 更新属性加成
xingyunzhuanlun.updateAttributes(actor, newLuckValue)
-- 后端发送停止帧给前端(放在高级转动分支内部)
local resp = {
stopFrame = stopFrame, -- 停止帧(0-7)
luckChange = value, -- 幸运值变化
isAdvanced = (arg2 == 1) -- 是否是高级转动
}
local respStr = tbl2json(resp)
release_print(string.format("【发送给前端】stopFrame=%d, luckChange=%d, isAdvanced=%s",
stopFrame, value, tostring(arg2 == 1)))
sendMsg(actor, 58004, 0, 0, 0, respStr)
else
-- 如果 arg2 不是 0 也不是 1,可以在这里处理错误
release_print(string.format("【错误】未知的操作类型 arg2=%s", tostring(arg2)))
end
end
```
**修改要点:**
1. 将发送给前端的代码分别移到 `arg2 == 0` 和 `arg2 == 1` 两个分支内部
2. 确保 `stopFrame` 和 `value` 变量在发送时是有效的
3. 添加了 `else` 分支来处理未知的操作类型
4. 将所有的 `p()` 函数替换为 `release_print()`(根据引擎要求)
5. 将 `lib:msg()` 替换为 `sendMsg()`(根据引擎接口)
这样修改后,你的代码就不会出现变量为 `nil` 的错误了。如果还有其他问题,随时可以问我,或者请教我的师傅浮生梦尊师!
← 返回问答库