aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Globals/ObjectMgr.cpp
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2018-01-17 02:17:49 -0300
committerShauren <shauren.trinity@gmail.com>2021-06-16 01:00:11 +0200
commit21556667c16b282b77934bddee3d86f0c632ef31 (patch)
tree4669148763e4d450f12a46a7f2c8a7a2f6913a87 /src/server/game/Globals/ObjectMgr.cpp
parent5b5bc4c5c7cad020bd831185057451b674c234d8 (diff)
Core/Globals: throw some RAII into ObjectMgr, and load templates into vectors
Ref #14274 (cherry picked from commit b64c5043140dc7b7908e259e441de16cc0261320)
Diffstat (limited to 'src/server/game/Globals/ObjectMgr.cpp')
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp361
1 files changed, 178 insertions, 183 deletions
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 8bd7173f44f..a9987ae6954 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -223,10 +223,6 @@ ObjectMgr::ObjectMgr():
_voidItemId(1),
DBCLocaleIndex(LOCALE_enUS)
{
- for (uint8 i = 0; i < MAX_CLASSES; ++i)
-
- for (uint8 j = 0; j < MAX_RACES; ++j)
- _playerInfo[j][i] = nullptr;
}
ObjectMgr* ObjectMgr::instance()
@@ -237,31 +233,6 @@ ObjectMgr* ObjectMgr::instance()
ObjectMgr::~ObjectMgr()
{
- for (QuestMap::iterator i = _questTemplates.begin(); i != _questTemplates.end(); ++i)
- delete i->second;
-
- for (PetLevelInfoContainer::iterator i = _petInfoStore.begin(); i != _petInfoStore.end(); ++i)
- delete[] i->second;
-
- for (int race = 0; race < MAX_RACES; ++race)
- {
- for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
- {
- if (_playerInfo[race][class_])
- delete[] _playerInfo[race][class_]->levelInfo;
- delete _playerInfo[race][class_];
- }
- }
-
- for (CacheVendorItemContainer::iterator itr = _cacheVendorItemStore.begin(); itr != _cacheVendorItemStore.end(); ++itr)
- itr->second.Clear();
-
- for (DungeonEncounterContainer::iterator itr =_dungeonEncounterStore.begin(); itr != _dungeonEncounterStore.end(); ++itr)
- for (DungeonEncounterList::iterator encounterItr = itr->second.begin(); encounterItr != itr->second.end(); ++encounterItr)
- delete *encounterItr;
-
- for (AccessRequirementContainer::iterator itr = _accessRequirementStore.begin(); itr != _accessRequirementStore.end(); ++itr)
- delete itr->second;
}
void ObjectMgr::AddLocaleString(std::string&& value, LocaleConstant localeConstant, std::vector<std::string>& data)
@@ -390,7 +361,7 @@ void ObjectMgr::LoadCreatureTemplates()
// 69 70 71 72 73 74 75 76
// "RacialLeader, movementId, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, "
// 77
- // "ScriptName FROM creature_template WHERE entry = ? OR 1 = ?");
+ // "ScriptName FROM creature_template WHERE entry = ? OR 1 = ? ORDER BY entry DESC");
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_TEMPLATE);
stmt->setUInt32(0, 0);
@@ -403,29 +374,35 @@ void ObjectMgr::LoadCreatureTemplates()
return;
}
- _creatureTemplateStore.reserve(result->GetRowCount());
+ uint32 count = 0;
+
+ uint32 const maxCreatureId = (*result)[0].GetUInt32();
+ _creatureTemplateStore.resize(maxCreatureId + 1);
do
{
Field* fields = result->Fetch();
LoadCreatureTemplate(fields);
- }
- while (result->NextRow());
+
+ ++count;
+ } while (result->NextRow());
// We load the creature models after loading but before checking
LoadCreatureTemplateModels();
// Checking needs to be done after loading because of the difficulty self referencing
- for (CreatureTemplateContainer::const_iterator itr = _creatureTemplateStore.begin(); itr != _creatureTemplateStore.end(); ++itr)
- CheckCreatureTemplate(&itr->second);
+ for (auto const& creatureTemplate : _creatureTemplateStore)
+ if (creatureTemplate)
+ CheckCreatureTemplate(creatureTemplate.get());
- TC_LOG_INFO("server.loading", ">> Loaded %u creature definitions in %u ms", uint32(_creatureTemplateStore.size()), GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u creature definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
void ObjectMgr::LoadCreatureTemplate(Field* fields)
{
uint32 entry = fields[0].GetUInt32();
- CreatureTemplate& creatureTemplate = _creatureTemplateStore[entry];
+ _creatureTemplateStore[entry] = std::make_unique<CreatureTemplate>();
+ CreatureTemplate& creatureTemplate = *_creatureTemplateStore[entry].get();
creatureTemplate.Entry = entry;
@@ -686,8 +663,8 @@ void ObjectMgr::LoadCreatureScalingData()
uint32 entry = fields[0].GetUInt32();
Difficulty difficulty = Difficulty(fields[1].GetUInt8());
- auto itr = _creatureTemplateStore.find(entry);
- if (itr == _creatureTemplateStore.end())
+ CreatureTemplate const* creatureTemplate = GetCreatureTemplate(entry);
+ if (!creatureTemplate)
{
TC_LOG_ERROR("sql.sql", "Creature template (Entry: %u) does not exist but has a record in `creature_template_scaling`", entry);
continue;
@@ -700,7 +677,7 @@ void ObjectMgr::LoadCreatureScalingData()
creatureLevelScaling.DeltaLevelMax = fields[5].GetInt16();
creatureLevelScaling.ContentTuningID = fields[6].GetInt32();
- itr->second.scalingStore[difficulty] = creatureLevelScaling;
+ const_cast<CreatureTemplate*>(creatureTemplate)->scalingStore[difficulty] = creatureLevelScaling;
++count;
} while (result->NextRow());
@@ -3018,13 +2995,17 @@ void ObjectMgr::LoadItemTemplates()
uint32 oldMSTime = getMSTime();
uint32 sparseCount = 0;
+ uint32 const maxItemId = sItemSparseStore.GetNumRows();
+ _itemTemplateStore.resize(maxItemId + 1);
+
for (ItemSparseEntry const* sparse : sItemSparseStore)
{
ItemEntry const* db2Data = sItemStore.LookupEntry(sparse->ID);
if (!db2Data)
continue;
- ItemTemplate& itemTemplate = _itemTemplateStore[sparse->ID];
+ _itemTemplateStore[sparse->ID] = std::make_unique<ItemTemplate>();
+ ItemTemplate& itemTemplate = *_itemTemplateStore[sparse->ID].get();
itemTemplate.BasicData = db2Data;
itemTemplate.ExtendedData = sparse;
@@ -3101,11 +3082,11 @@ void ObjectMgr::LoadItemTemplates()
// Load item effects (spells)
for (ItemEffectEntry const* effectEntry : sItemEffectStore)
{
- auto itemItr = _itemTemplateStore.find(effectEntry->ParentItemID);
- if (itemItr == _itemTemplateStore.end())
+ ItemTemplate const* itemTemplate = GetItemTemplate(effectEntry->ParentItemID);
+ if (!itemTemplate)
continue;
- itemItr->second.Effects.push_back(effectEntry);
+ const_cast<ItemTemplate*>(itemTemplate)->Effects.push_back(effectEntry);
}
TC_LOG_INFO("server.loading", ">> Loaded %u item templates in %u ms", sparseCount, GetMSTimeDiffToNow(oldMSTime));
@@ -3123,7 +3104,8 @@ void ObjectMgr::LoadItemTemplateAddon()
{
Field* fields = result->Fetch();
uint32 itemId = fields[0].GetUInt32();
- if (!GetItemTemplate(itemId))
+ ItemTemplate* itemTemplate = const_cast<ItemTemplate*>(GetItemTemplate(itemId));
+ if (!itemTemplate)
{
TC_LOG_ERROR("sql.sql", "Item %u specified in `item_template_addon` does not exist, skipped.", itemId);
continue;
@@ -3136,13 +3118,12 @@ void ObjectMgr::LoadItemTemplateAddon()
TC_LOG_ERROR("sql.sql", "Minimum money loot specified in `item_template_addon` for item %u was greater than maximum amount, swapping.", itemId);
std::swap(minMoneyLoot, maxMoneyLoot);
}
- ItemTemplate& itemTemplate = _itemTemplateStore[itemId];
- itemTemplate.FlagsCu = fields[1].GetUInt32();
- itemTemplate.FoodType = fields[2].GetUInt8();
- itemTemplate.MinMoneyLoot = minMoneyLoot;
- itemTemplate.MaxMoneyLoot = maxMoneyLoot;
- itemTemplate.SpellPPMRate = fields[5].GetFloat();
- itemTemplate.RandomBonusListTemplateId = fields[6].GetUInt32();
+ itemTemplate->FlagsCu = fields[1].GetUInt32();
+ itemTemplate->FoodType = fields[2].GetUInt8();
+ itemTemplate->MinMoneyLoot = minMoneyLoot;
+ itemTemplate->MaxMoneyLoot = maxMoneyLoot;
+ itemTemplate->SpellPPMRate = fields[5].GetFloat();
+ itemTemplate->RandomBonusListTemplateId = fields[6].GetUInt32();
++count;
} while (result->NextRow());
}
@@ -3161,13 +3142,14 @@ void ObjectMgr::LoadItemScriptNames()
{
Field* fields = result->Fetch();
uint32 itemId = fields[0].GetUInt32();
- if (!GetItemTemplate(itemId))
+ ItemTemplate* itemTemplate = const_cast<ItemTemplate*>(GetItemTemplate(itemId));
+ if (!itemTemplate)
{
TC_LOG_ERROR("sql.sql", "Item %u specified in `item_script_names` does not exist, skipped.", itemId);
continue;
}
- _itemTemplateStore[itemId].ScriptId = GetScriptId(fields[1].GetString());
+ itemTemplate->ScriptId = GetScriptId(fields[1].GetString());
++count;
} while (result->NextRow());
}
@@ -3177,10 +3159,7 @@ void ObjectMgr::LoadItemScriptNames()
ItemTemplate const* ObjectMgr::GetItemTemplate(uint32 entry) const
{
- ItemTemplateContainer::const_iterator itr = _itemTemplateStore.find(entry);
- if (itr != _itemTemplateStore.end())
- return &(itr->second);
- return nullptr;
+ return entry < _itemTemplateStore.size() ? _itemTemplateStore[entry].get() : nullptr;
}
void ObjectMgr::LoadVehicleTemplateAccessories()
@@ -3360,21 +3339,19 @@ void ObjectMgr::LoadPetLevelInfo()
continue;
}
- PetLevelInfo*& pInfoMapEntry = _petInfoStore[creature_id];
+ auto& pInfoMapEntry = _petInfoStore[creature_id];
if (!pInfoMapEntry)
- pInfoMapEntry = new PetLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)];
+ pInfoMapEntry = std::make_unique<PetLevelInfo[]>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
// data for level 1 stored in [0] array element, ...
- PetLevelInfo* pLevelInfo = &pInfoMapEntry[current_level-1];
+ PetLevelInfo* pLevelInfo = &pInfoMapEntry[current_level - 1];
pLevelInfo->health = fields[2].GetUInt16();
pLevelInfo->mana = fields[3].GetUInt16();
pLevelInfo->armor = fields[9].GetUInt32();
- for (int i = 0; i < MAX_STATS; i++)
- {
- pLevelInfo->stats[i] = fields[i+4].GetUInt16();
- }
+ for (uint8 i = 0; i < MAX_STATS; i++)
+ pLevelInfo->stats[i] = fields[i + 4].GetUInt16();
++count;
}
@@ -3383,13 +3360,13 @@ void ObjectMgr::LoadPetLevelInfo()
// Fill gaps and check integrity
for (PetLevelInfoContainer::iterator itr = _petInfoStore.begin(); itr != _petInfoStore.end(); ++itr)
{
- PetLevelInfo* pInfo = itr->second;
+ auto& pInfo = itr->second;
// fatal error if no level 1 data
if (!pInfo || pInfo[0].health == 0)
{
TC_LOG_ERROR("sql.sql", "Creature %u does not have pet stats data for Level 1!", itr->first);
- exit(1);
+ ABORT();
}
// fill level gaps
@@ -3411,11 +3388,11 @@ PetLevelInfo const* ObjectMgr::GetPetLevelInfo(uint32 creature_id, uint8 level)
if (level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
level = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
- PetLevelInfoContainer::const_iterator itr = _petInfoStore.find(creature_id);
+ auto itr = _petInfoStore.find(creature_id);
if (itr == _petInfoStore.end())
return nullptr;
- return &itr->second[level-1]; // data for level 1 stored in [0] array element, ...
+ return &itr->second[level - 1]; // data for level 1 stored in [0] array element, ...
}
void ObjectMgr::PlayerCreateInfoAddItemHelper(uint32 race_, uint32 class_, uint32 itemId, int32 count)
@@ -3454,7 +3431,7 @@ void ObjectMgr::LoadPlayerInfo()
if (!result)
{
TC_LOG_ERROR("server.loading", ">> Loaded 0 player create definitions. DB table `playercreateinfo` is empty.");
- exit(1);
+ ABORT();
}
else
{
@@ -3512,7 +3489,7 @@ void ObjectMgr::LoadPlayerInfo()
continue;
}
- PlayerInfo* info = new PlayerInfo();
+ std::unique_ptr<PlayerInfo> info = std::make_unique<PlayerInfo>();
info->mapId = mapId;
info->areaId = areaId;
info->positionX = positionX;
@@ -3521,7 +3498,7 @@ void ObjectMgr::LoadPlayerInfo()
info->orientation = orientation;
info->displayId_m = maleModel->DisplayID;
info->displayId_f = femaleModel->DisplayID;
- _playerInfo[current_race][current_class] = info;
+ _playerInfo[current_race][current_class] = std::move(info);
++count;
}
@@ -3553,7 +3530,7 @@ void ObjectMgr::LoadPlayerInfo()
if (!characterLoadout->RaceMask.HasRace(raceIndex))
continue;
- if (PlayerInfo* playerInfo = _playerInfo[raceIndex][characterLoadout->ChrClassID])
+ if (auto& playerInfo = _playerInfo[raceIndex][characterLoadout->ChrClassID])
{
for (ItemTemplate const* itemTemplate : *items)
{
@@ -3666,7 +3643,7 @@ void ObjectMgr::LoadPlayerInfo()
if (rcInfo->RaceMask.HasRace(raceIndex))
for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex)
if (rcInfo->ClassMask == -1 || ((1 << (classIndex - 1)) & rcInfo->ClassMask))
- if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
+ if (auto& info = _playerInfo[raceIndex][classIndex])
info->skills.push_back(rcInfo);
TC_LOG_INFO("server.loading", ">> Loaded player create skills in %u ms", GetMSTimeDiffToNow(oldMSTime));
@@ -3714,7 +3691,7 @@ void ObjectMgr::LoadPlayerInfo()
{
if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
{
- if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
+ if (auto& info = _playerInfo[raceIndex][classIndex])
{
info->customSpells.push_back(spellId);
++count;
@@ -3774,7 +3751,7 @@ void ObjectMgr::LoadPlayerInfo()
{
if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
{
- if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
+ if (auto& info = _playerInfo[raceIndex][classIndex])
{
info->castSpells.push_back(spellId);
++count;
@@ -3823,7 +3800,7 @@ void ObjectMgr::LoadPlayerInfo()
continue;
}
- if (PlayerInfo* info = _playerInfo[current_race][current_class])
+ if (auto& info = _playerInfo[current_race][current_class])
info->action.push_back(PlayerCreateInfoAction(fields[2].GetUInt16(), fields[3].GetUInt32(), fields[4].GetUInt16()));
++count;
@@ -3851,7 +3828,7 @@ void ObjectMgr::LoadPlayerInfo()
if (!raceStatsResult)
{
TC_LOG_ERROR("server.loading", ">> Loaded 0 race stats definitions. DB table `player_racestats` is empty.");
- exit(1);
+ ABORT();
}
do
@@ -3876,7 +3853,7 @@ void ObjectMgr::LoadPlayerInfo()
if (!result)
{
TC_LOG_ERROR("server.loading", ">> Loaded 0 level stats definitions. DB table `player_classlevelstats` is empty.");
- exit(1);
+ ABORT();
}
uint32 count = 0;
@@ -3905,13 +3882,13 @@ void ObjectMgr::LoadPlayerInfo()
for (std::size_t race = 0; race < raceStatModifiers.size(); ++race)
{
- if (PlayerInfo* info = _playerInfo[race][current_class])
+ if (auto& info = _playerInfo[race][current_class])
{
if (!info->levelInfo)
- info->levelInfo = new PlayerLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)];
+ info->levelInfo = std::make_unique<PlayerLevelInfo[]>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
PlayerLevelInfo& levelInfo = info->levelInfo[current_level - 1];
- for (int i = 0; i < MAX_STATS; ++i)
+ for (uint8 i = 0; i < MAX_STATS; ++i)
levelInfo.stats[i] = fields[i + 2].GetUInt16() + raceStatModifiers[race].StatModifier[i];
}
}
@@ -3921,19 +3898,19 @@ void ObjectMgr::LoadPlayerInfo()
while (result->NextRow());
// Fill gaps and check integrity
- for (int race = 0; race < MAX_RACES; ++race)
+ for (uint8 race = 0; race < MAX_RACES; ++race)
{
// skip non existed races
if (!sChrRacesStore.LookupEntry(race))
continue;
- for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
+ for (uint8 class_ = 0; class_ < MAX_CLASSES; ++class_)
{
// skip non existed classes
if (!sChrClassesStore.LookupEntry(class_))
continue;
- PlayerInfo* info = _playerInfo[race][class_];
+ auto& info = _playerInfo[race][class_];
if (!info)
continue;
@@ -3959,7 +3936,7 @@ void ObjectMgr::LoadPlayerInfo()
if (!info->levelInfo || info->levelInfo[0].stats[0] == 0)
{
TC_LOG_ERROR("sql.sql", "Race %i Class %i Level 1 does not have stats data!", race, class_);
- exit(1);
+ ABORT();
}
// fill level gaps
@@ -4057,12 +4034,12 @@ void ObjectMgr::GetPlayerLevelInfo(uint32 race, uint32 class_, uint8 level, Play
if (level < 1 || race >= MAX_RACES || class_ >= MAX_CLASSES)
return;
- PlayerInfo const* pInfo = _playerInfo[race][class_];
+ auto const& pInfo = _playerInfo[race][class_];
if (!pInfo)
return;
if (level <= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
- *info = pInfo->levelInfo[level-1];
+ *info = pInfo->levelInfo[level - 1];
else
BuildPlayerLevelInfo(race, class_, level, info);
}
@@ -4070,10 +4047,10 @@ void ObjectMgr::GetPlayerLevelInfo(uint32 race, uint32 class_, uint8 level, Play
void ObjectMgr::BuildPlayerLevelInfo(uint8 race, uint8 _class, uint8 level, PlayerLevelInfo* info) const
{
// base data (last known level)
- *info = _playerInfo[race][_class]->levelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)-1];
+ *info = _playerInfo[race][_class]->levelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) - 1];
// if conversion from uint32 to uint8 causes unexpected behaviour, change lvl to uint32
- for (uint8 lvl = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)-1; lvl < level; ++lvl)
+ for (uint8 lvl = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) - 1; lvl < level; ++lvl)
{
switch (_class)
{
@@ -4139,9 +4116,6 @@ void ObjectMgr::LoadQuests()
{
uint32 oldMSTime = getMSTime();
- // For reload case
- for (auto itr = _questTemplates.begin(); itr != _questTemplates.end(); ++itr)
- delete itr->second;
_questTemplates.clear();
_questTemplatesAutoPush.clear();
_questObjectives.clear();
@@ -4179,13 +4153,18 @@ void ObjectMgr::LoadQuests()
"AcceptedSoundKitID, CompleteSoundKitID, AreaGroupID, TimeAllowed, AllowableRaces, TreasurePickerID, Expansion, ManagedWorldStateID, QuestSessionBonus, "
//107 108 109 110 111 112 113 114 115
"LogTitle, LogDescription, QuestDescription, AreaDescription, PortraitGiverText, PortraitGiverName, PortraitTurnInText, PortraitTurnInName, QuestCompletionLog"
- " FROM quest_template");
+ " FROM quest_template ORDER BY ID DESC");
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 quests definitions. DB table `quest_template` is empty.");
return;
}
+ uint32 const maxQuestId = (*result)[0].GetUInt32();
+ _questTemplates.resize(maxQuestId + 1);
+
+ uint32 count = 0;
+
// create multimap previous quest for each existed quest
// some quests can have many previous maps set by NextQuestId in previous quest
// for example set of race quests can lead to single not race specific quest
@@ -4193,10 +4172,11 @@ void ObjectMgr::LoadQuests()
{
Field* fields = result->Fetch();
- Quest* newQuest = new Quest(fields);
- _questTemplates[newQuest->GetQuestId()] = newQuest;
+ std::unique_ptr<Quest> newQuest = std::make_unique<Quest>(fields);
+ _questTemplates[newQuest->GetQuestId()] = std::move(newQuest);
+ ++count;
if (newQuest->IsAutoPush())
- _questTemplatesAutoPush.push_back(newQuest);
+ _questTemplatesAutoPush.push_back(newQuest.get()); // BROKEN BUT WILL BE FIXED IN THE REVERT CHERRY-PICK
} while (result->NextRow());
struct QuestLoaderHelper
@@ -4255,9 +4235,11 @@ void ObjectMgr::LoadQuests()
Field* fields = result->Fetch();
uint32 questId = fields[0].GetUInt32();
- auto itr = _questTemplates.find(questId);
- if (itr != _questTemplates.end())
- (itr->second->*loader.LoaderFunction)(fields);
+ if (questId < _questTemplates.size() && _questTemplates[questId])
+ {
+ Quest* const quest = _questTemplates[questId].get();
+ (quest->*loader.LoaderFunction)(fields);
+ }
else
TC_LOG_ERROR("server.loading", "Table `%s` has data for quest %u but such quest does not exist", loader.TableName, questId);
} while (result->NextRow());
@@ -4296,22 +4278,23 @@ void ObjectMgr::LoadQuests()
uint32 questId = fields[2].GetUInt32();
// Do not throw error here because error for non existing quest is thrown while loading quest objectives. we do not need duplication
- auto itr = _questTemplates.find(questId);
- if (itr != _questTemplates.end())
- itr->second->LoadQuestObjectiveVisualEffect(fields);
+ Quest const* quest = GetQuestTemplate(questId);
+ if (quest)
+ const_cast<Quest*>(quest)->LoadQuestObjectiveVisualEffect(fields);
} while (result->NextRow());
}
std::map<uint32, uint32> usedMailTemplates;
// Post processing
- for (QuestMap::iterator iter = _questTemplates.begin(); iter != _questTemplates.end(); ++iter)
+ for (auto& qinfo : _questTemplates)
{
- // skip post-loading checks for disabled quests
- if (DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, iter->first, nullptr))
+ if (!qinfo)
continue;
- Quest* qinfo = iter->second;
+ // skip post-loading checks for disabled quests
+ if (DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, qinfo->GetQuestId(), nullptr))
+ continue;
// additional quest integrity checks (GO, creature_template and items must be loaded already)
@@ -4799,10 +4782,9 @@ void ObjectMgr::LoadQuests()
usedMailTemplates.emplace(qinfo->_rewardMailTemplateId, qinfo->GetQuestId());
}
- if (qinfo->_nextQuestInChain)
+ if (uint32 nextQuestInChain = qinfo->_nextQuestInChain)
{
- auto qNextItr = _questTemplates.find(qinfo->_nextQuestInChain);
- if (qNextItr == _questTemplates.end())
+ if (nextQuestInChain >= _questTemplates.size() || !_questTemplates[nextQuestInChain])
{
TC_LOG_ERROR("sql.sql", "Quest %u has `NextQuestInChain` = %u but quest %u does not exist, quest chain will not work.",
qinfo->GetQuestId(), qinfo->_nextQuestInChain, qinfo->_nextQuestInChain);
@@ -4886,19 +4868,18 @@ void ObjectMgr::LoadQuests()
}
// fill additional data stores
- if (qinfo->_prevQuestID)
+ if (uint32 prevQuestId = std::abs(qinfo->_prevQuestID))
{
- if (_questTemplates.find(abs(qinfo->GetPrevQuestId())) == _questTemplates.end())
+ if (prevQuestId >= _questTemplates.size() || !_questTemplates[prevQuestId])
TC_LOG_ERROR("sql.sql", "Quest %d has PrevQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->GetPrevQuestId());
}
- if (qinfo->_nextQuestID)
+ if (uint32 nextQuestId = qinfo->_nextQuestID)
{
- auto qNextItr = _questTemplates.find(qinfo->_nextQuestID);
- if (qNextItr == _questTemplates.end())
+ if (nextQuestId >= _questTemplates.size() || !_questTemplates[nextQuestId])
TC_LOG_ERROR("sql.sql", "Quest %d has NextQuestId %u, but no such quest", qinfo->GetQuestId(), qinfo->_nextQuestID);
else
- qNextItr->second->DependentPreviousQuests.push_back(qinfo->GetQuestId());
+ _questTemplates[nextQuestId]->DependentPreviousQuests.push_back(qinfo->GetQuestId());
}
if (qinfo->_exclusiveGroup)
@@ -4940,7 +4921,7 @@ void ObjectMgr::LoadQuests()
if (Quest const* quest = GetQuestTemplate(paragonReputation->QuestID))
const_cast<Quest*>(quest)->SetSpecialFlag(QUEST_SPECIAL_FLAGS_REPEATABLE);
- TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " quests definitions in %u ms", _questTemplates.size(), GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u quests definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
void ObjectMgr::LoadQuestStartersAndEnders()
@@ -5493,10 +5474,14 @@ void ObjectMgr::LoadEventScripts()
std::set<uint32> evt_scripts;
// Load all possible script entries from gameobjects
- GameObjectTemplateContainer const* gotc = sObjectMgr->GetGameObjectTemplates();
- for (GameObjectTemplateContainer::const_iterator itr = gotc->begin(); itr != gotc->end(); ++itr)
- if (uint32 eventId = itr->second.GetEventScriptId())
+ for (auto const& gameObjectTemplate : _gameObjectTemplateStore)
+ {
+ if (!gameObjectTemplate)
+ continue;
+
+ if (uint32 eventId = gameObjectTemplate->GetEventScriptId())
evt_scripts.insert(eventId);
+ }
// Load all possible script entries from spells
for (SpellNameEntry const* spellNameEntry : sSpellNameStore)
@@ -5858,7 +5843,7 @@ void ObjectMgr::LoadInstanceEncounters()
continue;
}
- std::map<uint32, std::pair<uint32, DungeonEncounterEntry const*>>::const_iterator itr = dungeonLastBosses.find(lastEncounterDungeon);
+ auto itr = dungeonLastBosses.find(lastEncounterDungeon);
if (lastEncounterDungeon)
{
if (itr != dungeonLastBosses.end())
@@ -5914,14 +5899,14 @@ void ObjectMgr::LoadInstanceEncounters()
if (sDB2Manager.GetMapDifficultyData(dungeonEncounter->MapID, Difficulty(difficulty->ID)))
{
DungeonEncounterList& encounters = _dungeonEncounterStore[MAKE_PAIR64(dungeonEncounter->MapID, difficulty->ID)];
- encounters.push_back(new DungeonEncounter(dungeonEncounter, EncounterCreditType(creditType), creditEntry, lastEncounterDungeon));
+ encounters.push_back(std::make_unique<DungeonEncounter>(dungeonEncounter, EncounterCreditType(creditType), creditEntry, lastEncounterDungeon));
}
}
}
else
{
DungeonEncounterList& encounters = _dungeonEncounterStore[MAKE_PAIR64(dungeonEncounter->MapID, dungeonEncounter->DifficultyID)];
- encounters.push_back(new DungeonEncounter(dungeonEncounter, EncounterCreditType(creditType), creditEntry, lastEncounterDungeon));
+ encounters.push_back(std::make_unique<DungeonEncounter>(dungeonEncounter, EncounterCreditType(creditType), creditEntry, lastEncounterDungeon));
}
++count;
@@ -6451,6 +6436,11 @@ uint32 ObjectMgr::GetTaxiMountDisplayId(uint32 id, uint32 team, bool allowed_alt
return mountModel.CreatureDisplayID;
}
+Quest const* ObjectMgr::GetQuestTemplate(uint32 quest_id) const
+{
+ return quest_id < _questTemplates.size() ? _questTemplates[quest_id].get() : nullptr;
+}
+
void ObjectMgr::LoadGraveyardZones()
{
uint32 oldMSTime = getMSTime();
@@ -6721,7 +6711,7 @@ AccessRequirement const* ObjectMgr::GetAccessRequirement(uint32 mapid, Difficult
{
AccessRequirementContainer::const_iterator itr = _accessRequirementStore.find(MAKE_PAIR64(mapid, difficulty));
if (itr != _accessRequirementStore.end())
- return itr->second;
+ return itr->second.get();
return nullptr;
}
@@ -6859,13 +6849,7 @@ void ObjectMgr::LoadAccessRequirements()
{
uint32 oldMSTime = getMSTime();
- if (!_accessRequirementStore.empty())
- {
- for (AccessRequirementContainer::iterator itr = _accessRequirementStore.begin(); itr != _accessRequirementStore.end(); ++itr)
- delete itr->second;
-
- _accessRequirementStore.clear(); // need for reload case
- }
+ _accessRequirementStore.clear(); // need for reload case
// 0 1 2 3 4 5 6 7 8 9
QueryResult result = WorldDatabase.Query("SELECT mapid, difficulty, level_min, level_max, item, item2, quest_done_A, quest_done_H, completed_achievement, quest_failed_text FROM access_requirement");
@@ -6898,7 +6882,9 @@ void ObjectMgr::LoadAccessRequirements()
uint64 requirement_ID = MAKE_PAIR64(mapid, difficulty);
- AccessRequirement* ar = new AccessRequirement();
+ auto& ar = _accessRequirementStore[requirement_ID];
+ ar = std::make_unique<AccessRequirement>();
+
ar->levelMin = fields[2].GetUInt8();
ar->levelMax = fields[3].GetUInt8();
ar->item = fields[4].GetUInt32();
@@ -6954,8 +6940,6 @@ void ObjectMgr::LoadAccessRequirements()
ar->achievement = 0;
}
}
-
- _accessRequirementStore[requirement_ID] = ar;
++count;
} while (result->NextRow());
@@ -7236,9 +7220,12 @@ void ObjectMgr::LoadGameObjectTemplate()
{
uint32 oldMSTime = getMSTime();
+ uint32 const maxdb2GameObjectId = sGameObjectsStore.GetNumRows();
+ _gameObjectTemplateStore.resize(maxdb2GameObjectId + 1);
for (GameObjectsEntry const* db2go : sGameObjectsStore)
{
- GameObjectTemplate& go = _gameObjectTemplateStore[db2go->ID];
+ _gameObjectTemplateStore[db2go->ID] = std::make_unique<GameObjectTemplate>();
+ GameObjectTemplate& go = *_gameObjectTemplateStore[db2go->ID].get();
go.entry = db2go->ID;
go.type = db2go->TypeID;
go.displayId = db2go->DisplayID;
@@ -7258,7 +7245,7 @@ void ObjectMgr::LoadGameObjectTemplate()
"Data13, Data14, Data15, Data16, Data17, Data18, Data19, Data20, Data21, Data22, Data23, Data24, Data25, Data26, Data27, Data28, "
// 37 38 39 40 41 42 43 44
"Data29, Data30, Data31, Data32, Data33, ContentTuningId, AIName, ScriptName "
- "FROM gameobject_template");
+ "FROM gameobject_template ORDER BY entry DESC");
if (!result)
{
@@ -7266,7 +7253,9 @@ void ObjectMgr::LoadGameObjectTemplate()
return;
}
- _gameObjectTemplateStore.reserve(result->GetRowCount());
+ uint32 const maxGameObjectId = (*result)[0].GetUInt32();
+ if (maxGameObjectId > maxdb2GameObjectId)
+ _gameObjectTemplateStore.resize(maxGameObjectId + 1);
uint32 count = 0;
do
{
@@ -7274,7 +7263,8 @@ void ObjectMgr::LoadGameObjectTemplate()
uint32 entry = fields[0].GetUInt32();
- GameObjectTemplate& got = _gameObjectTemplateStore[entry];
+ _gameObjectTemplateStore[entry] = std::make_unique<GameObjectTemplate>();
+ GameObjectTemplate& got = *_gameObjectTemplateStore[entry].get();
got.entry = entry;
got.type = uint32(fields[1].GetUInt8());
got.displayId = fields[2].GetUInt32();
@@ -7934,7 +7924,7 @@ void ObjectMgr::LoadQuestPOI()
{
uint32 oldMSTime = getMSTime();
- _questPOIStore.clear(); // need for reload case
+ _questPOIStore.clear(); // need for reload case
uint32 count = 0;
@@ -8063,13 +8053,15 @@ void ObjectMgr::LoadNPCSpellClickSpells()
// all spellclick data loaded, now we check if there are creatures with NPC_FLAG_SPELLCLICK but with no data
// NOTE: It *CAN* be the other way around: no spellclick flag but with spellclick data, in case of creature-only vehicle accessories
- CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
- for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
+ for (auto const& creatureTemplate : _creatureTemplateStore)
{
- if ((itr->second.npcflag & UNIT_NPC_FLAG_SPELLCLICK) && _spellClickInfoStore.find(itr->second.Entry) == _spellClickInfoStore.end())
+ if (!creatureTemplate)
+ continue;
+
+ if ((creatureTemplate->npcflag & UNIT_NPC_FLAG_SPELLCLICK) && _spellClickInfoStore.find(creatureTemplate->Entry) == _spellClickInfoStore.end())
{
- TC_LOG_ERROR("sql.sql", "npc_spellclick_spells: Creature template %u has UNIT_NPC_FLAG_SPELLCLICK but no data in spellclick table! Removing flag", itr->second.Entry);
- const_cast<CreatureTemplate*>(&itr->second)->npcflag &= ~UNIT_NPC_FLAG_SPELLCLICK;
+ TC_LOG_ERROR("sql.sql", "npc_spellclick_spells: Creature template %u has UNIT_NPC_FLAG_SPELLCLICK but no data in spellclick table! Removing flag", creatureTemplate->Entry);
+ const_cast<CreatureTemplate*>(creatureTemplate.get())->npcflag &= ~UNIT_NPC_FLAG_SPELLCLICK;
}
}
@@ -8128,7 +8120,7 @@ void ObjectMgr::LoadQuestRelationsHelper(QuestRelations& map, QuestRelationsReve
uint32 quest = result->Fetch()[1].GetUInt32();
uint32 poolId = result->Fetch()[2].GetUInt32();
- if (_questTemplates.find(quest) == _questTemplates.end())
+ if (quest >= _questTemplates.size() || !_questTemplates[quest])
{
TC_LOG_ERROR("sql.sql", "Table `%s`: Quest %u listed for entry %u does not exist.", table.c_str(), quest, id);
continue;
@@ -8397,7 +8389,7 @@ void ObjectMgr::LoadGameObjectForQuests()
_gameObjectForQuestStore.clear(); // need for reload case
- if (sObjectMgr->GetGameObjectTemplates()->empty())
+ if (_gameObjectTemplateStore.empty())
{
TC_LOG_INFO("server.loading", ">> Loaded 0 GameObjects for quests");
return;
@@ -8406,42 +8398,43 @@ void ObjectMgr::LoadGameObjectForQuests()
uint32 count = 0;
// collect GO entries for GO that must activated
- GameObjectTemplateContainer const* gotc = sObjectMgr->GetGameObjectTemplates();
- for (GameObjectTemplateContainer::const_iterator itr = gotc->begin(); itr != gotc->end(); ++itr)
+ for (auto const& gameObjectTemplate : _gameObjectTemplateStore)
{
- switch (itr->second.type)
+ if (!gameObjectTemplate)
+ continue;
+
+ switch (gameObjectTemplate->type)
{
case GAMEOBJECT_TYPE_QUESTGIVER:
- _gameObjectForQuestStore.insert(itr->second.entry);
+ _gameObjectForQuestStore.insert(gameObjectTemplate->entry);
++count;
break;
case GAMEOBJECT_TYPE_CHEST:
{
// scan GO chest with loot including quest items
- uint32 loot_id = (itr->second.GetLootId());
-
+ uint32 lootId = gameObjectTemplate->GetLootId();
// find quest loot for GO
- if (itr->second.chest.questID || LootTemplates_Gameobject.HaveQuestLootFor(loot_id))
+ if (gameObjectTemplate->chest.questID || LootTemplates_Gameobject.HaveQuestLootFor(lootId))
{
- _gameObjectForQuestStore.insert(itr->second.entry);
+ _gameObjectForQuestStore.insert(gameObjectTemplate->entry);
++count;
}
break;
}
case GAMEOBJECT_TYPE_GENERIC:
{
- if (itr->second.generic.questID > 0) //quests objects
+ if (gameObjectTemplate->generic.questID > 0) //quests objects
{
- _gameObjectForQuestStore.insert(itr->second.entry);
+ _gameObjectForQuestStore.insert(gameObjectTemplate->entry);
++count;
}
break;
}
case GAMEOBJECT_TYPE_GOOBER:
{
- if (itr->second.goober.questID > 0) //quests objects
+ if (gameObjectTemplate->goober.questID > 0) //quests objects
{
- _gameObjectForQuestStore.insert(itr->second.entry);
+ _gameObjectForQuestStore.insert(gameObjectTemplate->entry);
++count;
}
break;
@@ -8607,7 +8600,7 @@ int32 ObjectMgr::GetBaseReputationOf(FactionEntry const* factionEntry, uint8 rac
uint32 classMask = 1 << (playerClass - 1);
- for (int i = 0; i < 4; i++)
+ for (uint8 i = 0; i < 4; ++i)
{
if ((!factionEntry->ReputationClassMask[i] ||
factionEntry->ReputationClassMask[i] & classMask) &&
@@ -9022,7 +9015,7 @@ void ObjectMgr::LoadCreatureTrainers()
TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " default trainers in %u ms", _creatureDefaultTrainers.size(), GetMSTimeDiffToNow(oldMSTime));
}
-int ObjectMgr::LoadReferenceVendor(int32 vendor, int32 item, std::set<uint32> *skip_vendors)
+uint32 ObjectMgr::LoadReferenceVendor(int32 vendor, int32 item, std::set<uint32> *skip_vendors)
{
// find all items from the reference vendor
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_NPC_VENDOR_REF);
@@ -9551,14 +9544,16 @@ void ObjectMgr::LoadCreatureClassLevelStats()
}
while (result->NextRow());
- CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
- for (auto itr = ctc->begin(); itr != ctc->end(); ++itr)
+ for (auto const& creatureTemplate : _creatureTemplateStore)
{
- std::pair<int16, int16> levels = itr->second.GetMinMaxLevel();
+ if (!creatureTemplate)
+ continue;
+
+ std::pair<int16, int16> levels = creatureTemplate->GetMinMaxLevel();
for (int16 lvl = levels.first; lvl <= levels.second; ++lvl)
{
- if (_creatureBaseStatsStore.find(MAKE_PAIR16(lvl, itr->second.unit_class)) == _creatureBaseStatsStore.end())
- TC_LOG_ERROR("sql.sql", "Missing base stats for creature class %u level %u", itr->second.unit_class, lvl);
+ if (_creatureBaseStatsStore.find(MAKE_PAIR16(lvl, creatureTemplate->unit_class)) == _creatureBaseStatsStore.end())
+ TC_LOG_ERROR("sql.sql", "Missing base stats for creature class %u level %u", creatureTemplate->unit_class, lvl);
}
}
@@ -9985,11 +9980,7 @@ TerrainSwapInfo const* ObjectMgr::GetTerrainSwapInfo(uint32 terrainSwapId) const
GameObjectTemplate const* ObjectMgr::GetGameObjectTemplate(uint32 entry) const
{
- GameObjectTemplateContainer::const_iterator itr = _gameObjectTemplateStore.find(entry);
- if (itr != _gameObjectTemplateStore.end())
- return &(itr->second);
-
- return nullptr;
+ return entry < _gameObjectTemplateStore.size() ? _gameObjectTemplateStore[entry].get() : nullptr;
}
GameObjectTemplateAddon const* ObjectMgr::GetGameObjectTemplateAddon(uint32 entry) const
@@ -10003,11 +9994,12 @@ GameObjectTemplateAddon const* ObjectMgr::GetGameObjectTemplateAddon(uint32 entr
CreatureTemplate const* ObjectMgr::GetCreatureTemplate(uint32 entry) const
{
- CreatureTemplateContainer::const_iterator itr = _creatureTemplateStore.find(entry);
- if (itr != _creatureTemplateStore.end())
- return &(itr->second);
+ return entry < _creatureTemplateStore.size() ? _creatureTemplateStore[entry].get() : nullptr;
+}
- return nullptr;
+QuestPOIData const* ObjectMgr::GetQuestPOIData(int32 QuestID)
+{
+ return Trinity::Containers::MapGetValuePtr(_questPOIStore, QuestID);
}
VehicleTemplate const* ObjectMgr::GetVehicleTemplate(Vehicle* veh) const
@@ -10034,7 +10026,7 @@ VehicleAccessoryList const* ObjectMgr::GetVehicleAccessoryList(Vehicle* veh) con
DungeonEncounterList const* ObjectMgr::GetDungeonEncounterList(uint32 mapId, Difficulty difficulty) const
{
- DungeonEncounterContainer::const_iterator itr = _dungeonEncounterStore.find(MAKE_PAIR64(mapId, difficulty));
+ auto itr = _dungeonEncounterStore.find(MAKE_PAIR64(mapId, difficulty));
if (itr != _dungeonEncounterStore.end())
return &itr->second;
return nullptr;
@@ -10046,10 +10038,10 @@ PlayerInfo const* ObjectMgr::GetPlayerInfo(uint32 race, uint32 class_) const
return nullptr;
if (class_ >= MAX_CLASSES)
return nullptr;
- PlayerInfo const* info = _playerInfo[race][class_];
+ auto const& info = _playerInfo[race][class_];
if (!info)
return nullptr;
- return info;
+ return info.get();
}
void ObjectMgr::LoadRaceAndClassExpansionRequirements()
@@ -10359,18 +10351,21 @@ void ObjectMgr::InitializeQueriesData(QueryDataGroup mask)
// Initialize Query data for creatures
if (mask & QUERY_DATA_CREATURES)
- for (auto& creaturePair : _creatureTemplateStore)
- creaturePair.second.InitializeQueryData();
+ for (auto const& creatureTemplate : _creatureTemplateStore)
+ if (creatureTemplate)
+ creatureTemplate->InitializeQueryData();
// Initialize Query Data for gameobjects
if (mask & QUERY_DATA_GAMEOBJECTS)
- for (auto& gameobjectPair : _gameObjectTemplateStore)
- gameobjectPair.second.InitializeQueryData();
+ for (auto const& gameObjectTemplate : _gameObjectTemplateStore)
+ if (gameObjectTemplate)
+ gameObjectTemplate->InitializeQueryData();
// Initialize Query Data for quests
if (mask & QUERY_DATA_QUESTS)
- for (auto& questPair : _questTemplates)
- questPair.second->InitializeQueryData();
+ for (auto const& questTemplate : _questTemplates)
+ if (questTemplate)
+ questTemplate->InitializeQueryData();
// Initialize Quest POI data
if (mask & QUERY_DATA_POIS)