Load npc_options at server startup, use cached data at creature gossip menu init.

Also new .reload table command added. Note: currently it will not affect creatures that have gossim memu created at command use moment.
This commit is contained in:
VladimirMangos 2008-10-27 16:43:31 +03:00
parent e96fedc97c
commit 9e6390d88d
8 changed files with 77 additions and 31 deletions

View file

@ -228,6 +228,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "item_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL },
{ "mangos_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadMangosStringCommand, "", NULL },
{ "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL },
{ "npc_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcOptionCommand, "", NULL },
{ "npc_trainer", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL },
{ "npc_vendor", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcVendorCommand, "", NULL },
{ "page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPageTextsCommand, "", NULL },

View file

@ -183,6 +183,7 @@ class ChatHandler
bool HandleReloadLootTemplatesSkinningCommand(const char* args);
bool HandleReloadMangosStringCommand(const char* args);
bool HandleReloadNpcGossipCommand(const char* args);
bool HandleReloadNpcOptionCommand(const char* args);
bool HandleReloadNpcTrainerCommand(const char* args);
bool HandleReloadNpcVendorCommand(const char* args);
bool HandleReloadQuestAreaTriggersCommand(const char* args);

View file

@ -668,12 +668,9 @@ void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid )
// lazy loading single time at use
LoadGossipOptions();
GossipOption* gso;
GossipOption* ingso;
for( GossipOptionList::iterator i = m_goptions.begin( ); i != m_goptions.end( ); i++ )
{
gso=&*i;
GossipOption* gso=&*i;
if(gso->GossipId == gossipid)
{
bool cantalking=true;
@ -746,11 +743,9 @@ void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid )
}
}
if(!gso->Option.empty() && cantalking )
{ //note for future dev: should have database fields for BoxMessage & BoxMoney
pm->GetGossipMenu().AddMenuItem((uint8)gso->Icon,gso->Option, gossipid,gso->Action,"",0,false);
ingso=gso;
}
//note for future dev: should have database fields for BoxMessage & BoxMoney
if(!gso->OptionText.empty() && cantalking)
pm->GetGossipMenu().AddMenuItem((uint8)gso->Icon,gso->OptionText, gossipid,gso->Action,"",0,false);
}
}
@ -797,8 +792,8 @@ void Creature::OnGossipSelect(Player* player, uint32 option)
uint32 action=gossipmenu.GetItem(option).m_gAction;
uint32 zoneid=GetZoneId();
uint64 guid=GetGUID();
GossipOption const *gossip=GetGossipOption( action );
uint32 textid;
if(!gossip)
{
zoneid=0;
@ -806,7 +801,8 @@ void Creature::OnGossipSelect(Player* player, uint32 option)
if(!gossip)
return;
}
textid=GetGossipTextId( action, zoneid);
uint32 textid=GetGossipTextId( action, zoneid);
if(textid==0)
textid=GetNpcTextId();
@ -895,7 +891,7 @@ void Creature::OnPoiSelect(Player* player, GossipOption const *gossip)
Map const* map=MapManager::Instance().GetBaseMap( mapid );
uint16 areaflag=map->GetAreaFlag(GetPositionX(),GetPositionY());
uint32 zoneid=Map::GetZoneId(areaflag,mapid);
std::string areaname= gossip->Option;
std::string areaname= gossip->OptionText;
/*
uint16 pflag;
@ -989,24 +985,10 @@ void Creature::LoadGossipOptions()
uint32 npcflags=GetUInt32Value(UNIT_NPC_FLAGS);
QueryResult *result = WorldDatabase.PQuery( "SELECT id,gossip_id,npcflag,icon,action,option_text FROM npc_option WHERE (npcflag & %u)<>0", npcflags );
if(!result)
return;
GossipOption go;
do
{
Field *fields = result->Fetch();
go.Id= fields[0].GetUInt32();
go.GossipId = fields[1].GetUInt32();
go.NpcFlag=fields[2].GetUInt32();
go.Icon=fields[3].GetUInt32();
go.Action=fields[4].GetUInt32();
go.Option=fields[5].GetCppString();
addGossipOption(go);
}while( result->NextRow() );
delete result;
CacheNpcOptionList const& noList = objmgr.GetNpcOptions ();
for (CacheNpcOptionList::const_iterator i = noList.begin (); i != noList.end (); ++i)
if(i->NpcFlag & npcflags)
addGossipOption(*i);
m_gossipOptionLoaded = true;
}

View file

@ -109,7 +109,7 @@ struct GossipOption
uint32 NpcFlag;
uint32 Icon;
uint32 Action;
std::string Option;
std::string OptionText;
};
enum CreatureFlagsExtra

View file

@ -100,6 +100,7 @@ bool ChatHandler::HandleReloadAllLootCommand(const char*)
bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
{
HandleReloadNpcGossipCommand("a");
HandleReloadNpcOptionCommand("a");
HandleReloadNpcTrainerCommand("a");
HandleReloadNpcVendorCommand("a");
return true;
@ -345,6 +346,14 @@ bool ChatHandler::HandleReloadMangosStringCommand(const char*)
return true;
}
bool ChatHandler::HandleReloadNpcOptionCommand(const char*)
{
sLog.outString( "Re-Loading `npc_option` Table!" );
objmgr.LoadNpcOptions();
SendGlobalSysMessage("DB table `npc_option` reloaded.");
return true;
}
bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
{
sLog.outString( "Re-Loading `npc_gossip` Table!" );

View file

@ -6882,6 +6882,51 @@ void ObjectMgr::LoadNpcTextId()
sLog.outString( ">> Loaded %d NpcTextId ", count );
}
void ObjectMgr::LoadNpcOptions()
{
m_mCacheNpcOptionList.clear(); // For reload case
QueryResult *result = WorldDatabase.Query( "SELECT id,gossip_id,npcflag,icon,action,option_text FROM npc_option");
if( !result )
{
barGoLink bar( 1 );
bar.step();
sLog.outString();
sLog.outErrorDb(">> Loaded `npc_option`, table is empty!");
return;
}
barGoLink bar( result->GetRowCount() );
uint32 count = 0;
do
{
bar.step();
Field* fields = result->Fetch();
GossipOption go;
go.Id = fields[0].GetUInt32();
go.GossipId = fields[1].GetUInt32();
go.NpcFlag = fields[2].GetUInt32();
go.Icon = fields[3].GetUInt32();
go.Action = fields[4].GetUInt32();
go.OptionText = fields[5].GetCppString();
m_mCacheNpcOptionList.push_back(go);
++count;
} while (result->NextRow());
delete result;
sLog.outString();
sLog.outString( ">> Loaded %d npc_option entries", count );
}
void ObjectMgr::AddVendorItem( uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedcost )
{
VendorItemData& vList = m_mCacheVendorItemMap[entry];

View file

@ -229,6 +229,7 @@ struct PlayerCondition
// NPC gossip text id
typedef HM_NAMESPACE::hash_map<uint32, uint32> CacheNpcTextIdMap;
typedef std::list<GossipOption> CacheNpcOptionList;
typedef HM_NAMESPACE::hash_map<uint32, VendorItemData> CacheVendorItemMap;
typedef HM_NAMESPACE::hash_map<uint32, TrainerSpellData> CacheTrainerSpellMap;
@ -544,6 +545,7 @@ class ObjectMgr
void LoadWeatherZoneChances();
void LoadGameTele();
void LoadNpcOptions();
void LoadNpcTextId();
void LoadVendors();
void LoadTrainerSpell();
@ -712,6 +714,8 @@ class ObjectMgr
bool AddGameTele(GameTele& data);
bool DeleteGameTele(std::string name);
CacheNpcOptionList const& GetNpcOptions() const { return m_mCacheNpcOptionList; }
uint32 GetNpcGossip(uint32 entry) const
{
CacheNpcTextIdMap::const_iterator iter = m_mCacheNpcTextIdMap.find(entry);
@ -850,6 +854,7 @@ class ObjectMgr
typedef std::vector<PlayerCondition> ConditionStore;
ConditionStore mConditions;
CacheNpcOptionList m_mCacheNpcOptionList;
CacheNpcTextIdMap m_mCacheNpcTextIdMap;
CacheVendorItemMap m_mCacheVendorItemMap;
CacheTrainerSpellMap m_mCacheTrainerSpellMap;

View file

@ -1111,6 +1111,9 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Npc Text Id..." );
objmgr.LoadNpcTextId(); // must be after load Creature and NpcText
sLog.outString( "Loading Npc Options..." );
objmgr.LoadNpcOptions();
sLog.outString( "Loading vendors..." );
objmgr.LoadVendors(); // must be after load CreatureTemplate and ItemTemplate