diff options
| -rw-r--r-- | sql/updates/world/2015_04_06_01_world.sql | 15 | ||||
| -rw-r--r-- | src/server/game/Entities/Creature/Creature.h | 5 | ||||
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObject.h | 6 | ||||
| -rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 66 | ||||
| -rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 22 | ||||
| -rw-r--r-- | src/server/game/Handlers/QueryHandler.cpp | 17 | ||||
| -rw-r--r-- | src/server/game/World/World.cpp | 6 | 
7 files changed, 120 insertions, 17 deletions
diff --git a/sql/updates/world/2015_04_06_01_world.sql b/sql/updates/world/2015_04_06_01_world.sql new file mode 100644 index 00000000000..a47def6c50c --- /dev/null +++ b/sql/updates/world/2015_04_06_01_world.sql @@ -0,0 +1,15 @@ +DROP TABLE IF EXISTS `creature_questitem`; +CREATE TABLE `creature_questitem` ( +  `CreatureEntry` int(10) unsigned NOT NULL DEFAULT '0', +  `Idx` int(10) unsigned NOT NULL DEFAULT '0', +  `ItemId` int(10) unsigned NOT NULL DEFAULT '0', +  PRIMARY KEY (`CreatureEntry`,`Idx`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `gameobject_questitem`; +CREATE TABLE `gameobject_questitem` ( +  `GameObjectEntry` int(10) unsigned NOT NULL DEFAULT '0', +  `Idx` int(10) unsigned NOT NULL DEFAULT '0', +  `ItemId` int(10) unsigned NOT NULL DEFAULT '0', +  PRIMARY KEY (`GameObjectEntry`,`Idx`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8;
\ No newline at end of file diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 3fd06e41458..5d18e1e079d 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -69,7 +69,6 @@ enum CreatureFlagsExtra  #define MAX_KILL_CREDIT 2  #define MAX_CREATURE_MODELS 4 -#define MAX_CREATURE_QUEST_ITEMS 6  #define MAX_CREATURE_NAMES 4  #define CREATURE_MAX_SPELLS 8  #define MAX_CREATURE_DIFFICULTIES 3 @@ -136,7 +135,6 @@ struct CreatureTemplate      float   ModDamage;      float   ModExperience;      bool    RacialLeader; -    uint32  questItems[MAX_CREATURE_QUEST_ITEMS];      uint32  movementId;      bool    RegenHealth;      uint32  MechanicImmuneMask; @@ -205,6 +203,9 @@ struct CreatureTemplate      }  }; +typedef std::vector<uint32> CreatureQuestItemList; +typedef std::unordered_map<uint32, CreatureQuestItemList> CreatureQuestItemMap; +  // Benchmarked: Faster than std::map (insert/find)  typedef std::unordered_map<uint32, CreatureTemplate> CreatureTemplateContainer; diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index b4492cd77c7..50bd1ebd9f5 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -30,8 +30,6 @@ class GameObjectAI;  class Group;  class Transport; -#define MAX_GAMEOBJECT_QUEST_ITEMS 6 -  // from `gameobject_template`  struct GameObjectTemplate  { @@ -45,7 +43,6 @@ struct GameObjectTemplate      uint32  faction;      uint32  flags;      float   size; -    uint32  questItems[MAX_GAMEOBJECT_QUEST_ITEMS];      int32   unkInt32;      union      { @@ -847,6 +844,9 @@ struct GameObjectData      bool dbData;  }; +typedef std::vector<uint32> GameObjectQuestItemList; +typedef std::unordered_map<uint32, GameObjectQuestItemList> GameObjectQuestItemMap; +  // For containers:  [GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY        -> ...  // For bobber:      GO_NOT_READY  ->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED-><deleted>  // For door(closed):[GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY(close) -> ... diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 51063666470..0316c31794c 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -539,9 +539,6 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields)      creatureTemplate.ModExperience  = fields[72].GetFloat();      creatureTemplate.RacialLeader   = fields[73].GetBool(); -    for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) -        creatureTemplate.questItems[i] = fields[74 + i].GetUInt32(); -      creatureTemplate.movementId         = fields[80].GetUInt32();      creatureTemplate.RegenHealth        = fields[81].GetBool();      creatureTemplate.MechanicImmuneMask = fields[82].GetUInt32(); @@ -6231,9 +6228,6 @@ void ObjectMgr::LoadGameObjectTemplate()          got.flags          = fields[8].GetUInt32();          got.size           = fields[9].GetFloat(); -        for (uint8 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i) -            got.questItems[i] = fields[10 + i].GetUInt32(); -          for (uint8 i = 0; i < MAX_GAMEOBJECT_DATA; ++i)              got.raw.data[i] = fields[16 + i].GetUInt32(); @@ -8920,3 +8914,63 @@ std::string ObjectMgr::GetRealmName(uint32 realm) const      RealmNameContainer::const_iterator iter = _realmNameStore.find(realm);      return iter != _realmNameStore.end() ? iter->second : "";  } + +void ObjectMgr::LoadGameObjectQuestItems() +{ +    uint32 oldMSTime = getMSTime(); + +    //                                               0                1 +    QueryResult result = WorldDatabase.Query("SELECT GameObjectEntry, ItemId FROM gameobject_questitem ORDER BY Idx ASC"); + +    if (!result) +    { +        TC_LOG_INFO("server.loading", ">> Loaded 0 gameobject quest items. DB table `gameobject_questitem` is empty."); +        return; +    } + +    uint32 count = 0; +    do +    { +        Field* fields = result->Fetch(); + +        uint32 entry = fields[0].GetUInt32(); +        uint32 item = fields[1].GetUInt32(); + +        _gameObjectQuestItemStore[entry].push_back(item); + +        ++count; +    } +    while (result->NextRow()); + +    TC_LOG_INFO("server.loading", ">> Loaded %u gameobject quest items in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); +} + +void ObjectMgr::LoadCreatureQuestItems() +{ +    uint32 oldMSTime = getMSTime(); + +    //                                               0              1 +    QueryResult result = WorldDatabase.Query("SELECT CreatureEntry, ItemId FROM creature_questitem ORDER BY Idx ASC"); + +    if (!result) +    { +        TC_LOG_INFO("server.loading", ">> Loaded 0 creature quest items. DB table `creature_questitem` is empty."); +        return; +    } + +    uint32 count = 0; +    do +    { +        Field* fields = result->Fetch(); + +        uint32 entry = fields[0].GetUInt32(); +        uint32 item = fields[1].GetUInt32(); + +        _creatureQuestItemStore[entry].push_back(item); + +        ++count; +    } +    while (result->NextRow()); + +    TC_LOG_INFO("server.loading", ">> Loaded %u creature quest items in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); +}
\ No newline at end of file diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 49d7b024b19..b49b46cb555 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -725,6 +725,24 @@ class ObjectMgr          static ObjectGuid GetPlayerGUIDByName(std::string const& name); +        GameObjectQuestItemList* GetGameObjectQuestItemList(uint32 id) +        { +            GameObjectQuestItemMap::iterator itr = _gameObjectQuestItemStore.find(id); +            if (itr != _gameObjectQuestItemStore.end()) +                return &itr->second; +            return NULL; +        } +        GameObjectQuestItemMap const* GetGameObjectQuestItemMap() const { return &_gameObjectQuestItemStore; } + +        CreatureQuestItemList* GetCreatureQuestItemList(uint32 id) +        { +            CreatureQuestItemMap::iterator itr = _creatureQuestItemStore.find(id); +            if (itr != _creatureQuestItemStore.end()) +                return &itr->second; +            return NULL; +        } +        CreatureQuestItemMap const* GetCreatureQuestItemMap() const { return &_creatureQuestItemStore; } +          /**          * Retrieves the player name by guid.          * @@ -930,6 +948,8 @@ class ObjectMgr          void LoadCreatureTemplateAddons();          void LoadCreatureTemplate(Field* fields);          void CheckCreatureTemplate(CreatureTemplate const* cInfo); +        void LoadGameObjectQuestItems(); +        void LoadCreatureQuestItems();          void LoadTempSummons();          void LoadCreatures();          void LoadLinkedRespawn(); @@ -1401,6 +1421,8 @@ class ObjectMgr          CreatureModelContainer _creatureModelStore;          CreatureAddonContainer _creatureAddonStore;          GameObjectAddonContainer _gameObjectAddonStore; +        GameObjectQuestItemMap _gameObjectQuestItemStore; +        CreatureQuestItemMap _creatureQuestItemStore;          CreatureTemplateAddonContainer _creatureTemplateAddonStore;          EquipmentInfoContainer _equipmentInfoStore;          LinkedRespawnContainer _linkedRespawnStore; diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index 93ae3873857..a5288b274a4 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -89,9 +89,12 @@ void WorldSession::HandleCreatureQuery(WorldPackets::Query::QueryCreature& packe          stats.HpMulti = creatureInfo->ModHealth;          stats.EnergyMulti = creatureInfo->ModMana;          stats.Leader = creatureInfo->RacialLeader; -        for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) -            if (creatureInfo->questItems[i]) -                stats.QuestItems.push_back(creatureInfo->questItems[i]); + +        CreatureQuestItemList* items = sObjectMgr->GetCreatureQuestItemList(packet.CreatureID); +        if (items) +            for (uint32 item : *items) +                stats.QuestItems.push_back(item); +          stats.CreatureMovementInfoID = creatureInfo->movementId;          stats.RequiredExpansion = creatureInfo->expansionUnknown;          stats.Flags[0] = creatureInfo->type_flags; @@ -128,9 +131,11 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPackets::Query::QueryGameObj          stats.IconName = gameObjectInfo->IconName;          stats.Name[0] = gameObjectInfo->name; -        for (uint8 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; i++) -            if (gameObjectInfo->questItems[i]) -                stats.QuestItems.push_back(gameObjectInfo->questItems[i]); +        GameObjectQuestItemList* items = sObjectMgr->GetGameObjectQuestItemList(packet.GameObjectID); +        if (items) +            for (uint32 item : *items) +                stats.QuestItems.push_back(item); +          for (uint32 i = 0; i < MAX_GAMEOBJECT_DATA; i++)              stats.Data[i] = gameObjectInfo->raw.data[i]; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index dc40e5f3c2b..3a38acae452 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1622,6 +1622,12 @@ void World::SetInitialWorldSettings()      TC_LOG_INFO("server.loading", "Loading GameObject Addon Data...");      sObjectMgr->LoadGameObjectAddons();                          // must be after LoadGameObjectTemplate() and LoadGameobjects() +     +    TC_LOG_INFO("server.loading", "Loading GameObject Quest Items..."); +    sObjectMgr->LoadGameObjectQuestItems(); +     +    TC_LOG_INFO("server.loading", "Loading Creature Quest Items..."); +    sObjectMgr->LoadCreatureQuestItems();      TC_LOG_INFO("server.loading", "Loading Creature Linked Respawn...");      sObjectMgr->LoadLinkedRespawn();                             // must be after LoadCreatures(), LoadGameObjects()  | 
