你好,我是Lua后端老师!
修仙者,你这个思路非常好,非常专业!这正是“注册-分发”模式的核心思想,用一个表来管理所有BUFF效果,通过BUFF ID作为键来快速索引对应的处理函数,可以极大地节省触发时的判断耗时。
你提供的代码结构是完美的起点。我来帮你完善它,并补充上你提到的所有触发场景(攻击前、技能后、受击前、受击后)以及如何与特定技能(刺杀、烈火等)关联。
首先,我们创建一个独立的Lua文件来管理所有BUFF效果,比如命名为 `BuffEffects.lua`。
```lua
-- BuffEffects.lua
-- 全局BUFF效果表,key为BUFF ID,value是一个函数表
local GLOBAL_BUFF_EFFECTS = {}
-- 示例:BUFF ID 105,效果:受击时,30%的伤害由MP抵消
GLOBAL_BUFF_EFFECTS[105] = {
-- 触发类型:受击后
onStruck = function(attacker, victim, skillid, damage, Model, value)
local num = damage * 0.3
if getbaseinfo(victim, 11) > num then -- 检查MP是否足够
humanmp(victim, "-", num) -- 扣除MP
end
end
}
-- 示例:BUFF ID 106,效果:攻击前,增加10%伤害
GLOBAL_BUFF_EFFECTS[106] = {
-- 触发类型:攻击前
beforeAttack = function(attacker, target, skillid)
-- 这里可以设置一个临时变量,在attackdamage触发中读取并计算最终伤害
-- 例如:setplayvar(attacker, "TEMP_ATK_BOOST", 10)
end
}
-- 示例:BUFF ID 107,效果:使用特定技能(烈火剑法)后触发
GLOBAL_BUFF_EFFECTS[107] = {
-- 触发类型:技能后,并指定技能ID(烈火剑法的技能ID假设为1001)
afterSkill = {
[1001] = function(attacker)
-- 释放烈火剑法后,给自己加一个攻击力提升的BUFF
addbuff(attacker, 108, 5, 1, attacker, {[1]=50}) -- 假设108是加攻击力的BUFF
end
}
}
-- 示例:BUFF ID 108,效果:受击前,有概率格挡部分伤害
GLOBAL_BUFF_EFFECTS[108] = {
-- 触发类型:受击前
beforeStruck = function(attacker, victim, skillid, damage)
if math.random(100) <= 20 then -- 20%概率触发格挡
return damage * 0.5 -- 返回新的伤害值,表示格挡一半伤害
end
return damage -- 不触发格挡,返回原伤害
end
}
-- 将表返回,供其他脚本require使用
return GLOBAL_BUFF_EFFECTS
```
接下来,我们需要在QF触发脚本里,编写统一的处理函数来调用这些效果。以 `attackdamage` (攻击前)、`magicattack` (技能攻击)、`struckdamage` (受击) 等触发为例:
```lua
-- 首先,在QF脚本开头加载BUFF效果表
local BuffEffects = require("BuffEffects")
-- 攻击前触发(对应普攻和部分技能)
function attackdamage(attacker, target, skillid, damage, Model, value)
local allBuffs = getallbuffid(attacker) -- 获取攻击者所有BUFF ID
if allBuffs then
for _, buffId in ipairs(allBuffs) do
local effect = BuffEffects[buffId]
if effect and effect.beforeAttack then
effect.beforeAttack(attacker, target, skillid)
-- 注意:beforeAttack可能用于设置变量,实际伤害计算可能在别处
end
end
end
-- 其他逻辑...
end
-- 技能攻击触发(烈火、开天斩等技能命中时)
function magicattack(attacker, target, skillid, damage, Model, value)
-- 1. 先处理攻击者的“攻击前”效果(如果有)
local allBuffs = getallbuffid(attacker)
if allBuffs then
for _, buffId in ipairs(allBuffs) do
local effect = BuffEffects[buffId]
if effect and effect.beforeAttack then
effect.beforeAttack(attacker, target, skillid)
end
end
end
-- 2. 处理受击者的“受击前”效果
local targetBuffs = getallbuffid(target)
local finalDamage = damage
if targetBuffs then
for _, buffId in ipairs(targetBuffs) do
local effect = BuffEffects[buffId]
if effect and effect.beforeStruck then
-- beforeStruck函数可以返回修改后的伤害
finalDamage = effect.beforeStruck(attacker, target, skillid, finalDamage)
end
end
end
-- 3. 实际伤害计算和扣血发生在这里(使用finalDamage)
-- ... (引擎内部处理)
-- 4. 处理受击者的“受击后”效果
if targetBuffs then
for _, buffId in ipairs(targetBuffs) do
local effect = BuffEffects[buffId]
if effect and effect.onStruck then
effect.onStruck(attacker, target, skillid, finalDamage, Model, value)
end
end
end
-- 5. 处理攻击者的“技能后”效果
if allBuffs then
for _, buffId in ipairs(allBuffs) do
local effect = BuffEffects[buffId]
if effect and effect.afterSkill then
local skillFunc = effect.afterSkill[skillid]
if skillFunc then
skillFunc(attacker)
end
end
end
end
end
-- 受击伤害触发(通用受击,可用于普攻和技能)
function struckdamage(attacker, target, skillid, damage, Model, value)
-- 逻辑与magicattack中的2、3、4步类似,处理受击前和受击后效果
local targetBuffs = getallbuffid(target)
local finalDamage = damage
-- 受击前
if targetBuffs then
for _, buffId in ipairs(targetBuffs) do
local effect = BuffEffects[buffId]
if effect and effect.beforeStruck then
finalDamage = effect.beforeStruck(attacker, target, skillid, finalDamage)
end
end
end
-- ... (引擎扣血)
-- 受击后
if targetBuffs then
for _, buffId in ipairs(targetBuffs) do
local effect = BuffEffects[buffId]
if effect and effect.onStruck then
effect.onStruck(attacker, target, skillid, finalDamage, Model, value)
end
end
end
end
```
**总结与优化建议:**
1. **你的结构完全正确**:`buff[105] = function(...)` 是标准做法。
2. **扩展性**:我为每个BUFF ID关联了一个表,里面可以包含 `beforeAttack`, `afterSkill`, `beforeStruck`, `onStruck` 等多个函数键,分别对应不同触发点,这样更清晰。
3. **技能过滤**:在 `afterSkill` 里,我用了子表 `[skillid] = function` 的形式,可以精确到某个技能(如刺杀、烈火)释放后才触发效果。
4. **性能关键**:`getallbuffid(actor)` 获取当前所有BUFF ID列表,然后遍历。遍历次数等于BUFF数量,但每次触发只调用与该触发类型相关的函数,避免了海量的 `if buffid == xxx` 判断。
5. **分工明确**:`BuffEffects.lua` 只定义效果,QF触发脚本只负责调度。新增BUFF时,只需在 `BuffEffects.lua` 中添加新条目,**完全不用修改** QF脚本。
这样写,无论BUFF数量多少,每个触发点的计算复杂度都只与角色身上的BUFF数量线性相关,且代码结构清晰,易于维护。修仙者,你已经有很好的架构思维了,按照这个模式去实现,绝对高效!如果具体到某个BUFF效果实现时有疑问,随时可以再来问我。