*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
|
int32 EffectMiscValueB[MAX_SPELL_EFFECTS]; // 119-121 m_effectMiscValueB
|
||||||
uint32 EffectTriggerSpell[MAX_SPELL_EFFECTS]; // 122-124 m_effectTriggerSpell
|
uint32 EffectTriggerSpell[MAX_SPELL_EFFECTS]; // 122-124 m_effectTriggerSpell
|
||||||
float EffectPointsPerComboPoint[MAX_SPELL_EFFECTS]; // 125-127 m_effectPointsPerCombo
|
float EffectPointsPerComboPoint[MAX_SPELL_EFFECTS]; // 125-127 m_effectPointsPerCombo
|
||||||
flag96 EffectSpellClassMask[MAX_SPELL_EFFECTS]; // 127-133
|
flag96 EffectSpellClassMask[MAX_SPELL_EFFECTS]; // 127-136
|
||||||
uint32 SpellVisual[2]; // 134-135 m_spellVisualID
|
uint32 SpellVisual[2]; // 137-138 m_spellVisualID
|
||||||
uint32 SpellIconID; // 136 m_spellIconID
|
uint32 SpellIconID; // 139 m_spellIconID
|
||||||
uint32 activeIconID; // 137 m_activeIconID
|
uint32 activeIconID; // 140 m_activeIconID
|
||||||
//uint32 spellPriority; // 138 not used
|
//uint32 spellPriority; // 141 not used
|
||||||
char* SpellName[16]; // 139-154 m_name_lang
|
char* SpellName[16]; // 142-157 m_name_lang
|
||||||
//uint32 SpellNameFlag; // 155 not used
|
//uint32 SpellNameFlag; // 158 not used
|
||||||
char* Rank[16]; // 156-171 m_nameSubtext_lang
|
char* Rank[16]; // 159-174 m_nameSubtext_lang
|
||||||
//uint32 RankFlags; // 172 not used
|
//uint32 RankFlags; // 175 not used
|
||||||
//char* Description[16]; // 173-188 m_description_lang not used
|
//char* Description[16]; // 176-191 m_description_lang not used
|
||||||
//uint32 DescriptionFlags; // 189 not used
|
//uint32 DescriptionFlags; // 192 not used
|
||||||
//char* ToolTip[16]; // 190-205 m_auraDescription_lang not used
|
//char* ToolTip[16]; // 193-208 m_auraDescription_lang not used
|
||||||
//uint32 ToolTipFlags; // 206 not used
|
//uint32 ToolTipFlags; // 209 not used
|
||||||
uint32 ManaCostPercentage; // 207 m_manaCostPct
|
uint32 ManaCostPercentage; // 210 m_manaCostPct
|
||||||
uint32 StartRecoveryCategory; // 208 m_startRecoveryCategory
|
uint32 StartRecoveryCategory; // 211 m_startRecoveryCategory
|
||||||
uint32 StartRecoveryTime; // 209 m_startRecoveryTime
|
uint32 StartRecoveryTime; // 212 m_startRecoveryTime
|
||||||
uint32 MaxTargetLevel; // 210 m_maxTargetLevel
|
uint32 MaxTargetLevel; // 213 m_maxTargetLevel
|
||||||
uint32 SpellFamilyName; // 211 m_spellClassSet
|
uint32 SpellFamilyName; // 214 m_spellClassSet
|
||||||
flag96 SpellFamilyFlags; // 212-214
|
flag96 SpellFamilyFlags; // 215-217
|
||||||
uint32 MaxAffectedTargets; // 215 m_maxTargets
|
uint32 MaxAffectedTargets; // 218 m_maxTargets
|
||||||
uint32 DmgClass; // 216 m_defenseType
|
uint32 DmgClass; // 219 m_defenseType
|
||||||
uint32 PreventionType; // 217 m_preventionType
|
uint32 PreventionType; // 220 m_preventionType
|
||||||
//uint32 StanceBarOrder; // 218 m_stanceBarOrder not used
|
//uint32 StanceBarOrder; // 221 m_stanceBarOrder not used
|
||||||
float DmgMultiplier[3]; // 219-221 m_effectChainAmplitude
|
float DmgMultiplier[3]; // 222-224 m_effectChainAmplitude
|
||||||
//uint32 MinFactionId; // 222 m_minFactionID not used
|
//uint32 MinFactionId; // 225 m_minFactionID not used
|
||||||
//uint32 MinReputation; // 223 m_minReputation not used
|
//uint32 MinReputation; // 226 m_minReputation not used
|
||||||
//uint32 RequiredAuraVision; // 224 m_requiredAuraVision not used
|
//uint32 RequiredAuraVision; // 227 m_requiredAuraVision not used
|
||||||
uint32 TotemCategory[2]; // 225-226 m_requiredTotemCategoryID
|
uint32 TotemCategory[2]; // 228-229 m_requiredTotemCategoryID
|
||||||
int32 AreaGroupId; // 227 m_requiredAreaGroupId
|
int32 AreaGroupId; // 230 m_requiredAreaGroupId
|
||||||
uint32 SchoolMask; // 228 m_schoolMask
|
uint32 SchoolMask; // 231 m_schoolMask
|
||||||
uint32 runeCostID; // 229 m_runeCostID
|
uint32 runeCostID; // 232 m_runeCostID
|
||||||
//uint32 spellMissileID; // 230 m_spellMissileID not used
|
//uint32 spellMissileID; // 233 m_spellMissileID not used
|
||||||
//uint32 PowerDisplayId; // 231 PowerDisplay.dbc, new in 3.1
|
//uint32 PowerDisplayId; // 234 PowerDisplay.dbc, new in 3.1
|
||||||
//float unk_320_4[3]; // 232-234 3.2.0
|
//float unk_320_4[3]; // 235-237 3.2.0
|
||||||
//uint32 spellDescriptionVariableID; // 235 3.2.0
|
//uint32 spellDescriptionVariableID; // 238 3.2.0
|
||||||
|
|
||||||
// helpers
|
// helpers
|
||||||
int32 CalculateSimpleValue(uint8 eff) const { return EffectBasePoints[eff]+int32(EffectBaseDice[eff]); }
|
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 );
|
sLog.outString( ">> Loaded %u spell required records", rows );
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SpellRankEntry
|
void SpellMgr::LoadSpellRanks()
|
||||||
{
|
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
mSpellChains.clear(); // need for reload case
|
mSpellChains.clear(); // need for reload case
|
||||||
|
|
||||||
std::vector<uint32> ChainedSpells;
|
QueryResult_AutoPtr result = WorldDatabase.Query("SELECT first_spell_id, spell_id, rank from spell_ranks ORDER BY first_spell_id , rank");
|
||||||
for (uint32 ability_id = 0; ability_id < sSkillLineAbilityStore.GetNumRows(); ++ability_id)
|
|
||||||
|
if (!result)
|
||||||
{
|
{
|
||||||
SkillLineAbilityEntry const *AbilityInfo=sSkillLineAbilityStore.LookupEntry(ability_id);
|
barGoLink bar(1);
|
||||||
if (!AbilityInfo)
|
bar.step();
|
||||||
continue;
|
|
||||||
if (!AbilityInfo->forward_spellid)
|
sLog.outString();
|
||||||
continue;
|
sLog.outString(">> Loaded 0 spell rank records");
|
||||||
ChainedSpells.push_back(AbilityInfo->forward_spellid);
|
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);
|
// spellid, rank
|
||||||
if (!AbilityInfo)
|
std::list<std::pair<int32, int32>> rankChain;
|
||||||
continue;
|
int32 currentSpell = -1;
|
||||||
|
int32 lastSpell = -1;
|
||||||
//get only spell with lowest ability_id to prevent doubles
|
|
||||||
uint32 spell_id = AbilityInfo->spellId;
|
// fill one chain
|
||||||
bool found = false;
|
while(currentSpell == lastSpell && !finished)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
bar.step();
|
bar.step();
|
||||||
RankErrorMap.insert(std::pair<char const *, std::multimap<SpellRankEntry, SpellRankValue>::iterator>(itr2->second.Rank,itr2));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool error = false;
|
Field *fields = result->Fetch();
|
||||||
//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;
|
|
||||||
|
|
||||||
//compare effects and casting time
|
currentSpell = fields[0].GetUInt32();
|
||||||
currEntry.CastingTimeIndex = SpellInfo->CastingTimeIndex;
|
if (lastSpell == -1)
|
||||||
currEntry.Effect[0] = SpellInfo->Effect[0];
|
lastSpell = currentSpell;
|
||||||
currEntry.Effect[1] = SpellInfo->Effect[1];
|
uint32 spell_id = fields[1].GetUInt32();
|
||||||
currEntry.Effect[2] = SpellInfo->Effect[2];
|
uint32 rank = fields[2].GetUInt32();
|
||||||
|
|
||||||
currEntry.Aura[0] = SpellInfo->EffectApplyAuraName[0];
|
// don't drop the row if we're moving to the next rank
|
||||||
currEntry.Aura[1] = SpellInfo->EffectApplyAuraName[1];
|
if (currentSpell == lastSpell)
|
||||||
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();)
|
|
||||||
{
|
{
|
||||||
char const *err_entry = itr2->first;
|
rankChain.push_back(std::make_pair(spell_id, rank));
|
||||||
uint32 rank_count = RankErrorMap.count(itr2->first);
|
if (!result->NextRow())
|
||||||
if (rank_count > 1)
|
finished = true;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
else
|
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);
|
sLog.outErrorDb("Spell rank identifier(first_spell_id) %u listed in `spell_ranks` does not exist!", lastSpell);
|
||||||
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)
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
++count;
|
// check if chain is long enough
|
||||||
|
if (rankChain.size() < 2)
|
||||||
uint32 spell_rank = 1;
|
|
||||||
for (std::list<uint32>::iterator itr2 = RankedSpells.begin(); itr2 != RankedSpells.end(); ++spell_rank)
|
|
||||||
{
|
{
|
||||||
uint32 spell_id = *itr2;
|
sLog.outErrorDb("There is only 1 spell rank for identifier(first_spell_id) %u in `spell_ranks`, entry is not needed!", lastSpell);
|
||||||
mSpellChains[spell_id].rank = spell_rank;
|
continue;
|
||||||
mSpellChains[spell_id].first = RankedSpells.front();
|
}
|
||||||
mSpellChains[spell_id].last = RankedSpells.back();
|
int32 curRank = 0;
|
||||||
|
bool valid = true;
|
||||||
++itr2;
|
// check spells in chain
|
||||||
if (spell_rank<2)
|
for (std::list<std::pair<int32, int32>>::iterator itr = rankChain.begin() ; itr!= rankChain.end(); ++itr)
|
||||||
mSpellChains[spell_id].prev = 0;
|
{
|
||||||
|
SpellEntry const * spell = sSpellStore.LookupEntry(itr->first);
|
||||||
if (spell_id == RankedSpells.back())
|
if (!spell)
|
||||||
mSpellChains[spell_id].next = 0;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
mSpellChains[*itr2].prev = spell_id;
|
sLog.outErrorDb("Spell %u (rank %u) listed in `spell_ranks` for chain %u does not exist!", itr->first, itr->second, lastSpell);
|
||||||
mSpellChains[spell_id].next = *itr2;
|
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
|
++rows;
|
||||||
//for(UNORDERED_MAP<uint32, SpellChainNode>::iterator itr = mSpellChains.begin(); itr != mSpellChains.end(); ++itr)
|
} while (!finished);
|
||||||
//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);
|
|
||||||
|
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
sLog.outString(">> Loaded %u spell chains",count);
|
sLog.outString( ">> Loaded %u spell rank records", rows );
|
||||||
}
|
}
|
||||||
|
|
||||||
// set data in core for now
|
// set data in core for now
|
||||||
|
|||||||
+1
-1
@@ -1207,7 +1207,7 @@ class SpellMgr
|
|||||||
static SpellMgr& Instance();
|
static SpellMgr& Instance();
|
||||||
|
|
||||||
// Loading data at server startup
|
// Loading data at server startup
|
||||||
void LoadSpellChains();
|
void LoadSpellRanks();
|
||||||
void LoadSpellRequired();
|
void LoadSpellRequired();
|
||||||
void LoadSpellLearnSkills();
|
void LoadSpellLearnSkills();
|
||||||
void LoadSpellLearnSpells();
|
void LoadSpellLearnSpells();
|
||||||
|
|||||||
+3
-3
@@ -1305,8 +1305,8 @@ void World::SetInitialWorldSettings()
|
|||||||
sLog.outString("Loading Game Object Templates..."); // must be after LoadPageTexts
|
sLog.outString("Loading Game Object Templates..."); // must be after LoadPageTexts
|
||||||
objmgr.LoadGameobjectInfo();
|
objmgr.LoadGameobjectInfo();
|
||||||
|
|
||||||
sLog.outString("Loading Spell Chain Data...");
|
sLog.outString("Loading Spell Rank Data...");
|
||||||
spellmgr.LoadSpellChains();
|
spellmgr.LoadSpellRanks();
|
||||||
|
|
||||||
sLog.outString("Loading Spell Required Data...");
|
sLog.outString("Loading Spell Required Data...");
|
||||||
spellmgr.LoadSpellRequired();
|
spellmgr.LoadSpellRequired();
|
||||||
@@ -1315,7 +1315,7 @@ void World::SetInitialWorldSettings()
|
|||||||
spellmgr.LoadSpellElixirs();
|
spellmgr.LoadSpellElixirs();
|
||||||
|
|
||||||
sLog.outString("Loading Spell Learn Skills...");
|
sLog.outString("Loading Spell Learn Skills...");
|
||||||
spellmgr.LoadSpellLearnSkills(); // must be after LoadSpellChains
|
spellmgr.LoadSpellLearnSkills(); // must be after LoadSpellRanks
|
||||||
|
|
||||||
sLog.outString("Loading Spell Learn Spells...");
|
sLog.outString("Loading Spell Learn Spells...");
|
||||||
spellmgr.LoadSpellLearnSpells();
|
spellmgr.LoadSpellLearnSpells();
|
||||||
|
|||||||
Reference in New Issue
Block a user