mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-16 16:56:07 +00:00
refactor(Core/Spells): Implement QAston Proc System (#11079)
* . * sql * . * . * 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * Update spell_item.cpp * Update Unit.cpp * 16 * 17 * 18 * 19 * 20 * 21 * Update Unit.cpp * REVERT UltraNIX Commit * 22 * 23 * . * . * . * warrior * warlock * shaman rogue priest paladin mage * spell item * hunter * druid * dk * war * error style * Update rev_1647677899565690722.sql * Update rev_1647677899565690722.sql * Update rev_1647677899565690722.sql * . * DOND DEL ME WAD DO DO * error 2 * . * . * . * FIX * Update SpellInfoCorrections.cpp * Update SpellInfoCorrections.cpp * . * ja genau * Update .gitignore * . * . * ., * . * . * . * . * Update Unit.cpp
This commit is contained in:
committed by
GitHub
parent
5189b43a28
commit
cbd3fd0967
@@ -2751,8 +2751,8 @@ void Creature::AddSpellCooldown(uint32 spell_id, uint32 /*itemid*/, uint32 end_t
|
||||
uint32 categorycooldown = categoryId ? spellInfo->CategoryRecoveryTime : 0;
|
||||
if (Player* modOwner = GetSpellModOwner())
|
||||
{
|
||||
modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, spellcooldown);
|
||||
modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, categorycooldown);
|
||||
modOwner->ApplySpellMod<SPELLMOD_COOLDOWN>(spellInfo->Id, spellcooldown);
|
||||
modOwner->ApplySpellMod<SPELLMOD_COOLDOWN>(spellInfo->Id, categorycooldown);
|
||||
}
|
||||
|
||||
SpellCategoryStore::const_iterator i_scstore = sSpellsByCategoryStore.find(categoryId);
|
||||
|
||||
@@ -764,7 +764,7 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
|
||||
case DAMAGE_LAVA:
|
||||
case DAMAGE_SLIME:
|
||||
{
|
||||
DamageInfo dmgInfo(this, this, damage, nullptr, type == DAMAGE_LAVA ? SPELL_SCHOOL_MASK_FIRE : SPELL_SCHOOL_MASK_NATURE, DIRECT_DAMAGE);
|
||||
DamageInfo dmgInfo(this, this, damage, nullptr, type == DAMAGE_LAVA ? SPELL_SCHOOL_MASK_FIRE : SPELL_SCHOOL_MASK_NATURE, DIRECT_DAMAGE, BASE_ATTACK);
|
||||
Unit::CalcAbsorbResist(dmgInfo);
|
||||
absorb = dmgInfo.GetAbsorb();
|
||||
resist = dmgInfo.GetResist();
|
||||
@@ -7058,21 +7058,22 @@ void Player::ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply,
|
||||
}
|
||||
}
|
||||
|
||||
void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
|
||||
void Player::CastItemCombatSpell(DamageInfo const& damageInfo)
|
||||
{
|
||||
Unit* target = damageInfo.GetVictim();
|
||||
if (!target || !target->IsAlive() || target == this)
|
||||
return;
|
||||
|
||||
// Xinef: do not use disarmed weapons, special exception - shaman ghost wolf form
|
||||
// Xinef: normal forms proc on hit enchants / built in item bonuses
|
||||
if (!CanUseAttackType(attType) || GetShapeshiftForm() == FORM_GHOSTWOLF)
|
||||
if (!CanUseAttackType(damageInfo.GetAttackType()) || GetShapeshiftForm() == FORM_GHOSTWOLF)
|
||||
return;
|
||||
|
||||
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
|
||||
{
|
||||
// If usable, try to cast item spell
|
||||
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
if (!item->IsBroken())
|
||||
if (!item->IsBroken() && CanUseAttackType(damageInfo.GetAttackType()))
|
||||
if (ItemTemplate const* proto = item->GetTemplate())
|
||||
{
|
||||
// Additional check for weapons
|
||||
@@ -7080,7 +7081,7 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
|
||||
{
|
||||
// offhand item cannot proc from main hand hit etc
|
||||
EquipmentSlots slot;
|
||||
switch (attType)
|
||||
switch (damageInfo.GetAttackType())
|
||||
{
|
||||
case BASE_ATTACK:
|
||||
slot = EQUIPMENT_SLOT_MAINHAND;
|
||||
@@ -7099,19 +7100,20 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
|
||||
continue;
|
||||
}
|
||||
|
||||
CastItemCombatSpell(target, attType, procVictim, procEx, item, proto);
|
||||
CastItemCombatSpell(damageInfo, item, proto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx, Item* item, ItemTemplate const* proto)
|
||||
void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemTemplate const* proto)
|
||||
{
|
||||
if (!sScriptMgr->CanCastItemCombatSpell(this, target, attType, procVictim, procEx, item, proto))
|
||||
return;
|
||||
// if (!sScriptMgr->CanCastItemCombatSpell(this, target, attType, procVictim, procEx, item, proto))
|
||||
// return;
|
||||
|
||||
// Can do effect if any damage done to target
|
||||
if (procVictim & PROC_FLAG_TAKEN_DAMAGE)
|
||||
//if (damageInfo->procVictim & PROC_FLAG_TAKEN_ANY_DAMAGE)
|
||||
// for done procs allow normal + critical + absorbs by default
|
||||
bool canTrigger = (damageInfo.GetHitMask() & (PROC_HIT_NORMAL | PROC_HIT_CRITICAL | PROC_HIT_ABSORB)) != 0;
|
||||
if (canTrigger)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ITEM_SPELLS; ++i)
|
||||
{
|
||||
@@ -7132,11 +7134,15 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
|
||||
continue;
|
||||
}
|
||||
|
||||
// not allow proc extra attack spell at extra attack
|
||||
if (m_extraAttacks && spellInfo->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
|
||||
return;
|
||||
|
||||
float chance = (float)spellInfo->ProcChance;
|
||||
|
||||
if (spellData.SpellPPMRate)
|
||||
{
|
||||
uint32 WeaponSpeed = GetAttackTime(attType);
|
||||
uint32 WeaponSpeed = GetAttackTime(damageInfo.GetAttackType());
|
||||
chance = GetPPMProcChance(WeaponSpeed, spellData.SpellPPMRate, spellInfo);
|
||||
}
|
||||
else if (chance > 100.0f)
|
||||
@@ -7144,8 +7150,8 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
|
||||
chance = GetWeaponProcChance();
|
||||
}
|
||||
|
||||
if (roll_chance_f(chance) && sScriptMgr->OnCastItemCombatSpell(this, target, spellInfo, item))
|
||||
CastSpell(target, spellInfo->Id, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD), item);
|
||||
if (roll_chance_f(chance)/* && sScriptMgr->OnCastItemCombatSpell(this, target, spellInfo, item)*/)
|
||||
CastSpell(damageInfo.GetVictim(), spellInfo->Id, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD), item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7167,14 +7173,14 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
|
||||
if (entry && entry->procEx)
|
||||
{
|
||||
// Check hit/crit/dodge/parry requirement
|
||||
if ((entry->procEx & procEx) == 0)
|
||||
if ((entry->procEx & damageInfo.GetHitMask()) == 0)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can do effect if any damage done to target
|
||||
if (!(procVictim & PROC_FLAG_TAKEN_DAMAGE))
|
||||
//if (!(damageInfo->procVictim & PROC_FLAG_TAKEN_ANY_DAMAGE))
|
||||
// for done procs allow normal + critical + absorbs by default
|
||||
if (!canTrigger)
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -7197,7 +7203,7 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
|
||||
}
|
||||
|
||||
// Apply spell mods
|
||||
ApplySpellMod(pEnchant->spellid[s], SPELLMOD_CHANCE_OF_SUCCESS, chance);
|
||||
ApplySpellMod<SPELLMOD_CHANCE_OF_SUCCESS>(pEnchant->spellid[s], chance);
|
||||
|
||||
// Shiv has 100% chance to apply the poison
|
||||
if (FindCurrentSpellBySpellId(5938) && e_slot == TEMP_ENCHANTMENT_SLOT)
|
||||
@@ -7220,7 +7226,7 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
|
||||
if (spellInfo->IsPositive())
|
||||
CastSpell(this, spellInfo, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD), item);
|
||||
else
|
||||
CastSpell(target, spellInfo, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD), item);
|
||||
CastSpell(damageInfo.GetVictim(), spellInfo, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD), item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9565,9 +9571,11 @@ bool Player::IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod
|
||||
if (!mod || !spellInfo)
|
||||
return false;
|
||||
|
||||
// Mod out of charges
|
||||
if (spell && mod->charges == -1 && spell->m_appliedMods.find(mod->ownerAura) == spell->m_appliedMods.end())
|
||||
// First time this aura applies a mod to us and is out of charges
|
||||
if (spell && mod->ownerAura->IsUsingCharges() && !mod->ownerAura->GetCharges() && !spell->m_appliedMods.count(mod->ownerAura))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// +duration to infinite duration spells making them limited
|
||||
if (mod->op == SPELLMOD_DURATION && spellInfo->GetDuration() == -1)
|
||||
@@ -9609,50 +9617,46 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply)
|
||||
LOG_DEBUG("spells.aura", "Player::AddSpellMod {}", mod->spellId);
|
||||
uint16 Opcode = (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER;
|
||||
|
||||
int i = 0;
|
||||
flag96 _mask = 0;
|
||||
for (int eff = 0; eff < 96; ++eff)
|
||||
flag96 modMask;
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
{
|
||||
if (eff != 0 && eff % 32 == 0)
|
||||
_mask[i++] = 0;
|
||||
|
||||
_mask[i] = uint32(1) << (eff - (32 * i));
|
||||
if (mod->mask & _mask)
|
||||
for (uint32 eff = 0; eff < 32; ++eff)
|
||||
{
|
||||
int32 val = 0;
|
||||
for (SpellModList::iterator itr = m_spellMods[mod->op].begin(); itr != m_spellMods[mod->op].end(); ++itr)
|
||||
modMask[i] = uint32(1) << eff;
|
||||
if ((mod->mask & modMask))
|
||||
{
|
||||
if ((*itr)->type == mod->type && (*itr)->mask & _mask)
|
||||
val += (*itr)->value;
|
||||
int32 val = 0;
|
||||
for (SpellModifier* spellMod : m_spellMods[mod->op])
|
||||
{
|
||||
if (spellMod->type == mod->type && (spellMod->mask & modMask))
|
||||
{
|
||||
val += spellMod->value;
|
||||
}
|
||||
}
|
||||
val += apply ? mod->value : -(mod->value);
|
||||
WorldPacket data(Opcode, (1 + 1 + 4));
|
||||
data << uint8(eff + 32 * i);
|
||||
data << uint8(mod->op);
|
||||
data << int32(val);
|
||||
SendDirectMessage(&data);
|
||||
}
|
||||
val += apply ? mod->value : -(mod->value);
|
||||
WorldPacket data(Opcode, (1 + 1 + 4));
|
||||
data << uint8(eff);
|
||||
data << uint8(mod->op);
|
||||
data << int32(val);
|
||||
SendDirectMessage(&data);
|
||||
}
|
||||
|
||||
modMask[i] = 0;
|
||||
}
|
||||
|
||||
if (apply)
|
||||
{
|
||||
m_spellMods[mod->op].push_back(mod);
|
||||
if (getClass() == CLASS_MAGE)
|
||||
m_spellMods[mod->op].sort(MageSpellModPred());
|
||||
else
|
||||
m_spellMods[mod->op].sort(SpellModPred());
|
||||
m_spellMods[mod->op].insert(mod);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spellMods[mod->op].remove(mod);
|
||||
// mods bound to aura will be removed in AuraEffect::~AuraEffect
|
||||
if (!mod->ownerAura)
|
||||
delete mod;
|
||||
m_spellMods[mod->op].erase(mod);
|
||||
}
|
||||
}
|
||||
|
||||
// Restore spellmods in case of failed cast
|
||||
void Player::RestoreSpellMods(Spell* spell, uint32 ownerAuraId, Aura* aura)
|
||||
void Player::RestoreSpellMods(Spell* spell, uint32 ownerAuraId /*= 0*/, Aura* aura /*= nullptr*/)
|
||||
{
|
||||
if (!spell || spell->m_appliedMods.empty())
|
||||
return;
|
||||
@@ -9661,16 +9665,16 @@ void Player::RestoreSpellMods(Spell* spell, uint32 ownerAuraId, Aura* aura)
|
||||
|
||||
for (uint8 i = 0; i < MAX_SPELLMOD; ++i)
|
||||
{
|
||||
for (SpellModList::iterator itr = m_spellMods[i].begin(); itr != m_spellMods[i].end(); ++itr)
|
||||
for (auto itr = m_spellMods[i].begin(); itr != m_spellMods[i].end(); ++itr)
|
||||
{
|
||||
SpellModifier* mod = *itr;
|
||||
|
||||
// Spellmods without aura set cannot be charged
|
||||
if (!mod->ownerAura || !mod->ownerAura->IsUsingCharges())
|
||||
// Spellmods without charged aura set cannot be charged
|
||||
if (!mod->ownerAura->IsUsingCharges())
|
||||
continue;
|
||||
|
||||
// Restore only specific owner aura mods
|
||||
if (ownerAuraId && (ownerAuraId != mod->ownerAura->GetSpellInfo()->Id))
|
||||
if (ownerAuraId && mod->spellId != ownerAuraId)
|
||||
continue;
|
||||
|
||||
if (aura && mod->ownerAura != aura)
|
||||
@@ -9691,27 +9695,14 @@ void Player::RestoreSpellMods(Spell* spell, uint32 ownerAuraId, Aura* aura)
|
||||
// only see the first of its modifier restored)
|
||||
aurasQueue.push_back(mod->ownerAura);
|
||||
|
||||
// add mod charges back to mod
|
||||
if (mod->charges == -1)
|
||||
mod->charges = 1;
|
||||
else
|
||||
mod->charges++;
|
||||
|
||||
// Do not set more spellmods than available
|
||||
if (mod->ownerAura->GetCharges() < mod->charges)
|
||||
mod->charges = mod->ownerAura->GetCharges();
|
||||
|
||||
// Skip this check for now - aura charges may change due to various reason
|
||||
/// @todo track these changes correctly
|
||||
//ASSERT (mod->ownerAura->GetCharges() <= mod->charges);
|
||||
// add charges back to aura
|
||||
mod->ownerAura->ModCharges(1);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::list<Aura*>::iterator itr = aurasQueue.begin(); itr != aurasQueue.end(); ++itr)
|
||||
for (Aura* aura : aurasQueue)
|
||||
{
|
||||
Spell::UsedSpellMods::iterator iterMod = spell->m_appliedMods.find(*itr);
|
||||
if (iterMod != spell->m_appliedMods.end())
|
||||
spell->m_appliedMods.erase(iterMod);
|
||||
spell->m_appliedMods.erase(aura);
|
||||
}
|
||||
|
||||
// Xinef: clear the list just do be sure
|
||||
@@ -9719,77 +9710,32 @@ void Player::RestoreSpellMods(Spell* spell, uint32 ownerAuraId, Aura* aura)
|
||||
spell->m_appliedMods.clear();
|
||||
}
|
||||
|
||||
void Player::RestoreAllSpellMods(uint32 ownerAuraId, Aura* aura)
|
||||
void Player::RestoreAllSpellMods(uint32 ownerAuraId /*= 0*/, Aura* aura /*= nullptr*/)
|
||||
{
|
||||
for (uint32 i = 0; i < CURRENT_MAX_SPELL; ++i)
|
||||
if (m_currentSpells[i])
|
||||
RestoreSpellMods(m_currentSpells[i], ownerAuraId, aura);
|
||||
if (Spell* spell = m_currentSpells[i])
|
||||
RestoreSpellMods(spell, ownerAuraId, aura);
|
||||
}
|
||||
|
||||
void Player::RemoveSpellMods(Spell* spell)
|
||||
void Player::ApplyModToSpell(SpellModifier* mod, Spell* spell)
|
||||
{
|
||||
if (!spell)
|
||||
return;
|
||||
|
||||
if (spell->m_appliedMods.empty())
|
||||
// don't do anything with no charges
|
||||
if (mod->ownerAura->IsUsingCharges() && !mod->ownerAura->GetCharges())
|
||||
return;
|
||||
|
||||
SpellInfo const* const spellInfo = spell->m_spellInfo;
|
||||
|
||||
for (uint8 i = 0; i < MAX_SPELLMOD; ++i)
|
||||
{
|
||||
for (SpellModList::const_iterator itr = m_spellMods[i].begin(); itr != m_spellMods[i].end();)
|
||||
{
|
||||
SpellModifier* mod = *itr;
|
||||
++itr;
|
||||
|
||||
// spellmods without aura set cannot be charged
|
||||
if (!mod->ownerAura || !mod->ownerAura->IsUsingCharges())
|
||||
continue;
|
||||
|
||||
// check if mod affected this spell
|
||||
Spell::UsedSpellMods::iterator iterMod = spell->m_appliedMods.find(mod->ownerAura);
|
||||
if (iterMod == spell->m_appliedMods.end())
|
||||
continue;
|
||||
|
||||
// remove from list
|
||||
// leave this here, if spell have two mods it will remove 2 charges - wrong
|
||||
spell->m_appliedMods.erase(iterMod);
|
||||
|
||||
// MAGE T8P4 BONUS
|
||||
if( spellInfo->SpellFamilyName == SPELLFAMILY_MAGE )
|
||||
{
|
||||
SpellInfo const* sp = mod->ownerAura->GetSpellInfo();
|
||||
// Missile Barrage, Hot Streak, Brain Freeze (trigger spell - Fireball!)
|
||||
if( sp->SpellIconID == 3261 || sp->SpellIconID == 2999 || sp->SpellIconID == 2938 )
|
||||
if( AuraEffect* aurEff = GetAuraEffectDummy(64869) )
|
||||
if( roll_chance_i(aurEff->GetAmount()) )
|
||||
{
|
||||
mod->charges = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (mod->ownerAura->DropCharge(AURA_REMOVE_BY_EXPIRE))
|
||||
itr = m_spellMods[i].begin();
|
||||
}
|
||||
}
|
||||
// register inside spell, proc system uses this to drop charges
|
||||
spell->m_appliedMods.insert(mod->ownerAura);
|
||||
}
|
||||
|
||||
void Player::DropModCharge(SpellModifier* mod, Spell* spell)
|
||||
bool Player::HasSpellModApplied(SpellModifier* mod, Spell* spell)
|
||||
{
|
||||
// don't handle spells with proc_event entry defined
|
||||
// this is a temporary workaround, because all spellmods should be handled like that
|
||||
if (sSpellMgr->GetSpellProcEvent(mod->spellId))
|
||||
return;
|
||||
if (!spell)
|
||||
return false;
|
||||
|
||||
if (spell && mod->ownerAura && mod->charges > 0)
|
||||
{
|
||||
if (--mod->charges == 0)
|
||||
mod->charges = -1;
|
||||
|
||||
spell->m_appliedMods.insert(mod->ownerAura);
|
||||
}
|
||||
return spell->m_appliedMods.count(mod->ownerAura) != 0;
|
||||
}
|
||||
|
||||
void Player::SetSpellModTakingSpell(Spell* spell, bool apply)
|
||||
@@ -10687,7 +10633,7 @@ void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 ite
|
||||
if (rec > 0)
|
||||
{
|
||||
int32 oldRec = rec;
|
||||
ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, rec, spell);
|
||||
ApplySpellMod<SPELLMOD_COOLDOWN>(spellInfo->Id, rec, spell);
|
||||
if (oldRec != rec)
|
||||
{
|
||||
useSpellCooldown = true;
|
||||
@@ -10696,7 +10642,7 @@ void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 ite
|
||||
|
||||
if (catrec > 0 && !spellInfo->HasAttribute(SPELL_ATTR6_NO_CATEGORY_COOLDOWN_MODS))
|
||||
{
|
||||
ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, catrec, spell);
|
||||
ApplySpellMod<SPELLMOD_COOLDOWN>(spellInfo->Id, catrec, spell);
|
||||
}
|
||||
|
||||
if (int32 cooldownMod = GetTotalAuraModifier(SPELL_AURA_MOD_COOLDOWN))
|
||||
@@ -11472,6 +11418,7 @@ void Player::ApplyEquipCooldown(Item* pItem)
|
||||
if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_NO_EQUIP_COOLDOWN))
|
||||
return;
|
||||
|
||||
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
|
||||
for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
|
||||
{
|
||||
_Spell const& spellData = pItem->GetTemplate()->Spells[i];
|
||||
@@ -11480,11 +11427,15 @@ void Player::ApplyEquipCooldown(Item* pItem)
|
||||
if (!spellData.SpellId)
|
||||
continue;
|
||||
|
||||
// xinef: apply hidden cooldown for procs
|
||||
// apply proc cooldown to equip auras if we have any
|
||||
if (spellData.SpellTrigger == ITEM_SPELLTRIGGER_ON_EQUIP)
|
||||
{
|
||||
// xinef: uint32(-1) special marker for proc cooldowns
|
||||
AddSpellCooldown(spellData.SpellId, uint32(-1), 30 * IN_MILLISECONDS);
|
||||
SpellProcEntry const* procEntry = sSpellMgr->GetSpellProcEntry(spellData.SpellId);
|
||||
if (!procEntry)
|
||||
continue;
|
||||
|
||||
if (Aura* itemAura = GetAura(spellData.SpellId, GetGUID(), pItem->GetGUID()))
|
||||
itemAura->AddProcCooldown(now + procEntry->Cooldown);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,10 +89,10 @@ typedef void(*bgZoneRef)(Battleground*, WorldPacket&);
|
||||
#define MAKE_SKILL_BONUS(t, p) MAKE_PAIR32(t, p)
|
||||
|
||||
// Note: SPELLMOD_* values is aura types in fact
|
||||
enum SpellModType
|
||||
enum SpellModType : uint8
|
||||
{
|
||||
SPELLMOD_FLAT = 107, // SPELL_AURA_ADD_FLAT_MODIFIER
|
||||
SPELLMOD_PCT = 108 // SPELL_AURA_ADD_PCT_MODIFIER
|
||||
SPELLMOD_FLAT = SPELL_AURA_ADD_FLAT_MODIFIER,
|
||||
SPELLMOD_PCT = SPELL_AURA_ADD_PCT_MODIFIER
|
||||
};
|
||||
|
||||
// 2^n values, Player::m_isunderwater is a bitmask. These are Trinity internal values, they are never send to any client
|
||||
@@ -180,10 +180,9 @@ enum TalentTree // talent tabs
|
||||
// Spell modifier (used for modify other spells)
|
||||
struct SpellModifier
|
||||
{
|
||||
SpellModifier(Aura* _ownerAura = nullptr) : op(SPELLMOD_DAMAGE), type(SPELLMOD_FLAT), charges(0), mask(), ownerAura(_ownerAura) {}
|
||||
SpellModOp op : 8;
|
||||
SpellModType type : 8;
|
||||
int16 charges : 16;
|
||||
SpellModifier(Aura* _ownerAura = nullptr) : op(SPELLMOD_DAMAGE), type(SPELLMOD_FLAT), mask(), ownerAura(_ownerAura) {}
|
||||
SpellModOp op;
|
||||
SpellModType type;
|
||||
int32 value{0};
|
||||
flag96 mask;
|
||||
uint32 spellId{0};
|
||||
@@ -192,7 +191,7 @@ struct SpellModifier
|
||||
|
||||
typedef std::unordered_map<uint32, PlayerTalent*> PlayerTalentMap;
|
||||
typedef std::unordered_map<uint32, PlayerSpell*> PlayerSpellMap;
|
||||
typedef std::list<SpellModifier*> SpellModList;
|
||||
typedef std::unordered_set<SpellModifier*> SpellModContainer;
|
||||
|
||||
typedef GuidList WhisperListContainer;
|
||||
|
||||
@@ -1730,13 +1729,14 @@ public:
|
||||
SpellCooldowns& GetSpellCooldownMap() { return m_spellCooldowns; }
|
||||
|
||||
void AddSpellMod(SpellModifier* mod, bool apply);
|
||||
bool IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod, Spell* spell = nullptr);
|
||||
static bool IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod, Spell* spell = nullptr);
|
||||
bool HasSpellMod(SpellModifier* mod, Spell* spell);
|
||||
template <class T> T ApplySpellMod(uint32 spellId, SpellModOp op, T& basevalue, Spell* spell = nullptr, bool temporaryPet = false);
|
||||
void RemoveSpellMods(Spell* spell);
|
||||
template <SpellModOp op, class T>
|
||||
void ApplySpellMod(uint32 spellId, T& basevalue, Spell* spell = nullptr) const;
|
||||
void RestoreSpellMods(Spell* spell, uint32 ownerAuraId = 0, Aura* aura = nullptr);
|
||||
void RestoreAllSpellMods(uint32 ownerAuraId = 0, Aura* aura = nullptr);
|
||||
void DropModCharge(SpellModifier* mod, Spell* spell);
|
||||
static void ApplyModToSpell(SpellModifier* mod, Spell* spell);
|
||||
static bool HasSpellModApplied(SpellModifier* mod, Spell* spell);
|
||||
void SetSpellModTakingSpell(Spell* spell, bool apply);
|
||||
|
||||
[[nodiscard]] bool HasSpellCooldown(uint32 spell_id) const override;
|
||||
@@ -2166,9 +2166,9 @@ public:
|
||||
void ApplyItemEquipSpell(Item* item, bool apply, bool form_change = false);
|
||||
void ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply, bool form_change = false);
|
||||
void UpdateEquipSpellsAtFormChange();
|
||||
void CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx);
|
||||
void CastItemCombatSpell(DamageInfo const& damageInfo);
|
||||
void CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemTemplate const* proto);
|
||||
void CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 cast_count, uint32 glyphIndex);
|
||||
void CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx, Item* item, ItemTemplate const* proto);
|
||||
|
||||
void SendEquipmentSetList();
|
||||
void SetEquipmentSet(uint32 index, EquipmentSet eqset);
|
||||
@@ -2551,7 +2551,7 @@ public:
|
||||
// mt maps
|
||||
[[nodiscard]] const PlayerTalentMap& GetTalentMap() const { return m_talents; }
|
||||
[[nodiscard]] uint32 GetNextSave() const { return m_nextSave; }
|
||||
[[nodiscard]] SpellModList const& GetSpellModList(uint32 type) const { return m_spellMods[type]; }
|
||||
[[nodiscard]] SpellModContainer const& GetSpellModContainer(uint32 type) const { return m_spellMods[type]; }
|
||||
|
||||
void SetServerSideVisibility(ServerSideVisibilityType type, AccountTypes sec);
|
||||
void SetServerSideVisibilityDetect(ServerSideVisibilityType type, AccountTypes sec);
|
||||
@@ -2756,7 +2756,7 @@ public:
|
||||
uint32 m_baseHealthRegen;
|
||||
int32 m_spellPenetrationItemMod;
|
||||
|
||||
SpellModList m_spellMods[MAX_SPELLMOD];
|
||||
SpellModContainer m_spellMods[MAX_SPELLMOD];
|
||||
//uint32 m_pad;
|
||||
// Spell* m_spellModTakingSpell; // Spell for which charges are dropped in spell::finish
|
||||
|
||||
@@ -2940,130 +2940,132 @@ void AddItemsSetItem(Player* player, Item* item);
|
||||
void RemoveItemsSetItem(Player* player, ItemTemplate const* proto);
|
||||
|
||||
// "the bodies of template functions must be made available in a header file"
|
||||
template <class T> T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T& basevalue, Spell* spell, bool temporaryPet)
|
||||
template <SpellModOp op, class T>
|
||||
void Player::ApplySpellMod(uint32 spellId, T& basevalue, Spell* spell) const
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (!spellInfo)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return;
|
||||
|
||||
float totalmul = 1.0f;
|
||||
float totalmul = 1.f;
|
||||
int32 totalflat = 0;
|
||||
|
||||
auto calculateSpellMod = [&](SpellModifier* mod)
|
||||
{
|
||||
// xinef: temporary pets cannot use charged mods of owner, needed for mirror image QQ they should use their own auras
|
||||
if (temporaryPet && mod->charges != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (mod->type == SPELLMOD_FLAT)
|
||||
{
|
||||
// xinef: do not allow to consume more than one 100% crit increasing spell
|
||||
if (mod->op == SPELLMOD_CRITICAL_CHANCE && totalflat >= 100)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int32 flatValue = mod->value;
|
||||
|
||||
// SPELL_MOD_THREAT - divide by 100 (in packets we send threat * 100)
|
||||
if (mod->op == SPELLMOD_THREAT)
|
||||
{
|
||||
flatValue /= 100;
|
||||
}
|
||||
|
||||
totalflat += flatValue;
|
||||
}
|
||||
else if (mod->type == SPELLMOD_PCT)
|
||||
{
|
||||
// skip percent mods for null basevalue (most important for spell mods with charges)
|
||||
if (basevalue == T(0) || totalmul == 0.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// special case (skip > 10sec spell casts for instant cast setting)
|
||||
if (mod->op == SPELLMOD_CASTING_TIME && basevalue >= T(10000) && mod->value <= -100)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// xinef: special exception for surge of light, dont affect crit chance if previous mods were not applied
|
||||
else if (mod->op == SPELLMOD_CRITICAL_CHANCE && spell && !HasSpellMod(mod, spell))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// xinef: special case for backdraft gcd reduce with backlast time reduction, dont affect gcd if cast time was not applied
|
||||
else if (mod->op == SPELLMOD_GLOBAL_COOLDOWN && spell && !HasSpellMod(mod, spell))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// xinef: those two mods should be multiplicative (Glyph of Renew)
|
||||
if (mod->op == SPELLMOD_DAMAGE || mod->op == SPELLMOD_DOT)
|
||||
{
|
||||
totalmul *= CalculatePct(1.0f, 100.0f + mod->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
totalmul += CalculatePct(1.0f, mod->value);
|
||||
}
|
||||
}
|
||||
|
||||
DropModCharge(mod, spell);
|
||||
};
|
||||
|
||||
// Drop charges for triggering spells instead of triggered ones
|
||||
if (m_spellModTakingSpell)
|
||||
{
|
||||
spell = m_spellModTakingSpell;
|
||||
}
|
||||
|
||||
SpellModifier* chargedMod = nullptr;
|
||||
for (auto mod : m_spellMods[op])
|
||||
switch (op)
|
||||
{
|
||||
// Charges can be set only for mods with auras
|
||||
if (!mod->ownerAura)
|
||||
// special case, if a mod makes spell instant, only consume that mod
|
||||
case SPELLMOD_CASTING_TIME:
|
||||
{
|
||||
ASSERT(!mod->charges);
|
||||
}
|
||||
|
||||
if (!IsAffectedBySpellmod(spellInfo, mod, spell))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mod->ownerAura->IsUsingCharges())
|
||||
{
|
||||
if (!chargedMod || (chargedMod->ownerAura->GetSpellInfo()->SpellPriority < mod->ownerAura->GetSpellInfo()->SpellPriority))
|
||||
SpellModifier* modInstantSpell = nullptr;
|
||||
for (SpellModifier* mod : m_spellMods[SPELLMOD_CASTING_TIME])
|
||||
{
|
||||
chargedMod = mod;
|
||||
if (!IsAffectedBySpellmod(spellInfo, mod, spell))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mod->type == SPELLMOD_PCT && basevalue < T(10000) && mod->value <= -100)
|
||||
{
|
||||
modInstantSpell = mod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
if (modInstantSpell)
|
||||
{
|
||||
Player::ApplyModToSpell(modInstantSpell, spell);
|
||||
basevalue = T(0);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
calculateSpellMod(mod);
|
||||
// special case if two mods apply 100% critical chance, only consume one
|
||||
case SPELLMOD_CRITICAL_CHANCE:
|
||||
{
|
||||
SpellModifier* modCritical = nullptr;
|
||||
for (auto mod : m_spellMods[SPELLMOD_CRITICAL_CHANCE])
|
||||
{
|
||||
if (!IsAffectedBySpellmod(spellInfo, mod, spell))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mod->type == SPELLMOD_FLAT && mod->value >= 100)
|
||||
{
|
||||
modCritical = mod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (modCritical)
|
||||
{
|
||||
Player::ApplyModToSpell(modCritical, spell);
|
||||
basevalue = T(100);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (chargedMod)
|
||||
for (auto mod : m_spellMods[op])
|
||||
{
|
||||
calculateSpellMod(chargedMod);
|
||||
}
|
||||
if (!IsAffectedBySpellmod(spellInfo, mod, spell))
|
||||
continue;
|
||||
|
||||
switch (mod->type)
|
||||
{
|
||||
case SPELLMOD_FLAT:
|
||||
totalflat += mod->value;
|
||||
break;
|
||||
case SPELLMOD_PCT:
|
||||
{
|
||||
// skip percent mods for null basevalue (most important for spell mods with charges)
|
||||
if (basevalue == T(0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// special case (skip > 10s spell casts for instant cast setting)
|
||||
if (op == SPELLMOD_CASTING_TIME)
|
||||
{
|
||||
if (mod->value <= -100 && basevalue >= T(10000))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
totalmul += CalculatePct(1.f, mod->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*// xinef: special exception for surge of light, dont affect crit chance if previous mods were not applied
|
||||
else if (mod->op == SPELLMOD_CRITICAL_CHANCE && spell && !HasSpellMod(mod, spell))
|
||||
continue;
|
||||
// xinef: special case for backdraft gcd reduce with backlast time reduction, dont affect gcd if cast time was not applied
|
||||
else if (mod->op == SPELLMOD_GLOBAL_COOLDOWN && spell && !HasSpellMod(mod, spell))
|
||||
continue;
|
||||
// xinef: those two mods should be multiplicative (Glyph of Renew)
|
||||
if (mod->op == SPELLMOD_DAMAGE || mod->op == SPELLMOD_DOT)
|
||||
totalmul *= CalculatePct(1.0f, 100.0f + mod->value);
|
||||
else
|
||||
totalmul += CalculatePct(1.0f, mod->value);*/
|
||||
|
||||
Player::ApplyModToSpell(mod, spell);
|
||||
}
|
||||
float diff = 0.0f;
|
||||
if (op == SPELLMOD_CASTING_TIME || op == SPELLMOD_DURATION)
|
||||
{
|
||||
diff = ((float)basevalue + totalflat) * (totalmul - 1.0f) + (float)totalflat;
|
||||
}
|
||||
else
|
||||
{
|
||||
diff = (float)basevalue * (totalmul - 1.0f) + (float)totalflat;
|
||||
}
|
||||
|
||||
basevalue = T((float)basevalue + diff);
|
||||
return T(diff);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -702,13 +702,13 @@ struct DiminishingReturn
|
||||
: DRGroup(group), stack(0), hitTime(t), hitCount(count)
|
||||
{}
|
||||
|
||||
DiminishingGroup DRGroup: 16;
|
||||
uint16 stack: 16;
|
||||
DiminishingGroup DRGroup;
|
||||
uint16 stack;
|
||||
uint32 hitTime;
|
||||
uint32 hitCount;
|
||||
};
|
||||
|
||||
enum MeleeHitOutcome
|
||||
enum MeleeHitOutcome : uint8
|
||||
{
|
||||
MELEE_HIT_EVADE, MELEE_HIT_MISS, MELEE_HIT_DODGE, MELEE_HIT_BLOCK, MELEE_HIT_PARRY,
|
||||
MELEE_HIT_GLANCING, MELEE_HIT_CRIT, MELEE_HIT_CRUSHING, MELEE_HIT_NORMAL
|
||||
@@ -761,11 +761,12 @@ private:
|
||||
uint32 m_absorb;
|
||||
uint32 m_resist;
|
||||
uint32 m_block;
|
||||
uint32 m_hitMask;
|
||||
uint32 m_cleanDamage;
|
||||
public:
|
||||
explicit DamageInfo(Unit* _attacker, Unit* _victim, uint32 _damage, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType, uint32 cleanDamage = 0);
|
||||
DamageInfo(Unit* attacker, Unit* victim, uint32 damage, SpellInfo const* spellInfo, SpellSchoolMask schoolMask, DamageEffectType damageType, WeaponAttackType attackType, uint32 cleanDamage = 0);
|
||||
explicit DamageInfo(CalcDamageInfo& dmgInfo);
|
||||
DamageInfo(SpellNonMeleeDamage const& spellNonMeleeDamage, DamageEffectType damageType);
|
||||
DamageInfo(SpellNonMeleeDamage const& spellNonMeleeDamage, DamageEffectType damageType, WeaponAttackType attackType, uint32 hitMask);
|
||||
|
||||
void ModifyDamage(int32 amount);
|
||||
void AbsorbDamage(uint32 amount);
|
||||
@@ -784,6 +785,7 @@ public:
|
||||
[[nodiscard]] uint32 GetBlock() const { return m_block; };
|
||||
|
||||
[[nodiscard]] uint32 GetUnmitigatedDamage() const;
|
||||
[[nodiscard]] uint32 GetHitMask() const;
|
||||
};
|
||||
|
||||
class HealInfo
|
||||
@@ -792,33 +794,33 @@ private:
|
||||
Unit* const m_healer;
|
||||
Unit* const m_target;
|
||||
uint32 m_heal;
|
||||
uint32 m_effectiveHeal;
|
||||
uint32 m_absorb;
|
||||
SpellInfo const* const m_spellInfo;
|
||||
SpellSchoolMask const m_schoolMask;
|
||||
uint32 m_hitMask;
|
||||
public:
|
||||
explicit HealInfo(Unit* _healer, Unit* _target, uint32 _heal, SpellInfo 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;
|
||||
}
|
||||
explicit HealInfo(Unit* healer, Unit* target, uint32 heal, SpellInfo const* spellInfo, SpellSchoolMask schoolMask);
|
||||
void AbsorbHeal(uint32 amount);
|
||||
|
||||
void SetHeal(uint32 amount)
|
||||
{
|
||||
m_heal = amount;
|
||||
}
|
||||
|
||||
void SetEffectiveHeal(uint32 amount)
|
||||
{
|
||||
m_effectiveHeal = amount;
|
||||
}
|
||||
|
||||
[[nodiscard]] Unit* GetHealer() const { return m_healer; }
|
||||
[[nodiscard]] Unit* GetTarget() const { return m_target; }
|
||||
[[nodiscard]] uint32 GetHeal() const { return m_heal; }
|
||||
[[nodiscard]] uint32 GetEffectiveHeal() const { return m_effectiveHeal; }
|
||||
[[nodiscard]] uint32 GetAbsorb() const { return m_absorb; }
|
||||
[[nodiscard]] SpellInfo const* GetSpellInfo() const { return m_spellInfo; };
|
||||
[[nodiscard]] SpellSchoolMask GetSchoolMask() const { return m_schoolMask; };
|
||||
[[nodiscard]] uint32 GetHitMask() const;
|
||||
};
|
||||
|
||||
class ProcEventInfo
|
||||
@@ -923,7 +925,7 @@ struct SpellPeriodicAuraLogInfo
|
||||
};
|
||||
|
||||
void createProcFlags(SpellInfo const* spellInfo, WeaponAttackType attackType, bool positive, uint32& procAttacker, uint32& procVictim);
|
||||
uint32 createProcExtendMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCondition);
|
||||
uint32 createProcHitMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCondition);
|
||||
|
||||
struct RedirectThreatInfo
|
||||
{
|
||||
@@ -1288,6 +1290,7 @@ public:
|
||||
typedef std::list<Aura*> AuraList;
|
||||
typedef std::list<AuraApplication*> AuraApplicationList;
|
||||
typedef std::list<DiminishingReturn> Diminishing;
|
||||
typedef std::vector<std::pair<uint8 /*procEffectMask*/, AuraApplication*>> AuraApplicationProcContainer;
|
||||
typedef GuidUnorderedSet ComboPointHolderSet;
|
||||
|
||||
typedef std::map<uint8, AuraApplication*> VisibleAuraMap;
|
||||
@@ -1439,10 +1442,10 @@ public:
|
||||
void setPowerType(Powers power);
|
||||
[[nodiscard]] uint32 GetPower(Powers power) const { return GetUInt32Value(static_cast<uint16>(UNIT_FIELD_POWER1) + power); }
|
||||
[[nodiscard]] uint32 GetMaxPower(Powers power) const { return GetUInt32Value(static_cast<uint16>(UNIT_FIELD_MAXPOWER1) + power); }
|
||||
void SetPower(Powers power, uint32 val, bool withPowerUpdate = true);
|
||||
void SetPower(Powers power, uint32 val);
|
||||
void SetMaxPower(Powers power, uint32 val);
|
||||
// returns the change in power
|
||||
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate = true);
|
||||
int32 ModifyPower(Powers power, int32 val);
|
||||
int32 ModifyPowerPct(Powers power, float pct, bool apply = true);
|
||||
|
||||
[[nodiscard]] uint32 GetAttackTime(WeaponAttackType att) const
|
||||
@@ -1526,16 +1529,15 @@ public:
|
||||
uint16 GetMaxSkillValueForLevel(Unit const* target = nullptr) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
|
||||
static void DealDamageMods(Unit const* victim, uint32& damage, uint32* absorb);
|
||||
static uint32 DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage = nullptr, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* spellProto = nullptr, bool durabilityLoss = true, bool allowGM = false, Spell const* spell = nullptr);
|
||||
static void Kill(Unit* killer, Unit* victim, bool durabilityLoss = true, WeaponAttackType attackType = BASE_ATTACK, SpellInfo const* spellProto = nullptr, Spell const* spell = nullptr);
|
||||
static int32 DealHeal(Unit* healer, Unit* victim, uint32 addhealth);
|
||||
static void Kill(Unit* killer, Unit* victim, bool durabilityLoss = true, WeaponAttackType attackType = BASE_ATTACK, SpellInfo const* spellProto = nullptr);
|
||||
static void DealHeal(HealInfo& healInfo);
|
||||
|
||||
static void ProcDamageAndSpell(Unit* actor, Unit* victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType = BASE_ATTACK, SpellInfo const* procSpellInfo = nullptr, SpellInfo const* procAura = nullptr, int8 procAuraEffectIndex = -1, Spell const* procSpell = nullptr, DamageInfo* damageInfo = nullptr, HealInfo* healInfo = nullptr, uint32 procPhase = 2 /*PROC_SPELL_PHASE_HIT*/);
|
||||
void ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellInfo const* procSpellInfo, uint32 damage, SpellInfo const* procAura = nullptr, int8 procAuraEffectIndex = -1, Spell const* procSpell = nullptr, DamageInfo* damageInfo = nullptr, HealInfo* healInfo = nullptr, uint32 procPhase = 2 /*PROC_SPELL_PHASE_HIT*/);
|
||||
void ProcSkillsAndAuras(Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo);
|
||||
|
||||
void GetProcAurasTriggeredOnEvent(std::list<AuraApplication*>& aurasTriggeringProc, std::list<AuraApplication*>* procAuras, ProcEventInfo eventInfo);
|
||||
void GetProcAurasTriggeredOnEvent(AuraApplicationProcContainer& aurasTriggeringProc, AuraApplicationList* 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 TriggerAurasProcOnEvent(Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo);
|
||||
void TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, AuraApplicationProcContainer& procAuras);
|
||||
|
||||
void HandleEmoteCommand(uint32 emoteId);
|
||||
void AttackerStateUpdate (Unit* victim, WeaponAttackType attType = BASE_ATTACK, bool extra = false, bool ignoreCasting = false);
|
||||
@@ -1543,12 +1545,7 @@ public:
|
||||
void CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* damageInfo, WeaponAttackType attackType = BASE_ATTACK, const bool sittingVictim = false);
|
||||
void DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss);
|
||||
|
||||
void HandleProcExtraAttackFor(Unit* victim, uint32 count);
|
||||
void SetLastExtraAttackSpell(uint32 spellId) { _lastExtraAttackSpell = spellId; }
|
||||
[[nodiscard]] uint32 GetLastExtraAttackSpell() const { return _lastExtraAttackSpell; }
|
||||
void AddExtraAttacks(uint32 count);
|
||||
void SetLastDamagedTargetGuid(ObjectGuid const& guid) { _lastDamagedTargetGuid = guid; }
|
||||
[[nodiscard]] ObjectGuid const& GetLastDamagedTargetGuid() const { return _lastDamagedTargetGuid; }
|
||||
void HandleProcExtraAttackFor(Unit* victim);
|
||||
|
||||
void CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = BASE_ATTACK, bool crit = false);
|
||||
void DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss, Spell const* spell = nullptr);
|
||||
@@ -1700,7 +1697,7 @@ public:
|
||||
[[nodiscard]] virtual bool IsUnderWater() const;
|
||||
bool isInAccessiblePlaceFor(Creature const* c) const;
|
||||
|
||||
void SendHealSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical = false);
|
||||
void SendHealSpellLog(HealInfo& healInfo, bool critical = false);
|
||||
int32 HealBySpell(HealInfo& healInfo, bool critical = false);
|
||||
void SendEnergizeSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, Powers powertype);
|
||||
void EnergizeBySpell(Unit* victim, uint32 SpellID, uint32 Damage, Powers powertype);
|
||||
@@ -2515,14 +2512,6 @@ protected:
|
||||
bool _instantCast;
|
||||
|
||||
private:
|
||||
bool IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo);
|
||||
bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, Spell const* spellProc = nullptr);
|
||||
bool HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool* handled);
|
||||
bool HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, uint32 procPhase, ProcEventInfo& eventInfo);
|
||||
bool HandleOverrideClassScriptAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 cooldown);
|
||||
bool HandleAuraRaidProcFromChargeWithValue(AuraEffect* triggeredByAura);
|
||||
bool HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura);
|
||||
|
||||
void UpdateSplineMovement(uint32 t_diff);
|
||||
void UpdateSplinePosition();
|
||||
|
||||
@@ -2530,6 +2519,8 @@ private:
|
||||
[[nodiscard]] float GetCombatRatingReduction(CombatRating cr) const;
|
||||
[[nodiscard]] uint32 GetCombatRatingDamageReduction(CombatRating cr, float rate, float cap, uint32 damage) const;
|
||||
|
||||
void ProcSkillsAndReactives(bool isVictim, Unit* procTarget, uint32 typeMask, uint32 hitMask, WeaponAttackType attType);
|
||||
|
||||
protected:
|
||||
void SetFeared(bool apply);
|
||||
void SetConfused(bool apply);
|
||||
@@ -2563,10 +2554,6 @@ private:
|
||||
bool _isWalkingBeforeCharm; ///< Are we walking before we were charmed?
|
||||
|
||||
[[nodiscard]] float processDummyAuras(float TakenTotalMod) const;
|
||||
|
||||
uint32 _lastExtraAttackSpell;
|
||||
std::unordered_map<ObjectGuid /*guid*/, uint32 /*count*/> extraAttacksTargets;
|
||||
ObjectGuid _lastDamagedTargetGuid;
|
||||
};
|
||||
|
||||
namespace Acore
|
||||
|
||||
Reference in New Issue
Block a user