mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Spell: SpellAura Redux (#22794)
* typo and correction
* spell aura no longer shared between targets
_spellAura isolated
* SPELL_AURA_CONTROL_VEHICLE is not strictly single target spell
Steam Tank Control and Wyrmrest Commander
units can reseat themselves again
* Rename 9999_99_99_99_world.sql to 2019_03_08_00_world.sql
(cherry picked from commit ec3cb05d7f)
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_gen_vehicle_control_link' AND `spell_id` IN (49078, 50343);
|
||||
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
|
||||
(49078, 'spell_gen_vehicle_control_link'),
|
||||
(50343, 'spell_gen_vehicle_control_link');
|
||||
@@ -3150,14 +3150,13 @@ void Unit::_AddAura(UnitAura* aura, Unit* caster)
|
||||
if (aura->IsRemoved())
|
||||
return;
|
||||
|
||||
aura->SetIsSingleTarget(caster && (aura->GetSpellInfo()->IsSingleTarget() || aura->HasEffectType(SPELL_AURA_CONTROL_VEHICLE)));
|
||||
aura->SetIsSingleTarget(caster && aura->GetSpellInfo()->IsSingleTarget());
|
||||
if (aura->IsSingleTarget())
|
||||
{
|
||||
ASSERT((IsInWorld() && !IsDuringRemoveFromWorld()) || (aura->GetCasterGUID() == GetGUID()) ||
|
||||
(IsLoading() && aura->HasEffectType(SPELL_AURA_CONTROL_VEHICLE)));
|
||||
ASSERT((IsInWorld() && !IsDuringRemoveFromWorld()) || aura->GetCasterGUID() == GetGUID());
|
||||
/* @HACK: Player is not in world during loading auras.
|
||||
* Single target auras are not saved or loaded from database
|
||||
* but may be created as a result of aura links (player mounts with passengers)
|
||||
* but may be created as a result of aura links.
|
||||
*/
|
||||
|
||||
// register single target aura
|
||||
@@ -11853,6 +11852,11 @@ void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* a
|
||||
}
|
||||
else if (seatId >= 0 && seatId == GetTransSeat())
|
||||
return;
|
||||
else
|
||||
{
|
||||
//Exit the current vehicle because unit will reenter in a new seat.
|
||||
m_vehicle->GetBase()->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE, GetGUID(), aurApp->GetBase());
|
||||
}
|
||||
}
|
||||
|
||||
if (aurApp->GetRemoveMode())
|
||||
|
||||
@@ -1169,9 +1169,6 @@ bool Aura::IsSingleTargetWith(Aura const* aura) const
|
||||
break;
|
||||
}
|
||||
|
||||
if (HasEffectType(SPELL_AURA_CONTROL_VEHICLE) && aura->HasEffectType(SPELL_AURA_CONTROL_VEHICLE))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -2671,7 +2671,9 @@ void Spell::TargetInfo::DoDamageAndTriggers(Spell* spell)
|
||||
spell->m_caster->ToPlayer()->UpdatePvP(true);
|
||||
}
|
||||
|
||||
spell->_spellAura = HitAura;
|
||||
spell->CallScriptAfterHitHandlers();
|
||||
spell->_spellAura = nullptr;
|
||||
}
|
||||
|
||||
void Spell::GOTargetInfo::DoTargetSpellHit(Spell* spell, SpellEffectInfo const& spellEffectInfo)
|
||||
@@ -2841,8 +2843,7 @@ void Spell::DoSpellEffectHit(Unit* unit, SpellEffectInfo const& spellEffectInfo,
|
||||
{
|
||||
bool refresh = false;
|
||||
|
||||
// delayed spells with multiple targets need to create a new aura object, otherwise we'll access a deleted aura
|
||||
if (!_spellAura || (m_spellInfo->HasHitDelay() && !m_spellInfo->IsChanneled()))
|
||||
if (!hitInfo.HitAura)
|
||||
{
|
||||
bool const resetPeriodicTimer = !(_triggeredCastFlags & TRIGGERED_DONT_RESET_PERIODIC_TIMER);
|
||||
uint32 const allAuraEffectMask = Aura::BuildEffectMaskForOwner(m_spellInfo, MAX_EFFECT_MASK, unit);
|
||||
@@ -2858,22 +2859,22 @@ void Spell::DoSpellEffectHit(Unit* unit, SpellEffectInfo const& spellEffectInfo,
|
||||
|
||||
if (Aura* aura = Aura::TryRefreshStackOrCreate(createInfo))
|
||||
{
|
||||
_spellAura = aura->ToUnitAura();
|
||||
hitInfo.HitAura = aura->ToUnitAura();
|
||||
|
||||
// Set aura stack amount to desired value
|
||||
if (m_spellValue->AuraStackAmount > 1)
|
||||
{
|
||||
if (!refresh)
|
||||
_spellAura->SetStackAmount(m_spellValue->AuraStackAmount);
|
||||
hitInfo.HitAura->SetStackAmount(m_spellValue->AuraStackAmount);
|
||||
else
|
||||
_spellAura->ModStackAmount(m_spellValue->AuraStackAmount);
|
||||
hitInfo.HitAura->ModStackAmount(m_spellValue->AuraStackAmount);
|
||||
}
|
||||
|
||||
_spellAura->SetDiminishGroup(hitInfo.DRGroup);
|
||||
hitInfo.HitAura->SetDiminishGroup(hitInfo.DRGroup);
|
||||
|
||||
if (!m_spellValue->Duration)
|
||||
{
|
||||
hitInfo.AuraDuration = caster->ModSpellDuration(m_spellInfo, unit, hitInfo.AuraDuration, hitInfo.Positive, _spellAura->GetEffectMask());
|
||||
hitInfo.AuraDuration = caster->ModSpellDuration(m_spellInfo, unit, hitInfo.AuraDuration, hitInfo.Positive, hitInfo.HitAura->GetEffectMask());
|
||||
|
||||
if (hitInfo.AuraDuration > 0)
|
||||
{
|
||||
@@ -2886,7 +2887,7 @@ void Spell::DoSpellEffectHit(Unit* unit, SpellEffectInfo const& spellEffectInfo,
|
||||
{
|
||||
int32 origDuration = hitInfo.AuraDuration;
|
||||
hitInfo.AuraDuration = 0;
|
||||
for (AuraEffect const* auraEff : _spellAura->GetAuraEffects())
|
||||
for (AuraEffect const* auraEff : hitInfo.HitAura->GetAuraEffects())
|
||||
if (auraEff)
|
||||
if (int32 period = auraEff->GetPeriod()) // period is hastened by UNIT_MOD_CAST_SPEED
|
||||
hitInfo.AuraDuration = std::max(std::max(origDuration / period, 1) * period, hitInfo.AuraDuration);
|
||||
@@ -2900,21 +2901,21 @@ void Spell::DoSpellEffectHit(Unit* unit, SpellEffectInfo const& spellEffectInfo,
|
||||
else
|
||||
hitInfo.AuraDuration = m_spellValue->Duration.get();
|
||||
|
||||
if (hitInfo.AuraDuration != _spellAura->GetMaxDuration())
|
||||
if (hitInfo.AuraDuration != hitInfo.HitAura->GetMaxDuration())
|
||||
{
|
||||
_spellAura->SetMaxDuration(hitInfo.AuraDuration);
|
||||
_spellAura->SetDuration(hitInfo.AuraDuration);
|
||||
hitInfo.HitAura->SetMaxDuration(hitInfo.AuraDuration);
|
||||
hitInfo.HitAura->SetDuration(hitInfo.AuraDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
_spellAura->AddStaticApplication(unit, aura_effmask);
|
||||
|
||||
hitInfo.HitAura = _spellAura;
|
||||
hitInfo.HitAura->AddStaticApplication(unit, aura_effmask);
|
||||
}
|
||||
}
|
||||
|
||||
_spellAura = hitInfo.HitAura;
|
||||
HandleEffects(unit, nullptr, nullptr, spellEffectInfo, SPELL_EFFECT_HANDLE_HIT_TARGET);
|
||||
_spellAura = nullptr;
|
||||
}
|
||||
|
||||
void Spell::DoTriggersOnSpellHit(Unit* unit, uint32 effMask)
|
||||
|
||||
@@ -801,7 +801,7 @@ class TC_GAME_API AuraScript : public _SpellScript
|
||||
#define AuraEffectApplyFn(F, I, N, M) EffectApplyHandlerFunction(&F, I, N, M)
|
||||
|
||||
// executed after aura effect is removed with specified mode from target
|
||||
// should be used when when effect handler preventing/replacing is needed, do not use this hook for triggering spellcasts/removing auras etc - may be unsafe
|
||||
// should be used when effect handler preventing/replacing is needed, do not use this hook for triggering spellcasts/removing auras etc - may be unsafe
|
||||
// example: OnEffectRemove += AuraEffectRemoveFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
|
||||
// where function is: void function (AuraEffect const* aurEff, AuraEffectHandleModes mode);
|
||||
HookList<EffectApplyHandler> OnEffectRemove;
|
||||
|
||||
@@ -4060,6 +4060,26 @@ class spell_corrupting_plague_aura : public AuraScript
|
||||
}
|
||||
};
|
||||
|
||||
enum SiegeTankControl
|
||||
{
|
||||
SPELL_SIEGE_TANK_CONTROL = 47963
|
||||
};
|
||||
|
||||
class spell_gen_vehicle_control_link : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_gen_vehicle_control_link);
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
GetTarget()->RemoveAurasDueToSpell(SPELL_SIEGE_TANK_CONTROL); //aurEff->GetAmount()
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_gen_vehicle_control_link::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
// 34779 - Freezing Circle
|
||||
enum FreezingCircleMisc
|
||||
{
|
||||
@@ -4471,6 +4491,7 @@ void AddSC_generic_spell_scripts()
|
||||
RegisterSpellScript(spell_gen_clear_debuffs);
|
||||
RegisterAuraScript(spell_gen_pony_mount_check);
|
||||
RegisterAuraScript(spell_corrupting_plague_aura);
|
||||
RegisterAuraScript(spell_gen_vehicle_control_link);
|
||||
RegisterSpellScript(spell_freezing_circle);
|
||||
RegisterSpellScript(spell_gen_decimatus_transformation_sickness);
|
||||
RegisterSpellScript(spell_gen_anetheron_summon_towering_infernal);
|
||||
|
||||
@@ -318,7 +318,7 @@ class spell_warl_haunt : public SpellScriptLoader
|
||||
{
|
||||
if (Aura* aura = GetHitAura())
|
||||
if (AuraEffect* aurEff = aura->GetEffect(EFFECT_1))
|
||||
aurEff->SetAmount(CalculatePct(aurEff->GetAmount(), GetHitDamage()));
|
||||
aurEff->SetAmount(CalculatePct(GetHitDamage(), aurEff->GetAmount()));
|
||||
}
|
||||
|
||||
void Register() override
|
||||
|
||||
Reference in New Issue
Block a user