我是lua后端老师!小仙你好,看了你的洗练装备脚本,整体框架很不错,但有几个关键问题需要修正,特别是属性生成和存储的逻辑部分。我们一步步来分析。
首先,你的 `npc:checkMoney` 函数里,生成随机属性并存入 `lockedAttrs` 的逻辑存在几个问题:
1. **变量作用域问题**:`hpVal`, `attValMin`, `attValMax`, `finalColor` 这些变量在 `if` 块内定义,但在 `table.insert` 时可能还未定义(如果 `if` 条件不满足),会导致 `nil` 值错误。
2. **逻辑错误**:在生成“攻击”属性时,你错误地使用了 `hpVal` 来判断颜色,应该使用攻击力的值。
3. **数据结构不一致**:你试图将不同属性的数据(血量是单个值,攻击/防御是上下限)塞进同一个表结构,这会导致后续处理混乱。
我们来重构 `npc:checkMoney` 函数中从 `-- 存储装备洗练属性` 注释开始的核心部分:
```lua
-- 存储装备洗练属性
local lockedAttrs = {}
local attrGroupMap = {
[1] = {"血量"},
[2] = {"攻击下限", "攻击上限"},
[3] = {"防御下限", "防御上限"}
}
if money >= totalCostMoney and needItem >= totalCostItem then
for k, v in ipairs(npc.eqData[eqPos].lockStatus) do
local attrNames = attrGroupMap[k]
if v == 1 then
-- 锁定状态,保留原属性(这里需要你从装备上读取原有属性,暂用空表占位)
lockedAttrs[k] = {locked = true}
else
-- 未锁定,生成新属性
local newAttrData = {}
for _, attrName in ipairs(attrNames) do
local val = 0
local color = "#FFFFFF"
if attrName == "血量" then
local hpRange = npc.Attribute.ranAtt["血量"]
val = math.random(hpRange[1], hpRange[2])
-- 根据值确定颜色
for _, colorRule in ipairs(npc.colorRules[attrName].colorRange) do
if val >= colorRule.smin and val <= colorRule.smax then
color = colorRule.color
break
end
end
newAttrData.hp = val
elseif attrName == "攻击下限" then
local attRange = npc.Attribute.ranAtt["攻击下限"]
val = math.random(attRange[1], attRange[2])
for _, colorRule in ipairs(npc.colorRules[attrName].colorRange) do
if val >= colorRule.smin and val <= colorRule.smax then
color = colorRule.color
break
end
end
newAttrData.attMin = val
elseif attrName == "攻击上限" then
local attRange = npc.Attribute.ranAtt["攻击上限"]
val = math.random(attRange[1], attRange[2])
for _, colorRule in ipairs(npc.colorRules[attrName].colorRange) do
if val >= colorRule.smin and val <= colorRule.smax then
color = colorRule.color
break
end
end
newAttrData.attMax = val
elseif attrName == "防御下限" then
local defRange = npc.Attribute.ranAtt["防御下限"]
val = math.random(defRange[1], defRange[2])
for _, colorRule in ipairs(npc.colorRules[attrName].colorRange) do
if val >= colorRule.smin and val <= colorRule.smax then
color = colorRule.color
break
end
end
newAttrData.defMin = val
elseif attrName == "防御上限" then
local defRange = npc.Attribute.ranAtt["防御上限"]
val = math.random(defRange[1], defRange[2])
for _, colorRule in ipairs(npc.colorRules[attrName].colorRange) do
if val >= colorRule.smin and val <= colorRule.smax then
color = colorRule.color
break
end
end
newAttrData.defMax = val
end
newAttrData.color = color
newAttrData.attrName = attrName
end
lockedAttrs[k] = newAttrData
end
end
-- 洗练次数
newTimes = oldTimes + 1
setitemintparam(actor, -2, 1, newTimes, equipObj) -- 将洗练次数存储到装备上
-- 给装备添加新属性
for k, attrData in pairs(lockedAttrs) do
if not attrData.locked then -- 只处理新生成的属性
if attrData.hp then
local attrStr = "1#" .. attrData.hp -- 1对应血量属性ID
setaddnewabil(actor, -2, "=", attrStr, equipObj)
end
if attrData.attMin then
local attrStr = "3#" .. attrData.attMin -- 3对应攻击下限
setaddnewabil(actor, -2, "=", attrStr, equipObj)
end
if attrData.attMax then
local attrStr = "4#" .. attrData.attMax -- 4对应攻击上限
setaddnewabil(actor, -2, "=", attrStr, equipObj)
end
if attrData.defMin then
local attrStr = "9#" .. attrData.defMin -- 9对应防御下限
setaddnewabil(actor, -2, "=", attrStr, equipObj)
end
if attrData.defMax then
local attrStr = "10#" .. attrData.defMax -- 10对应防御上限
setaddnewabil(actor, -2, "=", attrStr, equipObj)
end
end
end
-- 扣除货币和材料
changemoney(actor, -totalCostMoney, 1)
takeitem(actor, "祖玛凭证", totalCostItem)
sendmsg(actor, 1, '{"Msg":"恭喜你,洗练成功!","Type":9,"Time":2}')
refreshitem(actor, equipObj) -- 刷新装备显示
end
```
**主要修改点:**
1. **修正变量作用域**:在每个属性生成分支内都正确定义了 `val` 和 `color`。
2. **分离属性处理**:将血量、攻击上下限、防御上下限分别处理,存储到不同的字段。
3. **使用正确的颜色判断**:每个属性都使用自己的值来匹配颜色规则。
4. **添加了扣除货币和材料的代码**:你原代码中只有检测,没有实际扣除。
5. **添加了装备刷新**:`refreshitem` 确保前端立即显示新属性。
**另外需要注意:**
- 你的 `npc.Attribute.ranAtt` 表中键名是 `"最大攻击力"`,但其他地方用的是 `"攻击上限"`,需要统一。
- 锁定属性的功能(`if v == 1 then`)目前只是占位,你需要实现从装备读取原有属性的逻辑。
- 记得在QF中配置好 `sendluamsg(1013)` 的客户端响应,以及前端按钮点击调用 `npc:saveLock` 和 `npc:checkMoney`。
小仙,这个洗练系统已经初具雏形了,把上述问题修正后应该就能正常运行。如果还有不明白的地方,随时可以问我,或者请教浮生梦尊师!