Implementation of QAston proc system

This commit is contained in:
hondacrx
2017-08-14 08:12:31 -04:00
parent df8f6133b3
commit 9a039f35a2
23 changed files with 1083 additions and 1730 deletions
+14
View File
@@ -4289,10 +4289,24 @@ namespace Game.Entities
if (proto.GetFlags().HasAnyFlag(ItemFlags.NoEquipCooldown))
return;
DateTime now = DateTime.Now;
for (byte i = 0; i < proto.Effects.Count; ++i)
{
var effectData = proto.Effects[i];
// apply proc cooldown to equip auras if we have any
if (effectData.Trigger == ItemSpelltriggerType.OnEquip)
{
SpellProcEntry procEntry = Global.SpellMgr.GetSpellProcEntry(effectData.SpellID);
if (procEntry == null)
continue;
Aura itemAura = GetAura(effectData.SpellID, GetGUID(), pItem.GetGUID());
if (itemAura != null)
itemAura.AddProcCooldown(now + TimeSpan.FromMilliseconds(procEntry.Cooldown));
continue;
}
// no spell
if (effectData.SpellID == 0)
continue;
+143 -136
View File
@@ -1797,19 +1797,18 @@ namespace Game.Entities
return;
List<Aura> aurasQueue = new List<Aura>();
for (var i = 0; i < (int)SpellModOp.Max; ++i)
{
for (var j = 0; j < (int)SpellModType.End; ++j)
{
foreach (var mod in m_spellMods[i][j])
{
// spellmods without aura set cannot be charged
if (mod.ownerAura == null || !mod.ownerAura.IsUsingCharges())
// Spellmods without charged aura set cannot be charged
if (!mod.ownerAura.IsUsingCharges())
continue;
// Restore only specific owner aura mods
if (ownerAuraId != 0 && (ownerAuraId != mod.ownerAura.GetSpellInfo().Id))
if (ownerAuraId != 0 && mod.spellId != ownerAuraId)
continue;
if (aura != null && mod.ownerAura != aura)
@@ -1831,70 +1830,37 @@ namespace Game.Entities
// only see the first of its modifier restored)
aurasQueue.Add(mod.ownerAura);
// add mod charges back to mod
if (mod.charges == -1)
mod.charges = 1;
else
mod.charges++;
// Do not set more spellmods than avalible
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);
}
}
}
foreach (var removeAura in aurasQueue)
spell.m_appliedMods.Remove(aura);
}
public void RestoreAllSpellMods(uint ownerAuraId = 0, Aura aura = null)
{
for (CurrentSpellTypes i = 0; i < CurrentSpellTypes.Max; ++i)
{
var appliedMod = spell.m_appliedMods.Find(p => p == removeAura);
if (appliedMod != null)
spell.m_appliedMods.Remove(appliedMod);
Spell spell = m_currentSpells[i];
if (spell != null)
RestoreSpellMods(spell, ownerAuraId, aura);
}
}
public void RestoreAllSpellMods(uint ownerAuraId, Aura aura)
{
for (CurrentSpellTypes i = 0; i < CurrentSpellTypes.Max; ++i)
if (GetCurrentSpell(i) != null)
RestoreSpellMods(m_currentSpells[i], ownerAuraId, aura);
}
public void RemoveSpellMods(Spell spell)
public void ApplyModToSpell(SpellModifier mod, Spell spell)
{
if (spell == null)
return;
if (spell.m_appliedMods.Empty())
// don't do anything with no charges
if (mod.ownerAura.IsUsingCharges() && mod.ownerAura.GetCharges() == 0)
return;
for (var i = 0; i < (int)SpellModOp.Max; ++i)
{
for (var j = 0; j < (int)SpellModType.End; ++j)
{
for (var c = 0; c < m_spellMods[i][j].Count; c++)
{
SpellModifier mod = m_spellMods[i][j][c];
// spellmods without aura set cannot be charged
if (mod.ownerAura == null || !mod.ownerAura.IsUsingCharges())
continue;
// check if mod affected this spell
var iterMod = spell.m_appliedMods.Find(p => p == mod.ownerAura);
if (iterMod == null)
continue;
// remove from list
spell.m_appliedMods.Remove(iterMod);
if (mod.ownerAura.DropCharge(AuraRemoveMode.Expire))
c = 0;
}
}
}
// register inside spell, proc system uses this to drop charges
spell.m_appliedMods.Add(mod.ownerAura);
}
public void LearnCustomSpells()
@@ -2643,25 +2609,71 @@ namespace Game.Entities
if (m_spellModTakingSpell != null)
spell = m_spellModTakingSpell;
switch (op)
{
// special case, if a mod makes spell instant, only consume that mod
case SpellModOp.CastingTime:
{
SpellModifier modInstantSpell = null;
foreach (SpellModifier mod in m_spellMods[(int)op][(int)SpellModType.Pct])
{
if (!IsAffectedBySpellmod(spellInfo, mod, spell))
continue;
if (Convert.ToInt64(basevalue) < 10000 && mod.value <= -100)
{
modInstantSpell = mod;
break;
}
}
if (modInstantSpell != null)
{
ApplyModToSpell(modInstantSpell, spell);
basevalue = default(T);
return;
}
break;
}
// special case if two mods apply 100% critical chance, only consume one
case SpellModOp.CriticalChance:
{
SpellModifier modCritical = null;
foreach (SpellModifier mod in m_spellMods[(int)op][(int)SpellModType.Flat])
{
if (!IsAffectedBySpellmod(spellInfo, mod, spell))
continue;
if (mod.value >= 100)
{
modCritical = mod;
break;
}
}
if (modCritical != null)
{
ApplyModToSpell(modCritical, spell);
basevalue = (T)Convert.ChangeType(100, typeof(T));
return;
}
break;
}
default:
break;
}
foreach (var mod in m_spellMods[(int)op][(int)SpellModType.Flat])
{
// Charges can be set only for mods with auras
if (mod.ownerAura == null)
Contract.Assert(mod.charges == 0);
if (!IsAffectedBySpellmod(spellInfo, mod, spell))
continue;
totalflat += mod.value;
DropModCharge(mod, spell);
ApplyModToSpell(mod, spell);
}
foreach (var mod in m_spellMods[(int)op][(int)SpellModType.Pct])
{
// Charges can be set only for mods with auras
if (mod.ownerAura == null)
Contract.Assert(mod.charges == 0);
if (!IsAffectedBySpellmod(spellInfo, mod, spell))
continue;
@@ -2670,22 +2682,26 @@ namespace Game.Entities
continue;
// special case (skip > 10sec spell casts for instant cast setting)
if (mod.op == SpellModOp.CastingTime && Convert.ToInt64(basevalue) >= 10000 && mod.value <= -100)
continue;
if (op == SpellModOp.CastingTime)
{
if (Convert.ToInt32(basevalue) >= 10000 && mod.value <= -100)
continue;
}
totalmul *= 1.0f + MathFunctions.CalculatePct(1.0f, mod.value);
DropModCharge(mod, spell);
ApplyModToSpell(mod, spell);
}
basevalue = (T)Convert.ChangeType(((Convert.ToSingle(basevalue) + totalflat) * totalmul), typeof(T));
}
bool IsAffectedBySpellmod(SpellInfo spellInfo, SpellModifier mod, Spell spell)
{
if (mod == null || spellInfo == null)
return false;
// Mod out of charges
if (spell != null && mod.charges == -1 && !spell.m_appliedMods.Contains(mod.ownerAura))
// First time this aura applies a mod to us and is out of charges
if (spell && mod.ownerAura.IsUsingCharges() && mod.ownerAura.GetCharges() == 0 && !spell.m_appliedMods.Contains(mod.ownerAura))
return false;
// +duration to infinite duration spells making them limited
@@ -2694,21 +2710,6 @@ namespace Game.Entities
return spellInfo.IsAffectedBySpellMod(mod);
}
void DropModCharge(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 (Global.SpellMgr.GetSpellProcEvent(mod.spellId) != null)
return;
if (spell != null && mod.ownerAura != null && mod.charges > 0)
{
if (--mod.charges == 0)
mod.charges = -1;
spell.m_appliedMods.Add(mod.ownerAura);
}
}
public void SetSpellModTakingSpell(Spell spell, bool apply)
{
@@ -2992,10 +2993,62 @@ namespace Game.Entities
return false;
}
public void CastItemCombatSpell(Unit target, WeaponAttackType attType, ProcFlags procVictim, ProcFlagsExLegacy procEx, Item item, ItemTemplate proto)
public void CastItemCombatSpell(DamageInfo damageInfo)
{
Unit target = damageInfo.GetVictim();
if (target == null || !target.IsAlive() || target == this)
return;
for (byte i = EquipmentSlot.Start; i < EquipmentSlot.End; ++i)
{
// If usable, try to cast item spell
Item item = GetItemByPos(InventorySlots.Bag0, i);
if (item != null)
{
if (!item.IsBroken() && CanUseAttackType(damageInfo.GetAttackType()))
{
ItemTemplate proto = item.GetTemplate();
if (proto != null)
{
// Additional check for weapons
if (proto.GetClass() == ItemClass.Weapon)
{
// offhand item cannot proc from main hand hit etc
byte slot;
switch (damageInfo.GetAttackType())
{
case WeaponAttackType.BaseAttack:
case WeaponAttackType.RangedAttack:
slot = EquipmentSlot.MainHand;
break;
case WeaponAttackType.OffAttack:
slot = EquipmentSlot.OffHand;
break;
default:
slot = EquipmentSlot.End;
break;
}
if (slot != i)
continue;
// Check if item is useable (forms or disarm)
if (damageInfo.GetAttackType() == WeaponAttackType.BaseAttack)
if (!IsUseEquipedWeapon(true) && !IsInFeralForm())
continue;
}
CastItemCombatSpell(damageInfo, item, proto);
}
}
}
}
}
public void CastItemCombatSpell(DamageInfo damageInfo, Item item, ItemTemplate proto)
{
// Can do effect if any damage done to target
if (procVictim.HasAnyFlag(ProcFlags.TakenDamage))
// for done procs allow normal + critical + absorbs by default
bool canTrigger = damageInfo.GetHitMask().HasAnyFlag(ProcFlagsHit.Normal | ProcFlagsHit.Critical | ProcFlagsHit.Absorb);
if (canTrigger)
{
for (byte i = 0; i < proto.Effects.Count; ++i)
{
@@ -3024,14 +3077,14 @@ namespace Game.Entities
if (proto.SpellPPMRate != 0)
{
uint WeaponSpeed = GetBaseAttackTime(attType);
uint WeaponSpeed = GetBaseAttackTime(damageInfo.GetAttackType());
chance = GetPPMProcChance(WeaponSpeed, proto.SpellPPMRate, spellInfo);
}
else if (chance > 100.0f)
chance = GetWeaponProcChance();
if (RandomHelper.randChance(chance))
CastSpell(target, spellInfo.Id, true, item);
CastSpell(damageInfo.GetVictim(), spellInfo.Id, true, item);
}
}
@@ -3053,13 +3106,13 @@ namespace Game.Entities
if (entry != null && entry.procEx != 0)
{
// Check hit/crit/dodge/parry requirement
if ((entry.procEx & procEx) == 0)
if (((uint)entry.procEx & (uint)damageInfo.GetHitMask()) == 0)
continue;
}
else
{
// Can do effect if any damage done to target
if (!Convert.ToBoolean(procVictim & ProcFlags.TakenDamage))
// for done procs allow normal + critical + absorbs by default
if (!canTrigger)
continue;
}
@@ -3093,58 +3146,12 @@ namespace Game.Entities
if (spellInfo.IsPositive())
CastSpell(this, spellInfo, true, item);
else
CastSpell(target, spellInfo, true, item);
CastSpell(damageInfo.GetVictim(), spellInfo, true, item);
}
}
}
}
public void CastItemCombatSpell(Unit target, WeaponAttackType attType, ProcFlags procVictim, ProcFlagsExLegacy procEx)
{
if (target == null || !target.IsAlive() || target == this)
return;
for (byte i = EquipmentSlot.Start; i < EquipmentSlot.End; ++i)
{
// If usable, try to cast item spell
Item item = GetItemByPos(InventorySlots.Bag0, i);
if (item != null)
if (!item.IsBroken() && CanUseAttackType(attType))
{
ItemTemplate proto = item.GetTemplate();
if (proto != null)
{
// Additional check for weapons
if (proto.GetClass() == ItemClass.Weapon)
{
// offhand item cannot proc from main hand hit etc
byte slot;
switch (attType)
{
case WeaponAttackType.BaseAttack:
case WeaponAttackType.RangedAttack:
slot = EquipmentSlot.MainHand;
break;
case WeaponAttackType.OffAttack:
slot = EquipmentSlot.OffHand;
break;
default:
slot = EquipmentSlot.End;
break;
}
if (slot != i)
continue;
// Check if item is useable (forms or disarm)
if (attType == WeaponAttackType.BaseAttack)
if (!IsUseEquipedWeapon(true) && !IsInFeralForm())
continue;
}
CastItemCombatSpell(target, attType, procVictim, procEx, item, proto);
}
}
}
}
float GetWeaponProcChance()
{
// normalized proc chance for weapon attack speed
+25 -39
View File
@@ -595,7 +595,8 @@ namespace Game.Entities
DealDamageMods(victim, ref damageInfo.damage, ref damageInfo.absorb);
SendAttackStateUpdate(damageInfo);
ProcDamageAndSpell(damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, damageInfo.procEx, damageInfo.damage, damageInfo.attackType);
DamageInfo dmgInfo = new DamageInfo(damageInfo);
ProcSkillsAndAuras(damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, ProcFlagsSpellType.None, ProcFlagsSpellPhase.None, dmgInfo.GetHitMask(), null, dmgInfo, null);
DealMeleeDamage(damageInfo, true);
@@ -646,7 +647,6 @@ namespace Game.Entities
damageInfo.procAttacker = ProcFlags.None;
damageInfo.procVictim = ProcFlags.None;
damageInfo.procEx = ProcFlagsExLegacy.None;
damageInfo.hitOutCome = MeleeHitOutcome.Normal;
SendAttackStateUpdate(damageInfo);
@@ -808,7 +808,10 @@ namespace Game.Entities
}
if (IsTypeId(TypeId.Player))
ToPlayer().CastItemCombatSpell(victim, damageInfo.attackType, damageInfo.procVictim, damageInfo.procEx);
{
DamageInfo dmgInfo = new DamageInfo(damageInfo);
ToPlayer().CastItemCombatSpell(dmgInfo);
}
// Do effect if any damage done to target
if (damageInfo.damage != 0)
@@ -1431,16 +1434,17 @@ namespace Game.Entities
// Do KILL and KILLED procs. KILL proc is called only for the unit who landed the killing blow (and its owner - for pets and totems) regardless of who tapped the victim
if (IsPet() || IsTotem())
{
// proc only once for victim
Unit owner = GetOwner();
if (owner != null)
owner.ProcDamageAndSpell(victim, ProcFlags.Kill, ProcFlags.None, ProcFlagsExLegacy.None, 0);
owner.ProcSkillsAndAuras(victim, ProcFlags.Kill, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
}
if (!victim.IsCritter())
ProcDamageAndSpell(victim, ProcFlags.Kill, ProcFlags.Killed, ProcFlagsExLegacy.None, 0);
ProcSkillsAndAuras(victim, ProcFlags.Kill, ProcFlags.Killed, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
// Proc auras on death - must be before aura/combat remove
victim.ProcDamageAndSpell(null, ProcFlags.Death, ProcFlags.None, ProcFlagsExLegacy.None, 0, WeaponAttackType.BaseAttack, null);
victim.ProcSkillsAndAuras(victim, ProcFlags.None, ProcFlags.Death, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
// update get killing blow achievements, must be done before setDeathState to be able to require auras on target
// and before Spirit of Redemption as it also removes auras
@@ -1808,7 +1812,6 @@ namespace Game.Entities
damageInfo.HitInfo = 0;
damageInfo.procAttacker = ProcFlags.None;
damageInfo.procVictim = ProcFlags.None;
damageInfo.procEx = ProcFlagsExLegacy.None;
damageInfo.hitOutCome = MeleeHitOutcome.Evade;
if (victim == null)
@@ -1839,7 +1842,6 @@ namespace Game.Entities
damageInfo.HitInfo |= HitInfo.NormalSwing;
damageInfo.TargetState = VictimState.Immune;
damageInfo.procEx |= ProcFlagsExLegacy.Immune;
damageInfo.damage = 0;
damageInfo.cleanDamage = 0;
return;
@@ -1869,25 +1871,22 @@ namespace Game.Entities
case MeleeHitOutcome.Evade:
damageInfo.HitInfo |= HitInfo.Miss | HitInfo.SwingNoHitSound;
damageInfo.TargetState = VictimState.Evades;
damageInfo.procEx |= ProcFlagsExLegacy.Evade;
damageInfo.damage = 0;
damageInfo.cleanDamage = 0;
return;
case MeleeHitOutcome.Miss:
damageInfo.HitInfo |= HitInfo.Miss;
damageInfo.TargetState = VictimState.Intact;
damageInfo.procEx |= ProcFlagsExLegacy.Miss;
damageInfo.damage = 0;
damageInfo.cleanDamage = 0;
break;
case MeleeHitOutcome.Normal:
damageInfo.TargetState = VictimState.Hit;
damageInfo.procEx |= ProcFlagsExLegacy.NormalHit;
break;
case MeleeHitOutcome.Crit:
damageInfo.HitInfo |= HitInfo.CriticalHit;
damageInfo.TargetState = VictimState.Hit;
damageInfo.procEx |= ProcFlagsExLegacy.CriticalHit;
// Crit bonus calc
damageInfo.damage += damageInfo.damage;
float mod = 0.0f;
@@ -1905,19 +1904,16 @@ namespace Game.Entities
break;
case MeleeHitOutcome.Parry:
damageInfo.TargetState = VictimState.Parry;
damageInfo.procEx |= ProcFlagsExLegacy.Parry;
damageInfo.cleanDamage += damageInfo.damage;
damageInfo.damage = 0;
break;
case MeleeHitOutcome.Dodge:
damageInfo.TargetState = VictimState.Dodge;
damageInfo.procEx |= ProcFlagsExLegacy.Dodge;
damageInfo.cleanDamage += damageInfo.damage;
damageInfo.damage = 0;
break;
case MeleeHitOutcome.Block:
damageInfo.TargetState = VictimState.Hit;
damageInfo.procEx |= ProcFlagsExLegacy.Block | ProcFlagsExLegacy.NormalHit;
// 30% damage blocked, double blocked amount if block is critical
damageInfo.blocked_amount = MathFunctions.CalculatePct(damageInfo.damage, damageInfo.target.isBlockCritical() ? damageInfo.target.GetBlockPercent() * 2 : damageInfo.target.GetBlockPercent());
damageInfo.damage -= damageInfo.blocked_amount;
@@ -1926,7 +1922,6 @@ namespace Game.Entities
case MeleeHitOutcome.Glancing:
damageInfo.HitInfo |= HitInfo.Glancing;
damageInfo.TargetState = VictimState.Hit;
damageInfo.procEx |= ProcFlagsExLegacy.NormalHit;
int leveldif = (int)victim.getLevel() - (int)getLevel();
if (leveldif > 3)
leveldif = 3;
@@ -1938,7 +1933,6 @@ namespace Game.Entities
case MeleeHitOutcome.Crushing:
damageInfo.HitInfo |= HitInfo.Crushing;
damageInfo.TargetState = VictimState.Hit;
damageInfo.procEx |= ProcFlagsExLegacy.NormalHit;
// 150% normal damage
damageInfo.damage += (damageInfo.damage / 2);
break;
@@ -1965,10 +1959,7 @@ namespace Game.Entities
CalcAbsorbResist(damageInfo.target, (SpellSchoolMask)damageInfo.damageSchoolMask, DamageEffectType.Direct, damageInfo.damage, ref damageInfo.absorb, ref damageInfo.resist);
if (damageInfo.absorb != 0)
{
damageInfo.HitInfo |= (damageInfo.damage - damageInfo.absorb == 0 ? HitInfo.FullAbsorb : HitInfo.PartialAbsorb);
damageInfo.procEx |= ProcFlagsExLegacy.Absorb;
}
if (damageInfo.resist != 0)
damageInfo.HitInfo |= (damageInfo.damage - damageInfo.resist == 0 ? HitInfo.FullResist : HitInfo.PartialResist);
@@ -2437,7 +2428,7 @@ namespace Game.Entities
if (eff.GetAmount() >= 0)
{
// Reduce shield amount
eff.SetAmount(eff.GetAmount() - currentAbsorb);
eff.ChangeAmount(eff.GetAmount() - currentAbsorb);
// Aura cannot absorb anything more - remove it
if (eff.GetAmount() <= 0)
eff.GetBase().Remove(AuraRemoveMode.EnemySpell);
@@ -2498,7 +2489,7 @@ namespace Game.Entities
// Check if our aura is using amount to count damage
if (absorbAurEff.GetAmount() >= 0)
{
absorbAurEff.SetAmount(absorbAurEff.GetAmount() - currentAbsorb);
absorbAurEff.ChangeAmount(absorbAurEff.GetAmount() - currentAbsorb);
if ((absorbAurEff.GetAmount() <= 0))
absorbAurEff.GetBase().Remove(AuraRemoveMode.EnemySpell);
}
@@ -2558,7 +2549,8 @@ namespace Game.Entities
SendSpellNonMeleeDamageLog(log);
// break 'Fear' and similar auras
caster.ProcDamageAndSpellFor(true, this, ProcFlags.TakenSpellMagicDmgClassNeg, ProcFlagsExLegacy.NormalHit, WeaponAttackType.BaseAttack, eff.GetSpellInfo(), splitDamage);
DamageInfo damageInfo = new DamageInfo(caster, this, splitDamage, eff.GetSpellInfo(), schoolMask, DamageEffectType.Direct, WeaponAttackType.BaseAttack);
ProcSkillsAndAuras(caster, ProcFlags.None, ProcFlags.TakenSpellMagicDmgClassNeg, ProcFlagsSpellType.Damage, ProcFlagsSpellPhase.Hit, ProcFlagsHit.None, null, damageInfo, null);
}
}
@@ -2566,24 +2558,22 @@ namespace Game.Entities
absorb = dmgInfo.GetAbsorb();
}
public void CalcHealAbsorb(Unit victim, SpellInfo healSpell, ref uint healAmount, ref uint absorb)
public void CalcHealAbsorb(HealInfo healInfo)
{
if (healAmount == 0)
if (healInfo.GetHeal() == 0)
return;
int RemainingHeal = (int)healAmount;
// Need remove expired auras after
bool existExpired = false;
// absorb without mana cost
var vHealAbsorb = victim.GetAuraEffectsByType(AuraType.SchoolHealAbsorb);
var vHealAbsorb = healInfo.GetTarget().GetAuraEffectsByType(AuraType.SchoolHealAbsorb);
foreach (var eff in vHealAbsorb)
{
if (RemainingHeal <= 0)
if (healInfo.GetHeal() <= 0)
break;
if (!Convert.ToBoolean(eff.GetMiscValue() & (int)healSpell.SchoolMask))
if (!Convert.ToBoolean(eff.GetMiscValue() & (int)healInfo.GetSpellInfo().SchoolMask))
continue;
// Max Amount can be absorbed by this aura
@@ -2598,13 +2588,12 @@ namespace Game.Entities
// currentAbsorb - damage can be absorbed by shield
// If need absorb less damage
if (RemainingHeal < currentAbsorb)
currentAbsorb = RemainingHeal;
currentAbsorb = (int)Math.Min(healInfo.GetHeal(), currentAbsorb);
RemainingHeal -= currentAbsorb;
healInfo.AbsorbHeal((uint)currentAbsorb);
// Reduce shield amount
eff.SetAmount(eff.GetAmount() - currentAbsorb);
eff.ChangeAmount(eff.GetAmount() - currentAbsorb);
// Need remove it later
if (eff.GetAmount() <= 0)
existExpired = true;
@@ -2619,16 +2608,13 @@ namespace Game.Entities
++i;
if (auraEff.GetAmount() <= 0)
{
uint removedAuras = victim.m_removedAurasCount;
uint removedAuras = healInfo.GetTarget().m_removedAurasCount;
auraEff.GetBase().Remove(AuraRemoveMode.EnemySpell);
if (removedAuras + 1 < victim.m_removedAurasCount)
if (removedAuras + 1 < healInfo.GetTarget().m_removedAurasCount)
i = 0;
}
}
}
absorb = (uint)(RemainingHeal > 0 ? (healAmount - RemainingHeal) : healAmount);
healAmount = (uint)RemainingHeal;
}
public uint CalcArmorReducedDamage(Unit attacker, Unit victim, uint damage, SpellInfo spellInfo, WeaponAttackType attackType = WeaponAttackType.Max)
+26 -27
View File
@@ -154,23 +154,10 @@ namespace Game.Entities
public DiminishingLevels hitCount;
}
public class ProcTriggeredData
{
public ProcTriggeredData(Aura _aura)
{
aura = _aura;
effMask = 0;
spellProcEvent = null;
}
public SpellProcEventEntry spellProcEvent;
public Aura aura;
public uint effMask;
}
public class ProcEventInfo
{
public ProcEventInfo(Unit actor, Unit actionTarget, Unit procTarget, uint typeMask, uint spellTypeMask,
uint spellPhaseMask, uint hitMask, Spell spell, DamageInfo damageInfo, HealInfo healInfo)
public ProcEventInfo(Unit actor, Unit actionTarget, Unit procTarget, ProcFlags typeMask, ProcFlagsSpellType spellTypeMask,
ProcFlagsSpellPhase spellPhaseMask, ProcFlagsHit hitMask, Spell spell, DamageInfo damageInfo, HealInfo healInfo)
{
_actor = actor;
_actionTarget = actionTarget;
@@ -188,10 +175,10 @@ namespace Game.Entities
public Unit GetActionTarget() { return _actionTarget; }
public Unit GetProcTarget() { return _procTarget; }
public ProcFlags GetTypeMask() { return (ProcFlags)_typeMask; }
public ProcFlagsSpellType GetSpellTypeMask() { return (ProcFlagsSpellType)_spellTypeMask; }
public ProcFlagsSpellPhase GetSpellPhaseMask() { return (ProcFlagsSpellPhase)_spellPhaseMask; }
public ProcFlagsHit GetHitMask() { return (ProcFlagsHit)_hitMask; }
public ProcFlags GetTypeMask() { return _typeMask; }
public ProcFlagsSpellType GetSpellTypeMask() { return _spellTypeMask; }
public ProcFlagsSpellPhase GetSpellPhaseMask() { return _spellPhaseMask; }
public ProcFlagsHit GetHitMask() { return _hitMask; }
public SpellInfo GetSpellInfo()
{
@@ -221,13 +208,15 @@ namespace Game.Entities
public DamageInfo GetDamageInfo() { return _damageInfo; }
public HealInfo GetHealInfo() { return _healInfo; }
public Spell GetProcSpell() { return _spell; }
Unit _actor;
Unit _actionTarget;
Unit _procTarget;
uint _typeMask;
uint _spellTypeMask;
uint _spellPhaseMask;
uint _hitMask;
ProcFlags _typeMask;
ProcFlagsSpellType _spellTypeMask;
ProcFlagsSpellPhase _spellPhaseMask;
ProcFlagsHit _hitMask;
Spell _spell;
DamageInfo _damageInfo;
HealInfo _healInfo;
@@ -245,6 +234,7 @@ namespace Game.Entities
m_damageType = damageType;
m_attackType = attackType;
}
public DamageInfo(CalcDamageInfo dmgInfo)
{
m_attacker = dmgInfo.attacker;
@@ -291,11 +281,20 @@ namespace Game.Entities
case MeleeHitOutcome.Evade:
m_hitMask |= ProcFlagsHit.Evade;
break;
case MeleeHitOutcome.Crushing:
case MeleeHitOutcome.Glancing:
case MeleeHitOutcome.Normal:
m_hitMask |= ProcFlagsHit.Normal;
break;
case MeleeHitOutcome.Crit:
m_hitMask |= ProcFlagsHit.Critical;
break;
default:
break;
}
}
public DamageInfo(SpellNonMeleeDamage spellNonMeleeDamage, DamageEffectType damageType, WeaponAttackType attackType)
public DamageInfo(SpellNonMeleeDamage spellNonMeleeDamage, DamageEffectType damageType, WeaponAttackType attackType, ProcFlagsHit hitMask)
{
m_attacker = spellNonMeleeDamage.attacker;
m_victim = spellNonMeleeDamage.target;
@@ -307,6 +306,7 @@ namespace Game.Entities
m_absorb = spellNonMeleeDamage.absorb;
m_resist = spellNonMeleeDamage.resist;
m_block = spellNonMeleeDamage.blocked;
m_hitMask = hitMask;
if (spellNonMeleeDamage.blocked != 0)
m_hitMask |= ProcFlagsHit.Block;
@@ -354,7 +354,7 @@ namespace Game.Entities
public uint GetAbsorb() { return m_absorb; }
public uint GetResist() { return m_resist; }
uint GetBlock() { return m_block; }
ProcFlagsHit GetHitMask() { return m_hitMask; }
public ProcFlagsHit GetHitMask() { return m_hitMask; }
Unit m_attacker;
Unit m_victim;
@@ -380,7 +380,7 @@ namespace Game.Entities
_schoolMask = schoolMask;
}
void AbsorbHeal(uint amount)
public void AbsorbHeal(uint amount)
{
amount = Math.Min(amount, GetHeal());
_absorb += amount;
@@ -425,7 +425,6 @@ namespace Game.Entities
public WeaponAttackType attackType { get; set; }
public ProcFlags procAttacker { get; set; }
public ProcFlags procVictim { get; set; }
public ProcFlagsExLegacy procEx { get; set; }
public uint cleanDamage { get; set; } // Used only for rage calculation
public MeleeHitOutcome hitOutCome { get; set; } // TODO: remove this field (need use TargetState)
}
File diff suppressed because it is too large Load Diff