Implement(Hooks): Hooks for ScaleAura in Spell.cpp

Co-authored-by: Kargatum <dowlandtop@yandex.com>
This commit is contained in:
yehonal
2019-08-29 18:59:00 +02:00
parent 1e2d984587
commit fdae37880d
8 changed files with 69 additions and 41 deletions

View File

@@ -2744,6 +2744,16 @@ bool ScriptMgr::CanSelectSpecTalent(Spell* spell)
return ret;
}
void ScriptMgr::OnScaleAuraUnitAdd(Spell* spell, Unit* target, uint32 effectMask, bool checkIfValid, bool implicit, uint8 auraScaleMask, TargetInfo& targetInfo)
{
FOREACH_SCRIPT(SpellSC)->OnScaleAuraUnitAdd(spell, target, effectMask, checkIfValid, implicit, auraScaleMask, targetInfo);
}
void ScriptMgr::OnRemoveAuraScaleTargets(Spell* spell, TargetInfo& targetInfo, uint8 auraScaleMask, bool& needErase)
{
FOREACH_SCRIPT(SpellSC)->OnRemoveAuraScaleTargets(spell, targetInfo, auraScaleMask, needErase);
}
// GameEventScript
void ScriptMgr::OnGameEventStart(uint16 EventID)
{
@@ -2904,7 +2914,7 @@ void ScriptMgr::OnInstanceSave(InstanceSave* instanceSave)
FOREACH_SCRIPT(MiscScript)->OnInstanceSave(instanceSave);
}
void ScriptMgr::OnPlayerSetPhase(AuraEffect* auraEff, AuraApplication const* aurApp, uint8 mode, bool apply, uint32& newPhase)
void ScriptMgr::OnPlayerSetPhase(const AuraEffect* auraEff, AuraApplication const* aurApp, uint8 mode, bool apply, uint32& newPhase)
{
FOREACH_SCRIPT(MiscScript)->OnPlayerSetPhase(auraEff, aurApp, mode, apply, newPhase);
}

View File

@@ -66,6 +66,7 @@ struct Condition;
struct ItemTemplate;
struct OutdoorPvPData;
struct GroupQueueInfo;
struct TargetInfo;
#define VISIBLE_RANGE 166.0f //MAX visible range (size of grid)
@@ -1291,6 +1292,10 @@ public:
virtual bool CanScalingEverything(Spell* /*spell*/) { return false; }
virtual bool CanSelectSpecTalent(Spell* /*spell*/) { return true; }
virtual void OnScaleAuraUnitAdd(Spell* /*spell*/, Unit* /*target*/, uint32 /*effectMask*/, bool /*checkIfValid*/, bool /*implicit*/, uint8 /*auraScaleMask*/, TargetInfo& /*targetInfo*/) { }
virtual void OnRemoveAuraScaleTargets(Spell* /*spell*/, TargetInfo& /*targetInfo*/, uint8 /*auraScaleMask*/, bool& /*needErase*/) { }
};
// this class can be used to be extended by Modules
@@ -1843,6 +1848,8 @@ class ScriptMgr
bool CanPrepare(Spell* spell, SpellCastTargets const* targets, AuraEffect const* triggeredByAura);
bool CanScalingEverything(Spell* spell);
bool CanSelectSpecTalent(Spell* spell);
void OnScaleAuraUnitAdd(Spell* spell, Unit* target, uint32 effectMask, bool checkIfValid, bool implicit, uint8 auraScaleMask, TargetInfo& targetInfo);
void OnRemoveAuraScaleTargets(Spell* spell, TargetInfo& targetInfo, uint8 auraScaleMask, bool& needErase);
public: /* GameEventScript */

View File

