aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPolarCookie <sei009@post.uit.no>2019-03-08 08:34:16 +0100
committerGiacomo Pozzoni <giacomopoz@gmail.com>2019-03-08 08:34:16 +0100
commitec3cb05d7fbc5cef60d000af910dc39dd3af92bf (patch)
treef0b35878eb73b046aca3964ae5d0d790cec03171
parent3eecadcebf11f7418b6cdcf5d3602cea5e4e60f7 (diff)
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
-rw-r--r--sql/updates/world/3.3.5/2019_03_08_00_world.sql4
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp12
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp3
-rw-r--r--src/server/game/Spells/Spell.cpp27
-rw-r--r--src/server/game/Spells/SpellScript.h2
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp21
-rw-r--r--src/server/scripts/Spells/spell_warlock.cpp2
7 files changed, 49 insertions, 22 deletions
diff --git a/sql/updates/world/3.3.5/2019_03_08_00_world.sql b/sql/updates/world/3.3.5/2019_03_08_00_world.sql
new file mode 100644
index 00000000000..1cf16d8a632
--- /dev/null
+++ b/sql/updates/world/3.3.5/2019_03_08_00_world.sql
@@ -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');
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 2eb335850b2..177f48ffc3b 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -3265,14 +3265,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
@@ -12499,6 +12498,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())
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index db19f7aa395..caa6ab536c9 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -1191,9 +1191,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;
}
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index a9418ed28f2..05ab4296d9e 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2577,7 +2577,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, uint8 effIndex)
@@ -2762,8 +2764,7 @@ void Spell::DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& hitInfo)
{
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->Speed > 0.0f && !m_spellInfo->IsChanneled()))
+ if (!hitInfo.HitAura)
{
bool const resetPeriodicTimer = !(_triggeredCastFlags & TRIGGERED_DONT_RESET_PERIODIC_TIMER);
uint8 const allAuraEffectMask = Aura::BuildEffectMaskForOwner(hitInfo.AuraSpellInfo, MAX_EFFECT_MASK, unit);
@@ -2782,20 +2783,20 @@ void Spell::DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& hitInfo)
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);
- hitInfo.AuraDuration = caster->ModSpellDuration(hitInfo.AuraSpellInfo, unit, hitInfo.AuraDuration, hitInfo.Positive, _spellAura->GetEffectMask());
+ hitInfo.AuraDuration = caster->ModSpellDuration(hitInfo.AuraSpellInfo, unit, hitInfo.AuraDuration, hitInfo.Positive, hitInfo.HitAura->GetEffectMask());
// Haste modifies duration of channeled spells
if (m_spellInfo->IsChanneled())
@@ -2804,21 +2805,21 @@ void Spell::DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& hitInfo)
else if (m_originalCaster && (m_originalCaster->HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, hitInfo.AuraSpellInfo) || m_spellInfo->HasAttribute(SPELL_ATTR5_HASTE_AFFECT_DURATION)))
hitInfo.AuraDuration = int32(hitInfo.AuraDuration * m_originalCaster->GetFloatValue(UNIT_MOD_CAST_SPEED));
- 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, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ _spellAura = nullptr;
}
void Spell::DoTriggersOnSpellHit(Unit* unit, uint8 effMask)
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index e1fce218bac..d2cf973c9a0 100644
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -736,7 +736,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;
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index e8c1b3438ff..48ab431147a 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -4126,6 +4126,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 FreezingCircleSpells
{
@@ -4289,5 +4309,6 @@ 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);
}
diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp
index 80c96a18bdc..4195b828046 100644
--- a/src/server/scripts/Spells/spell_warlock.cpp
+++ b/src/server/scripts/Spells/spell_warlock.cpp
@@ -773,7 +773,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