[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

@ -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`
--

View 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;

View 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;

View file

@ -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

View file

@ -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());

View file

@ -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; }

View file

@ -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;
}

View file

@ -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;

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 " : "");
}

View file

@ -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;
};

View file

@ -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";

View file

@ -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();

View file

@ -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);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "10866"
#define REVISION_NR "10867"
#endif // __REVISION_NR_H__

View file

@ -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__