@@ -842,20 +842,25 @@ void Spell::SelectSpellTargets()
else if (m_auraScaleMask)
{
bool checkLvl = !m_UniqueTargetInfo.empty();
for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end();)
for (std::list<TargetInfo>::iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
{
// remove targets which did not pass min level check
if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask)
if (m_auraScaleMask && itr->effectMask == m_auraScaleMask)
{
bool needErase = false;
// Do not check for selfcast
if (!ihit->scaleAura /*[AZTH] && ihit->targetGUID != m_caster->GetGUID()*/ /*[AZTH]*/ && !sAzthUtils->isSpecialSpellForTw(m_spellInfo) /*[/AZTH]*/)
{
m_UniqueTargetInfo.erase(ihit++);
continue;
if (!itr->scaleAura && itr->targetGUID != m_caster->GetGUID())
needErase = true;
sScriptMgr->OnRemoveAuraScaleTargets(this, *itr, m_auraScaleMask, needErase);
if (needErase)
m_UniqueTargetInfo.erase(itr);
}
}
++ihit;
}
if (checkLvl && m_UniqueTargetInfo.empty())
{
SendCastResult(SPELL_FAILED_LOWLEVEL);
@@ -2351,18 +2356,21 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
uint64 targetGUID = target->GetGUID();
// Lookup target in already in list
for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
for (auto itr : m_UniqueTargetInfo)
{
if (targetGUID == ihit->targetGUID) // Found in list
if (targetGUID == itr.targetGUID) // Found in list
{
ihit->effectMask |= effectMask; // Immune effects removed from mask
ihit->scaleAura = false;
if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask /*[AZTH] && m_caster != target*/)
itr.effectMask |= effectMask; // Immune effects removed from mask
itr.scaleAura = false;
if (m_auraScaleMask && itr.effectMask == m_auraScaleMask && m_caster != target)
{
SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
if (uint32(target->getLevel() + 10) >= auraSpell->SpellLevel)
ihit->scaleAura = true;
itr.scaleAura = true;
}
sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, itr);
return;
}
}
@@ -2379,13 +2387,15 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
targetInfo.crit = false;
targetInfo.scaleAura = false;
if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask /*[AZTH] && m_caster != target*/)
if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask)
{
SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
if (uint32(target->getLevel() + 10) >= auraSpell->SpellLevel)
targetInfo.scaleAura = true;
}
sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
// Calculate hit result
if (m_originalCaster)
{

View File

@@ -91,6 +91,21 @@ struct SpellDestination
Position _transportOffset;
};
// Targets store structures and data
struct TargetInfo
{
uint64 targetGUID;
uint64 timeDelay;
SpellMissInfo missCondition:8;
SpellMissInfo reflectResult:8;
uint8 effectMask:8;
bool processed:1;
bool alive:1;
bool crit:1;
bool scaleAura:1;
int32 damage;
};
class SpellCastTargets
{
public:
@@ -519,21 +534,7 @@ class Spell
// xinef: moved to public
void LoadScripts();
// Targets store structures and data
struct TargetInfo
{
uint64 targetGUID;
uint64 timeDelay;
SpellMissInfo missCondition:8;
SpellMissInfo reflectResult:8;
uint8 effectMask:8;
bool processed:1;
bool alive:1;
bool crit:1;
bool scaleAura:1;
int32 damage;
};
std::list<TargetInfo>* GetUniqueTargetInfo() { return &m_UniqueTargetInfo; }
protected:
bool HasGlobalCooldown() const;

View File

@@ -265,8 +265,8 @@ class spell_mother_shahraz_fatal_attraction : public SpellScriptLoader
void SetDest(SpellDestination& dest)
{
std::list<Spell::TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<Spell::TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
std::list<TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (Unit* target = ObjectAccessor::GetUnit(*GetCaster(), ihit->targetGUID))
{
dest.Relocate(*target);

View File

@@ -614,8 +614,8 @@ class spell_illidari_council_empyreal_balance : public SpellScriptLoader
}
float pct = (_sharedHealth / _sharedHealthMax) * 100.0f;
std::list<Spell::TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<Spell::TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
std::list<TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (Creature* target = ObjectAccessor::GetCreature(*GetCaster(), ihit->targetGUID))
{
target->LowerPlayerDamageReq(target->GetMaxHealth());

View File

@@ -601,8 +601,8 @@ class spell_pet_gen_valkyr_guardian_smite : public SpellScriptLoader
{
if (GetHitUnit() != GetCaster())
{
std::list<Spell::TargetInfo>* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<Spell::TargetInfo>::iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
std::list<TargetInfo>* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<TargetInfo>::iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (ihit->targetGUID == GetCaster()->GetGUID())
ihit->damage = -int32(GetHitDamage()*0.25f);
}

View File

@@ -430,8 +430,8 @@ class spell_dk_chains_of_ice : public SpellScriptLoader
{
if (Unit* target = GetExplTargetUnit())
{
std::list<Spell::TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<Spell::TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
std::list<TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (ihit->missCondition == SPELL_MISS_NONE && ihit->targetGUID == target->GetGUID())
GetCaster()->CastSpell(target, 55095 /*SPELL_FROST_FEVER*/, true);
}
@@ -610,8 +610,8 @@ class spell_dk_rune_of_the_fallen_crusader : public SpellScriptLoader
void RecalculateDamage()
{
std::list<Spell::TargetInfo>* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<Spell::TargetInfo>::iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
std::list<TargetInfo>* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<TargetInfo>::iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (ihit->targetGUID == GetCaster()->GetGUID())
ihit->crit = roll_chance_f(GetCaster()->GetFloatValue(PLAYER_CRIT_PERCENTAGE));
}