[10867] Implement templates for trainer spell data in npc_trainer_template.

New table let avoid duplication similar trainer spells for different trainers.
This commit is contained in:
VladimirMangos 2010-12-13 15:10:16 +03:00
parent f228a1c08d
commit 1d8f222621
15 changed files with 229 additions and 77 deletions

View file

@ -8825,29 +8825,31 @@ void ObjectMgr::LoadMailLevelRewards()
sLog.outString( ">> Loaded %u level dependent mail rewards,", count );
}
void ObjectMgr::LoadTrainerSpell()
void ObjectMgr::LoadTrainers(char const* tableName, bool isTemplates)
{
CacheTrainerSpellMap& trainerList = isTemplates ? m_mCacheTrainerTemplateSpellMap : m_mCacheTrainerSpellMap;
// For reload case
for (CacheTrainerSpellMap::iterator itr = m_mCacheTrainerSpellMap.begin(); itr != m_mCacheTrainerSpellMap.end(); ++itr)
for (CacheTrainerSpellMap::iterator itr = trainerList.begin(); itr != trainerList.end(); ++itr)
itr->second.Clear();
m_mCacheTrainerSpellMap.clear();
trainerList.clear();
std::set<uint32> skip_trainers;
QueryResult *result = WorldDatabase.Query("SELECT entry, spell,spellcost,reqskill,reqskillvalue,reqlevel FROM npc_trainer");
QueryResult *result = WorldDatabase.PQuery("SELECT entry, spell,spellcost,reqskill,reqskillvalue,reqlevel FROM %s", tableName);
if( !result )
if (!result)
{
barGoLink bar( 1 );
barGoLink bar(1);
bar.step();
sLog.outString();
sLog.outErrorDb(">> Loaded `npc_trainer`, table is empty!");
sLog.outErrorDb(">> Loaded `%s`, table is empty!", tableName);
return;
}
barGoLink bar( (int)result->GetRowCount() );
barGoLink bar((int)result->GetRowCount());
std::set<uint32> talentIds;
@ -8861,48 +8863,60 @@ void ObjectMgr::LoadTrainerSpell()
uint32 entry = fields[0].GetUInt32();
uint32 spell = fields[1].GetUInt32();
CreatureInfo const* cInfo = GetCreatureTemplate(entry);
if(!cInfo)
{
sLog.outErrorDb("Table `npc_trainer` have entry for nonexistent creature template (Entry: %u), ignore", entry);
continue;
}
if(!(cInfo->npcflag & UNIT_NPC_FLAG_TRAINER))
{
if (skip_trainers.find(entry) == skip_trainers.end())
{
sLog.outErrorDb("Table `npc_trainer` have data for creature (Entry: %u) without trainer flag, ignore", entry);
skip_trainers.insert(entry);
}
continue;
}
SpellEntry const *spellinfo = sSpellStore.LookupEntry(spell);
if(!spellinfo)
if (!spellinfo)
{
sLog.outErrorDb("Table `npc_trainer` for Trainer (Entry: %u ) has non existing spell %u, ignore", entry,spell);
sLog.outErrorDb("Table `%s` for trainer (Entry: %u ) has non existing spell %u, ignore", tableName, entry, spell);
continue;
}
if(!SpellMgr::IsSpellValid(spellinfo))
if (!SpellMgr::IsSpellValid(spellinfo))
{
sLog.outErrorDb("Table `npc_trainer` for Trainer (Entry: %u) has broken learning spell %u, ignore", entry, spell);
sLog.outErrorDb("Table `%s` for trainer (Entry: %u) has broken learning spell %u, ignore", tableName, entry, spell);
continue;
}
if(GetTalentSpellCost(spell))
if (GetTalentSpellCost(spell))
{
if (talentIds.find(spell) == talentIds.end())
{
sLog.outErrorDb("Table `npc_trainer` has talent as learning spell %u, ignore", spell);
sLog.outErrorDb("Table `%s` has talent as learning spell %u, ignore", tableName, spell);
talentIds.insert(spell);
}
continue;
}
TrainerSpellData& data = m_mCacheTrainerSpellMap[entry];
if (!isTemplates)
{
CreatureInfo const* cInfo = GetCreatureTemplate(entry);
if (!cInfo)
{
sLog.outErrorDb("Table `%s` have entry for nonexistent creature template (Entry: %u), ignore", tableName, entry);
continue;
}
if (!(cInfo->npcflag & UNIT_NPC_FLAG_TRAINER))
{
if (skip_trainers.find(entry) == skip_trainers.end())
{
sLog.outErrorDb("Table `%s` have data for creature (Entry: %u) without trainer flag, ignore", tableName, entry);
skip_trainers.insert(entry);
}
continue;
}
if (TrainerSpellData const* tSpells = cInfo->trainerId ? GetNpcTrainerTemplateSpells(cInfo->trainerId) : NULL)
{
if (tSpells->spellList.find(spell) != tSpells->spellList.end())
{
sLog.outErrorDb("Table `%s` for trainer (Entry: %u) has spell %u listed in trainer template %u, ignore", tableName, entry, spell);
continue;
}
}
}
TrainerSpellData& data = trainerList[entry];
TrainerSpell& trainerSpell = data.spellList[spell];
trainerSpell.spell = spell;
@ -8927,7 +8941,7 @@ void ObjectMgr::LoadTrainerSpell()
}
}
if(SpellMgr::IsProfessionSpell(trainerSpell.learnedSpell))
if (SpellMgr::IsProfessionSpell(trainerSpell.learnedSpell))
data.trainerType = 2;
++count;
@ -8936,7 +8950,35 @@ void ObjectMgr::LoadTrainerSpell()
delete result;
sLog.outString();
sLog.outString( ">> Loaded %d Trainers", count );
sLog.outString( ">> Loaded %d trainer %sspells", count, isTemplates ? "template " : "" );
}
void ObjectMgr::LoadTrainerTemplates()
{
LoadTrainers("npc_trainer_template", true);
// post loading check
std::set<uint32> trainer_ids;
for(CacheTrainerSpellMap::const_iterator tItr = m_mCacheTrainerTemplateSpellMap.begin(); tItr != m_mCacheTrainerTemplateSpellMap.end(); ++tItr)
trainer_ids.insert(tItr->first);
for(uint32 i = 1; i < sCreatureStorage.MaxEntry; ++i)
{
if (CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(i))
{
if (cInfo->trainerId)
{
if (trainer_ids.count(cInfo->trainerId) > 0)
trainer_ids.erase(cInfo->trainerId);
else
sLog.outErrorDb("Creature (Entry: %u) has trainer_id = %u for nonexistent trainer template", cInfo->Entry, cInfo->trainerId);
}
}
}
for(std::set<uint32>::const_iterator tItr = trainer_ids.begin(); tItr != trainer_ids.end(); ++tItr)
sLog.outErrorDb("Table `npc_trainer_template` has trainer template %u not used by any trainers ", *tItr);
}
void ObjectMgr::LoadVendors(char const* tableName, bool isTemplates)
@ -8988,7 +9030,7 @@ void ObjectMgr::LoadVendors(char const* tableName, bool isTemplates)
delete result;
sLog.outString();
sLog.outString( ">> Loaded %u vendor items", count);
sLog.outString( ">> Loaded %u vendor %sitems", count, isTemplates ? "template " : "");
}