目录
- 概述
- 定义
- 核心机制
- 1. Aura 系统
- 2. 可用的 Aura 类型
- 注册方式
- 1. 脚本中监听
- 2. 在脚本加载器中注册
- 使用场景
- 1. 增益 Buff
- 2. 减益 Debuff
- 3. 控制效果
- 4. 特殊状态
- 代码示例
- 示例 1: 施加隐身 Buff
- 示例 2: 火焰持续伤害
- 示例 3: 减速效果
- 示例 4: 脚本中动态添加 Aura
- 示例 5: 自定义光环持续时间
- 最佳实践
- 1. 正确选择 Aura 类型
- 2. 检查重复 Aura
- 3. 设置正确的持续时间
- 4. 使用 AuraScript
- 5. 性能优化
- 注意事项
- 1. 脚本注册
- 2. 避免无限循环
- 3. 线程安全
- 4. 性能影响
- 5. 持久化配置
- 总结
概述
SPELL_EFFECT_APPLY_AURA是 TrinityCore 中的一种重要法术效果,主要用于在施法命中目标时给目标附加一个 Aura(光环)。Aura 本质上是一个可配置的效果容器,可以包含多种子效果,如修改属性、造成伤害、阻止移动等。
主要特点:
- 是 TrinityCore 中实现持续性魔法效果的核心机制
- Aura 可以包含多种子效果
- 支持多种 Aura 类型,如属性修改、伤害、控制等,广泛用于增益、减益、周期性伤害、控制等
定义
SPELL_EFFECT_APPLY_AURA在SharedDefines.h中定义为SpellEffectName枚举的第 6 个值
核心机制
1. Aura 系统
SPELL_EFFECT_APPLY_AURA通过 Aura 系统实现持续性效果:
// 在 Spell 定义中指定 Effect= SPELL_EFFECT_APPLY_AURASpellEntry spellInfo;spellInfo.Effect[0]=SPELL_EFFECT_APPLY_AURA;spellInfo.EffectApplyAuraName[0]=SPELL_AURA_MOD_INVISIBILITY;// 指定光环的具体类型2. 可用的 Aura 类型
SPELL_EFFECT_APPLY_AURA必须配合EffectApplyAuraName使用,相关定义在SpellAuraDefines.h中的AuraType枚举,常见的 Aura 类型包括:
| Aura 类型 | 用途 |
|---|---|
SPELL_AURA_MOD_ATTACK_POWER | 修改攻击力 |
SPELL_AURA_MOD_RESISTANCE | 修改抗性 |
SPELL_AURA_PERIODIC_DAMAGE | 周期性伤害 |
SPELL_AURA_MOD_DECREASE_SPEED | 减速 |
SPELL_AURA_MOD_ROOT | 定身 |
SPELL_AURA_MOD_SILENCE | 沉默 |
SPELL_AURA_MOD_INVISIBILITY | 隐身 |
注册方式
1. 脚本中监听
classspell_custom_aura:publicSpellScript{PrepareSpellScript(spell_custom_aura);voidHandleAura(SpellEffIndex effIndex){// 自定义逻辑}voidRegister()override{OnEffectHitTarget+=SpellEffectFn(spell_custom_aura::HandleAura,EFFECT_0,SPELL_EFFECT_APPLY_AURA);}};2. 在脚本加载器中注册
voidAddSC_custom_spell(){RegisterSpellScript(spell_custom_aura);}使用场景
1. 增益 Buff
- 增加攻击力、护甲、抗性
- 提升移动速度
- 恢复生命值/法力值
2. 减益 Debuff
- 降低攻击速度、移动速度
- 造成周期性伤害(DOT)
- 降低属性值
3. 控制效果
- 定身、沉默
- 眩晕、昏迷
- 变形
4. 特殊状态
- 隐身、潜行
- 无敌、免疫
- 特殊机制标记
代码示例
示例 1: 施加隐身 Buff
classspell_invisibility:publicSpellScript{PrepareSpellScript(spell_invisibility);voidHandleAura(SpellEffIndex/*effIndex*/){Unit*target=GetHitUnit();if(!target)return;// 隐身效果已通过数据库配置// 这里可以添加额外的自定义逻辑target->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE);}voidRegister()override{OnEffectHitTarget+=SpellEffectFn(spell_invisibility::HandleAura,EFFECT_0,SPELL_EFFECT_APPLY_AURA);}};示例 2: 火焰持续伤害
classspell_fire_dot:publicSpellScript{PrepareSpellScript(spell_fire_dot);voidHandleAura(SpellEffIndex/*effIndex*/){Unit*target=GetHitUnit();if(!target)return;// 可以根据目标类型调整伤害if(target->IsPlayer())// 玩家受到的伤害;else// NPC 受到的伤害;}voidRegister()override{OnEffectHitTarget+=SpellEffectFn(spell_fire_dot::HandleAura,EFFECT_0,SPELL_EFFECT_APPLY_AURA);}};示例 3: 减速效果
classspell_slow:publicSpellScript{PrepareSpellScript(spell_slow);voidHandleAura(SpellEffIndex/*effIndex*/){Unit*caster=GetCaster();Unit*target=GetHitUnit();if(!caster||!target)return;// 可以根据施法者等级调整减速幅度int32 reduction=50;// 默认 50% 减速// 自定义逻辑}voidRegister()override{OnEffectHitTarget+=SpellEffectFn(spell_slow::HandleAura,EFFECT_0,SPELL_EFFECT_APPLY_AURA);}};示例 4: 脚本中动态添加 Aura
classspell_dynamic_aura:publicSpellScript{PrepareSpellScript(spell_dynamic_aura);voidHandleAura(SpellEffIndex/*effIndex*/){Unit*target=GetHitUnit();if(!target)return;// 动态施加额外的 Auraif(target->GetHealthPct()<20.0f)target->CastSpell(target,SPELL_EMERGENCY_HEAL,true);}voidRegister()override{OnEffectHitTarget+=SpellEffectFn(spell_dynamic_aura::HandleAura,EFFECT_0,SPELL_EFFECT_APPLY_AURA);}};示例 5: 自定义光环持续时间
classspell_custom_duration_aura:publicAuraScript{PrepareAuraScript(spell_custom_duration_aura);voidOnApply(AuraEffectconst*aurEff,AuraEffectHandleModes/*mode*/){Unit*target=GetTarget();if(!target)return;// 自定义持续时间if(target->GetTypeId()==TYPEID_PLAYER){Aura*aura=aurEff->GetBase();aura->SetDuration(10000);// 玩家 10 秒}else{Aura*aura=aurEff->GetBase();aura->SetDuration(20000);// NPC 20 秒}}voidRegister()override{OnEffectApply+=AuraEffectApplyFn(spell_custom_duration_aura::OnApply,EFFECT_0,SPELL_AURA_ANY,AURA_EFFECT_HANDLE_REAL);}};最佳实践
1. 正确选择 Aura 类型
确保EffectApplyAuraName匹配所需的 Aura 类型:
// 增加攻击力spellInfo.EffectApplyAuraName[0]=SPELL_AURA_MOD_ATTACK_POWER;// 周期性伤害spellInfo.EffectApplyAuraName[0]=SPELL_AURA_PERIODIC_DAMAGE;// 减速spellInfo.EffectApplyAuraName[0]=SPELL_AURA_MOD_DECREASE_SPEED;2. 检查重复 Aura
避免重复施加相同的 Aura:
voidHandleAura(SpellEffIndex/*effIndex*/){Unit*target=GetHitUnit();if(!target)return;// 检查是否已有该 Auraif(target->HasAura(SPELL_CUSTOM_AURA))return;// 执行逻辑}3. 设置正确的持续时间
注意部分 Aura 默认无限时长,需要手动设置:
classspell_timed_aura:publicAuraScript{PrepareAuraScript(spell_timed_aura);voidOnApply(AuraEffectconst*aurEff,AuraEffectHandleModes/*mode*/){Aura*aura=aurEff->GetBase();if(!aura->GetDuration())aura->SetDuration(60000);// 60 秒}voidRegister()override{OnEffectApply+=AuraEffectApplyFn(spell_timed_aura::OnApply,EFFECT_0,SPELL_AURA_ANY,AURA_EFFECT_HANDLE_REAL);}};4. 使用 AuraScript
对于需要深度控制 Aura 行为的情况,使用AuraScript:
classspell_advanced_aura:publicAuraScript{PrepareAuraScript(spell_advanced_aura);voidOnPeriodic(AuraEffectconst*aurEff){Unit*caster=GetCaster();Unit*target=GetTarget();// 周期性触发逻辑}voidOnApply(AuraEffectconst*aurEff,AuraEffectHandleModes/*mode*/){// Aura 施加时的逻辑}voidOnRemove(AuraEffectconst*aurEff,AuraEffectHandleModes/*mode*/){// Aura 移除时的逻辑}voidRegister()override{OnEffectPeriodic+=AuraEffectPeriodicFn(spell_advanced_aura::OnPeriodic,EFFECT_0,SPELL_AURA_PERIODIC_DAMAGE);OnEffectApply+=AuraEffectApplyFn(spell_advanced_aura::OnApply,EFFECT_0,SPELL_AURA_ANY,AURA_EFFECT_HANDLE_REAL);OnEffectRemove+=AuraEffectRemoveFn(spell_advanced_aura::OnRemove,EFFECT_0,SPELL_AURA_ANY,AURA_EFFECT_HANDLE_REAL);}};5. 性能优化
对高频触发的技能,减少不必要的 Aura 创建与销毁:
// 避免在循环中频繁创建 Aurafor(Unit*target:targets){// 检查是否已有 Auraif(!target->HasAura(SPELL_BUFF))target->CastSpell(target,SPELL_BUFF,true);}注意事项
1. 脚本注册
不要忘记在脚本加载器中注册:
voidAddSC_custom_aura_script(){RegisterSpellScript(spell_custom_aura);RegisterAuraScript(spell_advanced_aura);}2. 避免无限循环
在 Aura 的周期性效果中避免无限循环调用:
voidOnPeriodic(AuraEffectconst*aurEff){Unit*caster=GetCaster();Unit*target=GetTarget();// 错误示例:可能导致无限循环// target->CastSpell(target, SAME_SPELL, true);// 正确做法:使用不同的技能 ID// target->CastSpell(target, DIFFERENT_SPELL, true);}3. 线程安全
注意 TrinityCore 是多线程的,确保代码是线程安全的:
- 避免静态变量
- 使用线程安全的数据结构
- 注意对象生命周期
4. 性能影响
频繁施加/移除 Aura 会增加服务器计算量:
- 保持处理逻辑简洁
- 避免在 Aura 处理函数中执行复杂计算
- 使用缓存减少重复计算
5. 持久化配置
对于不需要保存到数据库的 Aura,禁用持久化:
classspell_non_persistent_aura:publicAuraScript{PrepareAuraScript(spell_non_persistent_aura);voidOnApply(AuraEffectconst*aurEff,AuraEffectHandleModes/*mode*/){Aura*aura=aurEff->GetBase();aura->SetCanBeSaved(false);// 不保存到数据库}voidRegister()override{OnEffectApply+=AuraEffectApplyFn(spell_non_persistent_aura::OnApply,EFFECT_0,SPELL_AURA_ANY,AURA_EFFECT_HANDLE_REAL);}};总结
SPELL_EFFECT_APPLY_AURA是 TrinityCore 中实现持续性魔法效果的核心机制。通过它可以实现从简单的增益 Buff 到复杂的周期性伤害效果等各种功能。关键在于正确理解 Aura 类型的工作原理,并根据具体需求选择合适的配置和脚本实现方式。
关键要点:
SPELL_EFFECT_APPLY_AURA用于施加持续性效果- 必须配合
EffectApplyAuraName指定具体的 Aura 类型 - 支持通过
SpellScript和AuraScript进行深度定制 - 广泛应用于增益、减益、控制等场景
- 注意性能和线程安全问题