Core/Spells: Implement using different difficulty data from all spell related db2s, not just SpellEffect and SpellPower

Port From (https://github.com/TrinityCore/TrinityCore/commit/c7306439e7004288fb85890d6a5f730cf1761d71)
This commit is contained in:
hondacrx
2020-06-18 12:39:39 -04:00
parent f0942a257e
commit d7954f4fc7
89 changed files with 1738 additions and 1893 deletions
+1 -1
View File
@@ -169,7 +169,7 @@ namespace Framework.Constants
PassengerRemoved = 28, // Cooldownmin, Cooldownmax
Charmed = 29, // onRemove (0 - on apply, 1 - on remove)
CharmedTarget = 30, // None
SpellhitTarget = 31, // Spellid, School, Cooldownmin, Cooldownmax
SpellHitTarget = 31, // Spellid, School, Cooldownmin, Cooldownmax
Damaged = 32, // Mindmg, Maxdmg, Cooldownmin, Cooldownmax
DamagedTarget = 33, // Mindmg, Maxdmg, Cooldownmin, Cooldownmax
Movementinform = 34, // Movementtype(Any), Pointid
@@ -442,8 +442,8 @@ namespace Framework.Constants
ModMaxPower = 418, // NYI
ModBaseManaPct = 419,
ModBattlePetXpPct = 420,
ModAbsorbEffectsAmountPct = 421, // NYI
Unk422 = 422,
ModAbsorbEffectsDonePct = 421, // NYI
ModAbsorbEffectsTakenPct = 422, //NYI
Unk423 = 423,
Unk424 = 424,
Unk425 = 425,
@@ -32,6 +32,8 @@ namespace Framework.Constants
public const int EffectAll = 255;
public const float TrajectoryMissileSize = 3.0f;
public const int MaxPowersPerSpell = 4;
}
@@ -2323,7 +2325,7 @@ namespace Framework.Constants
UnitNearbyParty = 3,
UnitNearbyAlly = 4,
UnitPet = 5,
UnitEnemy = 6,
UnitTargetEnemy = 6,
UnitSrcAreaEntry = 7,
UnitDestAreaEntry = 8,
DestHome = 9,
@@ -2333,11 +2335,11 @@ namespace Framework.Constants
DestDb = 17,
DestCaster = 18,
UnitCasterAreaParty = 20,
UnitAlly = 21,
UnitTargetAlly = 21,
SrcCaster = 22,
GameobjectTarget = 23,
UnitConeEnemy24 = 24,
UnitAny = 25,
UnitTargetAny = 25,
GameobjectItemTarget = 26,
UnitMaster = 27,
DestDynobjEnemy = 28,
@@ -2347,9 +2349,9 @@ namespace Framework.Constants
DestCasterSummon = 32, // Front Left, Doesn'T Use Radius
UnitSrcAreaParty = 33,
UnitDestAreaParty = 34,
UnitParty = 35,
UnitTargetParty = 35,
DestCasterUnk36 = 36,
UnitLastAreaParty = 37,
UnitLastTargetAreaParty = 37,
UnitNearbyEntry = 38,
DestCasterFishing = 39,
GameobjectNearbyEntry = 40,
@@ -2365,7 +2367,7 @@ namespace Framework.Constants
DestCasterLeft = 50,
GameobjectSrcArea = 51,
GameobjectDestArea = 52,
DestEnemy = 53,
DestTargetEnemy = 53,
UnitConeEnemy54 = 54,
DestCasterFrontLeap = 55, // For A Leap Spell
UnitCasterAreaRaid = 56,
@@ -83,7 +83,7 @@ namespace Framework.Database
PrepareStatement(CharStatements.SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?");
PrepareStatement(CharStatements.SEL_CHARACTER_INSTANCE, "SELECT id, permanent, map, difficulty, extendState, resettime, entranceId FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = ?");
PrepareStatement(CharStatements.SEL_CHARACTER_AURAS, "SELECT casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, maxDuration, remainTime, remainCharges, castItemId, castItemLevel FROM character_aura WHERE guid = ?");
PrepareStatement(CharStatements.SEL_CHARACTER_AURAS, "SELECT casterGuid, itemGuid, spell, effectMask, recalculateMask, difficulty, stackCount, maxDuration, remainTime, remainCharges, castItemId, castItemLevel FROM character_aura WHERE guid = ?");
PrepareStatement(CharStatements.SEL_CHARACTER_AURA_EFFECTS, "SELECT casterGuid, itemGuid, spell, effectMask, effectIndex, amount, baseAmount FROM character_aura_effect WHERE guid = ?");
PrepareStatement(CharStatements.SEL_CHARACTER_SPELL, "SELECT spell, active, disabled FROM character_spell WHERE guid = ?");
PrepareStatement(CharStatements.SEL_CHARACTER_QUESTSTATUS, "SELECT quest, status, timer FROM character_queststatus WHERE guid = ? AND status <> 0");
@@ -339,8 +339,8 @@ namespace Framework.Database
PrepareStatement(CharStatements.DEL_TRANSMOG_OUTFIT, "DELETE FROM character_transmog_outfits WHERE setguid=?");
// Auras
PrepareStatement(CharStatements.INS_AURA, "INSERT INTO character_aura (guid, casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, maxDuration, remainTime, remainCharges, castItemId, castItemLevel) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
PrepareStatement(CharStatements.INS_AURA, "INSERT INTO character_aura (guid, casterGuid, itemGuid, spell, effectMask, recalculateMask, difficulty, stackCount, maxDuration, remainTime, remainCharges, castItemId, castItemLevel) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
PrepareStatement(CharStatements.INS_AURA_EFFECT, "INSERT INTO character_aura_effect (guid, casterGuid, itemGuid, spell, effectMask, effectIndex, amount, baseAmount) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
@@ -708,7 +708,7 @@ namespace Framework.Database
PrepareStatement(CharStatements.DEL_CHAR_PET_DECLINEDNAME_BY_OWNER, "DELETE FROM character_pet_declinedname WHERE owner = ?");
PrepareStatement(CharStatements.DEL_CHAR_PET_DECLINEDNAME, "DELETE FROM character_pet_declinedname WHERE id = ?");
PrepareStatement(CharStatements.INS_CHAR_PET_DECLINEDNAME, "INSERT INTO character_pet_declinedname (id, owner, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?, ?)");
PrepareStatement(CharStatements.SEL_PET_AURA, "SELECT casterGuid, spell, effectMask, recalculateMask, stackCount, maxDuration, remainTime, remainCharges FROM pet_aura WHERE guid = ?");
PrepareStatement(CharStatements.SEL_PET_AURA, "SELECT casterGuid, spell, effectMask, recalculateMask, difficulty, stackCount, maxDuration, remainTime, remainCharges FROM pet_aura WHERE guid = ?");
PrepareStatement(CharStatements.SEL_PET_AURA_EFFECT, "SELECT casterGuid, spell, effectMask, effectIndex, amount, baseAmount FROM pet_aura_effect WHERE guid = ?");
PrepareStatement(CharStatements.SEL_PET_SPELL, "SELECT spell, active FROM pet_spell WHERE guid = ?");
PrepareStatement(CharStatements.SEL_PET_SPELL_COOLDOWN, "SELECT spell, time, categoryId, categoryEnd FROM pet_spell_cooldown WHERE guid = ? AND time > UNIX_TIMESTAMP()");
@@ -723,8 +723,8 @@ namespace Framework.Database
PrepareStatement(CharStatements.INS_PET_SPELL_CHARGES, "INSERT INTO pet_spell_charges (guid, categoryId, rechargeStart, rechargeEnd) VALUES (?, ?, ?, ?)");
PrepareStatement(CharStatements.DEL_PET_SPELL_BY_SPELL, "DELETE FROM pet_spell WHERE guid = ? and spell = ?");
PrepareStatement(CharStatements.INS_PET_SPELL, "INSERT INTO pet_spell (guid, spell, active) VALUES (?, ?, ?)");
PrepareStatement(CharStatements.INS_PET_AURA, "INSERT INTO pet_aura (guid, casterGuid, spell, effectMask, recalculateMask, stackCount, maxDuration, remainTime, remainCharges) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
PrepareStatement(CharStatements.INS_PET_AURA, "INSERT INTO pet_aura (guid, casterGuid, spell, effectMask, recalculateMask, difficulty, stackCount, maxDuration, remainTime, remainCharges) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
PrepareStatement(CharStatements.INS_PET_AURA_EFFECT, "INSERT INTO pet_aura_effect (guid, casterGuid, spell, effectMask, effectIndex, amount, baseAmount) " +
"VALUES (?, ?, ?, ?, ?, ?, ?)");
PrepareStatement(CharStatements.SEL_CHAR_PET_BY_ENTRY, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType, specialization FROM character_pet WHERE owner = ? AND id = ?");
+26 -16
View File
@@ -28,7 +28,7 @@ namespace Game.AI
public override void InitializeAI()
{
for (var i = 0; i < SharedConst.MaxCreatureSpells; ++i)
if (me.m_spells[i] != 0 && Global.SpellMgr.GetSpellInfo(me.m_spells[i]) != null)
if (me.m_spells[i] != 0 && Global.SpellMgr.HasSpellInfo(me.m_spells[i], me.GetMap().GetDifficultyID()))
spells.Add(me.m_spells[i]);
base.InitializeAI();
@@ -42,18 +42,22 @@ namespace Game.AI
public override void JustDied(Unit killer)
{
foreach (var id in spells)
if (AISpellInfo[id].condition == AICondition.Die)
{
AISpellInfoType info = GetAISpellInfo(id, me.GetMap().GetDifficultyID());
if (info.condition == AICondition.Die)
me.CastSpell(killer, id, true);
}
}
public override void EnterCombat(Unit victim)
{
foreach (var id in spells)
{
if (AISpellInfo[id].condition == AICondition.Aggro)
AISpellInfoType info = GetAISpellInfo(id, me.GetMap().GetDifficultyID());
if (info.condition == AICondition.Aggro)
me.CastSpell(victim, id, false);
else if (AISpellInfo[id].condition == AICondition.Combat)
_events.ScheduleEvent(id, AISpellInfo[id].cooldown + RandomHelper.Rand32() % AISpellInfo[id].cooldown);
else if (info.condition == AICondition.Combat)
_events.ScheduleEvent(id, info.cooldown + RandomHelper.Rand32() % info.cooldown);
}
}
@@ -71,9 +75,10 @@ namespace Game.AI
if (spellId != 0)
{
DoCast(spellId);
_events.ScheduleEvent(spellId, AISpellInfo[spellId].cooldown + RandomHelper.Rand32() % AISpellInfo[spellId].cooldown);
AISpellInfoType info = GetAISpellInfo(spellId, me.GetMap().GetDifficultyID());
_events.ScheduleEvent(spellId, info.cooldown + RandomHelper.Rand32() % info.cooldown);
}
else
DoMeleeAttackIfReady();
}
@@ -112,8 +117,12 @@ namespace Game.AI
m_attackDist = 30.0f;
foreach (var id in spells)
if (AISpellInfo[id].condition == AICondition.Combat && m_attackDist > AISpellInfo[id].maxRange)
m_attackDist = AISpellInfo[id].maxRange;
{
AISpellInfoType info = GetAISpellInfo(id, me.GetMap().GetDifficultyID());
if (info.condition == AICondition.Combat && m_attackDist > info.maxRange)
m_attackDist = info.maxRange;
}
if (m_attackDist == 30.0f)
m_attackDist = SharedConst.MeleeRange;
}
@@ -132,12 +141,12 @@ namespace Game.AI
uint count = 0;
foreach (var id in spells)
{
if (AISpellInfo[id].condition == AICondition.Aggro)
AISpellInfoType info = GetAISpellInfo(id, me.GetMap().GetDifficultyID());
if (info.condition == AICondition.Aggro)
me.CastSpell(victim, id, false);
else if (AISpellInfo[id].condition == AICondition.Combat)
else if (info.condition == AICondition.Combat)
{
uint cooldown = AISpellInfo[id].realCooldown;
uint cooldown = info.realCooldown;
if (count == spell)
{
DoCast(spells[spell]);
@@ -169,7 +178,8 @@ namespace Game.AI
{
DoCast(spellId);
uint casttime = (uint)me.GetCurrentSpellCastTime(spellId);
_events.ScheduleEvent(spellId, (casttime != 0 ? casttime : 500) + AISpellInfo[spellId].realCooldown);
AISpellInfoType info = GetAISpellInfo(spellId, me.GetMap().GetDifficultyID());
_events.ScheduleEvent(spellId, (casttime != 0 ? casttime : 500) + info.realCooldown);
}
}
@@ -184,7 +194,7 @@ namespace Game.AI
if (me.m_spells[0] == 0)
Log.outError(LogFilter.ScriptsAi, "ArcherAI set for creature (entry = {0}) with spell1=0. AI will do nothing", me.GetEntry());
var spellInfo = Global.SpellMgr.GetSpellInfo(me.m_spells[0]);
var spellInfo = Global.SpellMgr.GetSpellInfo(me.m_spells[0], me.GetMap().GetDifficultyID());
m_minRange = spellInfo != null ? spellInfo.GetMinRange(false) : 0;
if (m_minRange == 0)
@@ -234,7 +244,7 @@ namespace Game.AI
if (me.m_spells[0] == 0)
Log.outError(LogFilter.Server, "TurretAI set for creature (entry = {0}) with spell1=0. AI will do nothing", me.GetEntry());
var spellInfo = Global.SpellMgr.GetSpellInfo(me.m_spells[0]);
var spellInfo = Global.SpellMgr.GetSpellInfo(me.m_spells[0], me.GetMap().GetDifficultyID());
m_minRange = spellInfo != null ? spellInfo.GetMinRange(false) : 0;
me.m_CombatDistance = spellInfo != null ? spellInfo.GetMaxRange(false) : 0;
me.m_SightDistance = me.m_CombatDistance;
+3
View File
@@ -492,6 +492,9 @@ namespace Game.AI
public uint cooldown;
public uint realCooldown;
public float maxRange;
public byte Targets; // set of enum SelectTarget
public byte Effects; // set of enum SelectEffect
}
public enum AITarget
+1 -1
View File
@@ -138,7 +138,7 @@ namespace Game.AI
if (spellID == 0)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellID, me.GetMap().GetDifficultyID());
if (spellInfo == null)
continue;
+1 -1
View File
@@ -42,7 +42,7 @@ namespace Game.AI
return;
// Search spell
var spellInfo = Global.SpellMgr.GetSpellInfo(me.ToTotem().GetSpell());
var spellInfo = Global.SpellMgr.GetSpellInfo(me.ToTotem().GetSpell(), me.GetMap().GetDifficultyID());
if (spellInfo == null)
return;
+93 -13
View File
@@ -99,7 +99,7 @@ namespace Game.AI
if (me.HasUnitState(UnitState.Casting) || !me.IsAttackReady())
return true;
var spellInfo = Global.SpellMgr.GetSpellInfo(spell);
var spellInfo = Global.SpellMgr.GetSpellInfo(spell, me.GetMap().GetDifficultyID());
if (spellInfo != null)
{
if (me.IsWithinCombatRange(me.GetVictim(), spellInfo.GetMaxRange(false)))
@@ -215,7 +215,8 @@ namespace Game.AI
{
Unit target = null;
switch (AISpellInfo[spellId].target)
AISpellInfoType info = GetAISpellInfo(spellId, me.GetMap().GetDifficultyID());
switch (info.target)
{
default:
case AITarget.Self:
@@ -226,7 +227,7 @@ namespace Game.AI
break;
case AITarget.Enemy:
{
var spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
var spellInfo = Global.SpellMgr.GetSpellInfo(spellId, me.GetMap().GetDifficultyID());
if (spellInfo != null)
{
bool playerOnly = spellInfo.HasAttribute(SpellAttr3.OnlyTargetPlayers);
@@ -240,7 +241,7 @@ namespace Game.AI
break;
case AITarget.Debuff:
{
var spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
var spellInfo = Global.SpellMgr.GetSpellInfo(spellId, me.GetMap().GetDifficultyID());
if (spellInfo != null)
{
bool playerOnly = spellInfo.HasAttribute(SpellAttr3.OnlyTargetPlayers);
@@ -289,12 +290,11 @@ namespace Game.AI
public static void FillAISpellInfo()
{
var spellStorage = Global.SpellMgr.GetSpellInfoStorage();
AISpellInfo = new AISpellInfoType[spellStorage.Keys.Max() + 1];
//AISpellInfo = new AISpellInfoType[spellStorage.Keys.Max() + 1];
foreach (var spellInfo in spellStorage.Values)
Global.SpellMgr.ForEachSpellInfo(spellInfo =>
{
AISpellInfoType AIInfo = AISpellInfo[spellInfo.Id];
AISpellInfoType AIInfo = new AISpellInfoType();
if (spellInfo.HasAttribute(SpellAttr0.CastableWhileDead))
AIInfo.condition = AICondition.Die;
else if (spellInfo.IsPassive() || spellInfo.GetDuration() == -1)
@@ -312,14 +312,14 @@ namespace Game.AI
}
else
{
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect == null)
continue;
var targetType = effect.TargetA.GetTarget();
if (targetType == Targets.UnitEnemy || targetType == Targets.DestEnemy)
if (targetType == Targets.UnitTargetEnemy || targetType == Targets.DestTargetEnemy)
{
if (AIInfo.target < AITarget.Victim)
AIInfo.target = AITarget.Victim;
@@ -332,7 +332,7 @@ namespace Game.AI
if (effect.Effect == SpellEffectName.ApplyAura)
{
if (targetType == Targets.UnitEnemy)
if (targetType == Targets.UnitTargetEnemy)
{
if (AIInfo.target < AITarget.Debuff)
AIInfo.target = AITarget.Debuff;
@@ -347,7 +347,82 @@ namespace Game.AI
}
AIInfo.realCooldown = spellInfo.RecoveryTime + spellInfo.StartRecoveryTime;
AIInfo.maxRange = spellInfo.GetMaxRange(false) * 3 / 4;
AIInfo.Effects = 0;
AIInfo.Targets = 0;
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect == null)
continue;
// Spell targets self.
if (effect.TargetA.GetTarget() == Targets.UnitCaster)
AIInfo.Targets |= 1 << ((int)SelectTargetType.Self - 1);
// Spell targets a single enemy.
if (effect.TargetA.GetTarget() == Targets.UnitTargetEnemy ||
effect.TargetA.GetTarget() == Targets.DestTargetEnemy)
AIInfo.Targets |= 1 << ((int)SelectTargetType.SingleEnemy - 1);
// Spell targets AoE at enemy.
if (effect.TargetA.GetTarget() == Targets.UnitSrcAreaEnemy ||
effect.TargetA.GetTarget() == Targets.UnitDestAreaEnemy ||
effect.TargetA.GetTarget() == Targets.SrcCaster ||
effect.TargetA.GetTarget() == Targets.DestDynobjEnemy)
AIInfo.Targets |= 1 << ((int)SelectTargetType.AoeEnemy - 1);
// Spell targets an enemy.
if (effect.TargetA.GetTarget() == Targets.UnitTargetEnemy ||
effect.TargetA.GetTarget() == Targets.DestTargetEnemy ||
effect.TargetA.GetTarget() == Targets.UnitSrcAreaEnemy ||
effect.TargetA.GetTarget() == Targets.UnitDestAreaEnemy ||
effect.TargetA.GetTarget() == Targets.SrcCaster ||
effect.TargetA.GetTarget() == Targets.DestDynobjEnemy)
AIInfo.Targets |= 1 << ((int)SelectTargetType.AnyEnemy - 1);
// Spell targets a single friend (or self).
if (effect.TargetA.GetTarget() == Targets.UnitCaster ||
effect.TargetA.GetTarget() == Targets.UnitTargetAlly ||
effect.TargetA.GetTarget() == Targets.UnitTargetParty)
AIInfo.Targets |= 1 << ((int)SelectTargetType.SingleFriend - 1);
// Spell targets AoE friends.
if (effect.TargetA.GetTarget() == Targets.UnitCasterAreaParty ||
effect.TargetA.GetTarget() == Targets.UnitLastTargetAreaParty ||
effect.TargetA.GetTarget() == Targets.SrcCaster)
AIInfo.Targets |= 1 << ((int)SelectTargetType.AoeFriend - 1);
// Spell targets any friend (or self).
if (effect.TargetA.GetTarget() == Targets.UnitCaster ||
effect.TargetA.GetTarget() == Targets.UnitTargetAlly ||
effect.TargetA.GetTarget() == Targets.UnitTargetParty ||
effect.TargetA.GetTarget() == Targets.UnitCasterAreaParty ||
effect.TargetA.GetTarget() == Targets.UnitLastTargetAreaParty ||
effect.TargetA.GetTarget() == Targets.SrcCaster)
AIInfo.Targets |= 1 << ((int)SelectTargetType.AnyFriend - 1);
// Make sure that this spell includes a damage effect.
if (effect.Effect == SpellEffectName.SchoolDamage ||
effect.Effect == SpellEffectName.Instakill ||
effect.Effect == SpellEffectName.EnvironmentalDamage ||
effect.Effect == SpellEffectName.HealthLeech)
AIInfo.Effects |= 1 << ((int)SelectEffect.Damage - 1);
// Make sure that this spell includes a healing effect (or an apply aura with a periodic heal).
if (effect.Effect == SpellEffectName.Heal ||
effect.Effect == SpellEffectName.HealMaxHealth ||
effect.Effect == SpellEffectName.HealMechanical ||
(effect.Effect == SpellEffectName.ApplyAura && effect.ApplyAuraName == AuraType.PeriodicHeal))
AIInfo.Effects |= 1 << ((int)SelectEffect.Healing - 1);
// Make sure that this spell applies an aura.
if (effect.Effect == SpellEffectName.ApplyAura)
AIInfo.Effects |= 1 << ((int)SelectEffect.Aura - 1);
}
AISpellInfo[(spellInfo.Id, spellInfo.Difficulty)] = AIInfo;
});
}
public virtual bool CanAIAttack(Unit victim) { return true; }
@@ -411,7 +486,12 @@ namespace Game.AI
// Called when the dialog status between a player and the creature is requested.
public virtual QuestGiverStatus GetDialogStatus(Player player) { return QuestGiverStatus.ScriptedNoStatus; }
public static AISpellInfoType[] AISpellInfo;
public AISpellInfoType GetAISpellInfo(uint spellId, Difficulty difficulty)
{
return AISpellInfo.LookupByKey((spellId, difficulty));
}
public static Dictionary<(uint id, Difficulty difficulty), AISpellInfoType> AISpellInfo = new Dictionary<(uint id, Difficulty difficulty), AISpellInfoType>();
protected Unit me { get; private set; }
}
@@ -493,7 +573,7 @@ namespace Game.AI
public SpellTargetSelector(Unit caster, uint spellId)
{
_caster = caster;
_spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
_spellInfo = Global.SpellMgr.GetSpellInfo(spellId, caster.GetMap().GetDifficultyID());
Cypher.Assert(_spellInfo != null);
}
+1 -1
View File
@@ -487,7 +487,7 @@ namespace Game.AI
if (knownRank == 0)
return null;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(knownRank);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(knownRank, me.GetMap().GetDifficultyID());
if (spellInfo == null)
return null;
+4 -3
View File
@@ -136,7 +136,8 @@ namespace Game.AI
//Check if each spell is viable(set it to null if not)
for (uint i = 0; i < SharedConst.MaxCreatureSpells; i++)
{
SpellInfo tempSpell = Global.SpellMgr.GetSpellInfo(me.m_spells[i]);
SpellInfo tempSpell = Global.SpellMgr.GetSpellInfo(me.m_spells[i], me.GetMap().GetDifficultyID());
AISpellInfoType aiSpell = GetAISpellInfo(me.m_spells[i], me.GetMap().GetDifficultyID());
//This spell doesn't exist
if (tempSpell == null)
@@ -144,11 +145,11 @@ namespace Game.AI
// Targets and Effects checked first as most used restrictions
//Check the spell targets if specified
if (targets != 0 && !Convert.ToBoolean(Global.ScriptMgr.spellSummaryStorage[me.m_spells[i]].Targets & (1 << ((int)targets - 1))))
if (targets != 0 && !Convert.ToBoolean(aiSpell.Targets & (1 << ((int)targets - 1))))
continue;
//Check the type of spell if we are looking for a specific spell type
if (effect != 0 && !Convert.ToBoolean(Global.ScriptMgr.spellSummaryStorage[me.m_spells[i]].Effects & (1 << ((int)effect - 1))))
if (effect != 0 && !Convert.ToBoolean(aiSpell.Effects & (1 << ((int)effect - 1))))
continue;
//Check for school if specified
+1 -1
View File
@@ -656,7 +656,7 @@ namespace Game.AI
public override void SpellHitTarget(Unit target, SpellInfo spell)
{
GetScript().ProcessEventsFor(SmartEvents.SpellhitTarget, target, 0, 0, false, spell);
GetScript().ProcessEventsFor(SmartEvents.SpellHitTarget, target, 0, 0, false, spell);
}
public override void DamageTaken(Unit attacker, ref uint damage)
+16 -7
View File
@@ -102,7 +102,7 @@ namespace Game.AI
}
case SmartScriptType.Spell:
{
if (!Global.SpellMgr.HasSpellInfo((uint)temp.entryOrGuid))
if (!Global.SpellMgr.HasSpellInfo((uint)temp.entryOrGuid, Difficulty.None))
{
Log.outError(LogFilter.Sql, "SmartAIMgr.LoadSmartAIFromDB: Scene id ({0}) does not exist, skipped loading.", temp.entryOrGuid);
continue;
@@ -505,10 +505,10 @@ namespace Game.AI
return false;
break;
case SmartEvents.SpellHit:
case SmartEvents.SpellhitTarget:
case SmartEvents.SpellHitTarget:
if (e.Event.spellHit.spell != 0)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(e.Event.spellHit.spell);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(e.Event.spellHit.spell, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.ScriptsAi, "SmartAIMgr: Entry {0} SourceType {1} Event {2} Action {3} uses non-existent Spell entry {4}, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.Event.spellHit.spell);
@@ -571,6 +571,15 @@ namespace Game.AI
return false;
break;
case SmartEvents.VictimCasting:
if (e.Event.targetCasting.spellId > 0 && !Global.SpellMgr.HasSpellInfo(e.Event.targetCasting.spellId, Difficulty.None))
{
Log.outError(LogFilter.Sql, $"SmartAIMgr: Entry {e.entryOrGuid} SourceType {e.GetScriptType()} Event {e.event_id} Action {e.GetActionType()} uses non-existent Spell entry {e.Event.spellHit.spell}, skipped.");
return false;
}
if (!IsMinMaxValid(e, e.Event.minMax.repeatMin, e.Event.minMax.repeatMax))
return false;
break;
case SmartEvents.PassengerBoarded:
case SmartEvents.PassengerRemoved:
if (!IsMinMaxValid(e, e.Event.minMax.repeatMin, e.Event.minMax.repeatMax))
@@ -912,8 +921,8 @@ namespace Game.AI
if (!IsSpellValid(e, e.Action.cast.spell))
return false;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(e.Action.cast.spell);
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(e.Action.cast.spell, Difficulty.None);
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect != null && (effect.IsEffect(SpellEffectName.KillCredit) || effect.IsEffect(SpellEffectName.KillCredit2)))
{
@@ -1437,7 +1446,7 @@ namespace Game.AI
}
bool IsSpellValid(SmartScriptHolder e, uint entry)
{
if (!Global.SpellMgr.HasSpellInfo(entry))
if (!Global.SpellMgr.HasSpellInfo(entry, Difficulty.None))
{
Log.outError(LogFilter.ScriptsAi, "SmartAIMgr: Entry {0} SourceType {1} Event {2} Action {3} uses non-existent Spell entry {4}, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry);
return false;
@@ -1599,7 +1608,7 @@ namespace Game.AI
{ SmartEvents.PassengerRemoved, SmartScriptTypeMaskId.Creature },
{ SmartEvents.Charmed, SmartScriptTypeMaskId.Creature },
{ SmartEvents.CharmedTarget, SmartScriptTypeMaskId.Creature },
{ SmartEvents.SpellhitTarget, SmartScriptTypeMaskId.Creature },
{ SmartEvents.SpellHitTarget, SmartScriptTypeMaskId.Creature },
{ SmartEvents.Damaged, SmartScriptTypeMaskId.Creature },
{ SmartEvents.DamagedTarget, SmartScriptTypeMaskId.Creature },
{ SmartEvents.Movementinform, SmartScriptTypeMaskId.Creature },
+2 -2
View File
@@ -501,7 +501,7 @@ namespace Game.AI
// unless target is outside spell range, out of mana, or LOS.
bool _allowMove = false;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(e.Action.cast.spell);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(e.Action.cast.spell, me.GetMap().GetDifficultyID());
var costs = spellInfo.CalcPowerCost(me, spellInfo.GetSchoolMask());
bool hasPower = true;
foreach (var cost in costs)
@@ -3438,7 +3438,7 @@ namespace Game.AI
RecalcTimer(e, e.Event.kill.cooldownMin, e.Event.kill.cooldownMax);
break;
}
case SmartEvents.SpellhitTarget:
case SmartEvents.SpellHitTarget:
case SmartEvents.SpellHit:
{
if (spell == null)
+2 -2
View File
@@ -3046,14 +3046,14 @@ namespace Game.Achievements
case CriteriaDataType.SAura:
case CriteriaDataType.TAura:
{
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(Aura.SpellId);
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(Aura.SpellId, Difficulty.None);
if (spellEntry == null)
{
Log.outError(LogFilter.Sql, "Table `criteria_data` (Entry: {0} Type: {1}) for data type {2} has wrong spell id in value1 ({3}), ignored.",
criteria.Id, criteria.Entry.Type, DataType, Aura.SpellId);
return false;
}
SpellEffectInfo effect = spellEntry.GetEffect(Difficulty.None, Aura.EffectIndex);
SpellEffectInfo effect = spellEntry.GetEffect(Aura.EffectIndex);
if (effect == null)
{
Log.outError(LogFilter.Sql, "Table `criteria_data` (Entry: {0} Type: {1}) for data type {2} has wrong spell effect index in value2 ({3}), ignored.",
+1 -1
View File
@@ -228,7 +228,7 @@ namespace Game.Chat
static bool CheckSpellExistsAndIsValid(CommandHandler handler, uint spellId)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, Difficulty.None);
if (spellInfo == null)
{
handler.SendSysMessage(CypherStrings.CommandNospellfound);
+1 -1
View File
@@ -45,7 +45,7 @@ namespace Game.Chat.Commands
{
case DisableType.Spell:
{
if (!Global.SpellMgr.HasSpellInfo(entry))
if (!Global.SpellMgr.HasSpellInfo(entry, Difficulty.None))
{
handler.SendSysMessage(CypherStrings.CommandNospellfound);
return false;
+8 -10
View File
@@ -41,13 +41,13 @@ namespace Game.Chat.Commands
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
uint spell = handler.ExtractSpellIdFromLink(args);
if (spell == 0 || !Global.SpellMgr.HasSpellInfo(spell))
if (spell == 0 || !Global.SpellMgr.HasSpellInfo(spell, Difficulty.None))
return false;
string all = args.NextString();
bool allRanks = !string.IsNullOrEmpty(all) && all == "all";
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell, Difficulty.None);
if (spellInfo == null || !Global.SpellMgr.IsSpellValid(spellInfo, handler.GetSession().GetPlayer()))
{
handler.SendSysMessage(CypherStrings.CommandSpellBroken, spell);
@@ -78,15 +78,13 @@ namespace Game.Chat.Commands
[Command("gm", RBACPermissions.CommandLearnAllGm)]
static bool HandleLearnAllGMCommand(StringArguments args, CommandHandler handler)
{
foreach (var spellInfo in Global.SpellMgr.GetSpellInfoStorage().Values)
foreach (var skillSpell in Global.SpellMgr.GetSkillLineAbilityMapBounds((uint)SkillType.Internal))
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(skillSpell.Spell, Difficulty.None);
if (spellInfo == null || !Global.SpellMgr.IsSpellValid(spellInfo, handler.GetSession().GetPlayer(), false))
continue;
if (!spellInfo.IsAbilityOfSkillType(SkillType.Internal))
continue;
handler.GetSession().GetPlayer().LearnSpell(spellInfo.Id, false);
handler.GetSession().GetPlayer().LearnSpell(skillSpell.Spell, false);
}
handler.SendSysMessage(CypherStrings.LearningGmSkills);
@@ -228,7 +226,7 @@ namespace Game.Chat.Commands
if (skillLine.ClassMask != 0 && (skillLine.ClassMask & classmask) == 0)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(skillLine.Spell);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(skillLine.Spell, Difficulty.None);
if (spellInfo == null || !Global.SpellMgr.IsSpellValid(spellInfo, player, false))
continue;
@@ -257,7 +255,7 @@ namespace Game.Chat.Commands
foreach (var entry in CliDB.SkillLineAbilityStorage.Values)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(entry.Spell);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(entry.Spell, Difficulty.None);
if (spellInfo == null)
continue;
@@ -295,7 +293,7 @@ namespace Game.Chat.Commands
if (playerClass != talentInfo.ClassID)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID, Difficulty.None);
if (spellInfo == null || !Global.SpellMgr.IsSpellValid(spellInfo, handler.GetSession().GetPlayer(), false))
continue;
+9 -6
View File
@@ -1065,8 +1065,11 @@ namespace Game.Chat
bool found = false;
uint count = 0;
// Search in Spell.dbc
foreach (var spellInfo in Global.SpellMgr.GetSpellInfoStorage().Values)
// Search in SpellName.dbc
foreach (SpellNameRecord spellName in CliDB.SpellNameStorage.Values)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellName.Id, Difficulty.None);
if (spellInfo != null)
{
LocaleConstant locale = handler.GetSessionDbcLocale();
string name = spellInfo.SpellName[locale];
@@ -1102,7 +1105,7 @@ namespace Game.Chat
SpellEffectInfo effect = spellInfo.GetEffect(0);
bool learn = (effect.Effect == SpellEffectName.LearnSpell);
SpellInfo learnSpellInfo = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell);
SpellInfo learnSpellInfo = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell, spellInfo.Difficulty);
bool talent = spellInfo.HasAttribute(SpellCustomAttributes.IsTalent);
bool passive = spellInfo.IsPassive();
@@ -1142,7 +1145,7 @@ namespace Game.Chat
if (!found)
found = true;
}
}
}
if (!found)
handler.SendSysMessage(CypherStrings.CommandNospellfound);
@@ -1161,7 +1164,7 @@ namespace Game.Chat
uint id = args.NextUInt32();
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(id);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(id, Difficulty.None);
if (spellInfo != null)
{
LocaleConstant locale = handler.GetSessionDbcLocale();
@@ -1176,7 +1179,7 @@ namespace Game.Chat
SpellEffectInfo effect = spellInfo.GetEffect(0);
bool learn = (effect.Effect == SpellEffectName.LearnSpell);
SpellInfo learnSpellInfo = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell);
SpellInfo learnSpellInfo = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell, Difficulty.None);
bool talent = spellInfo.HasAttribute(SpellCustomAttributes.IsTalent);
bool passive = spellInfo.IsPassive();
+3 -3
View File
@@ -1009,7 +1009,7 @@ namespace Game.Chat
if (player.IsInFlight() || player.IsInCombat())
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SPELL_UNSTUCK_ID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SPELL_UNSTUCK_ID, Difficulty.None);
if (spellInfo == null)
return false;
@@ -2065,11 +2065,11 @@ namespace Game.Chat
if (spellid == 0)
return false;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellid);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellid, attacker.GetMap().GetDifficultyID());
if (spellInfo == null)
return false;
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(attacker, target, spellid, spellInfo.GetSpellXSpellVisualId(attacker), spellInfo.SchoolMask);
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(attacker, target, spellInfo, spellInfo.GetSpellXSpellVisualId(attacker), spellInfo.SchoolMask);
damageInfo.damage = damage_;
attacker.DealDamageMods(damageInfo.target, ref damageInfo.damage, ref damageInfo.absorb);
target.DealSpellDamage(damageInfo, true);
+2 -2
View File
@@ -107,7 +107,7 @@ namespace Game.Chat
}
uint spellId = handler.ExtractSpellIdFromLink(args);
if (spellId == 0 || !Global.SpellMgr.HasSpellInfo(spellId))
if (spellId == 0 || !Global.SpellMgr.HasSpellInfo(spellId, Difficulty.None))
return false;
// Check if pet already has it
@@ -118,7 +118,7 @@ namespace Game.Chat
}
// Check if spell is valid
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, Difficulty.None);
if (spellInfo == null || !Global.SpellMgr.IsSpellValid(spellInfo))
{
handler.SendSysMessage(CypherStrings.CommandSpellBroken, spellId);
+4 -4
View File
@@ -57,7 +57,7 @@ namespace Game.Chat
if (spellIid == 0)
return false;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellIid);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellIid, target.GetMap().GetDifficultyID());
if (spellInfo == null)
{
handler.SendSysMessage(CypherStrings.UnknownSpell, owner == handler.GetSession().GetPlayer() ? handler.GetCypherString(CypherStrings.You) : nameLink);
@@ -72,7 +72,7 @@ namespace Game.Chat
}
[CommandNonGroup("aura", RBACPermissions.CommandAura)]
static bool Auracommand(StringArguments args, CommandHandler handler)
static bool HandleAuraCommand(StringArguments args, CommandHandler handler)
{
Unit target = handler.GetSelectedUnit();
if (!target)
@@ -85,11 +85,11 @@ namespace Game.Chat
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
uint spellId = handler.ExtractSpellIdFromLink(args);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, target.GetMap().GetDifficultyID());
if (spellInfo != null)
{
ObjectGuid castId = ObjectGuid.Create(HighGuid.Cast, SpellCastSource.Normal, target.GetMapId(), spellId, target.GetMap().GenerateLowGuid(HighGuid.Cast));
Aura.TryRefreshStackOrCreate(spellInfo, castId, SpellConst.MaxEffectMask, target, target);
Aura.TryRefreshStackOrCreate(spellInfo, castId, SpellConst.MaxEffectMask, target, target, target.GetMap().GetDifficultyID());
}
return true;
+1 -1
View File
@@ -275,7 +275,7 @@ namespace Game.Combat
threat *= threatEntry.pctMod;
// Energize is not affected by Mods
foreach (SpellEffectInfo effect in threatSpell.GetEffectsForDifficulty(hatedUnit.GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in threatSpell.GetEffects())
if (effect != null && (effect.Effect == SpellEffectName.Energize || effect.ApplyAuraName == AuraType.PeriodicEnergize))
return threat;
+13 -11
View File
@@ -575,10 +575,10 @@ namespace Game
}
bool AddToSpellImplicitTargetConditions(Condition cond)
{
Global.SpellMgr.ForEachSpellInfoDifficulty((uint)cond.SourceEntry, spellInfo =>
{
uint conditionEffMask = cond.SourceGroup;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)cond.SourceEntry);
Cypher.Assert(spellInfo != null);
List<uint> sharedMasks = new List<uint>();
for (byte i = 0; i < SpellConst.MaxEffects; ++i)
{
@@ -607,6 +607,7 @@ namespace Game
SpellEffectInfo inner = spellInfo.GetEffect(effIndex);
if (inner == null)
continue;
if (inner.ImplicitTargetConditions == cmp)
sharedMask |= (uint)(1 << effIndex);
}
@@ -625,7 +626,7 @@ namespace Game
break;
if (firstEffIndex >= SpellConst.MaxEffects)
return false;
return;
SpellEffectInfo effect = spellInfo.GetEffect(firstEffIndex);
if (effect == null)
@@ -642,7 +643,7 @@ namespace Game
{
Log.outError(LogFilter.Sql, "{0} in `condition` table, has incorrect SourceGroup {1} (spell effectMask) set - " +
"effect masks are overlapping (all SourceGroup values having given bit set must be equal) - ignoring.", cond.ToString(), cond.SourceGroup);
return false;
return;
}
}
// no data for shared mask, we can create new submask
@@ -671,6 +672,7 @@ namespace Game
break;
}
}
});
return true;
}
@@ -929,7 +931,7 @@ namespace Game
}
case ConditionSourceType.SpellImplicitTarget:
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)cond.SourceEntry);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)cond.SourceEntry, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Sql, "{0} SourceEntry in `condition` table does not exist in `spell.dbc`, ignoring.", cond.ToString());
@@ -949,7 +951,7 @@ namespace Game
if (((1 << i) & cond.SourceGroup) == 0)
continue;
SpellEffectInfo effect = spellInfo.GetEffect(Difficulty.None, i);
SpellEffectInfo effect = spellInfo.GetEffect(i);
if (effect == null)
continue;
@@ -998,7 +1000,7 @@ namespace Game
case ConditionSourceType.Spell:
case ConditionSourceType.SpellProc:
{
SpellInfo spellProto = Global.SpellMgr.GetSpellInfo((uint)cond.SourceEntry);
SpellInfo spellProto = Global.SpellMgr.GetSpellInfo((uint)cond.SourceEntry, Difficulty.None);
if (spellProto == null)
{
Log.outError(LogFilter.Sql, "{0} SourceEntry in `condition` table does not exist in `spell.dbc`, ignoring.", cond.ToString());
@@ -1020,7 +1022,7 @@ namespace Game
return false;
}
if (!Global.SpellMgr.HasSpellInfo((uint)cond.SourceEntry))
if (!Global.SpellMgr.HasSpellInfo((uint)cond.SourceEntry, Difficulty.None))
{
Log.outError(LogFilter.Sql, "{0} SourceEntry in `condition` table does not exist in `spell.dbc`, ignoring.", cond.ToString());
return false;
@@ -1033,7 +1035,7 @@ namespace Game
return false;
}
if (!Global.SpellMgr.HasSpellInfo((uint)cond.SourceEntry))
if (!Global.SpellMgr.HasSpellInfo((uint)cond.SourceEntry, Difficulty.None))
{
Log.outError(LogFilter.Sql, "{0} SourceEntry in `condition` table does not exist in `spell.dbc`, ignoring.", cond.ToString());
return false;
@@ -1093,7 +1095,7 @@ namespace Game
{
case ConditionTypes.Aura:
{
if (!Global.SpellMgr.HasSpellInfo(cond.ConditionValue1))
if (!Global.SpellMgr.HasSpellInfo(cond.ConditionValue1, Difficulty.None))
{
Log.outError(LogFilter.Sql, "{0} has non existing spell (Id: {1}), skipped", cond.ToString(), cond.ConditionValue1);
return false;
@@ -1268,7 +1270,7 @@ namespace Game
}
case ConditionTypes.Spell:
{
if (!Global.SpellMgr.HasSpellInfo(cond.ConditionValue1))
if (!Global.SpellMgr.HasSpellInfo(cond.ConditionValue1, Difficulty.None))
{
Log.outError(LogFilter.Sql, "{0} has non existing spell (Id: {1}), skipped", cond.ToString(true), cond.ConditionValue1);
return false;
+1 -1
View File
@@ -73,7 +73,7 @@ namespace Game
switch (type)
{
case DisableType.Spell:
if (!(Global.SpellMgr.HasSpellInfo(entry) || flags.HasAnyFlag<byte>(DisableFlags.SpellDeprecatedSpell)))
if (!(Global.SpellMgr.HasSpellInfo(entry, Difficulty.None) || flags.HasAnyFlag<byte>(DisableFlags.SpellDeprecatedSpell)))
{
Log.outError(LogFilter.Sql, "Spell entry {0} from `disables` doesn't exist in dbc, skipped.", entry);
continue;
-73
View File
@@ -473,30 +473,6 @@ namespace Game.DataStorage
foreach (SpellClassOptionsRecord classOption in CliDB.SpellClassOptionsStorage.Values)
_spellFamilyNames.Add(classOption.SpellClassSet);
foreach (SpellPowerRecord power in CliDB.SpellPowerStorage.Values)
{
SpellPowerDifficultyRecord powerDifficulty = CliDB.SpellPowerDifficultyStorage.LookupByKey(power.Id);
if (powerDifficulty != null)
{
if (!_spellPowerDifficulties.ContainsKey(power.SpellID))
_spellPowerDifficulties[power.SpellID] = new Dictionary<uint, List<SpellPowerRecord>>();
if (!_spellPowerDifficulties[power.SpellID].ContainsKey(powerDifficulty.DifficultyID))
_spellPowerDifficulties[power.SpellID][powerDifficulty.DifficultyID] = new List<SpellPowerRecord>();
_spellPowerDifficulties[power.SpellID][powerDifficulty.DifficultyID].Insert(powerDifficulty.OrderIndex, power);
}
else
{
if (!_spellPowers.ContainsKey(power.SpellID))
_spellPowers[power.SpellID] = new List<SpellPowerRecord>();
_spellPowers[power.SpellID].Insert(power.OrderIndex, power);
}
}
CliDB.SpellPowerStorage.Clear();
foreach (SpellProcsPerMinuteModRecord ppmMod in CliDB.SpellProcsPerMinuteModStorage.Values)
_spellProcsPerMinuteMods.Add(ppmMod.SpellProcsPerMinuteID, ppmMod);
@@ -1745,53 +1721,6 @@ namespace Game.DataStorage
return _spellFamilyNames.Contains((byte)family);
}
public List<SpellPowerRecord> GetSpellPowers(uint spellId, Difficulty difficulty = Difficulty.None)
{
return GetSpellPowers(spellId, difficulty, out _);
}
public List<SpellPowerRecord> GetSpellPowers(uint spellId, Difficulty difficulty, out bool hasDifficultyPowers)
{
SpellPowerRecord[] powers = new SpellPowerRecord[0];
hasDifficultyPowers = false;
var difficultyDic = _spellPowerDifficulties.LookupByKey(spellId);
if (difficultyDic != null)
{
hasDifficultyPowers = true;
DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(difficulty);
while (difficultyEntry != null)
{
var powerDifficultyList = difficultyDic.LookupByKey(difficultyEntry.Id);
if (powerDifficultyList != null)
{
if (powerDifficultyList.Count > powers.Length)
Array.Resize(ref powers, powerDifficultyList.Count);
foreach (SpellPowerRecord difficultyPower in powerDifficultyList)
if (powers[difficultyPower.OrderIndex] == null)
powers[difficultyPower.OrderIndex] = difficultyPower;
}
difficultyEntry = CliDB.DifficultyStorage.LookupByKey(difficultyEntry.FallbackDifficultyID);
}
}
var record = _spellPowers.LookupByKey(spellId);
if (record != null)
{
if (record.Count > powers.Length)
Array.Resize(ref powers, record.Count);
foreach (SpellPowerRecord power in record)
if (powers[power.OrderIndex] == null)
powers[power.OrderIndex] = power;
}
return powers.ToList();
}
public List<SpellProcsPerMinuteModRecord> GetSpellProcsPerMinuteMods(uint spellprocsPerMinuteId)
{
return _spellProcsPerMinuteMods.LookupByKey(spellprocsPerMinuteId);
@@ -2180,8 +2109,6 @@ namespace Game.DataStorage
MultiMap<uint, SpecializationSpellsRecord> _specializationSpellsBySpec = new MultiMap<uint, SpecializationSpellsRecord>();
List<Tuple<int, uint>> _specsBySpecSet = new List<Tuple<int, uint>>();
List<byte> _spellFamilyNames = new List<byte>();
Dictionary<uint, List<SpellPowerRecord>> _spellPowers = new Dictionary<uint, List<SpellPowerRecord>>();
Dictionary<uint, Dictionary<uint, List<SpellPowerRecord>>> _spellPowerDifficulties = new Dictionary<uint, Dictionary<uint, List<SpellPowerRecord>>>();
MultiMap<uint, SpellProcsPerMinuteModRecord> _spellProcsPerMinuteMods = new MultiMap<uint, SpellProcsPerMinuteModRecord>();
List<TalentRecord>[][][] _talentsByPosition = new List<TalentRecord>[(int)Class.Max][][];
List<uint> _toys = new List<uint>();
@@ -539,9 +539,9 @@ namespace Game.Entities
switch (action.TargetType)
{
case AreaTriggerActionUserTypes.Friend:
return caster._IsValidAssistTarget(unit, Global.SpellMgr.GetSpellInfo(action.Param));
return caster._IsValidAssistTarget(unit, Global.SpellMgr.GetSpellInfo(action.Param, caster.GetMap().GetDifficultyID()));
case AreaTriggerActionUserTypes.Enemy:
return caster._IsValidAttackTarget(unit, Global.SpellMgr.GetSpellInfo(action.Param));
return caster._IsValidAttackTarget(unit, Global.SpellMgr.GetSpellInfo(action.Param, caster.GetMap().GetDifficultyID()));
case AreaTriggerActionUserTypes.Raid:
return caster.IsInRaidWith(unit);
case AreaTriggerActionUserTypes.Party:
+9 -9
View File
@@ -1760,7 +1760,7 @@ namespace Game.Entities
return false;
bool immunedToAllEffects = true;
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect == null || !effect.IsEffect())
continue;
@@ -1780,7 +1780,7 @@ namespace Game.Entities
public override bool IsImmunedToSpellEffect(SpellInfo spellInfo, uint index, Unit caster)
{
SpellEffectInfo effect = spellInfo.GetEffect(GetMap().GetDifficultyID(), index);
SpellEffectInfo effect = spellInfo.GetEffect(index);
if (effect == null)
return true;
@@ -1816,7 +1816,7 @@ namespace Game.Entities
{
if (m_spells[i] == 0)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(m_spells[i]);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(m_spells[i], GetMap().GetDifficultyID());
if (spellInfo == null)
{
Log.outError(LogFilter.Unit, "WORLD: unknown spell id {0}", m_spells[i]);
@@ -1824,7 +1824,7 @@ namespace Game.Entities
}
bool bcontinue = true;
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect != null && ((effect.Effect == SpellEffectName.SchoolDamage) || (effect.Effect == SpellEffectName.Instakill)
|| (effect.Effect == SpellEffectName.EnvironmentalDamage) || (effect.Effect == SpellEffectName.HealthLeech)))
@@ -1865,7 +1865,7 @@ namespace Game.Entities
{
if (m_spells[i] == 0)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(m_spells[i]);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(m_spells[i], GetMap().GetDifficultyID());
if (spellInfo == null)
{
Log.outError(LogFilter.Unit, "WORLD: unknown spell id {0}", m_spells[i]);
@@ -1873,7 +1873,7 @@ namespace Game.Entities
}
bool bcontinue = true;
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect != null && effect.Effect == SpellEffectName.Heal)
{
@@ -2209,7 +2209,7 @@ namespace Game.Entities
{
foreach (var id in cainfo.auras)
{
SpellInfo AdditionalSpellInfo = Global.SpellMgr.GetSpellInfo(id);
SpellInfo AdditionalSpellInfo = Global.SpellMgr.GetSpellInfo(id, GetMap().GetDifficultyID());
if (AdditionalSpellInfo == null)
{
Log.outError(LogFilter.Sql, "Creature ({0}) has wrong spell {1} defined in `auras` field.", GetGUID().ToString(), id);
@@ -2593,7 +2593,7 @@ namespace Game.Entities
if (spellID == 0)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellID, GetMap().GetDifficultyID());
if (spellInfo != null)
{
if (spellInfo.GetRecoveryTime() == 0 // No cooldown
@@ -2771,7 +2771,7 @@ namespace Game.Entities
SpellInfo spellInfo = focusSpell.GetSpellInfo();
// don't use spell focus for vehicle spells
if (spellInfo.HasAura(Difficulty.None, AuraType.ControlVehicle))
if (spellInfo.HasAura(AuraType.ControlVehicle))
return;
if ((!target || target == this) && focusSpell.GetCastTime() == 0) // instant cast, untargeted (or self-targeted) spell doesn't need any facing updates
+5 -11
View File
@@ -442,18 +442,12 @@ namespace Game.Misc
packet.SuggestedPartyMembers = quest.SuggestedPlayers;
// RewardSpell can teach multiple spells in trigger spell effects. But not all effects must be SPELL_EFFECT_LEARN_SPELL. See example spell 33950
if (quest.RewardSpell != 0)
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.RewardSpell, Difficulty.None);
if (spellInfo != null)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.RewardSpell);
if (spellInfo.HasEffect(SpellEffectName.LearnSpell))
{
var effects = spellInfo.GetEffectsForDifficulty(Difficulty.None);
foreach (var spellEffectInfo in effects)
{
if (spellEffectInfo.IsEffect(SpellEffectName.LearnSpell))
packet.LearnSpells.Add(spellEffectInfo.TriggerSpell);
}
}
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
if (effect.IsEffect(SpellEffectName.LearnSpell))
packet.LearnSpells.Add(effect.TriggerSpell);
}
quest.BuildQuestRewards(packet.Rewards, _session.GetPlayer());
+3 -3
View File
@@ -15,7 +15,7 @@ namespace Game.Entities
public Array<uint> ReqAbility = new Array<uint>(3);
public byte ReqLevel;
public bool IsCastable() { return Global.SpellMgr.GetSpellInfo(SpellId).HasEffect(SpellEffectName.LearnSpell); }
public bool IsCastable() { return Global.SpellMgr.GetSpellInfo(SpellId, Difficulty.None).HasEffect(SpellEffectName.LearnSpell); }
}
public class Trainer
@@ -98,7 +98,7 @@ namespace Game.Entities
if (state != TrainerSpellState.Available)
return false;
SpellInfo trainerSpellInfo = Global.SpellMgr.GetSpellInfo(trainerSpell.SpellId);
SpellInfo trainerSpellInfo = Global.SpellMgr.GetSpellInfo(trainerSpell.SpellId, Difficulty.None);
if (trainerSpellInfo.IsPrimaryProfessionFirstRank() && player.GetFreePrimaryProfessionPoints() == 0)
return false;
@@ -129,7 +129,7 @@ namespace Game.Entities
// check ranks
bool hasLearnSpellEffect = false;
bool knowsAllLearnedSpells = true;
foreach (SpellEffectInfo spellEffect in Global.SpellMgr.GetSpellInfo(trainerSpell.SpellId).GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo spellEffect in Global.SpellMgr.GetSpellInfo(trainerSpell.SpellId, Difficulty.None).GetEffects())
{
if (spellEffect == null || !spellEffect.IsEffect(SpellEffectName.LearnSpell))
continue;
+1 -1
View File
@@ -239,7 +239,7 @@ namespace Game.Entities
public SpellInfo GetSpellInfo()
{
return Global.SpellMgr.GetSpellInfo(GetSpellId());
return Global.SpellMgr.GetSpellInfo(GetSpellId(), GetMap().GetDifficultyID());
}
public override void BuildValuesCreate(WorldPacket data, Player target)
@@ -1215,7 +1215,7 @@ namespace Game.Entities
if (trapInfo == null || trapInfo.type != GameObjectTypes.Trap)
return;
SpellInfo trapSpell = Global.SpellMgr.GetSpellInfo(trapInfo.Trap.spell);
SpellInfo trapSpell = Global.SpellMgr.GetSpellInfo(trapInfo.Trap.spell, GetMap().GetDifficultyID());
if (trapSpell == null) // checked at load already
return;
@@ -1945,7 +1945,7 @@ namespace Game.Entities
if (spellId == 0)
return;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
if (spellInfo == null)
{
if (!user.IsTypeId(TypeId.Player) || !Global.OutdoorPvPMgr.HandleCustomSpell(user.ToPlayer(), spellId, this))
@@ -1972,12 +1972,12 @@ namespace Game.Entities
public void CastSpell(Unit target, uint spellId, TriggerCastFlags triggered)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
if (spellInfo == null)
return;
bool self = false;
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect != null && effect.TargetA.GetTarget() == Targets.UnitCaster)
{
+2 -2
View File
@@ -2340,7 +2340,7 @@ namespace Game.Entities
if (eff.SetBonuses.Contains(itemSetSpell))
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(itemSetSpell.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(itemSetSpell.SpellID, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Player, "WORLD: unknown spell id {0} in items set {1} effects", itemSetSpell.SpellID, setid);
@@ -2392,7 +2392,7 @@ namespace Game.Entities
if (!eff.SetBonuses.Contains(itemSetSpell))
continue;
player.ApplyEquipSpell(Global.SpellMgr.GetSpellInfo(itemSetSpell.SpellID), null, false);
player.ApplyEquipSpell(Global.SpellMgr.GetSpellInfo(itemSetSpell.SpellID, Difficulty.None), null, false);
eff.SetBonuses.Remove(itemSetSpell);
}
@@ -2093,10 +2093,10 @@ namespace Game.Entities
CreatureTemplate cinfo = unit.ToCreature().GetCreatureTemplate();
// this also applies for transform auras
SpellInfo transform = Global.SpellMgr.GetSpellInfo(unit.GetTransForm());
SpellInfo transform = Global.SpellMgr.GetSpellInfo(unit.GetTransForm(), unit.GetMap().GetDifficultyID());
if (transform != null)
{
foreach (SpellEffectInfo effect in transform.GetEffectsForDifficulty(unit.GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in transform.GetEffects())
{
if (effect != null && effect.IsAura(AuraType.Transform))
{
+21 -13
View File
@@ -146,7 +146,7 @@ namespace Game.Entities
return false;
uint summonSpellId = result.Read<uint>(14);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(summonSpellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(summonSpellId, owner.GetMap().GetDifficultyID());
bool isTemporarySummon = spellInfo != null && spellInfo.GetDuration() > 0;
if (current && isTemporarySummon)
@@ -887,15 +887,22 @@ namespace Game.Entities
AuraKey key = new AuraKey(casterGuid, itemGuid, result.Read<uint>(1), result.Read<uint>(2));
uint recalculateMask = result.Read<uint>(3);
byte stackCount = result.Read<byte>(4);
int maxDuration = result.Read<int>(5);
int remainTime = result.Read<int>(6);
byte remainCharges = result.Read<byte>(7);
Difficulty difficulty = (Difficulty)result.Read<byte>(4);
byte stackCount = result.Read<byte>(5);
int maxDuration = result.Read<int>(6);
int remainTime = result.Read<int>(7);
byte remainCharges = result.Read<byte>(8);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(key.SpellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(key.SpellId, difficulty);
if (spellInfo == null)
{
Log.outError(LogFilter.Pet, "Unknown aura (spellid {0}), ignore.", key.SpellId);
Log.outError(LogFilter.Pet, "Pet._LoadAuras: Unknown aura (spellid {0}), ignore.", key.SpellId);
continue;
}
if (difficulty != Difficulty.None && !CliDB.DifficultyStorage.ContainsKey(difficulty))
{
Log.outError(LogFilter.Pet, $"Pet._LoadAuras: Unknown difficulty {difficulty} (spellid {key.SpellId}), ignore.");
continue;
}
@@ -919,7 +926,7 @@ namespace Game.Entities
var info = effectInfo[key];
ObjectGuid castId = ObjectGuid.Create(HighGuid.Cast, SpellCastSource.Normal, GetMapId(), spellInfo.Id, GetMap().GenerateLowGuid(HighGuid.Cast));
Aura aura = Aura.TryCreate(spellInfo, castId, key.EffectMask, this, null, info.BaseAmounts, null, casterGuid);
Aura aura = Aura.TryCreate(spellInfo, castId, key.EffectMask, this, null, difficulty, info.BaseAmounts, null, casterGuid);
if (aura != null)
{
if (!aura.CanBeSaved())
@@ -969,6 +976,7 @@ namespace Game.Entities
stmt.AddValue(index++, key.SpellId);
stmt.AddValue(index++, key.EffectMask);
stmt.AddValue(index++, recalculateMask);
stmt.AddValue(index++, aura.GetCastDifficulty());
stmt.AddValue(index++, aura.GetStackAmount());
stmt.AddValue(index++, aura.GetMaxDuration());
stmt.AddValue(index++, aura.GetDuration());
@@ -996,7 +1004,7 @@ namespace Game.Entities
bool AddSpell(uint spellId, ActiveStates active = ActiveStates.Decide, PetSpellState state = PetSpellState.New, PetSpellType type = PetSpellType.Normal)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, Difficulty.None);
if (spellInfo == null)
{
// do pet spell book cleanup
@@ -1062,7 +1070,7 @@ namespace Game.Entities
if (pair.Value.state == PetSpellState.Removed)
continue;
SpellInfo oldRankSpellInfo = Global.SpellMgr.GetSpellInfo(pair.Key);
SpellInfo oldRankSpellInfo = Global.SpellMgr.GetSpellInfo(pair.Key, Difficulty.None);
if (oldRankSpellInfo == null)
continue;
@@ -1156,7 +1164,7 @@ namespace Game.Entities
{
for (byte i = 0; i < SharedConst.MaxCreatureSpellDataSlots; ++i)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(defSpells.spellid[i]);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(defSpells.spellid[i], Difficulty.None);
if (spellInfo == null)
continue;
@@ -1254,7 +1262,7 @@ namespace Game.Entities
GetCharmInfo().SetActionBar(i, 0, ActiveStates.Passive);
else if (ab.GetActiveState() == ActiveStates.Enabled)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(ab.GetAction());
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(ab.GetAction(), Difficulty.None);
if (spellInfo != null)
ToggleAutocast(spellInfo, true);
}
@@ -1518,7 +1526,7 @@ namespace Game.Entities
{
foreach (var specSpell in specSpells)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(specSpell.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(specSpell.SpellID, Difficulty.None);
if (spellInfo == null || spellInfo.SpellLevel > GetLevel())
continue;
+16 -8
View File
@@ -499,20 +499,27 @@ namespace Game.Entities
itemGuid.SetRawValue(auraResult.Read<byte[]>(1));
AuraKey key = new AuraKey(casterGuid, itemGuid, auraResult.Read<uint>(2), auraResult.Read<uint>(3));
uint recalculateMask = auraResult.Read<uint>(4);
byte stackCount = auraResult.Read<byte>(5);
int maxDuration = auraResult.Read<int>(6);
int remainTime = auraResult.Read<int>(7);
byte remainCharges = auraResult.Read<byte>(8);
uint castItemId = auraResult.Read<uint>(9);
int castItemLevel = auraResult.Read<int>(10);
Difficulty difficulty = (Difficulty)auraResult.Read<byte>(5);
byte stackCount = auraResult.Read<byte>(6);
int maxDuration = auraResult.Read<int>(7);
int remainTime = auraResult.Read<int>(8);
byte remainCharges = auraResult.Read<byte>(9);
uint castItemId = auraResult.Read<uint>(10);
int castItemLevel = auraResult.Read<int>(11);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(key.SpellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(key.SpellId, difficulty);
if (spellInfo == null)
{
Log.outError(LogFilter.Player, "Unknown aura (spellid {0}), ignore.", key.SpellId);
continue;
}
if (difficulty != Difficulty.None && !CliDB.DifficultyStorage.ContainsKey(difficulty))
{
Log.outError(LogFilter.Player, $"Player._LoadAuras: Player '{GetName()}' ({GetGUID()}) has an invalid aura difficulty {difficulty} (SpellID: {key.SpellId}), ignoring.");
continue;
}
// negative effects should continue counting down after logout
if (remainTime != -1 && !spellInfo.IsPositive())
{
@@ -535,7 +542,7 @@ namespace Game.Entities
AuraLoadEffectInfo info = effectInfo[key];
ObjectGuid castId = ObjectGuid.Create(HighGuid.Cast, SpellCastSource.Normal, GetMapId(), spellInfo.Id, GetMap().GenerateLowGuid(HighGuid.Cast));
Aura aura = Aura.TryCreate(spellInfo, castId, key.EffectMask, this, null, info.BaseAmounts, null, casterGuid, itemGuid, castItemId, castItemLevel);
Aura aura = Aura.TryCreate(spellInfo, castId, key.EffectMask, this, null, difficulty, info.BaseAmounts, null, casterGuid, itemGuid, castItemId, castItemLevel);
if (aura != null)
{
if (!aura.CanBeSaved())
@@ -1738,6 +1745,7 @@ namespace Game.Entities
stmt.AddValue(index++, key.SpellId);
stmt.AddValue(index++, key.EffectMask);
stmt.AddValue(index++, recalculateMask);
stmt.AddValue(index++, aura.GetCastDifficulty());
stmt.AddValue(index++, aura.GetStackAmount());
stmt.AddValue(index++, aura.GetMaxDuration());
stmt.AddValue(index++, aura.GetDuration());
+9 -8
View File
@@ -1634,7 +1634,7 @@ namespace Game.Entities
if (pProto != null && IsInCombat() && (pProto.GetClass() == ItemClass.Weapon || pProto.GetInventoryType() == InventoryType.Relic) && m_weaponChangeTimer == 0)
{
uint cooldownSpell = (uint)(GetClass() == Class.Rogue ? 6123 : 6119);
var spellProto = Global.SpellMgr.GetSpellInfo(cooldownSpell);
var spellProto = Global.SpellMgr.GetSpellInfo(cooldownSpell, Difficulty.None);
if (spellProto == null)
Log.outError(LogFilter.Player, "Weapon switch cooldown spell {0} couldn't be found in Spell.dbc", cooldownSpell);
@@ -4272,11 +4272,11 @@ namespace Game.Entities
continue;
// check if it is valid spell
SpellInfo spellproto = Global.SpellMgr.GetSpellInfo((uint)effectData.SpellID);
SpellInfo spellproto = Global.SpellMgr.GetSpellInfo((uint)effectData.SpellID, Difficulty.None);
if (spellproto == null)
continue;
if (spellproto.HasAura(GetMap().GetDifficultyID(), AuraType.ModXpPct) && !GetSession().GetCollectionMgr().CanApplyHeirloomXpBonus(item.GetEntry(), GetLevel())
if (spellproto.HasAura(AuraType.ModXpPct) && !GetSession().GetCollectionMgr().CanApplyHeirloomXpBonus(item.GetEntry(), GetLevel())
&& Global.DB2Mgr.GetHeirloomByItemId(item.GetEntry()) != null)
continue;
@@ -4336,10 +4336,11 @@ namespace Game.Entities
DateTime now = GameTime.GetGameTimeSteadyPoint();
foreach (ItemEffectRecord effectData in pItem.GetEffects())
{
SpellInfo effectSpellInfo = Global.SpellMgr.GetSpellInfo((uint)effectData.SpellID, Difficulty.None);
// apply proc cooldown to equip auras if we have any
if (effectData.TriggerType == ItemSpelltriggerType.OnEquip)
{
SpellProcEntry procEntry = Global.SpellMgr.GetSpellProcEntry((uint)effectData.SpellID);
SpellProcEntry procEntry = Global.SpellMgr.GetSpellProcEntry(effectSpellInfo);
if (procEntry == null)
continue;
@@ -4358,7 +4359,7 @@ namespace Game.Entities
continue;
// Don't replace longer cooldowns by equip cooldown if we have any.
if (GetSpellHistory().GetRemainingCooldown(Global.SpellMgr.GetSpellInfo((uint)effectData.SpellID)) > 30 * Time.InMilliseconds)
if (GetSpellHistory().GetRemainingCooldown(effectSpellInfo) > 30 * Time.InMilliseconds)
continue;
GetSpellHistory().AddCooldown((uint)effectData.SpellID, pItem.GetEntry(), TimeSpan.FromSeconds(30));
@@ -5468,7 +5469,7 @@ namespace Game.Entities
public void ApplyArtifactPowerRank(Item artifact, ArtifactPowerRankRecord artifactPowerRank, bool apply)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(artifactPowerRank.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(artifactPowerRank.SpellID, Difficulty.None);
if (spellInfo == null)
return;
@@ -5597,7 +5598,7 @@ namespace Game.Entities
void ApplyAzeriteEssencePower(AzeriteItem item, AzeriteEssencePowerRecord azeriteEssencePower, bool major, bool apply)
{
SpellInfo powerSpell = Global.SpellMgr.GetSpellInfo(azeriteEssencePower.MinorPowerDescription);
SpellInfo powerSpell = Global.SpellMgr.GetSpellInfo(azeriteEssencePower.MinorPowerDescription, Difficulty.None);
if (powerSpell != null)
{
if (apply)
@@ -5608,7 +5609,7 @@ namespace Game.Entities
if (major)
{
powerSpell = Global.SpellMgr.GetSpellInfo(azeriteEssencePower.MajorPowerDescription);
powerSpell = Global.SpellMgr.GetSpellInfo(azeriteEssencePower.MajorPowerDescription, Difficulty.None);
if (powerSpell != null)
{
if (powerSpell.IsPassive())
+2 -2
View File
@@ -379,7 +379,7 @@ namespace Game.Entities
bool AddPvpTalent(PvpTalentRecord talent, byte activeTalentGroup, byte slot)
{
//ASSERT(talent);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talent.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talent.SpellID, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Spells, $"Player.AddPvpTalent: Spell (ID: {talent.SpellID}) does not exist.");
@@ -406,7 +406,7 @@ namespace Game.Entities
void RemovePvpTalent(PvpTalentRecord talent)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talent.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talent.SpellID, Difficulty.None);
if (spellInfo == null)
return;
+9 -9
View File
@@ -93,13 +93,13 @@ namespace Game.Entities
return;
}
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)spell_id);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)spell_id, Difficulty.None);
if (spellInfo == null)
return;
// check learned spells state
bool found = false;
foreach (SpellEffectInfo eff in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo eff in spellInfo.GetEffects())
{
if (eff != null && eff.Effect == SpellEffectName.LearnSpell && !HasSpell(eff.TriggerSpell))
{
@@ -784,16 +784,16 @@ namespace Game.Entities
if (quest.SourceSpellID > 0)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.SourceSpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.SourceSpellID, GetMap().GetDifficultyID());
Unit caster = this;
if (questGiver != null && questGiver.IsTypeMask(TypeMask.Unit) && !quest.HasFlag(QuestFlags.PlayerCastOnAccept) && !spellInfo.HasTargetType(Targets.UnitCaster) && !spellInfo.HasTargetType(Targets.DestCasterSummon))
{
Unit unit = questGiver.ToUnit();
if (unit != null)
unit.CastSpell(this, quest.SourceSpellID, true);
caster = unit;
}
caster.CastSpell(this, quest.SourceSpellID, true);
caster.CastSpell(this, spellInfo, true);
}
SetQuestSlot(log_slot, quest_id, qtime);
@@ -1092,7 +1092,7 @@ namespace Game.Entities
// cast spells after mark quest complete (some spells have quest completed state requirements in spell_area data)
if (quest.RewardSpell > 0)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.RewardSpell);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.RewardSpell, GetMap().GetDifficultyID());
Unit caster = this;
if (questGiver != null && questGiver.IsTypeMask(TypeMask.Unit) && !quest.HasFlag(QuestFlags.PlayerCastOnComplete) && !spellInfo.HasTargetType(Targets.UnitCaster))
{
@@ -1101,7 +1101,7 @@ namespace Game.Entities
caster = unit;
}
caster.CastSpell(this, quest.RewardSpell, true);
caster.CastSpell(this, spellInfo, true);
}
else
{
@@ -1109,7 +1109,7 @@ namespace Game.Entities
{
if (quest.RewardDisplaySpell[i] > 0)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.RewardDisplaySpell[i]);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.RewardDisplaySpell[i], GetMap().GetDifficultyID());
Unit caster = this;
if (questGiver != null && questGiver.IsTypeMask(TypeMask.Unit) && !quest.HasFlag(QuestFlags.PlayerCastOnComplete) && !spellInfo.HasTargetType(Targets.UnitCaster))
{
@@ -1118,7 +1118,7 @@ namespace Game.Entities
caster = unit;
}
caster.CastSpell(this, quest.RewardDisplaySpell[i], true);
caster.CastSpell(this, spellInfo, true);
}
}
}
+24 -24
View File
@@ -309,7 +309,7 @@ namespace Game.Entities
{
foreach (uint spellId in overrides)
{
SpellInfo newInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo newInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
if (newInfo != null)
return GetCastSpellInfo(newInfo);
}
@@ -338,7 +338,7 @@ namespace Game.Entities
for (int j = 0; j < specSpells.Count; ++j)
{
SpecializationSpellsRecord specSpell = specSpells[j];
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(specSpell.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(specSpell.SpellID, Difficulty.None);
if (spellInfo == null || spellInfo.SpellLevel > GetLevel())
continue;
@@ -1027,7 +1027,7 @@ namespace Game.Entities
{
if (proto.Effects[idx].SpellID != 0 && proto.Effects[idx].TriggerType == ItemSpelltriggerType.OnUse)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)proto.Effects[idx].SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)proto.Effects[idx].SpellID, Difficulty.None);
if (spellInfo != null)
GetSpellHistory().SendCooldownEvent(spellInfo, m_lastPotionId);
}
@@ -1267,7 +1267,7 @@ namespace Game.Entities
uint SkillValue = GetPureSkillValue((SkillType)_spell_idx.SkillupSkillLineID);
// Alchemy Discoveries here
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(spellid);
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(spellid, Difficulty.None);
if (spellEntry != null && spellEntry.Mechanic == Mechanics.Discovery)
{
uint discoveredSpell = SkillDiscovery.GetSkillDiscoverySpell(_spell_idx.SkillupSkillLineID, spellid, this);
@@ -1507,7 +1507,7 @@ namespace Game.Entities
uint learn_spell_id = (uint)item.GetEffect(0).SpellID;
uint learning_spell_id = (uint)item.GetEffect(1).SpellID;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(learn_spell_id);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(learn_spell_id, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Player, "Player.CastItemUseSpell: Item (Entry: {0}) in have wrong spell id {1}, ignoring ", item.GetEntry(), learn_spell_id);
@@ -1537,7 +1537,7 @@ namespace Game.Entities
if (effectData.TriggerType != ItemSpelltriggerType.OnUse)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)effectData.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)effectData.SpellID, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Player, "Player.CastItemUseSpell: Item (Entry: {0}) in have wrong spell id {1}, ignoring", item.GetEntry(), effectData.SpellID);
@@ -1571,7 +1571,7 @@ namespace Game.Entities
if (pEnchant.Effect[s] != ItemEnchantmentType.UseSpell)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(pEnchant.EffectArg[s]);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(pEnchant.EffectArg[s], Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Player, "Player.CastItemUseSpell Enchant {0}, cast unknown spell {1}", enchant_id, pEnchant.EffectArg[s]);
@@ -1609,7 +1609,7 @@ namespace Game.Entities
if (ability.SkillLine != skillId)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(ability.Spell);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(ability.Spell, Difficulty.None);
if (spellInfo == null)
continue;
@@ -1855,7 +1855,7 @@ namespace Game.Entities
if (pair.Value.State == PlayerSpellState.Removed || pair.Value.Disabled)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(pair.Key);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(pair.Key, Difficulty.None);
if (spellInfo == null || !spellInfo.IsPassive() || spellInfo.EquippedItemClass < 0)
continue;
@@ -2107,7 +2107,7 @@ namespace Game.Entities
uint nextSpell = Global.SpellMgr.GetNextSpellInChain(spellId);
if (nextSpell != 0)
{
SpellInfo spellInfo1 = Global.SpellMgr.GetSpellInfo(nextSpell);
SpellInfo spellInfo1 = Global.SpellMgr.GetSpellInfo(nextSpell, Difficulty.None);
if (HasSpell(nextSpell) && !spellInfo1.HasAttribute(SpellCustomAttributes.IsTalent))
RemoveSpell(nextSpell, disabled, false);
}
@@ -2149,7 +2149,7 @@ namespace Game.Entities
}
// update free primary prof.points (if not overflow setting, can be in case GM use before .learn prof. learning)
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, Difficulty.None);
if (spellInfo != null && spellInfo.IsPrimaryProfessionFirstRank())
{
uint freeProfs = GetFreePrimaryProfessionPoints() + 1;
@@ -2283,7 +2283,7 @@ namespace Game.Entities
// passive spells which apply aura and have an item requirement are to be added manually, instead of casted
if (spellInfo.EquippedItemClass >= 0)
{
foreach (SpellEffectInfo effectInfo in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effectInfo in spellInfo.GetEffects())
{
if (effectInfo != null && effectInfo.IsAura())
{
@@ -2309,7 +2309,7 @@ namespace Game.Entities
bool AddSpell(uint spellId, bool active, bool learning, bool dependent, bool disabled, bool loading = false, uint fromSkill = 0)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, Difficulty.None);
if (spellInfo == null)
{
// do character spell book cleanup (all characters)
@@ -2476,7 +2476,7 @@ namespace Game.Entities
if (_spell.Value.State == PlayerSpellState.Removed)
continue;
SpellInfo i_spellInfo = Global.SpellMgr.GetSpellInfo(_spell.Key);
SpellInfo i_spellInfo = Global.SpellMgr.GetSpellInfo(_spell.Key, Difficulty.None);
if (i_spellInfo == null)
continue;
@@ -2708,7 +2708,7 @@ namespace Game.Entities
public void ApplySpellMod(uint spellId, SpellModOp op, ref int basevalue, Spell spell = null)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
if (spellInfo == null)
return;
@@ -2807,7 +2807,7 @@ namespace Game.Entities
public void ApplySpellMod(uint spellId, SpellModOp op, ref uint basevalue, Spell spell = null)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
if (spellInfo == null)
return;
@@ -2906,7 +2906,7 @@ namespace Game.Entities
public void ApplySpellMod(uint spellId, SpellModOp op, ref float basevalue, Spell spell = null)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
if (spellInfo == null)
return;
@@ -3117,7 +3117,7 @@ namespace Game.Entities
foreach (ItemSetSpellRecord itemSetSpell in eff.SetBonuses)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(itemSetSpell.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(itemSetSpell.SpellID, Difficulty.None);
if (itemSetSpell.ChrSpecID != 0 && itemSetSpell.ChrSpecID != GetPrimarySpecialization())
ApplyEquipSpell(spellInfo, null, false, false); // item set aura is not for current spec
@@ -3137,7 +3137,7 @@ namespace Game.Entities
// remove cooldowns on spells that have < 10 min CD
GetSpellHistory().ResetCooldowns(p =>
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(p.Key);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(p.Key, Difficulty.None);
return spellInfo.RecoveryTime < 10 * Time.Minute * Time.InMilliseconds && spellInfo.CategoryRecoveryTime < 10 * Time.Minute * Time.InMilliseconds;
}, true);
@@ -3329,7 +3329,7 @@ namespace Game.Entities
if (effectData.TriggerType != ItemSpelltriggerType.ChanceOnHit)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)effectData.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)effectData.SpellID, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Player, "WORLD: unknown Item spellid {0}", effectData.SpellID);
@@ -3387,7 +3387,7 @@ namespace Game.Entities
if (entry != null && entry.AttributesMask.HasAnyFlag(EnchantProcAttributes.WhiteHit) && damageInfo.GetSpellInfo() != null)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(pEnchant.EffectArg[s]);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(pEnchant.EffectArg[s], Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Player, "Player.CastItemCombatSpell(GUID: {0}, name: {1}, enchant: {2}): unknown spell {3} is casted, ignoring...",
@@ -3435,8 +3435,8 @@ namespace Game.Entities
for (byte i = 0; i < SpellConst.MaxEffects; ++i)
{
if (spellInfo.GetEffect(Difficulty.None, i).IsEffect())
values.Add(SpellValueMod.BasePoint0 + i, MathFunctions.CalculatePct(spellInfo.GetEffect(Difficulty.None, i).CalcValue(this), effectPct));
if (spellInfo.GetEffect(i).IsEffect())
values.Add(SpellValueMod.BasePoint0 + i, MathFunctions.CalculatePct(spellInfo.GetEffect(i).CalcValue(this), effectPct));
}
}
@@ -3478,7 +3478,7 @@ namespace Game.Entities
foreach (var spellId in smap.Keys)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, Difficulty.None);
if (spellInfo == null)
continue;
@@ -58,7 +58,7 @@ namespace Game.Entities
public bool AddTalent(TalentRecord talent, byte spec, bool learning)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talent.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talent.SpellID, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Spells, "Player.AddTalent: Spell (ID: {0}) does not exist.", talent.SpellID);
@@ -84,14 +84,14 @@ namespace Game.Entities
public void RemoveTalent(TalentRecord talent)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talent.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talent.SpellID, Difficulty.None);
if (spellInfo == null)
return;
RemoveSpell(talent.SpellID, true);
// search for spells that the talent teaches and unlearn them
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
if (effect != null && effect.TriggerSpell > 0 && effect.Effect == SpellEffectName.LearnSpell)
RemoveSpell(effect.TriggerSpell, true);
@@ -294,14 +294,14 @@ namespace Game.Entities
if (talentInfo.SpellID == 0)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID, Difficulty.None);
if (spellInfo == null)
continue;
RemoveSpell(talentInfo.SpellID, true);
// search for spells that the talent teaches and unlearn them
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
if (effect != null && effect.TriggerSpell > 0 && effect.Effect == SpellEffectName.LearnSpell)
RemoveSpell(effect.TriggerSpell, true);
@@ -311,14 +311,14 @@ namespace Game.Entities
foreach (var talentInfo in CliDB.PvpTalentStorage.Values)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID, Difficulty.None);
if (spellInfo == null)
continue;
RemoveSpell(talentInfo.SpellID, true);
// search for spells that the talent teaches and unlearn them
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
if (effect != null && effect.TriggerSpell > 0 && effect.Effect == SpellEffectName.LearnSpell)
RemoveSpell(effect.TriggerSpell, true);
@@ -575,7 +575,7 @@ namespace Game.Entities
continue;
}
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID);
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID, Difficulty.None);
if (spellEntry == null)
{
Log.outError(LogFilter.Player, "Player {0} has unknown talent spell: {1}", GetName(), talentInfo.SpellID);
@@ -597,7 +597,7 @@ namespace Game.Entities
continue;
}
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID);
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID, Difficulty.None);
if (spellEntry == null)
{
Log.outError(LogFilter.Player, $"Player.SendTalentsInfoData: Player '{GetName()}' ({GetGUID()}) has unknown pvp talent spell: {talentInfo.SpellID}");
+5 -5
View File
@@ -1182,7 +1182,7 @@ namespace Game.Entities
for (uint i = 0; i < SharedConst.MaxCreatureSpells; ++i)
{
uint spellId = vehicle.m_spells[i];
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
if (spellInfo == null)
continue;
@@ -1193,7 +1193,7 @@ namespace Game.Entities
}
if (spellInfo.IsPassive())
vehicle.CastSpell(vehicle, spellId, true);
vehicle.CastSpell(vehicle, spellInfo, true);
petSpells.ActionButtons[i] = UnitActionBarEntry.MAKE_UNIT_ACTION_BUTTON(spellId, i + 8);
}
@@ -1429,7 +1429,7 @@ namespace Game.Entities
switch ((ActionButtonType)type)
{
case ActionButtonType.Spell:
if (Global.SpellMgr.GetSpellInfo(action) == null)
if (!Global.SpellMgr.HasSpellInfo(action, Difficulty.None))
{
Log.outError(LogFilter.Player, "Spell action {0} not added into button {1} for player {2} (GUID: {3}): spell not exist", action, button, GetName(), GetGUID());
return false;
@@ -3723,7 +3723,7 @@ namespace Game.Entities
public override bool IsImmunedToSpellEffect(SpellInfo spellInfo, uint index, Unit caster)
{
SpellEffectInfo effect = spellInfo.GetEffect(GetMap().GetDifficultyID(), index);
SpellEffectInfo effect = spellInfo.GetEffect(index);
if (effect == null || !effect.IsEffect())
return false;
@@ -4937,7 +4937,7 @@ namespace Game.Entities
{
//returning of reagents only for players, so best done here
uint spellId = pet ? pet.m_unitData.CreatedBySpell : m_oldpetspell;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
if (spellInfo != null)
{
+3 -3
View File
@@ -913,12 +913,12 @@ namespace Game.Entities
return 0;
int resistMech = 0;
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect == null || !effect.IsEffect())
break;
int effect_mech = (int)spellInfo.GetEffectMechanic(effect.EffectIndex, GetMap().GetDifficultyID());
int effect_mech = (int)spellInfo.GetEffectMechanic(effect.EffectIndex);
if (effect_mech != 0)
{
int temp = GetTotalAuraModifierByMiscValue(AuraType.ModMechanicResistance, effect_mech);
@@ -1451,7 +1451,7 @@ namespace Game.Entities
Aura aura = GetAura(chrSpec.MasterySpellID[i]);
if (aura != null)
{
foreach (SpellEffectInfo effect in aura.GetSpellEffectInfos())
foreach (SpellEffectInfo effect in aura.GetSpellInfo().GetEffects())
{
if (effect == null)
continue;
+3 -3
View File
@@ -75,7 +75,7 @@ namespace Game.Entities
base.InitStats(duration);
// Get spell cast by totem
SpellInfo totemSpell = Global.SpellMgr.GetSpellInfo(GetSpell());
SpellInfo totemSpell = Global.SpellMgr.GetSpellInfo(GetSpell(), GetMap().GetDifficultyID());
if (totemSpell != null)
if (totemSpell.CalcCastTime(GetLevel()) != 0) // If spell has cast time . its an active totem
m_type = TotemType.Active;
@@ -124,7 +124,7 @@ namespace Game.Entities
{
owner.SendAutoRepeatCancel(this);
SpellInfo spell = Global.SpellMgr.GetSpellInfo(m_unitData.CreatedBySpell);
SpellInfo spell = Global.SpellMgr.GetSpellInfo(m_unitData.CreatedBySpell, GetMap().GetDifficultyID());
if (spell != null)
GetSpellHistory().SendCooldownEvent(spell, 0, null, false);
@@ -149,7 +149,7 @@ namespace Game.Entities
if (GetEntry() == 5925)
return false;
SpellEffectInfo effect = spellInfo.GetEffect(GetMap().GetDifficultyID(), index);
SpellEffectInfo effect = spellInfo.GetEffect(index);
if (effect == null)
return true;
+3 -3
View File
@@ -106,7 +106,7 @@ namespace Game.Entities
for (byte i = 0; i < SharedConst.MaxCreatureSpells; ++i)
{
uint spellId = _unit.ToCreature().m_spells[i];
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, _unit.GetMap().GetDifficultyID());
if (spellInfo != null)
{
if (spellInfo.IsPassive())
@@ -133,7 +133,7 @@ namespace Game.Entities
for (uint x = 0; x < SharedConst.MaxSpellCharm; ++x)
{
uint spellId = _unit.ToCreature().m_spells[x];
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, _unit.GetMap().GetDifficultyID());
if (spellInfo == null)
{
@@ -260,7 +260,7 @@ namespace Game.Entities
// check correctness
if (PetActionBar[index].IsActionBarForSpell())
{
SpellInfo spelInfo = Global.SpellMgr.GetSpellInfo(PetActionBar[index].GetAction());
SpellInfo spelInfo = Global.SpellMgr.GetSpellInfo(PetActionBar[index].GetAction(), _unit.GetMap().GetDifficultyID());
if (spelInfo == null)
SetActionBar(index, 0, ActiveStates.Passive);
else if (!spelInfo.IsAutocastable())
+7 -7
View File
@@ -1108,7 +1108,7 @@ namespace Game.Entities
if (!victim.IsTypeId(TypeId.Player))
{
// Part of Evade mechanics. DoT's and Thorns / Retribution Aura do not contribute to this
if (damagetype != DamageEffectType.DOT && damage > 0 && !victim.GetOwnerGUID().IsPlayer() && (spellProto == null || !spellProto.HasAura(GetMap().GetDifficultyID(), AuraType.DamageShield)))
if (damagetype != DamageEffectType.DOT && damage > 0 && !victim.GetOwnerGUID().IsPlayer() && (spellProto == null || !spellProto.HasAura(AuraType.DamageShield)))
victim.ToCreature().SetLastDamagedTime(GameTime.GetGameTime() + SharedConst.MaxAggroResetTime);
victim.AddThreat(this, damage, damageSchoolMask, spellProto);
@@ -2632,7 +2632,7 @@ namespace Game.Entities
uint split_absorb = 0;
DealDamageMods(caster, ref splitDamage, ref split_absorb);
SpellNonMeleeDamage log = new SpellNonMeleeDamage(this, caster, itr.GetSpellInfo().Id, itr.GetBase().GetSpellXSpellVisualId(), damageInfo.GetSchoolMask(), itr.GetBase().GetCastGUID());
SpellNonMeleeDamage log = new SpellNonMeleeDamage(this, caster, itr.GetSpellInfo(), itr.GetBase().GetSpellXSpellVisualId(), damageInfo.GetSchoolMask(), itr.GetBase().GetCastGUID());
CleanDamage cleanDamage = new CleanDamage(splitDamage, 0, WeaponAttackType.BaseAttack, MeleeHitOutcome.Normal);
DealDamage(caster, splitDamage, cleanDamage, DamageEffectType.Direct, damageInfo.GetSchoolMask(), itr.GetSpellInfo(), false);
log.damage = splitDamage;
@@ -2806,7 +2806,7 @@ namespace Game.Entities
if (APbonus != 0) // Can be negative
{
bool normalized = spellProto != null && spellProto.HasEffect(GetMap().GetDifficultyID(), SpellEffectName.NormalizedWeaponDmg);
bool normalized = spellProto != null && spellProto.HasEffect(SpellEffectName.NormalizedWeaponDmg);
DoneFlatBenefit += (int)(APbonus / 3.5f * GetAPMultiplier(attType, normalized));
}
@@ -2986,7 +2986,7 @@ namespace Game.Entities
if (!spellInfo.IsChanneled() && DotDuration > 0)
DotFactor = DotDuration / 15000.0f;
uint DotTicks = spellInfo.GetMaxTicks(GetMap().GetDifficultyID());
uint DotTicks = spellInfo.GetMaxTicks();
if (DotTicks != 0)
DotFactor /= DotTicks;
}
@@ -3051,12 +3051,12 @@ namespace Game.Entities
// can't attack invisible
if (bySpell == null || !bySpell.HasAttribute(SpellAttr6.CanTargetInvisible))
{
if (obj && !obj.CanSeeOrDetect(target, bySpell != null && bySpell.IsAffectingArea(GetMap().GetDifficultyID())))
if (obj && !obj.CanSeeOrDetect(target, bySpell != null && bySpell.IsAffectingArea()))
return false;
else if (!obj)
{
// ignore stealth for aoe spells. Ignore stealth if target is player and unit in combat with same player
bool ignoreStealthCheck = (bySpell != null && bySpell.IsAffectingArea(GetMap().GetDifficultyID())) ||
bool ignoreStealthCheck = (bySpell != null && bySpell.IsAffectingArea()) ||
(target.GetTypeId() == TypeId.Player && target.HasStealthAura() && target.IsInCombat() && IsInCombatWith(target));
if (!CanSeeOrDetect(target, ignoreStealthCheck))
@@ -3185,7 +3185,7 @@ namespace Game.Entities
return false;
// can't assist invisible
if ((bySpell == null || !bySpell.HasAttribute(SpellAttr6.CanTargetInvisible)) && !CanSeeOrDetect(target, bySpell != null && bySpell.IsAffectingArea(GetMap().GetDifficultyID())))
if ((bySpell == null || !bySpell.HasAttribute(SpellAttr6.CanTargetInvisible)) && !CanSeeOrDetect(target, bySpell != null && bySpell.IsAffectingArea()))
return false;
// can't assist dead
+4 -4
View File
@@ -306,7 +306,7 @@ namespace Game.Entities
m_attacker = spellNonMeleeDamage.attacker;
m_victim = spellNonMeleeDamage.target;
m_damage = spellNonMeleeDamage.damage;
m_spellInfo = Global.SpellMgr.GetSpellInfo(spellNonMeleeDamage.SpellId);
m_spellInfo = spellNonMeleeDamage.Spell;
m_schoolMask = spellNonMeleeDamage.schoolMask;
m_damageType = damageType;
m_attackType = attackType;
@@ -450,11 +450,11 @@ namespace Game.Entities
public class SpellNonMeleeDamage
{
public SpellNonMeleeDamage(Unit _attacker, Unit _target, uint _SpellID, uint _SpellXSpellVisualID, SpellSchoolMask _schoolMask, ObjectGuid _castId = default)
public SpellNonMeleeDamage(Unit _attacker, Unit _target, SpellInfo _spellInfo, uint _SpellXSpellVisualID, SpellSchoolMask _schoolMask, ObjectGuid _castId = default)
{
target = _target;
attacker = _attacker;
SpellId = _SpellID;
Spell = _spellInfo;
SpellXSpellVisualID = _SpellXSpellVisualID;
schoolMask = _schoolMask;
castId = _castId;
@@ -464,7 +464,7 @@ namespace Game.Entities
public Unit target;
public Unit attacker;
public ObjectGuid castId;
public uint SpellId;
public SpellInfo Spell;
public uint SpellXSpellVisualID;
public uint damage;
public uint originalDamage;
+4 -4
View File
@@ -194,7 +194,7 @@ namespace Game.Entities
minion.SetSpeedRate(i, m_speed_rate[(int)i]);
// Send infinity cooldown - client does that automatically but after relog cooldown needs to be set again
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(minion.m_unitData.CreatedBySpell);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(minion.m_unitData.CreatedBySpell, GetMap().GetDifficultyID());
if (spellInfo != null && spellInfo.IsCooldownStartedOnEvent())
GetSpellHistory().StartCooldown(spellInfo, 0, null, true);
}
@@ -222,10 +222,10 @@ namespace Game.Entities
else if (minion.IsTotem())
{
// All summoned by totem minions must disappear when it is removed.
SpellInfo spInfo = Global.SpellMgr.GetSpellInfo(minion.ToTotem().GetSpell());
SpellInfo spInfo = Global.SpellMgr.GetSpellInfo(minion.ToTotem().GetSpell(), GetMap().GetDifficultyID());
if (spInfo != null)
{
foreach (SpellEffectInfo effect in spInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spInfo.GetEffects())
{
if (effect == null || effect.Effect != SpellEffectName.Summon)
continue;
@@ -235,7 +235,7 @@ namespace Game.Entities
}
}
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(minion.m_unitData.CreatedBySpell);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(minion.m_unitData.CreatedBySpell, GetMap().GetDifficultyID());
// Remove infinity cooldown
if (spellInfo != null && spellInfo.IsCooldownStartedOnEvent())
GetSpellHistory().SendCooldownEvent(spellInfo);
+41 -42
View File
@@ -36,12 +36,12 @@ namespace Game.Entities
// function uses real base points (typically value - 1)
public int CalculateSpellDamage(Unit target, SpellInfo spellProto, uint effect_index, int? basePoints = null, uint castItemId = 0, int itemLevel = -1)
{
SpellEffectInfo effect = spellProto.GetEffect(GetMap().GetDifficultyID(), effect_index);
SpellEffectInfo effect = spellProto.GetEffect(effect_index);
return effect != null ? effect.CalcValue(this, basePoints, target, castItemId, itemLevel) : 0;
}
public int CalculateSpellDamage(Unit target, SpellInfo spellProto, uint effect_index, out float variance, int? basePoints = null, uint castItemId = 0, int itemLevel = -1)
{
SpellEffectInfo effect = spellProto.GetEffect(GetMap().GetDifficultyID(), effect_index);
SpellEffectInfo effect = spellProto.GetEffect(effect_index);
variance = 0.0f;
return effect != null ? effect.CalcValue(out variance, this, basePoints, target, castItemId, itemLevel) : 0;
}
@@ -466,7 +466,7 @@ namespace Game.Entities
DoneTotal += (int)(DoneAdvertisedBenefit * coeff * stack);
}
foreach (SpellEffectInfo eff in spellProto.GetEffectsForDifficulty(GetMap().GetDifficultyID()))
foreach (SpellEffectInfo eff in spellProto.GetEffects())
{
if (eff == null)
continue;
@@ -586,7 +586,7 @@ namespace Game.Entities
return false;
});
foreach (SpellEffectInfo eff in spellProto.GetEffectsForDifficulty(GetMap().GetDifficultyID()))
foreach (SpellEffectInfo eff in spellProto.GetEffects())
{
if (eff == null)
continue;
@@ -1040,7 +1040,7 @@ namespace Game.Entities
}
public void CastSpell(Unit victim, uint spellId, TriggerCastFlags triggerFlags = TriggerCastFlags.None, Item castItem = null, AuraEffect triggeredByAura = null, ObjectGuid originalCaster = default)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
if (spellInfo == null)
{
Log.outError(LogFilter.Spells, "CastSpell: unknown spell id {0} by caster: {1}", spellId, GetGUID().ToString());
@@ -1061,7 +1061,7 @@ namespace Game.Entities
}
public void CastSpell(float x, float y, float z, uint spellId, bool triggered, Item castItem = null, AuraEffect triggeredByAura = null, ObjectGuid originalCaster = default)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
if (spellInfo == null)
{
Log.outError(LogFilter.Unit, "CastSpell: unknown spell id {0} by caster: {1}", spellId, GetGUID().ToString());
@@ -1074,7 +1074,7 @@ namespace Game.Entities
}
public void CastSpell(GameObject go, uint spellId, bool triggered, Item castItem = null, AuraEffect triggeredByAura = null, ObjectGuid originalCaster = default)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
if (spellInfo == null)
{
Log.outError(LogFilter.Unit, "CastSpell: unknown spell id {0} by caster: {1}", spellId, GetGUID().ToString());
@@ -1111,7 +1111,7 @@ namespace Game.Entities
}
public void CastCustomSpell(uint spellId, Dictionary<SpellValueMod, int> values, Unit victim = null, TriggerCastFlags triggerFlags = TriggerCastFlags.None, Item castItem = null, AuraEffect triggeredByAura = null, ObjectGuid originalCaster = default)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
if (spellInfo == null)
{
Log.outError(LogFilter.Unit, "CastSpell: unknown spell id {0} by caster: {1}", spellId, GetGUID().ToString());
@@ -1152,7 +1152,7 @@ namespace Game.Entities
bool DirectDamage = false;
bool AreaEffect = false;
foreach (SpellEffectInfo effect in spellProto.GetEffectsForDifficulty(GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in spellProto.GetEffects())
{
if (effect == null)
continue;
@@ -1213,7 +1213,7 @@ namespace Game.Entities
CastingTime /= 2;
// 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
foreach (SpellEffectInfo effect in spellProto.GetEffectsForDifficulty(GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in spellProto.GetEffects())
{
if (effect != null && (effect.Effect == SpellEffectName.HealthLeech ||
(effect.Effect == SpellEffectName.ApplyAura && effect.ApplyAuraName == AuraType.PeriodicLeech)))
@@ -1239,7 +1239,7 @@ namespace Game.Entities
bool matches = auraEffect.GetMiscValue() != 0 ? auraEffect.GetMiscValue() == spellInfo.Id : auraEffect.IsAffectingSpell(spellInfo);
if (matches)
{
SpellInfo info = Global.SpellMgr.GetSpellInfo((uint)auraEffect.GetAmount());
SpellInfo info = Global.SpellMgr.GetSpellInfo((uint)auraEffect.GetAmount(), GetMap().GetDifficultyID());
if (info != null)
return info;
}
@@ -1266,7 +1266,7 @@ namespace Game.Entities
{
if (effect.GetMiscValue() == spellInfo.Id)
{
SpellInfo visualSpell = Global.SpellMgr.GetSpellInfo((uint)effect.GetMiscValueB());
SpellInfo visualSpell = Global.SpellMgr.GetSpellInfo((uint)effect.GetMiscValueB(), GetMap().GetDifficultyID());
if (visualSpell != null)
{
spellInfo = visualSpell;
@@ -1512,7 +1512,7 @@ namespace Game.Entities
int gain = victim.ModifyPower(powerType, damage);
int overEnergize = damage - gain;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
victim.GetHostileRefManager().ThreatAssist(this, damage * 0.5f, spellInfo);
SendEnergizeSpellLog(victim, spellId, damage, overEnergize, powerType);
@@ -1583,7 +1583,7 @@ namespace Game.Entities
}
bool immuneToAllEffects = true;
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
// State/effect immunities applied by aura expect full spell immunity
// Ignore effects with mechanic, they are supposed to be checked separately
@@ -1610,7 +1610,7 @@ namespace Game.Entities
if ((pair.Key & schoolMask) == 0)
continue;
SpellInfo immuneSpellInfo = Global.SpellMgr.GetSpellInfo(pair.Value);
SpellInfo immuneSpellInfo = Global.SpellMgr.GetSpellInfo(pair.Value, GetMap().GetDifficultyID());
if (!(immuneSpellInfo != null && immuneSpellInfo.IsPositive() && spellInfo.IsPositive() && caster && IsFriendlyTo(caster)))
if (!spellInfo.CanPierceImmuneAura(immuneSpellInfo))
schoolImmunityMask |= pair.Key;
@@ -1654,7 +1654,7 @@ namespace Game.Entities
if (spellInfo == null)
return false;
SpellEffectInfo effect = spellInfo.GetEffect(GetMap().GetDifficultyID(), index);
SpellEffectInfo effect = spellInfo.GetEffect(index);
if (effect == null || !effect.IsEffect())
return false;
@@ -1731,7 +1731,7 @@ namespace Game.Entities
uint schoolImmunityMask = 0;
var schoolList = m_spellImmune[(int)SpellImmunity.School];
foreach (var pair in schoolList)
if (Convert.ToBoolean(pair.Key & schoolMask) && !spellInfo.CanPierceImmuneAura(Global.SpellMgr.GetSpellInfo(pair.Value)))
if (Convert.ToBoolean(pair.Key & schoolMask) && !spellInfo.CanPierceImmuneAura(Global.SpellMgr.GetSpellInfo(pair.Value, GetMap().GetDifficultyID())))
schoolImmunityMask |= pair.Key;
// // We need to be immune to all types
@@ -2212,7 +2212,7 @@ namespace Game.Entities
if (transformId == 0)
return false;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(transformId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(transformId, GetMap().GetDifficultyID());
if (spellInfo == null)
return false;
@@ -2465,16 +2465,15 @@ namespace Game.Entities
if (!victim.IsAlive() || victim.HasUnitState(UnitState.InFlight) || (victim.IsTypeId(TypeId.Unit) && victim.ToCreature().IsEvadingAttacks()))
return;
SpellInfo spellProto = Global.SpellMgr.GetSpellInfo(damageInfo.SpellId);
if (spellProto == null)
if (damageInfo.Spell == null)
{
Log.outDebug(LogFilter.Unit, "Unit.DealSpellDamage has wrong damageInfo.SpellID: {0}", damageInfo.SpellId);
Log.outDebug(LogFilter.Unit, "Unit.DealSpellDamage has no spell");
return;
}
// Call default DealDamage
CleanDamage cleanDamage = new CleanDamage(damageInfo.cleanDamage, damageInfo.absorb, WeaponAttackType.BaseAttack, MeleeHitOutcome.Normal);
DealDamage(victim, damageInfo.damage, cleanDamage, DamageEffectType.SpellDirect, damageInfo.schoolMask, spellProto, durabilityLoss);
DealDamage(victim, damageInfo.damage, cleanDamage, DamageEffectType.SpellDirect, damageInfo.schoolMask, damageInfo.Spell, durabilityLoss);
}
public void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage log)
@@ -2483,7 +2482,7 @@ namespace Game.Entities
packet.Me = log.target.GetGUID();
packet.CasterGUID = log.attacker.GetGUID();
packet.CastID = log.castId;
packet.SpellID = (int)log.SpellId;
packet.SpellID = (int)(log.Spell != null ? log.Spell.Id : 0);
packet.Damage = (int)log.damage;
packet.OriginalDamage = (int)log.originalDamage;
if (log.damage > log.preHitHealth)
@@ -2622,7 +2621,7 @@ namespace Game.Entities
}
// turn off snare auras by setting amount to 0
foreach (SpellEffectInfo effect in aura.GetSpellInfo().GetEffectsForDifficulty(GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in aura.GetSpellInfo().GetEffects())
{
if (effect == null || !effect.IsEffect())
continue;
@@ -2902,7 +2901,7 @@ namespace Game.Entities
if (target == null)
return null;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
if (spellInfo == null)
return null;
@@ -2929,7 +2928,7 @@ namespace Game.Entities
}
ObjectGuid castId = ObjectGuid.Create(HighGuid.Cast, SpellCastSource.Normal, GetMapId(), spellInfo.Id, GetMap().GenerateLowGuid(HighGuid.Cast));
Aura aura = Aura.TryRefreshStackOrCreate(spellInfo, castId, effMask, target, this);
Aura aura = Aura.TryRefreshStackOrCreate(spellInfo, castId, effMask, target, this, GetMap().GetDifficultyID());
if (aura != null)
{
aura.ApplyForTargets();
@@ -2960,14 +2959,14 @@ namespace Game.Entities
Unit target = Convert.ToBoolean(clickInfo.castFlags & (byte)SpellClickCastFlags.TargetClicker) ? clicker : this;
ObjectGuid origCasterGUID = Convert.ToBoolean(clickInfo.castFlags & (byte)SpellClickCastFlags.OrigCasterOwner) ? GetOwnerGUID() : clicker.GetGUID();
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(clickInfo.spellId);
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(clickInfo.spellId, caster.GetMap().GetDifficultyID());
// if (!spellEntry) should be checked at npc_spellclick load
if (seatId > -1)
{
byte i = 0;
bool valid = false;
foreach (SpellEffectInfo effect in spellEntry.GetEffectsForDifficulty(GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in spellEntry.GetEffects())
{
if (effect == null)
continue;
@@ -2991,14 +2990,14 @@ namespace Game.Entities
else // This can happen during Player._LoadAuras
{
int[] bp0 = new int[SpellConst.MaxEffects];
foreach (SpellEffectInfo effect in spellEntry.GetEffectsForDifficulty(GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in spellEntry.GetEffects())
{
if (effect != null)
bp0[effect.EffectIndex] = effect.BasePoints;
}
bp0[i] = seatId;
Aura.TryRefreshStackOrCreate(spellEntry, ObjectGuid.Create(HighGuid.Cast, SpellCastSource.Normal, GetMapId(), spellEntry.Id, GetMap().GenerateLowGuid(HighGuid.Cast)), SpellConst.MaxEffectMask, this, clicker, bp0, null, origCasterGUID);
Aura.TryRefreshStackOrCreate(spellEntry, ObjectGuid.Create(HighGuid.Cast, SpellCastSource.Normal, GetMapId(), spellEntry.Id, GetMap().GenerateLowGuid(HighGuid.Cast)), SpellConst.MaxEffectMask, this, clicker, GetMap().GetDifficultyID(), bp0, null, origCasterGUID);
}
}
else
@@ -3006,7 +3005,7 @@ namespace Game.Entities
if (IsInMap(caster))
caster.CastSpell(target, spellEntry, flags, null, null, origCasterGUID);
else
Aura.TryRefreshStackOrCreate(spellEntry, ObjectGuid.Create(HighGuid.Cast, SpellCastSource.Normal, GetMapId(), spellEntry.Id, GetMap().GenerateLowGuid(HighGuid.Cast)), SpellConst.MaxEffectMask, this, clicker, null, null, origCasterGUID);
Aura.TryRefreshStackOrCreate(spellEntry, ObjectGuid.Create(HighGuid.Cast, SpellCastSource.Normal, GetMapId(), spellEntry.Id, GetMap().GenerateLowGuid(HighGuid.Cast)), SpellConst.MaxEffectMask, this, clicker, GetMap().GetDifficultyID(), null, null, origCasterGUID);
}
result = true;
@@ -3045,7 +3044,7 @@ namespace Game.Entities
if (spellInfo.Mechanic != 0 && Convert.ToBoolean(mechanicMask & (1 << (int)spellInfo.Mechanic)))
return true;
foreach (SpellEffectInfo effect in pair.Value.GetBase().GetSpellEffectInfos())
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
if (effect != null && effect.Effect != 0 && effect.Mechanic != 0)
if (Convert.ToBoolean(mechanicMask & (1 << (int)effect.Mechanic)))
return true;
@@ -3331,10 +3330,10 @@ namespace Game.Entities
if (aura.IsSingleTarget())
aura.UnregisterSingleTarget();
Aura newAura = Aura.TryRefreshStackOrCreate(aura.GetSpellInfo(), aura.GetCastGUID(), effMask, stealer, null, baseDamage, null, aura.GetCasterGUID());
Aura newAura = Aura.TryRefreshStackOrCreate(aura.GetSpellInfo(), aura.GetCastGUID(), effMask, stealer, null, aura.GetCastDifficulty(), baseDamage, null, aura.GetCasterGUID());
if (newAura != null)
{
// created aura must not be single target aura,, so stealer won't loose it on recast
// created aura must not be single target aura, so stealer won't loose it on recast
if (newAura.IsSingleTarget())
{
newAura.UnregisterSingleTarget();
@@ -3742,7 +3741,7 @@ namespace Game.Entities
if (pair.Value == null)
continue;
Aura aura = pair.Value.GetBase();
if (!aura.GetSpellInfo().HasAura(GetMap().GetDifficultyID(), type))
if (!aura.GetSpellInfo().HasAura(type))
_UnapplyAura(pair, AuraRemoveMode.Default);
}
@@ -3752,7 +3751,7 @@ namespace Game.Entities
continue;
Aura aura = pair.Value;
if (!aura.GetSpellInfo().HasAura(GetMap().GetDifficultyID(), type))
if (!aura.GetSpellInfo().HasAura(type))
RemoveOwnedAura(pair, AuraRemoveMode.Default);
}
}
@@ -3761,14 +3760,14 @@ namespace Game.Entities
foreach (var pair in GetAppliedAuras())
{
Aura aura = pair.Value.GetBase();
if (!aura.GetSpellInfo().HasAura(GetMap().GetDifficultyID(), type1) || !aura.GetSpellInfo().HasAura(GetMap().GetDifficultyID(), type2))
if (!aura.GetSpellInfo().HasAura(type1) || !aura.GetSpellInfo().HasAura(type2))
_UnapplyAura(pair, AuraRemoveMode.Default);
}
foreach (var pair in GetOwnedAuras())
{
Aura aura = pair.Value;
if (!aura.GetSpellInfo().HasAura(GetMap().GetDifficultyID(), type1) || !aura.GetSpellInfo().HasAura(GetMap().GetDifficultyID(), type2))
if (!aura.GetSpellInfo().HasAura(type1) || !aura.GetSpellInfo().HasAura(type2))
RemoveOwnedAura(pair, AuraRemoveMode.Default);
}
}
@@ -3789,7 +3788,7 @@ namespace Game.Entities
if (spell.Value.State == PlayerSpellState.Removed || spell.Value.Disabled)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell.Key);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell.Key, Difficulty.None);
if (spellInfo == null || !spellInfo.IsPassive())
continue;
@@ -3804,7 +3803,7 @@ namespace Game.Entities
{
if (spell.Value.state == PetSpellState.Removed)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell.Key);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell.Key, Difficulty.None);
if (spellInfo == null || !spellInfo.IsPassive())
continue;
if (spellInfo.CasterAuraState == flag)
@@ -4189,7 +4188,7 @@ namespace Game.Entities
return null;
// update basepoints with new values - effect amount will be recalculated in ModStackAmount
foreach (SpellEffectInfo effect in foundAura.GetSpellEffectInfos())
foreach (SpellEffectInfo effect in newAura.GetEffects())
{
if (effect == null)
continue;
@@ -4234,7 +4233,7 @@ namespace Game.Entities
if (!IsHighestExclusiveAura(aura))
{
if (!aura.GetSpellInfo().IsAffectingArea(GetMap().GetDifficultyID()))
if (!aura.GetSpellInfo().IsAffectingArea())
{
Unit caster = aura.GetCaster();
if (caster && caster.IsTypeId(TypeId.Player))
+5 -5
View File
@@ -269,7 +269,7 @@ namespace Game.Entities
public bool IsDisallowedMountForm(uint spellId, ShapeShiftForm form, uint displayId)
{
SpellInfo transformSpellInfo = Global.SpellMgr.GetSpellInfo(GetTransForm());
SpellInfo transformSpellInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
if (transformSpellInfo != null)
if (transformSpellInfo.HasAttribute(SpellAttr0.CastableWhileMounted))
return false;
@@ -601,7 +601,7 @@ namespace Game.Entities
if (gameObj.GetSpellId() != 0)
{
SpellInfo createBySpell = Global.SpellMgr.GetSpellInfo(gameObj.GetSpellId());
SpellInfo createBySpell = Global.SpellMgr.GetSpellInfo(gameObj.GetSpellId(), GetMap().GetDifficultyID());
// Need disable spell use for owner
if (createBySpell != null && createBySpell.HasAttribute(SpellAttr0.DisabledWhileActive))
// note: item based cooldowns and cooldown spell mods with charges ignored (unknown existing cases)
@@ -634,7 +634,7 @@ namespace Game.Entities
{
RemoveAurasDueToSpell(spellid);
SpellInfo createBySpell = Global.SpellMgr.GetSpellInfo(spellid);
SpellInfo createBySpell = Global.SpellMgr.GetSpellInfo(spellid, GetMap().GetDifficultyID());
// Need activate spell use for owner
if (createBySpell != null && createBySpell.IsCooldownStartedOnEvent())
// note: item based cooldowns and cooldown spell mods with charges ignored (unknown existing cases)
@@ -1772,7 +1772,7 @@ namespace Game.Entities
Global.SpellMgr.IsSpellMemberOfSpellGroup(spellProto.Id, SpellGroup.ElixirBattle) ||
Global.SpellMgr.IsSpellMemberOfSpellGroup(spellProto.Id, SpellGroup.ElixirGuardian)))
{
SpellEffectInfo effect = spellProto.GetEffect(Difficulty.None, 0);
SpellEffectInfo effect = spellProto.GetEffect(0);
if (target.HasAura(53042) && effect != null && target.HasSpell(effect.TriggerSpell))
duration *= 2;
}
@@ -2674,7 +2674,7 @@ namespace Game.Entities
if (effIndex != -1)
{
// bleeding effects are not reduced by armor
SpellEffectInfo effect = spellInfo.GetEffect(GetMap().GetDifficultyID(), (uint)effIndex);
SpellEffectInfo effect = spellInfo.GetEffect((uint)effIndex);
if (effect != null)
{
if (effect.ApplyAuraName == AuraType.PeriodicDamage || effect.Effect == SpellEffectName.SchoolDamage)
+34 -29
View File
@@ -1393,7 +1393,7 @@ namespace Game
case ScriptCommands.RemoveAura:
{
if (Global.SpellMgr.GetSpellInfo(tmp.RemoveAura.SpellID) == null)
if (!Global.SpellMgr.HasSpellInfo(tmp.RemoveAura.SpellID, Difficulty.None))
{
Log.outError(LogFilter.Sql, "Table `{0}` using non-existent spell (id: {1}) in SCRIPT_COMMAND_REMOVE_AURA for script id {2}",
tableName, tmp.RemoveAura.SpellID, tmp.id);
@@ -1410,7 +1410,7 @@ namespace Game
case ScriptCommands.CastSpell:
{
if (Global.SpellMgr.GetSpellInfo(tmp.CastSpell.SpellID) == null)
if (!Global.SpellMgr.HasSpellInfo(tmp.CastSpell.SpellID, Difficulty.None))
{
Log.outError(LogFilter.Sql, "Table `{0}` using non-existent spell (id: {1}) in SCRIPT_COMMAND_CAST_SPELL for script id {2}",
tableName, tmp.CastSpell.SpellID, tmp.id);
@@ -1493,7 +1493,7 @@ namespace Game
foreach (var script in sSpellScripts)
{
uint spellId = script.Key & 0x00FFFFFF;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Sql, "Table `spell_scripts` has not existing spell (Id: {0}) as script id", spellId);
@@ -1521,18 +1521,19 @@ namespace Game
}
// Load all possible script entries from spells
foreach (var spell in Global.SpellMgr.GetSpellInfoStorage().Values)
foreach (SpellNameRecord spellNameEntry in CliDB.SpellNameStorage.Values)
{
foreach (SpellEffectInfo effect in spell.GetEffectsForDifficulty(Difficulty.None))
SpellInfo spell = Global.SpellMgr.GetSpellInfo(spellNameEntry.Id, Difficulty.None);
if (spell != null)
{
if (effect == null)
continue;
if (effect.Effect == SpellEffectName.SendEvent)
foreach (SpellEffectInfo effect in spell.GetEffects())
{
if (effect != null && effect.Effect == SpellEffectName.SendEvent)
if (effect.MiscValue != 0)
evt_scripts.Add((uint)effect.MiscValue);
}
}
}
foreach (var path_idx in CliDB.TaxiPathNodesByPath)
{
@@ -1612,7 +1613,7 @@ namespace Game
spellId = -spellId;
}
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)spellId, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Sql, "Scriptname: `{0}` spell (Id: {1}) does not exist.", scriptName, spellId);
@@ -1663,7 +1664,7 @@ namespace Game
foreach (var script in spellScriptsStorage.KeyValueList)
{
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(script.Key);
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(script.Key, Difficulty.None);
Dictionary<SpellScriptLoader, uint> SpellScriptLoaders = Global.ScriptMgr.CreateSpellScriptLoaders(script.Key);
foreach (var pair in SpellScriptLoaders)
@@ -1973,14 +1974,14 @@ namespace Game
if (!uint.TryParse(id, out uint spellId))
continue;
SpellInfo AdditionalSpellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo AdditionalSpellInfo = Global.SpellMgr.GetSpellInfo(spellId, Difficulty.None);
if (AdditionalSpellInfo == null)
{
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) has wrong spell {1} defined in `auras` field in `creature_template_addon`.", entry, spellId);
continue;
}
if (AdditionalSpellInfo.HasAura(Difficulty.None, AuraType.ControlVehicle))
if (AdditionalSpellInfo.HasAura(AuraType.ControlVehicle))
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) has SPELL_AURA_CONTROL_VEHICLE aura {1} defined in `auras` field in `creature_template_addon`.", entry, spellId);
if (creatureAddon.auras.Contains(spellId))
@@ -2087,14 +2088,14 @@ namespace Game
if (!uint.TryParse(id, out uint spellId))
continue;
SpellInfo AdditionalSpellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo AdditionalSpellInfo = Global.SpellMgr.GetSpellInfo(spellId, Difficulty.None);
if (AdditionalSpellInfo == null)
{
Log.outError(LogFilter.Sql, "Creature (GUID: {0}) has wrong spell {1} defined in `auras` field in `creatureaddon`.", guid, spellId);
continue;
}
if (AdditionalSpellInfo.HasAura(Difficulty.None, AuraType.ControlVehicle))
if (AdditionalSpellInfo.HasAura(AuraType.ControlVehicle))
Log.outError(LogFilter.Sql, "Creature (GUID: {0}) has SPELL_AURA_CONTROL_VEHICLE aura {1} defined in `auras` field in `creature_addon`.", guid, spellId);
if (creatureAddon.auras.Contains(spellId))
@@ -2677,7 +2678,7 @@ namespace Game
for (byte j = 0; j < SharedConst.MaxCreatureSpells; ++j)
{
if (cInfo.Spells[j] != 0 && !Global.SpellMgr.HasSpellInfo(cInfo.Spells[j]))
if (cInfo.Spells[j] != 0 && !Global.SpellMgr.HasSpellInfo(cInfo.Spells[j], Difficulty.None))
{
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) has non-existing Spell{1} ({2}), set to 0.", cInfo.Entry, j + 1, cInfo.Spells[j]);
cInfo.Spells[j] = 0;
@@ -2991,7 +2992,7 @@ namespace Game
spell.ReqAbility[2] = trainerSpellsResult.Read<uint>(7);
spell.ReqLevel = trainerSpellsResult.Read<byte>(8);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell.SpellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell.SpellId, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Sql, $"Table `trainer_spell` references non-existing spell (SpellId: {spell.SpellId}) for TrainerId {trainerId}, ignoring");
@@ -3008,7 +3009,7 @@ namespace Game
for (var i = 0; i < spell.ReqAbility.Count; ++i)
{
uint requiredSpell = spell.ReqAbility[i];
if (requiredSpell != 0 && !Global.SpellMgr.HasSpellInfo(requiredSpell))
if (requiredSpell != 0 && !Global.SpellMgr.HasSpellInfo(requiredSpell, Difficulty.None))
{
Log.outError(LogFilter.Sql, $"Table `trainer_spell` references non-existing spell (ReqAbility {i + 1}: {requiredSpell}) for TrainerId {spell.SpellId} and SpellId {trainerId}, ignoring");
allReqValid = false;
@@ -4439,7 +4440,7 @@ namespace Game
}
void CheckGOSpellId(GameObjectTemplate goInfo, uint dataN, uint N)
{
if (Global.SpellMgr.HasSpellInfo(dataN))
if (Global.SpellMgr.HasSpellInfo(dataN, Difficulty.None))
return;
Log.outError(LogFilter.Sql, "Gameobject (Entry: {0} GoType: {1}) have data{2}={3} but Spell (Entry {4}) not exist.", goInfo.entry, goInfo.type, N, dataN, dataN);
@@ -5225,7 +5226,7 @@ namespace Game
break;
}
case EncounterCreditType.CastSpell:
if (!Global.SpellMgr.HasSpellInfo(creditEntry))
if (!Global.SpellMgr.HasSpellInfo(creditEntry, Difficulty.None))
{
Log.outError(LogFilter.Sql, "Table `instance_encounters` has an invalid spell (entry {0}) linked to the encounter {1} ({2}), skipped!",
creditEntry, entry, dungeonEncounter.Name[Global.WorldMgr.GetDefaultDbcLocale()]);
@@ -6239,9 +6240,9 @@ namespace Game
uint alliance = result.Read<uint>(0);
uint horde = result.Read<uint>(1);
if (!Global.SpellMgr.HasSpellInfo(alliance))
if (!Global.SpellMgr.HasSpellInfo(alliance, Difficulty.None))
Log.outError(LogFilter.Sql, "Spell {0} (alliance_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", alliance);
else if (!Global.SpellMgr.HasSpellInfo(horde))
else if (!Global.SpellMgr.HasSpellInfo(horde, Difficulty.None))
Log.outError(LogFilter.Sql, "Spell {0} (horde_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", horde);
else
FactionChangeSpells[alliance] = horde;
@@ -6730,7 +6731,7 @@ namespace Game
if (qinfo.SourceSpellID != 0)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(qinfo.SourceSpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(qinfo.SourceSpellID, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Sql, "Quest {0} has `SourceSpellid` = {1} but spell {1} doesn't exist, quest can't be done.",
@@ -6810,7 +6811,7 @@ namespace Game
Log.outError(LogFilter.Sql, "Quest {0} objective {1} has invalid currency amount {2}", qinfo.Id, obj.Id, obj.Amount);
break;
case QuestObjectiveType.LearnSpell:
if (!Global.SpellMgr.HasSpellInfo((uint)obj.ObjectID))
if (!Global.SpellMgr.HasSpellInfo((uint)obj.ObjectID, Difficulty.None))
Log.outError(LogFilter.Sql, "Quest {0} objective {1} has non existing spell id {2}", qinfo.Id, obj.Id, obj.ObjectID);
break;
case QuestObjectiveType.WinPetBattleAgainstNpc:
@@ -6943,7 +6944,7 @@ namespace Game
{
if (qinfo.RewardDisplaySpell[i] != 0)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(qinfo.RewardSpell);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(qinfo.RewardSpell, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Sql, "Quest {0} has `RewardSpell` = {1} but spell {2} does not exist, spell removed as display reward.",
@@ -6961,7 +6962,7 @@ namespace Game
if (qinfo.RewardSpell > 0)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(qinfo.RewardSpell);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(qinfo.RewardSpell, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Sql, "Quest {0} has `RewardSpellCast` = {1} but spell {2} does not exist, quest will not have a spell reward.",
@@ -7130,9 +7131,13 @@ namespace Game
}
// check QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT for spell with SPELL_EFFECT_QUEST_COMPLETE
foreach (var spellInfo in Global.SpellMgr.GetSpellInfoStorage().Values)
foreach (SpellNameRecord spellNameEntry in CliDB.SpellNameStorage.Values)
{
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellNameEntry.Id, Difficulty.None);
if (spellInfo == null)
continue;
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect == null || effect.Effect != SpellEffectName.QuestComplete)
continue;
@@ -7736,7 +7741,7 @@ namespace Game
}
uint spellid = result.Read<uint>(1);
SpellInfo spellinfo = Global.SpellMgr.GetSpellInfo(spellid);
SpellInfo spellinfo = Global.SpellMgr.GetSpellInfo(spellid, Difficulty.None);
if (spellinfo == null)
{
Log.outError(LogFilter.Sql, "Table npc_spellclick_spells creature: {0} references unknown spellid {1}. Skipping entry.", npc_entry, spellid);
+12 -12
View File
@@ -75,7 +75,7 @@ namespace Game
if (!pet.IsAlive())
{
SpellInfo spell = (flag == ActiveStates.Enabled || flag == ActiveStates.Passive) ? Global.SpellMgr.GetSpellInfo(spellid) : null;
SpellInfo spell = (flag == ActiveStates.Enabled || flag == ActiveStates.Passive) ? Global.SpellMgr.GetSpellInfo(spellid, pet.GetMap().GetDifficultyID()) : null;
if (spell == null)
return;
if (!spell.HasAttribute(SpellAttr0.CastableWhileDead))
@@ -285,14 +285,14 @@ namespace Game
unit_target = Global.ObjAccessor.GetUnit(GetPlayer(), guid2);
// do not cast unknown spells
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellid);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellid, pet.GetMap().GetDifficultyID());
if (spellInfo == null)
{
Log.outError(LogFilter.Network, "WORLD: unknown PET spell id {0}", spellid);
return;
}
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect != null && (effect.TargetA.GetTarget() == Targets.UnitSrcAreaEnemy || effect.TargetA.GetTarget() == Targets.UnitDestAreaEnemy || effect.TargetA.GetTarget() == Targets.DestDynobjEnemy))
return;
@@ -484,7 +484,7 @@ namespace Game
//if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add
if (!((act_state == ActiveStates.Enabled || act_state == ActiveStates.Disabled || act_state == ActiveStates.Passive) && spell_id != 0 && !pet.HasSpell(spell_id)))
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id, pet.GetMap().GetDifficultyID());
if (spellInfo != null)
{
//sign for autocast
@@ -607,7 +607,7 @@ namespace Game
return;
}
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(packet.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(packet.SpellID, pet.GetMap().GetDifficultyID());
if (spellInfo == null)
{
Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocast: Unknown spell id {0} used by {1}.", packet.SpellID, packet.PetGUID.ToString());
@@ -636,13 +636,6 @@ namespace Game
[WorldPacketHandler(ClientOpcodes.PetCastSpell)]
void HandlePetCastSpell(PetCastSpell petCastSpell)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(petCastSpell.Cast.SpellID);
if (spellInfo == null)
{
Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: unknown spell id {0} tried to cast by {1}", petCastSpell.Cast.SpellID, petCastSpell.PetGUID.ToString());
return;
}
Unit caster = Global.ObjAccessor.GetUnit(GetPlayer(), petCastSpell.PetGUID);
if (!caster)
{
@@ -650,6 +643,13 @@ namespace Game
return;
}
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(petCastSpell.Cast.SpellID, caster.GetMap().GetDifficultyID());
if (spellInfo == null)
{
Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: unknown spell id {0} tried to cast by {1}", petCastSpell.Cast.SpellID, petCastSpell.PetGUID.ToString());
return;
}
// This opcode is also sent from charmed and possessed units (players and creatures)
if (caster != GetPlayer().GetGuardianPet() && caster != GetPlayer().GetCharm())
{
+6 -7
View File
@@ -92,7 +92,7 @@ namespace Game
{
foreach (ItemEffectRecord effect in item.GetEffects())
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)effect.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)effect.SpellID, user.GetMap().GetDifficultyID());
if (spellInfo != null)
{
if (!spellInfo.CanBeUsedInCombat())
@@ -274,7 +274,7 @@ namespace Game
if (mover != GetPlayer() && mover.IsTypeId(TypeId.Player))
return;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(cast.Cast.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(cast.Cast.SpellID, mover.GetMap().GetDifficultyID());
if (spellInfo == null)
{
Log.outError(LogFilter.Network, "WORLD: unknown spell id {0}", cast.Cast.SpellID);
@@ -351,7 +351,7 @@ namespace Game
[WorldPacketHandler(ClientOpcodes.CancelAura)]
void HandleCancelAura(CancelAura cancelAura)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(cancelAura.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(cancelAura.SpellID, _player.GetMap().GetDifficultyID());
if (spellInfo == null)
return;
@@ -401,14 +401,13 @@ namespace Game
[WorldPacketHandler(ClientOpcodes.PetCancelAura)]
void HandlePetCancelAura(PetCancelAura packet)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(packet.SpellID);
if (spellInfo == null)
if (!Global.SpellMgr.HasSpellInfo(packet.SpellID, Difficulty.None))
{
Log.outError(LogFilter.Network, "WORLD: unknown PET spell id {0}", packet.SpellID);
return;
}
Creature pet= ObjectAccessor.GetCreatureOrPetOrVehicle(_player, packet.PetGUID);
Creature pet = ObjectAccessor.GetCreatureOrPetOrVehicle(_player, packet.PetGUID);
if (pet == null)
{
Log.outError(LogFilter.Network, "HandlePetCancelAura: Attempt to cancel an aura for non-existant {0} by player '{1}'", packet.PetGUID.ToString(), GetPlayer().GetName());
@@ -480,7 +479,7 @@ namespace Game
if (!selfResSpells.Contains(selfRes.SpellId))
return;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(selfRes.SpellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(selfRes.SpellId, _player.GetMap().GetDifficultyID());
if (spellInfo != null)
_player.CastSpell(_player, spellInfo, false, null);
+1 -1
View File
@@ -67,7 +67,7 @@ namespace Game
if (effect == null)
return;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(packet.Cast.SpellID);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(packet.Cast.SpellID, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Network, "HandleUseToy: unknown spell id: {0} used by Toy Item entry {1}", packet.Cast.SpellID, itemId);
+2 -2
View File
@@ -341,7 +341,7 @@ namespace Game
uint my_spell_id = my_trade.GetSpell();
if (my_spell_id != 0)
{
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(my_spell_id);
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(my_spell_id, _player.GetMap().GetDifficultyID());
Item castItem = my_trade.GetSpellCastItem();
if (spellEntry == null || !his_trade.GetItem(TradeSlots.NonTraded) ||
@@ -377,7 +377,7 @@ namespace Game
uint his_spell_id = his_trade.GetSpell();
if (his_spell_id != 0)
{
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(his_spell_id);
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(his_spell_id, trader.GetMap().GetDifficultyID());
Item castItem = his_trade.GetSpellCastItem();
if (spellEntry == null || !my_trade.GetItem(TradeSlots.NonTraded) || (his_trade.HasSpellCastItem() && !castItem))
+6 -1
View File
@@ -20,6 +20,7 @@ using Framework.Database;
using Game.Conditions;
using Game.DataStorage;
using Game.Entities;
using Game.Spells;
using System;
using System.Collections.Generic;
@@ -378,8 +379,12 @@ namespace Game.Loots
uint count = Spell.LoadAndCollectLootIds(out lootIdSet);
// remove real entries and check existence loot
foreach (var spellInfo in Global.SpellMgr.GetSpellInfoStorage().Values)
foreach (SpellNameRecord spellNameEntry in CliDB.SpellNameStorage.Values)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellNameEntry.Id, Difficulty.None);
if (spellInfo == null)
continue;
// possible cases
if (!spellInfo.IsLootCrafting())
continue;
+1 -1
View File
@@ -139,7 +139,7 @@ namespace Game.Network.Packets
}
public List<HotfixData> Hotfixes = new List<HotfixData>();
public ByteBuffer HotfixContent;
public ByteBuffer HotfixContent = new ByteBuffer();
public class HotfixData
{
-67
View File
@@ -335,73 +335,6 @@ namespace Game.Scripting
public void FillSpellSummary()
{
UnitAI.FillAISpellInfo();
SpellInfo pTempSpell;
var spellStorage = Global.SpellMgr.GetSpellInfoStorage();
foreach (var i in spellStorage.Keys)
{
spellSummaryStorage[i] = new SpellSummary();
pTempSpell = spellStorage.LookupByKey(i);
// This spell doesn't exist.
if (pTempSpell == null)
continue;
foreach (SpellEffectInfo effect in pTempSpell.GetEffectsForDifficulty(Difficulty.None))
{
if (effect == null)
continue;
// Spell targets self.
if (effect.TargetA.GetTarget() == Targets.UnitCaster)
spellSummaryStorage[i].Targets |= 1 << ((int)SelectTargetType.Self - 1);
// Spell targets a single enemy.
if (effect.TargetA.GetTarget() == Targets.UnitEnemy || effect.TargetA.GetTarget() == Targets.DestEnemy)
spellSummaryStorage[i].Targets |= 1 << ((int)SelectTargetType.SingleEnemy - 1);
// Spell targets AoE at enemy.
if (effect.TargetA.GetTarget() == Targets.UnitSrcAreaEnemy || effect.TargetA.GetTarget() == Targets.UnitDestAreaEnemy ||
effect.TargetA.GetTarget() == Targets.SrcCaster || effect.TargetA.GetTarget() == Targets.DestDynobjEnemy)
spellSummaryStorage[i].Targets |= 1 << ((int)SelectTargetType.AoeEnemy - 1);
// Spell targets an enemy.
if (effect.TargetA.GetTarget() == Targets.UnitEnemy || effect.TargetA.GetTarget() == Targets.DestEnemy ||
effect.TargetA.GetTarget() == Targets.UnitSrcAreaEnemy || effect.TargetA.GetTarget() == Targets.UnitDestAreaEnemy ||
effect.TargetA.GetTarget() == Targets.SrcCaster || effect.TargetA.GetTarget() == Targets.DestDynobjEnemy)
spellSummaryStorage[i].Targets |= 1 << ((int)SelectTargetType.AnyEnemy - 1);
// Spell targets a single friend (or self).
if (effect.TargetA.GetTarget() == Targets.UnitCaster || effect.TargetA.GetTarget() == Targets.UnitAlly ||
effect.TargetA.GetTarget() == Targets.UnitParty)
spellSummaryStorage[i].Targets |= 1 << ((int)SelectTargetType.SingleFriend - 1);
// Spell targets AoE friends.
if (effect.TargetA.GetTarget() == Targets.UnitCasterAreaParty || effect.TargetA.GetTarget() == Targets.UnitLastAreaParty ||
effect.TargetA.GetTarget() == Targets.SrcCaster)
spellSummaryStorage[i].Targets |= 1 << ((int)SelectTargetType.AoeFriend - 1);
// Spell targets any friend (or self).
if (effect.TargetA.GetTarget() == Targets.UnitCaster || effect.TargetA.GetTarget() == Targets.UnitAlly ||
effect.TargetA.GetTarget() == Targets.UnitParty || effect.TargetA.GetTarget() == Targets.UnitCasterAreaParty ||
effect.TargetA.GetTarget() == Targets.UnitLastAreaParty || effect.TargetA.GetTarget() == Targets.SrcCaster)
spellSummaryStorage[i].Targets |= 1 << ((int)SelectTargetType.AnyFriend - 1);
// Make sure that this spell includes a damage effect.
if (effect.Effect == SpellEffectName.SchoolDamage || effect.Effect == SpellEffectName.Instakill ||
effect.Effect == SpellEffectName.EnvironmentalDamage || effect.Effect == SpellEffectName.HealthLeech)
spellSummaryStorage[i].Effects |= 1 << ((int)SelectEffect.Damage - 1);
// Make sure that this spell includes a healing effect (or an apply aura with a periodic heal).
if (effect.Effect == SpellEffectName.Heal || effect.Effect == SpellEffectName.HealMaxHealth ||
effect.Effect == SpellEffectName.HealMechanical || (effect.Effect == SpellEffectName.ApplyAura && effect.ApplyAuraName == AuraType.PeriodicHeal))
spellSummaryStorage[i].Effects |= 1 << ((int)SelectEffect.Healing - 1);
// Make sure that this spell applies an aura.
if (effect.Effect == SpellEffectName.ApplyAura)
spellSummaryStorage[i].Effects |= 1 << ((int)SelectEffect.Aura - 1);
}
}
}
public List<SplineChainLink> GetSplineChain(Creature who, ushort chainId)
+9 -3
View File
@@ -48,7 +48,7 @@ namespace Game.Scripting
bool allValid = true;
foreach (uint spellId in spellIds)
{
if (!Global.SpellMgr.HasSpellInfo(spellId))
if (!Global.SpellMgr.HasSpellInfo(spellId, Difficulty.None))
{
Log.outError(LogFilter.Scripts, "BaseSpellScript.ValidateSpellInfo: Spell {0} does not exist.", spellId);
allValid = false;
@@ -494,11 +494,12 @@ namespace Game.Scripting
public Unit GetCaster() { return m_spell.GetCaster(); }
public Unit GetOriginalCaster() { return m_spell.GetOriginalCaster(); }
public SpellInfo GetSpellInfo() { return m_spell.GetSpellInfo(); }
public Difficulty GetCastDifficulty() { return m_spell.GetCastDifficulty(); }
public SpellValue GetSpellValue() { return m_spell.m_spellValue; }
public SpellEffectInfo GetEffectInfo(uint effIndex)
{
return m_spell.GetEffect(effIndex);
return GetSpellInfo().GetEffect(effIndex);
}
// methods useable after spell is prepared
@@ -773,7 +774,7 @@ namespace Game.Scripting
public delegate void AuraEffectAbsorbDelegate(AuraEffect aura, DamageInfo damageInfo, ref uint absorbAmount);
public delegate void AuraEffectSplitDelegate(AuraEffect aura, DamageInfo damageInfo, uint splitAmount);
public delegate bool AuraCheckProcDelegate(ProcEventInfo info);
public delegate bool AuraCheckEffectProcDelegate(AuraEffect aura , ProcEventInfo info);
public delegate bool AuraCheckEffectProcDelegate(AuraEffect aura, ProcEventInfo info);
public delegate void AuraProcDelegate(ProcEventInfo info);
public delegate void AuraEffectProcDelegate(AuraEffect aura, ProcEventInfo info);
@@ -1422,5 +1423,10 @@ namespace Game.Scripting
}
// returns AuraApplication object of currently processed target
public AuraApplication GetTargetApplication() { return m_auraApplication; }
public Difficulty GetCastDifficulty()
{
return GetAura().GetCastDifficulty();
}
}
}
+38 -49
View File
@@ -123,7 +123,7 @@ namespace Game.Spells
if (IsSelfcasted() || caster == null || !caster.IsFriendlyTo(GetTarget()))
{
bool negativeFound = false;
foreach (SpellEffectInfo effect in GetBase().GetSpellEffectInfos())
foreach (SpellEffectInfo effect in GetBase().GetSpellInfo().GetEffects())
{
if (effect != null && (Convert.ToBoolean((1 << (int)effect.EffectIndex) & effMask) && !GetBase().GetSpellInfo().IsPositiveEffect(effect.EffectIndex)))
{
@@ -138,7 +138,7 @@ namespace Game.Spells
else
{
bool positiveFound = false;
foreach (SpellEffectInfo effect in GetBase().GetSpellEffectInfos())
foreach (SpellEffectInfo effect in GetBase().GetSpellInfo().GetEffects())
{
if (effect != null && (Convert.ToBoolean((1 << (int)effect.EffectIndex) & effMask) && GetBase().GetSpellInfo().IsPositiveEffect(effect.EffectIndex)))
{
@@ -284,9 +284,10 @@ namespace Game.Spells
{
const int UPDATE_TARGET_MAP_INTERVAL = 500;
public Aura(SpellInfo spellproto, ObjectGuid castId, WorldObject owner, Unit caster, Item castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint castItemId, int castItemLevel)
public Aura(SpellInfo spellproto, ObjectGuid castId, WorldObject owner, Unit caster, Difficulty castDifficulty, Item castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint castItemId, int castItemLevel)
{
m_spellInfo = spellproto;
m_castDifficulty = castDifficulty;
m_castGuid = castId;
m_casterGuid = !casterGUID.IsEmpty() ? casterGUID : caster.GetGUID();
m_castItemGuid = castItem != null ? castItem.GetGUID() : castItemGuid;
@@ -306,9 +307,8 @@ namespace Game.Spells
m_lastProcAttemptTime = (DateTime.Now - TimeSpan.FromSeconds(10));
m_lastProcSuccessTime = (DateTime.Now - TimeSpan.FromSeconds(120));
var powers = Global.DB2Mgr.GetSpellPowers(GetId(), caster ? caster.GetMap().GetDifficultyID() : Difficulty.None);
foreach (var power in powers)
if (power.ManaPerSecond != 0 || power.PowerPctPerSecond > 0.0f)
foreach (SpellPowerRecord power in m_spellInfo.PowerCosts)
if (power != null && (power.ManaPerSecond != 0 || power.PowerPctPerSecond > 0.0f))
m_periodicCosts.Add(power);
if (!m_periodicCosts.Empty())
@@ -337,11 +337,9 @@ namespace Game.Spells
public void _InitEffects(uint effMask, Unit caster, int[] baseAmount)
{
// shouldn't be in constructor - functions in AuraEffect.AuraEffect use polymorphism
_spellEffectInfos = m_spellInfo.GetEffectsForDifficulty(GetOwner().GetMap().GetDifficultyID());
_effects = new AuraEffect[GetSpellInfo().GetEffects().Count];
_effects = new AuraEffect[GetSpellEffectInfos().Length];
foreach (SpellEffectInfo effect in GetSpellEffectInfos())
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects())
{
if (effect != null && Convert.ToBoolean(effMask & (1 << (int)effect.EffectIndex)))
_effects[effect.EffectIndex] = new AuraEffect(this, effect.EffectIndex, baseAmount != null ? baseAmount[effect.EffectIndex] : (int?)null, caster);
@@ -897,7 +895,7 @@ namespace Game.Spells
public bool HasMoreThanOneEffectForType(AuraType auraType)
{
uint count = 0;
foreach (SpellEffectInfo effect in GetSpellEffectInfos())
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects())
{
if (effect != null && HasEffect(effect.EffectIndex) && effect.ApplyAuraName == auraType)
++count;
@@ -908,7 +906,7 @@ namespace Game.Spells
public bool IsArea()
{
foreach (SpellEffectInfo effect in GetSpellEffectInfos())
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects())
{
if (effect != null && HasEffect(effect.EffectIndex) && effect.IsAreaAuraEffect())
return true;
@@ -1287,7 +1285,7 @@ namespace Game.Spells
// check cooldown
if (caster.IsTypeId(TypeId.Player))
{
if (caster.GetSpellHistory().HasCooldown(aura.GetId()))
if (caster.GetSpellHistory().HasCooldown(aura.GetSpellInfo()))
{
// This additional check is needed to add a minimal delay before cooldown in in effect
// to allow all bubbles broken by a single damage source proc mana return
@@ -1502,14 +1500,14 @@ namespace Game.Spells
if (IsPassive() && sameCaster && (m_spellInfo.IsDifferentRankOf(existingSpellInfo) || (m_spellInfo.Id == existingSpellInfo.Id && m_castItemGuid.IsEmpty())))
return false;
foreach (SpellEffectInfo effect in existingAura.GetSpellEffectInfos())
foreach (SpellEffectInfo effect in existingSpellInfo.GetEffects())
{
// prevent remove triggering aura by triggered aura
if (effect != null && effect.TriggerSpell == GetId())
return true;
}
foreach (SpellEffectInfo effect in GetSpellEffectInfos())
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects())
{
// prevent remove triggered aura by triggering aura refresh
if (effect != null && effect.TriggerSpell == existingAura.GetId())
@@ -1552,7 +1550,7 @@ namespace Game.Spells
// check same periodic auras
for (byte i = 0; i < SpellConst.MaxEffects; i++)
{
SpellEffectInfo effect = GetSpellEffectInfo(i);
SpellEffectInfo effect = m_spellInfo.GetEffect(i);
if (effect == null)
continue;
@@ -1570,7 +1568,7 @@ namespace Game.Spells
case AuraType.ObsModPower:
case AuraType.ObsModHealth:
case AuraType.PeriodicTriggerSpellWithValue:
SpellEffectInfo existingEffect = GetSpellEffectInfo(i);
SpellEffectInfo existingEffect = m_spellInfo.GetEffect(i);
// periodic auras which target areas are not allowed to stack this way (replenishment for example)
if (effect.IsTargetingArea() || (existingEffect != null && existingEffect.IsTargetingArea()))
break;
@@ -1639,7 +1637,7 @@ namespace Game.Spells
SetNeedClientUpdateForTargets();
}
SpellProcEntry procEntry = Global.SpellMgr.GetSpellProcEntry(GetId());
SpellProcEntry procEntry = Global.SpellMgr.GetSpellProcEntry(GetSpellInfo());
Cypher.Assert(procEntry != null);
@@ -1651,7 +1649,7 @@ namespace Game.Spells
public uint GetProcEffectMask(AuraApplication aurApp, ProcEventInfo eventInfo, DateTime now)
{
SpellProcEntry procEntry = Global.SpellMgr.GetSpellProcEntry(GetId());
SpellProcEntry procEntry = Global.SpellMgr.GetSpellProcEntry(GetSpellInfo());
// only auras with spell proc entry can trigger proc
if (procEntry == null)
return 0;
@@ -1671,7 +1669,7 @@ namespace Game.Spells
}
// check don't break stealth attr present
if (m_spellInfo.HasAura(Difficulty.None, AuraType.ModStealth))
if (m_spellInfo.HasAura(AuraType.ModStealth))
{
SpellInfo eventSpellInfo = eventInfo.GetSpellInfo();
if (eventSpellInfo != null)
@@ -2240,6 +2238,7 @@ namespace Game.Spells
public SpellInfo GetSpellInfo() { return m_spellInfo; }
public uint GetId() { return m_spellInfo.Id; }
public Difficulty GetCastDifficulty() { return m_castDifficulty; }
public ObjectGuid GetCastGUID() { return m_castGuid; }
public ObjectGuid GetCasterGUID() { return m_casterGuid; }
public ObjectGuid GetCastItemGUID() { return m_castItemGuid; }
@@ -2297,7 +2296,7 @@ namespace Game.Spells
byte CalcMaxCharges(Unit caster)
{
uint maxProcCharges = m_spellInfo.ProcCharges;
var procEntry = Global.SpellMgr.GetSpellProcEntry(GetId());
var procEntry = Global.SpellMgr.GetSpellProcEntry(GetSpellInfo());
if (procEntry != null)
maxProcCharges = procEntry.Charges;
@@ -2357,15 +2356,6 @@ namespace Game.Spells
public AuraEffect[] GetAuraEffects() { return _effects; }
public SpellEffectInfo[] GetSpellEffectInfos() { return _spellEffectInfos; }
public SpellEffectInfo GetSpellEffectInfo(uint index)
{
if (index >= _spellEffectInfos.Length)
return null;
return _spellEffectInfos[index];
}
public void SetLastProcAttemptTime(DateTime lastProcAttemptTime) { m_lastProcAttemptTime = lastProcAttemptTime; }
public void SetLastProcSuccessTime(DateTime lastProcSuccessTime) { m_lastProcSuccessTime = lastProcSuccessTime; }
@@ -2379,14 +2369,14 @@ namespace Game.Spells
{
case TypeId.Unit:
case TypeId.Player:
foreach (SpellEffectInfo effect in spellProto.GetEffectsForDifficulty(owner.GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in spellProto.GetEffects())
{
if (effect != null && effect.IsUnitOwnedAuraEffect())
effMask |= (uint)(1 << (int)effect.EffectIndex);
}
break;
case TypeId.DynamicObject:
foreach (SpellEffectInfo effect in spellProto.GetEffectsForDifficulty(owner.GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in spellProto.GetEffects())
{
if (effect != null && effect.Effect == SpellEffectName.PersistentAreaAura)
effMask |= (uint)(1 << (int)effect.EffectIndex);
@@ -2397,12 +2387,11 @@ namespace Game.Spells
}
return (effMask & availableEffectMask);
}
public static Aura TryRefreshStackOrCreate(SpellInfo spellproto, ObjectGuid castId, uint tryEffMask, WorldObject owner, Unit caster, int[] baseAmount = null, Item castItem = null, ObjectGuid casterGUID = default, bool resetPeriodicTimer = true, ObjectGuid castItemGuid = default, uint castItemId = 0, int castItemLevel = -1)
public static Aura TryRefreshStackOrCreate(SpellInfo spellproto, ObjectGuid castId, uint tryEffMask, WorldObject owner, Unit caster, Difficulty castDifficulty, int[] baseAmount = null, Item castItem = null, ObjectGuid casterGUID = default, bool resetPeriodicTimer = true, ObjectGuid castItemGuid = default, uint castItemId = 0, int castItemLevel = -1)
{
bool throwway;
return TryRefreshStackOrCreate(spellproto, castId, tryEffMask, owner, caster, out throwway, baseAmount, castItem, casterGUID, resetPeriodicTimer, castItemGuid, castItemId, castItemLevel);
return TryRefreshStackOrCreate(spellproto, castId, tryEffMask, owner, caster, castDifficulty, out _, baseAmount, castItem, casterGUID, resetPeriodicTimer, castItemGuid, castItemId, castItemLevel);
}
public static Aura TryRefreshStackOrCreate(SpellInfo spellproto, ObjectGuid castId, uint tryEffMask, WorldObject owner, Unit caster, out bool refresh, int[] baseAmount, Item castItem = null, ObjectGuid casterGUID = default, bool resetPeriodicTimer = true, ObjectGuid castItemGuid = default, uint castItemId = 0, int castItemLevel = -1)
public static Aura TryRefreshStackOrCreate(SpellInfo spellproto, ObjectGuid castId, uint tryEffMask, WorldObject owner, Unit caster, Difficulty castDifficulty, out bool refresh, int[] baseAmount, Item castItem = null, ObjectGuid casterGUID = default, bool resetPeriodicTimer = true, ObjectGuid castItemGuid = default, uint castItemId = 0, int castItemLevel = -1)
{
Cypher.Assert(spellproto != null);
Cypher.Assert(owner != null);
@@ -2425,9 +2414,9 @@ namespace Game.Spells
return foundAura;
}
else
return Create(spellproto, castId, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemGuid, castItemId, castItemLevel);
return Create(spellproto, castId, effMask, owner, caster, castDifficulty, baseAmount, castItem, casterGUID, castItemGuid, castItemId, castItemLevel);
}
public static Aura TryCreate(SpellInfo spellproto, ObjectGuid castId, uint tryEffMask, WorldObject owner, Unit caster, int[] baseAmount, Item castItem = null, ObjectGuid casterGUID = default, ObjectGuid castItemGuid = default, uint castItemId = 0, int castItemLevel = -1)
public static Aura TryCreate(SpellInfo spellproto, ObjectGuid castId, uint tryEffMask, WorldObject owner, Unit caster, Difficulty castDifficulty, int[] baseAmount, Item castItem = null, ObjectGuid casterGUID = default, ObjectGuid castItemGuid = default, uint castItemId = 0, int castItemLevel = -1)
{
Cypher.Assert(spellproto != null);
Cypher.Assert(owner != null);
@@ -2436,9 +2425,9 @@ namespace Game.Spells
uint effMask = BuildEffectMaskForOwner(spellproto, tryEffMask, owner);
if (effMask == 0)
return null;
return Create(spellproto, castId, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemGuid, castItemId, castItemLevel);
return Create(spellproto, castId, effMask, owner, caster, castDifficulty, baseAmount, castItem, casterGUID, castItemGuid, castItemId, castItemLevel);
}
public static Aura Create(SpellInfo spellproto, ObjectGuid castId, uint effMask, WorldObject owner, Unit caster, int[] baseAmount, Item castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint castItemId, int castItemLevel)
public static Aura Create(SpellInfo spellproto, ObjectGuid castId, uint effMask, WorldObject owner, Unit caster, Difficulty castDifficulty, int[] baseAmount, Item castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint castItemId, int castItemLevel)
{
Cypher.Assert(effMask != 0);
Cypher.Assert(spellproto != null);
@@ -2468,10 +2457,10 @@ namespace Game.Spells
{
case TypeId.Unit:
case TypeId.Player:
aura = new UnitAura(spellproto, castId, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemGuid, castItemId, castItemLevel);
aura = new UnitAura(spellproto, castId, effMask, owner, caster, castDifficulty, baseAmount, castItem, casterGUID, castItemGuid, castItemId, castItemLevel);
break;
case TypeId.DynamicObject:
aura = new DynObjAura(spellproto, castId, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemGuid, castItemId, castItemLevel);
aura = new DynObjAura(spellproto, castId, effMask, owner, caster, castDifficulty, baseAmount, castItem, casterGUID, castItemGuid, castItemId, castItemLevel);
break;
default:
Cypher.Assert(false);
@@ -2486,6 +2475,7 @@ namespace Game.Spells
#region Fields
List<AuraScript> m_loadedScripts = new List<AuraScript>();
SpellInfo m_spellInfo;
Difficulty m_castDifficulty;
ObjectGuid m_castGuid;
ObjectGuid m_casterGuid;
ObjectGuid m_castItemGuid;
@@ -2506,7 +2496,6 @@ namespace Game.Spells
byte m_stackAmount; // Aura stack amount
//might need to be arrays still
SpellEffectInfo[] _spellEffectInfos;
AuraEffect[] _effects;
Dictionary<ObjectGuid, AuraApplication> m_applications = new Dictionary<ObjectGuid, AuraApplication>();
@@ -2526,8 +2515,8 @@ namespace Game.Spells
public class UnitAura : Aura
{
public UnitAura(SpellInfo spellproto, ObjectGuid castId, uint effMask, WorldObject owner, Unit caster, int[] baseAmount, Item castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint castItemId, int castItemLevel)
: base(spellproto, castId, owner, caster, castItem, casterGUID, castItemGuid, castItemId, castItemLevel)
public UnitAura(SpellInfo spellproto, ObjectGuid castId, uint effMask, WorldObject owner, Unit caster, Difficulty castDifficulty, int[] baseAmount, Item castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint castItemId, int castItemLevel)
: base(spellproto, castId, owner, caster, castDifficulty, castItem, casterGUID, castItemGuid, castItemId, castItemLevel)
{
m_AuraDRGroup = DiminishingGroup.None;
LoadScripts();
@@ -2560,7 +2549,7 @@ namespace Game.Spells
public override void FillTargetMap(ref Dictionary<Unit, uint> targets, Unit caster)
{
foreach (SpellEffectInfo effect in GetSpellEffectInfos())
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects())
{
if (effect == null || !HasEffect(effect.EffectIndex))
continue;
@@ -2637,8 +2626,8 @@ namespace Game.Spells
public class DynObjAura : Aura
{
public DynObjAura(SpellInfo spellproto, ObjectGuid castId, uint effMask, WorldObject owner, Unit caster, int[] baseAmount, Item castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint castItemId, int castItemLevel)
: base(spellproto, castId, owner, caster, castItem, casterGUID, castItemGuid, castItemId, castItemLevel)
public DynObjAura(SpellInfo spellproto, ObjectGuid castId, uint effMask, WorldObject owner, Unit caster, Difficulty castDifficulty, int[] baseAmount, Item castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint castItemId, int castItemLevel)
: base(spellproto, castId, owner, caster, castDifficulty, castItem, casterGUID, castItemGuid, castItemId, castItemLevel)
{
LoadScripts();
Cypher.Assert(GetDynobjOwner() != null);
@@ -2661,7 +2650,7 @@ namespace Game.Spells
Unit dynObjOwnerCaster = GetDynobjOwner().GetCaster();
float radius = GetDynobjOwner().GetRadius();
foreach (SpellEffectInfo effect in GetSpellEffectInfos())
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects())
{
if (effect == null || !HasEffect(effect.EffectIndex))
continue;
+28 -28
View File
@@ -32,14 +32,14 @@ namespace Game.Spells
{
public class AuraEffect
{
public AuraEffect(Aura baseAura, uint effindex, int? baseAmount, Unit caster)
public AuraEffect(Aura baseAura, uint effIndex, int? baseAmount, Unit caster)
{
auraBase = baseAura;
m_spellInfo = baseAura.GetSpellInfo();
_effectInfo = baseAura.GetSpellEffectInfo(effindex);
_effectInfo = m_spellInfo.GetEffect(effIndex);
m_baseAmount = baseAmount.HasValue ? baseAmount.Value : _effectInfo.CalcBaseValue(caster, baseAura.GetAuraType() == AuraObjectType.Unit ? baseAura.GetOwner().ToUnit() : null, baseAura.GetCastItemId(), baseAura.GetCastItemLevel());
m_donePct = 1.0f;
m_effIndex = (byte)effindex;
m_effIndex = (byte)effIndex;
m_canBeRecalculated = true;
m_isPeriodic = false;
@@ -683,7 +683,7 @@ namespace Game.Spells
{
// Don't proc extra attacks while already processing extra attack spell
uint triggerSpellId = GetSpellEffectInfo().TriggerSpell;
SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(triggerSpellId);
SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(triggerSpellId, GetBase().GetCastDifficulty());
if (triggeredSpellInfo != null)
if (aurApp.GetTarget().ExtraAttacks != 0 && triggeredSpellInfo.HasEffect(SpellEffectName.AddExtraAttacks))
return false;
@@ -818,7 +818,7 @@ namespace Game.Spells
if (pair.Key == spellId || pair.Key == spellId2 || pair.Key == spellId3 || pair.Key == spellId4)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(pair.Key);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(pair.Key, Difficulty.None);
if (spellInfo == null || !(spellInfo.IsPassive() || spellInfo.HasAttribute(SpellAttr0.HiddenClientside)))
continue;
@@ -1340,7 +1340,7 @@ namespace Game.Spells
if (modelid > 0)
{
SpellInfo transformSpellInfo = Global.SpellMgr.GetSpellInfo(target.GetTransForm());
SpellInfo transformSpellInfo = Global.SpellMgr.GetSpellInfo(target.GetTransForm(), GetBase().GetCastDifficulty());
if (transformSpellInfo == null || !GetSpellInfo().IsPositive())
target.SetDisplayId(modelid);
}
@@ -1438,7 +1438,7 @@ namespace Game.Spells
if (apply)
{
// update active transform spell only when transform not set or not overwriting negative by positive case
SpellInfo transformSpellInfo = Global.SpellMgr.GetSpellInfo(target.GetTransForm());
SpellInfo transformSpellInfo = Global.SpellMgr.GetSpellInfo(target.GetTransForm(), GetBase().GetCastDifficulty());
if (transformSpellInfo == null || !GetSpellInfo().IsPositive() || transformSpellInfo.IsPositive())
{
target.SetTransForm(GetId());
@@ -2168,7 +2168,7 @@ namespace Game.Spells
}
//some spell has one aura of mount and one of vehicle
foreach (SpellEffectInfo effect in GetBase().GetSpellEffectInfos())
foreach (SpellEffectInfo effect in GetSpellInfo().GetEffects())
if (effect != null && GetSpellEffectInfo().Effect == SpellEffectName.Summon && effect.MiscValue == GetMiscValue())
displayId = 0;
}
@@ -4464,10 +4464,10 @@ namespace Game.Spells
uint spellId = 24659;
if (apply && caster != null)
{
SpellInfo spell = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spell = Global.SpellMgr.GetSpellInfo(spellId, GetBase().GetCastDifficulty());
for (uint i = 0; i < spell.StackAmount; ++i)
caster.CastSpell(target, spell.Id, true, null, null, GetCasterGUID());
caster.CastSpell(target, spell, true, null, null, GetCasterGUID());
break;
}
target.RemoveAurasDueToSpell(spellId);
@@ -4479,9 +4479,9 @@ namespace Game.Spells
uint spellId = 24662;
if (apply && caster != null)
{
SpellInfo spell = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spell = Global.SpellMgr.GetSpellInfo(spellId, GetBase().GetCastDifficulty());
for (uint i = 0; i < spell.StackAmount; ++i)
caster.CastSpell(target, spell.Id, true, null, null, GetCasterGUID());
caster.CastSpell(target, spell, true, null, null, GetCasterGUID());
break;
}
target.RemoveAurasDueToSpell(spellId);
@@ -4720,11 +4720,11 @@ namespace Game.Spells
Unit target = aurApp.GetTarget();
uint triggeredSpellId = GetSpellEffectInfo().TriggerSpell;
SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(triggeredSpellId);
SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(triggeredSpellId, GetBase().GetCastDifficulty());
if (triggeredSpellInfo == null)
return;
Unit caster = triggeredSpellInfo.NeedsToBeTriggeredByCaster(m_spellInfo, target.GetMap().GetDifficultyID()) ? GetCaster() : target;
Unit caster = triggeredSpellInfo.NeedsToBeTriggeredByCaster(m_spellInfo) ? GetCaster() : target;
if (!caster)
return;
@@ -4740,13 +4740,13 @@ namespace Game.Spells
}
else
{
ObjectGuid casterGUID = triggeredSpellInfo.NeedsToBeTriggeredByCaster(m_spellInfo, caster.GetMap().GetDifficultyID()) ? GetCasterGUID() : target.GetGUID();
ObjectGuid casterGUID = triggeredSpellInfo.NeedsToBeTriggeredByCaster(m_spellInfo) ? GetCasterGUID() : target.GetGUID();
target.RemoveAura(triggeredSpellId, casterGUID, 0, aurApp.GetRemoveMode());
}
}
else if (mode.HasAnyFlag(AuraEffectHandleModes.Reapply) && apply)
{
ObjectGuid casterGUID = triggeredSpellInfo.NeedsToBeTriggeredByCaster(m_spellInfo, caster.GetMap().GetDifficultyID()) ? GetCasterGUID() : target.GetGUID();
ObjectGuid casterGUID = triggeredSpellInfo.NeedsToBeTriggeredByCaster(m_spellInfo) ? GetCasterGUID() : target.GetGUID();
// change the stack amount to be equal to stack amount of our aura
Aura triggeredAura = target.GetAura(triggeredSpellId, casterGUID);
if (triggeredAura != null)
@@ -5054,7 +5054,7 @@ namespace Game.Spells
// generic casting code with custom spells and target/caster customs
uint triggerSpellId = GetSpellEffectInfo().TriggerSpell;
SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(triggerSpellId);
SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(triggerSpellId, GetBase().GetCastDifficulty());
SpellInfo auraSpellInfo = GetSpellInfo();
uint auraId = auraSpellInfo.Id;
@@ -5320,11 +5320,11 @@ namespace Game.Spells
}
// Reget trigger spell proto
triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(triggerSpellId);
triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(triggerSpellId, GetBase().GetCastDifficulty());
if (triggeredSpellInfo != null)
{
Unit triggerCaster = triggeredSpellInfo.NeedsToBeTriggeredByCaster(m_spellInfo, target.GetMap().GetDifficultyID()) ? caster : target;
Unit triggerCaster = triggeredSpellInfo.NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target;
if (triggerCaster != null)
{
triggerCaster.CastSpell(target, triggeredSpellInfo, true, null, this);
@@ -5338,10 +5338,10 @@ namespace Game.Spells
void HandlePeriodicTriggerSpellWithValueAuraTick(Unit target, Unit caster)
{
uint triggerSpellId = GetSpellEffectInfo().TriggerSpell;
SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(triggerSpellId);
SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(triggerSpellId, GetBase().GetCastDifficulty());
if (triggeredSpellInfo != null)
{
Unit triggerCaster = triggeredSpellInfo.NeedsToBeTriggeredByCaster(m_spellInfo, target.GetMap().GetDifficultyID()) ? caster : target;
Unit triggerCaster = triggeredSpellInfo.NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target;
if (triggerCaster != null)
{
int basepoints = GetAmount();
@@ -5571,7 +5571,7 @@ namespace Game.Spells
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, GetSpellInfo(), GetBase().GetSpellXSpellVisualId(), GetSpellInfo().GetSchoolMask(), GetBase().GetCastGUID());
log.damage = damage;
log.originalDamage = dmg;
log.absorb = absorb;
@@ -5876,7 +5876,7 @@ namespace Game.Spells
SpellInfo spellProto = GetSpellInfo();
// maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(caster, target, spellProto.Id, GetBase().GetSpellXSpellVisualId(), spellProto.SchoolMask, GetBase().GetCastGUID());
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(caster, target, spellProto, GetBase().GetSpellXSpellVisualId(), spellProto.SchoolMask, GetBase().GetCastGUID());
// no SpellDamageBonus for burn mana
caster.CalculateSpellDamageTaken(damageInfo, (int)(gain * dmgMultiplier), spellProto);
@@ -5917,7 +5917,7 @@ namespace Game.Spells
Unit triggerTarget = eventInfo.GetProcTarget();
uint triggerSpellId = GetSpellEffectInfo().TriggerSpell;
SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(triggerSpellId);
SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(triggerSpellId, GetBase().GetCastDifficulty());
if (triggeredSpellInfo != null)
{
Log.outDebug(LogFilter.Spells, "AuraEffect.HandleProcTriggerSpellAuraProc: Triggering spell {0} from aura {1} proc", triggeredSpellInfo.Id, GetId());
@@ -5933,7 +5933,7 @@ namespace Game.Spells
Unit triggerTarget = eventInfo.GetProcTarget();
uint triggerSpellId = GetSpellEffectInfo().TriggerSpell;
SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(triggerSpellId);
SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(triggerSpellId, GetBase().GetCastDifficulty());
if (triggeredSpellInfo != null)
{
int basepoints0 = GetAmount();
@@ -5954,7 +5954,7 @@ namespace Game.Spells
return;
}
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(target, triggerTarget, GetId(), GetBase().GetSpellXSpellVisualId(), GetSpellInfo().SchoolMask, GetBase().GetCastGUID());
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(target, triggerTarget, GetSpellInfo(), GetBase().GetSpellXSpellVisualId(), GetSpellInfo().SchoolMask, GetBase().GetCastGUID());
int damage = (int)target.SpellDamageBonusDone(triggerTarget, GetSpellInfo(), (uint)GetAmount(), DamageEffectType.SpellDirect, GetSpellEffectInfo());
damage = (int)triggerTarget.SpellDamageBonusTaken(target, GetSpellInfo(), (uint)damage, DamageEffectType.SpellDirect, GetSpellEffectInfo());
target.CalculateSpellDamageTaken(damageInfo, damage, GetSpellInfo());
@@ -6128,7 +6128,7 @@ namespace Game.Spells
return;
Unit target = aurApp.GetTarget();
SpellInfo triggerSpellInfo = Global.SpellMgr.GetSpellInfo(GetSpellEffectInfo().TriggerSpell);
SpellInfo triggerSpellInfo = Global.SpellMgr.GetSpellInfo(GetSpellEffectInfo().TriggerSpell, GetBase().GetCastDifficulty());
if (triggerSpellInfo == null)
return;
@@ -6139,7 +6139,7 @@ namespace Game.Spells
else
{
List<uint> summonedEntries = new List<uint>();
foreach (var spellEffect in triggerSpellInfo.GetEffectsForDifficulty(target.GetMap().GetDifficultyID()))
foreach (var spellEffect in triggerSpellInfo.GetEffects())
{
if (spellEffect != null && spellEffect.Effect == SpellEffectName.Summon)
{
+7 -2
View File
@@ -17,6 +17,7 @@
using Framework.Constants;
using Framework.Database;
using Game.DataStorage;
using Game.Entities;
using System.Collections.Generic;
using System.Linq;
@@ -62,7 +63,7 @@ namespace Game.Spells
if (reqSkillOrSpell > 0) // spell case
{
uint absReqSkillOrSpell = (uint)reqSkillOrSpell;
SpellInfo reqSpellInfo = Global.SpellMgr.GetSpellInfo(absReqSkillOrSpell);
SpellInfo reqSpellInfo = Global.SpellMgr.GetSpellInfo(absReqSkillOrSpell, Difficulty.None);
if (reqSpellInfo == null)
{
if (!reportedReqSpells.Contains(absReqSkillOrSpell))
@@ -117,8 +118,12 @@ namespace Game.Spells
Log.outError(LogFilter.Sql, "Some items can't be successfully discovered: have in chance field value < 0.000001 in `skill_discovery_template` DB table . List:\n{0}", ssNonDiscoverableEntries.ToString());
// report about empty data for explicit discovery spells
foreach (var spellEntry in Global.SpellMgr.GetSpellInfoStorage().Values)
foreach (SpellNameRecord spellNameEntry in CliDB.SpellNameStorage.Values)
{
SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(spellNameEntry.Id, Difficulty.None);
if (spellEntry == null)
continue;
// skip not explicit discovery spells
if (!spellEntry.IsExplicitDiscovery())
continue;
+4 -4
View File
@@ -44,14 +44,14 @@ namespace Game.Spells
{
uint spellId = result.Read<uint>(0);
if (!Global.SpellMgr.HasSpellInfo(spellId))
if (!Global.SpellMgr.HasSpellInfo(spellId, Framework.Constants.Difficulty.None))
{
Log.outError(LogFilter.Sql, "Skill specialization {0} has non-existent spell id in `skill_extra_item_template`!", spellId);
continue;
}
uint requiredSpecialization = result.Read<uint>(1);
if (!Global.SpellMgr.HasSpellInfo(requiredSpecialization))
if (!Global.SpellMgr.HasSpellInfo(requiredSpecialization, Framework.Constants.Difficulty.None))
{
Log.outError(LogFilter.Sql, "Skill specialization {0} have not existed required specialization spell id {1} in `skill_extra_item_template`!", spellId, requiredSpecialization);
continue;
@@ -144,14 +144,14 @@ namespace Game.Spells
do
{
uint spellId = result.Read<uint>(0);
if (!Global.SpellMgr.HasSpellInfo(spellId))
if (!Global.SpellMgr.HasSpellInfo(spellId, Framework.Constants.Difficulty.None))
{
Log.outError(LogFilter.Sql, "Skill perfection data for spell {0} has non-existent spell id in `skill_perfect_item_template`!", spellId);
continue;
}
uint requiredSpecialization = result.Read<uint>(1);
if (!Global.SpellMgr.HasSpellInfo(requiredSpecialization))
if (!Global.SpellMgr.HasSpellInfo(requiredSpecialization, Framework.Constants.Difficulty.None))
{
Log.outError(LogFilter.Sql, "Skill perfection data for spell {0} has non-existent required specialization spell id {1} in `skill_perfect_item_template`!", spellId, requiredSpecialization);
continue;
+65 -85
View File
@@ -40,10 +40,9 @@ namespace Game.Spells
{
m_spellInfo = info;
m_caster = (info.HasAttribute(SpellAttr6.CastByCharmer) && caster.GetCharmerOrOwner() != null ? caster.GetCharmerOrOwner() : caster);
m_spellValue = new SpellValue(caster.GetMap().GetDifficultyID(), m_spellInfo, caster);
m_spellValue = new SpellValue(m_spellInfo, caster);
m_preGeneratedPath = new PathGenerator(m_caster);
m_castItemLevel = -1;
_effects = info.GetEffectsForDifficulty(caster.GetMap().GetDifficultyID());
m_castId = ObjectGuid.Create(HighGuid.Cast, SpellCastSource.Normal, m_caster.GetMapId(), m_spellInfo.Id, m_caster.GetMap().GenerateLowGuid(HighGuid.Cast));
m_SpellVisual = caster.GetCastSpellXSpellVisualId(m_spellInfo);
@@ -235,7 +234,7 @@ namespace Game.Spells
SelectExplicitTargets();
uint processedAreaEffectsMask = 0;
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect == null)
continue;
@@ -330,11 +329,11 @@ namespace Game.Spells
// targets for effect already selected
if (Convert.ToBoolean(effectMask & processedEffectMask))
return;
SpellEffectInfo _effect = GetEffect(effIndex);
SpellEffectInfo _effect = m_spellInfo.GetEffect(effIndex);
if (_effect != null)
{
// choose which targets we can select at once
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect == null || effect.EffectIndex <= effIndex)
continue;
@@ -509,7 +508,7 @@ namespace Game.Spells
return;
}
SpellEffectInfo effect = GetEffect(effIndex);
SpellEffectInfo effect = m_spellInfo.GetEffect(effIndex);
if (effect == null)
return;
@@ -644,7 +643,7 @@ namespace Game.Spells
List<WorldObject> targets = new List<WorldObject>();
SpellTargetObjectTypes objectType = targetType.GetObjectType();
SpellTargetCheckTypes selectionType = targetType.GetCheckType();
SpellEffectInfo effect = GetEffect(effIndex);
SpellEffectInfo effect = m_spellInfo.GetEffect(effIndex);
if (effect == null)
return;
@@ -732,7 +731,7 @@ namespace Game.Spells
return;
}
List<WorldObject> targets = new List<WorldObject>();
SpellEffectInfo effect = GetEffect(effIndex);
SpellEffectInfo effect = m_spellInfo.GetEffect(effIndex);
if (effect == null)
return;
@@ -830,7 +829,7 @@ namespace Game.Spells
break;
}
default:
SpellEffectInfo effect = GetEffect(effIndex);
SpellEffectInfo effect = m_spellInfo.GetEffect(effIndex);
if (effect != null)
{
float dist = effect.CalcRadius(m_caster);
@@ -882,11 +881,11 @@ namespace Game.Spells
switch (targetType.GetTarget())
{
case Targets.DestEnemy:
case Targets.DestTargetEnemy:
case Targets.DestAny:
break;
default:
SpellEffectInfo effect = GetEffect(effIndex);
SpellEffectInfo effect = m_spellInfo.GetEffect(effIndex);
if (effect != null)
{
float angle = targetType.CalcDirectionAngle();
@@ -927,7 +926,7 @@ namespace Game.Spells
case Targets.DestDest:
return;
default:
SpellEffectInfo effect = GetEffect(effIndex);
SpellEffectInfo effect = m_spellInfo.GetEffect(effIndex);
if (effect != null)
{
float angle = targetType.CalcDirectionAngle();
@@ -1018,7 +1017,7 @@ namespace Game.Spells
void SelectImplicitChainTargets(uint effIndex, SpellImplicitTargetInfo targetType, WorldObject target, uint effMask)
{
SpellEffectInfo effect = GetEffect(effIndex);
SpellEffectInfo effect = m_spellInfo.GetEffect(effIndex);
if (effect == null)
return;
@@ -1030,7 +1029,7 @@ namespace Game.Spells
if (maxTargets > 1)
{
// mark damage multipliers as used
foreach (SpellEffectInfo eff in GetEffects())
foreach (SpellEffectInfo eff in m_spellInfo.GetEffects())
if (eff != null && Convert.ToBoolean(effMask & (1 << (int)eff.EffectIndex)))
m_damageMultipliers[eff.EffectIndex] = 1.0f;
m_applyMultiplierMask |= (byte)effMask;
@@ -1090,7 +1089,7 @@ namespace Game.Spells
// We should check if triggered spell has greater range (which is true in many cases, and initial spell has too short max range)
// limit max range to 300 yards, sometimes triggered spells can have 50000yds
float bestDist = m_spellInfo.GetMaxRange(false);
SpellInfo triggerSpellInfo = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell);
SpellInfo triggerSpellInfo = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell, GetCastDifficulty());
if (triggerSpellInfo != null)
bestDist = Math.Min(Math.Max(bestDist, triggerSpellInfo.GetMaxRange(false)), Math.Min(dist2d, 300.0f));
@@ -1153,7 +1152,7 @@ namespace Game.Spells
{
// special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
// @todo this is a workaround - target shouldn't be stored in target map for those spells
SpellEffectInfo effect = GetEffect(effIndex);
SpellEffectInfo effect = m_spellInfo.GetEffect(effIndex);
if (effect == null)
return;
switch (effect.Effect)
@@ -1505,7 +1504,7 @@ namespace Game.Spells
void AddUnitTarget(Unit target, uint effectMask, bool checkIfValid = true, bool Implicit = true, Position losPosition = null)
{
uint validEffectMask = 0;
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
if (effect != null && (effectMask & (1 << (int)effect.EffectIndex)) != 0 && CheckEffectTarget(target, effect, losPosition))
validEffectMask |= 1u << (int)effect.EffectIndex;
@@ -1520,7 +1519,7 @@ namespace Game.Spells
return;
// Check for effect immune skip if immuned
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
if (effect != null && target.IsImmunedToSpellEffect(m_spellInfo, effect.EffectIndex, m_caster))
effectMask &= ~(uint)(1 << (int)effect.EffectIndex);
@@ -1603,7 +1602,7 @@ namespace Game.Spells
void AddGOTarget(GameObject go, uint effectMask)
{
uint validEffectMask = 0;
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
if (effect != null && (effectMask & (1 << (int)effect.EffectIndex)) != 0 && CheckEffectTarget(go, effect))
validEffectMask |= (uint)(1 << (int)effect.EffectIndex);
@@ -1660,7 +1659,7 @@ namespace Game.Spells
void AddItemTarget(Item item, uint effectMask)
{
uint validEffectMask = 0;
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
if (effect != null && (effectMask & (1 << (int)effect.EffectIndex)) != 0 && CheckEffectTarget(item, effect))
validEffectMask |= 1u << (int)effect.EffectIndex;
@@ -1709,7 +1708,7 @@ namespace Game.Spells
{
uint farMask = 0;
// create far target mask
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect != null && effect.IsFarUnitTargetEffect())
if (Convert.ToBoolean((1 << (int)effect.EffectIndex) & mask))
@@ -1726,7 +1725,7 @@ namespace Game.Spells
// do far effects on the unit
// can't use default call because of threading, do stuff as fast as possible
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
if (effect != null && Convert.ToBoolean(farMask & (1 << (int)effect.EffectIndex)))
HandleEffects(unit, null, null, effect.EffectIndex, SpellEffectHandleMode.HitTarget);
return;
@@ -1885,7 +1884,7 @@ namespace Game.Spells
else if (m_damage > 0)
{
// Fill base damage struct (unitTarget - is real spell target)
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(caster, unitTarget, m_spellInfo.Id, m_SpellVisual, m_spellSchoolMask, m_castId);
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(caster, unitTarget, m_spellInfo, m_SpellVisual, m_spellSchoolMask, m_castId);
// Check damage immunity
if (unitTarget.IsImmunedToDamage(m_spellInfo))
@@ -1926,7 +1925,7 @@ namespace Game.Spells
else
{
// Fill base damage struct (unitTarget - is real spell target)
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(caster, unitTarget, m_spellInfo.Id, m_SpellVisual, m_spellSchoolMask);
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(caster, unitTarget, m_spellInfo, m_SpellVisual, m_spellSchoolMask);
hitMask |= Unit.CreateProcHitMask(damageInfo, missInfo);
// Do triggers for unit
if (canEffectTrigger)
@@ -1996,7 +1995,7 @@ namespace Game.Spells
// disable effects to which unit is immune
SpellMissInfo returnVal = SpellMissInfo.Immune;
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
if (effect != null && Convert.ToBoolean(effectMask & (1 << (int)effect.EffectIndex)))
if (unit.IsImmunedToSpellEffect(m_spellInfo, effect.EffectIndex, m_caster))
effectMask &= (uint)~(1 << (int)effect.EffectIndex);
@@ -2051,7 +2050,7 @@ namespace Game.Spells
}
uint aura_effmask = 0;
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
if (effect != null && (Convert.ToBoolean(effectMask & (1 << (int)effect.EffectIndex)) && effect.IsUnitOwnedAuraEffect()))
aura_effmask |= (1u << (int)effect.EffectIndex);
@@ -2075,7 +2074,7 @@ namespace Game.Spells
if (m_originalCaster != null)
{
int[] basePoints = new int[SpellConst.MaxEffects];
foreach (SpellEffectInfo auraSpellEffect in GetEffects())
foreach (SpellEffectInfo auraSpellEffect in m_spellInfo.GetEffects())
if (auraSpellEffect != null)
basePoints[auraSpellEffect.EffectIndex] = (m_spellValue.CustomBasePointsMask & (1 << (int)auraSpellEffect.EffectIndex)) != 0 ?
m_spellValue.EffectBasePoints[auraSpellEffect.EffectIndex] : auraSpellEffect.CalcBaseValue(m_originalCaster, unit, m_castItemEntry, m_castItemLevel);
@@ -2083,7 +2082,7 @@ namespace Game.Spells
bool refresh = false;
bool resetPeriodicTimer = !_triggeredCastFlags.HasAnyFlag(TriggerCastFlags.DontResetPeriodicTimer);
m_spellAura = Aura.TryRefreshStackOrCreate(m_spellInfo, m_castId, (byte)effectMask, unit,
m_originalCaster, out refresh, basePoints, m_CastItem, ObjectGuid.Empty, resetPeriodicTimer, ObjectGuid.Empty, m_castItemEntry, m_castItemLevel);
m_originalCaster, GetCastDifficulty(), out refresh, basePoints, m_CastItem, ObjectGuid.Empty, resetPeriodicTimer, ObjectGuid.Empty, m_castItemEntry, m_castItemLevel);
if (m_spellAura != null)
{
// Set aura stack amount to desired value
@@ -2117,7 +2116,7 @@ namespace Game.Spells
{
m_spellAura.Remove();
bool found = false;
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
if (effect != null && (Convert.ToBoolean(effectMask & (1 << (int)effect.EffectIndex)) && effect.Effect != SpellEffectName.ApplyAura))
found = true;
if (!found)
@@ -2137,7 +2136,7 @@ namespace Game.Spells
{
int origDuration = duration;
duration = 0;
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect != null)
{
@@ -2168,7 +2167,7 @@ namespace Game.Spells
}
}
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
if (effect != null && Convert.ToBoolean(effectMask & (1 << (int)effect.EffectIndex)))
HandleEffects(unit, null, null, effect.EffectIndex, SpellEffectHandleMode.HitTarget);
@@ -2244,7 +2243,7 @@ namespace Game.Spells
PrepareScriptHitHandlers();
CallScriptBeforeHitHandlers(SpellMissInfo.None);
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
if (effect != null && Convert.ToBoolean(effectMask & (1 << (int)effect.EffectIndex)))
HandleEffects(null, null, go, effect.EffectIndex, SpellEffectHandleMode.HitTarget);
@@ -2264,7 +2263,7 @@ namespace Game.Spells
PrepareScriptHitHandlers();
CallScriptBeforeHitHandlers(SpellMissInfo.None);
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
if (effect != null && Convert.ToBoolean(effectMask & (1 << (int)effect.EffectIndex)))
HandleEffects(null, target.item, null, effect.EffectIndex, SpellEffectHandleMode.HitTarget);
@@ -2281,7 +2280,7 @@ namespace Game.Spells
uint channelTargetEffectMask = m_channelTargetEffectMask;
uint channelAuraMask = 0;
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
if (effect != null && effect.Effect == SpellEffectName.ApplyAura)
channelAuraMask |= (1u << (int)effect.EffectIndex);
@@ -2481,7 +2480,7 @@ namespace Game.Spells
if (!_triggeredCastFlags.HasAnyFlag(TriggerCastFlags.IgnoreAuraInterruptFlags) && m_spellInfo.IsBreakingStealth())
{
m_caster.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Cast);
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect != null && effect.GetUsedTargetObjectType() == SpellTargetObjectTypes.Unit)
{
@@ -2999,7 +2998,7 @@ namespace Game.Spells
PrepareScriptHitHandlers();
// handle effects with SPELL_EFFECT_HANDLE_HIT mode
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
// don't do anything for empty effect
if (effect == null || !effect.IsEffect())
@@ -3078,7 +3077,7 @@ namespace Game.Spells
// check if the player caster has moved before the spell finished
// with the exception of spells affected with SPELL_AURA_CAST_WHILE_WALKING effect
SpellEffectInfo effect = GetEffect(0);
SpellEffectInfo effect = m_spellInfo.GetEffect(0);
if ((m_caster.IsTypeId(TypeId.Player) && m_timer != 0) &&
m_caster.IsMoving() && m_spellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.Movement) &&
((effect != null && effect.Effect != SpellEffectName.Stuck) || !m_caster.HasUnitMovementFlag(MovementFlag.FallingFar)) &&
@@ -3187,7 +3186,7 @@ namespace Game.Spells
{
// Unsummon statue
uint spell = m_caster.m_unitData.CreatedBySpell;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell, GetCastDifficulty());
if (spellInfo != null && spellInfo.IconFileDataId == 134230)
{
Log.outDebug(LogFilter.Spells, "Statue {0} is unsummoned in spell {1} finish", m_caster.GetGUID().ToString(), m_spellInfo.Id);
@@ -3325,7 +3324,7 @@ namespace Game.Spells
else
{
uint item = 0;
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(caster.GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
if (effect.ItemType != 0)
item = effect.ItemType;
ItemTemplate proto = Global.ObjectMgr.GetItemTemplate(item);
@@ -3799,7 +3798,7 @@ namespace Game.Spells
spellExecuteLog.Caster = m_caster.GetGUID();
spellExecuteLog.SpellID = m_spellInfo.Id;
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect == null)
continue;
@@ -4321,7 +4320,7 @@ namespace Game.Spells
gameObjTarget = pGOTarget;
destTarget = m_destTargets[i].Position;
effectInfo = GetEffect(i);
effectInfo = m_spellInfo.GetEffect(i);
if (effectInfo == null)
{
Log.outError(LogFilter.Spells, "Spell: {0} HandleEffects at EffectIndex: {1} missing effect", m_spellInfo.Id, i);
@@ -4477,7 +4476,7 @@ namespace Game.Spells
if (m_caster.IsTypeId(TypeId.Player) && m_caster.ToPlayer().IsMoving() && (!m_caster.IsCharmed() || !m_caster.GetCharmerGUID().IsCreature()) && !m_caster.HasAuraTypeWithAffectMask(AuraType.CastWhileWalking, m_spellInfo))
{
// skip stuck spell to allow use it in falling case and apply spell limitations at movement
SpellEffectInfo effect = GetEffect(0);
SpellEffectInfo effect = m_spellInfo.GetEffect(0);
if ((!m_caster.HasUnitMovementFlag(MovementFlag.FallingFar) || (effect != null && effect.Effect != SpellEffectName.Stuck)) &&
(IsAutoRepeat() || m_spellInfo.HasAuraInterruptFlag(SpellAuraInterruptFlags.NotSeated)))
return SpellCastResult.Moving;
@@ -4584,7 +4583,7 @@ namespace Game.Spells
}
// check pet presence
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect != null && effect.TargetA.GetTarget() == Targets.UnitPet)
{
@@ -4678,7 +4677,7 @@ namespace Game.Spells
if (castResult != SpellCastResult.SpellCastOk)
return castResult;
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect == null)
continue;
@@ -4712,11 +4711,10 @@ namespace Game.Spells
break;
Pet pet = m_caster.ToPlayer().GetPet();
if (pet == null)
return SpellCastResult.NoPet;
SpellInfo learn_spellproto = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell);
SpellInfo learn_spellproto = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell, Difficulty.None);
if (learn_spellproto == null)
return SpellCastResult.NotKnown;
@@ -4749,7 +4747,7 @@ namespace Game.Spells
if (pet == null || pet.GetOwner() != m_caster)
return SpellCastResult.BadTargets;
SpellInfo learn_spellproto = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell);
SpellInfo learn_spellproto = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell, Difficulty.None);
if (learn_spellproto == null)
return SpellCastResult.NotKnown;
@@ -5194,7 +5192,7 @@ namespace Game.Spells
}
}
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect == null)
continue;
@@ -5255,7 +5253,7 @@ namespace Game.Spells
}
case AuraType.Mounted:
{
if (m_caster.IsInWater() && m_spellInfo.HasAura(m_caster.GetMap().GetDifficultyID(), AuraType.ModIncreaseMountedFlightSpeed))
if (m_caster.IsInWater() && m_spellInfo.HasAura(AuraType.ModIncreaseMountedFlightSpeed))
return SpellCastResult.OnlyAbovewater;
// Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
@@ -5613,7 +5611,7 @@ namespace Game.Spells
ObjectGuid targetguid = target.GetGUID();
// check if target already has the same or a more powerful aura
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect == null)
continue;
@@ -5837,7 +5835,7 @@ namespace Game.Spells
{
// such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
SpellCastResult failReason = SpellCastResult.SpellCastOk;
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
// skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
if (effect == null || effect.TargetA.GetTarget() == Targets.UnitPet)
@@ -5993,7 +5991,7 @@ namespace Game.Spells
}
// special checks for spell effects
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect == null)
continue;
@@ -6028,7 +6026,7 @@ namespace Game.Spells
player.SendEquipError(msg, null, null, effect.ItemType);
return SpellCastResult.DontReport;
}
else if ((efi = GetEffect(1)) != null)
else if ((efi = m_spellInfo.GetEffect(1)) != null)
player.CastSpell(m_caster, (uint)efi.CalcValue(), false); // move this to anywhere
return SpellCastResult.DontReport;
}
@@ -6437,7 +6435,7 @@ namespace Game.Spells
WorldObject transport = null;
// update effect destinations (in case of moved transport dest target)
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect == null)
continue;
@@ -6471,6 +6469,11 @@ namespace Game.Spells
return CurrentSpellTypes.Generic;
}
public Difficulty GetCastDifficulty()
{
return m_caster.GetMap().GetDifficultyID();
}
bool CheckEffectTarget(Unit target, SpellEffectInfo effect, Position losPosition)
{
if (!effect.IsEffect())
@@ -6632,7 +6635,7 @@ namespace Game.Spells
void HandleLaunchPhase()
{
// handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
// don't do anything for empty effect
if (effect == null || !effect.IsEffect())
@@ -6642,7 +6645,7 @@ namespace Game.Spells
}
float[] multiplier = new float[SpellConst.MaxEffects];
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
if (effect != null && Convert.ToBoolean(m_applyMultiplierMask & (1 << (int)effect.EffectIndex)))
multiplier[effect.EffectIndex] = effect.CalcDamageMultiplier(m_originalCaster, this);
@@ -6674,7 +6677,7 @@ namespace Game.Spells
if (unit == null)
return;
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect != null && Convert.ToBoolean(targetInfo.effectMask & (1 << (int)effect.EffectIndex)))
{
@@ -6723,7 +6726,7 @@ namespace Game.Spells
if (lockInfo == null)
return SpellCastResult.BadTargets;
SpellEffectInfo effect = GetEffect(effIndex);
SpellEffectInfo effect = m_spellInfo.GetEffect(effIndex);
if (effect == null)
return SpellCastResult.BadTargets; // no idea about correct error
@@ -7054,7 +7057,7 @@ namespace Game.Spells
{
bool only_on_caster = (triggeredByAura != null && triggeredByAura.HasAttribute(SpellAttr4.ProcOnlyOnCaster));
// If triggeredByAura has SPELL_ATTR4_PROC_ONLY_ON_CASTER then it can only proc on a casted spell with TARGET_UNIT_CASTER
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect != null && (Convert.ToBoolean(effMask & (1 << (int)effect.EffectIndex)) && (!only_on_caster || (effect.TargetA.GetTarget() == Targets.UnitCaster))))
return true;
@@ -7073,7 +7076,7 @@ namespace Game.Spells
if (!aurEff.IsAffectingSpell(m_spellInfo))
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(aurEff.GetSpellEffectInfo().TriggerSpell);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(aurEff.GetSpellEffectInfo().TriggerSpell, GetCastDifficulty());
if (spellInfo != null)
{
// calculate the chance using spell base amount, because aura amount is not updated on combo-points change
@@ -7279,25 +7282,6 @@ namespace Game.Spells
public SpellInfo GetTriggeredByAuraSpell() { return m_triggeredByAuraSpell; }
SpellEffectInfo[] GetEffects() { return _effects; }
public SpellEffectInfo GetEffect(uint index)
{
if (index >= _effects.Length)
return null;
return _effects[index];
}
bool HasEffect(SpellEffectName effect)
{
foreach (SpellEffectInfo eff in GetEffects())
{
if (eff != null && eff.IsEffect(effect))
return true;
}
return false;
}
public static implicit operator bool(Spell spell)
{
return spell != null;
@@ -7412,8 +7396,6 @@ namespace Game.Spells
// and in same time need aura data and after aura deleting.
public SpellInfo m_triggeredByAuraSpell;
SpellEffectInfo[] _effects = new SpellEffectInfo[SpellConst.MaxEffects];
bool m_skipCheck;
#endregion
}
@@ -7605,11 +7587,9 @@ namespace Game.Spells
public class SpellValue
{
public SpellValue(Difficulty difficulty, SpellInfo proto, Unit caster)
public SpellValue(SpellInfo proto, Unit caster)
{
var effects = proto.GetEffectsForDifficulty(difficulty);
Cypher.Assert(effects.Length <= SpellConst.MaxEffects);
foreach (SpellEffectInfo effect in effects)
foreach (SpellEffectInfo effect in proto.GetEffects())
if (effect != null)
EffectBasePoints[effect.EffectIndex] = effect.CalcBaseValue(caster, null, 0, -1);
+27 -85
View File
@@ -133,7 +133,7 @@ namespace Game.Spells
DamageInfo damageInfo = new DamageInfo(m_caster, unitTarget, (uint)damage, m_spellInfo, m_spellInfo.GetSchoolMask(), DamageEffectType.SpellDirect, WeaponAttackType.BaseAttack);
m_caster.CalcAbsorbResist(damageInfo);
SpellNonMeleeDamage log = new SpellNonMeleeDamage(m_caster, unitTarget, m_spellInfo.Id, m_SpellVisual, m_spellInfo.GetSchoolMask(), m_castId);
SpellNonMeleeDamage log = new SpellNonMeleeDamage(m_caster, unitTarget, m_spellInfo, m_SpellVisual, m_spellInfo.GetSchoolMask(), m_castId);
log.damage = damageInfo.GetDamage();
log.originalDamage = (uint)damage;
log.absorb = damageInfo.GetAbsorb();
@@ -359,7 +359,7 @@ namespace Game.Spells
case 29284:
{
// Brittle Armor
SpellInfo spell = Global.SpellMgr.GetSpellInfo(24575);
SpellInfo spell = Global.SpellMgr.GetSpellInfo(24575, GetCastDifficulty());
if (spell == null)
return;
@@ -371,7 +371,7 @@ namespace Game.Spells
case 29286:
{
// Mercurial Shield
SpellInfo spell = Global.SpellMgr.GetSpellInfo(26464);
SpellInfo spell = Global.SpellMgr.GetSpellInfo(26464, GetCastDifficulty());
if (spell == null)
return;
@@ -401,7 +401,7 @@ namespace Game.Spells
}
// normal case
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(triggered_spell_id);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(triggered_spell_id, GetCastDifficulty());
if (spellInfo == null)
{
Log.outDebug(LogFilter.Spells, "Spell.EffectTriggerSpell spell {0} tried to trigger unknown spell {1}", m_spellInfo.Id, triggered_spell_id);
@@ -411,13 +411,13 @@ namespace Game.Spells
SpellCastTargets targets = new SpellCastTargets();
if (effectHandleMode == SpellEffectHandleMode.LaunchTarget)
{
if (!spellInfo.NeedsToBeTriggeredByCaster(m_spellInfo, m_caster.GetMap().GetDifficultyID()))
if (!spellInfo.NeedsToBeTriggeredByCaster(m_spellInfo))
return;
targets.SetUnitTarget(unitTarget);
}
else //if (effectHandleMode == SpellEffectHandleMode.Launch)
{
if (spellInfo.NeedsToBeTriggeredByCaster(m_spellInfo, m_caster.GetMap().GetDifficultyID()) && effectInfo.GetProvidedTargetMask().HasAnyFlag(SpellCastTargetFlags.UnitMask))
if (spellInfo.NeedsToBeTriggeredByCaster(m_spellInfo) && effectInfo.GetProvidedTargetMask().HasAnyFlag(SpellCastTargetFlags.UnitMask))
return;
if (spellInfo.GetExplicitTargetMask().HasAnyFlag(SpellCastTargetFlags.DestLocation))
@@ -450,7 +450,7 @@ namespace Game.Spells
uint triggered_spell_id = effectInfo.TriggerSpell;
// normal case
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(triggered_spell_id);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(triggered_spell_id, GetCastDifficulty());
if (spellInfo == null)
{
Log.outDebug(LogFilter.Spells, "Spell.EffectTriggerMissileSpell spell {0} tried to trigger unknown spell {1}", m_spellInfo.Id, triggered_spell_id);
@@ -460,13 +460,13 @@ namespace Game.Spells
SpellCastTargets targets = new SpellCastTargets();
if (effectHandleMode == SpellEffectHandleMode.HitTarget)
{
if (!spellInfo.NeedsToBeTriggeredByCaster(m_spellInfo, m_caster.GetMap().GetDifficultyID()))
if (!spellInfo.NeedsToBeTriggeredByCaster(m_spellInfo))
return;
targets.SetUnitTarget(unitTarget);
}
else //if (effectHandleMode == SpellEffectHandleMode.Hit)
{
if (spellInfo.NeedsToBeTriggeredByCaster(m_spellInfo, m_caster.GetMap().GetDifficultyID()) && effectInfo.GetProvidedTargetMask().HasAnyFlag(SpellCastTargetFlags.UnitMask))
if (spellInfo.NeedsToBeTriggeredByCaster(m_spellInfo) && effectInfo.GetProvidedTargetMask().HasAnyFlag(SpellCastTargetFlags.UnitMask))
return;
if (spellInfo.GetExplicitTargetMask().HasAnyFlag(SpellCastTargetFlags.DestLocation))
@@ -503,7 +503,7 @@ namespace Game.Spells
uint triggered_spell_id = effectInfo.TriggerSpell;
// normal case
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(triggered_spell_id);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(triggered_spell_id, GetCastDifficulty());
if (spellInfo == null)
{
Log.outError(LogFilter.Spells, "Spell.EffectForceCast of spell {0}: triggering unknown spell id {1}", m_spellInfo.Id, triggered_spell_id);
@@ -548,7 +548,7 @@ namespace Game.Spells
return;
uint triggered_spell_id = effectInfo.TriggerSpell;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(triggered_spell_id);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(triggered_spell_id, GetCastDifficulty());
if (spellInfo == null)
{
Log.outError(LogFilter.Spells, "EffectTriggerRitualOfSummoning of spell {0}: triggering unknown spell id {1}", m_spellInfo.Id, triggered_spell_id);
@@ -1217,7 +1217,7 @@ namespace Game.Spells
if (!dynObj.CreateDynamicObject(caster.GetMap().GenerateLowGuid(HighGuid.DynamicObject), caster, m_spellInfo, destTarget, radius, DynamicObjectType.AreaSpell, m_SpellVisual))
return;
Aura aura = Aura.TryCreate(m_spellInfo, m_castId, SpellConst.MaxEffectMask, dynObj, caster, m_spellValue.EffectBasePoints, null, ObjectGuid.Empty, ObjectGuid.Empty, m_castItemEntry, m_castItemLevel);
Aura aura = Aura.TryCreate(m_spellInfo, m_castId, SpellConst.MaxEffectMask, dynObj, caster, GetCastDifficulty(), m_spellValue.EffectBasePoints, null, ObjectGuid.Empty, ObjectGuid.Empty, m_castItemEntry, m_castItemLevel);
if (aura != null)
{
m_spellAura = aura;
@@ -1775,8 +1775,8 @@ namespace Game.Spells
int basePoints = effectInfo.CalcValue();
if (basePoints > SharedConst.MaxVehicleSeats)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)basePoints);
if (spellInfo != null && spellInfo.HasAura(m_originalCaster.GetMap().GetDifficultyID(), AuraType.ControlVehicle))
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)basePoints, GetCastDifficulty());
if (spellInfo != null && spellInfo.HasAura(AuraType.ControlVehicle))
spellId = spellInfo.Id;
}
@@ -2435,7 +2435,7 @@ namespace Game.Spells
if (pet == null)
return;
SpellInfo learn_spellproto = Global.SpellMgr.GetSpellInfo(effectInfo.TriggerSpell);
SpellInfo learn_spellproto = Global.SpellMgr.GetSpellInfo(effectInfo.TriggerSpell, Difficulty.None);
if (learn_spellproto == null)
return;
@@ -2497,7 +2497,7 @@ namespace Game.Spells
// and handle all effects at once
for (var i = effIndex + 1; i < SpellConst.MaxEffects; ++i)
{
var effect = GetEffect(i);
var effect = m_spellInfo.GetEffect(i);
if (effect == null)
continue;
@@ -2588,7 +2588,7 @@ namespace Game.Spells
// Blood Strike
if (m_spellInfo.SpellFamilyFlags[0].HasAnyFlag(0x400000u))
{
SpellEffectInfo effect = GetEffect(2);
SpellEffectInfo effect = m_spellInfo.GetEffect(2);
if (effect != null)
{
float bonusPct = effect.CalcValue(m_caster) * unitTarget.GetDiseasesByCaster(m_caster.GetGUID()) / 2.0f;
@@ -2606,7 +2606,7 @@ namespace Game.Spells
bool normalized = false;
float weaponDamagePercentMod = 1.0f;
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect == null)
continue;
@@ -2659,7 +2659,7 @@ namespace Game.Spells
uint weaponDamage = m_caster.CalculateDamage(m_attackType, normalized, addPctMods);
// Sequence is important
foreach (SpellEffectInfo effect in GetEffects())
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
{
if (effect == null)
continue;
@@ -3118,8 +3118,8 @@ namespace Game.Spells
if (unitTarget == null || !unitTarget.IsTypeId(TypeId.Player) || effIndex != 0)
return;
uint spellID = (uint)GetEffect(0).CalcValue();
uint questID = (uint)GetEffect(1).CalcValue();
uint spellID = (uint)m_spellInfo.GetEffect(0).CalcValue();
uint questID = (uint)m_spellInfo.GetEffect(1).CalcValue();
if (unitTarget.ToPlayer().GetQuestStatus(questID) == QuestStatus.Complete)
unitTarget.CastSpell(unitTarget, spellID, true);
@@ -3192,7 +3192,7 @@ namespace Game.Spells
{
// @todo a hack, range = 11, should after some time cast, otherwise too far
m_caster.CastSpell(parent, 62496, true);
unitTarget.CastSpell(parent, (uint)GetEffect(0).CalcValue());
unitTarget.CastSpell(parent, (uint)m_spellInfo.GetEffect(0).CalcValue());
}
}
}
@@ -3289,64 +3289,6 @@ namespace Game.Spells
}
break;
}
case SpellFamilyNames.Paladin:
{
// Judgement (seal trigger)
if (m_spellInfo.GetCategory() == (int)SpellCategories.Judgement)
{
if (unitTarget == null || !unitTarget.IsAlive())
return;
uint spellId1;
uint spellId2 = 0;
// Judgement self add switch
switch (m_spellInfo.Id)
{
case 53407: spellId1 = 20184; break; // Judgement of Justice
case 20271: // Judgement of Light
case 57774: spellId1 = 20185; break; // Judgement of Light
case 53408: spellId1 = 20186; break; // Judgement of Wisdom
default:
Log.outError(LogFilter.Spells, "Unsupported Judgement (seal trigger) spell (Id: {0}) in Spell.EffectScriptEffect", m_spellInfo.Id);
return;
}
// all seals have aura dummy in 2 effect
foreach (var app in m_caster.GetAppliedAuras())
{
Aura aura = app.Value.GetBase();
if (aura.GetSpellInfo().GetSpellSpecific() == SpellSpecificType.Seal)
{
AuraEffect aureff = aura.GetEffect(2);
if (aureff != null)
if (aureff.GetAuraType() == AuraType.Dummy)
{
if (Global.SpellMgr.GetSpellInfo((uint)aureff.GetAmount()) != null)
spellId2 = (uint)aureff.GetAmount();
break;
}
if (spellId2 == 0)
{
switch (app.Key)
{
// Seal of light, Seal of wisdom, Seal of justice
case 20165:
case 20166:
case 20164:
spellId2 = 54158;
break;
}
}
break;
}
}
if (spellId1 != 0)
m_caster.CastSpell(unitTarget, spellId1, true);
if (spellId2 != 0)
m_caster.CastSpell(unitTarget, spellId2, true);
return;
}
break;
}
}
// normal DB scripted effect
@@ -3535,7 +3477,7 @@ namespace Game.Spells
player.TeleportTo(player.GetHomebind(), TeleportToOptions.Spell);
// Stuck spell trigger Hearthstone cooldown
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(8690);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(8690, GetCastDifficulty());
if (spellInfo == null)
return;
@@ -4399,7 +4341,7 @@ namespace Game.Spells
if (totem != null && totem.IsTotem())
{
uint spell_id = totem.m_unitData.CreatedBySpell;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id, GetCastDifficulty());
if (spellInfo != null)
{
var costs = spellInfo.CalcPowerCost(m_caster, spellInfo.GetSchoolMask());
@@ -5244,7 +5186,7 @@ namespace Game.Spells
if (spell_id == 0)
continue;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id, GetCastDifficulty());
if (spellInfo == null)
continue;
@@ -5255,7 +5197,7 @@ namespace Game.Spells
continue;
TriggerCastFlags triggerFlags = (TriggerCastFlags.IgnoreGCD | TriggerCastFlags.IgnoreCastInProgress | TriggerCastFlags.CastDirectly | TriggerCastFlags.DontReportCastError);
m_caster.CastSpell(m_caster, spell_id, triggerFlags);
m_caster.CastSpell(m_caster, spellInfo, triggerFlags);
}
}
@@ -5365,7 +5307,7 @@ namespace Game.Spells
uint health = (uint)target.CountPctFromMaxHealth(damage);
uint mana = (uint)MathFunctions.CalculatePct(target.GetMaxPower(PowerType.Mana), damage);
uint resurrectAura = 0;
if (Global.SpellMgr.GetSpellInfo(effectInfo.TriggerSpell) != null)
if (Global.SpellMgr.HasSpellInfo(effectInfo.TriggerSpell, Difficulty.None))
resurrectAura = effectInfo.TriggerSpell;
if (resurrectAura != 0 && target.HasAura(resurrectAura))
+6 -6
View File
@@ -40,7 +40,7 @@ namespace Game.Spells
do
{
uint spellId = cooldownsResult.Read<uint>(0);
if (!Global.SpellMgr.HasSpellInfo(spellId))
if (!Global.SpellMgr.HasSpellInfo(spellId, Difficulty.None))
continue;
int index = (typeof(T) == typeof(Pet) ? 1 : 2);
@@ -222,7 +222,7 @@ namespace Game.Spells
if (IsSchoolLocked(spellInfo.GetSchoolMask()))
return false;
if (HasCooldown(spellInfo.Id, itemId, ignoreCategoryCooldown))
if (HasCooldown(spellInfo, itemId, ignoreCategoryCooldown))
return false;
if (!HasCharge(spellInfo.ChargeCategoryId))
@@ -459,7 +459,7 @@ namespace Game.Spells
player.SendPacket(new CooldownEvent(player != _owner, categoryEntry.SpellId));
if (startCooldown)
StartCooldown(Global.SpellMgr.GetSpellInfo(categoryEntry.SpellId), itemId, spell);
StartCooldown(Global.SpellMgr.GetSpellInfo(categoryEntry.SpellId, _owner.GetMap().GetDifficultyID()), itemId, spell);
}
player.SendPacket(new CooldownEvent(player != _owner, spellInfo.Id));
@@ -581,7 +581,7 @@ namespace Game.Spells
public bool HasCooldown(uint spellId, uint itemId = 0, bool ignoreCategoryCooldown = false)
{
return HasCooldown(Global.SpellMgr.GetSpellInfo(spellId), itemId, ignoreCategoryCooldown);
return HasCooldown(Global.SpellMgr.GetSpellInfo(spellId, _owner.GetMap().GetDifficultyID()), itemId, ignoreCategoryCooldown);
}
public bool HasCooldown(SpellInfo spellInfo, uint itemId = 0, bool ignoreCategoryCooldown = false)
@@ -663,7 +663,7 @@ namespace Game.Spells
spellCooldown.Flags = SpellCooldownFlags.None;
foreach (uint spellId in knownSpells)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, _owner.GetMap().GetDifficultyID());
if (spellInfo.IsCooldownStartedOnEvent())
continue;
@@ -904,7 +904,7 @@ namespace Game.Spells
// add all profession CDs created while in duel (if any)
foreach (var c in _spellCooldowns)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(c.Key);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(c.Key, Difficulty.None);
if (spellInfo.RecoveryTime > 10 * Time.Minute * Time.InMilliseconds || spellInfo.CategoryRecoveryTime > 10 * Time.Minute * Time.InMilliseconds)
_spellCooldownsBeforeDuel[c.Key] = _spellCooldowns[c.Key];
+144 -349
View File
@@ -30,31 +30,20 @@ namespace Game.Spells
{
public class SpellInfo
{
public SpellInfo(SpellInfoLoadHelper data, Dictionary<uint, SpellEffectRecord[]> effectsMap, MultiMap<uint, SpellXSpellVisualRecord> visuals)
public SpellInfo(SpellNameRecord spellName, Difficulty difficulty, SpellInfoLoadHelper data, List<SpellXSpellVisualRecord> visuals)
{
Id = data.Entry.Id;
Id = spellName.Id;
Difficulty = difficulty;
_effects = new Dictionary<uint, SpellEffectInfo[]>();
if (effectsMap != null)
foreach (SpellEffectRecord spellEffect in data.Effects)
{
foreach (var pair in effectsMap)
{
if (!_effects.ContainsKey(pair.Key))
_effects[pair.Key] = new SpellEffectInfo[pair.Value.Length];
for (int i = 0; i < pair.Value.Length; ++i)
{
SpellEffectRecord effect = pair.Value[i];
if (effect == null)
if (spellEffect == null)
continue;
_effects[pair.Key][effect.EffectIndex] = new SpellEffectInfo(this, effect.EffectIndex, effect);
}
}
_effects[spellEffect.EffectIndex] = new SpellEffectInfo(this, spellEffect);
}
SpellName = data.Entry.Name;
SpellName = spellName.Name;
SpellMiscRecord _misc = data.Misc;
if (_misc != null)
@@ -90,10 +79,6 @@ namespace Game.Spells
if (visuals != null)
_visuals = visuals;
// sort all visuals so that the ones without a condition requirement are last on the list
foreach (var key in _visuals.Keys.ToList())
_visuals[key] = _visuals[key].OrderByDescending(x => x.CasterPlayerConditionID).ToList();
// SpellScalingEntry
SpellScalingRecord _scaling = data.Scaling;
if (_scaling != null)
@@ -204,7 +189,7 @@ namespace Game.Spells
}
// SpellPowerEntry
PowerCosts = Global.DB2Mgr.GetSpellPowers(Id, Difficulty.None, out _hasPowerDifficultyData);
PowerCosts = data.Powers;
// SpellReagentsEntry
SpellReagentsRecord _reagents = data.Reagents;
@@ -248,73 +233,36 @@ namespace Game.Spells
_auraState = AuraStateType.None;
}
public bool HasEffect(Difficulty difficulty, SpellEffectName effect)
{
var effects = GetEffectsForDifficulty(difficulty);
foreach (var eff in effects)
{
if (eff != null && eff.IsEffect(effect))
return true;
}
return false;
}
public bool HasEffect(SpellEffectName effect)
{
foreach (var pair in _effects)
{
foreach (SpellEffectInfo eff in pair.Value)
{
foreach (SpellEffectInfo eff in _effects.Values)
if (eff != null && eff.IsEffect(effect))
return true;
}
}
return false;
}
public bool HasAura(Difficulty difficulty, AuraType aura)
{
var effects = GetEffectsForDifficulty(difficulty);
foreach (SpellEffectInfo effect in effects)
public bool HasAura(AuraType aura)
{
foreach (SpellEffectInfo effect in _effects.Values)
if (effect != null && effect.IsAura(aura))
return true;
}
return false;
}
public bool HasAreaAuraEffect(Difficulty difficulty)
{
var effects = GetEffectsForDifficulty(difficulty);
foreach (SpellEffectInfo effect in effects)
{
if (effect != null && effect.IsAreaAuraEffect())
return true;
}
return false;
}
public bool HasAreaAuraEffect()
{
foreach (var pair in _effects)
{
foreach (SpellEffectInfo effect in pair.Value)
{
foreach (SpellEffectInfo effect in _effects.Values)
if (effect != null && effect.IsAreaAuraEffect())
return true;
}
}
return false;
}
public bool HasOnlyDamageEffects()
{
foreach (var pair in _effects)
{
foreach (SpellEffectInfo effect in pair.Value)
foreach (SpellEffectInfo effect in _effects.Values)
{
if (effect == null)
continue;
@@ -334,15 +282,14 @@ namespace Game.Spells
return false;
}
}
}
return true;
}
public bool IsExplicitDiscovery()
{
SpellEffectInfo effect0 = GetEffect(Difficulty.None, 0);
SpellEffectInfo effect1 = GetEffect(Difficulty.None, 1);
SpellEffectInfo effect0 = GetEffect(0);
SpellEffectInfo effect1 = GetEffect(1);
return ((effect0 != null && (effect0.Effect == SpellEffectName.CreateRandomItem || effect0.Effect == SpellEffectName.CreateLoot))
&& effect1 != null && effect1.Effect == SpellEffectName.ScriptEffect)
@@ -356,16 +303,15 @@ namespace Game.Spells
public bool IsQuestTame()
{
SpellEffectInfo effect0 = GetEffect(Difficulty.None, 0);
SpellEffectInfo effect1 = GetEffect(Difficulty.None, 1);
SpellEffectInfo effect0 = GetEffect(0);
SpellEffectInfo effect1 = GetEffect(1);
return effect0 != null && effect1 != null && effect0.Effect == SpellEffectName.Threat && effect1.Effect == SpellEffectName.ApplyAura
&& effect1.ApplyAuraName == AuraType.Dummy;
}
public bool IsProfession(Difficulty difficulty = Difficulty.None)
public bool IsProfession()
{
var effects = GetEffectsForDifficulty(difficulty);
foreach (SpellEffectInfo effect in effects)
foreach (SpellEffectInfo effect in _effects.Values)
{
if (effect != null && effect.Effect == SpellEffectName.Skill)
{
@@ -378,25 +324,19 @@ namespace Game.Spells
return false;
}
public bool IsPrimaryProfession(Difficulty difficulty)
{
var effects = GetEffectsForDifficulty(difficulty);
foreach (SpellEffectInfo effect in effects)
public bool IsPrimaryProfession()
{
foreach (SpellEffectInfo effect in _effects.Values)
if (effect != null && effect.Effect == SpellEffectName.Skill)
{
uint skill = (uint)effect.MiscValue;
if (Global.SpellMgr.IsPrimaryProfessionSkill(skill))
if (Global.SpellMgr.IsPrimaryProfessionSkill((uint)effect.MiscValue))
return true;
}
}
return false;
}
public bool IsPrimaryProfessionFirstRank(Difficulty difficulty = Difficulty.None)
public bool IsPrimaryProfessionFirstRank()
{
return IsPrimaryProfession(difficulty) && GetRank() == 1;
return IsPrimaryProfession() && GetRank() == 1;
}
public bool IsAbilityOfSkillType(SkillType skillType)
@@ -410,26 +350,22 @@ namespace Game.Spells
return false;
}
public bool IsAffectingArea(Difficulty difficulty)
{
var effects = GetEffectsForDifficulty(difficulty);
foreach (SpellEffectInfo effect in effects)
public bool IsAffectingArea()
{
foreach (SpellEffectInfo effect in _effects.Values)
if (effect != null && effect.IsEffect() && (effect.IsTargetingArea() || effect.IsEffect(SpellEffectName.PersistentAreaAura) || effect.IsAreaAuraEffect()))
return true;
}
return false;
}
// checks if spell targets are selected from area, doesn't include spell effects in check (like area wide auras for example)
public bool IsTargetingArea(Difficulty difficulty)
{
var effects = GetEffectsForDifficulty(difficulty);
foreach (SpellEffectInfo effect in effects)
public bool IsTargetingArea()
{
foreach (SpellEffectInfo effect in _effects.Values)
if (effect != null && effect.IsEffect() && effect.IsTargetingArea())
return true;
}
return false;
}
@@ -438,7 +374,7 @@ namespace Game.Spells
return Convert.ToBoolean(GetExplicitTargetMask() & SpellCastTargetFlags.UnitMask);
}
public bool NeedsToBeTriggeredByCaster(SpellInfo triggeringSpell, Difficulty difficulty)
public bool NeedsToBeTriggeredByCaster(SpellInfo triggeringSpell)
{
if (NeedsExplicitUnitTarget())
return true;
@@ -446,8 +382,7 @@ namespace Game.Spells
if (triggeringSpell.IsChanneled())
{
SpellCastTargetFlags mask = 0;
var effects = GetEffectsForDifficulty(difficulty);
foreach (SpellEffectInfo effect in effects)
foreach (SpellEffectInfo effect in _effects.Values)
{
if (effect != null && (effect.TargetA.GetTarget() != Targets.UnitCaster && effect.TargetA.GetTarget() != Targets.DestCaster
&& effect.TargetB.GetTarget() != Targets.UnitCaster && effect.TargetB.GetTarget() != Targets.DestCaster))
@@ -483,8 +418,7 @@ namespace Game.Spells
return false;
// All stance spells. if any better way, change it.
var effects = GetEffectsForDifficulty(Difficulty.None);
foreach (SpellEffectInfo effect in effects)
foreach (SpellEffectInfo effect in _effects.Values)
{
if (effect == null)
continue;
@@ -550,8 +484,7 @@ namespace Game.Spells
public bool IsGroupBuff()
{
var effects = GetEffectsForDifficulty(Difficulty.None);
foreach (SpellEffectInfo effect in effects)
foreach (SpellEffectInfo effect in _effects.Values)
{
if (effect == null)
continue;
@@ -704,7 +637,7 @@ namespace Game.Spells
if (!IsAffectedBySpellMods())
return false;
SpellInfo affectSpell = Global.SpellMgr.GetSpellInfo(mod.spellId);
SpellInfo affectSpell = Global.SpellMgr.GetSpellInfo(mod.spellId, Difficulty);
if (affectSpell == null)
return false;
@@ -1010,7 +943,7 @@ namespace Game.Spells
// aura limitations
if (player)
{
foreach (SpellEffectInfo effect in GetEffectsForDifficulty(player.GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in _effects.Values)
{
if (effect == null || !effect.IsAura())
continue;
@@ -1184,7 +1117,7 @@ namespace Game.Spells
return SpellCastResult.TargetAurastate;
if (unitTarget.HasAuraType(AuraType.PreventResurrection))
if (HasEffect(caster.GetMap().GetDifficultyID(), SpellEffectName.SelfResurrect) || HasEffect(caster.GetMap().GetDifficultyID(), SpellEffectName.Resurrect))
if (HasEffect(SpellEffectName.SelfResurrect) || HasEffect(SpellEffectName.Resurrect))
return SpellCastResult.TargetCannotBeResurrected;
if (HasAttribute(SpellAttr8.BattleResurrection))
@@ -1251,7 +1184,7 @@ namespace Game.Spells
if (vehicle)
{
VehicleSeatFlags checkMask = 0;
foreach (SpellEffectInfo effect in GetEffectsForDifficulty(caster.GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in _effects.Values)
{
if (effect != null && effect.ApplyAuraName == AuraType.ModShapeshift)
{
@@ -1262,7 +1195,7 @@ namespace Game.Spells
}
}
if (HasAura(caster.GetMap().GetDifficultyID(), AuraType.Mounted))
if (HasAura(AuraType.Mounted))
checkMask |= VehicleSeatFlags.CanCastMountSpell;
if (checkMask == 0)
@@ -1276,7 +1209,7 @@ namespace Game.Spells
// Can only summon uncontrolled minions/guardians when on controlled vehicle
if (vehicleSeat.HasSeatFlag(VehicleSeatFlags.CanControl | VehicleSeatFlags.Unk2))
{
foreach (SpellEffectInfo effect in GetEffectsForDifficulty(caster.GetMap().GetDifficultyID()))
foreach (SpellEffectInfo effect in _effects.Values)
{
if (effect == null || effect.Effect != SpellEffectName.Summon)
continue;
@@ -1323,14 +1256,10 @@ namespace Game.Spells
if (Mechanic != 0)
mask |= (uint)(1 << (int)Mechanic);
foreach (var pair in _effects)
{
foreach (SpellEffectInfo effect in pair.Value)
{
foreach (SpellEffectInfo effect in _effects.Values)
if (effect != null && effect.IsEffect() && effect.Mechanic != 0)
mask |= (uint)(1 << (int)effect.Mechanic);
}
}
mask |= 1u << (int)effect.Mechanic;
return mask;
}
@@ -1340,14 +1269,10 @@ namespace Game.Spells
if (Mechanic != 0)
mask |= (uint)(1 << (int)Mechanic);
foreach (var pair in _effects)
{
foreach (SpellEffectInfo effect in pair.Value)
{
if (effect != null && effect.EffectIndex == effIndex && effect.IsEffect() && effect.Mechanic != 0)
mask |= (uint)(1 << (int)effect.Mechanic);
}
}
var effect = _effects.LookupByKey(effIndex);
if (effect != null && effect.IsEffect() && effect.Mechanic != 0)
mask |= 1u << (int)effect.Mechanic;
return mask;
}
@@ -1357,24 +1282,22 @@ namespace Game.Spells
if (Mechanic != 0)
mask |= (uint)(1 << (int)Mechanic);
foreach (var pair in _effects)
{
foreach (SpellEffectInfo effect in pair.Value)
{
foreach (SpellEffectInfo effect in _effects.Values)
if (effect != null && Convert.ToBoolean(effectMask & (1 << (int)effect.EffectIndex)) && effect.Mechanic != 0)
mask |= (uint)(1 << (int)effect.Mechanic);
}
}
mask |= 1u << (int)effect.Mechanic;
return mask;
}
public Mechanics GetEffectMechanic(uint effIndex, Difficulty difficulty)
public Mechanics GetEffectMechanic(uint effIndex)
{
SpellEffectInfo effect = GetEffect(difficulty, effIndex);
SpellEffectInfo effect = GetEffect(effIndex);
if (effect != null && effect.IsEffect() && effect.Mechanic != 0)
return effect.Mechanic;
if (Mechanic != 0)
return Mechanic;
return Mechanics.None;
}
@@ -1448,8 +1371,7 @@ namespace Game.Spells
if (Convert.ToBoolean(GetSchoolMask() & SpellSchoolMask.Frost))
{
foreach (var pair in _effects)
foreach (SpellEffectInfo effect in pair.Value)
foreach (SpellEffectInfo effect in _effects.Values)
if (effect != null && (effect.IsAura(AuraType.ModStun) || effect.IsAura(AuraType.ModRoot)))
_auraState = AuraStateType.Frozen;
}
@@ -1483,12 +1405,11 @@ namespace Game.Spells
{
bool food = false;
bool drink = false;
foreach (var pair in _effects)
{
foreach (SpellEffectInfo effect in pair.Value)
foreach (SpellEffectInfo effect in _effects.Values)
{
if (effect == null || !effect.IsAura())
continue;
switch (effect.ApplyAuraName)
{
// Food
@@ -1505,7 +1426,6 @@ namespace Game.Spells
break;
}
}
}
if (food && drink)
_spellSpecific = SpellSpecificType.FoodAndDrink;
@@ -1541,7 +1461,8 @@ namespace Game.Spells
// Arcane brillance and Arcane intelect (normal check fails because of flags difference)
if (SpellFamilyFlags[0].HasAnyFlag(0x400u))
_spellSpecific = SpellSpecificType.MageArcaneBrillance;
SpellEffectInfo effect = GetEffect(Difficulty.None, 0);
SpellEffectInfo effect = GetEffect(0);
if (effect != null && SpellFamilyFlags[0].HasAnyFlag(0x1000000u) && effect.IsAura(AuraType.ModConfuse))
_spellSpecific = SpellSpecificType.MagePolymorph;
@@ -1626,9 +1547,7 @@ namespace Game.Spells
break;
}
foreach (var pair in _effects)
{
foreach (SpellEffectInfo effect in pair.Value)
foreach (SpellEffectInfo effect in _effects.Values)
{
if (effect != null && effect.Effect == SpellEffectName.ApplyAura)
{
@@ -1653,7 +1572,6 @@ namespace Game.Spells
}
}
}
}
public void _LoadSpellDiminishInfo()
{
@@ -1691,7 +1609,7 @@ namespace Game.Spells
if (IsPositive())
return DiminishingGroup.None;
if (HasAura(Difficulty.None, AuraType.ModTaunt))
if (HasAura(AuraType.ModTaunt))
return DiminishingGroup.Taunt;
switch (Id)
@@ -2374,16 +2292,13 @@ namespace Game.Spells
_allowedMechanicMask |= immuneInfo.MechanicImmuneMask;
});
foreach (var effects in _effects)
{
foreach (SpellEffectInfo effect in effects.Value)
foreach (SpellEffectInfo effect in _effects.Values)
{
if (effect == null)
continue;
loadImmunityInfoFn(effect);
}
}
if (HasAttribute(SpellAttr5.UsableWhileStunned))
{
@@ -2489,7 +2404,7 @@ namespace Game.Spells
if (auraSpellInfo == null)
return false;
foreach (SpellEffectInfo effectInfo in GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effectInfo in _effects.Values)
{
if (effectInfo == null)
continue;
@@ -2515,7 +2430,7 @@ namespace Game.Spells
return true;
bool immuneToAllEffects = true;
foreach (SpellEffectInfo auraSpellEffectInfo in auraSpellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo auraSpellEffectInfo in auraSpellInfo.GetEffects())
{
if (auraSpellEffectInfo == null)
continue;
@@ -2581,7 +2496,7 @@ namespace Game.Spells
if (aurEff.GetSpellInfo().HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
return false;
foreach (SpellEffectInfo effectInfo in GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effectInfo in _effects.Values)
{
if (effectInfo == null)
continue;
@@ -2716,13 +2631,13 @@ namespace Game.Spells
return (castTime > 0) ? castTime : 0;
}
public uint GetMaxTicks(Difficulty difficulty)
public uint GetMaxTicks()
{
int DotDuration = GetDuration();
if (DotDuration == 0)
return 1;
foreach (SpellEffectInfo effect in GetEffectsForDifficulty(difficulty))
foreach (SpellEffectInfo effect in _effects.Values)
{
if (effect != null && effect.Effect == SpellEffectName.ApplyAura)
{
@@ -2761,12 +2676,13 @@ namespace Game.Spells
{
List<SpellPowerCost> costs = new List<SpellPowerCost>();
var collector = new Action<List<SpellPowerRecord>>(powers =>
{
int healthCost = 0;
foreach (SpellPowerRecord power in powers)
foreach (SpellPowerRecord power in PowerCosts)
{
if (power == null)
continue;
if (power.RequiredAuraSpellID != 0 && !caster.HasAura(power.RequiredAuraSpellID))
continue;
@@ -2825,6 +2741,19 @@ namespace Game.Spells
if (power.PowerCostMaxPct != 0)
healthCost += (int)MathFunctions.CalculatePct(caster.GetMaxHealth(), power.PowerCostMaxPct);
int optionalCost = (int)power.OptionalCost;
optionalCost += caster.GetTotalAuraModifier(AuraType.ModAdditionalPowerCost, aurEff =>
{
return aurEff.GetMiscValue() == (int)power.PowerType
&& aurEff.IsAffectingSpell(this);
});
if (optionalCost != 0)
{
int remainingPower = caster.GetPower(power.PowerType) - powerCost;
powerCost += MathFunctions.RoundToInterval(ref remainingPower, 0, optionalCost);
}
if (power.PowerType != PowerType.Health)
{
// Flat mod from caster auras by spell school and power type
@@ -2927,12 +2856,6 @@ namespace Game.Spells
cost.Amount = healthCost;
costs.Add(cost);
}
});
if (!_hasPowerDifficultyData) // optimization - use static data for 99.5% cases (4753 of 4772 in build 6.1.0.19702)
collector(PowerCosts);
else
collector(Global.DB2Mgr.GetSpellPowers(Id, caster.GetMap().GetDifficultyID()));
return costs;
}
@@ -3110,7 +3033,7 @@ namespace Game.Spells
return this;
bool needRankSelection = false;
foreach (SpellEffectInfo effect in GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in _effects.Values)
{
if (effect != null && IsPositiveEffect(effect.EffectIndex) &&
(effect.Effect == SpellEffectName.ApplyAura ||
@@ -3165,37 +3088,13 @@ namespace Game.Spells
public uint GetSpellXSpellVisualId(Unit caster = null)
{
if (caster)
foreach (SpellXSpellVisualRecord visual in _visuals)
{
Difficulty difficulty = caster.GetMap().GetDifficultyID();
DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(difficulty);
while (difficultyEntry != null)
{
var visualList = _visuals.LookupByKey(difficulty);
if (visualList != null)
{
foreach (SpellXSpellVisualRecord visual in visualList)
{
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(visual.CasterPlayerConditionID);
if (playerCondition == null || (caster.IsTypeId(TypeId.Player) && ConditionManager.IsPlayerMeetingCondition(caster.ToPlayer(), playerCondition)))
return visual.Id;
}
}
difficultyEntry = CliDB.DifficultyStorage.LookupByKey(difficultyEntry.FallbackDifficultyID);
}
}
var defaultList = _visuals.LookupByKey(Difficulty.None);
if (defaultList != null)
{
foreach (var visual in defaultList)
{
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(visual.CasterPlayerConditionID);
if (playerCondition == null || (caster && caster.IsTypeId(TypeId.Player) && ConditionManager.IsPlayerMeetingCondition(caster.ToPlayer(), playerCondition)))
if (playerCondition == null || (caster && caster.GetTypeId() == TypeId.Player && ConditionManager.IsPlayerMeetingCondition(caster.ToPlayer(), playerCondition)))
return visual.Id;
}
}
return 0;
}
@@ -3220,9 +3119,7 @@ namespace Game.Spells
bool dstSet = false;
SpellCastTargetFlags targetMask = targets;
// prepare target mask using effect target entries
foreach (var pair in _effects)
{
foreach (SpellEffectInfo effect in pair.Value)
foreach (SpellEffectInfo effect in _effects.Values)
{
if (effect == null || !effect.IsEffect())
continue;
@@ -3240,9 +3137,9 @@ namespace Game.Spells
// don't add explicit object/dest flags when spell has no max range
if (GetMaxRange(true) == 0.0f && GetMaxRange(false) == 0.0f)
effectTargetMask &= ~(SpellCastTargetFlags.UnitMask | SpellCastTargetFlags.Gameobject | SpellCastTargetFlags.CorpseMask | SpellCastTargetFlags.DestLocation);
targetMask |= effectTargetMask;
}
}
ExplicitTargetMask = (uint)targetMask;
}
@@ -3300,22 +3197,13 @@ namespace Game.Spells
return true;
// Special case: effects which determine positivity of whole spell
foreach (var pair in _effects)
{
foreach (SpellEffectInfo effect in pair.Value)
{
if (effect != null && effect.IsAura() && effect.ApplyAuraName == AuraType.ModStealth)
foreach (SpellEffectInfo effectInfo in _effects.Values)
if (effectInfo != null && effectInfo.IsAura() && effectInfo.ApplyAuraName == AuraType.ModStealth)
return true;
}
}
foreach (var pair in _effects)
SpellEffectInfo effect = GetEffect(effIndex);
if (effect != null)
{
foreach (SpellEffectInfo effect in pair.Value)
{
if (effect == null || effect.EffectIndex != effIndex)
continue;
switch (effect.Effect)
{
case SpellEffectName.Dummy:
@@ -3368,13 +3256,11 @@ namespace Game.Spells
case AuraType.PeriodicTriggerSpell:
if (!deep)
{
var spellTriggeredProto = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell);
var spellTriggeredProto = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell, Difficulty);
if (spellTriggeredProto != null)
{
// negative targets of main spell return early
foreach (var pair2 in spellTriggeredProto._effects)
{
foreach (SpellEffectInfo eff in pair2.Value)
foreach (SpellEffectInfo eff in spellTriggeredProto._effects.Values)
{
if (eff == null || eff.Effect == 0)
continue;
@@ -3385,16 +3271,13 @@ namespace Game.Spells
}
}
}
}
break;
case AuraType.ProcTriggerSpell:
// many positive auras have negative triggered spells at damage for example and this not make it negative (it can be canceled for example)
break;
case AuraType.ModStun: //have positive and negative spells, we can't sort its correctly at this moment.
bool more = false;
foreach (var pair2 in _effects)
{
foreach (SpellEffectInfo eff in pair2.Value)
foreach (SpellEffectInfo eff in _effects.Values)
{
if (eff != null && eff.EffectIndex != 0)
{
@@ -3402,7 +3285,6 @@ namespace Game.Spells
break;
}
}
}
if (effIndex == 0 && !more)
return false; // but all single stun aura spells is negative
@@ -3483,8 +3365,6 @@ namespace Game.Spells
}
}
// non-positive targets
if (!_IsPositiveTarget(effect.TargetA.GetTarget(), effect.TargetB.GetTarget()))
return false;
@@ -3492,13 +3372,12 @@ namespace Game.Spells
// negative spell if triggered spell is negative
if (!deep && effect.ApplyAuraName == 0 && effect.TriggerSpell != 0)
{
SpellInfo spellTriggeredProto = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell);
SpellInfo spellTriggeredProto = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell, Difficulty);
if (spellTriggeredProto != null)
if (!spellTriggeredProto._IsPositiveSpell())
return false;
}
}
}
// ok, positive
return true;
}
@@ -3519,13 +3398,13 @@ namespace Game.Spells
switch (targetA)
{
case Targets.UnitNearbyEnemy:
case Targets.UnitEnemy:
case Targets.UnitTargetEnemy:
case Targets.UnitSrcAreaEnemy:
case Targets.UnitDestAreaEnemy:
case Targets.UnitConeEnemy24:
case Targets.UnitConeEnemy104:
case Targets.DestDynobjEnemy:
case Targets.DestEnemy:
case Targets.DestTargetEnemy:
return false;
default:
break;
@@ -3538,21 +3417,19 @@ namespace Game.Spells
public void _UnloadImplicitTargetConditionLists()
{
// find the same instances of ConditionList and delete them.
foreach (var pair in _effects)
var effectList = _effects.Values.ToList();
for (int i = 0; i < effectList.Count; ++i)
{
for (uint i = 0; i < pair.Value.Length; ++i)
SpellEffectInfo effect = effectList[i];
if (effect != null)
{
SpellEffectInfo effect = pair.Value[i];
if (effect == null)
continue;
var cur = effect.ImplicitTargetConditions;
if (cur == null)
continue;
for (var j = i; j < pair.Value.Length; ++j)
for (var j = i; j < effectList.Count; ++j)
{
SpellEffectInfo eff = pair.Value[j];
SpellEffectInfo eff = effectList[j];
if (eff != null && eff.ImplicitTargetConditions == cur)
eff.ImplicitTargetConditions = null;
}
@@ -3594,90 +3471,16 @@ namespace Game.Spells
return CategoryId;
}
public SpellEffectInfo[] GetEffectsForDifficulty(Difficulty difficulty)
{
SpellEffectInfo[] effList = new SpellEffectInfo[SpellConst.MaxEffects];
public ICollection<SpellEffectInfo> GetEffects() { return _effects.Values; }
// downscale difficulty if original was not found
DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(difficulty);
while (difficultyEntry != null)
{
var effectArray = _effects.LookupByKey(difficulty);
if (effectArray != null)
{
foreach (SpellEffectInfo effect in effectArray)
{
if (effect == null)
continue;
if (effList[effect.EffectIndex] == null)
effList[effect.EffectIndex] = effect;
}
}
difficultyEntry = CliDB.DifficultyStorage.LookupByKey(difficultyEntry.FallbackDifficultyID);
}
// DIFFICULTY_NONE effects are the default effects, always active if current difficulty's effects don't overwrite
var effects = _effects.LookupByKey(Difficulty.None);
if (effects != null)
{
foreach (SpellEffectInfo effect in effects)
{
if (effect == null)
continue;
if (effList[effect.EffectIndex] == null)
effList[effect.EffectIndex] = effect;
}
}
return effList;
}
public SpellEffectInfo GetEffect(uint index) { return GetEffect(Difficulty.None, index); }
public SpellEffectInfo GetEffect(Difficulty difficulty, uint index)
{
DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(difficulty);
while (difficultyEntry != null)
{
var effectArray = _effects.LookupByKey(difficulty);
if (effectArray != null)
if (effectArray.Length > index && effectArray[index] != null)
return effectArray[index];
difficultyEntry = CliDB.DifficultyStorage.LookupByKey(difficultyEntry.FallbackDifficultyID);
}
var spellEffectInfos = _effects.LookupByKey(Difficulty.None);
if (spellEffectInfos != null)
if (spellEffectInfos.Length > index)
return spellEffectInfos[index];
return null;
}
public SpellEffectInfo GetEffect(uint index) { return _effects.LookupByKey(index); }
public bool HasTargetType(Targets target)
{
foreach (var pair in _effects)
{
foreach (SpellEffectInfo effect in pair.Value)
{
foreach (SpellEffectInfo effect in _effects.Values)
if (effect != null && (effect.TargetA.GetTarget() == target || effect.TargetB.GetTarget() == target))
return true;
}
}
return false;
}
public bool HasTargetType(Difficulty difficulty, Targets target)
{
var effects = GetEffectsForDifficulty(difficulty);
foreach (SpellEffectInfo effect in effects)
{
if (effect != null && (effect.TargetA.GetTarget() == target || effect.TargetB.GetTarget() == target))
return true;
}
return false;
}
@@ -3705,8 +3508,9 @@ namespace Game.Spells
#region Fields
public uint Id;
uint CategoryId;
public uint Id { get; set; }
public Difficulty Difficulty { get; set; }
public uint CategoryId { get; set; }
public DispelType Dispel { get; set; }
public Mechanics Mechanic { get; set; }
public SpellAttr0 Attributes { get; set; }
@@ -3756,7 +3560,7 @@ namespace Game.Spells
public uint BaseLevel { get; set; }
public uint SpellLevel { get; set; }
public SpellDurationRecord DurationEntry { get; set; }
public List<SpellPowerRecord> PowerCosts = new List<SpellPowerRecord>();
public SpellPowerRecord[] PowerCosts = new SpellPowerRecord[SpellConst.MaxPowersPerSpell];
public uint RangeIndex { get; set; }
public SpellRangeRecord RangeEntry { get; set; }
public float Speed { get; set; }
@@ -3789,8 +3593,8 @@ namespace Game.Spells
public uint ExplicitTargetMask { get; set; }
public SpellChainNode ChainEntry { get; set; }
internal Dictionary<uint, SpellEffectInfo[]> _effects;
MultiMap<uint, SpellXSpellVisualRecord> _visuals = new MultiMap<uint, SpellXSpellVisualRecord>();
Dictionary<uint, SpellEffectInfo> _effects = new Dictionary<uint, SpellEffectInfo>();
List<SpellXSpellVisualRecord> _visuals = new List<SpellXSpellVisualRecord>();
bool _hasPowerDifficultyData;
SpellSpecificType _spellSpecific;
AuraStateType _auraState;
@@ -3810,44 +3614,35 @@ namespace Game.Spells
public class SpellEffectInfo
{
public SpellEffectInfo(SpellInfo spellInfo, uint effIndex, SpellEffectRecord _effect)
public SpellEffectInfo(SpellInfo spellInfo, SpellEffectRecord effect)
{
_spellInfo = spellInfo;
EffectIndex = effIndex;
TargetA = new SpellImplicitTargetInfo();
TargetB = new SpellImplicitTargetInfo();
SpellClassMask = new FlagArray128();
if (_effect != null)
{
EffectIndex = _effect.EffectIndex;
Effect = (SpellEffectName)_effect.Effect;
ApplyAuraName = (AuraType)_effect.EffectAura;
ApplyAuraPeriod = _effect.EffectAuraPeriod;
RealPointsPerLevel = _effect.EffectRealPointsPerLevel;
BasePoints = (int)_effect.EffectBasePoints;
PointsPerResource = _effect.EffectPointsPerResource;
Amplitude = _effect.EffectAmplitude;
ChainAmplitude = _effect.EffectChainAmplitude;
BonusCoefficient = _effect.EffectBonusCoefficient;
MiscValue = _effect.EffectMiscValue[0];
MiscValueB = _effect.EffectMiscValue[1];
Mechanic = (Mechanics)_effect.EffectMechanic;
PositionFacing = _effect.EffectPosFacing;
TargetA = new SpellImplicitTargetInfo((Targets)_effect.ImplicitTarget[0]);
TargetB = new SpellImplicitTargetInfo((Targets)_effect.ImplicitTarget[1]);
RadiusEntry = CliDB.SpellRadiusStorage.LookupByKey(_effect.EffectRadiusIndex[0]);
MaxRadiusEntry = CliDB.SpellRadiusStorage.LookupByKey(_effect.EffectRadiusIndex[1]);
ChainTargets = _effect.EffectChainTargets;
ItemType = _effect.EffectItemType;
TriggerSpell = _effect.EffectTriggerSpell;
SpellClassMask = _effect.EffectSpellClassMask;
BonusCoefficientFromAP = _effect.BonusCoefficientFromAP;
Scaling.Coefficient = _effect.Coefficient;
Scaling.Variance = _effect.Variance;
Scaling.ResourceCoefficient = _effect.ResourceCoefficient;
}
EffectIndex = effect.EffectIndex;
Effect = (SpellEffectName)effect.Effect;
ApplyAuraName = (AuraType)effect.EffectAura;
ApplyAuraPeriod = effect.EffectAuraPeriod;
RealPointsPerLevel = effect.EffectRealPointsPerLevel;
BasePoints = (int)effect.EffectBasePoints;
PointsPerResource = effect.EffectPointsPerResource;
Amplitude = effect.EffectAmplitude;
ChainAmplitude = effect.EffectChainAmplitude;
BonusCoefficient = effect.EffectBonusCoefficient;
MiscValue = effect.EffectMiscValue[0];
MiscValueB = effect.EffectMiscValue[1];
Mechanic = (Mechanics)effect.EffectMechanic;
PositionFacing = effect.EffectPosFacing;
TargetA = new SpellImplicitTargetInfo((Targets)effect.ImplicitTarget[0]);
TargetB = new SpellImplicitTargetInfo((Targets)effect.ImplicitTarget[1]);
RadiusEntry = CliDB.SpellRadiusStorage.LookupByKey(effect.EffectRadiusIndex[0]);
MaxRadiusEntry = CliDB.SpellRadiusStorage.LookupByKey(effect.EffectRadiusIndex[1]);
ChainTargets = effect.EffectChainTargets;
ItemType = effect.EffectItemType;
TriggerSpell = effect.EffectTriggerSpell;
SpellClassMask = effect.EffectSpellClassMask;
BonusCoefficientFromAP = effect.BonusCoefficientFromAP;
Scaling.Coefficient = effect.Coefficient;
Scaling.Variance = effect.Variance;
Scaling.ResourceCoefficient = effect.ResourceCoefficient;
ImplicitTargetConditions = null;
@@ -4612,7 +4407,7 @@ namespace Game.Spells
case Targets.UnitCasterAreaParty:
case Targets.UnitSrcAreaAlly:
case Targets.UnitSrcAreaParty:
case Targets.UnitLastAreaParty:
case Targets.UnitLastTargetAreaParty:
case Targets.GameobjectSrcArea:
case Targets.UnitCasterAreaRaid:
case Targets.CorpseSrcAreaEnemy:
+286 -149
View File
@@ -104,10 +104,10 @@ namespace Game.Entities
if (spellInfo == null)
return false;
bool need_check_reagents = false;
bool needCheckReagents = false;
// check effects
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect == null)
continue;
@@ -150,12 +150,12 @@ namespace Game.Entities
return false;
}
need_check_reagents = true;
needCheckReagents = true;
break;
}
case SpellEffectName.LearnSpell:
{
SpellInfo spellInfo2 = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell);
SpellInfo spellInfo2 = GetSpellInfo(effect.TriggerSpell, Difficulty.None);
if (!IsSpellValid(spellInfo2, player, msg))
{
if (msg)
@@ -172,7 +172,7 @@ namespace Game.Entities
}
}
if (need_check_reagents)
if (needCheckReagents)
{
for (int j = 0; j < SpellConst.MaxReagents; ++j)
{
@@ -444,9 +444,26 @@ namespace Game.Entities
return SpellGroupStackRule.Default;
}
public SpellProcEntry GetSpellProcEntry(uint spellId)
public SpellProcEntry GetSpellProcEntry(SpellInfo spellInfo)
{
return mSpellProcMap.LookupByKey(spellId);
SpellProcEntry procEntry = mSpellProcMap.LookupByKey((spellInfo.Id, spellInfo.Difficulty));
if (procEntry != null)
return procEntry;
DifficultyRecord difficulty = CliDB.DifficultyStorage.LookupByKey(spellInfo.Difficulty);
if (difficulty != null)
{
do
{
procEntry = mSpellProcMap.LookupByKey((spellInfo.Id, difficulty.FallbackDifficultyID));
if (procEntry != null)
return procEntry;
difficulty = CliDB.DifficultyStorage.LookupByKey(difficulty.FallbackDifficultyID);
} while (difficulty != null);
}
return null;
}
public static bool CanSpellTriggerProcOnEvent(SpellProcEntry procEntry, ProcEventInfo eventInfo)
@@ -622,10 +639,52 @@ namespace Game.Entities
return mSpellAreaForQuestAreaMap.LookupByKey(Tuple.Create(area_id, quest_id));
}
public SpellInfo GetSpellInfo(uint spellId, Difficulty difficulty)
{
var list = mSpellInfoMap.LookupByKey(spellId);
var index = list.FindIndex(spellInfo => spellInfo.Difficulty == difficulty);
if (index != -1)
return list[index];
DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(difficulty);
if (difficultyEntry != null)
{
do
{
index = list.FindIndex(spellInfo => spellInfo.Difficulty == (Difficulty)difficultyEntry.FallbackDifficultyID);
if (index != -1)
return list[index];
difficultyEntry = CliDB.DifficultyStorage.LookupByKey(difficultyEntry.FallbackDifficultyID);
} while (difficultyEntry != null);
}
return null;
}
List<SpellInfo> _GetSpellInfo(uint spellId)
{
return mSpellInfoMap.LookupByKey(spellId);
}
public void ForEachSpellInfo(Action<SpellInfo> callback)
{
foreach (SpellInfo spellInfo in mSpellInfoMap.Values)
callback(spellInfo);
}
public void ForEachSpellInfoDifficulty(uint spellId, Action<SpellInfo> callback)
{
foreach (SpellInfo spellInfo in _GetSpellInfo(spellId))
callback(spellInfo);
}
void UnloadSpellInfoChains()
{
foreach (var chain in mSpellChains)
mSpellInfoMap[chain.Key].ChainEntry = null;
foreach (var pair in mSpellChains)
foreach (SpellInfo spellInfo in _GetSpellInfo(pair.Key))
spellInfo.ChainEntry = null;
mSpellChains.Clear();
}
@@ -642,7 +701,7 @@ namespace Game.Entities
if (skillAbility.SupercedesSpell == 0)
continue;
if (!HasSpellInfo(skillAbility.SupercedesSpell) || !HasSpellInfo(skillAbility.Spell))
if (!HasSpellInfo(skillAbility.SupercedesSpell, Difficulty.None) || !HasSpellInfo(skillAbility.Spell, Difficulty.None))
continue;
chains[skillAbility.SupercedesSpell] = skillAbility.Spell;
@@ -655,8 +714,8 @@ namespace Game.Entities
if (hasPrev.Contains(pair.Key))
continue;
SpellInfo first = GetSpellInfo(pair.Key);
SpellInfo next = GetSpellInfo(pair.Value);
SpellInfo first = GetSpellInfo(pair.Key, Difficulty.None);
SpellInfo next = GetSpellInfo(pair.Value, Difficulty.None);
if (!mSpellChains.ContainsKey(pair.Key))
mSpellChains[pair.Key] = new SpellChainNode();
@@ -666,7 +725,8 @@ namespace Game.Entities
mSpellChains[pair.Key].next = next;
mSpellChains[pair.Key].last = next;
mSpellChains[pair.Key].rank = 1;
mSpellInfoMap[pair.Key].ChainEntry = mSpellChains[pair.Key];
foreach (SpellInfo difficultyInfo in _GetSpellInfo(pair.Key))
difficultyInfo.ChainEntry = mSpellChains[pair.Key];
if (!mSpellChains.ContainsKey(pair.Value))
mSpellChains[pair.Value] = new SpellChainNode();
@@ -676,14 +736,15 @@ namespace Game.Entities
mSpellChains[pair.Value].next = null;
mSpellChains[pair.Value].last = next;
mSpellChains[pair.Value].rank = 2;
mSpellInfoMap[pair.Value].ChainEntry = mSpellChains[pair.Value];
foreach (SpellInfo difficultyInfo in _GetSpellInfo(pair.Value))
difficultyInfo.ChainEntry = mSpellChains[pair.Value];
byte rank = 3;
var nextPair = chains.Find(pair.Value);
while (nextPair.Key != 0)
{
SpellInfo prev = GetSpellInfo(nextPair.Key); // already checked in previous iteration (or above, in case this is the first one)
SpellInfo last = GetSpellInfo(nextPair.Value);
SpellInfo prev = GetSpellInfo(nextPair.Key, Difficulty.None); // already checked in previous iteration (or above, in case this is the first one)
SpellInfo last = GetSpellInfo(nextPair.Value, Difficulty.None);
if (last == null)
break;
@@ -700,7 +761,8 @@ namespace Game.Entities
mSpellChains[nextPair.Value].next = null;
mSpellChains[nextPair.Value].last = last;
mSpellChains[nextPair.Value].rank = rank++;
mSpellInfoMap[nextPair.Value].ChainEntry = mSpellChains[nextPair.Value];
foreach (SpellInfo difficultyInfo in _GetSpellInfo(nextPair.Value))
difficultyInfo.ChainEntry = mSpellChains[nextPair.Value];
// fill 'last'
do
@@ -725,7 +787,6 @@ namespace Game.Entities
// 0 1
SQLResult result = DB.World.Query("SELECT spell_id, req_spell from spell_required");
if (result.IsEmpty())
{
Log.outInfo(LogFilter.ServerLoading, "Loaded 0 spell required records. DB table `spell_required` is empty.");
@@ -740,14 +801,14 @@ namespace Game.Entities
uint spell_req = result.Read<uint>(1);
// check if chain is made with valid first spell
SpellInfo spell = GetSpellInfo(spell_id);
SpellInfo spell = GetSpellInfo(spell_id, Difficulty.None);
if (spell == null)
{
Log.outError(LogFilter.Sql, "spell_id {0} in `spell_required` table is not found in dbcs, skipped", spell_id);
continue;
}
SpellInfo req_spell = GetSpellInfo(spell_req);
SpellInfo req_spell = GetSpellInfo(spell_req, Difficulty.None);
if (req_spell == null)
{
Log.outError(LogFilter.Sql, "req_spell {0} in `spell_required` table is not found in dbcs, skipped", spell_req);
@@ -781,11 +842,14 @@ namespace Game.Entities
// search auto-learned skills and add its to map also for use in unlearn spells/talents
uint dbc_count = 0;
foreach (var spell in mSpellInfoMap.Values)
foreach (var entry in mSpellInfoMap.Values)
{
foreach (SpellEffectInfo effect in spell.GetEffectsForDifficulty(Difficulty.None))
if (entry.Difficulty != Difficulty.None)
continue;
foreach (SpellEffectInfo effect in entry.GetEffects())
{
if (effect == null)
if (effect != null)
continue;
SpellLearnSkillNode dbc_node = new SpellLearnSkillNode();
@@ -810,7 +874,7 @@ namespace Game.Entities
continue;
}
mSpellLearnSkills.Add(spell.Id, dbc_node);
mSpellLearnSkills.Add(entry.Id, dbc_node);
++dbc_count;
break;
}
@@ -842,14 +906,14 @@ namespace Game.Entities
node.Active = result.Read<bool>(2);
node.AutoLearned = false;
SpellInfo spellInfo = GetSpellInfo(spell_id);
SpellInfo spellInfo = GetSpellInfo(spell_id, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Sql, "Spell {0} listed in `spell_learn_spell` does not exist", spell_id);
continue;
}
if (GetSpellInfo(node.Spell) == null)
if (!HasSpellInfo(node.Spell, Difficulty.None))
{
Log.outError(LogFilter.Sql, "Spell {0} listed in `spell_learn_spell` learning not existed spell {1}", spell_id, node.Spell);
continue;
@@ -869,7 +933,10 @@ namespace Game.Entities
uint dbc_count = 0;
foreach (var entry in mSpellInfoMap.Values)
{
foreach (SpellEffectInfo effect in entry.GetEffectsForDifficulty(Difficulty.None))
if (entry.Difficulty != Difficulty.None)
continue;
foreach (SpellEffectInfo effect in entry.GetEffects())
{
if (effect != null && effect.Effect == SpellEffectName.LearnSpell)
{
@@ -879,7 +946,7 @@ namespace Game.Entities
dbc_node.OverridesSpell = 0;
// ignore learning not existed spells (broken/outdated/or generic learnig spell 483
if (GetSpellInfo(dbc_node.Spell) == null)
if (GetSpellInfo(dbc_node.Spell, Difficulty.None) == null)
continue;
// talent or passive spells or skill-step spells auto-cast and not need dependent learning,
@@ -912,7 +979,7 @@ namespace Game.Entities
foreach (var spellLearnSpell in CliDB.SpellLearnSpellStorage.Values)
{
if (GetSpellInfo(spellLearnSpell.SpellID) == null)
if (!HasSpellInfo(spellLearnSpell.SpellID, Difficulty.None))
continue;
var db_node_bounds = mSpellLearnSpells.LookupByKey(spellLearnSpell.LearnSpellID);
@@ -997,7 +1064,7 @@ namespace Game.Entities
continue;
}
SpellInfo spellInfo = GetSpellInfo(spellId);
SpellInfo spellInfo = GetSpellInfo(spellId, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Sql, "Spell (ID: {0}) listed in `spell_target_position` does not exist.", spellId);
@@ -1079,8 +1146,7 @@ namespace Game.Entities
}
else
{
SpellInfo spellInfo = GetSpellInfo((uint)group.Value);
SpellInfo spellInfo = GetSpellInfo((uint)group.Value, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Sql, "Spell {0} listed in `spell_group` does not exist", group.Value);
@@ -1179,8 +1245,8 @@ namespace Game.Entities
foreach (uint spellId in spellIds)
{
SpellInfo spellInfo = GetSpellInfo(spellId);
foreach (SpellEffectInfo effectInfo in spellInfo.GetEffectsForDifficulty(Difficulty.None))
SpellInfo spellInfo = GetSpellInfo(spellId, Difficulty.None);
foreach (SpellEffectInfo effectInfo in spellInfo.GetEffects())
{
if (!effectInfo.IsAura())
continue;
@@ -1221,14 +1287,14 @@ namespace Game.Entities
// re-check spells against guessed group
foreach (uint spellId in spellIds)
{
SpellInfo spellInfo = GetSpellInfo(spellId);
SpellInfo spellInfo = GetSpellInfo(spellId, Difficulty.None);
bool found = false;
while (spellInfo != null)
{
foreach (AuraType auraType in auraTypes)
{
if (spellInfo.HasAura(Difficulty.None, auraType))
if (spellInfo.HasAura(auraType))
{
found = true;
break;
@@ -1278,7 +1344,7 @@ namespace Game.Entities
spellId = -spellId;
}
SpellInfo spellInfo = GetSpellInfo((uint)spellId);
SpellInfo spellInfo = GetSpellInfo((uint)spellId, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Sql, "Spell {0} listed in `spell_proc` does not exist", spellId);
@@ -1312,7 +1378,7 @@ namespace Game.Entities
while (spellInfo != null)
{
if (mSpellProcMap.ContainsKey(spellInfo.Id))
if (mSpellProcMap.ContainsKey((spellInfo.Id, spellInfo.Difficulty)))
{
Log.outError(LogFilter.Sql, "Spell {0} listed in `spell_proc` has duplicate entry in the table", spellInfo.Id);
break;
@@ -1363,7 +1429,7 @@ namespace Game.Entities
if (procEntry.HitMask != 0 && !(Convert.ToBoolean(procEntry.ProcFlags & ProcFlags.TakenHitMask) || (Convert.ToBoolean(procEntry.ProcFlags & ProcFlags.DoneHitMask) && (procEntry.SpellPhaseMask == 0 || Convert.ToBoolean(procEntry.SpellPhaseMask & (ProcFlagsSpellPhase.Hit | ProcFlagsSpellPhase.Finish))))))
Log.outError(LogFilter.Sql, "`spell_proc` table entry for spellId {0} has `HitMask` value defined, but it won't be used for defined `ProcFlags` and `SpellPhaseMask` values", spellInfo.Id);
mSpellProcMap.Add(spellInfo.Id, procEntry);
mSpellProcMap.Add((spellInfo.Id, spellInfo.Difficulty), procEntry);
++count;
if (allRanks)
@@ -1385,11 +1451,8 @@ namespace Game.Entities
foreach (SpellInfo spellInfo in mSpellInfoMap.Values)
{
if (spellInfo == null)
continue;
// Data already present in DB, overwrites default proc
if (mSpellProcMap.ContainsKey(spellInfo.Id))
if (mSpellProcMap.ContainsKey((spellInfo.Id, spellInfo.Difficulty)))
continue;
// Nothing to do if no flags set
@@ -1398,7 +1461,7 @@ namespace Game.Entities
bool addTriggerFlag = false;
ProcFlagsSpellType procSpellTypeMask = ProcFlagsSpellType.None;
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect == null || !effect.IsEffect())
continue;
@@ -1433,7 +1496,7 @@ namespace Game.Entities
if (procSpellTypeMask == 0)
{
foreach (SpellEffectInfo effectInfo in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effectInfo in spellInfo.GetEffects())
{
if (effectInfo != null && effectInfo.IsAura())
{
@@ -1449,7 +1512,7 @@ namespace Game.Entities
procEntry.SchoolMask = 0;
procEntry.ProcFlags = spellInfo.ProcFlags;
procEntry.SpellFamilyName = 0;
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
if (effect != null && effect.IsEffect() && IsTriggerAura(effect.ApplyAuraName))
procEntry.SpellFamilyMask |= effect.SpellClassMask;
@@ -1460,7 +1523,7 @@ namespace Game.Entities
procEntry.SpellPhaseMask = ProcFlagsSpellPhase.Hit;
procEntry.HitMask = ProcFlagsHit.None; // uses default proc @see SpellMgr::CanSpellTriggerProcOnEvent
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect == null || !effect.IsAura())
continue;
@@ -1498,7 +1561,7 @@ namespace Game.Entities
procEntry.Cooldown = spellInfo.ProcCooldown;
procEntry.Charges = spellInfo.ProcCharges;
mSpellProcMap[spellInfo.Id] = procEntry;
mSpellProcMap[(spellInfo.Id, spellInfo.Difficulty)] = procEntry;
++count;
}
@@ -1523,7 +1586,7 @@ namespace Game.Entities
{
uint entry = result.Read<uint>(0);
if (GetSpellInfo(entry) == null)
if (!HasSpellInfo(entry, Difficulty.None))
{
Log.outError(LogFilter.Sql, "Spell {0} listed in `spell_threat` does not exist", entry);
continue;
@@ -1580,7 +1643,7 @@ namespace Game.Entities
petAura.AddAura(pet, aura);
else
{
SpellInfo spellInfo = GetSpellInfo(spell);
SpellInfo spellInfo = GetSpellInfo(spell, Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Sql, "Spell {0} listed in `spell_pet_auras` does not exist", spell);
@@ -1599,7 +1662,7 @@ namespace Game.Entities
continue;
}
SpellInfo spellInfo2 = GetSpellInfo(aura);
SpellInfo spellInfo2 = GetSpellInfo(aura, Difficulty.None);
if (spellInfo2 == null)
{
Log.outError(LogFilter.Sql, "Aura {0} listed in `spell_pet_auras` does not exist", aura);
@@ -1627,7 +1690,7 @@ namespace Game.Entities
if (!spellInfo.HasAttribute(SpellAttr2.PreserveEnchantInArena) || !spellInfo.HasAttribute(SpellAttr0.NotShapeshift))
continue;
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect != null && effect.Effect == SpellEffectName.EnchantItemTemporary)
{
@@ -1706,14 +1769,23 @@ namespace Game.Entities
int effect = result.Read<int>(1);
int type = result.Read<int>(2);
SpellInfo spellInfo = GetSpellInfo((uint)Math.Abs(trigger));
SpellInfo spellInfo = GetSpellInfo((uint)Math.Abs(trigger), Difficulty.None);
if (spellInfo == null)
{
Log.outError(LogFilter.Sql, "Spell {0} listed in `spell_linked_spell` does not exist", Math.Abs(trigger));
continue;
}
spellInfo = GetSpellInfo((uint)Math.Abs(effect));
if (spellInfo == null)
if (effect >= 0)
{
foreach (SpellEffectInfo eff in spellInfo.GetEffects())
{
if (eff != null && eff.CalcValue() == Math.Abs(effect))
Log.outError(LogFilter.Sql, $"The spell {Math.Abs(trigger)} Effect: {Math.Abs(effect)} listed in `spell_linked_spell` has same bp{eff.EffectIndex} like effect (possible hack)");
}
}
if (!HasSpellInfo((uint)Math.Abs(effect), Difficulty.None))
{
Log.outError(LogFilter.Sql, "Spell {0} listed in `spell_linked_spell` does not exist", Math.Abs(effect));
continue;
@@ -1758,7 +1830,7 @@ namespace Game.Entities
if (skillLine.AcquireMethod != AbilityLearnType.OnSkillLearn)
continue;
SpellInfo spell = GetSpellInfo(skillLine.Spell);
SpellInfo spell = GetSpellInfo(skillLine.Spell, Difficulty.None);
if (spell == null) // not exist or triggered or talent
continue;
@@ -1795,7 +1867,9 @@ namespace Game.Entities
// different summon spells
foreach (var spellEntry in mSpellInfoMap.Values)
{
foreach (SpellEffectInfo effect in spellEntry.GetEffectsForDifficulty(Difficulty.None))
if (spellEntry.Difficulty != Difficulty.None)
{
foreach (SpellEffectInfo effect in spellEntry.GetEffects())
{
if (effect != null && (effect.Effect == SpellEffectName.Summon || effect.Effect == SpellEffectName.SummonPet))
{
@@ -1821,6 +1895,7 @@ namespace Game.Entities
}
}
}
}
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} summonable creature templates in {1} ms", countCreature, Time.GetMSTimeDiffToNow(oldMSTime));
}
@@ -1909,7 +1984,7 @@ namespace Game.Entities
spellArea.gender = (Gender)result.Read<uint>(8);
spellArea.flags = (SpellAreaFlag)result.Read<byte>(9);
SpellInfo spellInfo = GetSpellInfo(spell);
SpellInfo spellInfo = GetSpellInfo(spell, Difficulty.None);
if (spellInfo != null)
{
if (spellArea.flags.HasAnyFlag(SpellAreaFlag.AutoCast))
@@ -1974,7 +2049,7 @@ namespace Game.Entities
if (spellArea.auraSpell != 0)
{
SpellInfo info = GetSpellInfo((uint)Math.Abs(spellArea.auraSpell));
SpellInfo info = GetSpellInfo((uint)Math.Abs(spellArea.auraSpell), Difficulty.None);
if (info == null)
{
Log.outError(LogFilter.Sql, "Spell {0} listed in `spell_area` have wrong aura spell ({1}) requirement", spell, Math.Abs(spellArea.auraSpell));
@@ -2072,15 +2147,22 @@ namespace Game.Entities
uint oldMSTime = Time.GetMSTime();
mSpellInfoMap.Clear();
Dictionary<uint, SpellInfoLoadHelper> loadData = new Dictionary<uint, SpellInfoLoadHelper>();
var loadData = new Dictionary<(uint Id, Difficulty difficulty), SpellInfoLoadHelper>();
Dictionary<uint, BattlePetSpeciesRecord> battlePetSpeciesByCreature = new Dictionary<uint, BattlePetSpeciesRecord>();
foreach (var battlePetSpecies in CliDB.BattlePetSpeciesStorage.Values)
if (battlePetSpecies.CreatureID != 0)
battlePetSpeciesByCreature[battlePetSpecies.CreatureID] = battlePetSpecies;
Dictionary<uint, Dictionary<uint, SpellEffectRecord[]>> effectsBySpell = new Dictionary<uint, Dictionary<uint, SpellEffectRecord[]>>();
Dictionary<uint, MultiMap<uint, SpellXSpellVisualRecord>> visualsBySpell = new Dictionary<uint, MultiMap<uint, SpellXSpellVisualRecord>>();
SpellInfoLoadHelper GetLoadHelper(uint spellId, uint difficulty)
{
var key = (spellId, (Difficulty)difficulty);
if (!loadData.ContainsKey(key))
loadData[key] = new SpellInfoLoadHelper();
return loadData[key];
}
foreach (var effect in CliDB.SpellEffectStorage.Values)
{
Cypher.Assert(effect.EffectIndex < SpellConst.MaxEffects, $"MAX_SPELL_EFFECTS must be at least {effect.EffectIndex}");
@@ -2089,13 +2171,7 @@ namespace Game.Entities
Cypher.Assert(effect.ImplicitTarget[0] < (int)Targets.TotalSpellTargets, $"TOTAL_SPELL_TARGETS must be at least {effect.ImplicitTarget[0]}");
Cypher.Assert(effect.ImplicitTarget[1] < (int)Targets.TotalSpellTargets, $"TOTAL_SPELL_TARGETS must be at least {effect.ImplicitTarget[1]}");
if (!effectsBySpell.ContainsKey(effect.SpellID))
effectsBySpell[effect.SpellID] = new Dictionary<uint, SpellEffectRecord[]>();
if (!effectsBySpell[effect.SpellID].ContainsKey(effect.DifficultyID))
effectsBySpell[effect.SpellID][effect.DifficultyID] = new SpellEffectRecord[SpellConst.MaxEffects];
effectsBySpell[effect.SpellID][effect.DifficultyID][effect.EffectIndex] = effect;
GetLoadHelper(effect.SpellID, effect.DifficultyID).Effects[effect.EffectIndex] = effect;
if (effect.Effect == (int)SpellEffectName.Summon)
{
@@ -2112,112 +2188,164 @@ namespace Game.Entities
}
}
SpellInfoLoadHelper GetSpellInfoLoadHelper(uint spellId)
{
if (!loadData.ContainsKey(spellId))
loadData[spellId] = new SpellInfoLoadHelper();
return loadData[spellId];
}
foreach (SpellAuraOptionsRecord auraOptions in CliDB.SpellAuraOptionsStorage.Values)
if (auraOptions.DifficultyID == 0) // TODO: implement
GetSpellInfoLoadHelper(auraOptions.SpellID).AuraOptions = auraOptions;
GetLoadHelper(auraOptions.SpellID, auraOptions.DifficultyID).AuraOptions = auraOptions;
CliDB.SpellAuraOptionsStorage.Clear();
foreach (SpellAuraRestrictionsRecord auraRestrictions in CliDB.SpellAuraRestrictionsStorage.Values)
{
if (auraRestrictions.DifficultyID == 0) // TODO: implement
GetSpellInfoLoadHelper(auraRestrictions.SpellID).AuraRestrictions = auraRestrictions;
}
GetLoadHelper(auraRestrictions.SpellID, auraRestrictions.DifficultyID).AuraRestrictions = auraRestrictions;
CliDB.SpellAuraRestrictionsStorage.Clear();
foreach (SpellCastingRequirementsRecord castingRequirements in CliDB.SpellCastingRequirementsStorage.Values)
GetSpellInfoLoadHelper(castingRequirements.SpellID).CastingRequirements = castingRequirements;
GetLoadHelper(castingRequirements.SpellID, 0).CastingRequirements = castingRequirements;
CliDB.SpellCastingRequirementsStorage.Clear();
foreach (SpellCategoriesRecord categories in CliDB.SpellCategoriesStorage.Values)
{
if (categories.DifficultyID == 0) // TODO: implement
GetSpellInfoLoadHelper(categories.SpellID).Categories = categories;
}
GetLoadHelper(categories.SpellID, categories.DifficultyID).Categories = categories;
CliDB.SpellCategoriesStorage.Clear();
foreach (SpellClassOptionsRecord classOptions in CliDB.SpellClassOptionsStorage.Values)
GetSpellInfoLoadHelper(classOptions.SpellID).ClassOptions = classOptions;
GetLoadHelper(classOptions.SpellID, 0).ClassOptions = classOptions;
CliDB.SpellClassOptionsStorage.Clear();
foreach (SpellCooldownsRecord cooldowns in CliDB.SpellCooldownsStorage.Values)
{
if (cooldowns.DifficultyID == 0) // TODO: implement
GetSpellInfoLoadHelper(cooldowns.SpellID).Cooldowns = cooldowns;
}
GetLoadHelper(cooldowns.SpellID, cooldowns.DifficultyID).Cooldowns = cooldowns;
CliDB.SpellCooldownsStorage.Clear();
foreach (SpellEquippedItemsRecord equippedItems in CliDB.SpellEquippedItemsStorage.Values)
GetSpellInfoLoadHelper(equippedItems.SpellID).EquippedItems = equippedItems;
GetLoadHelper(equippedItems.SpellID, 0).EquippedItems = equippedItems;
CliDB.SpellEquippedItemsStorage.Clear();
foreach (SpellInterruptsRecord interrupts in CliDB.SpellInterruptsStorage.Values)
{
if (interrupts.DifficultyID == 0) // TODO: implement
GetSpellInfoLoadHelper(interrupts.SpellID).Interrupts = interrupts;
}
GetLoadHelper(interrupts.SpellID, interrupts.DifficultyID).Interrupts = interrupts;
CliDB.SpellInterruptsStorage.Clear();
foreach (SpellLevelsRecord levels in CliDB.SpellLevelsStorage.Values)
{
if (levels.DifficultyID == 0) // TODO: implement
GetSpellInfoLoadHelper(levels.SpellID).Levels = levels;
}
GetLoadHelper(levels.SpellID, levels.DifficultyID).Levels = levels;
foreach (SpellMiscRecord misc in CliDB.SpellMiscStorage.Values)
if (misc.DifficultyID == 0)
GetSpellInfoLoadHelper(misc.SpellID).Misc = misc;
GetLoadHelper(misc.SpellID, misc.DifficultyID).Misc = misc;
foreach (SpellPowerRecord power in CliDB.SpellPowerStorage.Values)
{
uint difficulty = 0;
byte index = power.OrderIndex;
SpellPowerDifficultyRecord powerDifficulty = CliDB.SpellPowerDifficultyStorage.LookupByKey(power.Id);
if (powerDifficulty != null)
{
difficulty = powerDifficulty.DifficultyID;
index = powerDifficulty.OrderIndex;
}
GetLoadHelper(power.SpellID, difficulty).Powers[index] = power;
}
foreach (SpellReagentsRecord reagents in CliDB.SpellReagentsStorage.Values)
GetSpellInfoLoadHelper(reagents.SpellID).Reagents = reagents;
GetLoadHelper(reagents.SpellID, 0).Reagents = reagents;
CliDB.SpellReagentsStorage.Clear();
foreach (SpellScalingRecord scaling in CliDB.SpellScalingStorage.Values)
GetSpellInfoLoadHelper(scaling.SpellID).Scaling = scaling;
GetLoadHelper(scaling.SpellID, 0).Scaling = scaling;
CliDB.SpellScalingStorage.Clear();
foreach (SpellShapeshiftRecord shapeshift in CliDB.SpellShapeshiftStorage.Values)
GetSpellInfoLoadHelper(shapeshift.SpellID).Shapeshift = shapeshift;
GetLoadHelper(shapeshift.SpellID, 0).Shapeshift = shapeshift;
CliDB.SpellShapeshiftStorage.Clear();
foreach (SpellTargetRestrictionsRecord targetRestrictions in CliDB.SpellTargetRestrictionsStorage.Values)
{
if (targetRestrictions.DifficultyID == 0) // TODO: implement
GetSpellInfoLoadHelper(targetRestrictions.SpellID).TargetRestrictions = targetRestrictions;
}
GetLoadHelper(targetRestrictions.SpellID, targetRestrictions.DifficultyID).TargetRestrictions = targetRestrictions;
CliDB.SpellTargetRestrictionsStorage.Clear();
foreach (SpellTotemsRecord totems in CliDB.SpellTotemsStorage.Values)
GetSpellInfoLoadHelper(totems.SpellID).Totems = totems;
GetLoadHelper(totems.SpellID, 0).Totems = totems;
CliDB.SpellTotemsStorage.Clear();
foreach (var visual in CliDB.SpellXSpellVisualStorage.Values)
{
if (!visualsBySpell.ContainsKey(visual.SpellID))
visualsBySpell[visual.SpellID] = new MultiMap<uint, SpellXSpellVisualRecord>();
visualsBySpell[visual.SpellID].Add(visual.DifficultyID, visual);
var visuals = GetLoadHelper(visual.SpellID, visual.DifficultyID).Visuals;
visuals.Add(visual);
}
foreach (var spellEntry in CliDB.SpellNameStorage.Values)
// sorted with unconditional visuals being last
foreach (var data in loadData)
data.Value.Visuals.Sort((left, right) => { return right.CasterPlayerConditionID.CompareTo(left.CasterPlayerConditionID); });
foreach (var data in loadData)
{
GetSpellInfoLoadHelper(spellEntry.Id).Entry = spellEntry;
mSpellInfoMap[spellEntry.Id] = new SpellInfo(loadData[spellEntry.Id], effectsBySpell.LookupByKey(spellEntry.Id), visualsBySpell.LookupByKey(spellEntry.Id));
SpellNameRecord spellNameEntry = CliDB.SpellNameStorage.LookupByKey(data.Key.Id);
if (spellNameEntry == null)
continue;
var visuals = data.Value.Visuals; // copy, need to ensure source remains unmodified
// fill blanks
DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(data.Key.difficulty);
if (difficultyEntry != null)
{
do
{
SpellInfoLoadHelper fallbackData = loadData.LookupByKey((data.Key.Id, (Difficulty)difficultyEntry.FallbackDifficultyID));
if (fallbackData != null)
{
if (data.Value.AuraOptions == null)
data.Value.AuraOptions = fallbackData.AuraOptions;
if (data.Value.AuraRestrictions == null)
data.Value.AuraRestrictions = fallbackData.AuraRestrictions;
if (data.Value.Categories == null)
data.Value.Categories = fallbackData.Categories;
if (data.Value.Cooldowns == null)
data.Value.Cooldowns = fallbackData.Cooldowns;
for (var i = 0; i < data.Value.Effects.Length; ++i)
if (data.Value.Effects[i] == null)
data.Value.Effects[i] = fallbackData.Effects[i];
if (data.Value.Interrupts == null)
data.Value.Interrupts = fallbackData.Interrupts;
if (data.Value.Levels == null)
data.Value.Levels = fallbackData.Levels;
if (data.Value.Misc == null)
data.Value.Misc = fallbackData.Misc;
for (var i = 0; i < fallbackData.Powers.Length; ++i)
if (data.Value.Powers[i] == null)
data.Value.Powers[i] = fallbackData.Powers[i];
if (data.Value.TargetRestrictions == null)
data.Value.TargetRestrictions = fallbackData.TargetRestrictions;
visuals.AddRange(fallbackData.Visuals);
}
difficultyEntry = CliDB.DifficultyStorage.LookupByKey(difficultyEntry.FallbackDifficultyID);
} while (difficultyEntry != null);
}
//first key = id, difficulty
//second key = id
mSpellInfoMap.Add(spellNameEntry.Id, new SpellInfo(spellNameEntry, data.Key.difficulty, data.Value, visuals));
}
CliDB.SpellNameStorage.Clear();
@@ -2248,13 +2376,15 @@ namespace Game.Entities
uint spellId = result.Read<uint>(0);
uint attributes = result.Read<uint>(1);
SpellInfo spellInfo = GetSpellInfo(spellId);
if (spellInfo == null)
var spells = _GetSpellInfo(spellId);
if (spells == null)
{
Log.outError(LogFilter.Sql, "Table `spell_custom_attr` has wrong spell (entry: {0}), ignored.", spellId);
continue;
}
foreach (SpellInfo spellInfo in spells)
{
// TODO: validate attributes
if (attributes.HasAnyFlag((uint)SpellCustomAttributes.ShareDamage))
{
@@ -2266,6 +2396,7 @@ namespace Game.Entities
}
spellInfo.AttributesCu |= (SpellCustomAttributes)attributes;
}
++count;
} while (result.NextRow());
@@ -2278,7 +2409,7 @@ namespace Game.Entities
foreach (var spellInfo in mSpellInfoMap.Values)
{
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect == null)
continue;
@@ -2352,19 +2483,19 @@ namespace Game.Entities
if (enchant.Effect[s] != ItemEnchantmentType.CombatSpell)
continue;
SpellInfo procInfo = GetSpellInfo(enchant.EffectArg[s]);
if (procInfo == null)
continue;
foreach (SpellInfo procInfo in _GetSpellInfo(enchant.EffectArg[s]))
{
// if proced directly from enchantment, not via proc aura
// NOTE: Enchant Weapon - Blade Ward also has proc aura spell and is proced directly
// however its not expected to stack so this check is good
if (procInfo.HasAura(Difficulty.None, AuraType.ProcTriggerSpell))
if (procInfo.HasAura(AuraType.ProcTriggerSpell))
continue;
procInfo.AttributesCu |= SpellCustomAttributes.EnchantProc;
}
}
}
break;
}
}
@@ -2374,7 +2505,7 @@ namespace Game.Entities
if (!spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult))
{
bool setFlag = false;
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect == null)
continue;
@@ -2497,7 +2628,7 @@ namespace Game.Entities
bool allNonBinary = true;
bool overrideAttr = false;
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect == null)
continue;
@@ -2508,7 +2639,7 @@ namespace Game.Entities
{
case AuraType.PeriodicTriggerSpell:
case AuraType.PeriodicTriggerSpellWithValue:
SpellInfo triggerSpell = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell);
SpellInfo triggerSpell = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell, Difficulty.None);
if (triggerSpell != null)
{
overrideAttr = true;
@@ -2535,7 +2666,7 @@ namespace Game.Entities
foreach (var spellInfo in mSpellInfoMap.Values)
{
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect == null)
continue;
@@ -2543,7 +2674,7 @@ namespace Game.Entities
if (effect.IsEffect() && (effect.TargetA.GetTarget() == Targets.DestTraj || effect.TargetB.GetTarget() == Targets.DestTraj))
{
// Get triggered spell if any
SpellInfo spellInfoTrigger = GetSpellInfo(effect.TriggerSpell);
SpellInfo spellInfoTrigger = GetSpellInfo(effect.TriggerSpell, Difficulty.None);
if (spellInfoTrigger != null)
{
float maxRangeMain = spellInfo.GetMaxRange();
@@ -2572,8 +2703,12 @@ namespace Game.Entities
spellInfo.ConeAngle = 90.0f;
}
// disable proc for magnet auras, they're handled differently
if (spellInfo.HasAura(AuraType.SpellMagnet))
spellInfo.ProcFlags = 0;
// due to the way spell system works, unit would change orientation in Spell::_cast
if (spellInfo.HasAura(Difficulty.None, AuraType.ControlVehicle))
if (spellInfo.HasAura(AuraType.ControlVehicle))
spellInfo.AttributesEx5 |= SpellAttr5.DontTurnDuringCast;
if (spellInfo.ActiveIconFileDataId == 135754) // flight
@@ -2936,7 +3071,7 @@ namespace Game.Entities
break;
case 71412: // Green Ooze Summon (Professor Putricide)
case 71415: // Orange Ooze Summon (Professor Putricide)
spellInfo.GetEffect(0).TargetA = new SpellImplicitTargetInfo(Targets.UnitAny);
spellInfo.GetEffect(0).TargetA = new SpellImplicitTargetInfo(Targets.UnitTargetAny);
break;
case 71159: // Awaken Plagued Zombies
spellInfo.DurationEntry = CliDB.SpellDurationStorage.LookupByKey(21);
@@ -2949,7 +3084,7 @@ namespace Game.Entities
spellInfo.GetEffect(1).Effect = 0;
break;
case 70911: // Unbound Plague (Professor Putricide) (needs target selection script)
spellInfo.GetEffect(0).TargetB = new SpellImplicitTargetInfo(Targets.UnitEnemy);
spellInfo.GetEffect(0).TargetB = new SpellImplicitTargetInfo(Targets.UnitTargetEnemy);
break;
case 71708: // Empowered Flare (Blood Prince Council)
spellInfo.AttributesEx3 |= SpellAttr3.NoDoneBonus;
@@ -2967,7 +3102,7 @@ namespace Game.Entities
spellInfo.DurationEntry = CliDB.SpellDurationStorage.LookupByKey(9); // 30 seconds (missing)
break;
case 70936: // Summon Suppressor (needs target selection script)
spellInfo.GetEffect(0).TargetA = new SpellImplicitTargetInfo(Targets.UnitAny);
spellInfo.GetEffect(0).TargetA = new SpellImplicitTargetInfo(Targets.UnitTargetAny);
spellInfo.GetEffect(0).TargetB = new SpellImplicitTargetInfo();
spellInfo.RangeEntry = CliDB.SpellRangeStorage.LookupByKey(157); // 90yd
break;
@@ -3138,7 +3273,7 @@ namespace Game.Entities
foreach (var spellInfo in mSpellInfoMap.Values)
{
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
{
if (effect == null)
continue;
@@ -3160,7 +3295,7 @@ namespace Game.Entities
}
// disable proc for magnet auras, they're handled differently
if (spellInfo.HasAura(Difficulty.None, AuraType.SpellMagnet))
if (spellInfo.HasAura(AuraType.SpellMagnet))
spellInfo.ProcFlags = 0;
if (spellInfo.ActiveIconFileDataId == 135754) // flight
@@ -3233,7 +3368,7 @@ namespace Game.Entities
foreach (var skillLine in CliDB.SkillLineAbilityStorage.Values)
{
SpellInfo spellInfo = GetSpellInfo(skillLine.Spell);
SpellInfo spellInfo = GetSpellInfo(skillLine.Spell, Difficulty.None);
if (spellInfo == null)
continue;
@@ -3275,7 +3410,7 @@ namespace Game.Entities
byte race = result.Read<byte>(1);
uint displayId = result.Read<uint>(2);
SpellInfo spellEntry = GetSpellInfo(spellId);
SpellInfo spellEntry = GetSpellInfo(spellId, Difficulty.None);
if (spellEntry == null)
{
Log.outError(LogFilter.Sql, $"SpellID: {spellId} in `spell_totem_model` table could not be found in dbc, skipped.");
@@ -3396,15 +3531,16 @@ namespace Game.Entities
}
// SpellInfo object management
public SpellInfo GetSpellInfo(uint spellId)
public bool HasSpellInfo(uint spellId, Difficulty difficulty)
{
return mSpellInfoMap.LookupByKey(spellId);
var list = mSpellInfoMap.LookupByKey(spellId);
if (list.Count == 0)
return false;
return list.Any(spellInfo => spellInfo.Difficulty == difficulty);
}
public bool HasSpellInfo(uint spellId)
{
return mSpellInfoMap.ContainsKey(spellId);
}
public Dictionary<uint, SpellInfo> GetSpellInfoStorage()
public MultiMap<uint, SpellInfo> GetSpellInfoStorage()
{
return mSpellInfoMap;
}
@@ -3519,7 +3655,7 @@ namespace Game.Entities
MultiMap<SpellGroup, int> mSpellGroupSpell = new MultiMap<SpellGroup, int>();
Dictionary<SpellGroup, SpellGroupStackRule> mSpellGroupStack = new Dictionary<SpellGroup, SpellGroupStackRule>();
MultiMap<SpellGroup, AuraType> mSpellSameEffectStack = new MultiMap<SpellGroup, AuraType>();
Dictionary<uint, SpellProcEntry> mSpellProcMap = new Dictionary<uint, SpellProcEntry>();
Dictionary<(uint id, Difficulty difficulty), SpellProcEntry> mSpellProcMap = new Dictionary<(uint id, Difficulty difficulty), SpellProcEntry>();
Dictionary<uint, SpellThreatEntry> mSpellThreatMap = new Dictionary<uint, SpellThreatEntry>();
Dictionary<uint, PetAura> mSpellPetAuraMap = new Dictionary<uint, PetAura>();
MultiMap<int, int> mSpellLinkedMap = new MultiMap<int, int>();
@@ -3534,7 +3670,7 @@ namespace Game.Entities
MultiMap<uint, SkillLineAbilityRecord> mSkillLineAbilityMap = new MultiMap<uint, SkillLineAbilityRecord>();
Dictionary<uint, MultiMap<uint, uint>> mPetLevelupSpellMap = new Dictionary<uint, MultiMap<uint, uint>>();
Dictionary<uint, PetDefaultSpellsEntry> mPetDefaultSpellsMap = new Dictionary<uint, PetDefaultSpellsEntry>(); // only spells not listed in related mPetLevelupSpellMap entry
Dictionary<uint, SpellInfo> mSpellInfoMap = new Dictionary<uint, SpellInfo>();
MultiMap<uint, SpellInfo> mSpellInfoMap = new MultiMap<uint, SpellInfo>();
Dictionary<Tuple<uint, byte>, uint> mSpellTotemModel = new Dictionary<Tuple<uint, byte>, uint>();
Dictionary<uint, BattlePetSpeciesRecord> mBattlePets = new Dictionary<uint, BattlePetSpeciesRecord>();
@@ -3571,23 +3707,24 @@ namespace Game.Entities
public class SpellInfoLoadHelper
{
public SpellNameRecord Entry;
public SpellAuraOptionsRecord AuraOptions;
public SpellAuraRestrictionsRecord AuraRestrictions;
public SpellCastingRequirementsRecord CastingRequirements;
public SpellCategoriesRecord Categories;
public SpellClassOptionsRecord ClassOptions;
public SpellCooldownsRecord Cooldowns;
public SpellEffectRecord[] Effects = new SpellEffectRecord[SpellConst.MaxEffects];
public SpellEquippedItemsRecord EquippedItems;
public SpellInterruptsRecord Interrupts;
public SpellLevelsRecord Levels;
public SpellMiscRecord Misc;
public SpellPowerRecord[] Powers = new SpellPowerRecord[SpellConst.MaxPowersPerSpell];
public SpellReagentsRecord Reagents;
public SpellScalingRecord Scaling;
public SpellShapeshiftRecord Shapeshift;
public SpellTargetRestrictionsRecord TargetRestrictions;
public SpellTotemsRecord Totems;
public List<SpellXSpellVisualRecord> Visuals = new List<SpellXSpellVisualRecord>(); // only to group visuals when parsing sSpellXSpellVisualStore, not for loading
}
public class SpellThreatEntry
@@ -130,7 +130,7 @@ namespace Game
static bool SpellCheck(uint spell_id)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id, Difficulty.None);
return spellInfo != null && !spellInfo.HasAttribute(SpellCustomAttributes.IsTalent);
}
@@ -117,7 +117,7 @@ namespace Scripts.Northrend.AzjolNerub.Ahnkahet.HeraldVolazj
// phase the player
target.CastSpell(target, SpellIds.InsanityTarget + insanityHandled, true);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.InsanityTarget + insanityHandled);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.InsanityTarget + insanityHandled, GetDifficulty());
if (spellInfo == null)
return;
@@ -1719,7 +1719,7 @@ Fall Time: 824
void HandleRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
SpellInfo damageInfo = Global.SpellMgr.GetSpellInfo(GunshipSpells.RocketPackDamage);
SpellInfo damageInfo = Global.SpellMgr.GetSpellInfo(GunshipSpells.RocketPackDamage, GetCastDifficulty());
GetTarget().CastCustomSpell(GunshipSpells.RocketPackDamage, SpellValueMod.BasePoint0, (int)(2 * (damageInfo.GetEffect(0).CalcValue() + aurEff.GetTickNumber() * aurEff.GetPeriod())), null, TriggerCastFlags.FullMask);
GetTarget().CastSpell(null, GunshipSpells.RocketBurst, TriggerCastFlags.FullMask);
}
@@ -41,7 +41,7 @@ namespace Scripts.Northrend.IcecrownCitadel
player.PlayerTalkClass.ClearMenus();
player.CLOSE_GOSSIP_MENU();
SpellInfo spell = Global.SpellMgr.GetSpellInfo(TeleportSpells[gossipListId]);
SpellInfo spell = Global.SpellMgr.GetSpellInfo(TeleportSpells[gossipListId], Difficulty.None);
if (spell == null)
return false;
@@ -84,7 +84,7 @@ namespace Scripts.Northrend.IcecrownCitadel
{
if (player.IsInCombat())
{
SpellInfo spell = Global.SpellMgr.GetSpellInfo(TeleporterSpells.FROZEN_THRONE_TELEPORT);
SpellInfo spell = Global.SpellMgr.GetSpellInfo(TeleporterSpells.FROZEN_THRONE_TELEPORT, Difficulty.None);
if (spell != null)
{
ObjectGuid castId = ObjectGuid.Create(HighGuid.Cast, SpellCastSource.Normal, player.GetMapId(), spell.Id, player.GetMap().GenerateLowGuid(HighGuid.Cast));
@@ -519,7 +519,7 @@ namespace Scripts.Northrend.IcecrownCitadel
if (target.HasAura(Spells.Impaled))
return false;
SpellEffectInfo effect = GetSpellInfo().GetEffect(target.GetMap().GetDifficultyID(), 0);
SpellEffectInfo effect = GetSpellInfo().GetEffect(0);
if (effect != null)
if (target.GetExactDist2d(GetOwner()) > effect.CalcRadius())
return false;
+1 -1
View File
@@ -263,7 +263,7 @@ namespace Scripts.Spells.DeathKnight
return;
int amount = (int)(damageInfo.GetDamage() / 2);
SpellNonMeleeDamage log = new SpellNonMeleeDamage(drw, drw.GetVictim(), spellInfo.Id, spellInfo.GetSpellXSpellVisualId(drw), spellInfo.GetSchoolMask());
SpellNonMeleeDamage log = new SpellNonMeleeDamage(drw, drw.GetVictim(), spellInfo, spellInfo.GetSpellXSpellVisualId(drw), spellInfo.GetSchoolMask());
log.damage = (uint)amount;
drw.DealDamage(drw.GetVictim(), (uint)amount, null, DamageEffectType.Direct, spellInfo.GetSchoolMask(), spellInfo, true);
drw.SendSpellNonMeleeDamageLog(log);
+5 -5
View File
@@ -701,7 +701,7 @@ namespace Scripts.Spells.Druid
if (player.GetSkillValue(SkillType.Riding) < 75)
return SpellCastResult.ApprenticeRidingRequirement;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(player.IsInWater() ? SpellIds.FormAquatic : SpellIds.FormStag);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(player.IsInWater() ? SpellIds.FormAquatic : SpellIds.FormStag, GetCastDifficulty());
return spellInfo.CheckLocation(player.GetMapId(), player.GetZoneId(), player.GetAreaId(), player);
}
@@ -758,7 +758,7 @@ namespace Scripts.Spells.Druid
SpellCastResult CheckLocationForForm(uint spell)
{
Player player = GetTarget().ToPlayer();
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell, GetCastDifficulty());
return spellInfo.CheckLocation(player.GetMapId(), player.GetZoneId(), player.GetAreaId(), player);
}
}
@@ -821,7 +821,7 @@ namespace Scripts.Spells.Druid
SpellCastResult CheckLocationForForm(uint spell_id)
{
Player player = GetTarget().ToPlayer();
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id, GetCastDifficulty());
if (!player.GetMap().IsOutdoors(player.GetPhaseShift(), player.GetPositionX(), player.GetPositionY(), player.GetPositionZ()))
return SpellCastResult.OnlyOutdoors;
@@ -900,9 +900,9 @@ namespace Scripts.Spells.Druid
Unit caster = eventInfo.GetActor();
Unit target = eventInfo.GetProcTarget();
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.Languish);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.Languish, GetCastDifficulty());
int amount = (int)MathFunctions.CalculatePct(damageInfo.GetDamage(), aurEff.GetAmount());
amount /= (int)spellInfo.GetMaxTicks(Difficulty.None);
amount /= (int)spellInfo.GetMaxTicks();
// Add remaining ticks to damage done
amount += (int)target.GetRemainingPeriodicAmount(caster.GetGUID(), SpellIds.Languish, AuraType.PeriodicDamage);
+1 -1
View File
@@ -1628,7 +1628,7 @@ namespace Scripts.Spells.Generic
public override void Register()
{
SpellInfo spell = Global.SpellMgr.GetSpellInfo(m_scriptSpellId);
SpellInfo spell = Global.SpellMgr.GetSpellInfo(m_scriptSpellId, Difficulty.None);
if (spell.HasEffect(SpellEffectName.ScriptEffect))
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, SpellConst.EffectFirstFound, SpellEffectName.ScriptEffect));
+1 -1
View File
@@ -434,7 +434,7 @@ namespace Scripts.Spells.Hunter
// immediately finishes the cooldown on your other Hunter abilities except Bestial Wrath
GetCaster().GetSpellHistory().ResetCooldowns(p =>
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(p.Key);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(p.Key, GetCastDifficulty());
//! If spellId in cooldown map isn't valid, the above will return a null pointer.
if (spellInfo.SpellFamilyName == SpellFamilyNames.Hunter &&
+3 -3
View File
@@ -555,9 +555,9 @@ namespace Scripts.Spells.Items
uint spellId = 0;
int amount = (int)(eventInfo.GetDamageInfo().GetDamage() * 0.4f);
if (eventInfo.GetDamageInfo().GetSpellInfo().HasEffect(Difficulty.None, SpellEffectName.Heal))
if (eventInfo.GetDamageInfo().GetSpellInfo().HasEffect(SpellEffectName.Heal))
spellId = SpellIds.AlchemistStoneExtraHeal;
else if (eventInfo.GetDamageInfo().GetSpellInfo().HasEffect(Difficulty.None, SpellEffectName.Energize))
else if (eventInfo.GetDamageInfo().GetSpellInfo().HasEffect(SpellEffectName.Energize))
spellId = SpellIds.AlchemistStoneExtraMana;
if (spellId == 0)
@@ -779,7 +779,7 @@ namespace Scripts.Spells.Items
void HandleDummy(uint effIndex)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.DeadlyPrecision);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.DeadlyPrecision, GetCastDifficulty());
GetCaster().CastCustomSpell(spellInfo.Id, SpellValueMod.AuraStack, (int)spellInfo.StackAmount, GetCaster(), true);
}
+5 -5
View File
@@ -149,7 +149,7 @@ namespace Scripts.Spells.Mage
}
GetTarget().SetHealth(GetTarget().CountPctFromMaxHealth(effect1.GetAmount()));
GetTarget().CastSpell(GetTarget(), GetAura().GetSpellEffectInfo(2).TriggerSpell, TriggerCastFlags.FullMask);
GetTarget().CastSpell(GetTarget(), GetSpellInfo().GetEffect(2).TriggerSpell, TriggerCastFlags.FullMask);
GetTarget().CastSpell(GetTarget(), SpellIds.CauterizeDot, TriggerCastFlags.FullMask);
GetTarget().CastSpell(GetTarget(), SpellIds.Cauterized, TriggerCastFlags.FullMask);
}
@@ -288,10 +288,10 @@ namespace Scripts.Spells.Mage
{
PreventDefaultAction();
SpellInfo igniteDot = Global.SpellMgr.GetSpellInfo(SpellIds.Ignite);
SpellInfo igniteDot = Global.SpellMgr.GetSpellInfo(SpellIds.Ignite, GetCastDifficulty());
int pct = aurEff.GetAmount();
int amount = (int)(MathFunctions.CalculatePct(eventInfo.GetDamageInfo().GetDamage(), pct) / igniteDot.GetMaxTicks(Difficulty.None));
int amount = (int)(MathFunctions.CalculatePct(eventInfo.GetDamageInfo().GetDamage(), pct) / igniteDot.GetMaxTicks());
amount += (int)eventInfo.GetProcTarget().GetRemainingPeriodicAmount(eventInfo.GetActor().GetGUID(), SpellIds.Ignite, AuraType.PeriodicDamage);
GetTarget().CastCustomSpell(SpellIds.Ignite, SpellValueMod.BasePoint0, amount, eventInfo.GetProcTarget(), true, null, aurEff);
}
@@ -464,7 +464,7 @@ namespace Scripts.Spells.Mage
void Apply(AuraEffect aurEff, AuraEffectHandleModes mode)
{
List<TempSummon> minions = new List<TempSummon>();
GetTarget().GetAllMinionsByEntry(minions, (uint)Global.SpellMgr.GetSpellInfo(SpellIds.RingOfFrostSummon).GetEffect(0).MiscValue);
GetTarget().GetAllMinionsByEntry(minions, (uint)Global.SpellMgr.GetSpellInfo(SpellIds.RingOfFrostSummon, GetCastDifficulty()).GetEffect(0).MiscValue);
// Get the last summoned RoF, save it and despawn older ones
foreach (var summon in minions)
@@ -513,7 +513,7 @@ namespace Scripts.Spells.Mage
void FilterTargets(List<WorldObject> targets)
{
WorldLocation dest = GetExplTargetDest();
float outRadius = Global.SpellMgr.GetSpellInfo(SpellIds.RingOfFrostSummon).GetEffect(0).CalcRadius();
float outRadius = Global.SpellMgr.GetSpellInfo(SpellIds.RingOfFrostSummon, GetCastDifficulty()).GetEffect(0).CalcRadius();
float inRadius = 6.5f;
targets.RemoveAll(target =>
+1 -1
View File
@@ -110,7 +110,7 @@ namespace Scripts.Spells.Monk
{
if (GetExplTargetUnit().GetEntry() != BlackOxStatusEntry)
{
SpellInfo singleTarget = Global.SpellMgr.GetSpellInfo(SpellIds.ProvokeSingleTarget);
SpellInfo singleTarget = Global.SpellMgr.GetSpellInfo(SpellIds.ProvokeSingleTarget, GetCastDifficulty());
SpellCastResult singleTargetExplicitResult = singleTarget.CheckExplicitTarget(GetCaster(), GetExplTargetUnit());
if (singleTargetExplicitResult != SpellCastResult.SpellCastOk)
return singleTargetExplicitResult;
+4 -4
View File
@@ -456,7 +456,7 @@ namespace Scripts.Spells.Paladin
{
public override bool Validate(SpellInfo spellInfo)
{
SpellInfo firstRankSpellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.HolyShockR1);
SpellInfo firstRankSpellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.HolyShockR1, Difficulty.None);
if (firstRankSpellInfo == null)
return false;
@@ -596,7 +596,7 @@ namespace Scripts.Spells.Paladin
{
if (eff.GetSpellInfo().GetSpellSpecific() == SpellSpecificType.Seal && eff.GetEffIndex() == 2)
{
if (Global.SpellMgr.HasSpellInfo((uint)eff.GetAmount()))
if (Global.SpellMgr.HasSpellInfo((uint)eff.GetAmount(), GetCastDifficulty()))
{
spellId = (uint)eff.GetAmount();
break;
@@ -923,9 +923,9 @@ namespace Scripts.Spells.Paladin
Unit caster = eventInfo.GetActor();
Unit target = eventInfo.GetProcTarget();
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.HolyMending);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.HolyMending, GetCastDifficulty());
int amount = (int)MathFunctions.CalculatePct(healInfo.GetHeal(), aurEff.GetAmount());
amount /= (int)spellInfo.GetMaxTicks(Difficulty.None);
amount /= (int)spellInfo.GetMaxTicks();
// Add remaining ticks to damage done
amount += (int)target.GetRemainingPeriodicAmount(caster.GetGUID(), SpellIds.HolyMending, AuraType.PeriodicHeal);
+7 -7
View File
@@ -409,8 +409,8 @@ namespace Scripts.Spells.Priest
if (healInfo == null || healInfo.GetHeal() == 0)
return;
SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.GlyphOfPrayerOfHealingHeal);
int heal = (int)(MathFunctions.CalculatePct(healInfo.GetHeal(), aurEff.GetAmount()) / triggeredSpellInfo.GetMaxTicks(Difficulty.None));
SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.GlyphOfPrayerOfHealingHeal, GetCastDifficulty());
int heal = (int)(MathFunctions.CalculatePct(healInfo.GetHeal(), aurEff.GetAmount()) / triggeredSpellInfo.GetMaxTicks());
GetTarget().CastCustomSpell(SpellIds.GlyphOfPrayerOfHealingHeal, SpellValueMod.BasePoint0, heal, eventInfo.GetProcTarget(), true, null, aurEff);
}
@@ -566,7 +566,7 @@ namespace Scripts.Spells.Priest
SpellCastTargets targets = new SpellCastTargets();
targets.SetDst(destPos);
targets.SetUnitTarget(GetCaster());
GetHitUnit().CastSpell(targets, Global.SpellMgr.GetSpellInfo((uint)GetEffectValue()), null);
GetHitUnit().CastSpell(targets, Global.SpellMgr.GetSpellInfo((uint)GetEffectValue(), GetCastDifficulty()), null);
}
public override void Register()
@@ -702,7 +702,7 @@ namespace Scripts.Spells.Priest
public override bool Validate(SpellInfo spellInfo)
{
SpellInfo firstRankSpellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.PenanceR1);
SpellInfo firstRankSpellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.PenanceR1, Difficulty.None);
if (firstRankSpellInfo == null)
return false;
@@ -997,9 +997,9 @@ namespace Scripts.Spells.Priest
if (healInfo == null || healInfo.GetHeal() == 0)
return;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.BlessedHealing);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.BlessedHealing, GetCastDifficulty());
int amount = (int)MathFunctions.CalculatePct(healInfo.GetHeal(), aurEff.GetAmount());
amount /= (int)spellInfo.GetMaxTicks(Difficulty.None);
amount /= (int)spellInfo.GetMaxTicks();
// Add remaining ticks to healing done
Unit caster = eventInfo.GetActor();
@@ -1134,7 +1134,7 @@ namespace Scripts.Spells.Priest
{
SpellCastTargets targets = new SpellCastTargets();
targets.SetDst(destPos);
GetCaster().CastSpell(targets, Global.SpellMgr.GetSpellInfo(SpellIds.AngelicFeatherAreatrigger), null);
GetCaster().CastSpell(targets, Global.SpellMgr.GetSpellInfo(SpellIds.AngelicFeatherAreatrigger, GetCastDifficulty()), null);
}
}
+7 -7
View File
@@ -612,7 +612,7 @@ namespace Scripts.Spells.Shaman
void ResetCooldown()
{
GetCaster().GetSpellHistory().RestoreCharge(Global.SpellMgr.GetSpellInfo(SpellIds.LavaBurst).ChargeCategoryId);
GetCaster().GetSpellHistory().RestoreCharge(Global.SpellMgr.GetSpellInfo(SpellIds.LavaBurst, GetCastDifficulty()).ChargeCategoryId);
}
public override void Register()
@@ -747,9 +747,9 @@ namespace Scripts.Spells.Shaman
if (damageInfo == null || damageInfo.GetDamage() == 0)
return;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.Electrified);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.Electrified, GetCastDifficulty());
int amount = (int)MathFunctions.CalculatePct(damageInfo.GetDamage(), aurEff.GetAmount());
amount /= (int)spellInfo.GetMaxTicks(Difficulty.None);
amount /= (int)spellInfo.GetMaxTicks();
// Add remaining ticks to damage done
Unit caster = eventInfo.GetActor();
@@ -781,9 +781,9 @@ namespace Scripts.Spells.Shaman
if (damageInfo == null || damageInfo.GetDamage() == 0)
return;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.LavaBurstBonusDamage);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.LavaBurstBonusDamage, GetCastDifficulty());
int amount = (int)MathFunctions.CalculatePct(damageInfo.GetDamage(), aurEff.GetAmount());
amount /= (int)spellInfo.GetMaxTicks(Difficulty.None);
amount /= (int)spellInfo.GetMaxTicks();
// Add remaining ticks to damage done
Unit caster = eventInfo.GetActor();
@@ -847,9 +847,9 @@ namespace Scripts.Spells.Shaman
if (healInfo == null || healInfo.GetHeal() == 0)
return;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.ChainedHeal);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.ChainedHeal, GetCastDifficulty());
int amount = (int)MathFunctions.CalculatePct(healInfo.GetHeal(), aurEff.GetAmount());
amount /= (int)spellInfo.GetMaxTicks(Difficulty.None);
amount /= (int)spellInfo.GetMaxTicks();
// Add remaining ticks to healing done
Unit caster = eventInfo.GetActor();
+3 -3
View File
@@ -226,7 +226,7 @@ namespace Scripts.Spells.Warlock
// WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST; allowing him to cast the WARLOCK_DEMONIC_CIRCLE_TELEPORT.
// If not in range remove the WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST.
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.DemonicCircleTeleport);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.DemonicCircleTeleport, GetCastDifficulty());
if (GetTarget().IsWithinDist(circle, spellInfo.GetMaxRange(true)))
{
@@ -338,7 +338,7 @@ namespace Scripts.Spells.Warlock
break;
case CreatureFamily.Voidwalker:
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.DemonicEmpowermentVoidwalker);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.DemonicEmpowermentVoidwalker, GetCastDifficulty());
int hp = (int)targetCreature.CountPctFromMaxHealth(GetCaster().CalculateSpellDamage(targetCreature, spellInfo, 0));
targetCreature.CastCustomSpell(targetCreature, SpellIds.DemonicEmpowermentVoidwalker, hp, 0, 0, true);
break;
@@ -556,7 +556,7 @@ namespace Scripts.Spells.Warlock
if (modOwner)
modOwner.ApplySpellMod(GetId(), SpellModOp.Cost, ref damage);
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(caster, caster, GetSpellInfo().Id, GetAura().GetSpellXSpellVisualId(), GetSpellInfo().SchoolMask, GetAura().GetCastGUID());
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(caster, caster, GetSpellInfo(), GetAura().GetSpellXSpellVisualId(), GetSpellInfo().SchoolMask, GetAura().GetCastGUID());
damageInfo.periodicLog = true;
damageInfo.damage = damage;
caster.DealSpellDamage(damageInfo, false);
+1 -1
View File
@@ -823,7 +823,7 @@ namespace Scripts.Spells.Warrior
//Get the Remaining Damage from the aura (if exist)
int remainingDamage = (int)target.GetRemainingPeriodicAmount(target.GetGUID(), SpellIds.TraumaEffect, AuraType.PeriodicDamage);
//Get 25% of damage from the spell casted (Slam & Whirlwind) plus Remaining Damage from Aura
int damage = (int)(MathFunctions.CalculatePct(eventInfo.GetDamageInfo().GetDamage(), aurEff.GetAmount()) / Global.SpellMgr.GetSpellInfo(SpellIds.TraumaEffect).GetMaxTicks(Difficulty.None)) + remainingDamage;
int damage = (int)(MathFunctions.CalculatePct(eventInfo.GetDamageInfo().GetDamage(), aurEff.GetAmount()) / Global.SpellMgr.GetSpellInfo(SpellIds.TraumaEffect, GetCastDifficulty()).GetMaxTicks()) + remainingDamage;
GetCaster().CastCustomSpell(SpellIds.TraumaEffect, SpellValueMod.BasePoint0, damage, target, true);
}
+2 -2
View File
@@ -99,7 +99,7 @@ namespace Scripts.World
{
DateTime now = GameTime.GetGameTimeSystemPoint();
uint cooldownDuration = pair.Value.CooldownEnd > now ? (uint)(pair.Value.CooldownEnd - now).TotalMilliseconds : 0;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(pair.Key);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(pair.Key, Difficulty.None);
return spellInfo.RecoveryTime < 10 * Time.Minute * Time.InMilliseconds
&& spellInfo.CategoryRecoveryTime < 10 * Time.Minute * Time.InMilliseconds
&& !pair.Value.OnHold
@@ -113,7 +113,7 @@ namespace Scripts.World
// remove cooldowns on spells that have < 10 min CD and has no onHold
player.GetSpellHistory().ResetCooldowns(pair =>
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(pair.Key);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(pair.Key, Difficulty.None);
return spellInfo.RecoveryTime < 10 * Time.Minute * Time.InMilliseconds
&& spellInfo.CategoryRecoveryTime < 10 * Time.Minute * Time.InMilliseconds
&& !pair.Value.OnHold;
+2 -2
View File
@@ -126,7 +126,7 @@ namespace Scripts.World
disabled = true;
break;
case 34475:
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(ItemScriptConst.SpellArcaneCharges);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(ItemScriptConst.SpellArcaneCharges, player.GetMap().GetDifficultyID());
if (spellInfo != null)
Spell.SendCastResult(player, spellInfo, 0, castId, SpellCastResult.NotOnGround);
break;
@@ -275,7 +275,7 @@ namespace Scripts.World
if (!player.GetTransport() || player.GetAreaId() != ItemScriptConst.AreaIdShatteredStraits)
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(ItemScriptConst.SpellPetrovBomb);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(ItemScriptConst.SpellPetrovBomb, Difficulty.None);
if (spellInfo != null)
Spell.SendCastResult(player, spellInfo, 0, castId, SpellCastResult.NotHere);
+1 -1
View File
@@ -1907,7 +1907,7 @@ namespace Scripts.World.NpcSpecial
break;
}
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, Difficulty.None);
if (spellInfo != null && spellInfo.GetEffect(0).Effect == SpellEffectName.SummonObjectWild)
return (uint)spellInfo.GetEffect(0).MiscValue;
+64 -60
View File
@@ -1,8 +1,8 @@
-- MySQL dump 10.16 Distrib 10.1.6-MariaDB, for Win64 (AMD64)
-- MySQL dump 10.13 Distrib 5.7.29, for Linux (x86_64)
--
-- Host: localhost Database: characters
-- ------------------------------------------------------
-- Server version 10.1.6-MariaDB
-- Server version 5.7.29-0ubuntu0.18.04.1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
@@ -166,8 +166,8 @@ DROP TABLE IF EXISTS `auction_bidders`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `auction_bidders` (
`auctionId` int unsigned NOT NULL,
`playerGuid` bigint unsigned NOT NULL,
`auctionId` int(10) unsigned NOT NULL,
`playerGuid` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`auctionId`,`playerGuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
@@ -189,8 +189,8 @@ DROP TABLE IF EXISTS `auction_items`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `auction_items` (
`auctionId` int unsigned NOT NULL,
`itemGuid` bigint unsigned NOT NULL,
`auctionId` int(10) unsigned NOT NULL,
`itemGuid` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`auctionId`,`itemGuid`),
UNIQUE KEY `idx_itemGuid` (`itemGuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -511,6 +511,7 @@ CREATE TABLE `character_aura` (
`spell` int(10) unsigned NOT NULL,
`effectMask` int(10) unsigned NOT NULL,
`recalculateMask` int(10) unsigned NOT NULL DEFAULT '0',
`difficulty` tinyint(3) unsigned NOT NULL DEFAULT '0',
`stackCount` tinyint(3) unsigned NOT NULL DEFAULT '1',
`maxDuration` int(11) NOT NULL DEFAULT '0',
`remainTime` int(11) NOT NULL DEFAULT '0',
@@ -2942,26 +2943,26 @@ CREATE TABLE `item_instance_azerite` (
`xp` bigint(20) unsigned NOT NULL DEFAULT '0',
`level` int(10) unsigned NOT NULL DEFAULT '1',
`knowledgeLevel` int(10) unsigned NOT NULL DEFAULT '0',
`selectedAzeriteEssences1specId` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences1azeriteEssenceId1` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences1azeriteEssenceId2` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences1azeriteEssenceId3` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences1azeriteEssenceId4` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences2specId` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences2azeriteEssenceId1` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences2azeriteEssenceId2` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences2azeriteEssenceId3` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences2azeriteEssenceId4` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences3specId` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences3azeriteEssenceId1` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences3azeriteEssenceId2` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences3azeriteEssenceId3` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences3azeriteEssenceId4` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences4specId` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences4azeriteEssenceId1` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences4azeriteEssenceId2` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences4azeriteEssenceId3` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences4azeriteEssenceId4` int(10) unsigned NULL DEFAULT '0',
`selectedAzeriteEssences1specId` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences1azeriteEssenceId1` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences1azeriteEssenceId2` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences1azeriteEssenceId3` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences1azeriteEssenceId4` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences2specId` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences2azeriteEssenceId1` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences2azeriteEssenceId2` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences2azeriteEssenceId3` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences2azeriteEssenceId4` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences3specId` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences3azeriteEssenceId1` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences3azeriteEssenceId2` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences3azeriteEssenceId3` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences3azeriteEssenceId4` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences4specId` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences4azeriteEssenceId1` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences4azeriteEssenceId2` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences4azeriteEssenceId3` int(10) unsigned DEFAULT '0',
`selectedAzeriteEssences4azeriteEssenceId4` int(10) unsigned DEFAULT '0',
PRIMARY KEY (`itemGuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
@@ -3026,7 +3027,7 @@ LOCK TABLES `item_instance_azerite_milestone_power` WRITE;
UNLOCK TABLES;
--
-- Table structure for table `item_instance_azerite`
-- Table structure for table `item_instance_azerite_unlocked_essence`
--
DROP TABLE IF EXISTS `item_instance_azerite_unlocked_essence`;
@@ -3342,6 +3343,7 @@ CREATE TABLE `pet_aura` (
`spell` int(10) unsigned NOT NULL,
`effectMask` int(10) unsigned NOT NULL,
`recalculateMask` int(10) unsigned NOT NULL DEFAULT '0',
`difficulty` tinyint(3) unsigned NOT NULL DEFAULT '0',
`stackCount` tinyint(3) unsigned NOT NULL DEFAULT '1',
`maxDuration` int(11) NOT NULL DEFAULT '0',
`remainTime` int(11) NOT NULL DEFAULT '0',
@@ -3711,11 +3713,11 @@ INSERT INTO `updates` VALUES
('2015_09_10_00_characters.sql','4555A7F35C107E54C13D74D20F141039ED42943E','ARCHIVED','2015-09-10 22:50:42',0),
('2015_10_16_00_characters.sql','E3A3FFF0CB42F04A8DCF0CE4362143C16E2083AF','ARCHIVED','2015-10-15 21:54:11',0),
('2015_11_06_00_characters_2015_10_12_00.sql','D6F9927BDED72AD0A81D6EC2C6500CBC34A39FA2','ARCHIVED','2015-11-06 23:43:27',0),
('2015_11_08_00_characters.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2015-11-08 00:51:45',15),
('2015_11_08_00_characters.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2015-11-08 00:51:45',0),
('2015_11_23_00_characters.sql','9FC828E9E48E8E2E9B99A5A0073D6614C5BFC6B5','ARCHIVED','2015-11-22 23:27:34',0),
('2016_01_05_00_characters.sql','0EAD24977F40DE2476B4567DA2B477867CC0DA1A','ARCHIVED','2016-01-04 23:07:40',0),
('2016_04_05_00_characters_2016_02_10_00_characters.sql','F1B4DA202819CABC7319A4470A2D224A34609E97','ARCHIVED','2016-04-05 20:34:41',0),
('2016_04_11_00_characters.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2016-04-11 02:24:14',30),
('2016_04_11_00_characters.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2016-04-11 02:24:14',0),
('2016_04_11_01_characters.sql','CA90F6D99C1EEA7B25BD58BC8368A8D78234BBEF','ARCHIVED','2016-04-11 18:14:18',0),
('2016_05_07_00_characters.sql','D1DB5557B21A552C935564D829B4E98B98149077','ARCHIVED','2016-05-07 00:00:00',0),
('2016_05_26_00_characters.sql','4179ADC32B96FD8D7D4CF5509A470B1ACE00BE85','ARCHIVED','2016-05-26 17:06:16',0),
@@ -3731,7 +3733,7 @@ INSERT INTO `updates` VALUES
('2016_07_19_08_characters.sql','FB41FD2F8A7114FEE154021A9D47488C4B12E2A9','ARCHIVED','2016-07-19 14:36:29',0),
('2016_08_15_00_characters.sql','BF0B5F453384210CD77C54E262A19B888AAA4095','ARCHIVED','2016-08-14 18:14:32',0),
('2016_08_25_00_characters.sql','4AD506C3FCE54238EF452AC07EC562BD41A9D50C','ARCHIVED','2016-08-25 22:54:11',0),
('2016_10_17_00_characters.sql','A0EF594CD73690D46A46031137DB0E895F079235','ARCHIVED','2016-10-16 16:33:05',25),
('2016_10_17_00_characters.sql','A0EF594CD73690D46A46031137DB0E895F079235','ARCHIVED','2016-10-16 16:33:05',0),
('2016_10_25_00_characters.sql','CC894484561CE138C10B69D34F7831CEDFAF496B','ARCHIVED','2016-10-25 17:19:35',0),
('2016_11_06_00_characters.sql','C7EC8B65C1BE7722C53BAB79C52C1549054178C0','ARCHIVED','2016-11-06 23:05:44',0),
('2016_12_09_00_characters.sql','2A68E4187CE7F7294CBC3804AC39F48B2727E64E','ARCHIVED','2016-12-09 18:38:46',0),
@@ -3740,42 +3742,43 @@ INSERT INTO `updates` VALUES
('2017_01_29_00_characters.sql','E7475DCC13A0910FF23BF0EFB731629950A73A0D','ARCHIVED','2017-01-29 15:00:00',0),
('2017_02_26_00_characters_2016_09_13_00_characters.sql','2EF7AD507D097ABC74FF1E98A65BEC03B12E51C6','ARCHIVED','2017-02-26 19:57:47',0),
('2017_04_15_00_characters.sql','F118BA33CD7DDF2EE5673C6749C2965EFFF53C23','ARCHIVED','2017-04-15 12:10:50',0),
('2017_04_19_00_characters.sql','5A36FD9015ED024BC085F995F72DC81B47CD1093','ARCHIVED','2017-04-18 23:16:18',30),
('2017_04_19_00_characters.sql','5A36FD9015ED024BC085F995F72DC81B47CD1093','ARCHIVED','2017-04-18 23:16:18',0),
('2017_05_08_00_characters.sql','86B5603EEBE1DE0EA56DBB264257967CFE583F46','ARCHIVED','2017-05-08 23:54:40',0),
('2017_05_14_00_characters.sql','3452261F366BFE76BB59C0AAA674FA1513042899','ARCHIVED','2017-05-14 17:29:04',0),
('2017_05_24_00_characters.sql','02701BF57589CD41456A748AEF425CBB2D3E6AD7','ARCHIVED','2017-05-24 22:00:00',0),
('2017_06_04_00_characters.sql','BC80D2B7515CC6E01701070D2DA466727F36DB5E','ARCHIVED','2017-06-04 14:43:26',0),
('2017_08_20_00_characters.sql','8C5BBF6AEAA6C7DE2F40A7D3878C8187A4729F13','ARCHIVED','2017-08-20 17:00:00',0),
('2017_08_20_01_characters.sql','2F50D5E6BF3888B8C5270D79228A1D0601FAFF1D','ARCHIVED','2017-08-20 17:52:21',0),
('2017_10_29_00_characters.sql','8CFC473E7E87E58C317A72016BF69E9050D3BC83','ARCHIVED','2017-04-19 00:07:40',25),
('2017_10_29_00_characters.sql','8CFC473E7E87E58C317A72016BF69E9050D3BC83','ARCHIVED','2017-04-19 00:07:40',0),
('2018_02_03_00_characters.sql','73E9BFD848D7A22F2A7DD89CF64E30E3A8689512','ARCHIVED','2018-02-03 23:52:42',0),
('2018_02_08_00_characters.sql','75FA162A9B85D678B26F972371265F1EC2C75187','ARCHIVED','2018-02-08 22:23:28',0),
('2018_02_19_00_characters.sql','75A0FFAFD0633921708DB0F72F9CC9796ACB960B','RELEASED','2018-02-19 22:33:32',117),
('2018_03_04_00_characters.sql','2A4CD2EE2547E718490706FADC78BF36F0DED8D6','RELEASED','2018-03-04 18:15:24',0),
('2018_04_28_00_characters.sql','CBD0FDC0F32DE3F456F7CE3D9CAD6933CD6A50F5','RELEASED','2018-04-28 12:44:09',0),
('2018_07_28_00_characters.sql','31F66AE7831251A8915625EC7F10FA138AB8B654','RELEASED','2018-07-28 18:30:19',0),
('2018_07_31_00_characters.sql','7DA8D4A4534520B23E6F5BBD5B8EE205B799C798','RELEASED','2018-07-31 20:54:39',0),
('2018_12_09_00_characters.sql','7FE9641C93ED762597C08F1E9B6649C9EC2F0E47','RELEASED','2018-09-18 23:34:29',0),
('2018_12_09_01_characters.sql','C80B936AAD94C58A0F33382CED08CFB4E0B6AC34','RELEASED','2018-10-10 22:05:28',0),
('2018_12_09_02_characters.sql','DBBA0C06985CE8AC4E6E7E94BD6B2673E9ADFAE2','RELEASED','2018-12-02 17:32:31',0),
('2019_06_08_00_characters.sql','6C5AF52AEF03BC019B96E7A07592C22660F9327B','RELEASED','2019-06-03 20:04:47',0),
('2019_06_08_01_characters.sql','55076AFAF4B55DB4E34029C269EE0C84315C31BA','RELEASED','2019-06-04 22:11:47',0),
('2019_06_25_00_characters.sql','B8CBF79DEE02B40B01424327D31E52C70335BEC6','RELEASED','2019-06-25 22:40:37',0),
('2019_07_15_00_characters.sql','E1C77F604FB2A2FE8B32258CD0C9EC71BEA4F0FF','RELEASED','2019-06-25 22:40:37',0),
('2019_10_26_00_characters.sql','F1090ACDEB876A7BB5ED8829373F6305A217949A','RELEASED','2019-10-25 23:04:42',0),
('2019_10_26_01_characters.sql','59D5860930D02AB77D2AAA704C564957A9143760','RELEASED','2019-10-26 22:04:46',0),
('2019_11_03_00_characters.sql','DC789597F85B890E9A7901B4443DAD9CAEE2A02A','RELEASED','2019-11-03 14:13:27',0),
('2019_11_12_00_characters.sql','D4C642B4D48DAE9F56329BDE51C258323A132A91','RELEASED','2019-11-12 16:31:29',0),
('2019_11_22_00_characters.sql','95DFA71DBD75542C098CD86E9C0051C9690902F0','RELEASED','2019-11-20 15:10:12',0),
('2019_11_30_00_characters.sql','D0678E62B651AECA60C2DD6989BF80BD999AD12B','RELEASED','2019-11-29 22:42:01',0),
('2019_12_05_00_characters.sql','EA381C9634A5646A3168F15DF4E06A708A622762','RELEASED','2019-12-05 20:56:58',0),
('2020_02_17_00_characters.sql','E1519A81D35F19B48B3C75A83A270CB4BA0B84F2','RELEASED','2020-02-17 21:55:17',0),
('2020_04_20_00_characters.sql','977B5E0C894E0A7E80B2A9626F17CA636A69BD22','RELEASED','2020-04-20 19:08:18',0),
('2020_04_24_00_characters.sql','85E2E0395A9457A53D73A9E0A7BB39B7E4C429BF','RELEASED','2020-04-24 22:04:59',0),
('2020_04_25_00_characters_2017_04_03_00_characters.sql','00FA3EFADAF807AC96619A3FE47216E21C3FCB19','RELEASED','2020-04-25 00:00:00',0),
('2020_04_26_00_characters_2017_04_12_00_characters.sql','86AA94DA9B1EA283101100886C10F648C0CE6494','RELEASED','2020-04-26 00:00:00',0),
('2020_04_26_01_characters_2017_04_12_01_characters.sql','5A8A1215E3A2356722F52CD7A64BBE03D21FBEA3','RELEASED','2020-04-26 00:00:00',0);
('2018_02_19_00_characters.sql','75A0FFAFD0633921708DB0F72F9CC9796ACB960B','ARCHIVED','2018-02-19 22:33:32',0),
('2018_03_04_00_characters.sql','2A4CD2EE2547E718490706FADC78BF36F0DED8D6','ARCHIVED','2018-03-04 18:15:24',0),
('2018_04_28_00_characters.sql','CBD0FDC0F32DE3F456F7CE3D9CAD6933CD6A50F5','ARCHIVED','2018-04-28 12:44:09',0),
('2018_07_28_00_characters.sql','31F66AE7831251A8915625EC7F10FA138AB8B654','ARCHIVED','2018-07-28 18:30:19',0),
('2018_07_31_00_characters.sql','7DA8D4A4534520B23E6F5BBD5B8EE205B799C798','ARCHIVED','2018-07-31 20:54:39',0),
('2018_12_09_00_characters.sql','7FE9641C93ED762597C08F1E9B6649C9EC2F0E47','ARCHIVED','2018-09-18 23:34:29',0),
('2018_12_09_01_characters.sql','C80B936AAD94C58A0F33382CED08CFB4E0B6AC34','ARCHIVED','2018-10-10 22:05:28',0),
('2018_12_09_02_characters.sql','DBBA0C06985CE8AC4E6E7E94BD6B2673E9ADFAE2','ARCHIVED','2018-12-02 17:32:31',0),
('2019_06_08_00_characters.sql','6C5AF52AEF03BC019B96E7A07592C22660F9327B','ARCHIVED','2019-06-03 20:04:47',0),
('2019_06_08_01_characters.sql','55076AFAF4B55DB4E34029C269EE0C84315C31BA','ARCHIVED','2019-06-04 22:11:47',0),
('2019_06_25_00_characters.sql','B8CBF79DEE02B40B01424327D31E52C70335BEC6','ARCHIVED','2019-06-25 22:40:37',0),
('2019_07_15_00_characters.sql','E1C77F604FB2A2FE8B32258CD0C9EC71BEA4F0FF','ARCHIVED','2019-06-25 22:40:37',0),
('2019_10_26_00_characters.sql','F1090ACDEB876A7BB5ED8829373F6305A217949A','ARCHIVED','2019-10-25 23:04:42',0),
('2019_10_26_01_characters.sql','59D5860930D02AB77D2AAA704C564957A9143760','ARCHIVED','2019-10-26 22:04:46',0),
('2019_11_03_00_characters.sql','DC789597F85B890E9A7901B4443DAD9CAEE2A02A','ARCHIVED','2019-11-03 14:13:27',0),
('2019_11_12_00_characters.sql','D4C642B4D48DAE9F56329BDE51C258323A132A91','ARCHIVED','2019-11-12 16:31:29',0),
('2019_11_22_00_characters.sql','95DFA71DBD75542C098CD86E9C0051C9690902F0','ARCHIVED','2019-11-20 15:10:12',0),
('2019_11_30_00_characters.sql','D0678E62B651AECA60C2DD6989BF80BD999AD12B','ARCHIVED','2019-11-29 22:42:01',0),
('2019_12_05_00_characters.sql','EA381C9634A5646A3168F15DF4E06A708A622762','ARCHIVED','2019-12-05 20:56:58',0),
('2020_02_17_00_characters.sql','E1519A81D35F19B48B3C75A83A270CB4BA0B84F2','ARCHIVED','2020-02-17 21:55:17',0),
('2020_04_20_00_characters.sql','977B5E0C894E0A7E80B2A9626F17CA636A69BD22','ARCHIVED','2020-04-20 19:08:18',0),
('2020_04_24_00_characters.sql','85E2E0395A9457A53D73A9E0A7BB39B7E4C429BF','ARCHIVED','2020-04-24 22:04:59',0),
('2020_04_25_00_characters_2017_04_03_00_characters.sql','00FA3EFADAF807AC96619A3FE47216E21C3FCB19','ARCHIVED','2020-04-25 00:00:00',0),
('2020_04_26_00_characters_2017_04_12_00_characters.sql','86AA94DA9B1EA283101100886C10F648C0CE6494','ARCHIVED','2020-04-26 00:00:00',0),
('2020_04_26_01_characters_2017_04_12_01_characters.sql','5A8A1215E3A2356722F52CD7A64BBE03D21FBEA3','ARCHIVED','2020-04-26 00:00:00',0),
('2020_06_12_00_characters.sql','DF16C99EFACA4DFADDDF35644AAC63F9B4AA2BD6','ARCHIVED','2020-06-11 16:24:56',0),
('2020_06_17_00_characters.sql','C3EE0D751E4B97CDF15F3BE27AAAE3646514A358','ARCHIVED','2020-06-17 17:04:56',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
@@ -3803,7 +3806,8 @@ INSERT INTO `updates_include` VALUES
('$/sql/updates/characters','RELEASED'),
('$/sql/custom/characters','RELEASED'),
('$/sql/old/6.x/characters','ARCHIVED'),
('$/sql/old/7/characters','ARCHIVED');
('$/sql/old/7/characters','ARCHIVED'),
('$/sql/old/8.x/characters','ARCHIVED');
/*!40000 ALTER TABLE `updates_include` ENABLE KEYS */;
UNLOCK TABLES;
@@ -3868,4 +3872,4 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2018-02-19 22:43:09
-- Dump completed on 2020-06-17 17:04:58