Core/Spells: Add a base for brand new proc system, this is a WIP and doesn't affect currently working code.

This commit is contained in:
QAston
2011-07-10 13:13:02 +02:00
parent 22135f4d91
commit 72ea9c9fa8
10 changed files with 621 additions and 59 deletions
+2 -2
View File
@@ -19631,7 +19631,7 @@ void Player::RestoreSpellMods(Spell* spell, uint32 ownerAuraId, Aura* aura)
SpellModifier *mod = *itr;
// spellmods without aura set cannot be charged
if (!mod->ownerAura || !mod->ownerAura->GetCharges())
if (!mod->ownerAura || !mod->ownerAura->IsUsingCharges())
continue;
// Restore only specific owner aura mods
@@ -19689,7 +19689,7 @@ void Player::RemoveSpellMods(Spell* spell)
++itr;
// spellmods without aura set cannot be charged
if (!mod->ownerAura || !mod->ownerAura->GetCharges())
if (!mod->ownerAura || !mod->ownerAura->IsUsingCharges())
continue;
// check if mod affected this spell
+121 -1
View File
@@ -92,6 +92,52 @@ static bool isAlwaysTriggeredAura[TOTAL_AURAS];
// Prepare lists
static bool procPrepared = InitTriggerAuraData();
DamageInfo::DamageInfo(Unit* _attacker, Unit* _victim, uint32 _damage, SpellEntry const* _spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType)
: m_attacker(_attacker), m_victim(_victim), m_damage(_damage), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask),
m_damageType(_damageType), m_attackType(BASE_ATTACK)
{
m_absorb = 0;
m_resist = 0;
m_block = 0;
}
DamageInfo::DamageInfo(CalcDamageInfo& dmgInfo)
: m_attacker(dmgInfo.attacker), m_victim(dmgInfo.target), m_damage(dmgInfo.damage), m_spellInfo(NULL), m_schoolMask(SpellSchoolMask(dmgInfo.damageSchoolMask)),
m_damageType(DIRECT_DAMAGE), m_attackType(dmgInfo.attackType)
{
m_absorb = 0;
m_resist = 0;
m_block = 0;
}
void DamageInfo::ModifyDamage(int32 amount)
{
amount = std::min(amount, int32(GetDamage()));
m_damage += amount;
}
void DamageInfo::AbsorbDamage(uint32 amount)
{
amount = std::min(amount, GetDamage());
m_absorb += amount;
m_damage -= amount;
}
void DamageInfo::ResistDamage(uint32 amount)
{
amount = std::min(amount, GetDamage());
m_resist += amount;
m_damage -= amount;
}
void DamageInfo::BlockDamage(uint32 amount)
{
amount = std::min(amount, GetDamage());
m_block += amount;
m_damage -= amount;
}
ProcEventInfo::ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, uint32 typeMask, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo)
:_actor(actor), _actionTarget(actionTarget), _procTarget(procTarget), _typeMask(typeMask), _spellTypeMask(spellTypeMask), _spellPhaseMask(spellPhaseMask),
_hitMask(hitMask), _spell(spell), _damageInfo(damageInfo), _healInfo(healInfo)
{
}
// we can disable this warning for this since it only
// causes undefined behavior when passed to the base class constructor
#ifdef _MSC_VER
@@ -1931,7 +1977,9 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex
DealDamageMods(pVictim, damageInfo.damage, &damageInfo.absorb);
SendAttackStateUpdate(&damageInfo);
//TriggerAurasProcOnEvent(damageInfo);
ProcDamageAndSpell(damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, damageInfo.procEx, damageInfo.damage, damageInfo.attackType);
DealMeleeDamage(&damageInfo, true);
if (GetTypeId() == TYPEID_PLAYER)
@@ -14294,7 +14342,11 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* pTarget, uint32 procFlag,
if (i->aura->IsRemoved())
continue;
bool useCharges = i->aura->GetCharges() > 0;
bool useCharges = i->aura->IsUsingCharges();
// no more charges to use, prevent proc
if (useCharges && !i->aura->GetCharges())
continue;
bool takeCharges = false;
SpellEntry const* spellInfo = i->aura->GetSpellProto();
uint32 Id = i->aura->GetId();
@@ -14495,6 +14547,70 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* pTarget, uint32 procFlag,
SetCantProc(false);
}
void Unit::GetProcAurasTriggeredOnEvent(std::list<AuraApplication*>& aurasTriggeringProc, std::list<AuraApplication*>* procAuras, ProcEventInfo eventInfo)
{
// use provided list of auras which can proc
if (procAuras)
{
for (std::list<AuraApplication*>::iterator itr = procAuras->begin(); itr!= procAuras->end(); ++itr)
{
ASSERT((*itr)->GetTarget() == this);
if (!(*itr)->GetRemoveMode())
if ((*itr)->GetBase()->IsProcTriggeredOnEvent(*itr, eventInfo))
{
(*itr)->GetBase()->PrepareProcToTrigger();
aurasTriggeringProc.push_back(*itr);
}
}
}
// or generate one on our own
else
{
for (AuraApplicationMap::iterator itr = GetAppliedAuras().begin(); itr!= GetAppliedAuras().end(); ++itr)
{
if (itr->second->GetBase()->IsProcTriggeredOnEvent(itr->second, eventInfo))
{
itr->second->GetBase()->PrepareProcToTrigger();
aurasTriggeringProc.push_back(itr->second);
}
}
}
}
void Unit::TriggerAurasProcOnEvent(CalcDamageInfo& damageInfo)
{
DamageInfo dmgInfo = DamageInfo(damageInfo);
TriggerAurasProcOnEvent(NULL, NULL, damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, 0, 0, damageInfo.procEx, NULL, &dmgInfo, NULL);
}
void Unit::TriggerAurasProcOnEvent(std::list<AuraApplication*>* myProcAuras, std::list<AuraApplication*>* targetProcAuras, Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo)
{
// prepare data for self trigger
ProcEventInfo myProcEventInfo = ProcEventInfo(this, actionTarget, actionTarget, typeMaskActor, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo);
std::list<AuraApplication*> myAurasTriggeringProc;
GetProcAurasTriggeredOnEvent(myAurasTriggeringProc, myProcAuras, myProcEventInfo);
// prepare data for target trigger
ProcEventInfo targetProcEventInfo = ProcEventInfo(this, actionTarget, this, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo);
std::list<AuraApplication*> targetAurasTriggeringProc;
if (typeMaskActionTarget)
GetProcAurasTriggeredOnEvent(targetAurasTriggeringProc, targetProcAuras, targetProcEventInfo);
TriggerAurasProcOnEvent(myProcEventInfo, myAurasTriggeringProc);
if (typeMaskActionTarget)
TriggerAurasProcOnEvent(targetProcEventInfo, targetAurasTriggeringProc);
}
void Unit::TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, std::list<AuraApplication*>& aurasTriggeringProc)
{
for (std::list<AuraApplication*>::iterator itr = aurasTriggeringProc.begin(); itr != aurasTriggeringProc.end(); ++itr)
{
if (!(*itr)->GetRemoveMode())
(*itr)->GetBase()->TriggerProcOnEvent(*itr, eventInfo);
}
}
SpellSchoolMask Unit::GetMeleeDamageSchoolMask() const
{
return SPELL_SCHOOL_MASK_NORMAL;
@@ -15059,6 +15175,10 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura * aura, SpellEntry co
{
SpellEntry const* spellProto = aura->GetSpellProto();
// let the aura be handled by new proc system if it has new entry
if (sSpellMgr->GetSpellProcEntry(spellProto->Id))
return false;
// Get proc Event Entry
spellProcEvent = sSpellMgr->GetSpellProcEvent(spellProto->Id);
+71 -31
View File
@@ -801,6 +801,8 @@ struct CleanDamage
MeleeHitOutcome hitOutCome;
};
struct CalcDamageInfo;
class DamageInfo
{
private:
@@ -810,51 +812,84 @@ private:
SpellEntry const* const m_spellInfo;
SpellSchoolMask const m_schoolMask;
DamageEffectType const m_damageType;
WeaponAttackType m_attackType;
uint32 m_absorb;
uint32 m_resist;
uint32 m_block;
public:
explicit DamageInfo(Unit* _attacker, Unit* _victim, uint32 _damage, SpellEntry const* _spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType)
: m_attacker(_attacker), m_victim(_victim), m_damage(_damage), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask), m_damageType(_damageType)
{
m_absorb = 0;
m_resist = 0;
m_block = 0;
}
void ModifyDamage(int32 amount)
{
amount = std::min(amount, int32(GetDamage()));
m_damage += amount;
}
void AbsorbDamage(uint32 amount)
{
amount = std::min(amount, GetDamage());
m_absorb += amount;
m_damage -= amount;
}
void ResistDamage(uint32 amount)
{
amount = std::min(amount, GetDamage());
m_resist += amount;
m_damage -= amount;
}
void BlockDamage(uint32 amount)
{
amount = std::min(amount, GetDamage());
m_block += amount;
m_damage -= amount;
}
explicit DamageInfo(Unit* _attacker, Unit* _victim, uint32 _damage, SpellEntry const* _spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType);
explicit DamageInfo(CalcDamageInfo& dmgInfo);
void ModifyDamage(int32 amount);
void AbsorbDamage(uint32 amount);
void ResistDamage(uint32 amount);
void BlockDamage(uint32 amount);
Unit* GetAttacker() const { return m_attacker; };
Unit* GetVictim() const { return m_victim; };
DamageEffectType GetDamageType() const { return m_damageType; };
SpellEntry const* GetSpellInfo() const { return m_spellInfo; };
SpellSchoolMask GetSchoolMask() const { return m_schoolMask; };
DamageEffectType GetDamageType() const { return m_damageType; };
WeaponAttackType GetAttackType() const { return m_attackType; };
uint32 GetDamage() const { return m_damage; };
uint32 GetAbsorb() const { return m_absorb; };
uint32 GetResist() const { return m_resist; };
uint32 GetBlock() const { return m_block; };
};
class HealInfo
{
private:
Unit* const m_healer;
Unit* const m_target;
uint32 m_heal;
uint32 m_absorb;
SpellEntry const* const m_spellInfo;
SpellSchoolMask const m_schoolMask;
public:
explicit HealInfo(Unit* _healer, Unit* _target, uint32 _heal, SpellEntry const* _spellInfo, SpellSchoolMask _schoolMask)
: m_healer(_healer), m_target(_target), m_heal(_heal), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask)
{
m_absorb = 0;
}
void AbsorbHeal(uint32 amount)
{
amount = std::min(amount, GetHeal());
m_absorb += amount;
m_heal -= amount;
}
uint32 GetHeal() const { return m_heal; };
};
class ProcEventInfo
{
private:
Unit* const _actor;
Unit* const _actionTarget;
Unit* const _procTarget;
uint32 _typeMask;
uint32 _spellTypeMask;
uint32 _spellPhaseMask;
uint32 _hitMask;
Spell* _spell;
DamageInfo* _damageInfo;
HealInfo* _healInfo;
public:
explicit ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, uint32 typeMask, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo);
Unit* GetActor() { return _actor; };
Unit* GetActionTarget() const { return _actionTarget; }
Unit* GetProcTarget() const { return _procTarget; }
uint32 GetTypeMask() const { return _typeMask; }
uint32 GetSpellTypeMask() const { return _spellTypeMask; }
uint32 GetSpellPhaseMask() const { return _spellPhaseMask; }
uint32 GetHitMask() const { return _hitMask; }
SpellEntry const* GetSpellInfo() const { return NULL; }
SpellSchoolMask GetSchoolMask() const { return SPELL_SCHOOL_MASK_NONE; }
DamageInfo* GetDamageInfo() const { return _damageInfo; }
HealInfo* GetHealInfo() const { return _healInfo; }
};
// Struct for use in Unit::CalculateMeleeDamage
// Need create structure like in SMSG_ATTACKERSTATEUPDATE opcode
struct CalcDamageInfo
@@ -1362,6 +1397,11 @@ class Unit : public WorldObject
void ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType = BASE_ATTACK, SpellEntry const *procSpell = NULL, SpellEntry const* procAura = NULL);
void ProcDamageAndSpellFor(bool isVictim, Unit* pTarget, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellEntry const* procSpell, uint32 damage , SpellEntry const* procAura = NULL);
void GetProcAurasTriggeredOnEvent(std::list<AuraApplication*>& aurasTriggeringProc, std::list<AuraApplication*>* procAuras, ProcEventInfo eventInfo);
void TriggerAurasProcOnEvent(CalcDamageInfo& damageInfo);
void TriggerAurasProcOnEvent(std::list<AuraApplication*>* myProcAuras, std::list<AuraApplication*>* targetProcAuras, Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo);
void TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, std::list<AuraApplication*>& procAuras);
void HandleEmoteCommand(uint32 anim_id);
void AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType = BASE_ATTACK, bool extra = false);