local npc = {}
function npc.main(actor, param1, param2, param3, str)
sendluamsg(actor, 10713, 105, 1, 0, getplaydef(actor, "T88"))
end
local CharacterFashionMap = {
["[N]沈沧海-A"] = {"时装1_1","时装1_","[N]沈沧海"},
["[N]沈沧海-B"] = {"时装1_2","时装1_"
🤖 回答引擎: 后端Lua |
🕒 时间: 2026-03-01 15:28:23 |
👁️ 阅读: 8
我是lua后端老师!
小仙,你好!看了你的代码,这是一个处理时装激活和穿戴的NPC脚本。整体结构清晰,功能明确,但在一些细节和健壮性上还有提升空间。我来为你分析一下,并提供一些优化建议。
首先,你的代码逻辑是:
1. 通过一个映射表 `CharacterFashionMap` 将NPC名称与对应的时装数据关联起来。
2. 在 `link` 函数中,根据 `param3` 的值执行不同操作:
* `param3 == 1`: 激活时装。检查玩家T88变量中是否包含特定时装的“未激活”状态,然后扣除对应道具,将状态改为“已激活”,并授予相应称号。
* `param3 == 2`: 穿戴时装。检查同一系列(如“时装1”)的5个部件是否全部激活,如果全部激活,则删除身上旧的时装并给予新的完整时装。
**优化建议和代码调整:**
1. **变量名与可读性**:`szbl`, `szqtjc` 这类缩写虽然节省空间,但不利于后期维护。建议使用更具描述性的名字。
2. **字符串查找的健壮性**:`string.find(szbl, CharacterFashionMap[str][1]..":0")` 这个查找可能不够精确。如果字符串格式有变或包含相似子串,可能导致误判。建议进行更严格的匹配或使用字符串分割后遍历。
3. **资源扣除验证**:`takes` 函数执行后,最好能明确知道扣除是否成功,虽然你已经有 `else` 分支处理失败,但这是好的做法。
4. **称号授予逻辑**:在激活部分,你每次都会先剥夺所有5个“点亮”称号,再根据当前激活数授予一个。可以考虑优化为只更新有变化的称号。
5. **穿戴时装逻辑**:`param3 == 2` 分支中的 `str` 参数,看起来应该是一个数字(如“1”代表“时装1”系列),但你在 `CharacterFashionMap` 中查找的键是完整的NPC名字。这里需要确保调用 `npc.link` 时传入的 `str` 参数与 `param3==2` 分支的逻辑匹配。目前代码中 `param3==2` 分支并未使用 `CharacterFashionMap`,而是直接拼接字符串,这要求 `str` 是数字字符串。如果 `str` 是NPC名字,这部分逻辑会出错。
6. **错误处理与日志**:在扣除失败等关键环节,除了打印日志,也可以考虑给玩家发送提示消息。
下面是一个根据你原有逻辑调整后的示例代码,主要增强了可读性和健壮性:
```lua
local npc = {}
function npc.main(actor, param1, param2, param3, str)
sendluamsg(actor, 10713, 105, 1, 0, getplaydef(actor, "T88"))
end
-- 时装配置表
-- 键: NPC名称
-- 值: {时装部件前缀, 时装系列前缀, 称号基础名}
local CharacterFashionMap = {
["[N]沈沧海-A"] = {"时装1_1", "时装1_", "[N]沈沧海"},
-- ... (其他配置项保持不变)
["[SSSR]金·螭-E"] = {"时装12_5", "时装12_", "[SSSR]金·螭"}
}
-- 处理NPC链接点击事件
function npc.link(actor, param1, param2, param3, str)
if param3 == 1 then
-- 激活时装部件
activateFashionPart(actor, str)
elseif param3 == 2 then
-- 穿戴整套时装 (注意:这里的str应为数字字符串,如 "1" 代表时装1系列)
wearFullFashionSet(actor, str)
end
end
-- 激活时装部件函数
local function activateFashionPart(actor, npcName)
local fashionData = CharacterFashionMap[npcName]
if not fashionData then
release_print("错误:未找到NPC名称对应的时装配置:" .. npcName)
return
end
local partPrefix = fashionData[1] -- 例如 "时装1_1"
local seriesPrefix = fashionData[2] -- 例如 "时装1_"
local titleBaseName = fashionData[3] -- 例如 "[N]沈沧海"
local playerFashionStr = getplaydef(actor, "T88")
local inactiveState = partPrefix .. ":0"
local activeState = partPrefix .. ":1"
-- 检查是否包含未激活的部件
if string.find(playerFashionStr, inactiveState, 1, true) then
-- 尝试扣除对应道具
if takes(actor, npcName .. "#" .. 1, 0, 0, "系统扣除") then
-- 替换状态
local newFashionStr, _ = string.gsub(playerFashionStr, inactiveState, activeState)
setplaydef(actor, "T88", newFashionStr)
-- 发送更新消息
sendluamsg(actor, 10713, 105, 2, 0, newFashionStr)
sendmsg(actor, 1, '{"Msg":"<font color=\'#ff0000\'>系统提示:</font><font color=\'#00FF00\'>恭喜您成功激活['.. npcName .. ']!</font>","Type":9}')
-- 计算并更新称号
updateFashionTitle(actor, newFashionStr, seriesPrefix, titleBaseName)
else
release_print("激活失败:扣除道具失败,NPC:" .. npcName .. ",玩家:" .. actor)
-- 可以给玩家发送扣除失败提示
-- sendmsg(actor, 1, '{"Msg":"<font color=\'#ff0000\'>系统提示:</font><font color=\'#FFFF00\'>道具不足,激活失败!</font>","Type":9}')
end
else
release_print("提示:该时装部件已激活或不存在,NPC:" .. npcName .. ",玩家:" .. actor)
end
end
-- 更新时装系列称号函数
local function updateFashionTitle(actor, fashionStr, seriesPrefix, titleBaseName)
local activatedCount = 0
-- 遍历该系列的5个部件
for i = 1, 5 do
local partState = seriesPrefix .. i .. ":1"
if string.find(fashionStr, partState, 1, true) then
activatedCount = activatedCount + 1
end
-- 先移除所有旧的“点亮”称号
deprivetitle(actor, titleBaseName .. "·点亮-" .. i)
end
-- 根据激活数量授予新称号
if activatedCount > 0 then
confertitle(actor, titleBaseName .. "·点亮-" .. activatedCount, 1)
end
end
-- 穿戴整套时装函数
local function wearFullFashionSet(actor, seriesNumber)
-- seriesNumber 应为字符串数字,如 "1"
local seriesPrefix = "时装" .. seriesNumber .. "_"
local fashionStr = getplaydef(actor, "T88")
local activatedCount = 0
for i = 1, 5 do
local partState = seriesPrefix .. i .. ":1"
if string.find(fashionStr, partState, 1, true) then
activatedCount = activatedCount + 1
end
end
-- 如果5个部件全部激活
if activatedCount == 5 then
-- 移除身上旧的时装(假设位置是17)
delbodyitem(actor, 17)
-- 给予新的完整时装
giveonitem(actor, 17, "时装" .. seriesNumber, 1)
sendmsg(actor, 1, '{"Msg":"<font color=\'#ff0000\'>系统提示:</font><font color=\'#00FF00\'>恭喜您成功穿戴时装!</font>","Type":9}')
else
release_print("穿戴失败:系列" .. seriesNumber .. "的部件未全部激活,当前激活数:" .. activatedCount .. ",玩家:" .. actor)
-- 可以给玩家发送提示
-- sendmsg(actor, 1, '{"Msg":"<font color=\'#ff0000\'>系统提示:</font><font color=\'#FFFF00\'>该系列时装尚未集齐,无法穿戴!</font>","Type":9}')
end
end
return npc
```
**主要改动说明:**
* **函数拆分**:将主要逻辑拆分为 `activateFashionPart`、`updateFashionTitle` 和 `wearFullFashionSet` 三个独立函数,使 `npc.link` 函数更简洁,职责更清晰。
* **配置检查**:在 `activateFashionPart` 开始时检查配置是否存在,避免因配置错误导致后续代码出错。
* **明确参数**:在 `wearFullFashionSet` 函数中,明确参数 `seriesNumber` 应该是数字字符串,用于拼接时装系列前缀。**这一点非常重要**,你需要确保在QF中调用 `npc.link` 并传入 `param3=2` 时,`str` 参数是像 `"1"`、`"2"` 这样的数字,而不是NPC名字。
* **增强日志**:在关键步骤和错误处增加了更详细的日志打印,便于调试。
* **添加注释**:为函数和关键代码段添加了注释,提高可读性。
**最后提醒:**
请务必检查你的QF脚本,确认调用 `npc.link` 时传入的参数是否正确。特别是当 `param3=2`(穿戴时装)时,`str` 参数必须与 `wearFullFashionSet` 函数期望的 `seriesNumber` 格式一致。
如果还有不明白的地方,随时可以再问我,或者去请教浮生梦尊师!
← 返回问答库