*Move spell rank extractor out of core, use sql table instead for easier maintaining of dependant database data.
--HG-- branch : trunk
This commit is contained in:
File diff suppressed because it is too large
Load Diff
+6920
File diff suppressed because it is too large
Load Diff
+35
-35
@@ -1421,41 +1421,41 @@ struct SpellEntry
|
||||
int32 EffectMiscValueB[MAX_SPELL_EFFECTS]; // 119-121 m_effectMiscValueB
|
||||
uint32 EffectTriggerSpell[MAX_SPELL_EFFECTS]; // 122-124 m_effectTriggerSpell
|
||||
float EffectPointsPerComboPoint[MAX_SPELL_EFFECTS]; // 125-127 m_effectPointsPerCombo
|
||||
flag96 EffectSpellClassMask[MAX_SPELL_EFFECTS]; // 127-133
|
||||
uint32 SpellVisual[2]; // 134-135 m_spellVisualID
|
||||
uint32 SpellIconID; // 136 m_spellIconID
|
||||
uint32 activeIconID; // 137 m_activeIconID
|
||||
//uint32 spellPriority; // 138 not used
|
||||
char* SpellName[16]; // 139-154 m_name_lang
|
||||
//uint32 SpellNameFlag; // 155 not used
|
||||
char* Rank[16]; // 156-171 m_nameSubtext_lang
|
||||
//uint32 RankFlags; // 172 not used
|
||||
//char* Description[16]; // 173-188 m_description_lang not used
|
||||
//uint32 DescriptionFlags; // 189 not used
|
||||
//char* ToolTip[16]; // 190-205 m_auraDescription_lang not used
|
||||
//uint32 ToolTipFlags; // 206 not used
|
||||
uint32 ManaCostPercentage; // 207 m_manaCostPct
|
||||
uint32 StartRecoveryCategory; // 208 m_startRecoveryCategory
|
||||
uint32 StartRecoveryTime; // 209 m_startRecoveryTime
|
||||
uint32 MaxTargetLevel; // 210 m_maxTargetLevel
|
||||
uint32 SpellFamilyName; // 211 m_spellClassSet
|
||||
flag96 SpellFamilyFlags; // 212-214
|
||||
uint32 MaxAffectedTargets; // 215 m_maxTargets
|
||||
uint32 DmgClass; // 216 m_defenseType
|
||||
uint32 PreventionType; // 217 m_preventionType
|
||||
//uint32 StanceBarOrder; // 218 m_stanceBarOrder not used
|
||||
float DmgMultiplier[3]; // 219-221 m_effectChainAmplitude
|
||||
//uint32 MinFactionId; // 222 m_minFactionID not used
|
||||
//uint32 MinReputation; // 223 m_minReputation not used
|
||||
//uint32 RequiredAuraVision; // 224 m_requiredAuraVision not used
|
||||
uint32 TotemCategory[2]; // 225-226 m_requiredTotemCategoryID
|
||||
int32 AreaGroupId; // 227 m_requiredAreaGroupId
|
||||
uint32 SchoolMask; // 228 m_schoolMask
|
||||
uint32 runeCostID; // 229 m_runeCostID
|
||||
//uint32 spellMissileID; // 230 m_spellMissileID not used
|
||||
//uint32 PowerDisplayId; // 231 PowerDisplay.dbc, new in 3.1
|
||||
//float unk_320_4[3]; // 232-234 3.2.0
|
||||
//uint32 spellDescriptionVariableID; // 235 3.2.0
|
||||
flag96 EffectSpellClassMask[MAX_SPELL_EFFECTS]; // 127-136
|
||||
uint32 SpellVisual[2]; // 137-138 m_spellVisualID
|
||||
uint32 SpellIconID; // 139 m_spellIconID
|
||||
uint32 activeIconID; // 140 m_activeIconID
|
||||
//uint32 spellPriority; // 141 not used
|
||||
char* SpellName[16]; // 142-157 m_name_lang
|
||||
//uint32 SpellNameFlag; // 158 not used
|
||||
char* Rank[16]; // 159-174 m_nameSubtext_lang
|
||||
//uint32 RankFlags; // 175 not used
|
||||
//char* Description[16]; // 176-191 m_description_lang not used
|
||||
//uint32 DescriptionFlags; // 192 not used
|
||||
//char* ToolTip[16]; // 193-208 m_auraDescription_lang not used
|
||||
//uint32 ToolTipFlags; // 209 not used
|
||||
uint32 ManaCostPercentage; // 210 m_manaCostPct
|
||||
uint32 StartRecoveryCategory; // 211 m_startRecoveryCategory
|
||||
uint32 StartRecoveryTime; // 212 m_startRecoveryTime
|
||||
uint32 MaxTargetLevel; // 213 m_maxTargetLevel
|
||||
uint32 SpellFamilyName; // 214 m_spellClassSet
|
||||
flag96 SpellFamilyFlags; // 215-217
|
||||
uint32 MaxAffectedTargets; // 218 m_maxTargets
|
||||
uint32 DmgClass; // 219 m_defenseType
|
||||
uint32 PreventionType; // 220 m_preventionType
|
||||
//uint32 StanceBarOrder; // 221 m_stanceBarOrder not used
|
||||
float DmgMultiplier[3]; // 222-224 m_effectChainAmplitude
|
||||
//uint32 MinFactionId; // 225 m_minFactionID not used
|
||||
//uint32 MinReputation; // 226 m_minReputation not used
|
||||
//uint32 RequiredAuraVision; // 227 m_requiredAuraVision not used
|
||||
uint32 TotemCategory[2]; // 228-229 m_requiredTotemCategoryID
|
||||
int32 AreaGroupId; // 230 m_requiredAreaGroupId
|
||||
uint32 SchoolMask; // 231 m_schoolMask
|
||||
uint32 runeCostID; // 232 m_runeCostID
|
||||
//uint32 spellMissileID; // 233 m_spellMissileID not used
|
||||
//uint32 PowerDisplayId; // 234 PowerDisplay.dbc, new in 3.1
|
||||
//float unk_320_4[3]; // 235-237 3.2.0
|
||||
//uint32 spellDescriptionVariableID; // 238 3.2.0
|
||||
|
||||
// helpers
|
||||
int32 CalculateSimpleValue(uint8 eff) const { return EffectBasePoints[eff]+int32(EffectBaseDice[eff]); }
|
||||
|
||||
+88
-270
@@ -3231,302 +3231,120 @@ void SpellMgr::LoadSpellRequired()
|
||||
sLog.outString( ">> Loaded %u spell required records", rows );
|
||||
}
|
||||
|
||||
struct SpellRankEntry
|
||||
{
|
||||
uint32 SkillId;
|
||||
char const *SpellName;
|
||||
uint32 DurationIndex;
|
||||
uint32 RangeIndex;
|
||||
uint32 SpellVisual;
|
||||
uint32 ProcFlags;
|
||||
flag96 SpellFamilyFlags;
|
||||
uint32 TargetAuraState;
|
||||
uint32 ManaCost;
|
||||
uint32 CastingTimeIndex;
|
||||
flag96 Effect;
|
||||
flag96 Aura;
|
||||
uint16 TalentID;
|
||||
|
||||
bool operator < (const SpellRankEntry & _Right) const
|
||||
{
|
||||
return (SkillId != _Right.SkillId ? SkillId < _Right.SkillId
|
||||
: SpellName != _Right.SpellName ? SpellName < _Right.SpellName
|
||||
: ProcFlags != _Right.ProcFlags ? ProcFlags < _Right.ProcFlags
|
||||
|
||||
: Effect != _Right.Effect ? Effect < _Right.Effect
|
||||
: Aura != _Right.Aura ? Aura < _Right.Aura
|
||||
: TalentID != _Right.TalentID ? TalentID < _Right.TalentID
|
||||
: (CastingTimeIndex != _Right.CastingTimeIndex) && (!CastingTimeIndex || !_Right.CastingTimeIndex || CastingTimeIndex == 1 || !_Right.CastingTimeIndex == 1) ? CastingTimeIndex < _Right.CastingTimeIndex
|
||||
|
||||
: SpellFamilyFlags != _Right.SpellFamilyFlags ? SpellFamilyFlags < _Right.SpellFamilyFlags
|
||||
: (SpellVisual != _Right.SpellVisual) && (!SpellVisual || !_Right.SpellVisual) ? SpellVisual < _Right.SpellVisual
|
||||
: (ManaCost != _Right.ManaCost) && (!ManaCost || !_Right.ManaCost) ? ManaCost < _Right.ManaCost
|
||||
: (DurationIndex != _Right.DurationIndex) && (!DurationIndex || !_Right.DurationIndex)? DurationIndex < _Right.DurationIndex
|
||||
: (RangeIndex != _Right.RangeIndex) && (!RangeIndex || !_Right.RangeIndex || RangeIndex == 1 || !_Right.RangeIndex == 1) ? RangeIndex < _Right.RangeIndex
|
||||
: TargetAuraState < _Right.TargetAuraState
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct SpellRankValue
|
||||
{
|
||||
uint32 Id;
|
||||
char const *Rank;
|
||||
bool strict;
|
||||
};
|
||||
|
||||
void SpellMgr::LoadSpellChains()
|
||||
void SpellMgr::LoadSpellRanks()
|
||||
{
|
||||
mSpellChains.clear(); // need for reload case
|
||||
|
||||
std::vector<uint32> ChainedSpells;
|
||||
for (uint32 ability_id = 0; ability_id < sSkillLineAbilityStore.GetNumRows(); ++ability_id)
|
||||
QueryResult_AutoPtr result = WorldDatabase.Query("SELECT first_spell_id, spell_id, rank from spell_ranks ORDER BY first_spell_id , rank");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
SkillLineAbilityEntry const *AbilityInfo=sSkillLineAbilityStore.LookupEntry(ability_id);
|
||||
if (!AbilityInfo)
|
||||
continue;
|
||||
if (!AbilityInfo->forward_spellid)
|
||||
continue;
|
||||
ChainedSpells.push_back(AbilityInfo->forward_spellid);
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded 0 spell rank records");
|
||||
sLog.outErrorDb("`spell_ranks` table is empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
std::multimap<SpellRankEntry, SpellRankValue> RankMap;
|
||||
barGoLink bar(result->GetRowCount());
|
||||
|
||||
for (uint32 ability_id = 0; ability_id < sSkillLineAbilityStore.GetNumRows(); ++ability_id)
|
||||
uint32 rows = 0;
|
||||
bool finished = false;
|
||||
|
||||
do
|
||||
{
|
||||
SkillLineAbilityEntry const *AbilityInfo=sSkillLineAbilityStore.LookupEntry(ability_id);
|
||||
if (!AbilityInfo)
|
||||
continue;
|
||||
|
||||
//get only spell with lowest ability_id to prevent doubles
|
||||
uint32 spell_id = AbilityInfo->spellId;
|
||||
bool found = false;
|
||||
for (uint32 i = 0; i < ChainedSpells.size(); ++i)
|
||||
{
|
||||
if (ChainedSpells.at(i) == spell_id)
|
||||
found = true;
|
||||
}
|
||||
if (found)
|
||||
continue;
|
||||
|
||||
if(mSkillLineAbilityMap.lower_bound(spell_id)->second->id != ability_id)
|
||||
continue;
|
||||
SpellEntry const *SpellInfo=sSpellStore.LookupEntry(spell_id);
|
||||
if (!SpellInfo)
|
||||
continue;
|
||||
std::string sRank = SpellInfo->Rank[sWorld.GetDefaultDbcLocale()];
|
||||
if(sRank.empty())
|
||||
continue;
|
||||
//exception to polymorph spells-make pig and turtle other chain than sheep
|
||||
if (SpellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (SpellInfo->SpellFamilyFlags[0] & 0x1000000) && SpellInfo->SpellIconID != 82)
|
||||
continue;
|
||||
|
||||
SpellRankEntry entry;
|
||||
SpellRankValue value;
|
||||
entry.SkillId = AbilityInfo->skillId;
|
||||
entry.SpellName = SpellInfo->SpellName[sWorld.GetDefaultDbcLocale()];
|
||||
entry.DurationIndex = SpellInfo->DurationIndex;
|
||||
entry.RangeIndex = SpellInfo->rangeIndex;
|
||||
entry.ProcFlags = SpellInfo->procFlags;
|
||||
entry.SpellFamilyFlags = SpellInfo->SpellFamilyFlags;
|
||||
entry.TargetAuraState = SpellInfo->TargetAuraState;
|
||||
entry.SpellVisual = SpellInfo->SpellVisual[0];
|
||||
entry.ManaCost = SpellInfo->manaCost;
|
||||
entry.CastingTimeIndex = 0;
|
||||
entry.TalentID = 0;
|
||||
for (;;)
|
||||
{
|
||||
AbilityInfo = mSkillLineAbilityMap.lower_bound(spell_id)->second;
|
||||
value.Id = spell_id;
|
||||
value.Rank = SpellInfo->Rank[sWorld.GetDefaultDbcLocale()];
|
||||
value.strict = false;
|
||||
RankMap.insert(std::pair<SpellRankEntry, SpellRankValue>(entry,value));
|
||||
spell_id = AbilityInfo->forward_spellid;
|
||||
SpellInfo = sSpellStore.LookupEntry(spell_id);
|
||||
if (!SpellInfo)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
barGoLink bar(RankMap.size());
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
for (std::multimap<SpellRankEntry, SpellRankValue>::iterator itr = RankMap.begin(); itr!=RankMap.end();)
|
||||
{
|
||||
SpellRankEntry entry = itr->first;
|
||||
//trac errors in extracted data
|
||||
std::multimap<char const *, std::multimap<SpellRankEntry, SpellRankValue>::iterator> RankErrorMap;
|
||||
for (std::multimap<SpellRankEntry, SpellRankValue>::iterator itr2 = RankMap.lower_bound(entry); itr2 != RankMap.upper_bound(entry); ++itr2)
|
||||
// spellid, rank
|
||||
std::list<std::pair<int32, int32>> rankChain;
|
||||
int32 currentSpell = -1;
|
||||
int32 lastSpell = -1;
|
||||
|
||||
// fill one chain
|
||||
while(currentSpell == lastSpell && !finished)
|
||||
{
|
||||
bar.step();
|
||||
RankErrorMap.insert(std::pair<char const *, std::multimap<SpellRankEntry, SpellRankValue>::iterator>(itr2->second.Rank,itr2));
|
||||
}
|
||||
|
||||
bool error = false;
|
||||
//if strict == true strict check is not needed
|
||||
if (!itr->second.strict)
|
||||
//check for rank duplicates, if there are any do strict check
|
||||
for (std::multimap<char const *, std::multimap<SpellRankEntry, SpellRankValue>::iterator>::iterator itr2 = RankErrorMap.begin(); itr2!=RankErrorMap.end();)
|
||||
{
|
||||
char const *err_entry = itr2->first;
|
||||
uint32 rank_count=RankErrorMap.count(itr2->first);
|
||||
if (rank_count > 1)
|
||||
{
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
++itr2;
|
||||
}
|
||||
bool allHaveTalents = true;
|
||||
if (error)
|
||||
{
|
||||
std::list<uint32> ConflictedSpells;
|
||||
for (std::multimap<SpellRankEntry, SpellRankValue>::iterator itr2 = RankMap.lower_bound(entry); itr2 != RankMap.upper_bound(entry); itr2 = RankMap.lower_bound(entry))
|
||||
{
|
||||
ConflictedSpells.push_back(itr2->second.Id);
|
||||
if (!GetTalentSpellPos(itr2->second.Id))
|
||||
allHaveTalents = false;
|
||||
RankMap.erase(itr2);
|
||||
}
|
||||
SpellRankEntry nextEntry, currEntry;
|
||||
for (; !ConflictedSpells.empty(); ConflictedSpells.pop_front())
|
||||
{
|
||||
SpellEntry const *SpellInfo = sSpellStore.LookupEntry(ConflictedSpells.front());
|
||||
currEntry.SkillId = entry.SkillId;
|
||||
currEntry.SpellName = SpellInfo->SpellName[sWorld.GetDefaultDbcLocale()];
|
||||
currEntry.DurationIndex = SpellInfo->DurationIndex;
|
||||
currEntry.RangeIndex = SpellInfo->rangeIndex;
|
||||
currEntry.ProcFlags = SpellInfo->procFlags;
|
||||
currEntry.SpellFamilyFlags = SpellInfo->SpellFamilyFlags;
|
||||
//compare talents only when all spells from chain have entry
|
||||
//to prevent wrong results with spells which have first rank talented and other not
|
||||
if (allHaveTalents)
|
||||
currEntry.TalentID=GetTalentSpellPos(ConflictedSpells.front())->talent_id;
|
||||
else
|
||||
currEntry.TalentID = 0;
|
||||
currEntry.TargetAuraState = SpellInfo->TargetAuraState;
|
||||
currEntry.SpellVisual = SpellInfo->SpellVisual[0];
|
||||
currEntry.ManaCost = SpellInfo->manaCost;
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
//compare effects and casting time
|
||||
currEntry.CastingTimeIndex = SpellInfo->CastingTimeIndex;
|
||||
currEntry.Effect[0] = SpellInfo->Effect[0];
|
||||
currEntry.Effect[1] = SpellInfo->Effect[1];
|
||||
currEntry.Effect[2] = SpellInfo->Effect[2];
|
||||
currentSpell = fields[0].GetUInt32();
|
||||
if (lastSpell == -1)
|
||||
lastSpell = currentSpell;
|
||||
uint32 spell_id = fields[1].GetUInt32();
|
||||
uint32 rank = fields[2].GetUInt32();
|
||||
|
||||
currEntry.Aura[0] = SpellInfo->EffectApplyAuraName[0];
|
||||
currEntry.Aura[1] = SpellInfo->EffectApplyAuraName[1];
|
||||
currEntry.Aura[2] = SpellInfo->EffectApplyAuraName[2];
|
||||
|
||||
SpellRankValue currValue;
|
||||
currValue.Id = ConflictedSpells.front();
|
||||
currValue.Rank = SpellInfo->Rank[sWorld.GetDefaultDbcLocale()];
|
||||
currValue.strict = true;
|
||||
RankMap.insert(std::pair<SpellRankEntry, SpellRankValue>(currEntry,currValue));
|
||||
}
|
||||
itr = RankMap.begin();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
for (std::multimap<char const *, std::multimap<SpellRankEntry, SpellRankValue>::iterator>::iterator itr2 = RankErrorMap.begin(); itr2!=RankErrorMap.end();)
|
||||
// don't drop the row if we're moving to the next rank
|
||||
if (currentSpell == lastSpell)
|
||||
{
|
||||
char const *err_entry = itr2->first;
|
||||
uint32 rank_count = RankErrorMap.count(itr2->first);
|
||||
if (rank_count > 1)
|
||||
for (itr2 = RankErrorMap.lower_bound(err_entry); itr2 != RankErrorMap.upper_bound(err_entry); ++itr2)
|
||||
{
|
||||
// I removed this pointless error message since there is NOTHING that can be
|
||||
// done about it. Spell chain data is read from DBC...
|
||||
// If you *REALLY* need to see this, uncomment this line and the one below
|
||||
// sLog.outDebug("There is a duplicate rank entry (%s) for spell: %u",itr2->first,itr2->second->second.Id);
|
||||
if (itr2->second->second.Id != 47541 && itr2->second->second.Id != 45902 && itr2->second->second.Id != 7620)
|
||||
{
|
||||
// Part two of pointless error messages...
|
||||
// sLog.outDebug("Spell %u removed from chain data.",itr2->second->second.Id);
|
||||
RankMap.erase(itr2->second);
|
||||
}
|
||||
}
|
||||
else
|
||||
++itr2;
|
||||
}
|
||||
|
||||
//order spells by spellLevel
|
||||
std::list<uint32> RankedSpells;
|
||||
uint32 min_spell_lvl = 0;
|
||||
std::multimap<SpellRankEntry, SpellRankValue>::iterator min_itr;
|
||||
for (; RankMap.count(entry);)
|
||||
{
|
||||
for (std::multimap<SpellRankEntry, SpellRankValue>::iterator itr2 = RankMap.lower_bound(entry); itr2!=RankMap.upper_bound(entry); ++itr2)
|
||||
{
|
||||
SpellEntry const *SpellInfo=sSpellStore.LookupEntry(itr2->second.Id);
|
||||
if (SpellInfo->spellLevel<min_spell_lvl || itr2 == RankMap.lower_bound(entry))
|
||||
{
|
||||
min_spell_lvl = SpellInfo->spellLevel;
|
||||
min_itr = itr2;
|
||||
}
|
||||
}
|
||||
RankedSpells.push_back(min_itr->second.Id);
|
||||
RankMap.erase(min_itr);
|
||||
}
|
||||
|
||||
//use data from talent.dbc
|
||||
uint16 talent_id = 0;
|
||||
for (std::list<uint32>::iterator itr2 = RankedSpells.begin(); itr2 != RankedSpells.end();)
|
||||
{
|
||||
if (TalentSpellPos const *TalentPos = GetTalentSpellPos(*itr2))
|
||||
{
|
||||
talent_id = TalentPos->talent_id;
|
||||
RankedSpells.erase(itr2);
|
||||
itr2 = RankedSpells.begin();
|
||||
rankChain.push_back(std::make_pair(spell_id, rank));
|
||||
if (!result->NextRow())
|
||||
finished = true;
|
||||
}
|
||||
else
|
||||
++itr2;
|
||||
break;
|
||||
}
|
||||
if (talent_id)
|
||||
// check if chain is made with valid first spell
|
||||
SpellEntry const * first = sSpellStore.LookupEntry(lastSpell);
|
||||
if (!first)
|
||||
{
|
||||
TalentEntry const *TalentInfo = sTalentStore.LookupEntry(talent_id);
|
||||
for (uint8 rank = MAX_TALENT_RANK; rank > 0; --rank)
|
||||
if (TalentInfo->RankID[rank-1])
|
||||
RankedSpells.push_front(TalentInfo->RankID[rank-1]);
|
||||
}
|
||||
|
||||
//do not proceed for spells with less than 2 ranks
|
||||
itr = RankMap.begin();
|
||||
if (RankedSpells.size() < 2)
|
||||
sLog.outErrorDb("Spell rank identifier(first_spell_id) %u listed in `spell_ranks` does not exist!", lastSpell);
|
||||
continue;
|
||||
|
||||
++count;
|
||||
|
||||
uint32 spell_rank = 1;
|
||||
for (std::list<uint32>::iterator itr2 = RankedSpells.begin(); itr2 != RankedSpells.end(); ++spell_rank)
|
||||
}
|
||||
// check if chain is long enough
|
||||
if (rankChain.size() < 2)
|
||||
{
|
||||
uint32 spell_id = *itr2;
|
||||
mSpellChains[spell_id].rank = spell_rank;
|
||||
mSpellChains[spell_id].first = RankedSpells.front();
|
||||
mSpellChains[spell_id].last = RankedSpells.back();
|
||||
|
||||
++itr2;
|
||||
if (spell_rank<2)
|
||||
mSpellChains[spell_id].prev = 0;
|
||||
|
||||
if (spell_id == RankedSpells.back())
|
||||
mSpellChains[spell_id].next = 0;
|
||||
else
|
||||
sLog.outErrorDb("There is only 1 spell rank for identifier(first_spell_id) %u in `spell_ranks`, entry is not needed!", lastSpell);
|
||||
continue;
|
||||
}
|
||||
int32 curRank = 0;
|
||||
bool valid = true;
|
||||
// check spells in chain
|
||||
for (std::list<std::pair<int32, int32>>::iterator itr = rankChain.begin() ; itr!= rankChain.end(); ++itr)
|
||||
{
|
||||
SpellEntry const * spell = sSpellStore.LookupEntry(itr->first);
|
||||
if (!spell)
|
||||
{
|
||||
mSpellChains[*itr2].prev = spell_id;
|
||||
mSpellChains[spell_id].next = *itr2;
|
||||
sLog.outErrorDb("Spell %u (rank %u) listed in `spell_ranks` for chain %u does not exist!", itr->first, itr->second, lastSpell);
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
++curRank;
|
||||
if (itr->second != curRank)
|
||||
{
|
||||
sLog.outErrorDb("Spell %u (rank %u) listed in `spell_ranks` for chain %u does not have proper rank value(should be %u)!", itr->first, itr->second, lastSpell, curRank);
|
||||
valid = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!valid)
|
||||
continue;
|
||||
int32 prevRank = 0;
|
||||
// insert the chain
|
||||
std::list<std::pair<int32, int32>>::iterator itr = rankChain.begin();
|
||||
do
|
||||
{
|
||||
int32 addedSpell = itr->first;
|
||||
mSpellChains[addedSpell].first = lastSpell;
|
||||
mSpellChains[addedSpell].last = rankChain.back().first;
|
||||
mSpellChains[addedSpell].rank = itr->second;
|
||||
mSpellChains[addedSpell].prev = prevRank;
|
||||
prevRank = addedSpell;
|
||||
++itr;
|
||||
if (itr == rankChain.end())
|
||||
{
|
||||
mSpellChains[addedSpell].next = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
mSpellChains[addedSpell].next = itr->first;
|
||||
}
|
||||
while (true);
|
||||
|
||||
//uncomment these two lines to print yourself list of spell_chains on startup
|
||||
//for(UNORDERED_MAP<uint32, SpellChainNode>::iterator itr = mSpellChains.begin(); itr != mSpellChains.end(); ++itr)
|
||||
//sLog.outString("Id: %u, Rank: %d , %s, %u, %u, %u, %u",itr->first,itr->second.rank, sSpellStore.LookupEntry(itr->first)->Rank[sWorld.GetDefaultDbcLocale()], itr->second.first, itr->second.last,itr->second.next, itr->second.prev);
|
||||
++rows;
|
||||
} while (!finished);
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u spell chains",count);
|
||||
sLog.outString( ">> Loaded %u spell rank records", rows );
|
||||
}
|
||||
|
||||
// set data in core for now
|
||||
|
||||
+1
-1
@@ -1207,7 +1207,7 @@ class SpellMgr
|
||||
static SpellMgr& Instance();
|
||||
|
||||
// Loading data at server startup
|
||||
void LoadSpellChains();
|
||||
void LoadSpellRanks();
|
||||
void LoadSpellRequired();
|
||||
void LoadSpellLearnSkills();
|
||||
void LoadSpellLearnSpells();
|
||||
|
||||
+3
-3
@@ -1305,8 +1305,8 @@ void World::SetInitialWorldSettings()
|
||||
sLog.outString("Loading Game Object Templates..."); // must be after LoadPageTexts
|
||||
objmgr.LoadGameobjectInfo();
|
||||
|
||||
sLog.outString("Loading Spell Chain Data...");
|
||||
spellmgr.LoadSpellChains();
|
||||
sLog.outString("Loading Spell Rank Data...");
|
||||
spellmgr.LoadSpellRanks();
|
||||
|
||||
sLog.outString("Loading Spell Required Data...");
|
||||
spellmgr.LoadSpellRequired();
|
||||
@@ -1315,7 +1315,7 @@ void World::SetInitialWorldSettings()
|
||||
spellmgr.LoadSpellElixirs();
|
||||
|
||||
sLog.outString("Loading Spell Learn Skills...");
|
||||
spellmgr.LoadSpellLearnSkills(); // must be after LoadSpellChains
|
||||
spellmgr.LoadSpellLearnSkills(); // must be after LoadSpellRanks
|
||||
|
||||
sLog.outString("Loading Spell Learn Spells...");
|
||||
spellmgr.LoadSpellLearnSpells();
|
||||
|
||||
Reference in New Issue
Block a user