Misc Fixes
This commit is contained in:
@@ -25,6 +25,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
public class RealmManager : Singleton<RealmManager>
|
public class RealmManager : Singleton<RealmManager>
|
||||||
{
|
{
|
||||||
@@ -48,14 +49,8 @@ public class RealmManager : Singleton<RealmManager>
|
|||||||
void UpdateRealm(Realm realm)
|
void UpdateRealm(Realm realm)
|
||||||
{
|
{
|
||||||
var oldRealm = _realms.LookupByKey(realm.Id);
|
var oldRealm = _realms.LookupByKey(realm.Id);
|
||||||
if (oldRealm == null)
|
if (oldRealm != null && oldRealm == realm)
|
||||||
{
|
return;
|
||||||
_realms[realm.Id] = realm;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oldRealm == realm)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_realms[realm.Id] = realm;
|
_realms[realm.Id] = realm;
|
||||||
}
|
}
|
||||||
@@ -323,7 +318,7 @@ public class RealmManager : Singleton<RealmManager>
|
|||||||
public List<Realm> GetRealms() { return _realms.Values.ToList(); }
|
public List<Realm> GetRealms() { return _realms.Values.ToList(); }
|
||||||
List<string> GetSubRegions() { return _subRegions; }
|
List<string> GetSubRegions() { return _subRegions; }
|
||||||
|
|
||||||
Dictionary<RealmHandle, Realm> _realms = new Dictionary<RealmHandle, Realm>();
|
ConcurrentDictionary<RealmHandle, Realm> _realms = new ConcurrentDictionary<RealmHandle, Realm>();
|
||||||
List<string> _subRegions = new List<string>();
|
List<string> _subRegions = new List<string>();
|
||||||
Timer _updateTimer;
|
Timer _updateTimer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -432,6 +432,9 @@ namespace Game.AI
|
|||||||
|
|
||||||
public virtual void MovementInform(MovementGeneratorType type, uint id) { }
|
public virtual void MovementInform(MovementGeneratorType type, uint id) { }
|
||||||
|
|
||||||
|
// Called when a spell cast gets interrupted
|
||||||
|
public virtual void OnSpellCastInterrupt(SpellInfo spell) { }
|
||||||
|
|
||||||
// Called at reaching home after evade
|
// Called at reaching home after evade
|
||||||
public virtual void JustReachedHome() { }
|
public virtual void JustReachedHome() { }
|
||||||
|
|
||||||
|
|||||||
@@ -718,6 +718,10 @@ namespace Game.Arenas
|
|||||||
|
|
||||||
foreach (var member in Members)
|
foreach (var member in Members)
|
||||||
{
|
{
|
||||||
|
// Save the effort and go
|
||||||
|
if (member.WeekGames == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_ARENA_TEAM_MEMBER);
|
stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_ARENA_TEAM_MEMBER);
|
||||||
stmt.AddValue(0, member.PersonalRating);
|
stmt.AddValue(0, member.PersonalRating);
|
||||||
stmt.AddValue(1, member.WeekGames);
|
stmt.AddValue(1, member.WeekGames);
|
||||||
@@ -738,8 +742,12 @@ namespace Game.Arenas
|
|||||||
DB.Characters.CommitTransaction(trans);
|
DB.Characters.CommitTransaction(trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FinishWeek()
|
public bool FinishWeek()
|
||||||
{
|
{
|
||||||
|
// No need to go further than this
|
||||||
|
if (stats.WeekGames == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Reset team stats
|
// Reset team stats
|
||||||
stats.WeekGames = 0;
|
stats.WeekGames = 0;
|
||||||
stats.WeekWins = 0;
|
stats.WeekWins = 0;
|
||||||
@@ -750,6 +758,8 @@ namespace Game.Arenas
|
|||||||
member.WeekGames = 0;
|
member.WeekGames = 0;
|
||||||
member.WeekWins = 0;
|
member.WeekWins = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsFighting()
|
public bool IsFighting()
|
||||||
|
|||||||
@@ -2055,19 +2055,20 @@ namespace Game.Chat
|
|||||||
// melee damage by specific school
|
// melee damage by specific school
|
||||||
if (string.IsNullOrEmpty(spellStr))
|
if (string.IsNullOrEmpty(spellStr))
|
||||||
{
|
{
|
||||||
uint absorb = 0;
|
Player attacker = handler.GetSession().GetPlayer();
|
||||||
uint resist = 0;
|
DamageInfo dmgInfo = new DamageInfo(attacker, target, damage_, null, schoolmask, DamageEffectType.SpellDirect, WeaponAttackType.BaseAttack);
|
||||||
|
attacker.CalcAbsorbResist(dmgInfo);
|
||||||
|
|
||||||
handler.GetSession().GetPlayer().CalcAbsorbResist(target, schoolmask, DamageEffectType.SpellDirect, damage_, ref absorb, ref resist);
|
if (dmgInfo.GetDamage() == 0)
|
||||||
|
|
||||||
if (damage_ <= absorb + resist)
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
damage_ -= absorb + resist;
|
damage_ = dmgInfo.GetDamage();
|
||||||
|
|
||||||
handler.GetSession().GetPlayer().DealDamageMods(target, ref damage_, ref absorb);
|
uint absorb = dmgInfo.GetAbsorb();
|
||||||
handler.GetSession().GetPlayer().DealDamage(target, damage_, null, DamageEffectType.Direct, schoolmask, null, false);
|
uint resist = dmgInfo.GetResist();
|
||||||
handler.GetSession().GetPlayer().SendAttackStateUpdate(HitInfo.AffectsVictim, target, schoolmask, damage_, absorb, resist, VictimState.Hit, 0);
|
attacker.DealDamageMods(target, ref damage_, ref absorb);
|
||||||
|
attacker.DealDamage(target, damage_, null, DamageEffectType.Direct, schoolmask, null, false);
|
||||||
|
attacker.SendAttackStateUpdate(HitInfo.AffectsVictim, target, schoolmask, damage_, absorb, resist, VictimState.Hit, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1045,7 +1045,10 @@ namespace Game.Entities
|
|||||||
if (quest.RewardSpell > 0)
|
if (quest.RewardSpell > 0)
|
||||||
{
|
{
|
||||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.RewardSpell);
|
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.RewardSpell);
|
||||||
if (questGiver.isTypeMask(TypeMask.Unit) && !spellInfo.HasEffect(Difficulty.None, SpellEffectName.LearnSpell) && !spellInfo.HasEffect(Difficulty.None, SpellEffectName.CreateItem) && !spellInfo.HasEffect(Difficulty.None, SpellEffectName.ApplyAura))
|
if (questGiver && questGiver.isTypeMask(TypeMask.Unit)
|
||||||
|
&& !spellInfo.HasEffect(Difficulty.None, SpellEffectName.LearnSpell)
|
||||||
|
&& !spellInfo.HasEffect(Difficulty.None, SpellEffectName.CreateItem)
|
||||||
|
&& !spellInfo.HasEffect(Difficulty.None, SpellEffectName.ApplyAura))
|
||||||
{
|
{
|
||||||
Unit unit = questGiver.ToUnit();
|
Unit unit = questGiver.ToUnit();
|
||||||
if (unit)
|
if (unit)
|
||||||
@@ -1061,7 +1064,9 @@ namespace Game.Entities
|
|||||||
if (quest.RewardDisplaySpell[i] > 0)
|
if (quest.RewardDisplaySpell[i] > 0)
|
||||||
{
|
{
|
||||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.RewardDisplaySpell[i]);
|
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.RewardDisplaySpell[i]);
|
||||||
if (questGiver.IsTypeId(TypeId.Unit) && !spellInfo.HasEffect(Difficulty.None, SpellEffectName.LearnSpell) && !spellInfo.HasEffect(Difficulty.None, SpellEffectName.CreateItem))
|
if (questGiver && questGiver.IsTypeId(TypeId.Unit)
|
||||||
|
&& !spellInfo.HasEffect(Difficulty.None, SpellEffectName.LearnSpell)
|
||||||
|
&& !spellInfo.HasEffect(Difficulty.None, SpellEffectName.CreateItem))
|
||||||
{
|
{
|
||||||
Unit unit = questGiver.ToUnit();
|
Unit unit = questGiver.ToUnit();
|
||||||
if (unit)
|
if (unit)
|
||||||
@@ -2639,7 +2644,10 @@ namespace Game.Entities
|
|||||||
public void SetQuestObjectiveData(QuestObjective objective, int data)
|
public void SetQuestObjectiveData(QuestObjective objective, int data)
|
||||||
{
|
{
|
||||||
if (objective.StorageIndex < 0)
|
if (objective.StorageIndex < 0)
|
||||||
|
{
|
||||||
Log.outError(LogFilter.Player, "SetQuestObjectiveData: called for quest {0} with invalid StorageIndex {1} (objective data is not tracked)", objective.QuestID, objective.StorageIndex);
|
Log.outError(LogFilter.Player, "SetQuestObjectiveData: called for quest {0} with invalid StorageIndex {1} (objective data is not tracked)", objective.QuestID, objective.StorageIndex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var status = m_QuestStatus.LookupByKey(objective.QuestID);
|
var status = m_QuestStatus.LookupByKey(objective.QuestID);
|
||||||
if (status == null)
|
if (status == null)
|
||||||
|
|||||||
@@ -4157,12 +4157,17 @@ namespace Game.Entities
|
|||||||
// Absorb, resist some environmental damage type
|
// Absorb, resist some environmental damage type
|
||||||
uint absorb = 0;
|
uint absorb = 0;
|
||||||
uint resist = 0;
|
uint resist = 0;
|
||||||
if (type == EnviromentalDamage.Lava)
|
switch (type)
|
||||||
CalcAbsorbResist(this, SpellSchoolMask.Fire, DamageEffectType.Direct, damage, ref absorb, ref resist);
|
{
|
||||||
else if (type == EnviromentalDamage.Slime)
|
case EnviromentalDamage.Lava:
|
||||||
CalcAbsorbResist(this, SpellSchoolMask.Nature, DamageEffectType.Direct, damage, ref absorb, ref resist);
|
case EnviromentalDamage.Slime:
|
||||||
|
DamageInfo dmgInfo = new DamageInfo(this, this, damage, null, type == EnviromentalDamage.Lava ? SpellSchoolMask.Fire : SpellSchoolMask.Nature, DamageEffectType.Direct, WeaponAttackType.BaseAttack);
|
||||||
damage -= absorb + resist;
|
CalcAbsorbResist(dmgInfo);
|
||||||
|
absorb = dmgInfo.GetAbsorb();
|
||||||
|
resist = dmgInfo.GetResist();
|
||||||
|
damage = dmgInfo.GetDamage();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
DealDamageMods(this, ref damage, ref absorb);
|
DealDamageMods(this, ref damage, ref absorb);
|
||||||
|
|
||||||
|
|||||||
+102
-108
@@ -844,9 +844,9 @@ namespace Game.Entities
|
|||||||
damage = SpellDamageBonusTaken(caster, i_spellProto, damage, DamageEffectType.SpellDirect, dmgShield.GetSpellEffectInfo());
|
damage = SpellDamageBonusTaken(caster, i_spellProto, damage, DamageEffectType.SpellDirect, dmgShield.GetSpellEffectInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint absorb = 0;
|
DamageInfo damageInfo1 = new DamageInfo(this, victim, damage, i_spellProto, i_spellProto.GetSchoolMask(), DamageEffectType.SpellDirect, WeaponAttackType.BaseAttack);
|
||||||
uint resist = 0;
|
victim.CalcAbsorbResist(damageInfo1);
|
||||||
victim.CalcAbsorbResist(this, i_spellProto.SchoolMask, DamageEffectType.SpellDirect, damage, ref absorb, ref resist, i_spellProto);
|
damage = damageInfo1.GetDamage();
|
||||||
// No Unit.CalcAbsorbResist here - opcode doesn't send that data - this damage is probably not affected by that
|
// No Unit.CalcAbsorbResist here - opcode doesn't send that data - this damage is probably not affected by that
|
||||||
victim.DealDamageMods(this, ref damage);
|
victim.DealDamageMods(this, ref damage);
|
||||||
|
|
||||||
@@ -857,7 +857,7 @@ namespace Game.Entities
|
|||||||
damageShield.TotalDamage = damage;
|
damageShield.TotalDamage = damage;
|
||||||
damageShield.OverKill = (uint)Math.Max(damage - GetHealth(), 0);
|
damageShield.OverKill = (uint)Math.Max(damage - GetHealth(), 0);
|
||||||
damageShield.SchoolMask = (uint)i_spellProto.SchoolMask;
|
damageShield.SchoolMask = (uint)i_spellProto.SchoolMask;
|
||||||
damageShield.LogAbsorbed = absorb;
|
damageShield.LogAbsorbed = damageInfo1.GetAbsorb();
|
||||||
|
|
||||||
victim.DealDamage(this, damage, null, DamageEffectType.SpellDirect, i_spellProto.GetSchoolMask(), i_spellProto, true);
|
victim.DealDamage(this, damage, null, DamageEffectType.SpellDirect, i_spellProto.GetSchoolMask(), i_spellProto, true);
|
||||||
damageShield.LogData.Initialize(this);
|
damageShield.LogData.Initialize(this);
|
||||||
@@ -1924,15 +1924,17 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
damageInfo.procVictim |= ProcFlags.TakenDamage;
|
damageInfo.procVictim |= ProcFlags.TakenDamage;
|
||||||
// Calculate absorb & resists
|
// Calculate absorb & resists
|
||||||
CalcAbsorbResist(damageInfo.target, (SpellSchoolMask)damageInfo.damageSchoolMask, DamageEffectType.Direct, damageInfo.damage, ref damageInfo.absorb, ref damageInfo.resist);
|
DamageInfo dmgInfo = new DamageInfo(damageInfo);
|
||||||
|
CalcAbsorbResist(dmgInfo);
|
||||||
|
damageInfo.absorb = dmgInfo.GetAbsorb();
|
||||||
|
damageInfo.resist = dmgInfo.GetResist();
|
||||||
|
damageInfo.damage = dmgInfo.GetDamage();
|
||||||
|
|
||||||
if (damageInfo.absorb != 0)
|
if (damageInfo.absorb != 0)
|
||||||
damageInfo.HitInfo |= (damageInfo.damage - damageInfo.absorb == 0 ? HitInfo.FullAbsorb : HitInfo.PartialAbsorb);
|
damageInfo.HitInfo |= (damageInfo.damage - damageInfo.absorb == 0 ? HitInfo.FullAbsorb : HitInfo.PartialAbsorb);
|
||||||
|
|
||||||
if (damageInfo.resist != 0)
|
if (damageInfo.resist != 0)
|
||||||
damageInfo.HitInfo |= (damageInfo.damage - damageInfo.resist == 0 ? HitInfo.FullResist : HitInfo.PartialResist);
|
damageInfo.HitInfo |= (damageInfo.damage - damageInfo.resist == 0 ? HitInfo.FullResist : HitInfo.PartialResist);
|
||||||
|
|
||||||
damageInfo.damage -= damageInfo.absorb + damageInfo.resist;
|
|
||||||
}
|
}
|
||||||
else // Impossible get negative result but....
|
else // Impossible get negative result but....
|
||||||
damageInfo.damage = 0;
|
damageInfo.damage = 0;
|
||||||
@@ -2314,105 +2316,51 @@ namespace Game.Entities
|
|||||||
return resistance * 10;
|
return resistance * 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CalcAbsorbResist(Unit victim, SpellSchoolMask schoolMask, DamageEffectType damagetype, uint damage, ref uint absorb, ref uint resist, SpellInfo spellInfo = null)
|
public void CalcAbsorbResist(DamageInfo damageInfo)
|
||||||
{
|
{
|
||||||
if (victim == null || !victim.IsAlive() || damage == 0)
|
if (!damageInfo.GetVictim() || !damageInfo.GetVictim().IsAlive() || damageInfo.GetDamage() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DamageInfo dmgInfo = new DamageInfo(this, victim, damage, spellInfo, schoolMask, damagetype, WeaponAttackType.BaseAttack);
|
uint spellResistance = CalcSpellResistance(damageInfo.GetVictim(), damageInfo.GetSchoolMask(), damageInfo.GetSpellInfo());
|
||||||
|
damageInfo.ResistDamage(MathFunctions.CalculatePct(damageInfo.GetDamage(), spellResistance));
|
||||||
uint spellResistance = CalcSpellResistance(victim, schoolMask, spellInfo);
|
|
||||||
dmgInfo.ResistDamage(MathFunctions.CalculatePct(damage, spellResistance));
|
|
||||||
|
|
||||||
// Ignore Absorption Auras
|
// Ignore Absorption Auras
|
||||||
float auraAbsorbMod = 0;
|
float auraAbsorbMod = GetMaxPositiveAuraModifierByMiscMask(AuraType.ModTargetAbsorbSchool, (uint)damageInfo.GetSchoolMask());
|
||||||
var AbsIgnoreAurasA = GetAuraEffectsByType(AuraType.ModTargetAbsorbSchool);
|
|
||||||
foreach (var eff in AbsIgnoreAurasA)
|
var abilityAbsorbAuras = GetAuraEffectsByType(AuraType.ModTargetAbilityAbsorbSchool);
|
||||||
|
foreach (AuraEffect aurEff in abilityAbsorbAuras)
|
||||||
{
|
{
|
||||||
if (!Convert.ToBoolean(eff.GetMiscValue() & (int)schoolMask))
|
if (!Convert.ToBoolean(aurEff.GetMiscValue() & (int)damageInfo.GetSchoolMask()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (eff.GetAmount() > auraAbsorbMod)
|
if (!aurEff.IsAffectingSpell(damageInfo.GetSpellInfo()))
|
||||||
auraAbsorbMod = eff.GetAmount();
|
|
||||||
}
|
|
||||||
|
|
||||||
var AbsIgnoreAurasB = GetAuraEffectsByType(AuraType.ModTargetAbilityAbsorbSchool);
|
|
||||||
foreach (var eff in AbsIgnoreAurasB)
|
|
||||||
{
|
|
||||||
if (!Convert.ToBoolean(eff.GetMiscValue() & (int)schoolMask))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((eff.GetAmount() > auraAbsorbMod) && eff.IsAffectingSpell(spellInfo))
|
if ((aurEff.GetAmount() > auraAbsorbMod))
|
||||||
auraAbsorbMod = eff.GetAmount();
|
auraAbsorbMod = aurEff.GetAmount();
|
||||||
}
|
}
|
||||||
|
|
||||||
MathFunctions.RoundToInterval(ref auraAbsorbMod, 0.0f, 100.0f);
|
MathFunctions.RoundToInterval(ref auraAbsorbMod, 0.0f, 100.0f);
|
||||||
|
|
||||||
int absorbIgnoringDamage = (int)MathFunctions.CalculatePct(dmgInfo.GetDamage(), auraAbsorbMod);
|
int absorbIgnoringDamage = (int)MathFunctions.CalculatePct(damageInfo.GetDamage(), auraAbsorbMod);
|
||||||
dmgInfo.ModifyDamage(-absorbIgnoringDamage);
|
damageInfo.ModifyDamage(-absorbIgnoringDamage);
|
||||||
|
|
||||||
// We're going to call functions which can modify content of the list during iteration over it's elements
|
// We're going to call functions which can modify content of the list during iteration over it's elements
|
||||||
// Let's copy the list so we can prevent iterator invalidation
|
// Let's copy the list so we can prevent iterator invalidation
|
||||||
var vSchoolAbsorbCopy = victim.GetAuraEffectsByType(AuraType.SchoolAbsorb);
|
var vSchoolAbsorbCopy = damageInfo.GetVictim().GetAuraEffectsByType(AuraType.SchoolAbsorb);
|
||||||
vSchoolAbsorbCopy.Sort(new AbsorbAuraOrderPred());
|
vSchoolAbsorbCopy.Sort(new AbsorbAuraOrderPred());
|
||||||
|
|
||||||
// absorb without mana cost
|
// absorb without mana cost
|
||||||
foreach (var eff in vSchoolAbsorbCopy)
|
foreach (var absorbAurEff in vSchoolAbsorbCopy)
|
||||||
{
|
{
|
||||||
// Check if aura was removed during iteration - we don't need to work on such auras
|
if (damageInfo.GetDamage() == 0)
|
||||||
AuraApplication aurApp = eff.GetBase().GetApplicationOfTarget(victim.GetGUID());
|
|
||||||
if (aurApp == null)
|
|
||||||
continue;
|
|
||||||
if (!Convert.ToBoolean(eff.GetMiscValue() & (int)schoolMask))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// get amount which can be still absorbed by the aura
|
|
||||||
int currentAbsorb = eff.GetAmount();
|
|
||||||
// aura with infinite absorb amount - let the scripts handle absorbtion amount, set here to 0 for safety
|
|
||||||
if (currentAbsorb < 0)
|
|
||||||
currentAbsorb = 0;
|
|
||||||
|
|
||||||
uint tempAbsorb = (uint)currentAbsorb;
|
|
||||||
|
|
||||||
bool defaultPrevented = false;
|
|
||||||
|
|
||||||
eff.GetBase().CallScriptEffectAbsorbHandlers(eff, aurApp, dmgInfo, ref tempAbsorb, ref defaultPrevented);
|
|
||||||
currentAbsorb = (int)tempAbsorb;
|
|
||||||
|
|
||||||
if (defaultPrevented)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// absorb must be smaller than the damage itself
|
|
||||||
MathFunctions.RoundToInterval(ref currentAbsorb, 0, dmgInfo.GetDamage());
|
|
||||||
|
|
||||||
dmgInfo.AbsorbDamage((uint)currentAbsorb);
|
|
||||||
|
|
||||||
tempAbsorb = (uint)currentAbsorb;
|
|
||||||
eff.GetBase().CallScriptEffectAfterAbsorbHandlers(eff, aurApp, dmgInfo, ref tempAbsorb);
|
|
||||||
|
|
||||||
// Check if our aura is using amount to count damage
|
|
||||||
if (eff.GetAmount() >= 0)
|
|
||||||
{
|
|
||||||
// Reduce shield amount
|
|
||||||
eff.ChangeAmount(eff.GetAmount() - currentAbsorb);
|
|
||||||
// Aura cannot absorb anything more - remove it
|
|
||||||
if (eff.GetAmount() <= 0)
|
|
||||||
eff.GetBase().Remove(AuraRemoveMode.EnemySpell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// absorb by mana cost
|
|
||||||
var vManaShieldCopy = victim.GetAuraEffectsByType(AuraType.ManaShield);
|
|
||||||
foreach (var absorbAurEff in vManaShieldCopy)
|
|
||||||
{
|
|
||||||
if (dmgInfo.GetDamage() <= 0)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Check if aura was removed during iteration - we don't need to work on such auras
|
// Check if aura was removed during iteration - we don't need to work on such auras
|
||||||
AuraApplication aurApp = absorbAurEff.GetBase().GetApplicationOfTarget(victim.GetGUID());
|
AuraApplication aurApp = absorbAurEff.GetBase().GetApplicationOfTarget(damageInfo.GetVictim().GetGUID());
|
||||||
if (aurApp == null)
|
if (aurApp == null)
|
||||||
continue;
|
continue;
|
||||||
// check damage school mask
|
if (!Convert.ToBoolean(absorbAurEff.GetMiscValue() & (int)damageInfo.GetSchoolMask()))
|
||||||
if (!Convert.ToBoolean(absorbAurEff.GetMiscValue() & (int)schoolMask))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// get amount which can be still absorbed by the aura
|
// get amount which can be still absorbed by the aura
|
||||||
@@ -2425,14 +2373,64 @@ namespace Game.Entities
|
|||||||
|
|
||||||
bool defaultPrevented = false;
|
bool defaultPrevented = false;
|
||||||
|
|
||||||
absorbAurEff.GetBase().CallScriptEffectManaShieldHandlers(absorbAurEff, aurApp, dmgInfo, ref tempAbsorb, defaultPrevented);
|
absorbAurEff.GetBase().CallScriptEffectAbsorbHandlers(absorbAurEff, aurApp, damageInfo, ref tempAbsorb, ref defaultPrevented);
|
||||||
currentAbsorb = (int)tempAbsorb;
|
currentAbsorb = (int)tempAbsorb;
|
||||||
|
|
||||||
if (defaultPrevented)
|
if (defaultPrevented)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// absorb must be smaller than the damage itself
|
// absorb must be smaller than the damage itself
|
||||||
MathFunctions.RoundToInterval(ref currentAbsorb, 0, dmgInfo.GetDamage());
|
currentAbsorb = MathFunctions.RoundToInterval(ref currentAbsorb, 0, damageInfo.GetDamage());
|
||||||
|
|
||||||
|
damageInfo.AbsorbDamage((uint)currentAbsorb);
|
||||||
|
|
||||||
|
tempAbsorb = (uint)currentAbsorb;
|
||||||
|
absorbAurEff.GetBase().CallScriptEffectAfterAbsorbHandlers(absorbAurEff, aurApp, damageInfo, ref tempAbsorb);
|
||||||
|
|
||||||
|
// Check if our aura is using amount to count damage
|
||||||
|
if (absorbAurEff.GetAmount() >= 0)
|
||||||
|
{
|
||||||
|
// Reduce shield amount
|
||||||
|
absorbAurEff.ChangeAmount(absorbAurEff.GetAmount() - currentAbsorb);
|
||||||
|
// Aura cannot absorb anything more - remove it
|
||||||
|
if (absorbAurEff.GetAmount() <= 0)
|
||||||
|
absorbAurEff.GetBase().Remove(AuraRemoveMode.EnemySpell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// absorb by mana cost
|
||||||
|
var vManaShieldCopy = damageInfo.GetVictim().GetAuraEffectsByType(AuraType.ManaShield);
|
||||||
|
foreach (var absorbAurEff in vManaShieldCopy)
|
||||||
|
{
|
||||||
|
if (damageInfo.GetDamage() == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Check if aura was removed during iteration - we don't need to work on such auras
|
||||||
|
AuraApplication aurApp = absorbAurEff.GetBase().GetApplicationOfTarget(damageInfo.GetVictim().GetGUID());
|
||||||
|
if (aurApp == null)
|
||||||
|
continue;
|
||||||
|
// check damage school mask
|
||||||
|
if (!Convert.ToBoolean(absorbAurEff.GetMiscValue() & (int)damageInfo.GetSchoolMask()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// get amount which can be still absorbed by the aura
|
||||||
|
int currentAbsorb = absorbAurEff.GetAmount();
|
||||||
|
// aura with infinite absorb amount - let the scripts handle absorbtion amount, set here to 0 for safety
|
||||||
|
if (currentAbsorb < 0)
|
||||||
|
currentAbsorb = 0;
|
||||||
|
|
||||||
|
uint tempAbsorb = (uint)currentAbsorb;
|
||||||
|
|
||||||
|
bool defaultPrevented = false;
|
||||||
|
|
||||||
|
absorbAurEff.GetBase().CallScriptEffectManaShieldHandlers(absorbAurEff, aurApp, damageInfo, ref tempAbsorb, defaultPrevented);
|
||||||
|
currentAbsorb = (int)tempAbsorb;
|
||||||
|
|
||||||
|
if (defaultPrevented)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// absorb must be smaller than the damage itself
|
||||||
|
currentAbsorb = MathFunctions.RoundToInterval(ref currentAbsorb, 0, damageInfo.GetDamage());
|
||||||
|
|
||||||
int manaReduction = currentAbsorb;
|
int manaReduction = currentAbsorb;
|
||||||
|
|
||||||
@@ -2441,15 +2439,15 @@ namespace Game.Entities
|
|||||||
if (manaMultiplier != 0)
|
if (manaMultiplier != 0)
|
||||||
manaReduction = (int)(manaReduction * manaMultiplier);
|
manaReduction = (int)(manaReduction * manaMultiplier);
|
||||||
|
|
||||||
int manaTaken = -victim.ModifyPower(PowerType.Mana, -manaReduction);
|
int manaTaken = -damageInfo.GetVictim().ModifyPower(PowerType.Mana, -manaReduction);
|
||||||
|
|
||||||
// take case when mana has ended up into account
|
// take case when mana has ended up into account
|
||||||
currentAbsorb = currentAbsorb != 0 ? currentAbsorb * manaTaken / manaReduction : 0;
|
currentAbsorb = currentAbsorb != 0 ? (currentAbsorb * (manaTaken / manaReduction)) : 0;
|
||||||
|
|
||||||
dmgInfo.AbsorbDamage((uint)currentAbsorb);
|
damageInfo.AbsorbDamage((uint)currentAbsorb);
|
||||||
|
|
||||||
tempAbsorb = (uint)currentAbsorb;
|
tempAbsorb = (uint)currentAbsorb;
|
||||||
absorbAurEff.GetBase().CallScriptEffectAfterManaShieldHandlers(absorbAurEff, aurApp, dmgInfo, ref tempAbsorb);
|
absorbAurEff.GetBase().CallScriptEffectAfterManaShieldHandlers(absorbAurEff, aurApp, damageInfo, ref tempAbsorb);
|
||||||
|
|
||||||
// Check if our aura is using amount to count damage
|
// Check if our aura is using amount to count damage
|
||||||
if (absorbAurEff.GetAmount() >= 0)
|
if (absorbAurEff.GetAmount() >= 0)
|
||||||
@@ -2460,67 +2458,63 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dmgInfo.ModifyDamage(absorbIgnoringDamage);
|
damageInfo.ModifyDamage(absorbIgnoringDamage);
|
||||||
|
|
||||||
// split damage auras - only when not damaging self
|
// split damage auras - only when not damaging self
|
||||||
if (victim != this)
|
if (damageInfo.GetVictim() != this)
|
||||||
{
|
{
|
||||||
// We're going to call functions which can modify content of the list during iteration over it's elements
|
// We're going to call functions which can modify content of the list during iteration over it's elements
|
||||||
// Let's copy the list so we can prevent iterator invalidation
|
// Let's copy the list so we can prevent iterator invalidation
|
||||||
var vSplitDamagePctCopy = victim.GetAuraEffectsByType(AuraType.SplitDamagePct);
|
var vSplitDamagePctCopy = damageInfo.GetVictim().GetAuraEffectsByType(AuraType.SplitDamagePct);
|
||||||
foreach (var eff in vSplitDamagePctCopy)
|
foreach (var itr in vSplitDamagePctCopy)
|
||||||
{
|
{
|
||||||
if (dmgInfo.GetDamage() <= 0)
|
if (damageInfo.GetDamage() == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Check if aura was removed during iteration - we don't need to work on such auras
|
// Check if aura was removed during iteration - we don't need to work on such auras
|
||||||
AuraApplication aurApp = eff.GetBase().GetApplicationOfTarget(victim.GetGUID());
|
AuraApplication aurApp = itr.GetBase().GetApplicationOfTarget(damageInfo.GetVictim().GetGUID());
|
||||||
if (aurApp == null)
|
if (aurApp == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// check damage school mask
|
// check damage school mask
|
||||||
if (!Convert.ToBoolean(eff.GetMiscValue() & (int)schoolMask))
|
if (!Convert.ToBoolean(itr.GetMiscValue() & (int)damageInfo.GetSchoolMask()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Damage can be splitted only if aura has an alive caster
|
// Damage can be splitted only if aura has an alive caster
|
||||||
Unit caster = eff.GetCaster();
|
Unit caster = itr.GetCaster();
|
||||||
if (caster == null || (caster == victim) || !caster.IsInWorld || !caster.IsAlive())
|
if (!caster || (caster == damageInfo.GetVictim()) || !caster.IsInWorld || !caster.IsAlive())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
uint splitDamage = MathFunctions.CalculatePct(dmgInfo.GetDamage(), eff.GetAmount());
|
uint splitDamage = MathFunctions.CalculatePct(damageInfo.GetDamage(), itr.GetAmount());
|
||||||
|
|
||||||
eff.GetBase().CallScriptEffectSplitHandlers(eff, aurApp, dmgInfo, splitDamage);
|
itr.GetBase().CallScriptEffectSplitHandlers(itr, aurApp, damageInfo, splitDamage);
|
||||||
|
|
||||||
// absorb must be smaller than the damage itself
|
// absorb must be smaller than the damage itself
|
||||||
MathFunctions.RoundToInterval(ref splitDamage, 0, dmgInfo.GetDamage());
|
splitDamage = MathFunctions.RoundToInterval(ref splitDamage, 0, damageInfo.GetDamage());
|
||||||
|
|
||||||
dmgInfo.AbsorbDamage(splitDamage);
|
damageInfo.AbsorbDamage(splitDamage);
|
||||||
|
|
||||||
// check if caster is immune to damage
|
// check if caster is immune to damage
|
||||||
if (caster.IsImmunedToDamage(schoolMask))
|
if (caster.IsImmunedToDamage(damageInfo.GetSchoolMask()))
|
||||||
{
|
{
|
||||||
victim.SendSpellMiss(caster, eff.GetSpellInfo().Id, SpellMissInfo.Immune);
|
damageInfo.GetVictim().SendSpellMiss(caster, itr.GetSpellInfo().Id, SpellMissInfo.Immune);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint split_absorb = 0;
|
uint split_absorb = 0;
|
||||||
DealDamageMods(caster, ref splitDamage, ref split_absorb);
|
DealDamageMods(caster, ref splitDamage, ref split_absorb);
|
||||||
|
|
||||||
SpellNonMeleeDamage log = new SpellNonMeleeDamage(this, caster, eff.GetSpellInfo().Id, eff.GetBase().GetSpellXSpellVisualId(), schoolMask, eff.GetBase().GetCastGUID());
|
SpellNonMeleeDamage log = new SpellNonMeleeDamage(this, caster, itr.GetSpellInfo().Id, itr.GetBase().GetSpellXSpellVisualId(), damageInfo.GetSchoolMask(), itr.GetBase().GetCastGUID());
|
||||||
CleanDamage cleanDamage = new CleanDamage(splitDamage, 0, WeaponAttackType.BaseAttack, MeleeHitOutcome.Normal);
|
CleanDamage cleanDamage = new CleanDamage(splitDamage, 0, WeaponAttackType.BaseAttack, MeleeHitOutcome.Normal);
|
||||||
DealDamage(caster, splitDamage, cleanDamage, DamageEffectType.Direct, schoolMask, eff.GetSpellInfo(), false);
|
DealDamage(caster, splitDamage, cleanDamage, DamageEffectType.Direct, damageInfo.GetSchoolMask(), itr.GetSpellInfo(), false);
|
||||||
log.damage = splitDamage;
|
log.damage = splitDamage;
|
||||||
log.absorb = split_absorb;
|
log.absorb = split_absorb;
|
||||||
SendSpellNonMeleeDamageLog(log);
|
SendSpellNonMeleeDamageLog(log);
|
||||||
|
|
||||||
// break 'Fear' and similar auras
|
// break 'Fear' and similar auras
|
||||||
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);
|
ProcSkillsAndAuras(caster, ProcFlags.None, ProcFlags.TakenSpellMagicDmgClassNeg, ProcFlagsSpellType.Damage, ProcFlagsSpellPhase.Hit, ProcFlagsHit.None, null, damageInfo, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resist = dmgInfo.GetResist();
|
|
||||||
absorb = dmgInfo.GetAbsorb();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CalcHealAbsorb(HealInfo healInfo)
|
public void CalcHealAbsorb(HealInfo healInfo)
|
||||||
|
|||||||
@@ -2439,15 +2439,13 @@ namespace Game.Entities
|
|||||||
Global.ScriptMgr.ModifySpellDamageTaken(damageInfo.target, damageInfo.attacker, ref damage);
|
Global.ScriptMgr.ModifySpellDamageTaken(damageInfo.target, damageInfo.attacker, ref damage);
|
||||||
|
|
||||||
// Calculate absorb resist
|
// Calculate absorb resist
|
||||||
if (damage > 0)
|
if (damage < 0)
|
||||||
{
|
|
||||||
CalcAbsorbResist(victim, damageSchoolMask, DamageEffectType.SpellDirect, (uint)damage, ref damageInfo.absorb, ref damageInfo.resist, spellInfo);
|
|
||||||
damage -= (int)(damageInfo.absorb + damageInfo.resist);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
damage = 0;
|
damage = 0;
|
||||||
|
|
||||||
damageInfo.damage = (uint)damage;
|
damageInfo.damage = (uint)damage;
|
||||||
|
DamageInfo dmgInfo = new DamageInfo(damageInfo, DamageEffectType.SpellDirect, WeaponAttackType.BaseAttack, ProcFlagsHit.None);
|
||||||
|
CalcAbsorbResist(dmgInfo);
|
||||||
|
damageInfo.damage = dmgInfo.GetDamage();
|
||||||
}
|
}
|
||||||
public void DealSpellDamage(SpellNonMeleeDamage damageInfo, bool durabilityLoss)
|
public void DealSpellDamage(SpellNonMeleeDamage damageInfo, bool durabilityLoss)
|
||||||
{
|
{
|
||||||
@@ -2664,9 +2662,6 @@ namespace Game.Entities
|
|||||||
if (diminish.HitCount == 0)
|
if (diminish.HitCount == 0)
|
||||||
return DiminishingLevels.Level1;
|
return DiminishingLevels.Level1;
|
||||||
|
|
||||||
if (diminish.HitTime == 0)
|
|
||||||
return DiminishingLevels.Level1;
|
|
||||||
|
|
||||||
// If last spell was cast more than 18 seconds ago - reset the count.
|
// If last spell was cast more than 18 seconds ago - reset the count.
|
||||||
if (diminish.Stack == 0 && Time.GetMSTimeDiffToNow(diminish.HitTime) > 18 * Time.InMilliseconds)
|
if (diminish.Stack == 0 && Time.GetMSTimeDiffToNow(diminish.HitTime) > 18 * Time.InMilliseconds)
|
||||||
{
|
{
|
||||||
@@ -2861,6 +2856,9 @@ namespace Game.Entities
|
|||||||
if (spell.getState() != SpellState.Finished)
|
if (spell.getState() != SpellState.Finished)
|
||||||
spell.cancel();
|
spell.cancel();
|
||||||
|
|
||||||
|
if (IsCreature() && IsAIEnabled)
|
||||||
|
ToCreature().GetAI().OnSpellCastInterrupt(spell.GetSpellInfo());
|
||||||
|
|
||||||
m_currentSpells[spellType] = null;
|
m_currentSpells[spellType] = null;
|
||||||
spell.SetReferencedFromCurrent(false);
|
spell.SetReferencedFromCurrent(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2482,11 +2482,13 @@ namespace Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!CliDB.FactionTemplateStorage.ContainsKey(cInfo.Faction))
|
if (!CliDB.FactionTemplateStorage.ContainsKey(cInfo.Faction))
|
||||||
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) has non-existing faction template ({1}).", cInfo.Entry, cInfo.Faction);
|
{
|
||||||
|
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) has non-existing faction template ({1}). This can lead to crashes, set to faction 35", cInfo.Entry, cInfo.Faction);
|
||||||
|
cInfo.Faction = 35;
|
||||||
|
}
|
||||||
|
|
||||||
// used later for scale
|
// used later for scale
|
||||||
CreatureDisplayInfoRecord displayScaleEntry = null;
|
CreatureDisplayInfoRecord displayScaleEntry = null;
|
||||||
|
|
||||||
if (cInfo.ModelId1 != 0)
|
if (cInfo.ModelId1 != 0)
|
||||||
{
|
{
|
||||||
CreatureDisplayInfoRecord displayEntry = CliDB.CreatureDisplayInfoStorage.LookupByKey(cInfo.ModelId1);
|
CreatureDisplayInfoRecord displayEntry = CliDB.CreatureDisplayInfoStorage.LookupByKey(cInfo.ModelId1);
|
||||||
|
|||||||
@@ -1711,6 +1711,15 @@ namespace Game.Spells
|
|||||||
if (!Global.SpellMgr.CanSpellTriggerProcOnEvent(procEntry, eventInfo))
|
if (!Global.SpellMgr.CanSpellTriggerProcOnEvent(procEntry, eventInfo))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// check don't break stealth attr present
|
||||||
|
if (m_spellInfo.HasAura(Difficulty.None, AuraType.ModStealth))
|
||||||
|
{
|
||||||
|
SpellInfo spell = eventInfo.GetSpellInfo();
|
||||||
|
if (spell != null)
|
||||||
|
if (spell.HasAttribute(SpellCustomAttributes.DontBreakStealth))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// check if aura can proc when spell is triggered (exception for hunter auto shot & wands)
|
// check if aura can proc when spell is triggered (exception for hunter auto shot & wands)
|
||||||
if (!procEntry.AttributesMask.HasAnyFlag(ProcAttributes.TriggeredCanProc) && !eventInfo.GetTypeMask().HasAnyFlag(ProcFlags.AutoAttackMask))
|
if (!procEntry.AttributesMask.HasAnyFlag(ProcAttributes.TriggeredCanProc) && !eventInfo.GetTypeMask().HasAnyFlag(ProcFlags.AutoAttackMask))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -674,15 +674,12 @@ namespace Game.Spells
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Spell own damage at apply won't break CC
|
// Spell own damage at apply won't break CC
|
||||||
if (spellInfo != null)
|
if (spellInfo != null && spellInfo == GetSpellInfo())
|
||||||
{
|
{
|
||||||
if (spellInfo == GetSpellInfo())
|
Aura aura = GetBase();
|
||||||
{
|
// called from spellcast, should not have ticked yet
|
||||||
Aura aura = GetBase();
|
if (aura.GetDuration() == aura.GetMaxDuration())
|
||||||
// called from spellcast, should not have ticked yet
|
return false;
|
||||||
if (aura.GetDuration() == aura.GetMaxDuration())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5544,8 +5541,6 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint absorb = 0;
|
|
||||||
uint resist = 0;
|
|
||||||
CleanDamage cleanDamage = new CleanDamage(0, 0, WeaponAttackType.BaseAttack, MeleeHitOutcome.Normal);
|
CleanDamage cleanDamage = new CleanDamage(0, 0, WeaponAttackType.BaseAttack, MeleeHitOutcome.Normal);
|
||||||
|
|
||||||
// AOE spells are not affected by the new periodic system.
|
// AOE spells are not affected by the new periodic system.
|
||||||
@@ -5615,14 +5610,21 @@ namespace Game.Spells
|
|||||||
if (!GetSpellInfo().HasAttribute(SpellAttr4.FixedDamage))
|
if (!GetSpellInfo().HasAttribute(SpellAttr4.FixedDamage))
|
||||||
caster.ApplyResilience(target, ref damage);
|
caster.ApplyResilience(target, ref damage);
|
||||||
|
|
||||||
caster.CalcAbsorbResist(target, GetSpellInfo().GetSchoolMask(), DamageEffectType.DOT, damage, ref absorb, ref resist, GetSpellInfo());
|
DamageInfo damageInfo = new DamageInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo().GetSchoolMask(), DamageEffectType.DOT, WeaponAttackType.BaseAttack);
|
||||||
|
caster.CalcAbsorbResist(damageInfo);
|
||||||
|
damage = damageInfo.GetDamage();
|
||||||
|
|
||||||
|
uint absorb = damageInfo.GetAbsorb();
|
||||||
|
uint resist = damageInfo.GetResist();
|
||||||
caster.DealDamageMods(target, ref damage, ref absorb);
|
caster.DealDamageMods(target, ref damage, ref absorb);
|
||||||
|
|
||||||
// Set trigger flag
|
// Set trigger flag
|
||||||
ProcFlags procAttacker = ProcFlags.DonePeriodic;
|
ProcFlags procAttacker = ProcFlags.DonePeriodic;
|
||||||
ProcFlags procVictim = ProcFlags.TakenPeriodic;
|
ProcFlags procVictim = ProcFlags.TakenPeriodic;
|
||||||
ProcFlagsHit hitMask = crit ? ProcFlagsHit.Critical : ProcFlagsHit.Normal;
|
ProcFlagsHit hitMask = damageInfo.GetHitMask();
|
||||||
damage = (damage <= absorb + resist) ? 0 : (damage - absorb - resist);
|
if (hitMask == 0)
|
||||||
|
hitMask = crit ? ProcFlagsHit.Critical : ProcFlagsHit.Normal;
|
||||||
|
|
||||||
if (damage != 0)
|
if (damage != 0)
|
||||||
procVictim |= ProcFlags.TakenDamage;
|
procVictim |= ProcFlags.TakenDamage;
|
||||||
|
|
||||||
@@ -5632,7 +5634,6 @@ namespace Game.Spells
|
|||||||
|
|
||||||
SpellPeriodicAuraLogInfo pInfo = new SpellPeriodicAuraLogInfo(this, damage, overkill, absorb, resist, 0.0f, crit);
|
SpellPeriodicAuraLogInfo pInfo = new SpellPeriodicAuraLogInfo(this, damage, overkill, absorb, resist, 0.0f, crit);
|
||||||
|
|
||||||
DamageInfo damageInfo = new DamageInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo().GetSchoolMask(), DamageEffectType.DOT, WeaponAttackType.BaseAttack);
|
|
||||||
caster.ProcSkillsAndAuras(target, procAttacker, procVictim, ProcFlagsSpellType.Damage, ProcFlagsSpellPhase.None, hitMask, null, damageInfo, null);
|
caster.ProcSkillsAndAuras(target, procAttacker, procVictim, ProcFlagsSpellType.Damage, ProcFlagsSpellPhase.None, hitMask, null, damageInfo, null);
|
||||||
|
|
||||||
caster.DealDamage(target, damage, cleanDamage, DamageEffectType.DOT, GetSpellInfo().GetSchoolMask(), GetSpellInfo(), true);
|
caster.DealDamage(target, damage, cleanDamage, DamageEffectType.DOT, GetSpellInfo().GetSchoolMask(), GetSpellInfo(), true);
|
||||||
@@ -5654,8 +5655,6 @@ namespace Game.Spells
|
|||||||
caster.SpellHitResult(target, GetSpellInfo(), false) != SpellMissInfo.None)
|
caster.SpellHitResult(target, GetSpellInfo(), false) != SpellMissInfo.None)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint absorb = 0;
|
|
||||||
uint resist = 0;
|
|
||||||
CleanDamage cleanDamage = new CleanDamage(0, 0, WeaponAttackType.BaseAttack, MeleeHitOutcome.Normal);
|
CleanDamage cleanDamage = new CleanDamage(0, 0, WeaponAttackType.BaseAttack, MeleeHitOutcome.Normal);
|
||||||
|
|
||||||
bool isAreaAura = GetSpellEffectInfo().IsAreaAuraEffect() || GetSpellEffectInfo().IsEffect(SpellEffectName.PersistentAreaAura);
|
bool isAreaAura = GetSpellEffectInfo().IsAreaAuraEffect() || GetSpellEffectInfo().IsEffect(SpellEffectName.PersistentAreaAura);
|
||||||
@@ -5698,10 +5697,15 @@ namespace Game.Spells
|
|||||||
if (!GetSpellInfo().HasAttribute(SpellAttr4.FixedDamage))
|
if (!GetSpellInfo().HasAttribute(SpellAttr4.FixedDamage))
|
||||||
caster.ApplyResilience(target, ref damage);
|
caster.ApplyResilience(target, ref damage);
|
||||||
|
|
||||||
caster.CalcAbsorbResist(target, GetSpellInfo().GetSchoolMask(), DamageEffectType.DOT, damage, ref absorb, ref resist, m_spellInfo);
|
DamageInfo damageInfo = new DamageInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo().GetSchoolMask(), DamageEffectType.DOT, WeaponAttackType.BaseAttack);
|
||||||
|
caster.CalcAbsorbResist(damageInfo);
|
||||||
|
|
||||||
|
uint absorb = damageInfo.GetAbsorb();
|
||||||
|
uint resist = damageInfo.GetResist();
|
||||||
|
|
||||||
|
// SendSpellNonMeleeDamageLog expects non-absorbed/non-resisted damage
|
||||||
SpellNonMeleeDamage log = new SpellNonMeleeDamage(caster, target, GetId(), GetBase().GetSpellXSpellVisualId(), GetSpellInfo().GetSchoolMask(), GetBase().GetCastGUID());
|
SpellNonMeleeDamage log = new SpellNonMeleeDamage(caster, target, GetId(), GetBase().GetSpellXSpellVisualId(), GetSpellInfo().GetSchoolMask(), GetBase().GetCastGUID());
|
||||||
log.damage = damage - absorb - resist;
|
log.damage = damage;
|
||||||
log.absorb = absorb;
|
log.absorb = absorb;
|
||||||
log.resist = resist;
|
log.resist = resist;
|
||||||
log.periodicLog = true;
|
log.periodicLog = true;
|
||||||
@@ -5711,16 +5715,15 @@ namespace Game.Spells
|
|||||||
// Set trigger flag
|
// Set trigger flag
|
||||||
ProcFlags procAttacker = ProcFlags.DonePeriodic;
|
ProcFlags procAttacker = ProcFlags.DonePeriodic;
|
||||||
ProcFlags procVictim = ProcFlags.TakenPeriodic;
|
ProcFlags procVictim = ProcFlags.TakenPeriodic;
|
||||||
ProcFlagsHit hitMask = crit ? ProcFlagsHit.Critical : ProcFlagsHit.Normal;
|
ProcFlagsHit hitMask = damageInfo.GetHitMask();
|
||||||
damage = (damage <= absorb + resist) ? 0 : (damage - absorb - resist);
|
if (hitMask == 0)
|
||||||
|
hitMask = crit ? ProcFlagsHit.Critical : ProcFlagsHit.Normal;
|
||||||
|
|
||||||
if (damage != 0)
|
if (damage != 0)
|
||||||
procVictim |= ProcFlags.TakenDamage;
|
procVictim |= ProcFlags.TakenDamage;
|
||||||
|
|
||||||
if (caster.IsAlive())
|
if (caster.IsAlive())
|
||||||
{
|
|
||||||
DamageInfo damageInfo = new DamageInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo().GetSchoolMask(), DamageEffectType.DOT, WeaponAttackType.BaseAttack);
|
|
||||||
caster.ProcSkillsAndAuras(target, procAttacker, procVictim, ProcFlagsSpellType.Damage, ProcFlagsSpellPhase.None, hitMask, null, damageInfo, null);
|
caster.ProcSkillsAndAuras(target, procAttacker, procVictim, ProcFlagsSpellType.Damage, ProcFlagsSpellPhase.None, hitMask, null, damageInfo, null);
|
||||||
}
|
|
||||||
|
|
||||||
int new_damage = (int)caster.DealDamage(target, damage, cleanDamage, DamageEffectType.DOT, GetSpellInfo().GetSchoolMask(), GetSpellInfo(), false);
|
int new_damage = (int)caster.DealDamage(target, damage, cleanDamage, DamageEffectType.DOT, GetSpellInfo().GetSchoolMask(), GetSpellInfo(), false);
|
||||||
if (caster.IsAlive())
|
if (caster.IsAlive())
|
||||||
|
|||||||
+13
-5
@@ -1891,7 +1891,19 @@ namespace Game.Spells
|
|||||||
if (m_damage > 0)
|
if (m_damage > 0)
|
||||||
positive = false;
|
positive = false;
|
||||||
else if (m_healing == 0)
|
else if (m_healing == 0)
|
||||||
positive = m_spellInfo.IsPositive();
|
{
|
||||||
|
for (byte i = 0; i < SpellConst.MaxEffects; ++i)
|
||||||
|
{
|
||||||
|
if (!Convert.ToBoolean(target.effectMask & (1 << i)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!m_spellInfo.IsPositiveEffect(i))
|
||||||
|
{
|
||||||
|
positive = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (m_spellInfo.DmgClass)
|
switch (m_spellInfo.DmgClass)
|
||||||
{
|
{
|
||||||
@@ -2077,11 +2089,7 @@ namespace Game.Spells
|
|||||||
return SpellMissInfo.Evade;
|
return SpellMissInfo.Evade;
|
||||||
|
|
||||||
if (m_caster._IsValidAttackTarget(unit, m_spellInfo))
|
if (m_caster._IsValidAttackTarget(unit, m_spellInfo))
|
||||||
{
|
|
||||||
unit.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Hitbyspell);
|
unit.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Hitbyspell);
|
||||||
if (!m_spellInfo.HasAttribute(SpellCustomAttributes.DontBreakStealth))
|
|
||||||
unit.RemoveAurasByType(AuraType.ModStealth);
|
|
||||||
}
|
|
||||||
else if (m_caster.IsFriendlyTo(unit))
|
else if (m_caster.IsFriendlyTo(unit))
|
||||||
{
|
{
|
||||||
// for delayed spells ignore negative spells (after duel end) for friendly targets
|
// for delayed spells ignore negative spells (after duel end) for friendly targets
|
||||||
|
|||||||
+12
-10
@@ -126,19 +126,21 @@ namespace Game.Spells
|
|||||||
if (unitTarget == null || !unitTarget.IsAlive())
|
if (unitTarget == null || !unitTarget.IsAlive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint absorb = 0;
|
// CalcAbsorbResist already in Player::EnvironmentalDamage
|
||||||
uint resist = 0;
|
|
||||||
|
|
||||||
m_caster.CalcAbsorbResist(unitTarget, m_spellInfo.GetSchoolMask(), DamageEffectType.SpellDirect, (uint)damage, ref absorb, ref resist, m_spellInfo);
|
|
||||||
|
|
||||||
SpellNonMeleeDamage log = new SpellNonMeleeDamage(m_caster, unitTarget, m_spellInfo.Id, m_SpellVisual, m_spellInfo.GetSchoolMask(), m_castId);
|
|
||||||
log.damage = (uint)(damage - absorb - resist);
|
|
||||||
log.absorb = absorb;
|
|
||||||
log.resist = resist;
|
|
||||||
if (unitTarget.IsTypeId(TypeId.Player))
|
if (unitTarget.IsTypeId(TypeId.Player))
|
||||||
unitTarget.ToPlayer().EnvironmentalDamage(EnviromentalDamage.Fire, (uint)damage);
|
unitTarget.ToPlayer().EnvironmentalDamage(EnviromentalDamage.Fire, (uint)damage);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DamageInfo damageInfo = new DamageInfo(m_caster, unitTarget, (uint)damage, m_spellInfo, m_spellInfo.GetSchoolMask(), DamageEffectType.SpellDirect, WeaponAttackType.BaseAttack);
|
||||||
|
m_caster.CalcAbsorbResist(damageInfo);
|
||||||
|
|
||||||
m_caster.SendSpellNonMeleeDamageLog(log);
|
SpellNonMeleeDamage log = new SpellNonMeleeDamage(m_caster, unitTarget, m_spellInfo.Id, m_SpellVisual, m_spellInfo.GetSchoolMask(), m_castId);
|
||||||
|
log.damage = (uint)damage;
|
||||||
|
log.absorb = damageInfo.GetAbsorb();
|
||||||
|
log.resist = damageInfo.GetResist();
|
||||||
|
|
||||||
|
m_caster.SendSpellNonMeleeDamageLog(log);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SpellEffectHandler(SpellEffectName.SchoolDamage)]
|
[SpellEffectHandler(SpellEffectName.SchoolDamage)]
|
||||||
|
|||||||
@@ -1,13 +1,26 @@
|
|||||||
using System;
|
/*
|
||||||
using System.Collections.Generic;
|
* Copyright (C) 2012-2017 CypherCore <http://github.com/CypherCore>
|
||||||
using System.Linq;
|
*
|
||||||
using System.Text;
|
* This program is free software: you can redistribute it and/or modify
|
||||||
using System.Threading.Tasks;
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Framework.Constants;
|
||||||
|
using Game;
|
||||||
using Game.AI;
|
using Game.AI;
|
||||||
using Game.Entities;
|
using Game.Entities;
|
||||||
using Framework.Constants;
|
|
||||||
using Game.Scripting;
|
using Game.Scripting;
|
||||||
using Game;
|
using System;
|
||||||
|
|
||||||
namespace Scripts.Kalimdor.ZoneAshenvale
|
namespace Scripts.Kalimdor.ZoneAshenvale
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -399,9 +399,12 @@ namespace Scripts.Northrend.CrusadersColiseum.TrialOfTheCrusader
|
|||||||
switch (eventId)
|
switch (eventId)
|
||||||
{
|
{
|
||||||
case Events.FireBomb:
|
case Events.FireBomb:
|
||||||
Unit target = SelectTarget(SelectAggroTarget.Random, 0, -me.GetVehicleBase().GetCombatReach(), true);
|
if (me.GetVehicleBase())
|
||||||
if (target)
|
{
|
||||||
me.CastSpell(target, SpellIds.FireBomb);
|
Unit target = SelectTarget(SelectAggroTarget.Random, 0, -me.GetVehicleBase().GetCombatReach(), true);
|
||||||
|
if (target)
|
||||||
|
me.CastSpell(target, SpellIds.FireBomb);
|
||||||
|
}
|
||||||
_events.Repeat(TimeSpan.FromSeconds(20));
|
_events.Repeat(TimeSpan.FromSeconds(20));
|
||||||
break;
|
break;
|
||||||
case Events.HeadCrack:
|
case Events.HeadCrack:
|
||||||
|
|||||||
Reference in New Issue
Block a user