mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
[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:
parent
f228a1c08d
commit
1d8f222621
15 changed files with 229 additions and 77 deletions
|
|
@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
|
|||
`version` varchar(120) default NULL,
|
||||
`creature_ai_version` varchar(120) default NULL,
|
||||
`cache_id` int(10) default '0',
|
||||
`required_10864_01_mangos_spell_proc_event` bit(1) default NULL
|
||||
`required_10867_02_mangos_creature_template` bit(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||
|
||||
--
|
||||
|
|
@ -1252,6 +1252,7 @@ CREATE TABLE `creature_template` (
|
|||
`movementId` int(11) UNSIGNED DEFAULT '0' NOT NULL,
|
||||
`RegenHealth` tinyint(3) unsigned NOT NULL default '1',
|
||||
`equipment_id` mediumint(8) unsigned NOT NULL default '0',
|
||||
`trainer_id` mediumint(8) unsigned NOT NULL default '0',
|
||||
`vendor_id` mediumint(8) unsigned NOT NULL default '0',
|
||||
`mechanic_immune_mask` int(10) unsigned NOT NULL default '0',
|
||||
`flags_extra` int(10) unsigned NOT NULL default '0',
|
||||
|
|
@ -3990,6 +3991,30 @@ LOCK TABLES `npc_trainer` WRITE;
|
|||
/*!40000 ALTER TABLE `npc_trainer` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `npc_trainer_template`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `npc_trainer_template`;
|
||||
CREATE TABLE `npc_trainer_template` (
|
||||
`entry` mediumint(8) unsigned NOT NULL default '0',
|
||||
`spell` mediumint(8) unsigned NOT NULL default '0',
|
||||
`spellcost` int(10) unsigned NOT NULL default '0',
|
||||
`reqskill` smallint(5) unsigned NOT NULL default '0',
|
||||
`reqskillvalue` smallint(5) unsigned NOT NULL default '0',
|
||||
`reqlevel` tinyint(3) unsigned NOT NULL default '0',
|
||||
UNIQUE KEY `entry_spell` (`entry`,`spell`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Dumping data for table `npc_trainer_template`
|
||||
--
|
||||
|
||||
LOCK TABLES `npc_trainer` WRITE;
|
||||
/*!40000 ALTER TABLE `npc_trainer_template` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `npc_trainer_template` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `npc_vendor`
|
||||
--
|
||||
|
|
|
|||
12
sql/updates/10867_01_mangos_npc_trainer_template.sql
Normal file
12
sql/updates/10867_01_mangos_npc_trainer_template.sql
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_10864_01_mangos_spell_proc_event required_10867_01_mangos_npc_trainer_template bit;
|
||||
|
||||
DROP TABLE IF EXISTS `npc_trainer_template`;
|
||||
CREATE TABLE `npc_trainer_template` (
|
||||
`entry` mediumint(8) unsigned NOT NULL default '0',
|
||||
`spell` mediumint(8) unsigned NOT NULL default '0',
|
||||
`spellcost` int(10) unsigned NOT NULL default '0',
|
||||
`reqskill` smallint(5) unsigned NOT NULL default '0',
|
||||
`reqskillvalue` smallint(5) unsigned NOT NULL default '0',
|
||||
`reqlevel` tinyint(3) unsigned NOT NULL default '0',
|
||||
UNIQUE KEY `entry_spell` (`entry`,`spell`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
4
sql/updates/10867_02_mangos_creature_template.sql
Normal file
4
sql/updates/10867_02_mangos_creature_template.sql
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_10867_01_mangos_npc_trainer_template required_10867_02_mangos_creature_template bit;
|
||||
|
||||
ALTER TABLE creature_template
|
||||
ADD COLUMN trainer_id mediumint(8) unsigned NOT NULL default '0' AFTER equipment_id;
|
||||
|
|
@ -133,6 +133,8 @@ pkgdata_DATA = \
|
|||
10862_01_characters_mail.sql \
|
||||
10863_01_mangos_spell_proc_event.sql \
|
||||
10864_01_mangos_spell_proc_event.sql \
|
||||
10867_01_mangos_npc_trainer_template.sql \
|
||||
10867_02_mangos_creature_template.sql \
|
||||
README
|
||||
|
||||
## Additional files to include when running 'make dist'
|
||||
|
|
@ -246,4 +248,6 @@ EXTRA_DIST = \
|
|||
10862_01_characters_mail.sql \
|
||||
10863_01_mangos_spell_proc_event.sql \
|
||||
10864_01_mangos_spell_proc_event.sql \
|
||||
10867_01_mangos_npc_trainer_template.sql \
|
||||
10867_02_mangos_creature_template.sql \
|
||||
README
|
||||
|
|
|
|||
|
|
@ -730,10 +730,11 @@ bool Creature::IsTrainerOf(Player* pPlayer, bool msg) const
|
|||
// pet trainers not have spells in fact now
|
||||
if (GetCreatureInfo()->trainer_type != TRAINER_TYPE_PETS)
|
||||
{
|
||||
TrainerSpellData const* trainer_spells = GetTrainerSpells();
|
||||
TrainerSpellData const* cSpells = GetTrainerSpells();
|
||||
TrainerSpellData const* tSpells = GetTrainerTemplateSpells();
|
||||
|
||||
// for not pet trainer expected not empty trainer list always
|
||||
if (!trainer_spells || trainer_spells->spellList.empty())
|
||||
if ((!cSpells || cSpells->spellList.empty()) && (!tSpells || tSpells->spellList.empty()))
|
||||
{
|
||||
sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_TRAINER but have empty trainer spell list.",
|
||||
GetGUIDLow(),GetEntry());
|
||||
|
|
@ -2181,7 +2182,8 @@ VendorItemData const* Creature::GetVendorItems() const
|
|||
|
||||
VendorItemData const* Creature::GetVendorTemplateItems() const
|
||||
{
|
||||
return GetCreatureInfo()->vendorId ? sObjectMgr.GetNpcVendorItemList(GetCreatureInfo()->vendorId) : NULL;
|
||||
uint32 vendorId = GetCreatureInfo()->vendorId;
|
||||
return vendorId ? sObjectMgr.GetNpcVendorItemList(vendorId) : NULL;
|
||||
}
|
||||
|
||||
uint32 Creature::GetVendorItemCurrentCount(VendorItem const* vItem)
|
||||
|
|
@ -2256,6 +2258,12 @@ uint32 Creature::UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 us
|
|||
return vCount->count;
|
||||
}
|
||||
|
||||
TrainerSpellData const* Creature::GetTrainerTemplateSpells() const
|
||||
{
|
||||
uint32 trainerId = GetCreatureInfo()->trainerId;
|
||||
return trainerId ? sObjectMgr.GetNpcTrainerTemplateSpells(trainerId) : NULL;
|
||||
}
|
||||
|
||||
TrainerSpellData const* Creature::GetTrainerSpells() const
|
||||
{
|
||||
return sObjectMgr.GetNpcTrainerSpells(GetEntry());
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ struct CreatureInfo
|
|||
uint32 movementId;
|
||||
bool RegenHealth;
|
||||
uint32 equipmentId;
|
||||
uint32 trainerId;
|
||||
uint32 vendorId;
|
||||
uint32 MechanicImmuneMask;
|
||||
uint32 flags_extra;
|
||||
|
|
@ -515,6 +516,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
|||
uint32 GetVendorItemCurrentCount(VendorItem const* vItem);
|
||||
uint32 UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 used_count);
|
||||
|
||||
TrainerSpellData const* GetTrainerTemplateSpells() const;
|
||||
TrainerSpellData const* GetTrainerSpells() const;
|
||||
|
||||
CreatureInfo const *GetCreatureInfo() const { return m_creatureInfo; }
|
||||
|
|
|
|||
|
|
@ -467,8 +467,12 @@ bool ChatHandler::HandleReloadNpcGossipCommand(char* /*args*/)
|
|||
|
||||
bool ChatHandler::HandleReloadNpcTrainerCommand(char* /*args*/)
|
||||
{
|
||||
sLog.outString( "Re-Loading `npc_trainer_template` Table!" );
|
||||
sObjectMgr.LoadTrainerTemplates();
|
||||
SendGlobalSysMessage("DB table `npc_trainer_template` reloaded.");
|
||||
|
||||
sLog.outString( "Re-Loading `npc_trainer` Table!" );
|
||||
sObjectMgr.LoadTrainerSpell();
|
||||
sObjectMgr.LoadTrainers();
|
||||
SendGlobalSysMessage("DB table `npc_trainer` reloaded.");
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,27 @@ void WorldSession::SendTrainerList(ObjectGuid guid)
|
|||
SendTrainerList(guid, str);
|
||||
}
|
||||
|
||||
|
||||
static void SendTrainerSpellHelper(WorldPacket& data, TrainerSpell const* tSpell, TrainerSpellState state, float fDiscountMod, bool can_learn_primary_prof)
|
||||
{
|
||||
bool primary_prof_first_rank = sSpellMgr.IsPrimaryProfessionFirstRankSpell(tSpell->learnedSpell);
|
||||
SpellChainNode const* chain_node = sSpellMgr.GetSpellChainNode(tSpell->learnedSpell);
|
||||
|
||||
data << uint32(tSpell->spell); // learned spell (or cast-spell in profession case)
|
||||
data << uint8(state==TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state);
|
||||
data << uint32(floor(tSpell->spellCost * fDiscountMod));
|
||||
|
||||
data << uint32(primary_prof_first_rank && can_learn_primary_prof ? 1 : 0);
|
||||
// primary prof. learn confirmation dialog
|
||||
data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state
|
||||
data << uint8(tSpell->reqLevel);
|
||||
data << uint32(tSpell->reqSkill);
|
||||
data << uint32(tSpell->reqSkillValue);
|
||||
data << uint32(!tSpell->IsCastable() && chain_node ? (chain_node->prev ? chain_node->prev : chain_node->req) : 0);
|
||||
data << uint32(!tSpell->IsCastable() && chain_node && chain_node->prev ? chain_node->req : 0);
|
||||
data << uint32(0);
|
||||
}
|
||||
|
||||
void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle)
|
||||
{
|
||||
DEBUG_LOG( "WORLD: SendTrainerList" );
|
||||
|
|
@ -134,57 +155,68 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle)
|
|||
if (!ci)
|
||||
return;
|
||||
|
||||
TrainerSpellData const* trainer_spells = unit->GetTrainerSpells();
|
||||
if (!trainer_spells)
|
||||
TrainerSpellData const* cSpells = unit->GetTrainerSpells();
|
||||
TrainerSpellData const* tSpells = unit->GetTrainerTemplateSpells();
|
||||
|
||||
if (!cSpells && !tSpells)
|
||||
{
|
||||
DEBUG_LOG("WORLD: SendTrainerList - Training spells not found for %s", guid.GetString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
WorldPacket data( SMSG_TRAINER_LIST, 8+4+4+trainer_spells->spellList.size()*38 + strTitle.size()+1);
|
||||
uint32 maxcount = (cSpells ? cSpells->spellList.size() : 0) + (tSpells ? tSpells->spellList.size() : 0);
|
||||
|
||||
WorldPacket data( SMSG_TRAINER_LIST, 8+4+4+maxcount*38 + strTitle.size()+1);
|
||||
data << ObjectGuid(guid);
|
||||
data << uint32(trainer_spells->trainerType);
|
||||
data << uint32(cSpells->trainerType ? cSpells->trainerType : tSpells->trainerType);
|
||||
|
||||
size_t count_pos = data.wpos();
|
||||
data << uint32(trainer_spells->spellList.size());
|
||||
data << uint32(maxcount);
|
||||
|
||||
// reputation discount
|
||||
float fDiscountMod = _player->GetReputationPriceDiscount(unit);
|
||||
bool can_learn_primary_prof = GetPlayer()->GetFreePrimaryProfessionPoints() > 0;
|
||||
|
||||
uint32 count = 0;
|
||||
for(TrainerSpellMap::const_iterator itr = trainer_spells->spellList.begin(); itr != trainer_spells->spellList.end(); ++itr)
|
||||
|
||||
if (cSpells)
|
||||
{
|
||||
for(TrainerSpellMap::const_iterator itr = cSpells->spellList.begin(); itr != cSpells->spellList.end(); ++itr)
|
||||
{
|
||||
TrainerSpell const* tSpell = &itr->second;
|
||||
|
||||
if(!_player->IsSpellFitByClassAndRace(tSpell->learnedSpell))
|
||||
continue;
|
||||
|
||||
bool primary_prof_first_rank = sSpellMgr.IsPrimaryProfessionFirstRankSpell(tSpell->learnedSpell);
|
||||
SpellChainNode const* chain_node = sSpellMgr.GetSpellChainNode(tSpell->learnedSpell);
|
||||
TrainerSpellState state = _player->GetTrainerSpellState(tSpell);
|
||||
|
||||
data << uint32(tSpell->spell); // learned spell (or cast-spell in profession case)
|
||||
data << uint8(state==TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state);
|
||||
data << uint32(floor(tSpell->spellCost * fDiscountMod));
|
||||
|
||||
data << uint32(primary_prof_first_rank && can_learn_primary_prof ? 1 : 0);
|
||||
// primary prof. learn confirmation dialog
|
||||
data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state
|
||||
data << uint8(tSpell->reqLevel);
|
||||
data << uint32(tSpell->reqSkill);
|
||||
data << uint32(tSpell->reqSkillValue);
|
||||
data << uint32(!tSpell->IsCastable() && chain_node ? (chain_node->prev ? chain_node->prev : chain_node->req) : 0);
|
||||
data << uint32(!tSpell->IsCastable() && chain_node && chain_node->prev ? chain_node->req : 0);
|
||||
data << uint32(0);
|
||||
SendTrainerSpellHelper(data, tSpell, state, fDiscountMod, can_learn_primary_prof);
|
||||
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
if (tSpells)
|
||||
{
|
||||
for(TrainerSpellMap::const_iterator itr = tSpells->spellList.begin(); itr != tSpells->spellList.end(); ++itr)
|
||||
{
|
||||
TrainerSpell const* tSpell = &itr->second;
|
||||
|
||||
if(!_player->IsSpellFitByClassAndRace(tSpell->learnedSpell))
|
||||
continue;
|
||||
|
||||
TrainerSpellState state = _player->GetTrainerSpellState(tSpell);
|
||||
|
||||
SendTrainerSpellHelper(data, tSpell, state, fDiscountMod, can_learn_primary_prof);
|
||||
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
data << strTitle;
|
||||
|
||||
data.put<uint32>(count_pos,count);
|
||||
SendPacket( &data );
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data )
|
||||
|
|
@ -210,12 +242,17 @@ void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data )
|
|||
return;
|
||||
|
||||
// check present spell in trainer spell list
|
||||
TrainerSpellData const* trainer_spells = unit->GetTrainerSpells();
|
||||
if (!trainer_spells)
|
||||
TrainerSpellData const* cSpells = unit->GetTrainerSpells();
|
||||
TrainerSpellData const* tSpells = unit->GetTrainerTemplateSpells();
|
||||
|
||||
if (!cSpells && !tSpells)
|
||||
return;
|
||||
|
||||
// not found, cheat?
|
||||
TrainerSpell const* trainer_spell = trainer_spells->Find(spellId);
|
||||
TrainerSpell const* trainer_spell = cSpells->Find(spellId);
|
||||
if (!trainer_spell)
|
||||
trainer_spell = tSpells->Find(spellId);
|
||||
|
||||
if (!trainer_spell)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 " : "");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -972,7 +972,8 @@ class ObjectMgr
|
|||
|
||||
void LoadVendorTemplates();
|
||||
void LoadVendors() { LoadVendors("npc_vendor", false); }
|
||||
void LoadTrainerSpell();
|
||||
void LoadTrainerTemplates();
|
||||
void LoadTrainers() { LoadTrainers("npc_trainer", false); }
|
||||
|
||||
std::string GeneratePetName(uint32 entry);
|
||||
uint32 GetBaseXP(uint32 level) const;
|
||||
|
|
@ -1209,6 +1210,15 @@ class ObjectMgr
|
|||
return &iter->second;
|
||||
}
|
||||
|
||||
TrainerSpellData const* GetNpcTrainerTemplateSpells(uint32 entry) const
|
||||
{
|
||||
CacheTrainerSpellMap::const_iterator iter = m_mCacheTrainerTemplateSpellMap.find(entry);
|
||||
if(iter == m_mCacheTrainerTemplateSpellMap.end())
|
||||
return NULL;
|
||||
|
||||
return &iter->second;
|
||||
}
|
||||
|
||||
VendorItemData const* GetNpcVendorItemList(uint32 entry) const
|
||||
{
|
||||
CacheVendorItemMap::const_iterator iter = m_mCacheVendorItemMap.find(entry);
|
||||
|
|
@ -1384,6 +1394,7 @@ class ObjectMgr
|
|||
void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr);
|
||||
void LoadQuestRelationsHelper(QuestRelationsMap& map, char const* table);
|
||||
void LoadVendors(char const* tableName, bool isTemplates);
|
||||
void LoadTrainers(char const* tableName, bool isTemplates);
|
||||
|
||||
MailLevelRewardMap m_mailLevelRewardMap;
|
||||
|
||||
|
|
@ -1433,6 +1444,7 @@ class ObjectMgr
|
|||
CacheNpcTextIdMap m_mCacheNpcTextIdMap;
|
||||
CacheVendorItemMap m_mCacheVendorTemplateItemMap;
|
||||
CacheVendorItemMap m_mCacheVendorItemMap;
|
||||
CacheTrainerSpellMap m_mCacheTrainerTemplateSpellMap;
|
||||
CacheTrainerSpellMap m_mCacheTrainerSpellMap;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@
|
|||
#include "Database/SQLStorageImpl.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
|
||||
const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiiis";
|
||||
const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiiii";
|
||||
const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiiiis";
|
||||
const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiiiii";
|
||||
const char CreatureDataAddonInfofmt[]="iiilliis";
|
||||
const char CreatureModelfmt[]="iffbii";
|
||||
const char CreatureInfoAddonInfofmt[]="iiilliis";
|
||||
|
|
|
|||
|
|
@ -1166,7 +1166,8 @@ void World::SetInitialWorldSettings()
|
|||
sObjectMgr.LoadVendors(); // must be after load CreatureTemplate, VendorTemplate, and ItemTemplate
|
||||
|
||||
sLog.outString( "Loading Trainers..." );
|
||||
sObjectMgr.LoadTrainerSpell(); // must be after load CreatureTemplate
|
||||
sObjectMgr.LoadTrainerTemplates(); // must be after load CreatureTemplate
|
||||
sObjectMgr.LoadTrainers(); // must be after load CreatureTemplate, TrainerTemplate
|
||||
|
||||
sLog.outString( "Loading Waypoint scripts..." ); // before loading from creature_movement
|
||||
sObjectMgr.LoadCreatureMovementScripts();
|
||||
|
|
|
|||
|
|
@ -253,6 +253,7 @@ class MANGOS_DLL_SPEC WorldSession
|
|||
|
||||
void SendTrainerList(ObjectGuid guid);
|
||||
void SendTrainerList(ObjectGuid guid, const std::string& strTitle );
|
||||
|
||||
void SendListInventory(ObjectGuid guid);
|
||||
bool CheckBanker(ObjectGuid guid);
|
||||
void SendShowBank(ObjectGuid guid);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "10866"
|
||||
#define REVISION_NR "10867"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef __REVISION_SQL_H__
|
||||
#define __REVISION_SQL_H__
|
||||
#define REVISION_DB_CHARACTERS "required_10862_01_characters_mail"
|
||||
#define REVISION_DB_MANGOS "required_10864_01_mangos_spell_proc_event"
|
||||
#define REVISION_DB_MANGOS "required_10867_02_mangos_creature_template"
|
||||
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
|
||||
#endif // __REVISION_SQL_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue