diff --git a/sql/mangos.sql b/sql/mangos.sql index 950cd0a3b..79b45732e 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_10660_01_mangos_game_event_quest` bit(1) default NULL + `required_10679_02_mangos_creature_template` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -1251,6 +1251,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', + `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', `ScriptName` char(64) NOT NULL default '', @@ -3990,6 +3991,29 @@ LOCK TABLES `npc_vendor` WRITE; /*!40000 ALTER TABLE `npc_vendor` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `npc_vendor_template` +-- + +DROP TABLE IF EXISTS `npc_vendor_template`; +CREATE TABLE `npc_vendor_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `maxcount` tinyint(3) unsigned NOT NULL default '0', + `incrtime` int(10) unsigned NOT NULL default '0', + `ExtendedCost` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`,`ExtendedCost`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Npc System'; + +-- +-- Dumping data for table `npc_vendor_template` +-- + +LOCK TABLES `npc_vendor_template` WRITE; +/*!40000 ALTER TABLE `npc_vendor_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `npc_vendor_template` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `page_text` -- diff --git a/sql/updates/10679_01_mangos_npc_vendor_template.sql b/sql/updates/10679_01_mangos_npc_vendor_template.sql new file mode 100644 index 000000000..e723d6f21 --- /dev/null +++ b/sql/updates/10679_01_mangos_npc_vendor_template.sql @@ -0,0 +1,11 @@ +ALTER TABLE db_version CHANGE COLUMN required_10660_01_mangos_game_event_quest required_10679_01_mangos_npc_vendor_template bit; + +DROP TABLE IF EXISTS `npc_vendor_template`; +CREATE TABLE `npc_vendor_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `maxcount` tinyint(3) unsigned NOT NULL default '0', + `incrtime` int(10) unsigned NOT NULL default '0', + `ExtendedCost` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`,`ExtendedCost`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Npc System'; diff --git a/sql/updates/10679_02_mangos_creature_template.sql b/sql/updates/10679_02_mangos_creature_template.sql new file mode 100644 index 000000000..cf7282110 --- /dev/null +++ b/sql/updates/10679_02_mangos_creature_template.sql @@ -0,0 +1,4 @@ +ALTER TABLE db_version CHANGE COLUMN required_10679_01_mangos_npc_vendor_template required_10679_02_mangos_creature_template bit; + +ALTER TABLE creature_template + ADD COLUMN vendor_id mediumint(8) unsigned NOT NULL default '0' AFTER equipment_id; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index e1d629a85..468c785dd 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -114,6 +114,8 @@ pkgdata_DATA = \ 10660_01_mangos_game_event_quest.sql \ 10662_01_characters_item_loot.sql \ 10664_01_characters_arena_team_stats.sql \ + 10679_01_mangos_npc_vendor_template.sql \ + 10679_02_mangos_creature_template.sql \ README ## Additional files to include when running 'make dist' @@ -208,4 +210,6 @@ EXTRA_DIST = \ 10660_01_mangos_game_event_quest.sql \ 10662_01_characters_item_loot.sql \ 10664_01_characters_arena_team_stats.sql \ + 10679_01_mangos_npc_vendor_template.sql \ + 10679_02_mangos_creature_template.sql \ README diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index eb2ed94cd..35f4e83c9 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -2174,6 +2174,11 @@ VendorItemData const* Creature::GetVendorItems() const return sObjectMgr.GetNpcVendorItemList(GetEntry()); } +VendorItemData const* Creature::GetVendorTemplateItems() const +{ + return GetCreatureInfo()->vendorId ? sObjectMgr.GetNpcVendorItemList(GetCreatureInfo()->vendorId) : NULL; +} + uint32 Creature::GetVendorItemCurrentCount(VendorItem const* vItem) { if(!vItem->maxcount) diff --git a/src/game/Creature.h b/src/game/Creature.h index f5a2e297d..b818ec5a1 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -129,6 +129,7 @@ struct CreatureInfo uint32 movementId; bool RegenHealth; uint32 equipmentId; + uint32 vendorId; uint32 MechanicImmuneMask; uint32 flags_extra; uint32 ScriptID; @@ -505,6 +506,7 @@ class MANGOS_DLL_SPEC Creature : public Unit float GetSpellDamageMod(int32 Rank); VendorItemData const* GetVendorItems() const; + VendorItemData const* GetVendorTemplateItems() const; uint32 GetVendorItemCurrentCount(VendorItem const* vItem); uint32 UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 used_count); diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp index a1cf09cd7..3856b7a60 100644 --- a/src/game/ItemHandler.cpp +++ b/src/game/ItemHandler.cpp @@ -742,8 +742,9 @@ void WorldSession::SendListInventory(ObjectGuid vendorguid) pCreature->StopMoving(); VendorItemData const* vItems = pCreature->GetVendorItems(); + VendorItemData const* tItems = pCreature->GetVendorTemplateItems(); - if (!vItems) + if (!vItems && !tItems) { WorldPacket data( SMSG_LIST_INVENTORY, (8+1+1) ); data << ObjectGuid(vendorguid); @@ -753,7 +754,9 @@ void WorldSession::SendListInventory(ObjectGuid vendorguid) return; } - uint8 numitems = vItems->GetItemCount(); + uint8 customitems = vItems ? vItems->GetItemCount() : 0; + uint8 numitems = customitems + (tItems ? tItems->GetItemCount() : 0); + uint8 count = 0; WorldPacket data( SMSG_LIST_INVENTORY, (8+1+numitems*8*4) ); @@ -766,7 +769,9 @@ void WorldSession::SendListInventory(ObjectGuid vendorguid) for(uint8 vendorslot = 0; vendorslot < numitems; ++vendorslot ) { - if (VendorItem const* crItem = vItems->GetItem(vendorslot)) + VendorItem const* crItem = vendorslot < customitems ? vItems->GetItem(vendorslot) : tItems->GetItem(vendorslot - customitems); + + if (crItem) { if (ItemPrototype const *pProto = ObjectMgr::GetItemPrototype(crItem->item)) { diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 4446e7564..df243a277 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -1617,7 +1617,7 @@ bool ChatHandler::HandleNpcAddVendorItemCommand(char* args) uint32 vendor_entry = vendor ? vendor->GetEntry() : 0; - if (!sObjectMgr.IsVendorItemValid(vendor_entry, itemId, maxcount, incrtime, extendedcost, m_session->GetPlayer())) + if (!sObjectMgr.IsVendorItemValid(false, "npc_vendor", vendor_entry, itemId, maxcount, incrtime, extendedcost, m_session->GetPlayer())) { SetSentErrorMessage(true); return false; diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index d8d30e24e..7305d6132 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -474,6 +474,11 @@ bool ChatHandler::HandleReloadNpcTrainerCommand(char* /*args*/) bool ChatHandler::HandleReloadNpcVendorCommand(char* /*args*/) { + // not safe reload vendor template tables independent... + sLog.outString( "Re-Loading `npc_vendor_template` Table!" ); + sObjectMgr.LoadVendorTemplates(); + SendGlobalSysMessage("DB table `npc_vendor_template` reloaded."); + sLog.outString( "Re-Loading `npc_vendor` Table!" ); sObjectMgr.LoadVendors(); SendGlobalSysMessage("DB table `npc_vendor` reloaded."); diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index cf4c61383..58df871a1 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -186,6 +186,9 @@ ObjectMgr::~ObjectMgr() for (ArenaTeamMap::iterator itr = mArenaTeamMap.begin(); itr != mArenaTeamMap.end(); ++itr) delete itr->second; + for (CacheVendorItemMap::iterator itr = m_mCacheVendorTemplateItemMap.begin(); itr != m_mCacheVendorTemplateItemMap.end(); ++itr) + itr->second.Clear(); + for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr) itr->second.Clear(); @@ -702,6 +705,12 @@ void ObjectMgr::LoadCreatureTemplates() } } + if(cInfo->vendorId > 0) + { + if(!(cInfo->npcflag & UNIT_NPC_FLAG_VENDOR)) + sLog.outErrorDb("Table `creature_template` have creature (Entry: %u) with vendor_id %u but not have flag UNIT_NPC_FLAG_VENDOR (%u), vendor items will ignored.", cInfo->Entry, cInfo->vendorId, UNIT_NPC_FLAG_VENDOR); + } + /// if not set custom creature scale then load scale from CreatureDisplayInfo.dbc if(cInfo->scale <= 0.0f) { @@ -8789,16 +8798,20 @@ void ObjectMgr::LoadTrainerSpell() sLog.outString( ">> Loaded %d Trainers", count ); } -void ObjectMgr::LoadVendors() +void ObjectMgr::LoadVendors(char const* tableName, bool isTemplates) { + CacheVendorItemMap& vendorList = isTemplates ? m_mCacheVendorTemplateItemMap : m_mCacheVendorItemMap; + CacheVendorItemMap const* parentList = isTemplates ? NULL : &m_mCacheVendorTemplateItemMap; + + // For reload case - for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr) + for (CacheVendorItemMap::iterator itr = vendorList.begin(); itr != vendorList.end(); ++itr) itr->second.Clear(); - m_mCacheVendorItemMap.clear(); + vendorList.clear(); std::set skip_vendors; - QueryResult *result = WorldDatabase.Query("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor"); + QueryResult *result = WorldDatabase.PQuery("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM %s", tableName); if( !result ) { barGoLink bar( 1 ); @@ -8806,7 +8819,7 @@ void ObjectMgr::LoadVendors() bar.step(); sLog.outString(); - sLog.outErrorDb(">> Loaded `npc_vendor`, table is empty!"); + sLog.outString(">> Loaded `%s`, table is empty!", tableName); return; } @@ -8824,19 +8837,48 @@ void ObjectMgr::LoadVendors() uint32 incrtime = fields[3].GetUInt32(); uint32 ExtendedCost = fields[4].GetUInt32(); - if(!IsVendorItemValid(entry,item_id,maxcount,incrtime,ExtendedCost,NULL,&skip_vendors)) + if (!IsVendorItemValid(isTemplates, tableName, entry, item_id, maxcount, incrtime, ExtendedCost, NULL, &skip_vendors)) continue; - VendorItemData& vList = m_mCacheVendorItemMap[entry]; + VendorItemData& vList = vendorList[entry]; - vList.AddItem(item_id,maxcount,incrtime,ExtendedCost); + vList.AddItem(item_id, maxcount, incrtime, ExtendedCost); ++count; } while (result->NextRow()); delete result; sLog.outString(); - sLog.outString( ">> Loaded %d Vendors ", count ); + sLog.outString( ">> Loaded %d vendor items", count); +} + + +void ObjectMgr::LoadVendorTemplates() +{ + LoadVendors("npc_vendor_template", true); + + // post loading check + std::set vendor_ids; + + for(CacheVendorItemMap::const_iterator vItr = m_mCacheVendorTemplateItemMap.begin(); vItr != m_mCacheVendorTemplateItemMap.end(); ++vItr) + vendor_ids.insert(vItr->first); + + for(uint32 i = 1; i < sCreatureStorage.MaxEntry; ++i) + { + if (CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(i)) + { + if (cInfo->vendorId) + { + if (vendor_ids.count(cInfo->vendorId) > 0) + vendor_ids.erase(cInfo->vendorId); + else + sLog.outErrorDb("Creature (Entry: %u) has vendor_id = %u for nonexistent vendor template", cInfo->Entry, cInfo->vendorId); + } + } + } + + for(std::set::const_iterator vItr = vendor_ids.begin(); vItr != vendor_ids.end(); ++vItr) + sLog.outErrorDb("Table `npc_vendor_template` has vendor template %u not used by any vendors ", *vItr); } void ObjectMgr::LoadNpcTextId() @@ -9121,91 +9163,123 @@ bool ObjectMgr::RemoveVendorItem( uint32 entry,uint32 item ) return true; } -bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* pl, std::set* skip_vendors ) const +bool ObjectMgr::IsVendorItemValid(bool isTemplate, char const* tableName, uint32 vendor_entry, uint32 item_id, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* pl, std::set* skip_vendors ) const { - CreatureInfo const* cInfo = GetCreatureTemplate(vendor_entry); - if(!cInfo) - { - if(pl) - ChatHandler(pl).SendSysMessage(LANG_COMMAND_VENDORSELECTION); - else - sLog.outErrorDb("Table `npc_vendor` has data for nonexistent creature (Entry: %u), ignoring", vendor_entry); - return false; - } + char const* idStr = isTemplate ? "vendor template" : "vendor"; + CreatureInfo const* cInfo = NULL; - if(!(cInfo->npcflag & UNIT_NPC_FLAG_VENDOR)) + if (!isTemplate) { - if(!skip_vendors || skip_vendors->count(vendor_entry)==0) + cInfo = GetCreatureTemplate(vendor_entry); + if (!cInfo) { if(pl) ChatHandler(pl).SendSysMessage(LANG_COMMAND_VENDORSELECTION); else - sLog.outErrorDb("Table `npc_vendor` has data for creature (Entry: %u) without vendor flag, ignoring", vendor_entry); - - if(skip_vendors) - skip_vendors->insert(vendor_entry); + sLog.outErrorDb("Table `%s` has data for nonexistent creature (Entry: %u), ignoring", tableName, vendor_entry); + return false; + } + + if (!(cInfo->npcflag & UNIT_NPC_FLAG_VENDOR)) + { + if (!skip_vendors || skip_vendors->count(vendor_entry)==0) + { + if (pl) + ChatHandler(pl).SendSysMessage(LANG_COMMAND_VENDORSELECTION); + else + sLog.outErrorDb("Table `%s` has data for creature (Entry: %u) without vendor flag, ignoring", tableName, vendor_entry); + + if (skip_vendors) + skip_vendors->insert(vendor_entry); + } + return false; } - return false; } - if(!GetItemPrototype(item_id)) + if (!GetItemPrototype(item_id)) { - if(pl) + if (pl) ChatHandler(pl).PSendSysMessage(LANG_ITEM_NOT_FOUND, item_id); else - sLog.outErrorDb("Table `npc_vendor` for vendor (Entry: %u) contain nonexistent item (%u), ignoring", - vendor_entry, item_id); + sLog.outErrorDb("Table `%s` for %s %u contain nonexistent item (%u), ignoring", + tableName, idStr, vendor_entry, item_id); return false; } - if(ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost)) + if (ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost)) { - if(pl) + if (pl) ChatHandler(pl).PSendSysMessage(LANG_EXTENDED_COST_NOT_EXIST,ExtendedCost); else - sLog.outErrorDb("Table `npc_vendor` contain item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignoring", - item_id, ExtendedCost, vendor_entry); + sLog.outErrorDb("Table `%s` contain item (Entry: %u) with wrong ExtendedCost (%u) for %s %u, ignoring", + tableName, item_id, ExtendedCost, idStr, vendor_entry); return false; } - if(maxcount > 0 && incrtime == 0) + if (maxcount > 0 && incrtime == 0) { - if(pl) + if (pl) ChatHandler(pl).PSendSysMessage("MaxCount!=0 (%u) but IncrTime==0", maxcount); else - sLog.outErrorDb( "Table `npc_vendor` has `maxcount` (%u) for item %u of vendor (Entry: %u) but `incrtime`=0, ignoring", - maxcount, item_id, vendor_entry); + sLog.outErrorDb( "Table `%s` has `maxcount` (%u) for item %u of %s %u but `incrtime`=0, ignoring", + tableName, maxcount, item_id, idStr, vendor_entry); return false; } - else if(maxcount==0 && incrtime > 0) + else if (maxcount==0 && incrtime > 0) { - if(pl) + if (pl) ChatHandler(pl).PSendSysMessage("MaxCount==0 but IncrTime<>=0"); else - sLog.outErrorDb( "Table `npc_vendor` has `maxcount`=0 for item %u of vendor (Entry: %u) but `incrtime`<>0, ignoring", - item_id, vendor_entry); + sLog.outErrorDb( "Table `%s` has `maxcount`=0 for item %u of %s %u but `incrtime`<>0, ignoring", + tableName, item_id, idStr, vendor_entry); return false; } - VendorItemData const* vItems = GetNpcVendorItemList(vendor_entry); - if(!vItems) + VendorItemData const* vItems = isTemplate ? GetNpcVendorTemplateItemList(vendor_entry) : GetNpcVendorItemList(vendor_entry); + VendorItemData const* tItems = isTemplate ? NULL : GetNpcVendorTemplateItemList(vendor_entry); + + if (!vItems && !tItems) return true; // later checks for non-empty lists - if(vItems->FindItemCostPair(item_id,ExtendedCost)) + if (vItems && vItems->FindItemCostPair(item_id, ExtendedCost)) { - if(pl) + if (pl) ChatHandler(pl).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, item_id, ExtendedCost); else - sLog.outErrorDb( "Table `npc_vendor` has duplicate items %u (with extended cost %u) for vendor (Entry: %u), ignoring", item_id, ExtendedCost, vendor_entry); + sLog.outErrorDb( "Table `%s` has duplicate items %u (with extended cost %u) for %s %u, ignoring", + tableName, item_id, ExtendedCost, idStr, vendor_entry); return false; } - if(vItems->GetItemCount() >= MAX_VENDOR_ITEMS) + if (!isTemplate) { - if(pl) + if (tItems && tItems->FindItemCostPair(item_id, ExtendedCost)) + { + if (pl) + ChatHandler(pl).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, item_id, ExtendedCost); + else + { + if (!cInfo->vendorId) + sLog.outErrorDb( "Table `%s` has duplicate items %u (with extended cost %u) for %s %u, ignoring", + tableName, item_id, ExtendedCost, idStr, vendor_entry); + else + sLog.outErrorDb( "Table `%s` has duplicate items %u (with extended cost %u) for %s %u (or possible in vendor template %u), ignoring", + tableName, item_id, ExtendedCost, idStr, vendor_entry, cInfo->vendorId); + } + return false; + } + } + + uint32 countItems = vItems ? vItems->GetItemCount() : 0; + countItems += tItems ? tItems->GetItemCount() : 0; + + if (countItems >= MAX_VENDOR_ITEMS) + { + if (pl) ChatHandler(pl).SendSysMessage(LANG_COMMAND_ADDVENDORITEMITEMS); else - sLog.outErrorDb( "Table `npc_vendor` has too many items (%u >= %i) for vendor (Entry: %u), ignoring", vItems->GetItemCount(), MAX_VENDOR_ITEMS, vendor_entry); + sLog.outErrorDb( "Table `%s` has too many items (%u >= %i) for %s %u, ignoring", + tableName, countItems, MAX_VENDOR_ITEMS, idStr, vendor_entry); return false; } diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 5b74ea60a..2a7a8b838 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -978,7 +978,8 @@ class ObjectMgr void LoadGossipMenu(); void LoadGossipMenuItems(); - void LoadVendors(); + void LoadVendorTemplates(); + void LoadVendors() { LoadVendors("npc_vendor", false); } void LoadTrainerSpell(); std::string GeneratePetName(uint32 entry); @@ -1225,9 +1226,18 @@ class ObjectMgr return &iter->second; } + VendorItemData const* GetNpcVendorTemplateItemList(uint32 entry) const + { + CacheVendorItemMap::const_iterator iter = m_mCacheVendorTemplateItemMap.find(entry); + if(iter == m_mCacheVendorTemplateItemMap.end()) + return NULL; + + return &iter->second; + } + void AddVendorItem(uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost); bool RemoveVendorItem(uint32 entry,uint32 item); - bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set* skip_vendors = NULL ) const; + bool IsVendorItemValid(bool isTemplate, char const* tableName, uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set* skip_vendors = NULL) const; void LoadScriptNames(); ScriptNameMap &GetScriptNames() { return m_scriptNames; } @@ -1370,6 +1380,7 @@ class ObjectMgr void LoadCreatureAddons(SQLStorage& creatureaddons, char const* entryName, char const* comment); void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr); void LoadQuestRelationsHelper(QuestRelationsMap& map, char const* table); + void LoadVendors(char const* tableName, bool isTemplates); MailLevelRewardMap m_mailLevelRewardMap; @@ -1417,6 +1428,7 @@ class ObjectMgr CreatureModelRaceMap m_mCreatureModelRaceMap; CacheNpcTextIdMap m_mCacheNpcTextIdMap; + CacheVendorItemMap m_mCacheVendorTemplateItemMap; CacheVendorItemMap m_mCacheVendorItemMap; CacheTrainerSpellMap m_mCacheTrainerSpellMap; }; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 138c4d4e6..5730d8b3b 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -12728,7 +12728,8 @@ void Player::PrepareGossipMenu(WorldObject *pSource, uint32 menuId) case GOSSIP_OPTION_VENDOR: { VendorItemData const* vItems = pCreature->GetVendorItems(); - if (!vItems || vItems->Empty()) + VendorItemData const* tItems = pCreature->GetVendorTemplateItems(); + if ((!vItems || vItems->Empty()) && (!tItems || tItems->Empty())) { sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_VENDOR but have empty trading item list.", pCreature->GetGUIDLow(), pCreature->GetEntry()); hasMenuItem = false; @@ -18686,7 +18687,8 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 } VendorItemData const* vItems = pCreature->GetVendorItems(); - if(!vItems || vItems->Empty()) + VendorItemData const* tItems = pCreature->GetVendorTemplateItems(); + if ((!vItems || vItems->Empty()) && (!tItems || tItems->Empty())) { SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); return false; diff --git a/src/game/World.cpp b/src/game/World.cpp index 5a58d0613..375d106eb 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1191,10 +1191,10 @@ void World::SetInitialWorldSettings() sObjectMgr.LoadGameTele(); sLog.outString( "Loading Npc Text Id..." ); - sObjectMgr.LoadNpcTextId(); // must be after load Creature and NpcText + sObjectMgr.LoadNpcTextId(); // must be after load Creature and NpcText sLog.outString( "Loading Gossip scripts..." ); - sObjectMgr.LoadGossipScripts(); // must be before gossip menu options + sObjectMgr.LoadGossipScripts(); // must be before gossip menu options sLog.outString( "Loading Gossip menus..." ); sObjectMgr.LoadGossipMenu(); @@ -1203,12 +1203,13 @@ void World::SetInitialWorldSettings() sObjectMgr.LoadGossipMenuItems(); sLog.outString( "Loading Vendors..." ); - sObjectMgr.LoadVendors(); // must be after load CreatureTemplate and ItemTemplate + sObjectMgr.LoadVendorTemplates(); // must be after load ItemTemplate + sObjectMgr.LoadVendors(); // must be after load CreatureTemplate, VendorTemplate, and ItemTemplate sLog.outString( "Loading Trainers..." ); - sObjectMgr.LoadTrainerSpell(); // must be after load CreatureTemplate + sObjectMgr.LoadTrainerSpell(); // must be after load CreatureTemplate - sLog.outString( "Loading Waypoint scripts..." ); // before loading from creature_movement + sLog.outString( "Loading Waypoint scripts..." ); // before loading from creature_movement sObjectMgr.LoadCreatureMovementScripts(); sLog.outString( "Loading Waypoints..." ); diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp index a797cb52e..720df16bd 100644 --- a/src/shared/Database/SQLStorage.cpp +++ b/src/shared/Database/SQLStorage.cpp @@ -25,8 +25,8 @@ extern DatabasePostgre WorldDatabase; extern DatabaseMysql WorldDatabase; #endif -const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiis"; -const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiii"; +const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiliiiiis"; +const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiliiiiii"; const char CreatureDataAddonInfofmt[]="iiiiiis"; const char CreatureModelfmt[]="iffbii"; const char CreatureInfoAddonInfofmt[]="iiiiiis"; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 637576cba..294c08267 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10678" + #define REVISION_NR "10679" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 08fb96362..651b7199b 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_10664_01_characters_arena_team_stats" - #define REVISION_DB_MANGOS "required_10660_01_mangos_game_event_quest" + #define REVISION_DB_MANGOS "required_10679_02_mangos_creature_template" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version" #endif // __REVISION_SQL_H__