AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
ObjectMgr Class Reference

#include "ObjectMgr.h"

Classes

struct  GameobjectInstanceSavedState
 

Public Types

typedef std::unordered_map< uint32, Item * > ItemMap
 
typedef std::unordered_map< uint32, Quest * > QuestMap
 
typedef std::unordered_map< uint32, AreaTriggerAreaTriggerContainer
 
typedef std::unordered_map< uint32, AreaTriggerTeleportAreaTriggerTeleportContainer
 
typedef std::unordered_map< uint32, uint32AreaTriggerScriptContainer
 
typedef std::unordered_map< uint32, std::unordered_map< uint8, DungeonProgressionRequirements * > > DungeonProgressionRequirementsContainer
 
typedef std::unordered_map< uint32, RepRewardRateRepRewardRateContainer
 
typedef std::unordered_map< uint32, ReputationOnKillEntryRepOnKillContainer
 
typedef std::unordered_map< uint32, RepSpilloverTemplateRepSpilloverTemplateContainer
 
typedef std::unordered_map< uint32, PointOfInterestPointOfInterestContainer
 
typedef std::vector< std::string > ScriptNameContainer
 
typedef std::map< uint32, uint32CharacterConversionMap
 
typedef std::unordered_map< ObjectGuid::LowType, std::vector< float > > CreatureSparringContainer
 
typedef std::multimap< int32, uint32ExclusiveQuestGroups
 
typedef std::pair< ExclusiveQuestGroups::const_iterator, ExclusiveQuestGroups::const_iterator > ExclusiveQuestGroupsBounds
 
typedef std::unordered_map< uint32, std::vector< uint32 > > BreadcrumbQuestMap
 

Public Member Functions

GameObjectTemplate const * GetGameObjectTemplate (uint32 entry)
 
bool IsGameObjectStaticTransport (uint32 entry)
 
GameObjectTemplateContainer const * GetGameObjectTemplates () const
 
int LoadReferenceVendor (int32 vendor, int32 item_id, std::set< uint32 > *skip_vendors)
 
void LoadGameObjectTemplate ()
 
void LoadGameObjectTemplateAddons ()
 
void AddGameobjectInfo (GameObjectTemplate *goinfo)
 
CreatureTemplate const * GetCreatureTemplate (uint32 entry)
 
CreatureTemplateContainer const * GetCreatureTemplates () const
 
CreatureModelInfo const * GetCreatureModelInfo (uint32 modelId) const
 
CreatureModelInfo const * GetCreatureModelRandomGender (CreatureModel *model, CreatureTemplate const *creatureTemplate) const
 
EquipmentInfo const * GetEquipmentInfo (uint32 entry, int8 &id)
 
CreatureAddon const * GetCreatureAddon (ObjectGuid::LowType lowguid)
 
GameObjectAddon const * GetGameObjectAddon (ObjectGuid::LowType lowguid)
 
GameObjectTemplateAddon const * GetGameObjectTemplateAddon (uint32 entry) const
 
CreatureAddon const * GetCreatureTemplateAddon (uint32 entry)
 
CreatureMovementData const * GetCreatureMovementOverride (ObjectGuid::LowType spawnId) const
 
ItemTemplate const * GetItemTemplate (uint32 entry)
 
ItemTemplateContainer const * GetItemTemplateStore () const
 
std::vector< ItemTemplate * > const * GetItemTemplateStoreFast () const
 
uint32 GetModelForTotem (SummonSlot totemSlot, Races race) const
 
uint32 GetModelForShapeshift (ShapeshiftForm form, Player *player) const
 
ItemSetNameEntry const * GetItemSetNameEntry (uint32 itemId)
 
InstanceTemplate const * GetInstanceTemplate (uint32 mapId)
 
PetLevelInfo const * GetPetLevelInfo (uint32 creature_id, uint8 level) const
 
PlayerClassInfo const * GetPlayerClassInfo (uint32 class_) const
 
void GetPlayerClassLevelInfo (uint32 class_, uint8 level, PlayerClassLevelInfo *info) const
 
PlayerInfo const * GetPlayerInfo (uint32 race, uint32 class_) const
 
void GetPlayerLevelInfo (uint32 race, uint32 class_, uint8 level, PlayerLevelInfo *info) const
 
uint32 GetNearestTaxiNode (float x, float y, float z, uint32 mapid, uint32 teamId)
 
void GetTaxiPath (uint32 source, uint32 destination, uint32 &path, uint32 &cost)
 
uint32 GetTaxiMountDisplayId (uint32 id, TeamId teamId, bool allowed_alt_team=false)
 
GameObjectQuestItemList const * GetGameObjectQuestItemList (uint32 id) const
 
GameObjectQuestItemMap const * GetGameObjectQuestItemMap () const
 
CreatureQuestItemList const * GetCreatureQuestItemList (uint32 id) const
 
CreatureQuestItemMap const * GetCreatureQuestItemMap () const
 
Quest const * GetQuestTemplate (uint32 quest_id) const
 
QuestMap const & GetQuestTemplates () const
 
uint32 GetQuestForAreaTrigger (uint32 Trigger_ID) const
 
bool IsTavernAreaTrigger (uint32 triggerID, uint32 faction) const
 
GossipText const * GetGossipText (uint32 Text_ID) const
 
AreaTrigger const * GetAreaTrigger (uint32 trigger) const
 
AreaTriggerTeleport const * GetAreaTriggerTeleport (uint32 trigger) const
 
DungeonProgressionRequirements const * GetAccessRequirement (uint32 mapid, Difficulty difficulty) const
 
AreaTriggerTeleport const * GetGoBackTrigger (uint32 Map) const
 
AreaTriggerTeleport const * GetMapEntranceTrigger (uint32 Map) const
 
AreaTriggerScriptContainer const & GetAllAreaTriggerScriptData () const
 
uint32 GetAreaTriggerScriptId (uint32 trigger_id)
 
SpellScriptsBounds GetSpellScriptsBounds (uint32 spell_id)
 
RepRewardRate const * GetRepRewardRate (uint32 factionId) const
 
ReputationOnKillEntry const * GetReputationOnKilEntry (uint32 id) const
 
int32 GetBaseReputationOf (FactionEntry const *factionEntry, uint8 race, uint8 playerClass)
 
RepSpilloverTemplate const * GetRepSpilloverTemplate (uint32 factionId) const
 
PointOfInterest const * GetPointOfInterest (uint32 id) const
 
QuestPOIVector const * GetQuestPOIVector (uint32 questId)
 
VehicleAccessoryList const * GetVehicleAccessoryList (Vehicle *veh) const
 
DungeonEncounterList const * GetDungeonEncounterList (uint32 mapId, Difficulty difficulty)
 
void LoadQuests ()
 
void LoadQuestMoneyRewards ()
 
void LoadQuestStartersAndEnders ()
 
void LoadGameobjectQuestStarters ()
 
void LoadGameobjectQuestEnders ()
 
void LoadCreatureQuestStarters ()
 
void LoadCreatureQuestEnders ()
 
QuestRelationsGetGOQuestRelationMap ()
 
QuestRelationsGetGOQuestInvolvedRelationMap ()
 
QuestRelationBounds GetGOQuestRelationBounds (uint32 go_entry)
 
QuestRelationBounds GetGOQuestInvolvedRelationBounds (uint32 go_entry)
 
QuestRelationsGetCreatureQuestRelationMap ()
 
QuestRelationsGetCreatureQuestInvolvedRelationMap ()
 
QuestRelationBounds GetCreatureQuestRelationBounds (uint32 creature_entry)
 
QuestRelationBounds GetCreatureQuestInvolvedRelationBounds (uint32 creature_entry)
 
void LoadEventScripts ()
 
void LoadSpellScripts ()
 
void LoadWaypointScripts ()
 
void LoadSpellScriptNames ()
 
void ValidateSpellScripts ()
 
void InitializeSpellInfoPrecomputedData ()
 
bool LoadModuleStrings ()
 
bool LoadModuleStringsLocale ()
 
bool LoadAcoreStrings ()
 
void LoadBroadcastTexts ()
 
void LoadBroadcastTextLocales ()
 
void LoadCreatureClassLevelStats ()
 
void LoadCreatureLocales ()
 
void LoadCreatureTemplates ()
 
void LoadCreatureTemplate (Field *fields, bool triggerHook=false)
 Loads a creature template from a database result.
 
void LoadCreatureTemplateModels ()
 
void LoadCreatureTemplateAddons ()
 
void LoadCreatureTemplateResistances ()
 
void LoadCreatureTemplateSpells ()
 
void LoadCreatureCustomIDs ()
 Load config option Creatures.CustomIDs into Store.
 
void CheckCreatureTemplate (CreatureTemplate const *cInfo)
 
void CheckCreatureMovement (char const *table, uint64 id, CreatureMovementData &creatureMovement)
 
void LoadGameObjectQuestItems ()
 
void LoadCreatureQuestItems ()
 
void LoadTempSummons ()
 
void LoadCreatures ()
 
void LoadCreatureSparring ()
 
void LoadLinkedRespawn ()
 
bool SetCreatureLinkedRespawn (ObjectGuid::LowType guid, ObjectGuid::LowType linkedGuid)
 
void LoadCreatureAddons ()
 
void LoadGameObjectAddons ()
 
void LoadCreatureModelInfo ()
 
void LoadPlayerTotemModels ()
 
void LoadPlayerShapeshiftModels ()
 
void LoadEquipmentTemplates ()
 
void LoadCreatureMovementOverrides ()
 
void LoadGameObjectLocales ()
 
void LoadGameobjects ()
 
void LoadItemTemplates ()
 
void LoadItemLocales ()
 
void LoadItemSetNames ()
 
void LoadItemSetNameLocales ()
 
void LoadQuestLocales ()
 
void LoadNpcTextLocales ()
 
void LoadQuestOfferRewardLocale ()
 
void LoadQuestRequestItemsLocale ()
 
void LoadPageTextLocales ()
 
void LoadGossipMenuItemsLocales ()
 
void LoadPointOfInterestLocales ()
 
void LoadQuestGreetingsLocales ()
 
void LoadInstanceTemplate ()
 
void LoadInstanceEncounters ()
 
void LoadMailLevelRewards ()
 
void LoadVehicleTemplateAccessories ()
 
void LoadVehicleAccessories ()
 
void LoadVehicleSeatAddon ()
 
void LoadGossipText ()
 
void LoadAreaTriggers ()
 
void LoadAreaTriggerTeleports ()
 
void LoadAccessRequirements ()
 
void LoadQuestAreaTriggers ()
 
void LoadQuestGreetings ()
 
void LoadAreaTriggerScripts ()
 
void LoadTavernAreaTriggers ()
 
void LoadGameObjectForQuests ()
 
void LoadPageTexts ()
 
PageText const * GetPageText (uint32 pageEntry)
 
void LoadPlayerInfo ()
 
void LoadPetLevelInfo ()
 
void LoadExplorationBaseXP ()
 
void LoadPetNames ()
 
void LoadPetNamesLocales ()
 
void LoadPetNumber ()
 
void LoadFishingBaseSkillLevel ()
 
void ChangeFishingBaseSkillLevel (uint32 entry, int32 skill)
 
void LoadReputationRewardRate ()
 
void LoadReputationOnKill ()
 
void LoadReputationSpilloverTemplate ()
 
void LoadPointsOfInterest ()
 
void LoadQuestPOI ()
 
void LoadNPCSpellClickSpells ()
 
void LoadGameTele ()
 
void LoadGossipMenu ()
 
void LoadGossipMenuItems ()
 
void LoadVendors ()
 
void LoadTrainers ()
 
void LoadCreatureDefaultTrainers ()
 
std::string GeneratePetName (uint32 entry)
 
std::string GeneratePetNameLocale (uint32 entry, LocaleConstant locale)
 
uint32 GetBaseXP (uint8 level)
 
uint32 GetXPForLevel (uint8 level) const
 
int32 GetFishingBaseSkillLevel (uint32 entry) const
 
void ReturnOrDeleteOldMails (bool serverUp)
 
CreatureBaseStats const * GetCreatureBaseStats (uint8 level, uint8 unitClass)
 
void SetHighestGuids ()
 
template<HighGuid type>
ObjectGuidGeneratorBaseGetGenerator ()
 
uint32 GenerateAuctionID ()
 
uint64 GenerateEquipmentSetGuid ()
 
uint32 GenerateMailID ()
 
uint32 GeneratePetNumber ()
 
ObjectGuid::LowType GenerateCreatureSpawnId ()
 
ObjectGuid::LowType GenerateGameObjectSpawnId ()
 
std::vector< uint32 > const * GetBreadcrumbsForQuest (uint32 questId) const
 
MailLevelReward const * GetMailLevelReward (uint32 level, uint32 raceMask)
 
CellObjectGuids const & GetGridObjectGuids (uint16 mapid, uint8 spawnMode, uint32 gridId)
 
CellObjectGuidsMap const & GetMapObjectGuids (uint16 mapid, uint8 spawnMode)
 
std::vector< TempSummonData > const * GetSummonGroup (uint32 summonerId, SummonerType summonerType, uint8 group) const
 
BroadcastText const * GetBroadcastText (uint32 id) const
 
CreatureDataContainer const & GetAllCreatureData () const
 
CreatureData const * GetCreatureData (ObjectGuid::LowType spawnId) const
 
CreatureSparringContainer const & GetSparringData () const
 
CreatureDataNewOrExistCreatureData (ObjectGuid::LowType spawnId)
 
CreatureData const * LoadCreatureDataFromDB (ObjectGuid::LowType spawnId)
 Loads a single creature spawn entry from the database into the data store cache.
 
void DeleteCreatureData (ObjectGuid::LowType spawnId)
 
ObjectGuid GetLinkedRespawnGuid (ObjectGuid guid) const
 
GameObjectDataContainer const & GetAllGOData () const
 
GameObjectData const * GetGameObjectData (ObjectGuid::LowType spawnId) const
 
CreatureLocale const * GetCreatureLocale (uint32 entry) const
 
GameObjectLocale const * GetGameObjectLocale (uint32 entry) const
 
ItemLocale const * GetItemLocale (uint32 entry) const
 
ItemSetNameLocale const * GetItemSetNameLocale (uint32 entry) const
 
PageTextLocale const * GetPageTextLocale (uint32 entry) const
 
QuestLocale const * GetQuestLocale (uint32 entry) const
 
GossipMenuItemsLocale const * GetGossipMenuItemsLocale (uint32 entry) const
 
PointOfInterestLocale const * GetPointOfInterestLocale (uint32 poi_id) const
 
QuestOfferRewardLocale const * GetQuestOfferRewardLocale (uint32 entry) const
 
QuestRequestItemsLocale const * GetQuestRequestItemsLocale (uint32 entry) const
 
NpcTextLocale const * GetNpcTextLocale (uint32 entry) const
 
QuestGreeting const * GetQuestGreeting (TypeID type, uint32 id) const
 
GameObjectDataNewGOData (ObjectGuid::LowType guid)
 
GameObjectData const * LoadGameObjectDataFromDB (ObjectGuid::LowType spawnId)
 Loads a single gameobject spawn entry from the database into the data store cache.
 
void DeleteGOData (ObjectGuid::LowType guid)
 
ModuleString const * GetModuleString (std::string module, uint32 id) const
 
std::string const * GetModuleString (std::string module, uint32 id, LocaleConstant locale) const
 
AcoreString const * GetAcoreString (uint32 entry) const
 
std::string GetAcoreString (uint32 entry, LocaleConstant locale) const
 
std::string GetAcoreStringForDBCLocale (uint32 entry) const
 
LocaleConstant GetDBCLocaleIndex () const
 
void SetDBCLocaleIndex (LocaleConstant locale)
 
void AddCreatureToGrid (ObjectGuid::LowType guid, CreatureData const *data)
 
void RemoveCreatureFromGrid (ObjectGuid::LowType guid, CreatureData const *data)
 
void AddGameobjectToGrid (ObjectGuid::LowType guid, GameObjectData const *data)
 
void RemoveGameobjectFromGrid (ObjectGuid::LowType guid, GameObjectData const *data)
 
ObjectGuid::LowType AddGOData (uint32 entry, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay=0, float rotation0=0, float rotation1=0, float rotation2=0, float rotation3=0)
 
ObjectGuid::LowType AddCreData (uint32 entry, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay=0)
 
void LoadReservedPlayerNamesDB ()
 
void LoadReservedPlayerNamesDBC ()
 
bool IsReservedName (std::string_view name) const
 
void AddReservedPlayerName (std::string const &name)
 
void LoadProfanityNamesFromDB ()
 
void LoadProfanityNamesFromDBC ()
 
bool IsProfanityName (std::string_view name) const
 
void AddProfanityPlayerName (std::string const &name)
 
GameTele const * GetGameTele (uint32 id) const
 
GameTele const * GetGameTele (std::string_view name, bool exactSearch=false) const
 
GameTeleContainer const & GetGameTeleMap () const
 
bool AddGameTele (GameTele &data)
 
bool DeleteGameTele (std::string_view name)
 
Trainer::TrainerGetTrainer (uint32 creatureId)
 
VendorItemData const * GetNpcVendorItemList (uint32 entry) const
 
void AddVendorItem (uint32 entry, uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedCost, bool persist=true)
 
bool RemoveVendorItem (uint32 entry, uint32 item, bool persist=true)
 
bool IsVendorItemValid (uint32 vendor_entry, uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost, Player *player=nullptr, std::set< uint32 > *skip_vendors=nullptr, uint32 ORnpcflag=0) const
 
void LoadScriptNames ()
 
ScriptNameContainerGetScriptNames ()
 
std::string const & GetScriptName (uint32 id) const
 
uint32 GetScriptId (std::string const &name)
 
SpellClickInfoMapBounds GetSpellClickInfoMapBounds (uint32 creature_id) const
 
GossipMenusMapBounds GetGossipMenusMapBounds (uint32 uiMenuId) const
 
GossipMenusMapBoundsNonConst GetGossipMenusMapBoundsNonConst (uint32 uiMenuId)
 
GossipMenuItemsMapBounds GetGossipMenuItemsMapBounds (uint32 uiMenuId) const
 
GossipMenuItemsMapBoundsNonConst GetGossipMenuItemsMapBoundsNonConst (uint32 uiMenuId)
 
void LoadFactionChangeAchievements ()
 
void LoadFactionChangeItems ()
 
void LoadFactionChangeQuests ()
 
void LoadFactionChangeReputations ()
 
void LoadFactionChangeSpells ()
 
void LoadFactionChangeTitles ()
 
bool IsTransportMap (uint32 mapId) const
 
VehicleSeatAddon const * GetVehicleSeatAddon (uint32 seatId) const
 
uint32 GetQuestMoneyReward (uint8 level, uint32 questMoneyDifficulty) const
 

Static Public Member Functions

static ObjectMgrinstance ()
 
static CreatureModel const * ChooseDisplayId (CreatureTemplate const *cinfo, CreatureData const *data=nullptr)
 
static void ChooseCreatureFlags (CreatureTemplate const *cinfo, uint32 &npcflag, uint32 &unit_flags, uint32 &dynamicflags, CreatureData const *data=nullptr)
 
static uint8 CheckPlayerName (std::string_view name, bool create=false)
 
static PetNameInvalidReason CheckPetName (std::string_view name)
 
static bool IsValidCharterName (std::string_view name)
 
static bool IsValidChannelName (std::string const &name)
 
static bool CheckDeclinedNames (std::wstring w_ownname, DeclinedName const &names)
 
static void AddLocaleString (std::string &&s, LocaleConstant locale, std::vector< std::string > &data)
 
static std::string_view GetLocaleString (std::vector< std::string > const &data, std::size_t locale)
 
static void GetLocaleString (const std::vector< std::string > &data, int loc_idx, std::string &value)
 

Public Attributes

ExclusiveQuestGroups mExclusiveQuestGroups
 
BreadcrumbQuestMap _breadcrumbsForQuest
 
CharacterConversionMap FactionChangeAchievements
 
CharacterConversionMap FactionChangeItems
 
CharacterConversionMap FactionChangeQuests
 
CharacterConversionMap FactionChangeReputation
 
CharacterConversionMap FactionChangeSpells
 
CharacterConversionMap FactionChangeTitles
 

Private Types

enum  CreatureLinkedRespawnType {
  CREATURE_TO_CREATURE ,
  CREATURE_TO_GO ,
  GO_TO_GO ,
  GO_TO_CREATURE
}
 
typedef std::unordered_map< uint32, GossipTextGossipTextContainer
 
typedef std::unordered_map< uint32, uint32QuestAreaTriggerContainer
 
typedef std::unordered_map< uint32, uint32TavernAreaTriggerContainer
 
typedef std::set< std::wstring > ReservedNamesContainer
 
typedef std::set< std::wstring > ProfanityNamesContainer
 
typedef std::map< uint32, PetLevelInfo * > PetLevelInfoContainer
 
typedef std::vector< uint32PlayerXPperLevel
 
typedef std::map< uint32, uint32BaseXPContainer
 
typedef std::map< uint32, int32FishingBaseSkillContainer
 
typedef std::map< uint32, std::vector< std::string > > HalfNameContainer
 
typedef std::map< std::pair< uint32, LocaleConstant >, std::vector< std::string > > HalfNameContainerLocale
 
typedef std::unordered_map< uint32, ItemSetNameEntryItemSetNameContainer
 

Private Member Functions

 ObjectMgr ()
 
 ~ObjectMgr ()
 
template<HighGuid high>
ObjectGuidGeneratorBaseGetGuidSequenceGenerator ()
 
void LoadScripts (ScriptsType type)
 
void LoadQuestRelationsHelper (QuestRelations &map, std::string const &table, bool starter, bool go)
 
void PlayerCreateInfoAddItemHelper (uint32 race_, uint32 class_, uint32 itemId, int32 count)
 
void BuildPlayerLevelInfo (uint8 race, uint8 class_, uint8 level, PlayerLevelInfo *plinfo) const
 

Private Attributes

uint32 _auctionId
 
uint64 _equipmentSetGuid
 
uint32 _mailId
 
std::mutex _mailIdMutex
 
uint32 _hiPetNumber
 
std::mutex _hiPetNumberMutex
 
ObjectGuid::LowType _creatureSpawnId
 
ObjectGuid::LowType _gameObjectSpawnId
 
std::map< HighGuid, std::unique_ptr< ObjectGuidGeneratorBase > > _guidGenerators
 
QuestMap _questTemplates
 
std::vector< Quest * > _questTemplatesFast
 
QuestAreaTriggerContainer _questAreaTriggerStore
 
TavernAreaTriggerContainer _tavernAreaTriggerStore
 
GossipTextContainer _gossipTextStore
 
QuestGreetingContainer _questGreetingStore
 
AreaTriggerContainer _areaTriggerStore
 
AreaTriggerTeleportContainer _areaTriggerTeleportStore
 
AreaTriggerScriptContainer _areaTriggerScriptStore
 
DungeonProgressionRequirementsContainer _accessRequirementStore
 
DungeonEncounterContainer _dungeonEncounterStore
 
RepRewardRateContainer _repRewardRateStore
 
RepOnKillContainer _repOnKillStore
 
RepSpilloverTemplateContainer _repSpilloverTemplateStore
 
GossipMenusContainer _gossipMenusStore
 
GossipMenuItemsContainer _gossipMenuItemsStore
 
PointOfInterestContainer _pointsOfInterestStore
 
QuestPOIContainer _questPOIStore
 
QuestRelations _goQuestRelations
 
QuestRelations _goQuestInvolvedRelations
 
QuestRelations _creatureQuestRelations
 
QuestRelations _creatureQuestInvolvedRelations
 
ReservedNamesContainer _reservedNamesStore
 
ProfanityNamesContainer _profanityNamesStore
 
GameTeleContainer _gameTeleStore
 
ScriptNameContainer _scriptNamesStore
 
SpellClickInfoContainer _spellClickInfoStore
 
SpellScriptsContainer _spellScriptsStore
 
VehicleAccessoryContainer _vehicleTemplateAccessoryStore
 
VehicleAccessoryContainer _vehicleAccessoryStore
 
VehicleSeatAddonContainer _vehicleSeatAddonStore
 
LocaleConstant DBCLocaleIndex
 
PageTextContainer _pageTextStore
 
InstanceTemplateContainer _instanceTemplateStore
 
CreatureSparringContainer _creatureSparringStore
 
MailLevelRewardContainer _mailLevelRewardStore
 
CreatureBaseStatsContainer _creatureBaseStatsStore
 
PetLevelInfoContainer _petInfoStore
 
PlayerClassInfo_playerClassInfo [MAX_CLASSES]
 
PlayerInfo_playerInfo [MAX_RACES][MAX_CLASSES]
 
PlayerXPperLevel _playerXPperLevel
 
BaseXPContainer _baseXPTable
 
FishingBaseSkillContainer _fishingBaseForAreaStore
 
HalfNameContainer _petHalfName0
 
HalfNameContainer _petHalfName1
 
HalfNameContainerLocale _petHalfLocaleName0
 
HalfNameContainerLocale _petHalfLocaleName1
 
ItemSetNameContainer _itemSetNameStore
 
MapObjectGuids _mapObjectGuidsStore
 
CellObjectGuidsMap _emptyCellObjectGuidsMap
 
CellObjectGuids _emptyCellObjectGuids
 
CreatureDataContainer _creatureDataStore
 
CreatureTemplateContainer _creatureTemplateStore
 
CreatureCustomIDsContainer _creatureCustomIDsStore
 
std::vector< CreatureTemplate * > _creatureTemplateStoreFast
 
CreatureModelContainer _creatureModelStore
 
CreatureAddonContainer _creatureAddonStore
 
CreatureAddonContainer _creatureTemplateAddonStore
 
std::unordered_map< ObjectGuid::LowType, CreatureMovementData_creatureMovementOverrides
 
GameObjectAddonContainer _gameObjectAddonStore
 
GameObjectQuestItemMap _gameObjectQuestItemStore
 
CreatureQuestItemMap _creatureQuestItemStore
 
EquipmentInfoContainer _equipmentInfoStore
 
LinkedRespawnContainer _linkedRespawnStore
 
CreatureLocaleContainer _creatureLocaleStore
 
GameObjectDataContainer _gameObjectDataStore
 
GameObjectLocaleContainer _gameObjectLocaleStore
 
GameObjectTemplateContainer _gameObjectTemplateStore
 
GameObjectTemplateAddonContainer _gameObjectTemplateAddonStore
 
TempSummonDataContainer _tempSummonDataStore
 Stores temp summon data grouped by summoner's entry, summoner's type and group id.
 
BroadcastTextContainer _broadcastTextStore
 
ItemTemplateContainer _itemTemplateStore
 
std::vector< ItemTemplate * > _itemTemplateStoreFast
 
ItemLocaleContainer _itemLocaleStore
 
ItemSetNameLocaleContainer _itemSetNameLocaleStore
 
QuestLocaleContainer _questLocaleStore
 
QuestOfferRewardLocaleContainer _questOfferRewardLocaleStore
 
QuestRequestItemsLocaleContainer _questRequestItemsLocaleStore
 
NpcTextLocaleContainer _npcTextLocaleStore
 
PageTextLocaleContainer _pageTextLocaleStore
 
ModuleStringContainer _moduleStringStore
 
AcoreStringContainer _acoreStringStore
 
GossipMenuItemsLocaleContainer _gossipMenuItemsLocaleStore
 
PointOfInterestLocaleContainer _pointOfInterestLocaleStore
 
CacheVendorItemContainer _cacheVendorItemStore
 
std::unordered_map< uint32, Trainer::Trainer_trainers
 
std::unordered_map< uint32, uint32_creatureDefaultTrainers
 
std::set< uint32_difficultyEntries [MAX_DIFFICULTY - 1]
 
std::set< uint32_hasDifficultyEntries [MAX_DIFFICULTY - 1]
 
std::set< uint32_transportMaps
 
PlayerTotemModelMap _playerTotemModel
 
PlayerShapeshiftModelMap _playerShapeshiftModel
 
QuestMoneyRewardStore _questMoneyRewards
 
std::vector< GameobjectInstanceSavedStateGameobjectInstanceSavedStateList
 

Friends

class PlayerDumpReader
 

Detailed Description

Member Typedef Documentation

◆ AreaTriggerContainer

typedef std::unordered_map<uint32, AreaTrigger> ObjectMgr::AreaTriggerContainer

◆ AreaTriggerScriptContainer

typedef std::unordered_map<uint32, uint32> ObjectMgr::AreaTriggerScriptContainer

◆ AreaTriggerTeleportContainer

◆ BaseXPContainer

typedef std::map<uint32, uint32> ObjectMgr::BaseXPContainer
private

◆ BreadcrumbQuestMap

typedef std::unordered_map<uint32, std::vector<uint32> > ObjectMgr::BreadcrumbQuestMap

◆ CharacterConversionMap

◆ CreatureSparringContainer

typedef std::unordered_map<ObjectGuid::LowType, std::vector<float> > ObjectMgr::CreatureSparringContainer

◆ DungeonProgressionRequirementsContainer

◆ ExclusiveQuestGroups

typedef std::multimap<int32, uint32> ObjectMgr::ExclusiveQuestGroups

◆ ExclusiveQuestGroupsBounds

typedef std::pair<ExclusiveQuestGroups::const_iterator, ExclusiveQuestGroups::const_iterator> ObjectMgr::ExclusiveQuestGroupsBounds

◆ FishingBaseSkillContainer

◆ GossipTextContainer

typedef std::unordered_map<uint32, GossipText> ObjectMgr::GossipTextContainer
private

◆ HalfNameContainer

typedef std::map<uint32, std::vector<std::string> > ObjectMgr::HalfNameContainer
private

◆ HalfNameContainerLocale

typedef std::map<std::pair<uint32, LocaleConstant>, std::vector<std::string> > ObjectMgr::HalfNameContainerLocale
private

◆ ItemMap

typedef std::unordered_map<uint32, Item*> ObjectMgr::ItemMap

◆ ItemSetNameContainer

typedef std::unordered_map<uint32, ItemSetNameEntry> ObjectMgr::ItemSetNameContainer
private

◆ PetLevelInfoContainer

◆ PlayerXPperLevel

typedef std::vector<uint32> ObjectMgr::PlayerXPperLevel
private

◆ PointOfInterestContainer

◆ ProfanityNamesContainer

typedef std::set<std::wstring> ObjectMgr::ProfanityNamesContainer
private

◆ QuestAreaTriggerContainer

typedef std::unordered_map<uint32, uint32> ObjectMgr::QuestAreaTriggerContainer
private

◆ QuestMap

typedef std::unordered_map<uint32, Quest*> ObjectMgr::QuestMap

◆ RepOnKillContainer

◆ RepRewardRateContainer

◆ RepSpilloverTemplateContainer

◆ ReservedNamesContainer

typedef std::set<std::wstring> ObjectMgr::ReservedNamesContainer
private

◆ ScriptNameContainer

typedef std::vector<std::string> ObjectMgr::ScriptNameContainer

◆ TavernAreaTriggerContainer

typedef std::unordered_map<uint32, uint32> ObjectMgr::TavernAreaTriggerContainer
private

Member Enumeration Documentation

◆ CreatureLinkedRespawnType

Enumerator
CREATURE_TO_CREATURE 
CREATURE_TO_GO 
GO_TO_GO 
GO_TO_CREATURE 
1662 {
1664 CREATURE_TO_GO, // Creature is dependant on GO
1665 GO_TO_GO,
1666 GO_TO_CREATURE, // GO is dependant on creature
1667 };
@ CREATURE_TO_GO
Definition ObjectMgr.h:1664
@ CREATURE_TO_CREATURE
Definition ObjectMgr.h:1663
@ GO_TO_GO
Definition ObjectMgr.h:1665
@ GO_TO_CREATURE
Definition ObjectMgr.h:1666

Constructor & Destructor Documentation

◆ ObjectMgr()

ObjectMgr::ObjectMgr ( )
private
299 :
300 _auctionId(1),
302 _mailId(1),
303 _hiPetNumber(1),
307{
308 for (uint8 i = 0; i < MAX_CLASSES; ++i)
309 {
310 _playerClassInfo[i] = nullptr;
311 for (uint8 j = 0; j < MAX_RACES; ++j)
312 _playerInfo[j][i] = nullptr;
313 }
314}
@ LOCALE_enUS
Definition Common.h:118
std::uint8_t uint8
Definition Define.h:109
#define MAX_RACES
Definition SharedDefines.h:95
#define MAX_CLASSES
Definition SharedDefines.h:155
PlayerInfo * _playerInfo[MAX_RACES][MAX_CLASSES]
Definition ObjectMgr.h:1594
ObjectGuid::LowType _gameObjectSpawnId
Definition ObjectMgr.h:1503
uint32 _mailId
Definition ObjectMgr.h:1497
ObjectGuid::LowType _creatureSpawnId
Definition ObjectMgr.h:1502
LocaleConstant DBCLocaleIndex
Definition ObjectMgr.h:1570
PlayerClassInfo * _playerClassInfo[MAX_CLASSES]
Definition ObjectMgr.h:1590
uint64 _equipmentSetGuid
Definition ObjectMgr.h:1496
uint32 _auctionId
Definition ObjectMgr.h:1495
uint32 _hiPetNumber
Definition ObjectMgr.h:1499

References _playerClassInfo, _playerInfo, MAX_CLASSES, and MAX_RACES.

◆ ~ObjectMgr()

ObjectMgr::~ObjectMgr ( )
private
317{
318 for (QuestMap::iterator i = _questTemplates.begin(); i != _questTemplates.end(); ++i)
319 delete i->second;
320
321 for (PetLevelInfoContainer::iterator i = _petInfoStore.begin(); i != _petInfoStore.end(); ++i)
322 delete[] i->second;
323
324 // free only if loaded
325 for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
326 {
327 if (_playerClassInfo[class_])
328 delete[] _playerClassInfo[class_]->levelInfo;
329 delete _playerClassInfo[class_];
330 }
331
332 for (int race = 0; race < MAX_RACES; ++race)
333 {
334 for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
335 {
336 if (_playerInfo[race][class_])
337 delete[] _playerInfo[race][class_]->levelInfo;
338 delete _playerInfo[race][class_];
339 }
340 }
341
342 for (CacheVendorItemContainer::iterator itr = _cacheVendorItemStore.begin(); itr != _cacheVendorItemStore.end(); ++itr)
343 itr->second.Clear();
344
345 for (DungeonEncounterContainer::iterator itr = _dungeonEncounterStore.begin(); itr != _dungeonEncounterStore.end(); ++itr)
346 for (DungeonEncounterList::iterator encounterItr = itr->second.begin(); encounterItr != itr->second.end(); ++encounterItr)
347 delete *encounterItr;
348
349 for (DungeonProgressionRequirementsContainer::iterator itr = _accessRequirementStore.begin(); itr != _accessRequirementStore.end(); ++itr)
350 {
351 std::unordered_map<uint8, DungeonProgressionRequirements*> difficulties = itr->second;
352 for (auto difficultiesItr = difficulties.begin(); difficultiesItr != difficulties.end(); ++difficultiesItr)
353 {
354 for (auto questItr = difficultiesItr->second->quests.begin(); questItr != difficultiesItr->second->quests.end(); ++questItr)
355 {
356 delete* questItr;
357 }
358
359 for (auto achievementItr = difficultiesItr->second->achievements.begin(); achievementItr != difficultiesItr->second->achievements.end(); ++achievementItr)
360 {
361 delete* achievementItr;
362 }
363
364 for (auto itemsItr = difficultiesItr->second->items.begin(); itemsItr != difficultiesItr->second->items.end(); ++itemsItr)
365 {
366 delete* itemsItr;
367 }
368
369 delete difficultiesItr->second;
370 }
371 }
372}
PetLevelInfoContainer _petInfoStore
Definition ObjectMgr.h:1588
QuestMap _questTemplates
Definition ObjectMgr.h:1518
DungeonProgressionRequirementsContainer _accessRequirementStore
Definition ObjectMgr.h:1532
DungeonEncounterContainer _dungeonEncounterStore
Definition ObjectMgr.h:1533
CacheVendorItemContainer _cacheVendorItemStore
Definition ObjectMgr.h:1654
PlayerClassLevelInfo * levelInfo
Definition Player.h:287
PlayerLevelInfo * levelInfo
Definition Player.h:341

References _accessRequirementStore, _cacheVendorItemStore, _dungeonEncounterStore, _petInfoStore, _playerClassInfo, _playerInfo, _questTemplates, PlayerClassInfo::levelInfo, PlayerInfo::levelInfo, MAX_CLASSES, and MAX_RACES.

Member Function Documentation

◆ AddCreatureToGrid()

void ObjectMgr::AddCreatureToGrid ( ObjectGuid::LowType  guid,
CreatureData const *  data 
)
2620{
2621 uint8 mask = data->spawnMask;
2622 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
2623 {
2624 if (mask & 1)
2625 {
2626 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
2627 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
2628 cell_guids.creatures.insert(guid);
2629 }
2630 }
2631}
uint32 MAKE_PAIR32(uint16 l, uint16 h)
Definition ObjectDefines.h:88
MapObjectGuids _mapObjectGuidsStore
Definition ObjectMgr.h:1615
GridCoord ComputeGridCoord(float x, float y)
Definition GridDefines.h:185
Definition ObjectMgr.h:479
CellGuidSet creatures
Definition ObjectMgr.h:480
Definition GridDefines.h:88
uint32 GetId() const
Definition GridDefines.h:150

References _mapObjectGuidsStore, Acore::ComputeGridCoord(), CellObjectGuids::creatures, CoordPair< LIMIT >::GetId(), MAKE_PAIR32(), CreatureData::mapid, CreatureData::posX, CreatureData::posY, and CreatureData::spawnMask.

Referenced by AddCreData(), and LoadCreatures().

◆ AddCreData()

ObjectGuid::LowType ObjectMgr::AddCreData ( uint32  entry,
uint32  map,
float  x,
float  y,
float  z,
float  o,
uint32  spawntimedelay = 0 
)
2699{
2700 CreatureTemplate const* cInfo = GetCreatureTemplate(entry);
2701 if (!cInfo)
2702 return 0;
2703
2704 uint32 level = cInfo->minlevel == cInfo->maxlevel ? cInfo->minlevel : urand(cInfo->minlevel, cInfo->maxlevel); // Only used for extracting creature base stats
2705 CreatureBaseStats const* stats = GetCreatureBaseStats(level, cInfo->unit_class);
2706 Map* map = sMapMgr->CreateBaseMap(mapId);
2707 if (!map)
2708 return 0;
2709
2711 CreatureData& data = NewOrExistCreatureData(spawnId);
2712 data.spawnMask = spawnId;
2713 data.id1 = entry;
2714 data.id2 = 0;
2715 data.id3 = 0;
2716 data.mapid = mapId;
2717 data.displayid = 0;
2718 data.equipmentId = 0;
2719 data.posX = x;
2720 data.posY = y;
2721 data.posZ = z;
2722 data.orientation = o;
2723 data.spawntimesecs = spawntimedelay;
2724 data.wander_distance = 0;
2725 data.currentwaypoint = 0;
2726 data.curhealth = stats->GenerateHealth(cInfo);
2727 data.curmana = stats->GenerateMana(cInfo);
2728 data.movementType = cInfo->MovementType;
2729 data.spawnMask = 1;
2731 data.dbData = false;
2732 data.npcflag = cInfo->npcflag;
2733 data.unit_flags = cInfo->unit_flags;
2734 data.dynamicflags = cInfo->dynamicflags;
2735
2736 AddCreatureToGrid(spawnId, &data);
2737
2738 // Spawn if necessary (loaded grids only)
2739 if (!map->Instanceable() && map->IsGridLoaded(x, y))
2740 {
2741 Creature* creature = new Creature();
2742 if (!creature->LoadCreatureFromDB(spawnId, map, true, true))
2743 {
2744 LOG_ERROR("sql.sql", "AddCreature: Cannot add creature entry {} to map", entry);
2745 delete creature;
2746 return 0;
2747 }
2748 }
2749
2750 return spawnId;
2751}
std::uint32_t uint32
Definition Define.h:107
#define LOG_ERROR(filterType__,...)
Definition Log.h:158
#define sMapMgr
Definition MapMgr.h:220
@ PHASEMASK_NORMAL
Definition Object.h:62
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:44
Definition Creature.h:47
bool LoadCreatureFromDB(ObjectGuid::LowType guid, Map *map, bool addToMap=true, bool allowDuplicate=false)
Definition Creature.cpp:1653
Definition Map.h:163
bool IsGridLoaded(GridCoord const &gridCoord) const
Definition Map.cpp:204
bool Instanceable() const
Definition Map.h:294
uint32 LowType
Definition ObjectGuid.h:122
CreatureBaseStats const * GetCreatureBaseStats(uint8 level, uint8 unitClass)
Definition ObjectMgr.cpp:10324
void AddCreatureToGrid(ObjectGuid::LowType guid, CreatureData const *data)
Definition ObjectMgr.cpp:2619
ObjectGuid::LowType GenerateCreatureSpawnId()
Definition ObjectMgr.cpp:7588
CreatureData & NewOrExistCreatureData(ObjectGuid::LowType spawnId)
Definition ObjectMgr.h:1228
CreatureTemplate const * GetCreatureTemplate(uint32 entry)
Definition ObjectMgr.cpp:10672
Definition CreatureData.h:299
uint32 GenerateMana(CreatureTemplate const *info) const
Definition CreatureData.h:314
uint32 GenerateHealth(CreatureTemplate const *info) const
Definition CreatureData.h:309
Definition CreatureData.h:366
float wander_distance
Definition CreatureData.h:380
uint32 phaseMask
Definition CreatureData.h:372
uint32 spawntimesecs
Definition CreatureData.h:379
uint32 dynamicflags
Definition CreatureData.h:388
uint32 npcflag
Definition CreatureData.h:386
bool dbData
Definition CreatureData.h:390
uint32 displayid
Definition CreatureData.h:373
uint8 movementType
Definition CreatureData.h:384
uint8 spawnMask
Definition CreatureData.h:385
uint32 unit_flags
Definition CreatureData.h:387
uint32 id2
Definition CreatureData.h:369
uint32 curhealth
Definition CreatureData.h:382
float orientation
Definition CreatureData.h:378
uint32 curmana
Definition CreatureData.h:383
uint32 id3
Definition CreatureData.h:370
float posY
Definition CreatureData.h:376
float posX
Definition CreatureData.h:375
int8 equipmentId
Definition CreatureData.h:374
uint32 currentwaypoint
Definition CreatureData.h:381
uint16 mapid
Definition CreatureData.h:371
float posZ
Definition CreatureData.h:377
uint32 id1
Definition CreatureData.h:368
Definition CreatureData.h:186
uint32 unit_flags
Definition CreatureData.h:214
uint8 minlevel
Definition CreatureData.h:195
uint8 maxlevel
Definition CreatureData.h:196
uint32 MovementType
Definition CreatureData.h:230
uint32 npcflag
Definition CreatureData.h:199
uint32 unit_class
Definition CreatureData.h:213
uint32 dynamicflags
Definition CreatureData.h:216

References AddCreatureToGrid(), CreatureData::curhealth, CreatureData::curmana, CreatureData::currentwaypoint, CreatureData::dbData, CreatureData::displayid, CreatureTemplate::dynamicflags, CreatureData::dynamicflags, CreatureData::equipmentId, GenerateCreatureSpawnId(), CreatureBaseStats::GenerateHealth(), CreatureBaseStats::GenerateMana(), GetCreatureBaseStats(), GetCreatureTemplate(), CreatureData::id1, CreatureData::id2, CreatureData::id3, Map::Instanceable(), Map::IsGridLoaded(), Creature::LoadCreatureFromDB(), LOG_ERROR, CreatureData::mapid, CreatureTemplate::maxlevel, CreatureTemplate::minlevel, CreatureTemplate::MovementType, CreatureData::movementType, NewOrExistCreatureData(), CreatureTemplate::npcflag, CreatureData::npcflag, CreatureData::orientation, CreatureData::phaseMask, PHASEMASK_NORMAL, CreatureData::posX, CreatureData::posY, CreatureData::posZ, sMapMgr, CreatureData::spawnMask, CreatureData::spawntimesecs, CreatureTemplate::unit_class, CreatureTemplate::unit_flags, CreatureData::unit_flags, urand(), and CreatureData::wander_distance.

◆ AddGameobjectInfo()

void ObjectMgr::AddGameobjectInfo ( GameObjectTemplate goinfo)

◆ AddGameobjectToGrid()

void ObjectMgr::AddGameobjectToGrid ( ObjectGuid::LowType  guid,
GameObjectData const *  data 
)
3062{
3063 uint8 mask = data->spawnMask;
3064 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
3065 {
3066 if (mask & 1)
3067 {
3068 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
3069 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
3070 cell_guids.gameobjects.insert(guid);
3071 }
3072 }
3073}
CellGuidSet gameobjects
Definition ObjectMgr.h:481

References _mapObjectGuidsStore, Acore::ComputeGridCoord(), CellObjectGuids::gameobjects, CoordPair< LIMIT >::GetId(), MAKE_PAIR32(), GameObjectData::mapid, GameObjectData::posX, GameObjectData::posY, and GameObjectData::spawnMask.

Referenced by AddGOData(), and LoadGameobjects().

◆ AddGameTele()

bool ObjectMgr::AddGameTele ( GameTele data)
9506{
9507 // find max id
9508 uint32 new_id = 0;
9509 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9510 if (itr->first > new_id)
9511 new_id = itr->first;
9512
9513 // use next
9514 ++new_id;
9515
9516 if (!Utf8toWStr(tele.name, tele.wnameLow))
9517 return false;
9518
9519 wstrToLower(tele.wnameLow);
9520
9521 _gameTeleStore[new_id] = tele;
9522
9524
9525 stmt->SetData(0, new_id);
9526 stmt->SetData(1, tele.position_x);
9527 stmt->SetData(2, tele.position_y);
9528 stmt->SetData(3, tele.position_z);
9529 stmt->SetData(4, tele.orientation);
9530 stmt->SetData(5, uint16(tele.mapId));
9531 stmt->SetData(6, tele.name);
9532
9533 WorldDatabase.Execute(stmt);
9534
9535 return true;
9536}
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition DatabaseEnv.cpp:20
std::uint16_t uint16
Definition Define.h:108
bool Utf8toWStr(char const *utf8str, std::size_t csize, wchar_t *wstr, std::size_t &wsize)
Definition Util.cpp:281
void wstrToLower(std::wstring &str)
Definition Util.cpp:382
@ WORLD_INS_GAME_TELE
Definition WorldDatabase.h:41
GameTeleContainer _gameTeleStore
Definition ObjectMgr.h:1558
Acore::Types::is_default< T > SetData(const uint8 index, T value)
Definition PreparedStatement.h:77
Definition PreparedStatement.h:157

References _gameTeleStore, GameTele::mapId, GameTele::name, GameTele::orientation, GameTele::position_x, GameTele::position_y, GameTele::position_z, PreparedStatementBase::SetData(), Utf8toWStr(), GameTele::wnameLow, WORLD_INS_GAME_TELE, WorldDatabase, and wstrToLower().

◆ AddGOData()

ObjectGuid::LowType ObjectMgr::AddGOData ( uint32  entry,
uint32  map,
float  x,
float  y,
float  z,
float  o,
uint32  spawntimedelay = 0,
float  rotation0 = 0,
float  rotation1 = 0,
float  rotation2 = 0,
float  rotation3 = 0 
)
2648{
2649 GameObjectTemplate const* goinfo = GetGameObjectTemplate(entry);
2650 if (!goinfo)
2651 return 0;
2652
2653 Map* map = sMapMgr->CreateBaseMap(mapId);
2654 if (!map)
2655 return 0;
2656
2658
2659 GameObjectData& data = NewGOData(spawnId);
2660 data.id = entry;
2661 data.mapid = mapId;
2662 data.posX = x;
2663 data.posY = y;
2664 data.posZ = z;
2665 data.orientation = o;
2666 data.rotation.x = rotation0;
2667 data.rotation.y = rotation1;
2668 data.rotation.z = rotation2;
2669 data.rotation.w = rotation3;
2670 data.spawntimesecs = spawntimedelay;
2671 data.animprogress = 100;
2672 data.spawnMask = 1;
2673 data.go_state = GO_STATE_READY;
2675 data.artKit = goinfo->type == GAMEOBJECT_TYPE_CAPTURE_POINT ? 21 : 0;
2676 data.dbData = false;
2677
2678 AddGameobjectToGrid(spawnId, &data);
2679
2680 // Spawn if necessary (loaded grids only)
2681 // We use spawn coords to spawn
2682 if (!map->Instanceable() && map->IsGridLoaded(x, y))
2683 {
2685 if (!go->LoadGameObjectFromDB(spawnId, map))
2686 {
2687 LOG_ERROR("sql.sql", "AddGOData: cannot add gameobject entry {} to map", entry);
2688 delete go;
2689 return 0;
2690 }
2691 }
2692
2693 LOG_DEBUG("maps", "AddGOData: spawnId {} entry {} map {} x {} y {} z {} o {}", spawnId, entry, mapId, x, y, z, o);
2694
2695 return spawnId;
2696}
@ GO_STATE_READY
Definition GameObjectData.h:706
#define LOG_DEBUG(filterType__,...)
Definition Log.h:170
@ GAMEOBJECT_TYPE_CAPTURE_POINT
Definition SharedDefines.h:1600
Definition GameObject.h:120
virtual bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map *map, bool addToMap=true)
Definition GameObject.cpp:1088
void AddGameobjectToGrid(ObjectGuid::LowType guid, GameObjectData const *data)
Definition ObjectMgr.cpp:3061
GameObjectTemplate const * GetGameObjectTemplate(uint32 entry)
Definition ObjectMgr.cpp:10648
ObjectGuid::LowType GenerateGameObjectSpawnId()
Definition ObjectMgr.cpp:7598
GameObjectData & NewGOData(ObjectGuid::LowType guid)
Definition ObjectMgr.h:1328
bool IsGameObjectStaticTransport(uint32 entry)
Definition ObjectMgr.cpp:10657
Definition Transport.h:115
Definition GameObjectData.h:712
bool dbData
Definition GameObjectData.h:728
float orientation
Definition GameObjectData.h:720
float posZ
Definition GameObjectData.h:719
uint8 artKit
Definition GameObjectData.h:727
int32 spawntimesecs
Definition GameObjectData.h:722
uint8 spawnMask
Definition GameObjectData.h:726
G3D::Quat rotation
Definition GameObjectData.h:721
uint32 animprogress
Definition GameObjectData.h:724
uint16 mapid
Definition GameObjectData.h:715
float posX
Definition GameObjectData.h:717
uint32 phaseMask
Definition GameObjectData.h:716
float posY
Definition GameObjectData.h:718
uint32 id
Definition GameObjectData.h:714
GOState go_state
Definition GameObjectData.h:725
Definition GameObjectData.h:31
uint32 type
Definition GameObjectData.h:33

References AddGameobjectToGrid(), GameObjectData::animprogress, GameObjectData::artKit, GameObjectData::dbData, GAMEOBJECT_TYPE_CAPTURE_POINT, GenerateGameObjectSpawnId(), GetGameObjectTemplate(), GameObjectData::go_state, GO_STATE_READY, GameObjectData::id, Map::Instanceable(), IsGameObjectStaticTransport(), Map::IsGridLoaded(), GameObject::LoadGameObjectFromDB(), LOG_DEBUG, LOG_ERROR, GameObjectData::mapid, NewGOData(), GameObjectData::orientation, GameObjectData::phaseMask, PHASEMASK_NORMAL, GameObjectData::posX, GameObjectData::posY, GameObjectData::posZ, GameObjectData::rotation, sMapMgr, GameObjectData::spawnMask, GameObjectData::spawntimesecs, and GameObjectTemplate::type.

◆ AddLocaleString()

◆ AddProfanityPlayerName()

void ObjectMgr::AddProfanityPlayerName ( std::string const &  name)
8873{
8874 if (!IsProfanityName(name))
8875 {
8876 std::wstring wstr;
8877 if (!Utf8toWStr(name, wstr))
8878 {
8879 LOG_ERROR("server", "Could not add invalid name to profanity player names: {}", name);
8880 return;
8881 }
8882 wstrToLower(wstr);
8883
8884 _profanityNamesStore.insert(wstr);
8885
8887 stmt->SetData(0, name);
8888 CharacterDatabase.Execute(stmt);
8889 }
8890}
@ CHAR_INS_PROFANITY_PLAYER_NAME
Definition CharacterDatabase.h:520
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition DatabaseEnv.cpp:21
ProfanityNamesContainer _profanityNamesStore
Definition ObjectMgr.h:1556
bool IsProfanityName(std::string_view name) const
Definition ObjectMgr.cpp:8857

References _profanityNamesStore, CHAR_INS_PROFANITY_PLAYER_NAME, CharacterDatabase, IsProfanityName(), LOG_ERROR, PreparedStatementBase::SetData(), Utf8toWStr(), and wstrToLower().

◆ AddReservedPlayerName()

void ObjectMgr::AddReservedPlayerName ( std::string const &  name)
8770{
8771 if (!IsReservedName(name))
8772 {
8773 std::wstring wstr;
8774 if (!Utf8toWStr(name, wstr))
8775 {
8776 LOG_ERROR("server", "Could not add invalid name to reserved player names: {}", name);
8777 return;
8778 }
8779 wstrToLower(wstr);
8780
8781 _reservedNamesStore.insert(wstr);
8782
8784 stmt->SetData(0, name);
8785 CharacterDatabase.Execute(stmt);
8786 }
8787}
@ CHAR_INS_RESERVED_PLAYER_NAME
Definition CharacterDatabase.h:519
bool IsReservedName(std::string_view name) const
Definition ObjectMgr.cpp:8754
ReservedNamesContainer _reservedNamesStore
Definition ObjectMgr.h:1552

References _reservedNamesStore, CHAR_INS_RESERVED_PLAYER_NAME, CharacterDatabase, IsReservedName(), LOG_ERROR, PreparedStatementBase::SetData(), Utf8toWStr(), and wstrToLower().

◆ AddVendorItem()

void ObjectMgr::AddVendorItem ( uint32  entry,
uint32  item,
int32  maxcount,
uint32  incrtime,
uint32  extendedCost,
bool  persist = true 
)
10002{
10003 VendorItemData& vList = _cacheVendorItemStore[entry];
10004 vList.AddItem(item, maxcount, incrtime, extendedCost);
10005
10006 if (persist)
10007 {
10009
10010 stmt->SetData(0, entry);
10011 stmt->SetData(1, item);
10012 stmt->SetData(2, maxcount);
10013 stmt->SetData(3, incrtime);
10014 stmt->SetData(4, extendedCost);
10015
10016 WorldDatabase.Execute(stmt);
10017 }
10018}
@ WORLD_INS_NPC_VENDOR
Definition WorldDatabase.h:43
Definition CreatureData.h:465
void AddItem(uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost)
Definition CreatureData.h:477

References _cacheVendorItemStore, VendorItemData::AddItem(), PreparedStatementBase::SetData(), WORLD_INS_NPC_VENDOR, and WorldDatabase.

◆ BuildPlayerLevelInfo()

void ObjectMgr::BuildPlayerLevelInfo ( uint8  race,
uint8  class_,
uint8  level,
PlayerLevelInfo plinfo 
) const
private
4820{
4821 // base data (last known level)
4822 *info = _playerInfo[race][_class]->levelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) - 1];
4823
4824 // if conversion from uint32 to uint8 causes unexpected behaviour, change lvl to uint32
4825 for (uint8 lvl = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) - 1; lvl < level; ++lvl)
4826 {
4827 switch (_class)
4828 {
4829 case CLASS_WARRIOR:
4830 info->stats[STAT_STRENGTH] += (lvl > 23 ? 2 : (lvl > 1 ? 1 : 0));
4831 info->stats[STAT_STAMINA] += (lvl > 23 ? 2 : (lvl > 1 ? 1 : 0));
4832 info->stats[STAT_AGILITY] += (lvl > 36 ? 1 : (lvl > 6 && (lvl % 2) ? 1 : 0));
4833 info->stats[STAT_INTELLECT] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4834 info->stats[STAT_SPIRIT] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4835 break;
4836 case CLASS_PALADIN:
4837 info->stats[STAT_STRENGTH] += (lvl > 3 ? 1 : 0);
4838 info->stats[STAT_STAMINA] += (lvl > 33 ? 2 : (lvl > 1 ? 1 : 0));
4839 info->stats[STAT_AGILITY] += (lvl > 38 ? 1 : (lvl > 7 && !(lvl % 2) ? 1 : 0));
4840 info->stats[STAT_INTELLECT] += (lvl > 6 && (lvl % 2) ? 1 : 0);
4841 info->stats[STAT_SPIRIT] += (lvl > 7 ? 1 : 0);
4842 break;
4843 case CLASS_HUNTER:
4844 info->stats[STAT_STRENGTH] += (lvl > 4 ? 1 : 0);
4845 info->stats[STAT_STAMINA] += (lvl > 4 ? 1 : 0);
4846 info->stats[STAT_AGILITY] += (lvl > 33 ? 2 : (lvl > 1 ? 1 : 0));
4847 info->stats[STAT_INTELLECT] += (lvl > 8 && (lvl % 2) ? 1 : 0);
4848 info->stats[STAT_SPIRIT] += (lvl > 38 ? 1 : (lvl > 9 && !(lvl % 2) ? 1 : 0));
4849 break;
4850 case CLASS_ROGUE:
4851 info->stats[STAT_STRENGTH] += (lvl > 5 ? 1 : 0);
4852 info->stats[STAT_STAMINA] += (lvl > 4 ? 1 : 0);
4853 info->stats[STAT_AGILITY] += (lvl > 16 ? 2 : (lvl > 1 ? 1 : 0));
4854 info->stats[STAT_INTELLECT] += (lvl > 8 && !(lvl % 2) ? 1 : 0);
4855 info->stats[STAT_SPIRIT] += (lvl > 38 ? 1 : (lvl > 9 && !(lvl % 2) ? 1 : 0));
4856 break;
4857 case CLASS_PRIEST:
4858 info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4859 info->stats[STAT_STAMINA] += (lvl > 5 ? 1 : 0);
4860 info->stats[STAT_AGILITY] += (lvl > 38 ? 1 : (lvl > 8 && (lvl % 2) ? 1 : 0));
4861 info->stats[STAT_INTELLECT] += (lvl > 22 ? 2 : (lvl > 1 ? 1 : 0));
4862 info->stats[STAT_SPIRIT] += (lvl > 3 ? 1 : 0);
4863 break;
4864 case CLASS_SHAMAN:
4865 info->stats[STAT_STRENGTH] += (lvl > 34 ? 1 : (lvl > 6 && (lvl % 2) ? 1 : 0));
4866 info->stats[STAT_STAMINA] += (lvl > 4 ? 1 : 0);
4867 info->stats[STAT_AGILITY] += (lvl > 7 && !(lvl % 2) ? 1 : 0);
4868 info->stats[STAT_INTELLECT] += (lvl > 5 ? 1 : 0);
4869 info->stats[STAT_SPIRIT] += (lvl > 4 ? 1 : 0);
4870 break;
4871 case CLASS_MAGE:
4872 info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4873 info->stats[STAT_STAMINA] += (lvl > 5 ? 1 : 0);
4874 info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4875 info->stats[STAT_INTELLECT] += (lvl > 24 ? 2 : (lvl > 1 ? 1 : 0));
4876 info->stats[STAT_SPIRIT] += (lvl > 33 ? 2 : (lvl > 2 ? 1 : 0));
4877 break;
4878 case CLASS_WARLOCK:
4879 info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4880 info->stats[STAT_STAMINA] += (lvl > 38 ? 2 : (lvl > 3 ? 1 : 0));
4881 info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4882 info->stats[STAT_INTELLECT] += (lvl > 33 ? 2 : (lvl > 2 ? 1 : 0));
4883 info->stats[STAT_SPIRIT] += (lvl > 38 ? 2 : (lvl > 3 ? 1 : 0));
4884 break;
4885 case CLASS_DRUID:
4886 info->stats[STAT_STRENGTH] += (lvl > 38 ? 2 : (lvl > 6 && (lvl % 2) ? 1 : 0));
4887 info->stats[STAT_STAMINA] += (lvl > 32 ? 2 : (lvl > 4 ? 1 : 0));
4888 info->stats[STAT_AGILITY] += (lvl > 38 ? 2 : (lvl > 8 && (lvl % 2) ? 1 : 0));
4889 info->stats[STAT_INTELLECT] += (lvl > 38 ? 3 : (lvl > 4 ? 1 : 0));
4890 info->stats[STAT_SPIRIT] += (lvl > 38 ? 3 : (lvl > 5 ? 1 : 0));
4891 }
4892 }
4893}
@ CLASS_HUNTER
Definition SharedDefines.h:143
@ CLASS_DRUID
Definition SharedDefines.h:151
@ CLASS_SHAMAN
Definition SharedDefines.h:147
@ CLASS_PRIEST
Definition SharedDefines.h:145
@ CLASS_WARRIOR
Definition SharedDefines.h:141
@ CLASS_WARLOCK
Definition SharedDefines.h:149
@ CLASS_MAGE
Definition SharedDefines.h:148
@ CLASS_PALADIN
Definition SharedDefines.h:142
@ CLASS_ROGUE
Definition SharedDefines.h:144
@ STAT_SPIRIT
Definition SharedDefines.h:273
@ STAT_INTELLECT
Definition SharedDefines.h:272
@ STAT_AGILITY
Definition SharedDefines.h:270
@ STAT_STRENGTH
Definition SharedDefines.h:269
@ STAT_STAMINA
Definition SharedDefines.h:271
@ CONFIG_MAX_PLAYER_LEVEL
Definition WorldConfig.h:190
#define sWorld
Definition World.h:316
std::array< uint32, MAX_STATS > stats
Definition Player.h:297

References _playerInfo, CLASS_DRUID, CLASS_HUNTER, CLASS_MAGE, CLASS_PALADIN, CLASS_PRIEST, CLASS_ROGUE, CLASS_SHAMAN, CLASS_WARLOCK, CLASS_WARRIOR, CONFIG_MAX_PLAYER_LEVEL, PlayerInfo::levelInfo, STAT_AGILITY, STAT_INTELLECT, STAT_SPIRIT, STAT_STAMINA, STAT_STRENGTH, PlayerLevelInfo::stats, and sWorld.

Referenced by GetPlayerLevelInfo().

◆ ChangeFishingBaseSkillLevel()

void ObjectMgr::ChangeFishingBaseSkillLevel ( uint32  entry,
int32  skill 
)
9325{
9326 AreaTableEntry const* fArea = sAreaTableStore.LookupEntry(entry);
9327 if (!fArea)
9328 {
9329 LOG_ERROR("sql.sql", "AreaId {} defined in `skill_fishing_base_level` does not exist", entry);
9330 return;
9331 }
9332
9333 _fishingBaseForAreaStore[entry] = skill;
9334
9335 LOG_INFO("server.loading", ">> Fishing base skill level of area {} changed to {}", entry, skill);
9336 LOG_INFO("server.loading", " ");
9337}
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
#define LOG_INFO(filterType__,...)
Definition Log.h:166
FishingBaseSkillContainer _fishingBaseForAreaStore
Definition ObjectMgr.h:1603
Definition DBCStructure.h:519

References _fishingBaseForAreaStore, LOG_ERROR, LOG_INFO, and sAreaTableStore.

◆ CheckCreatureMovement()

void ObjectMgr::CheckCreatureMovement ( char const *  table,
uint64  id,
CreatureMovementData creatureMovement 
)
1227{
1228 if (creatureMovement.Ground >= CreatureGroundMovementType::Max)
1229 {
1230 LOG_ERROR("sql.sql", "`{}`.`Ground` wrong value ({}) for Id {}, setting to Run.", table, uint32(creatureMovement.Ground), id);
1231 creatureMovement.Ground = CreatureGroundMovementType::Run;
1232 }
1233
1234 if (creatureMovement.Flight >= CreatureFlightMovementType::Max)
1235 {
1236 LOG_ERROR("sql.sql", "`{}`.`Flight` wrong value ({}) for Id {}, setting to None.", table, uint32(creatureMovement.Flight), id);
1237 creatureMovement.Flight = CreatureFlightMovementType::None;
1238 }
1239
1240 if (creatureMovement.Chase >= CreatureChaseMovementType::Max)
1241 {
1242 LOG_ERROR("sql.sql", "`{}`.`Chase` wrong value ({}) for Id {}, setting to Run.", table, uint32(creatureMovement.Chase), id);
1243 creatureMovement.Chase = CreatureChaseMovementType::Run;
1244 }
1245
1246 if (creatureMovement.Random >= CreatureRandomMovementType::Max)
1247 {
1248 LOG_ERROR("sql.sql", "`{}`.`Random` wrong value ({}) for Id {}, setting to Walk.", table, uint32(creatureMovement.Random), id);
1249 creatureMovement.Random = CreatureRandomMovementType::Walk;
1250 }
1251}
CreatureRandomMovementType Random
Definition CreatureData.h:127
CreatureFlightMovementType Flight
Definition CreatureData.h:123
CreatureChaseMovementType Chase
Definition CreatureData.h:126
CreatureGroundMovementType Ground
Definition CreatureData.h:122

References CreatureMovementData::Chase, CreatureMovementData::Flight, CreatureMovementData::Ground, LOG_ERROR, Max, None, CreatureMovementData::Random, Run, and Walk.

Referenced by CheckCreatureTemplate(), and LoadCreatureMovementOverrides().

◆ CheckCreatureTemplate()

void ObjectMgr::CheckCreatureTemplate ( CreatureTemplate const *  cInfo)
956{
957 if (!cInfo)
958 return;
959
960 bool ok = true; // bool to allow continue outside this loop
961 for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff)
962 {
963 if (!cInfo->DifficultyEntry[diff])
964 continue;
965 ok = false; // will be set to true at the end of this loop again
966
967 CreatureTemplate const* difficultyInfo = GetCreatureTemplate(cInfo->DifficultyEntry[diff]);
968 if (!difficultyInfo)
969 {
970 LOG_ERROR("sql.sql", "Creature (Entry: {}) has `difficulty_entry_{}`={} but creature entry {} does not exist.",
971 cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff], cInfo->DifficultyEntry[diff]);
972 continue;
973 }
974
975 bool ok2 = true;
976 for (uint32 diff2 = 0; diff2 < MAX_DIFFICULTY - 1 && ok2; ++diff2)
977 {
978 ok2 = false;
979 if (_difficultyEntries[diff2].find(cInfo->Entry) != _difficultyEntries[diff2].end())
980 {
981 LOG_ERROR("sql.sql", "Creature (Entry: {}) is listed as `difficulty_entry_{}` of another creature, but itself lists {} in `difficulty_entry_{}`.",
982 cInfo->Entry, diff2 + 1, cInfo->DifficultyEntry[diff], diff + 1);
983 continue;
984 }
985
986 if (_difficultyEntries[diff2].find(cInfo->DifficultyEntry[diff]) != _difficultyEntries[diff2].end())
987 {
988 LOG_ERROR("sql.sql", "Creature (Entry: {}) already listed as `difficulty_entry_{}` for another entry.", cInfo->DifficultyEntry[diff], diff2 + 1);
989 continue;
990 }
991
992 if (_hasDifficultyEntries[diff2].find(cInfo->DifficultyEntry[diff]) != _hasDifficultyEntries[diff2].end())
993 {
994 LOG_ERROR("sql.sql", "Creature (Entry: {}) has `difficulty_entry_{}`={} but creature entry {} has itself a value in `difficulty_entry_{}`.",
995 cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff], cInfo->DifficultyEntry[diff], diff2 + 1);
996 continue;
997 }
998 ok2 = true;
999 }
1000 if (!ok2)
1001 continue;
1002
1003 if (cInfo->expansion > difficultyInfo->expansion)
1004 {
1005 LOG_ERROR("sql.sql", "Creature (Entry: {}, expansion {}) has different `expansion` in difficulty {} mode (Entry: {}, expansion {}).",
1006 cInfo->Entry, cInfo->expansion, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->expansion);
1007 }
1008
1009 if (cInfo->faction != difficultyInfo->faction)
1010 {
1011 LOG_ERROR("sql.sql", "Creature (Entry: {}, faction {}) has different `faction` in difficulty {} mode (Entry: {}, faction {}).",
1012 cInfo->Entry, cInfo->faction, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->faction);
1013 }
1014
1015 if (cInfo->unit_class != difficultyInfo->unit_class)
1016 {
1017 LOG_ERROR("sql.sql", "Creature (Entry: {}, class {}) has different `unit_class` in difficulty {} mode (Entry: {}, class {}).",
1018 cInfo->Entry, cInfo->unit_class, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->unit_class);
1019 continue;
1020 }
1021
1022 if (cInfo->npcflag != difficultyInfo->npcflag)
1023 {
1024 LOG_ERROR("sql.sql", "Creature (Entry: {}) has different `npcflag` in difficulty {} mode (Entry: {}).", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
1025 continue;
1026 }
1027
1028 if (cInfo->family != difficultyInfo->family)
1029 {
1030 LOG_ERROR("sql.sql", "Creature (Entry: {}, family {}) has different `family` in difficulty {} mode (Entry: {}, family {}).",
1031 cInfo->Entry, cInfo->family, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->family);
1032 }
1033
1034 if (cInfo->type != difficultyInfo->type)
1035 {
1036 LOG_ERROR("sql.sql", "Creature (Entry: {}, type {}) has different `type` in difficulty {} mode (Entry: {}, type {}).",
1037 cInfo->Entry, cInfo->type, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->type);
1038 }
1039
1040 if (!cInfo->VehicleId && difficultyInfo->VehicleId)
1041 {
1042 LOG_ERROR("sql.sql", "Creature (Entry: {}, VehicleId {}) has different `VehicleId` in difficulty {} mode (Entry: {}, VehicleId {}).",
1043 cInfo->Entry, cInfo->VehicleId, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->VehicleId);
1044 }
1045
1046 // Xinef: check dmg school
1047 if (cInfo->dmgschool != difficultyInfo->dmgschool)
1048 {
1049 LOG_ERROR("sql.sql", "Creature (Entry: {}) has different `dmgschool` in difficulty {} mode (Entry: {})", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
1050 }
1051
1052 if (!difficultyInfo->AIName.empty())
1053 {
1054 LOG_ERROR("sql.sql", "Creature (Entry: {}) lists difficulty {} mode entry {} with `AIName` filled in. `AIName` of difficulty 0 mode creature is always used instead.",
1055 cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
1056 continue;
1057 }
1058
1059 if (difficultyInfo->ScriptID)
1060 {
1061 LOG_ERROR("sql.sql", "Creature (Entry: {}) lists difficulty {} mode entry {} with `ScriptName` filled in. `ScriptName` of difficulty 0 mode creature is always used instead.",
1062 cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
1063 continue;
1064 }
1065
1066 _hasDifficultyEntries[diff].insert(cInfo->Entry);
1067 _difficultyEntries[diff].insert(cInfo->DifficultyEntry[diff]);
1068 ok = true;
1069 }
1070
1071 if (!cInfo->AIName.empty() && !sCreatureAIRegistry->HasItem(cInfo->AIName))
1072 {
1073 LOG_ERROR("sql.sql", "Creature (Entry: {}) has non-registered `AIName` '{}' set, removing", cInfo->Entry, cInfo->AIName);
1074 const_cast<CreatureTemplate*>(cInfo)->AIName.clear();
1075 }
1076
1077 FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction);
1078 if (!factionTemplate)
1079 LOG_ERROR("sql.sql", "Creature (Entry: {}) has non-existing faction template ({}).", cInfo->Entry, cInfo->faction);
1080
1081 for (int k = 0; k < MAX_KILL_CREDIT; ++k)
1082 {
1083 if (cInfo->KillCredit[k])
1084 {
1085 if (!GetCreatureTemplate(cInfo->KillCredit[k]))
1086 {
1087 LOG_ERROR("sql.sql", "Creature (Entry: {}) lists non-existing creature entry {} in `KillCredit{}`.", cInfo->Entry, cInfo->KillCredit[k], k + 1);
1088 const_cast<CreatureTemplate*>(cInfo)->KillCredit[k] = 0;
1089 }
1090 }
1091 }
1092
1093 if (!cInfo->Models.size())
1094 LOG_ERROR("sql.sql", "Creature (Entry: {}) does not have any existing display id in creature_template_model.", cInfo->Entry);
1095 else
1096 {
1097 float const totalProbability = std::accumulate(cInfo->Models.begin(), cInfo->Models.end(), 0.0f, [](float sum, CreatureModel const& model) { return sum + model.Probability; });
1098
1099 if (totalProbability <= 0.0f)
1100 { // There are many cases in official data of all models having a probability of 0. Believe to be treated equivalent to equal chance ONLY if all are zeroed
1101 if (totalProbability == 0.0f)
1102 LOG_DEBUG("sql.sql", "Creature (Entry: {}) has zero total chance for all models in creature_template_model. Setting all to 1.0.", cInfo->Entry);
1103 else // Custom, likely bad data
1104 LOG_ERROR("sql.sql", "Creature (Entry: {}) has less than zero total chance for all models in creature_template_model. Setting all to 1.0.", cInfo->Entry);
1105
1106 auto& models = const_cast<CreatureTemplate*>(cInfo)->Models;
1107 for (auto& model : models)
1108 model.Probability = 1.0f;
1109 }
1110 }
1111
1112 if (!cInfo->unit_class || ((1 << (cInfo->unit_class - 1)) & CLASSMASK_ALL_CREATURES) == 0)
1113 {
1114 LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid unit_class ({}) in creature_template. Set to 1 (UNIT_CLASS_WARRIOR).", cInfo->Entry, cInfo->unit_class);
1115 const_cast<CreatureTemplate*>(cInfo)->unit_class = UNIT_CLASS_WARRIOR;
1116 }
1117
1118 if (cInfo->dmgschool >= MAX_SPELL_SCHOOL)
1119 {
1120 LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid spell school value ({}) in `dmgschool`.", cInfo->Entry, cInfo->dmgschool);
1121 const_cast<CreatureTemplate*>(cInfo)->dmgschool = SPELL_SCHOOL_NORMAL;
1122 }
1123
1124 if (cInfo->BaseAttackTime == 0)
1125 const_cast<CreatureTemplate*>(cInfo)->BaseAttackTime = BASE_ATTACK_TIME;
1126
1127 if (cInfo->RangeAttackTime == 0)
1128 const_cast<CreatureTemplate*>(cInfo)->RangeAttackTime = BASE_ATTACK_TIME;
1129
1130 if (cInfo->speed_walk == 0.0f)
1131 {
1132 LOG_ERROR("sql.sql", "Creature (Entry: {}) has wrong value ({}) in speed_walk, set to 1.", cInfo->Entry, cInfo->speed_walk);
1133 const_cast<CreatureTemplate*>(cInfo)->speed_walk = 1.0f;
1134 }
1135
1136 if (cInfo->speed_run == 0.0f)
1137 {
1138 LOG_ERROR("sql.sql", "Creature (Entry: {}) has wrong value ({}) in speed_run, set to 1.14286.", cInfo->Entry, cInfo->speed_run);
1139 const_cast<CreatureTemplate*>(cInfo)->speed_run = 1.14286f;
1140 }
1141
1142 if (cInfo->type && !sCreatureTypeStore.LookupEntry(cInfo->type))
1143 {
1144 LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid creature type ({}) in `type`.", cInfo->Entry, cInfo->type);
1145 const_cast<CreatureTemplate*>(cInfo)->type = CREATURE_TYPE_HUMANOID;
1146 }
1147
1148 // must exist or used hidden but used in data horse case
1149 if (cInfo->family && !sCreatureFamilyStore.LookupEntry(cInfo->family) && cInfo->family != CREATURE_FAMILY_HORSE_CUSTOM)
1150 {
1151 LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid creature family ({}) in `family`.", cInfo->Entry, cInfo->family);
1152 const_cast<CreatureTemplate*>(cInfo)->family = 0;
1153 }
1154
1155 CheckCreatureMovement("creature_template_movement", cInfo->Entry, const_cast<CreatureTemplate*>(cInfo)->Movement);
1156
1157 if (cInfo->HoverHeight < 0.0f)
1158 {
1159 LOG_ERROR("sql.sql", "Creature (Entry: {}) has wrong value ({}) in `HoverHeight`", cInfo->Entry, cInfo->HoverHeight);
1160 const_cast<CreatureTemplate*>(cInfo)->HoverHeight = 1.0f;
1161 }
1162
1163 if (cInfo->VehicleId)
1164 {
1165 VehicleEntry const* vehId = sVehicleStore.LookupEntry(cInfo->VehicleId);
1166 if (!vehId)
1167 {
1168 LOG_ERROR("sql.sql", "Creature (Entry: {}) has a non-existing VehicleId ({}). This *WILL* cause the client to freeze!", cInfo->Entry, cInfo->VehicleId);
1169 const_cast<CreatureTemplate*>(cInfo)->VehicleId = 0;
1170 }
1171 }
1172
1173 if (cInfo->PetSpellDataId)
1174 {
1175 CreatureSpellDataEntry const* spellDataId = sCreatureSpellDataStore.LookupEntry(cInfo->PetSpellDataId);
1176 if (!spellDataId)
1177 LOG_ERROR("sql.sql", "Creature (Entry: {}) has non-existing PetSpellDataId ({}).", cInfo->Entry, cInfo->PetSpellDataId);
1178 }
1179
1180 for (uint8 j = 0; j < MAX_CREATURE_SPELLS; ++j)
1181 {
1182 if (cInfo->spells[j] && !sSpellMgr->GetSpellInfo(cInfo->spells[j]))
1183 {
1184 LOG_ERROR("sql.sql", "Creature (Entry: {}) has non-existing Spell{} ({}), set to 0.", cInfo->Entry, j + 1, cInfo->spells[j]);
1185 const_cast<CreatureTemplate*>(cInfo)->spells[j] = 0;
1186 }
1187 }
1188
1189 if (cInfo->MovementType >= MAX_DB_MOTION_TYPE)
1190 {
1191 LOG_ERROR("sql.sql", "Creature (Entry: {}) has wrong movement generator type ({}), ignored and set to IDLE.", cInfo->Entry, cInfo->MovementType);
1192 const_cast<CreatureTemplate*>(cInfo)->MovementType = IDLE_MOTION_TYPE;
1193 }
1194
1195 if (cInfo->expansion > (MAX_EXPANSIONS - 1))
1196 {
1197 LOG_ERROR("sql.sql", "Table `creature_template` lists creature (Entry: {}) with expansion {}. Ignored and set to 0.", cInfo->Entry, cInfo->expansion);
1198 const_cast<CreatureTemplate*>(cInfo)->expansion = 0;
1199 }
1200
1201 if (uint32 badFlags = (cInfo->flags_extra & ~CREATURE_FLAG_EXTRA_DB_ALLOWED))
1202 {
1203 LOG_ERROR("sql.sql", "Table `creature_template` lists creature (Entry: {}) with disallowed `flags_extra` {}, removing incorrect flag.", cInfo->Entry, badFlags);
1204 const_cast<CreatureTemplate*>(cInfo)->flags_extra &= CREATURE_FLAG_EXTRA_DB_ALLOWED;
1205 }
1206
1207 const_cast<CreatureTemplate*>(cInfo)->DamageModifier *= Creature::_GetDamageMod(cInfo->rank);
1208
1209 // Hack for modules
1210 for (auto& itr : _creatureCustomIDsStore)
1211 {
1212 if (cInfo->Entry == itr)
1213 return;
1214 }
1215
1216 if ((cInfo->GossipMenuId && !(cInfo->npcflag & UNIT_NPC_FLAG_GOSSIP)) && !(cInfo->flags_extra & CREATURE_FLAG_EXTRA_MODULE))
1217 {
1218 LOG_ERROR("sql.sql", "Creature (Entry: {}) has assigned gossip menu {}, but npcflag does not include UNIT_NPC_FLAG_GOSSIP (1).", cInfo->Entry, cInfo->GossipMenuId);
1219 }
1220 else if ((!cInfo->GossipMenuId && (cInfo->npcflag & UNIT_NPC_FLAG_GOSSIP)) && !(cInfo->flags_extra & CREATURE_FLAG_EXTRA_MODULE))
1221 {
1222 LOG_INFO("sql.sql", "Creature (Entry: {}) has npcflag UNIT_NPC_FLAG_GOSSIP (1), but gossip menu is unassigned.", cInfo->Entry);
1223 }
1224}
#define sCreatureAIRegistry
Definition CreatureAIFactory.h:48
@ CREATURE_FLAG_EXTRA_DB_ALLOWED
Definition CreatureData.h:79
@ CREATURE_FLAG_EXTRA_MODULE
Definition CreatureData.h:69
#define MAX_KILL_CREDIT
Definition CreatureData.h:30
#define MAX_DIFFICULTY
Definition DBCEnums.h:283
DBCStorage< VehicleEntry > sVehicleStore(VehicleEntryfmt)
DBCStorage< CreatureSpellDataEntry > sCreatureSpellDataStore(CreatureSpellDatafmt)
DBCStorage< CreatureFamilyEntry > sCreatureFamilyStore(CreatureFamilyfmt)
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
DBCStorage< CreatureTypeEntry > sCreatureTypeStore(CreatureTypefmt)
@ MAX_DB_MOTION_TYPE
Definition MotionMaster.h:42
@ IDLE_MOTION_TYPE
Definition MotionMaster.h:39
@ SPELL_SCHOOL_NORMAL
Definition SharedDefines.h:294
constexpr auto MAX_SPELL_SCHOOL
Definition SharedDefines.h:303
@ CREATURE_FAMILY_HORSE_CUSTOM
Definition SharedDefines.h:2660
@ UNIT_CLASS_WARRIOR
Definition SharedDefines.h:166
@ CREATURE_TYPE_HUMANOID
Definition SharedDefines.h:2635
#define CLASSMASK_ALL_CREATURES
Definition SharedDefines.h:172
@ MAX_EXPANSIONS
Definition SharedDefines.h:56
#define sSpellMgr
Definition SpellMgr.h:826
@ UNIT_NPC_FLAG_GOSSIP
Definition UnitDefines.h:319
#define BASE_ATTACK_TIME
Definition Unit.h:43
static constexpr uint32 MAX_CREATURE_SPELLS
Definition Unit.h:47
Models
Definition boss_black_knight.cpp:79
spells
Definition boss_krystallus.cpp:26
static float _GetDamageMod(int32 Rank)
Definition Creature.cpp:1553
std::set< uint32 > _difficultyEntries[MAX_DIFFICULTY - 1]
Definition ObjectMgr.h:1658
CreatureCustomIDsContainer _creatureCustomIDsStore
Definition ObjectMgr.h:1620
std::set< uint32 > _hasDifficultyEntries[MAX_DIFFICULTY - 1]
Definition ObjectMgr.h:1659
void CheckCreatureMovement(char const *table, uint64 id, CreatureMovementData &creatureMovement)
Definition ObjectMgr.cpp:1226
Definition CreatureData.h:169
Definition DBCStructure.h:810
uint32 type
Definition CreatureData.h:218
uint32 ScriptID
Definition CreatureData.h:243
uint32 VehicleId
Definition CreatureData.h:226
CreatureMovementData Movement
Definition CreatureData.h:231
uint32 faction
Definition CreatureData.h:198
uint32 dmgschool
Definition CreatureData.h:207
uint32 expansion
Definition CreatureData.h:197
std::string AIName
Definition CreatureData.h:229
uint32 family
Definition CreatureData.h:217
Definition DBCStructure.h:939
Definition DBCStructure.h:2027

References _creatureCustomIDsStore, _difficultyEntries, Creature::_GetDamageMod(), _hasDifficultyEntries, CreatureTemplate::AIName, BASE_ATTACK_TIME, CreatureTemplate::BaseAttackTime, CheckCreatureMovement(), CLASSMASK_ALL_CREATURES, CREATURE_FAMILY_HORSE_CUSTOM, CREATURE_FLAG_EXTRA_DB_ALLOWED, CREATURE_FLAG_EXTRA_MODULE, CREATURE_TYPE_HUMANOID, CreatureTemplate::DifficultyEntry, CreatureTemplate::dmgschool, CreatureTemplate::Entry, CreatureTemplate::expansion, CreatureTemplate::faction, CreatureTemplate::family, CreatureTemplate::flags_extra, GetCreatureTemplate(), CreatureTemplate::GossipMenuId, CreatureTemplate::HoverHeight, IDLE_MOTION_TYPE, CreatureTemplate::KillCredit, LOG_DEBUG, LOG_ERROR, LOG_INFO, MAX_CREATURE_SPELLS, MAX_DB_MOTION_TYPE, MAX_DIFFICULTY, MAX_EXPANSIONS, MAX_KILL_CREDIT, MAX_SPELL_SCHOOL, CreatureTemplate::Models, CreatureTemplate::Movement, CreatureTemplate::MovementType, CreatureTemplate::npcflag, CreatureTemplate::PetSpellDataId, CreatureModel::Probability, CreatureTemplate::RangeAttackTime, CreatureTemplate::rank, sCreatureAIRegistry, sCreatureFamilyStore, sCreatureSpellDataStore, sCreatureTypeStore, CreatureTemplate::ScriptID, sFactionTemplateStore, CreatureTemplate::speed_run, CreatureTemplate::speed_walk, SPELL_SCHOOL_NORMAL, CreatureTemplate::spells, sSpellMgr, sVehicleStore, CreatureTemplate::type, CreatureTemplate::unit_class, UNIT_CLASS_WARRIOR, UNIT_NPC_FLAG_GOSSIP, and CreatureTemplate::VehicleId.

Referenced by LoadCreatureTemplates().

◆ CheckDeclinedNames()

bool ObjectMgr::CheckDeclinedNames ( std::wstring  w_ownname,
DeclinedName const &  names 
)
static
9340{
9341 // get main part of the name
9342 std::wstring mainpart = GetMainPartOfName(w_ownname, 0);
9343 // prepare flags
9344 bool x = true;
9345 bool y = true;
9346
9347 // check declined names
9348 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
9349 {
9350 std::wstring wname;
9351 if (!Utf8toWStr(names.name[i], wname))
9352 return false;
9353
9354 if (mainpart != GetMainPartOfName(wname, i + 1))
9355 x = false;
9356
9357 if (w_ownname != wname)
9358 y = false;
9359 }
9360 return (x || y);
9361}
#define MAX_DECLINED_NAME_CASES
Definition Unit.h:535
std::wstring GetMainPartOfName(std::wstring const &wname, uint32_t declension)
Definition Util.cpp:386

References GetMainPartOfName(), MAX_DECLINED_NAME_CASES, DeclinedName::name, and Utf8toWStr().

Referenced by WorldSession::HandlePetRename(), and WorldSession::HandleSetPlayerDeclinedNames().

◆ CheckPetName()

PetNameInvalidReason ObjectMgr::CheckPetName ( std::string_view  name)
static
9045{
9046 std::wstring wname;
9047 if (!Utf8toWStr(name, wname))
9048 return PET_NAME_INVALID;
9049
9050 if (wname.size() > MAX_PET_NAME)
9051 return PET_NAME_TOO_LONG;
9052
9053 uint32 minName = sWorld->getIntConfig(CONFIG_MIN_PET_NAME);
9054 if (wname.size() < minName)
9055 return PET_NAME_TOO_SHORT;
9056
9057 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_PET_NAMES);
9058 if (!isValidString(wname, strictMask, false))
9060
9061 // Check Reserved Name
9062 if (sObjectMgr->IsReservedName(name))
9063 return PET_NAME_RESERVED;
9064
9065 // Check Profanity Name
9066 if (sObjectMgr->IsProfanityName(name))
9067 return PET_NAME_PROFANE;
9068
9069 return PET_NAME_SUCCESS;
9070}
bool isValidString(std::wstring wstr, uint32 strictMask, bool numericOrSpace, bool create=false)
Definition ObjectMgr.cpp:8929
#define sObjectMgr
Definition ObjectMgr.h:1686
#define MAX_PET_NAME
Definition ObjectMgr.h:684
@ PET_NAME_INVALID
Definition SharedDefines.h:3916
@ PET_NAME_RESERVED
Definition SharedDefines.h:3922
@ PET_NAME_SUCCESS
Definition SharedDefines.h:3914
@ PET_NAME_MIXED_LANGUAGES
Definition SharedDefines.h:3920
@ PET_NAME_TOO_SHORT
Definition SharedDefines.h:3918
@ PET_NAME_TOO_LONG
Definition SharedDefines.h:3919
@ PET_NAME_PROFANE
Definition SharedDefines.h:3921
@ CONFIG_STRICT_PET_NAMES
Definition WorldConfig.h:177
@ CONFIG_MIN_PET_NAME
Definition WorldConfig.h:180

References CONFIG_MIN_PET_NAME, CONFIG_STRICT_PET_NAMES, isValidString(), MAX_PET_NAME, PET_NAME_INVALID, PET_NAME_MIXED_LANGUAGES, PET_NAME_PROFANE, PET_NAME_RESERVED, PET_NAME_SUCCESS, PET_NAME_TOO_LONG, PET_NAME_TOO_SHORT, sObjectMgr, sWorld, and Utf8toWStr().

Referenced by WorldSession::HandlePetRename().

◆ CheckPlayerName()

uint8 ObjectMgr::CheckPlayerName ( std::string_view  name,
bool  create = false 
)
static
8966{
8967 std::wstring wname;
8968
8969 // Check for invalid characters
8970 if (!Utf8toWStr(name, wname))
8972
8973 // Check for too long name
8974 if (wname.size() > MAX_PLAYER_NAME)
8975 return CHAR_NAME_TOO_LONG;
8976
8977 // Check for too short name
8978 uint32 minName = sWorld->getIntConfig(CONFIG_MIN_PLAYER_NAME);
8979 if (wname.size() < minName)
8980 return CHAR_NAME_TOO_SHORT;
8981
8982 // Check for mixed languages
8983 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_PLAYER_NAMES);
8984 if (!isValidString(wname, strictMask, false, create))
8986
8987 // Check for three consecutive letters
8988 wstrToLower(wname);
8989 for (std::size_t i = 2; i < wname.size(); ++i)
8990 if (wname[i] == wname[i - 1] && wname[i] == wname[i - 2])
8992
8993 // Check Reserved Name
8994 if (sObjectMgr->IsReservedName(name))
8995 return CHAR_NAME_RESERVED;
8996
8997 // Check Profanity Name
8998 if (sObjectMgr->IsProfanityName(name))
8999 return CHAR_NAME_PROFANE;
9000
9001 return CHAR_NAME_SUCCESS;
9002}
#define MAX_PLAYER_NAME
Definition ObjectMgr.h:682
@ CHAR_NAME_TOO_SHORT
Definition SharedDefines.h:3678
@ CHAR_NAME_THREE_CONSECUTIVE
Definition SharedDefines.h:3686
@ CHAR_NAME_INVALID_CHARACTER
Definition SharedDefines.h:3680
@ CHAR_NAME_TOO_LONG
Definition SharedDefines.h:3679
@ CHAR_NAME_RESERVED
Definition SharedDefines.h:3683
@ CHAR_NAME_MIXED_LANGUAGES
Definition SharedDefines.h:3681
@ CHAR_NAME_PROFANE
Definition SharedDefines.h:3682
@ CHAR_NAME_SUCCESS
Definition SharedDefines.h:3675
@ CONFIG_STRICT_PLAYER_NAMES
Definition WorldConfig.h:174
@ CONFIG_MIN_PLAYER_NAME
Definition WorldConfig.h:178

References CHAR_NAME_INVALID_CHARACTER, CHAR_NAME_MIXED_LANGUAGES, CHAR_NAME_PROFANE, CHAR_NAME_RESERVED, CHAR_NAME_SUCCESS, CHAR_NAME_THREE_CONSECUTIVE, CHAR_NAME_TOO_LONG, CHAR_NAME_TOO_SHORT, CONFIG_MIN_PLAYER_NAME, CONFIG_STRICT_PLAYER_NAMES, isValidString(), MAX_PLAYER_NAME, sObjectMgr, sWorld, Utf8toWStr(), and wstrToLower().

Referenced by character_commandscript::HandleCharacterRenameCommand(), WorldSession::HandleCharCreateOpcode(), WorldSession::HandleCharCustomizeCallback(), WorldSession::HandleCharFactionOrRaceChangeCallback(), WorldSession::HandleCharRenameOpcode(), PlayerDumpReader::LoadDump(), Player::LoadFromDB(), and character_commandscript::ValidatePDumpTarget().

◆ ChooseCreatureFlags()

void ObjectMgr::ChooseCreatureFlags ( CreatureTemplate const *  cinfo,
uint32 npcflag,
uint32 unit_flags,
uint32 dynamicflags,
CreatureData const *  data = nullptr 
)
static
1651{
1652 npcflag = cinfo->npcflag;
1653 unit_flags = cinfo->unit_flags;
1654 dynamicflags = cinfo->dynamicflags;
1655
1656 if (data)
1657 {
1658 if (data->npcflag)
1659 npcflag = data->npcflag;
1660
1661 if (data->unit_flags)
1662 unit_flags = data->unit_flags;
1663
1664 if (data->dynamicflags)
1665 dynamicflags = data->dynamicflags;
1666 }
1667}

References CreatureTemplate::dynamicflags, CreatureData::dynamicflags, CreatureTemplate::npcflag, CreatureData::npcflag, CreatureTemplate::unit_flags, and CreatureData::unit_flags.

Referenced by Creature::UpdateEntry().

◆ ChooseDisplayId()

CreatureModel const * ObjectMgr::ChooseDisplayId ( CreatureTemplate const *  cinfo,
CreatureData const *  data = nullptr 
)
static
1636{
1637 // Load creature model (display id)
1638 if (data && data->displayid)
1639 if (CreatureModel const* model = cinfo->GetModelWithDisplayId(data->displayid))
1640 return model;
1641
1642 if (!cinfo->HasFlagsExtra(CREATURE_FLAG_EXTRA_TRIGGER))
1643 if (CreatureModel const* model = cinfo->GetRandomValidModel())
1644 return model;
1645
1646 // Triggers by default receive the invisible model
1647 return cinfo->GetFirstInvisibleModel();
1648}
@ CREATURE_FLAG_EXTRA_TRIGGER
Definition CreatureData.h:52

References CREATURE_FLAG_EXTRA_TRIGGER, CreatureData::displayid, CreatureTemplate::GetFirstInvisibleModel(), CreatureTemplate::GetModelWithDisplayId(), CreatureTemplate::GetRandomValidModel(), and CreatureTemplate::HasFlagsExtra().

Referenced by npc_shattrath_daily_quest::DoAction(), Creature::GetNativeObjectScale(), AuraEffect::HandleAuraDummy(), AuraEffect::HandleAuraMounted(), AuraEffect::HandleAuraTransform(), Creature::InitEntry(), and SmartScript::ProcessAction().

◆ DeleteCreatureData()

void ObjectMgr::DeleteCreatureData ( ObjectGuid::LowType  spawnId)
8566{
8567 // remove mapid*cellid -> guid_set map
8568 CreatureData const* data = GetCreatureData(guid);
8569 if (data)
8570 RemoveCreatureFromGrid(guid, data);
8571
8572 _creatureDataStore.erase(guid);
8573}
CreatureDataContainer _creatureDataStore
Definition ObjectMgr.h:1618
void RemoveCreatureFromGrid(ObjectGuid::LowType guid, CreatureData const *data)
Definition ObjectMgr.cpp:2633
CreatureData const * GetCreatureData(ObjectGuid::LowType spawnId) const
Definition ObjectMgr.h:1219

References _creatureDataStore, GetCreatureData(), and RemoveCreatureFromGrid().

◆ DeleteGameTele()

bool ObjectMgr::DeleteGameTele ( std::string_view  name)
9539{
9540 // explicit name case
9541 std::wstring wname;
9542 if (!Utf8toWStr(name, wname))
9543 return false;
9544
9545 // converting string that we try to find to lower case
9546 wstrToLower(wname);
9547
9548 for (GameTeleContainer::iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9549 {
9550 if (itr->second.wnameLow == wname)
9551 {
9553
9554 stmt->SetData(0, itr->second.name);
9555
9556 WorldDatabase.Execute(stmt);
9557
9558 _gameTeleStore.erase(itr);
9559 return true;
9560 }
9561 }
9562
9563 return false;
9564}
@ WORLD_DEL_GAME_TELE
Definition WorldDatabase.h:42

References _gameTeleStore, PreparedStatementBase::SetData(), Utf8toWStr(), WORLD_DEL_GAME_TELE, WorldDatabase, and wstrToLower().

◆ DeleteGOData()

void ObjectMgr::DeleteGOData ( ObjectGuid::LowType  guid)
8576{
8577 // remove mapid*cellid -> guid_set map
8578 GameObjectData const* data = GetGameObjectData(guid);
8579 if (data)
8580 RemoveGameobjectFromGrid(guid, data);
8581
8582 _gameObjectDataStore.erase(guid);
8583}
GameObjectData const * GetGameObjectData(ObjectGuid::LowType spawnId) const
Definition ObjectMgr.h:1254
GameObjectDataContainer _gameObjectDataStore
Definition ObjectMgr.h:1632
void RemoveGameobjectFromGrid(ObjectGuid::LowType guid, GameObjectData const *data)
Definition ObjectMgr.cpp:3075

References _gameObjectDataStore, GetGameObjectData(), and RemoveGameobjectFromGrid().

◆ GenerateAuctionID()

uint32 ObjectMgr::GenerateAuctionID ( )
7558{
7559 if (_auctionId >= 0xFFFFFFFE)
7560 {
7561 LOG_ERROR("server.worldserver", "Auctions ids overflow!! Can't continue, shutting down server. ");
7563 }
7564 return _auctionId++;
7565}
static void StopNow(uint8 exitcode)
Definition World.h:188
@ ERROR_EXIT_CODE
Definition World.h:54

References _auctionId, ERROR_EXIT_CODE, LOG_ERROR, and World::StopNow().

◆ GenerateCreatureSpawnId()

uint32 ObjectMgr::GenerateCreatureSpawnId ( )
7589{
7590 if (_creatureSpawnId >= uint32(0xFFFFFF))
7591 {
7592 LOG_ERROR("server.worldserver", "Creature spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info.");
7594 }
7595 return _creatureSpawnId++;
7596}

References _creatureSpawnId, ERROR_EXIT_CODE, LOG_ERROR, and World::StopNow().

Referenced by AddCreData().

◆ GenerateEquipmentSetGuid()

uint64 ObjectMgr::GenerateEquipmentSetGuid ( )
7568{
7569 if (_equipmentSetGuid >= uint64(0xFFFFFFFFFFFFFFFELL))
7570 {
7571 LOG_ERROR("server.worldserver", "EquipmentSet guid overflow!! Can't continue, shutting down server. ");
7573 }
7574 return _equipmentSetGuid++;
7575}
std::uint64_t uint64
Definition Define.h:106

References _equipmentSetGuid, ERROR_EXIT_CODE, LOG_ERROR, and World::StopNow().

◆ GenerateGameObjectSpawnId()

uint32 ObjectMgr::GenerateGameObjectSpawnId ( )
7599{
7600 if (_gameObjectSpawnId >= uint32(0xFFFFFF))
7601 {
7602 LOG_ERROR("server.worldserver", "GameObject spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7604 }
7605 return _gameObjectSpawnId++;
7606}

References _gameObjectSpawnId, ERROR_EXIT_CODE, LOG_ERROR, and World::StopNow().

Referenced by AddGOData().

◆ GenerateMailID()

uint32 ObjectMgr::GenerateMailID ( )
7578{
7579 if (_mailId >= 0xFFFFFFFE)
7580 {
7581 LOG_ERROR("server.worldserver", "Mail ids overflow!! Can't continue, shutting down server. ");
7583 }
7584 std::lock_guard<std::mutex> guard(_mailIdMutex);
7585 return _mailId++;
7586}
std::mutex _mailIdMutex
Definition ObjectMgr.h:1498

References _mailId, _mailIdMutex, ERROR_EXIT_CODE, LOG_ERROR, and World::StopNow().

◆ GeneratePetName()

std::string ObjectMgr::GeneratePetName ( uint32  entry)
8065{
8066 std::vector<std::string>& list0 = _petHalfName0[entry];
8067 std::vector<std::string>& list1 = _petHalfName1[entry];
8068
8069 if (list0.empty() || list1.empty())
8070 {
8071 CreatureTemplate const* cinfo = GetCreatureTemplate(entry);
8072 char const* petname = GetPetName(cinfo->family, sWorld->GetDefaultDbcLocale());
8073 if (!petname)
8074 return cinfo->Name;
8075
8076 return std::string(petname);
8077 }
8078
8079 return *(list0.begin() + urand(0, list0.size() - 1)) + *(list1.begin() + urand(0, list1.size() - 1));
8080}
char const * GetPetName(uint32 petfamily, uint32 dbclang)
Definition DBCStores.cpp:665
HalfNameContainer _petHalfName1
Definition ObjectMgr.h:1607
HalfNameContainer _petHalfName0
Definition ObjectMgr.h:1606
std::string Name
Definition CreatureData.h:191

References _petHalfName0, _petHalfName1, CreatureTemplate::family, GetCreatureTemplate(), GetPetName(), CreatureTemplate::Name, sWorld, and urand().

Referenced by GeneratePetNameLocale().

◆ GeneratePetNameLocale()

std::string ObjectMgr::GeneratePetNameLocale ( uint32  entry,
LocaleConstant  locale 
)
8052{
8053 std::vector<std::string>& list0 = _petHalfLocaleName0[std::make_pair(entry, locale)];
8054 std::vector<std::string>& list1 = _petHalfLocaleName1[std::make_pair(entry, locale)];
8055
8056 if (list0.empty() || list1.empty())
8057 {
8058 return GeneratePetName(entry);
8059 }
8060
8061 return *(list0.begin() + urand(0, list0.size() - 1)) + *(list1.begin() + urand(0, list1.size() - 1));
8062}
HalfNameContainerLocale _petHalfLocaleName0
Definition ObjectMgr.h:1609
HalfNameContainerLocale _petHalfLocaleName1
Definition ObjectMgr.h:1610
std::string GeneratePetName(uint32 entry)
Definition ObjectMgr.cpp:8064

References _petHalfLocaleName0, _petHalfLocaleName1, GeneratePetName(), and urand().

◆ GeneratePetNumber()

uint32 ObjectMgr::GeneratePetNumber ( )
8083{
8084 std::lock_guard<std::mutex> guard(_hiPetNumberMutex);
8085 return ++_hiPetNumber;
8086}
std::mutex _hiPetNumberMutex
Definition ObjectMgr.h:1500

References _hiPetNumber, and _hiPetNumberMutex.

◆ GetAccessRequirement()

DungeonProgressionRequirements const * ObjectMgr::GetAccessRequirement ( uint32  mapid,
Difficulty  difficulty 
) const
inline
879 {
880 DungeonProgressionRequirementsContainer::const_iterator itr = _accessRequirementStore.find(mapid);
881 if (itr != _accessRequirementStore.end())
882 {
883 std::unordered_map<uint8, DungeonProgressionRequirements*> difficultiesProgressionRequirements = itr->second;
884 auto difficultiesItr = difficultiesProgressionRequirements.find(difficulty);
885 if (difficultiesItr != difficultiesProgressionRequirements.end())
886 {
887 return difficultiesItr->second;
888 }
889 }
890 return nullptr;
891 }

References _accessRequirementStore.

◆ GetAcoreString() [1/2]

AcoreString const * ObjectMgr::GetAcoreString ( uint32  entry) const
inline
1358 {
1359 AcoreStringContainer::const_iterator itr = _acoreStringStore.find(entry);
1360 if (itr == _acoreStringStore.end())
1361 return nullptr;
1362
1363 return &itr->second;
1364 }
AcoreStringContainer _acoreStringStore
Definition ObjectMgr.h:1650

References _acoreStringStore.

Referenced by GetAcoreString(), and GetAcoreStringForDBCLocale().

◆ GetAcoreString() [2/2]

std::string ObjectMgr::GetAcoreString ( uint32  entry,
LocaleConstant  locale 
) const
9271{
9272 AcoreString const* as = GetAcoreString(entry);
9273 if (as && !as->Content.empty())
9274 {
9275 if (as->Content.size() > std::size_t(locale) && !as->Content[locale].empty())
9276 return as->Content[locale];
9277
9278 return as->Content[DEFAULT_LOCALE];
9279 }
9280
9281 std::string msg = Acore::StringFormat("No entry for acore_string ({}) in DB.", entry);
9282 LOG_ERROR("sql.sql", msg);
9283 return msg;
9284}
#define DEFAULT_LOCALE
Definition Common.h:131
AcoreString const * GetAcoreString(uint32 entry) const
Definition ObjectMgr.h:1357
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default AC string format function.
Definition StringFormat.h:34
Definition ObjectMgr.h:502
std::vector< std::string > Content
Definition ObjectMgr.h:503

References AcoreString::Content, DEFAULT_LOCALE, GetAcoreString(), LOG_ERROR, and Acore::StringFormat().

◆ GetAcoreStringForDBCLocale()

std::string ObjectMgr::GetAcoreStringForDBCLocale ( uint32  entry) const
inline
1366{ return GetAcoreString(entry, DBCLocaleIndex); }

References DBCLocaleIndex, and GetAcoreString().

◆ GetAllAreaTriggerScriptData()

AreaTriggerScriptContainer const & ObjectMgr::GetAllAreaTriggerScriptData ( ) const
inline
896{ return _areaTriggerScriptStore; }
AreaTriggerScriptContainer _areaTriggerScriptStore
Definition ObjectMgr.h:1531

References _areaTriggerScriptStore.

◆ GetAllCreatureData()

CreatureDataContainer const & ObjectMgr::GetAllCreatureData ( ) const
inline
1218{ return _creatureDataStore; }

References _creatureDataStore.

◆ GetAllGOData()

GameObjectDataContainer const & ObjectMgr::GetAllGOData ( ) const
inline
1253{ return _gameObjectDataStore; }

References _gameObjectDataStore.

◆ GetAreaTrigger()

AreaTrigger const * ObjectMgr::GetAreaTrigger ( uint32  trigger) const
inline
863 {
864 AreaTriggerContainer::const_iterator itr = _areaTriggerStore.find(trigger);
865 if (itr != _areaTriggerStore.end())
866 return &itr->second;
867 return nullptr;
868 }
AreaTriggerContainer _areaTriggerStore
Definition ObjectMgr.h:1529

References _areaTriggerStore.

Referenced by GetGoBackTrigger(), LoadAreaTriggerScripts(), LoadAreaTriggerTeleports(), LoadQuestAreaTriggers(), and LoadTavernAreaTriggers().

◆ GetAreaTriggerScriptId()

uint32 ObjectMgr::GetAreaTriggerScriptId ( uint32  trigger_id)
9364{
9365 AreaTriggerScriptContainer::const_iterator i = _areaTriggerScriptStore.find(trigger_id);
9366 if (i != _areaTriggerScriptStore.end())
9367 return i->second;
9368 return 0;
9369}

References _areaTriggerScriptStore.

◆ GetAreaTriggerTeleport()

AreaTriggerTeleport const * ObjectMgr::GetAreaTriggerTeleport ( uint32  trigger) const
inline
871 {
872 AreaTriggerTeleportContainer::const_iterator itr = _areaTriggerTeleportStore.find(trigger);
873 if (itr != _areaTriggerTeleportStore.end())
874 return &itr->second;
875 return nullptr;
876 }
AreaTriggerTeleportContainer _areaTriggerTeleportStore
Definition ObjectMgr.h:1530

References _areaTriggerTeleportStore.

◆ GetBaseReputationOf()

int32 ObjectMgr::GetBaseReputationOf ( FactionEntry const *  factionEntry,
uint8  race,
uint8  playerClass 
)
9378{
9379 if (!factionEntry)
9380 return 0;
9381
9382 uint32 raceMask = (1 << (race - 1));
9383 uint32 classMask = (1 << (playerClass - 1));
9384
9385 for (int i = 0; i < 4; i++)
9386 {
9387 if ((!factionEntry->BaseRepClassMask[i] ||
9388 factionEntry->BaseRepClassMask[i] & classMask) &&
9389 (!factionEntry->BaseRepRaceMask[i] ||
9390 factionEntry->BaseRepRaceMask[i] & raceMask))
9391 return factionEntry->BaseRepValue[i];
9392 }
9393
9394 return 0;
9395}

References FactionEntry::BaseRepClassMask, FactionEntry::BaseRepRaceMask, and FactionEntry::BaseRepValue.

◆ GetBaseXP()

uint32 ObjectMgr::GetBaseXP ( uint8  level)
7993{
7994 return _baseXPTable[level] ? _baseXPTable[level] : 0;
7995}
BaseXPContainer _baseXPTable
Definition ObjectMgr.h:1600

References _baseXPTable.

◆ GetBreadcrumbsForQuest()

std::vector< uint32 > const * ObjectMgr::GetBreadcrumbsForQuest ( uint32  questId) const
inline
1152 {
1153 auto itr = _breadcrumbsForQuest.find(questId);
1154 if (itr != _breadcrumbsForQuest.end())
1155 return &itr->second;
1156
1157 return nullptr;
1158 }
BreadcrumbQuestMap _breadcrumbsForQuest
Definition ObjectMgr.h:1149

References _breadcrumbsForQuest.

◆ GetBroadcastText()

BroadcastText const * ObjectMgr::GetBroadcastText ( uint32  id) const
inline
1212 {
1213 BroadcastTextContainer::const_iterator itr = _broadcastTextStore.find(id);
1214 if (itr != _broadcastTextStore.end())
1215 return &itr->second;
1216 return nullptr;
1217 }
BroadcastTextContainer _broadcastTextStore
Definition ObjectMgr.h:1639

References _broadcastTextStore.

Referenced by LoadGossipMenuItems(), LoadGossipText(), and LoadScripts().

◆ GetCreatureAddon()

CreatureAddon const * ObjectMgr::GetCreatureAddon ( ObjectGuid::LowType  lowguid)
1423{
1424 CreatureAddonContainer::const_iterator itr = _creatureAddonStore.find(lowguid);
1425 if (itr != _creatureAddonStore.end())
1426 return &(itr->second);
1427
1428 return nullptr;
1429}
CreatureAddonContainer _creatureAddonStore
Definition ObjectMgr.h:1623

References _creatureAddonStore.

◆ GetCreatureBaseStats()

CreatureBaseStats const * ObjectMgr::GetCreatureBaseStats ( uint8  level,
uint8  unitClass 
)
10325{
10326 CreatureBaseStatsContainer::const_iterator it = _creatureBaseStatsStore.find(MAKE_PAIR16(level, unitClass));
10327
10328 if (it != _creatureBaseStatsStore.end())
10329 return &(it->second);
10330
10331 struct DefaultCreatureBaseStats : public CreatureBaseStats
10332 {
10333 DefaultCreatureBaseStats()
10334 {
10335 BaseArmor = 1;
10336 for (uint8 j = 0; j < MAX_EXPANSIONS; ++j)
10337 {
10338 BaseHealth[j] = 1;
10339 BaseDamage[j] = 0.0f;
10340 }
10341 BaseMana = 0;
10342 AttackPower = 0;
10343 RangedAttackPower = 0;
10344 }
10345 };
10346 static const DefaultCreatureBaseStats defStats;
10347 return &defStats;
10348}
uint16 MAKE_PAIR16(uint8 l, uint8 h)
Definition ObjectDefines.h:83
CreatureBaseStatsContainer _creatureBaseStatsStore
Definition ObjectMgr.h:1584

References _creatureBaseStatsStore, MAKE_PAIR16(), and MAX_EXPANSIONS.

Referenced by AddCreData().

◆ GetCreatureData()

CreatureData const * ObjectMgr::GetCreatureData ( ObjectGuid::LowType  spawnId) const
inline
1220 {
1221 CreatureDataContainer::const_iterator itr = _creatureDataStore.find(spawnId);
1222 if (itr == _creatureDataStore.end()) return nullptr;
1223 return &itr->second;
1224 }

References _creatureDataStore.

Referenced by DeleteCreatureData(), LoadCreatureAddons(), LoadCreatureDataFromDB(), LoadCreatureMovementOverrides(), LoadCreatureSparring(), LoadLinkedRespawn(), and SetCreatureLinkedRespawn().

◆ GetCreatureLocale()

CreatureLocale const * ObjectMgr::GetCreatureLocale ( uint32  entry) const
inline
1261 {
1262 CreatureLocaleContainer::const_iterator itr = _creatureLocaleStore.find(entry);
1263 if (itr == _creatureLocaleStore.end()) return nullptr;
1264 return &itr->second;
1265 }
CreatureLocaleContainer _creatureLocaleStore
Definition ObjectMgr.h:1631

References _creatureLocaleStore.

◆ GetCreatureModelInfo()

CreatureModelInfo const * ObjectMgr::GetCreatureModelInfo ( uint32  modelId) const
1627{
1628 CreatureModelContainer::const_iterator itr = _creatureModelStore.find(modelId);
1629 if (itr != _creatureModelStore.end())
1630 return &(itr->second);
1631
1632 return nullptr;
1633}
CreatureModelContainer _creatureModelStore
Definition ObjectMgr.h:1622

References _creatureModelStore.

Referenced by GetCreatureModelRandomGender(), and LoadCreatureTemplateModels().

◆ GetCreatureModelRandomGender()

CreatureModelInfo const * ObjectMgr::GetCreatureModelRandomGender ( CreatureModel model,
CreatureTemplate const *  creatureTemplate 
) const
1670{
1671 CreatureModelInfo const* modelInfo = GetCreatureModelInfo(model->CreatureDisplayID);
1672 if (!modelInfo)
1673 return nullptr;
1674
1675 // If a model for another gender exists, 50% chance to use it
1676 if (modelInfo->modelid_other_gender != 0 && urand(0, 1) == 0)
1677 {
1678 CreatureModelInfo const* minfo_tmp = GetCreatureModelInfo(modelInfo->modelid_other_gender);
1679 if (!minfo_tmp)
1680 LOG_ERROR("sql.sql", "Model (Entry: {}) has modelid_other_gender {} not found in table `creature_model_info`. ", model->CreatureDisplayID, modelInfo->modelid_other_gender);
1681 else
1682 {
1683 // Model ID changed
1684 model->CreatureDisplayID = modelInfo->modelid_other_gender;
1685 if (creatureTemplate)
1686 {
1687 auto itr = std::find_if(creatureTemplate->Models.begin(), creatureTemplate->Models.end(), [&](CreatureModel const& templateModel)
1688 {
1689 return templateModel.CreatureDisplayID == modelInfo->modelid_other_gender;
1690 });
1691 if (itr != creatureTemplate->Models.end())
1692 *model = *itr;
1693 }
1694 return minfo_tmp;
1695 }
1696 }
1697
1698 return modelInfo;
1699}
CreatureModelInfo const * GetCreatureModelInfo(uint32 modelId) const
Definition ObjectMgr.cpp:1626
Definition CreatureData.h:394
uint32 modelid_other_gender
Definition CreatureData.h:398
uint32 CreatureDisplayID
Definition CreatureData.h:179

References CreatureModel::CreatureDisplayID, GetCreatureModelInfo(), LOG_ERROR, CreatureModelInfo::modelid_other_gender, CreatureTemplate::Models, and urand().

Referenced by GetTaxiMountDisplayId().

◆ GetCreatureMovementOverride()

CreatureMovementData const * ObjectMgr::GetCreatureMovementOverride ( ObjectGuid::LowType  spawnId) const
1441{
1443}
std::unordered_map< ObjectGuid::LowType, CreatureMovementData > _creatureMovementOverrides
Definition ObjectMgr.h:1625
auto MapGetValuePtr(M &map, typename M::key_type const &key) -> decltype(AddressOrSelf(map.find(key) ->second))
Definition Containers.h:216

References _creatureMovementOverrides, and Acore::Containers::MapGetValuePtr().

◆ GetCreatureQuestInvolvedRelationBounds()

QuestRelationBounds ObjectMgr::GetCreatureQuestInvolvedRelationBounds ( uint32  creature_entry)
inline
1008 {
1009 return _creatureQuestInvolvedRelations.equal_range(creature_entry);
1010 }
QuestRelations _creatureQuestInvolvedRelations
Definition ObjectMgr.h:1548

References _creatureQuestInvolvedRelations.

◆ GetCreatureQuestInvolvedRelationMap()

QuestRelations * ObjectMgr::GetCreatureQuestInvolvedRelationMap ( )
inline

◆ GetCreatureQuestItemList()

CreatureQuestItemList const * ObjectMgr::GetCreatureQuestItemList ( uint32  id) const
inline
826 {
827 CreatureQuestItemMap::const_iterator itr = _creatureQuestItemStore.find(id);
828 if (itr != _creatureQuestItemStore.end())
829 return &itr->second;
830 return nullptr;
831 }
CreatureQuestItemMap _creatureQuestItemStore
Definition ObjectMgr.h:1628

References _creatureQuestItemStore.

◆ GetCreatureQuestItemMap()

CreatureQuestItemMap const * ObjectMgr::GetCreatureQuestItemMap ( ) const
inline
832{ return &_creatureQuestItemStore; }

References _creatureQuestItemStore.

◆ GetCreatureQuestRelationBounds()

QuestRelationBounds ObjectMgr::GetCreatureQuestRelationBounds ( uint32  creature_entry)
inline
1003 {
1004 return _creatureQuestRelations.equal_range(creature_entry);
1005 }
QuestRelations _creatureQuestRelations
Definition ObjectMgr.h:1547

References _creatureQuestRelations.

◆ GetCreatureQuestRelationMap()

QuestRelations * ObjectMgr::GetCreatureQuestRelationMap ( )
inline
993 {
995 }

References _creatureQuestRelations.

◆ GetCreatureTemplate()

◆ GetCreatureTemplateAddon()

CreatureAddon const * ObjectMgr::GetCreatureTemplateAddon ( uint32  entry)
1432{
1433 CreatureAddonContainer::const_iterator itr = _creatureTemplateAddonStore.find(entry);
1434 if (itr != _creatureTemplateAddonStore.end())
1435 return &(itr->second);
1436
1437 return nullptr;
1438}
CreatureAddonContainer _creatureTemplateAddonStore
Definition ObjectMgr.h:1624

References _creatureTemplateAddonStore.

◆ GetCreatureTemplates()

CreatureTemplateContainer const * ObjectMgr::GetCreatureTemplates ( ) const
inline
769{ return &_creatureTemplateStore; }
CreatureTemplateContainer _creatureTemplateStore
Definition ObjectMgr.h:1619

References _creatureTemplateStore.

Referenced by LoadCreatureClassLevelStats(), and LoadNPCSpellClickSpells().

◆ GetDBCLocaleIndex()

LocaleConstant ObjectMgr::GetDBCLocaleIndex ( ) const
inline
1367{ return DBCLocaleIndex; }

References DBCLocaleIndex.

◆ GetDungeonEncounterList()

DungeonEncounterList const * ObjectMgr::GetDungeonEncounterList ( uint32  mapId,
Difficulty  difficulty 
)
inline
947 {
948 std::unordered_map<uint32, DungeonEncounterList>::const_iterator itr = _dungeonEncounterStore.find(MAKE_PAIR32(mapId, difficulty));
949 if (itr != _dungeonEncounterStore.end())
950 return &itr->second;
951 return nullptr;
952 }

References _dungeonEncounterStore, and MAKE_PAIR32().

◆ GetEquipmentInfo()

EquipmentInfo const * ObjectMgr::GetEquipmentInfo ( uint32  entry,
int8 id 
)
1446{
1447 EquipmentInfoContainer::const_iterator itr = _equipmentInfoStore.find(entry);
1448 if (itr == _equipmentInfoStore.end())
1449 return nullptr;
1450
1451 if (itr->second.empty())
1452 return nullptr;
1453
1454 if (id == -1) // select a random element
1455 {
1456 EquipmentInfoContainerInternal::const_iterator ritr = itr->second.begin();
1457 std::advance(ritr, urand(0u, itr->second.size() - 1));
1458 id = std::distance(itr->second.begin(), ritr) + 1;
1459 return &ritr->second;
1460 }
1461 else
1462 {
1463 EquipmentInfoContainerInternal::const_iterator itr2 = itr->second.find(id);
1464 if (itr2 != itr->second.end())
1465 return &itr2->second;
1466 }
1467
1468 return nullptr;
1469}
EquipmentInfoContainer _equipmentInfoStore
Definition ObjectMgr.h:1629

References _equipmentInfoStore, and urand().

Referenced by LoadCreatureDataFromDB(), and LoadCreatures().

◆ GetFishingBaseSkillLevel()

int32 ObjectMgr::GetFishingBaseSkillLevel ( uint32  entry) const
inline
1118 {
1119 FishingBaseSkillContainer::const_iterator itr = _fishingBaseForAreaStore.find(entry);
1120 return itr != _fishingBaseForAreaStore.end() ? itr->second : 0;
1121 }

References _fishingBaseForAreaStore.

◆ GetGameObjectAddon()

GameObjectAddon const * ObjectMgr::GetGameObjectAddon ( ObjectGuid::LowType  lowguid)
1414{
1415 GameObjectAddonContainer::const_iterator itr = _gameObjectAddonStore.find(lowguid);
1416 if (itr != _gameObjectAddonStore.end())
1417 return &(itr->second);
1418
1419 return nullptr;
1420}
GameObjectAddonContainer _gameObjectAddonStore
Definition ObjectMgr.h:1626

References _gameObjectAddonStore.

◆ GetGameObjectData()

GameObjectData const * ObjectMgr::GetGameObjectData ( ObjectGuid::LowType  spawnId) const
inline
1255 {
1256 GameObjectDataContainer::const_iterator itr = _gameObjectDataStore.find(spawnId);
1257 if (itr == _gameObjectDataStore.end()) return nullptr;
1258 return &itr->second;
1259 }

References _gameObjectDataStore.

Referenced by DeleteGOData(), LoadGameObjectAddons(), LoadGameObjectDataFromDB(), LoadLinkedRespawn(), and LoadScripts().

◆ GetGameObjectLocale()

GameObjectLocale const * ObjectMgr::GetGameObjectLocale ( uint32  entry) const
inline
1267 {
1268 GameObjectLocaleContainer::const_iterator itr = _gameObjectLocaleStore.find(entry);
1269 if (itr == _gameObjectLocaleStore.end()) return nullptr;
1270 return &itr->second;
1271 }
GameObjectLocaleContainer _gameObjectLocaleStore
Definition ObjectMgr.h:1633

References _gameObjectLocaleStore.

◆ GetGameObjectQuestItemList()

GameObjectQuestItemList const * ObjectMgr::GetGameObjectQuestItemList ( uint32  id) const
inline
817 {
818 GameObjectQuestItemMap::const_iterator itr = _gameObjectQuestItemStore.find(id);
819 if (itr != _gameObjectQuestItemStore.end())
820 return &itr->second;
821 return nullptr;
822 }
GameObjectQuestItemMap _gameObjectQuestItemStore
Definition ObjectMgr.h:1627

References _gameObjectQuestItemStore.

◆ GetGameObjectQuestItemMap()

GameObjectQuestItemMap const * ObjectMgr::GetGameObjectQuestItemMap ( ) const
inline

◆ GetGameObjectTemplate()

GameObjectTemplate const * ObjectMgr::GetGameObjectTemplate ( uint32  entry)
10649{
10650 GameObjectTemplateContainer::const_iterator itr = _gameObjectTemplateStore.find(entry);
10651 if (itr != _gameObjectTemplateStore.end())
10652 return &(itr->second);
10653
10654 return nullptr;
10655}
GameObjectTemplateContainer _gameObjectTemplateStore
Definition ObjectMgr.h:1634

References _gameObjectTemplateStore.

Referenced by AddGOData(), IsGameObjectStaticTransport(), LoadGameObjectDataFromDB(), LoadGameobjectQuestEnders(), LoadGameObjectQuestItems(), LoadGameobjectQuestStarters(), LoadGameobjects(), LoadGameObjectTemplateAddons(), LoadQuestGreetings(), LoadQuestGreetingsLocales(), LoadQuests(), LoadScripts(), and LoadTempSummons().

◆ GetGameObjectTemplateAddon()

GameObjectTemplateAddon const * ObjectMgr::GetGameObjectTemplateAddon ( uint32  entry) const
10664{
10665 auto itr = _gameObjectTemplateAddonStore.find(entry);
10666 if (itr != _gameObjectTemplateAddonStore.end())
10667 return &itr->second;
10668
10669 return nullptr;
10670}
GameObjectTemplateAddonContainer _gameObjectTemplateAddonStore
Definition ObjectMgr.h:1635

References _gameObjectTemplateAddonStore.

◆ GetGameObjectTemplates()

GameObjectTemplateContainer const * ObjectMgr::GetGameObjectTemplates ( ) const
inline

◆ GetGameTele() [1/2]

GameTele const * ObjectMgr::GetGameTele ( std::string_view  name,
bool  exactSearch = false 
) const
9483{
9484 // explicit name case
9485 std::wstring wname;
9486 if (!Utf8toWStr(name, wname))
9487 return nullptr;
9488
9489 // converting string that we try to find to lower case
9490 wstrToLower(wname);
9491
9492 // Alternative first GameTele what contains wnameLow as substring in case no GameTele location found
9493 const GameTele* alt = nullptr;
9494 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9495 {
9496 if (itr->second.wnameLow == wname)
9497 return &itr->second;
9498 else if (!exactSearch && !alt && itr->second.wnameLow.find(wname) != std::wstring::npos)
9499 alt = &itr->second;
9500 }
9501
9502 return alt;
9503}
Definition ObjectMgr.h:133

References _gameTeleStore, Utf8toWStr(), GameTele::wnameLow, and wstrToLower().

◆ GetGameTele() [2/2]

GameTele const * ObjectMgr::GetGameTele ( uint32  id) const
inline
1399 {
1400 GameTeleContainer::const_iterator itr = _gameTeleStore.find(id);
1401 if (itr == _gameTeleStore.end()) return nullptr;
1402 return &itr->second;
1403 }

References _gameTeleStore.

◆ GetGameTeleMap()

GameTeleContainer const & ObjectMgr::GetGameTeleMap ( ) const
inline
1405{ return _gameTeleStore; }

References _gameTeleStore.

◆ GetGenerator()

template<HighGuid type>
ObjectGuidGeneratorBase & ObjectMgr::GetGenerator ( )
inline
1131 {
1132 static_assert(ObjectGuidTraits<type>::Global, "Only global guid can be generated in ObjectMgr context");
1133 return GetGuidSequenceGenerator<type>();
1134 }
Definition ObjectGuid.h:76

◆ GetGoBackTrigger()

AreaTriggerTeleport const * ObjectMgr::GetGoBackTrigger ( uint32  Map) const
7457{
7458 bool useParentDbValue = false;
7459 uint32 parentId = 0;
7460 MapEntry const* mapEntry = sMapStore.LookupEntry(Map);
7461 if (!mapEntry || mapEntry->entrance_map < 0)
7462 return nullptr;
7463
7464 if (mapEntry->IsDungeon())
7465 {
7466 InstanceTemplate const* iTemplate = sObjectMgr->GetInstanceTemplate(Map);
7467
7468 if (!iTemplate)
7469 return nullptr;
7470
7471 parentId = iTemplate->Parent;
7472 useParentDbValue = true;
7473 }
7474
7475 uint32 entrance_map = uint32(mapEntry->entrance_map);
7476 for (AreaTriggerTeleportContainer::const_iterator itr = _areaTriggerTeleportStore.begin(); itr != _areaTriggerTeleportStore.end(); ++itr)
7477 if ((!useParentDbValue && itr->second.target_mapId == entrance_map) || (useParentDbValue && itr->second.target_mapId == parentId))
7478 {
7479 AreaTrigger const* atEntry = GetAreaTrigger(itr->first);
7480 if (atEntry && atEntry->map == Map)
7481 return &itr->second;
7482 }
7483 return nullptr;
7484}
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
AreaTrigger const * GetAreaTrigger(uint32 trigger) const
Definition ObjectMgr.h:862
Definition ObjectMgr.h:421
uint32 map
Definition ObjectMgr.h:423
Definition Map.h:121
uint32 Parent
Definition Map.h:122
Definition DBCStructure.h:1325
int32 entrance_map
Definition DBCStructure.h:1340
bool IsDungeon() const
Definition DBCStructure.h:1351

References _areaTriggerTeleportStore, MapEntry::entrance_map, GetAreaTrigger(), MapEntry::IsDungeon(), AreaTrigger::map, InstanceTemplate::Parent, sMapStore, and sObjectMgr.

◆ GetGOQuestInvolvedRelationBounds()

QuestRelationBounds ObjectMgr::GetGOQuestInvolvedRelationBounds ( uint32  go_entry)
inline
988 {
989 return _goQuestInvolvedRelations.equal_range(go_entry);
990 }
QuestRelations _goQuestInvolvedRelations
Definition ObjectMgr.h:1546

References _goQuestInvolvedRelations.

◆ GetGOQuestInvolvedRelationMap()

QuestRelations * ObjectMgr::GetGOQuestInvolvedRelationMap ( )
inline
978 {
980 }

References _goQuestInvolvedRelations.

◆ GetGOQuestRelationBounds()

QuestRelationBounds ObjectMgr::GetGOQuestRelationBounds ( uint32  go_entry)
inline
983 {
984 return _goQuestRelations.equal_range(go_entry);
985 }
QuestRelations _goQuestRelations
Definition ObjectMgr.h:1545

References _goQuestRelations.

◆ GetGOQuestRelationMap()

QuestRelations * ObjectMgr::GetGOQuestRelationMap ( )
inline
973 {
974 return &_goQuestRelations;
975 }

References _goQuestRelations.

◆ GetGossipMenuItemsLocale()

GossipMenuItemsLocale const * ObjectMgr::GetGossipMenuItemsLocale ( uint32  entry) const
inline
1297 {
1298 GossipMenuItemsLocaleContainer::const_iterator itr = _gossipMenuItemsLocaleStore.find(entry);
1299 if (itr == _gossipMenuItemsLocaleStore.end()) return nullptr;
1300 return &itr->second;
1301 }
GossipMenuItemsLocaleContainer _gossipMenuItemsLocaleStore
Definition ObjectMgr.h:1651

References _gossipMenuItemsLocaleStore.

◆ GetGossipMenuItemsMapBounds()

GossipMenuItemsMapBounds ObjectMgr::GetGossipMenuItemsMapBounds ( uint32  uiMenuId) const
inline
1445 {
1446 return _gossipMenuItemsStore.equal_range(uiMenuId);
1447 }
GossipMenuItemsContainer _gossipMenuItemsStore
Definition ObjectMgr.h:1540

References _gossipMenuItemsStore.

◆ GetGossipMenuItemsMapBoundsNonConst()

GossipMenuItemsMapBoundsNonConst ObjectMgr::GetGossipMenuItemsMapBoundsNonConst ( uint32  uiMenuId)
inline
1449 {
1450 return _gossipMenuItemsStore.equal_range(uiMenuId);
1451 }

References _gossipMenuItemsStore.

◆ GetGossipMenusMapBounds()

GossipMenusMapBounds ObjectMgr::GetGossipMenusMapBounds ( uint32  uiMenuId) const
inline
1435 {
1436 return _gossipMenusStore.equal_range(uiMenuId);
1437 }
GossipMenusContainer _gossipMenusStore
Definition ObjectMgr.h:1539

References _gossipMenusStore.

◆ GetGossipMenusMapBoundsNonConst()

GossipMenusMapBoundsNonConst ObjectMgr::GetGossipMenusMapBoundsNonConst ( uint32  uiMenuId)
inline
1440 {
1441 return _gossipMenusStore.equal_range(uiMenuId);
1442 }

References _gossipMenusStore.

◆ GetGossipText()

GossipText const * ObjectMgr::GetGossipText ( uint32  Text_ID) const
6504{
6505 GossipTextContainer::const_iterator itr = _gossipTextStore.find(Text_ID);
6506 if (itr != _gossipTextStore.end())
6507 return &itr->second;
6508 return nullptr;
6509}
GossipTextContainer _gossipTextStore
Definition ObjectMgr.h:1527

References _gossipTextStore.

Referenced by LoadGossipMenu().

◆ GetGridObjectGuids()

CellObjectGuids const & ObjectMgr::GetGridObjectGuids ( uint16  mapid,
uint8  spawnMode,
uint32  gridId 
)
inline
1174 {
1175 MapObjectGuids::const_iterator itr1 = _mapObjectGuidsStore.find(MAKE_PAIR32(mapid, spawnMode));
1176 if (itr1 != _mapObjectGuidsStore.end())
1177 {
1178 CellObjectGuidsMap::const_iterator itr2 = itr1->second.find(gridId);
1179 if (itr2 != itr1->second.end())
1180 return itr2->second;
1181 }
1182 return _emptyCellObjectGuids;
1183 }
CellObjectGuids _emptyCellObjectGuids
Definition ObjectMgr.h:1617

References _emptyCellObjectGuids, _mapObjectGuidsStore, and MAKE_PAIR32().

◆ GetGuidSequenceGenerator()

template<HighGuid high>
ObjectGuidGeneratorBase & ObjectMgr::GetGuidSequenceGenerator ( )
inlineprivate
1508 {
1509 auto itr = _guidGenerators.find(high);
1510 if (itr == _guidGenerators.end())
1511 itr = _guidGenerators.insert(std::make_pair(high, std::unique_ptr<ObjectGuidGenerator<high>>(new ObjectGuidGenerator<high>()))).first;
1512
1513 return *itr->second;
1514 }
Definition ObjectGuid.h:297
std::map< HighGuid, std::unique_ptr< ObjectGuidGeneratorBase > > _guidGenerators
Definition ObjectMgr.h:1516

References _guidGenerators.

◆ GetInstanceTemplate()

InstanceTemplate const * ObjectMgr::GetInstanceTemplate ( uint32  mapId)
6410{
6411 InstanceTemplateContainer::const_iterator itr = _instanceTemplateStore.find(uint16(mapID));
6412 if (itr != _instanceTemplateStore.end())
6413 return &(itr->second);
6414
6415 return nullptr;
6416}
InstanceTemplateContainer _instanceTemplateStore
Definition ObjectMgr.h:1573

References _instanceTemplateStore.

◆ GetItemLocale()

ItemLocale const * ObjectMgr::GetItemLocale ( uint32  entry) const
inline
1273 {
1274 ItemLocaleContainer::const_iterator itr = _itemLocaleStore.find(entry);
1275 if (itr == _itemLocaleStore.end()) return nullptr;
1276 return &itr->second;
1277 }
ItemLocaleContainer _itemLocaleStore
Definition ObjectMgr.h:1642

References _itemLocaleStore.

◆ GetItemSetNameEntry()

ItemSetNameEntry const * ObjectMgr::GetItemSetNameEntry ( uint32  itemId)
inline
789 {
790 ItemSetNameContainer::iterator itr = _itemSetNameStore.find(itemId);
791 if (itr != _itemSetNameStore.end())
792 return &itr->second;
793 return nullptr;
794 }
ItemSetNameContainer _itemSetNameStore
Definition ObjectMgr.h:1613

References _itemSetNameStore.

◆ GetItemSetNameLocale()

ItemSetNameLocale const * ObjectMgr::GetItemSetNameLocale ( uint32  entry) const
inline
1279 {
1280 ItemSetNameLocaleContainer::const_iterator itr = _itemSetNameLocaleStore.find(entry);
1281 if (itr == _itemSetNameLocaleStore.end())return nullptr;
1282 return &itr->second;
1283 }
ItemSetNameLocaleContainer _itemSetNameLocaleStore
Definition ObjectMgr.h:1643

References _itemSetNameLocaleStore.

◆ GetItemTemplate()

ItemTemplate const * ObjectMgr::GetItemTemplate ( uint32  entry)
3759{
3760 return entry < _itemTemplateStoreFast.size() ? _itemTemplateStoreFast[entry] : nullptr;
3761}
std::vector< ItemTemplate * > _itemTemplateStoreFast
Definition ObjectMgr.h:1641

References _itemTemplateStoreFast.

Referenced by LoadAccessRequirements(), LoadFactionChangeItems(), LoadItemSetNames(), LoadItemTemplates(), LoadPlayerInfo(), LoadQuests(), and LoadScripts().

◆ GetItemTemplateStore()

ItemTemplateContainer const * ObjectMgr::GetItemTemplateStore ( ) const
inline
781{ return &_itemTemplateStore; }
ItemTemplateContainer _itemTemplateStore
Definition ObjectMgr.h:1640

References _itemTemplateStore.

◆ GetItemTemplateStoreFast()

std::vector< ItemTemplate * > const * ObjectMgr::GetItemTemplateStoreFast ( ) const
inline
782{ return &_itemTemplateStoreFast; }

References _itemTemplateStoreFast.

◆ GetLinkedRespawnGuid()

ObjectGuid ObjectMgr::GetLinkedRespawnGuid ( ObjectGuid  guid) const
inline
1246 {
1247 LinkedRespawnContainer::const_iterator itr = _linkedRespawnStore.find(guid);
1248 if (itr == _linkedRespawnStore.end())
1249 return ObjectGuid::Empty;
1250 return itr->second;
1251 }
static ObjectGuid const Empty
Definition ObjectGuid.h:120
LinkedRespawnContainer _linkedRespawnStore
Definition ObjectMgr.h:1630

References _linkedRespawnStore, and ObjectGuid::Empty.

◆ GetLocaleString() [1/2]

static void ObjectMgr::GetLocaleString ( const std::vector< std::string > &  data,
int  loc_idx,
std::string &  value 
)
inlinestatic
1462 {
1463 if (data.size() > std::size_t(loc_idx) && !data[loc_idx].empty())
1464 value = data[loc_idx];
1465 }

◆ GetLocaleString() [2/2]

◆ GetMailLevelReward()

MailLevelReward const * ObjectMgr::GetMailLevelReward ( uint32  level,
uint32  raceMask 
)
inline
1161 {
1162 MailLevelRewardContainer::const_iterator map_itr = _mailLevelRewardStore.find(level);
1163 if (map_itr == _mailLevelRewardStore.end())
1164 return nullptr;
1165
1166 for (const auto & set_itr : map_itr->second)
1167 if (set_itr.raceMask & raceMask)
1168 return &set_itr;
1169
1170 return nullptr;
1171 }
MailLevelRewardContainer _mailLevelRewardStore
Definition ObjectMgr.h:1582

References _mailLevelRewardStore.

◆ GetMapEntranceTrigger()

AreaTriggerTeleport const * ObjectMgr::GetMapEntranceTrigger ( uint32  Map) const

Searches for the areatrigger which teleports players to the given map

7490{
7491 for (AreaTriggerTeleportContainer::const_iterator itr = _areaTriggerTeleportStore.begin(); itr != _areaTriggerTeleportStore.end(); ++itr)
7492 {
7493 if (itr->second.target_mapId == Map) // Id is used to determine correct Scarlet Monastery instance
7494 {
7495 // xinef: no need to check, already done at loading
7496 //AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(itr->first);
7497 //if (atEntry)
7498 return &itr->second;
7499 }
7500 }
7501 return nullptr;
7502}

References _areaTriggerTeleportStore.

◆ GetMapObjectGuids()

CellObjectGuidsMap const & ObjectMgr::GetMapObjectGuids ( uint16  mapid,
uint8  spawnMode 
)
inline
1186 {
1187 MapObjectGuids::const_iterator itr1 = _mapObjectGuidsStore.find(MAKE_PAIR32(mapid, spawnMode));
1188 if (itr1 != _mapObjectGuidsStore.end())
1189 return itr1->second;
1191 }
CellObjectGuidsMap _emptyCellObjectGuidsMap
Definition ObjectMgr.h:1616

References _emptyCellObjectGuidsMap, _mapObjectGuidsStore, and MAKE_PAIR32().

◆ GetModelForShapeshift()

uint32 ObjectMgr::GetModelForShapeshift ( ShapeshiftForm  form,
Player player 
) const
1881{
1882 uint8 customizationID;
1883
1884 if (player->GetTeamId() == TEAM_ALLIANCE)
1885 customizationID = player->GetByteValue(PLAYER_BYTES, 3); // Use Hair Color
1886 else
1887 customizationID = player->GetByteValue(PLAYER_BYTES, 0); // Use Skin Color
1888
1889 auto itr = _playerShapeshiftModel.find(std::make_tuple(form, player->getRace(), customizationID, player->getGender()));
1890 if (itr != _playerShapeshiftModel.end())
1891 return itr->second; // Explicit combination
1892
1893 itr = _playerShapeshiftModel.find(std::make_tuple(form, player->getRace(), customizationID, GENDER_NONE));
1894 if (itr != _playerShapeshiftModel.end())
1895 return itr->second; // Combination applied to both genders
1896
1897 itr = _playerShapeshiftModel.find(std::make_tuple(form, player->getRace(), 255, player->getGender()));
1898 if (itr != _playerShapeshiftModel.end())
1899 return itr->second; // Default gender-dependent model
1900
1901 itr = _playerShapeshiftModel.find(std::make_tuple(form, player->getRace(), 255, GENDER_NONE));
1902 if (itr != _playerShapeshiftModel.end())
1903 return itr->second; // Last resort
1904
1905 LOG_DEBUG("entities.player", "ShapeshiftForm {} with RaceID ({}) have no shapeshift model data defined, using fallback data.", form, player->getRace());
1906 return 0;
1907}
@ GENDER_NONE
Definition SharedDefines.h:63
@ TEAM_ALLIANCE
Definition SharedDefines.h:771
@ PLAYER_BYTES
Definition UpdateFields.h:181
PlayerShapeshiftModelMap _playerShapeshiftModel
Definition ObjectMgr.h:1673
uint8 GetByteValue(uint16 index, uint8 offset) const
Definition Object.cpp:312
TeamId GetTeamId(bool original=false) const
Definition Player.h:2101
uint8 getGender() const
Definition Unit.h:838
uint8 getRace(bool original=false) const
Definition Unit.cpp:21113

References _playerShapeshiftModel, GENDER_NONE, Object::GetByteValue(), Unit::getGender(), Unit::getRace(), Player::GetTeamId(), LOG_DEBUG, PLAYER_BYTES, and TEAM_ALLIANCE.

◆ GetModelForTotem()

uint32 ObjectMgr::GetModelForTotem ( SummonSlot  totemSlot,
Races  race 
) const
1826{
1827 auto itr = _playerTotemModel.find(std::make_pair(totemSlot, race));
1828 if (itr != _playerTotemModel.end())
1829 return itr->second;
1830
1831 LOG_ERROR("misc", "TotemSlot {} with RaceID ({}) have no totem model data defined, set to default model.", totemSlot, race);
1832 return 0;
1833}
PlayerTotemModelMap _playerTotemModel
Definition ObjectMgr.h:1671

References _playerTotemModel, and LOG_ERROR.

◆ GetModuleString() [1/2]

ModuleString const * ObjectMgr::GetModuleString ( std::string  module,
uint32  id 
) const
inline
1347 {
1348 std::pair<std::string, uint32> pairKey = std::make_pair(module, id);
1349 ModuleStringContainer::const_iterator itr = _moduleStringStore.find(pairKey);
1350 if (itr == _moduleStringStore.end())
1351 return nullptr;
1352
1353 return &itr->second;
1354 }
ModuleStringContainer _moduleStringStore
Definition ObjectMgr.h:1649

References _moduleStringStore.

Referenced by GetModuleString().

◆ GetModuleString() [2/2]

std::string const * ObjectMgr::GetModuleString ( std::string  module,
uint32  id,
LocaleConstant  locale 
) const
9222{
9223 ModuleString const* ms = GetModuleString(module, id);
9224 if (ms && !ms->Content.empty())
9225 {
9226 if (ms->Content.size() > size_t(locale) && !ms->Content[locale].empty())
9227 return &ms->Content[locale];
9228
9229 return &ms->Content[DEFAULT_LOCALE];
9230 }
9231
9232 LOG_ERROR("sql.sql", "Module string module {} id {} not found in DB.", module, id);
9233
9234 return (std::string*)"error";
9235}
ModuleString const * GetModuleString(std::string module, uint32 id) const
Definition ObjectMgr.h:1346
Definition ObjectMgr.h:497
std::vector< std::string > Content
Definition ObjectMgr.h:498

References ModuleString::Content, DEFAULT_LOCALE, GetModuleString(), and LOG_ERROR.

◆ GetNearestTaxiNode()

uint32 ObjectMgr::GetNearestTaxiNode ( float  x,
float  y,
float  z,
uint32  mapid,
uint32  teamId 
)
7074{
7075 bool found = false;
7076 float dist = 10000;
7077 uint32 id = 0;
7078
7079 for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
7080 {
7081 TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i);
7082
7083 if (!node || node->map_id != mapid || (!node->MountCreatureID[teamId == TEAM_ALLIANCE ? 1 : 0] && node->MountCreatureID[0] != 32981)) // dk flight
7084 continue;
7085
7086 uint8 field = (uint8)((i - 1) / 32);
7087 uint32 submask = 1 << ((i - 1) % 32);
7088
7089 // skip not taxi network nodes
7090 if (field >= TaxiMaskSize || (sTaxiNodesMask[field] & submask) == 0)
7091 {
7092 continue;
7093 }
7094
7095 float dist2 = (node->x - x) * (node->x - x) + (node->y - y) * (node->y - y) + (node->z - z) * (node->z - z);
7096 if (found)
7097 {
7098 if (dist2 < dist)
7099 {
7100 dist = dist2;
7101 id = i;
7102 }
7103 }
7104 else
7105 {
7106 found = true;
7107 dist = dist2;
7108 id = i;
7109 }
7110 }
7111
7112 return id;
7113}
TaxiMask sTaxiNodesMask
Definition DBCStores.cpp:176
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
static constexpr std::size_t TaxiMaskSize
Definition DBCStructure.h:2248
Definition DBCStructure.h:1953
float z
Definition DBCStructure.h:1958
uint32 map_id
Definition DBCStructure.h:1955
float x
Definition DBCStructure.h:1956
float y
Definition DBCStructure.h:1957
uint32 MountCreatureID[2]
Definition DBCStructure.h:1961

References TaxiNodesEntry::map_id, TaxiNodesEntry::MountCreatureID, sTaxiNodesMask, sTaxiNodesStore, TaxiMaskSize, TEAM_ALLIANCE, TaxiNodesEntry::x, TaxiNodesEntry::y, and TaxiNodesEntry::z.

◆ GetNpcTextLocale()

NpcTextLocale const * ObjectMgr::GetNpcTextLocale ( uint32  entry) const
inline
1321 {
1322 NpcTextLocaleContainer::const_iterator itr = _npcTextLocaleStore.find(entry);
1323 if (itr == _npcTextLocaleStore.end()) return nullptr;
1324 return &itr->second;
1325 }
NpcTextLocaleContainer _npcTextLocaleStore
Definition ObjectMgr.h:1647

References _npcTextLocaleStore.

◆ GetNpcVendorItemList()

VendorItemData const * ObjectMgr::GetNpcVendorItemList ( uint32  entry) const
inline
1412 {
1413 CacheVendorItemContainer::const_iterator iter = _cacheVendorItemStore.find(entry);
1414 if (iter == _cacheVendorItemStore.end())
1415 return nullptr;
1416
1417 return &iter->second;
1418 }

References _cacheVendorItemStore.

Referenced by IsVendorItemValid().

◆ GetPageText()

PageText const * ObjectMgr::GetPageText ( uint32  pageEntry)
6326{
6327 PageTextContainer::const_iterator itr = _pageTextStore.find(pageEntry);
6328 if (itr != _pageTextStore.end())
6329 return &(itr->second);
6330
6331 return nullptr;
6332}
PageTextContainer _pageTextStore
Definition ObjectMgr.h:1572

References _pageTextStore.

Referenced by LoadGameObjectTemplate(), and LoadItemTemplates().

◆ GetPageTextLocale()

PageTextLocale const * ObjectMgr::GetPageTextLocale ( uint32  entry) const
inline
1285 {
1286 PageTextLocaleContainer::const_iterator itr = _pageTextLocaleStore.find(entry);
1287 if (itr == _pageTextLocaleStore.end()) return nullptr;
1288 return &itr->second;
1289 }
PageTextLocaleContainer _pageTextLocaleStore
Definition ObjectMgr.h:1648

References _pageTextLocaleStore.

◆ GetPetLevelInfo()

PetLevelInfo const * ObjectMgr::GetPetLevelInfo ( uint32  creature_id,
uint8  level 
) const
4125{
4126 if (level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4127 level = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
4128
4129 PetLevelInfoContainer::const_iterator itr = _petInfoStore.find(creature_id);
4130 if (itr == _petInfoStore.end())
4131 return nullptr;
4132
4133 return &itr->second[level - 1]; // data for level 1 stored in [0] array element, ...
4134}

References _petInfoStore, CONFIG_MAX_PLAYER_LEVEL, and sWorld.

◆ GetPlayerClassInfo()

PlayerClassInfo const * ObjectMgr::GetPlayerClassInfo ( uint32  class_) const
inline
801 {
802 if (class_ >= MAX_CLASSES)
803 return nullptr;
804 return _playerClassInfo[class_];
805 }

References _playerClassInfo, and MAX_CLASSES.

◆ GetPlayerClassLevelInfo()

void ObjectMgr::GetPlayerClassLevelInfo ( uint32  class_,
uint8  level,
PlayerClassLevelInfo info 
) const
4792{
4793 if (level < 1 || class_ >= MAX_CLASSES)
4794 return;
4795
4796 PlayerClassInfo const* pInfo = _playerClassInfo[class_];
4797
4798 if (level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4799 level = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
4800
4801 *info = pInfo->levelInfo[level - 1];
4802}
Definition Player.h:284

References _playerClassInfo, CONFIG_MAX_PLAYER_LEVEL, PlayerClassInfo::levelInfo, MAX_CLASSES, and sWorld.

◆ GetPlayerInfo()

PlayerInfo const * ObjectMgr::GetPlayerInfo ( uint32  race,
uint32  class_ 
) const
10695{
10696 if (race >= MAX_RACES)
10697 return nullptr;
10698 if (class_ >= MAX_CLASSES)
10699 return nullptr;
10700 PlayerInfo const* info = _playerInfo[race][class_];
10701 if (!info)
10702 return nullptr;
10703 return info;
10704}
Definition Player.h:323

References _playerInfo, MAX_CLASSES, and MAX_RACES.

◆ GetPlayerLevelInfo()

void ObjectMgr::GetPlayerLevelInfo ( uint32  race,
uint32  class_,
uint8  level,
PlayerLevelInfo info 
) const
4805{
4806 if (level < 1 || race >= MAX_RACES || class_ >= MAX_CLASSES)
4807 return;
4808
4809 PlayerInfo const* pInfo = _playerInfo[race][class_];
4810 if (!pInfo)
4811 return;
4812
4813 if (level <= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4814 *info = pInfo->levelInfo[level - 1];
4815 else
4816 BuildPlayerLevelInfo(race, class_, level, info);
4817}
void BuildPlayerLevelInfo(uint8 race, uint8 class_, uint8 level, PlayerLevelInfo *plinfo) const
Definition ObjectMgr.cpp:4819

References _playerInfo, BuildPlayerLevelInfo(), CONFIG_MAX_PLAYER_LEVEL, PlayerInfo::levelInfo, MAX_CLASSES, and MAX_RACES.

◆ GetPointOfInterest()

PointOfInterest const * ObjectMgr::GetPointOfInterest ( uint32  id) const
inline
929 {
930 PointOfInterestContainer::const_iterator itr = _pointsOfInterestStore.find(id);
931 if (itr != _pointsOfInterestStore.end())
932 return &itr->second;
933 return nullptr;
934 }
PointOfInterestContainer _pointsOfInterestStore
Definition ObjectMgr.h:1541

References _pointsOfInterestStore.

Referenced by LoadGossipMenuItems().

◆ GetPointOfInterestLocale()

PointOfInterestLocale const * ObjectMgr::GetPointOfInterestLocale ( uint32  poi_id) const
inline
1303 {
1304 PointOfInterestLocaleContainer::const_iterator itr = _pointOfInterestLocaleStore.find(poi_id);
1305 if (itr == _pointOfInterestLocaleStore.end()) return nullptr;
1306 return &itr->second;
1307 }
PointOfInterestLocaleContainer _pointOfInterestLocaleStore
Definition ObjectMgr.h:1652

References _pointOfInterestLocaleStore.

◆ GetQuestForAreaTrigger()

uint32 ObjectMgr::GetQuestForAreaTrigger ( uint32  Trigger_ID) const
inline
842 {
843 QuestAreaTriggerContainer::const_iterator itr = _questAreaTriggerStore.find(Trigger_ID);
844 if (itr != _questAreaTriggerStore.end())
845 return itr->second;
846 return 0;
847 }
QuestAreaTriggerContainer _questAreaTriggerStore
Definition ObjectMgr.h:1525

References _questAreaTriggerStore.

◆ GetQuestGreeting()

QuestGreeting const * ObjectMgr::GetQuestGreeting ( TypeID  type,
uint32  id 
) const
6804{
6805 uint8 typeIndex;
6806 if (type == TYPEID_UNIT)
6807 typeIndex = 0;
6808 else if (type == TYPEID_GAMEOBJECT)
6809 typeIndex = 1;
6810 else
6811 return nullptr;
6812
6813 std::pair<uint32, uint8> pairKey = std::make_pair(id, typeIndex);
6814 QuestGreetingContainer::const_iterator itr = _questGreetingStore.find(pairKey);
6815 if (itr == _questGreetingStore.end())
6816 return nullptr;
6817
6818 return &itr->second;
6819}
@ TYPEID_GAMEOBJECT
Definition ObjectGuid.h:37
@ TYPEID_UNIT
Definition ObjectGuid.h:35
QuestGreetingContainer _questGreetingStore
Definition ObjectMgr.h:1528

References _questGreetingStore, TYPEID_GAMEOBJECT, and TYPEID_UNIT.

◆ GetQuestLocale()

QuestLocale const * ObjectMgr::GetQuestLocale ( uint32  entry) const
inline
1291 {
1292 QuestLocaleContainer::const_iterator itr = _questLocaleStore.find(entry);
1293 if (itr == _questLocaleStore.end()) return nullptr;
1294 return &itr->second;
1295 }
QuestLocaleContainer _questLocaleStore
Definition ObjectMgr.h:1644

References _questLocaleStore.

◆ GetQuestMoneyReward()

uint32 ObjectMgr::GetQuestMoneyReward ( uint8  level,
uint32  questMoneyDifficulty 
) const
10831{
10832 if (questMoneyDifficulty < MAX_QUEST_MONEY_REWARDS)
10833 {
10834 auto const& itr = _questMoneyRewards.find(level);
10835 if (itr != _questMoneyRewards.end())
10836 {
10837 return itr->second.at(questMoneyDifficulty);
10838 }
10839 }
10840
10841 return 0;
10842}
static constexpr uint32 MAX_QUEST_MONEY_REWARDS
Definition ObjectMgr.h:718
QuestMoneyRewardStore _questMoneyRewards
Definition ObjectMgr.h:1675

References _questMoneyRewards, and MAX_QUEST_MONEY_REWARDS.

◆ GetQuestOfferRewardLocale()

QuestOfferRewardLocale const * ObjectMgr::GetQuestOfferRewardLocale ( uint32  entry) const
inline
1309 {
1310 auto itr = _questOfferRewardLocaleStore.find(entry);
1311 if (itr == _questOfferRewardLocaleStore.end()) return nullptr;
1312 return &itr->second;
1313 }
QuestOfferRewardLocaleContainer _questOfferRewardLocaleStore
Definition ObjectMgr.h:1645

References _questOfferRewardLocaleStore.

◆ GetQuestPOIVector()

QuestPOIVector const * ObjectMgr::GetQuestPOIVector ( uint32  questId)
inline
937 {
938 QuestPOIContainer::const_iterator itr = _questPOIStore.find(questId);
939 if (itr != _questPOIStore.end())
940 return &itr->second;
941 return nullptr;
942 }
QuestPOIContainer _questPOIStore
Definition ObjectMgr.h:1543

References _questPOIStore.

◆ GetQuestRequestItemsLocale()

QuestRequestItemsLocale const * ObjectMgr::GetQuestRequestItemsLocale ( uint32  entry) const
inline
1315 {
1316 auto itr = _questRequestItemsLocaleStore.find(entry);
1317 if (itr == _questRequestItemsLocaleStore.end()) return nullptr;
1318 return &itr->second;
1319 }
QuestRequestItemsLocaleContainer _questRequestItemsLocaleStore
Definition ObjectMgr.h:1646

References _questRequestItemsLocaleStore.

◆ GetQuestTemplate()

Quest const * ObjectMgr::GetQuestTemplate ( uint32  quest_id) const
inline
835 {
836 return quest_id < _questTemplatesFast.size() ? _questTemplatesFast[quest_id] : nullptr;
837 }
std::vector< Quest * > _questTemplatesFast
Definition ObjectMgr.h:1519

References _questTemplatesFast.

Referenced by LoadAccessRequirements(), LoadFactionChangeQuests(), LoadQuestAreaTriggers(), LoadQuests(), and LoadScripts().

◆ GetQuestTemplates()

QuestMap const & ObjectMgr::GetQuestTemplates ( ) const
inline
839{ return _questTemplates; }

References _questTemplates.

◆ GetRepRewardRate()

RepRewardRate const * ObjectMgr::GetRepRewardRate ( uint32  factionId) const
inline
901 {
902 RepRewardRateContainer::const_iterator itr = _repRewardRateStore.find(factionId);
903 if (itr != _repRewardRateStore.end())
904 return &itr->second;
905
906 return nullptr;
907 }
RepRewardRateContainer _repRewardRateStore
Definition ObjectMgr.h:1535

References _repRewardRateStore.

◆ GetRepSpilloverTemplate()

RepSpilloverTemplate const * ObjectMgr::GetRepSpilloverTemplate ( uint32  factionId) const
inline
920 {
921 RepSpilloverTemplateContainer::const_iterator itr = _repSpilloverTemplateStore.find(factionId);
922 if (itr != _repSpilloverTemplateStore.end())
923 return &itr->second;
924
925 return nullptr;
926 }
RepSpilloverTemplateContainer _repSpilloverTemplateStore
Definition ObjectMgr.h:1537

References _repSpilloverTemplateStore.

◆ GetReputationOnKilEntry()

ReputationOnKillEntry const * ObjectMgr::GetReputationOnKilEntry ( uint32  id) const
inline
910 {
911 RepOnKillContainer::const_iterator itr = _repOnKillStore.find(id);
912 if (itr != _repOnKillStore.end())
913 return &itr->second;
914 return nullptr;
915 }
RepOnKillContainer _repOnKillStore
Definition ObjectMgr.h:1536

References _repOnKillStore.

◆ GetScriptId()

uint32 ObjectMgr::GetScriptId ( std::string const &  name)
10185{
10186 // use binary search to find the script name in the sorted vector
10187 // assume "" is the first element
10188 if (name.empty())
10189 return 0;
10190
10191 ScriptNameContainer::const_iterator itr = std::lower_bound(_scriptNamesStore.begin(), _scriptNamesStore.end(), name);
10192 if (itr == _scriptNamesStore.end() || (*itr != name))
10193 return 0;
10194
10195 return uint32(itr - _scriptNamesStore.begin());
10196}
ScriptNameContainer _scriptNamesStore
Definition ObjectMgr.h:1560

References _scriptNamesStore.

Referenced by LoadAreaTriggerScripts(), LoadCreatureDataFromDB(), LoadCreatures(), LoadCreatureTemplate(), LoadGameObjectDataFromDB(), LoadGameobjects(), LoadGameObjectTemplate(), LoadInstanceTemplate(), LoadItemTemplates(), and LoadSpellScriptNames().

◆ GetScriptName()

std::string const & ObjectMgr::GetScriptName ( uint32  id) const
10179{
10180 static std::string const empty = "";
10181 return (id < _scriptNamesStore.size()) ? _scriptNamesStore[id] : empty;
10182}

References _scriptNamesStore.

Referenced by ValidateSpellScripts().

◆ GetScriptNames()

ScriptNameContainer & ObjectMgr::GetScriptNames ( )
inline
1425{ return _scriptNamesStore; }

References _scriptNamesStore.

◆ GetSparringData()

CreatureSparringContainer const & ObjectMgr::GetSparringData ( ) const
inline
1226{ return _creatureSparringStore; }
CreatureSparringContainer _creatureSparringStore
Definition ObjectMgr.h:1575

References _creatureSparringStore.

◆ GetSpellClickInfoMapBounds()

SpellClickInfoMapBounds ObjectMgr::GetSpellClickInfoMapBounds ( uint32  creature_id) const
inline
1430 {
1431 return _spellClickInfoStore.equal_range(creature_id);
1432 }
SpellClickInfoContainer _spellClickInfoStore
Definition ObjectMgr.h:1562

References _spellClickInfoStore.

◆ GetSpellScriptsBounds()

SpellScriptsBounds ObjectMgr::GetSpellScriptsBounds ( uint32  spell_id)
9372{
9373 return SpellScriptsBounds(_spellScriptsStore.lower_bound(spell_id), _spellScriptsStore.upper_bound(spell_id));
9374}
std::pair< SpellScriptsContainer::iterator, SpellScriptsContainer::iterator > SpellScriptsBounds
Definition ObjectMgr.h:389
SpellScriptsContainer _spellScriptsStore
Definition ObjectMgr.h:1564

References _spellScriptsStore.

◆ GetSummonGroup()

std::vector< TempSummonData > const * ObjectMgr::GetSummonGroup ( uint32  summonerId,
SummonerType  summonerType,
uint8  group 
) const
inline

Gets temp summon data for all creatures of specified group.

Parameters
summonerIdSummoner's entry.
summonerTypeSummoner's type, see SummonerType for available types.
groupId of required group.
Returns
null if group was not found, otherwise reference to the creature group data
1203 {
1204 TempSummonDataContainer::const_iterator itr = _tempSummonDataStore.find(TempSummonGroupKey(summonerId, summonerType, group));
1205 if (itr != _tempSummonDataStore.end())
1206 return &itr->second;
1207
1208 return nullptr;
1209 }
TempSummonDataContainer _tempSummonDataStore
Stores temp summon data grouped by summoner's entry, summoner's type and group id.
Definition ObjectMgr.h:1637
Key for storing temp summon data in TempSummonDataContainer.
Definition ObjectMgr.h:65

References _tempSummonDataStore.

◆ GetTaxiMountDisplayId()

uint32 ObjectMgr::GetTaxiMountDisplayId ( uint32  id,
TeamId  teamId,
bool  allowed_alt_team = false 
)
7140{
7141 CreatureModel mountModel;
7142 CreatureTemplate const* mount_info = nullptr;
7143
7144 // select mount creature id
7145 TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id);
7146 if (node)
7147 {
7148 uint32 mount_entry = node->MountCreatureID[teamId == TEAM_ALLIANCE ? 1 : 0];
7149
7150 // Fix for Alliance not being able to use Acherus taxi
7151 // only one mount type for both sides
7152 if (mount_entry == 0 && allowed_alt_team)
7153 {
7154 // Simply reverse the selection. At least one team in theory should have a valid mount ID to choose.
7155 mount_entry = node->MountCreatureID[teamId];
7156 }
7157
7158 mount_info = GetCreatureTemplate(mount_entry);
7159 if (mount_info)
7160 {
7161 CreatureModel const* model = mount_info->GetRandomValidModel();
7162 if (!model)
7163 {
7164 LOG_ERROR("sql.sql", "No displayid found for the taxi mount with the entry {}! Can't load it!", mount_entry);
7165 return 0;
7166 }
7167 mountModel = *model;
7168 }
7169 }
7170
7171 // minfo is not actually used but the mount_id was updated
7172 GetCreatureModelRandomGender(&mountModel, mount_info);
7173
7174 return mountModel.CreatureDisplayID;
7175}
CreatureModelInfo const * GetCreatureModelRandomGender(CreatureModel *model, CreatureTemplate const *creatureTemplate) const
Definition ObjectMgr.cpp:1669
CreatureModel const * GetRandomValidModel() const
Definition Creature.cpp:119

References CreatureModel::CreatureDisplayID, GetCreatureModelRandomGender(), GetCreatureTemplate(), CreatureTemplate::GetRandomValidModel(), LOG_ERROR, TaxiNodesEntry::MountCreatureID, sTaxiNodesStore, and TEAM_ALLIANCE.

◆ GetTaxiPath()

void ObjectMgr::GetTaxiPath ( uint32  source,
uint32  destination,
uint32 path,
uint32 cost 
)
7116{
7117 TaxiPathSetBySource::iterator src_i = sTaxiPathSetBySource.find(source);
7118 if (src_i == sTaxiPathSetBySource.end())
7119 {
7120 path = 0;
7121 cost = 0;
7122 return;
7123 }
7124
7125 TaxiPathSetForSource& pathSet = src_i->second;
7126
7127 TaxiPathSetForSource::iterator dest_i = pathSet.find(destination);
7128 if (dest_i == pathSet.end())
7129 {
7130 path = 0;
7131 cost = 0;
7132 return;
7133 }
7134
7135 cost = dest_i->second->price;
7136 path = dest_i->second->ID;
7137}
TaxiPathSetBySource sTaxiPathSetBySource
Definition DBCStores.cpp:183
std::map< uint32, TaxiPathEntry const * > TaxiPathSetForSource
Definition DBCStructure.h:2242

References TaxiNodesEntry::ID, and sTaxiPathSetBySource.

◆ GetTrainer()

Trainer::Trainer * ObjectMgr::GetTrainer ( uint32  creatureId)
9772{
9773 auto itr = _creatureDefaultTrainers.find(creatureId);
9774 if (itr != _creatureDefaultTrainers.end())
9775 return Acore::Containers::MapGetValuePtr(_trainers, itr->second);
9776
9777 return nullptr;
9778}
std::unordered_map< uint32, uint32 > _creatureDefaultTrainers
Definition ObjectMgr.h:1656
std::unordered_map< uint32, Trainer::Trainer > _trainers
Definition ObjectMgr.h:1655

References _creatureDefaultTrainers, _trainers, and Acore::Containers::MapGetValuePtr().

◆ GetVehicleAccessoryList()

VehicleAccessoryList const * ObjectMgr::GetVehicleAccessoryList ( Vehicle veh) const
10678{
10679 if (Creature* cre = veh->GetBase()->ToCreature())
10680 {
10681 // Give preference to GUID-based accessories
10682 VehicleAccessoryContainer::const_iterator itr = _vehicleAccessoryStore.find(cre->GetSpawnId());
10683 if (itr != _vehicleAccessoryStore.end())
10684 return &itr->second;
10685 }
10686
10687 // Otherwise return entry-based
10688 VehicleAccessoryContainer::const_iterator itr = _vehicleTemplateAccessoryStore.find(veh->GetCreatureEntry());
10689 if (itr != _vehicleTemplateAccessoryStore.end())
10690 return &itr->second;
10691 return nullptr;
10692}
VehicleAccessoryContainer _vehicleAccessoryStore
Definition ObjectMgr.h:1567
VehicleAccessoryContainer _vehicleTemplateAccessoryStore
Definition ObjectMgr.h:1566
Creature * ToCreature()
Definition Object.h:205
Unit * GetBase() const
May be called from scripts.
Definition Vehicle.h:37
uint32 GetCreatureEntry() const
Definition Vehicle.h:39

References _vehicleAccessoryStore, _vehicleTemplateAccessoryStore, Vehicle::GetBase(), Vehicle::GetCreatureEntry(), and Object::ToCreature().

◆ GetVehicleSeatAddon()

VehicleSeatAddon const * ObjectMgr::GetVehicleSeatAddon ( uint32  seatId) const
inline
1484 {
1485 VehicleSeatAddonContainer::const_iterator itr = _vehicleSeatAddonStore.find(seatId);
1486 if (itr == _vehicleSeatAddonStore.end())
1487 return nullptr;
1488
1489 return &itr->second;
1490 }
VehicleSeatAddonContainer _vehicleSeatAddonStore
Definition ObjectMgr.h:1568

References _vehicleSeatAddonStore.

◆ GetXPForLevel()

uint32 ObjectMgr::GetXPForLevel ( uint8  level) const
7998{
7999 if (level < _playerXPperLevel.size())
8000 return _playerXPperLevel[level];
8001 return 0;
8002}
PlayerXPperLevel _playerXPperLevel
Definition ObjectMgr.h:1597

References _playerXPperLevel.

◆ InitializeSpellInfoPrecomputedData()

void ObjectMgr::InitializeSpellInfoPrecomputedData ( )
6273{
6274 uint32 limit = sSpellStore.GetNumRows();
6275 for(uint32 i = 0; i <= limit; ++i)
6276 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(i))
6277 {
6278 const_cast<SpellInfo*>(spellInfo)->SetStackableWithRanks(spellInfo->ComputeIsStackableWithRanks());
6279 const_cast<SpellInfo*>(spellInfo)->SetCritCapable(spellInfo->ComputeIsCritCapable());
6280 const_cast<SpellInfo*>(spellInfo)->SetSpellValid(SpellMgr::ComputeIsSpellValid(spellInfo, false));
6281 }
6282}
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
Definition SpellInfo.h:316
static bool ComputeIsSpellValid(SpellInfo const *spellInfo, bool msg=true)
Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book,...
Definition SpellMgr.cpp:367

References SpellMgr::ComputeIsSpellValid(), sSpellMgr, and sSpellStore.

◆ instance()

ObjectMgr * ObjectMgr::instance ( )
static
375{
376 static ObjectMgr instance;
377 return &instance;
378}
Definition ObjectMgr.h:725
static ObjectMgr * instance()
Definition ObjectMgr.cpp:374

References instance().

Referenced by instance().

◆ IsGameObjectStaticTransport()

bool ObjectMgr::IsGameObjectStaticTransport ( uint32  entry)
10658{
10659 GameObjectTemplate const* goinfo = GetGameObjectTemplate(entry);
10660 return goinfo && goinfo->type == GAMEOBJECT_TYPE_TRANSPORT;
10661}
@ GAMEOBJECT_TYPE_TRANSPORT
Definition SharedDefines.h:1582

References GAMEOBJECT_TYPE_TRANSPORT, GetGameObjectTemplate(), and GameObjectTemplate::type.

Referenced by AddGOData().

◆ IsProfanityName()

bool ObjectMgr::IsProfanityName ( std::string_view  name) const
8858{
8859 // pussywizard
8860 if (name.size() >= 2 && (name[name.size() - 2] == 'G' || name[name.size() - 2] == 'g') && (name[name.size() - 1] == 'M' || name[name.size() - 1] == 'm'))
8861 return true;
8862
8863 std::wstring wstr;
8864 if (!Utf8toWStr (name, wstr))
8865 return false;
8866
8867 wstrToLower(wstr);
8868
8869 return _profanityNamesStore.find(wstr) != _profanityNamesStore.end();
8870}

References _profanityNamesStore, Utf8toWStr(), and wstrToLower().

Referenced by AddProfanityPlayerName().

◆ IsReservedName()

bool ObjectMgr::IsReservedName ( std::string_view  name) const
8755{
8756 // pussywizard
8757 if (name.size() >= 2 && (name[name.size() - 2] == 'G' || name[name.size() - 2] == 'g') && (name[name.size() - 1] == 'M' || name[name.size() - 1] == 'm'))
8758 return true;
8759
8760 std::wstring wstr;
8761 if (!Utf8toWStr (name, wstr))
8762 return false;
8763
8764 wstrToLower(wstr);
8765
8766 return _reservedNamesStore.find(wstr) != _reservedNamesStore.end();
8767}

References _reservedNamesStore, Utf8toWStr(), and wstrToLower().

Referenced by AddReservedPlayerName().

◆ IsTavernAreaTrigger()

bool ObjectMgr::IsTavernAreaTrigger ( uint32  triggerID,
uint32  faction 
) const
inline
850 {
851 auto itr = _tavernAreaTriggerStore.find(triggerID);
852 if (itr != _tavernAreaTriggerStore.end())
853 {
854 return (itr->second & faction) != 0;
855 }
856
857 return false;
858 }
TavernAreaTriggerContainer _tavernAreaTriggerStore
Definition ObjectMgr.h:1526

References _tavernAreaTriggerStore.

◆ IsTransportMap()

bool ObjectMgr::IsTransportMap ( uint32  mapId) const
inline
1481{ return _transportMaps.count(mapId) != 0; }
std::set< uint32 > _transportMaps
Definition ObjectMgr.h:1669

References _transportMaps.

◆ IsValidChannelName()

bool ObjectMgr::IsValidChannelName ( std::string const &  name)
static
9031{
9032 std::wstring wname;
9033 if (!Utf8toWStr(name, wname))
9034 return false;
9035
9036 if (wname.size() > MAX_CHANNEL_NAME)
9037 return false;
9038
9039 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_CHANNEL_NAMES);
9040
9041 return isValidString(wname, strictMask, true);
9042}
#define MAX_CHANNEL_NAME
Definition ObjectMgr.h:686
@ CONFIG_STRICT_CHANNEL_NAMES
Definition WorldConfig.h:176

References CONFIG_STRICT_CHANNEL_NAMES, isValidString(), MAX_CHANNEL_NAME, sWorld, and Utf8toWStr().

◆ IsValidCharterName()

bool ObjectMgr::IsValidCharterName ( std::string_view  name)
static
9005{
9006 std::wstring wname;
9007 if (!Utf8toWStr(name, wname))
9008 return false;
9009
9010 if (wname.size() > MAX_CHARTER_NAME)
9011 return false;
9012
9013 uint32 minName = sWorld->getIntConfig(CONFIG_MIN_CHARTER_NAME);
9014 if (wname.size() < minName)
9015 return false;
9016
9017 // Check Reserved Name
9018 if (sObjectMgr->IsReservedName(name))
9019 return false;
9020
9021 // Check Profanity Name
9022 if (sObjectMgr->IsProfanityName(name))
9023 return false;
9024
9025 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_CHARTER_NAMES);
9026
9027 return isValidString(wname, strictMask, true);
9028}
#define MAX_CHARTER_NAME
Definition ObjectMgr.h:685
@ CONFIG_MIN_CHARTER_NAME
Definition WorldConfig.h:179
@ CONFIG_STRICT_CHARTER_NAMES
Definition WorldConfig.h:175

References CONFIG_MIN_CHARTER_NAME, CONFIG_STRICT_CHARTER_NAMES, isValidString(), MAX_CHARTER_NAME, sObjectMgr, sWorld, and Utf8toWStr().

Referenced by WorldSession::HandlePetitionBuyOpcode(), WorldSession::HandlePetitionRenameOpcode(), ArenaTeam::SetName(), and Guild::SetName().

◆ IsVendorItemValid()

bool ObjectMgr::IsVendorItemValid ( uint32  vendor_entry,
uint32  item,
int32  maxcount,
uint32  ptime,
uint32  ExtendedCost,
Player player = nullptr,
std::set< uint32 > *  skip_vendors = nullptr,
uint32  ORnpcflag = 0 
) const
10043{
10044 /*
10045 CreatureTemplate const* cInfo = GetCreatureTemplate(vendor_entry);
10046 if (!cInfo)
10047 {
10048 if (player)
10049 ChatHandler(player->GetSession()).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
10050 else
10051 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have data for not existed creature template (Entry: {}), ignore", vendor_entry);
10052 return false;
10053 }
10054
10055 if (!((cInfo->npcflag | ORnpcflag) & UNIT_NPC_FLAG_VENDOR))
10056 {
10057 if (!skip_vendors || skip_vendors->count(vendor_entry) == 0)
10058 {
10059 if (player)
10060 ChatHandler(player->GetSession()).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
10061 else
10062 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have data for not creature template (Entry: {}) without vendor flag, ignore", vendor_entry);
10063
10064 if (skip_vendors)
10065 skip_vendors->insert(vendor_entry);
10066 }
10067 return false;
10068 }
10069 */
10070
10071 if (!sObjectMgr->GetItemTemplate(item_id))
10072 {
10073 if (player)
10075 else
10076 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` for Vendor (Entry: {}) have in item list non-existed item ({}), ignore", vendor_entry, item_id);
10077 return false;
10078 }
10079
10080 if (ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost))
10081 {
10082 if (player)
10084 else
10085 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have Item (Entry: {}) with wrong ExtendedCost ({}) for vendor ({}), ignore", item_id, ExtendedCost, vendor_entry);
10086 return false;
10087 }
10088
10089 if (maxcount > 0 && incrtime == 0)
10090 {
10091 if (player)
10092 ChatHandler(player->GetSession()).PSendSysMessage("MaxCount != 0 ({}) but IncrTime == 0", maxcount);
10093 else
10094 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` has `maxcount` ({}) for item {} of vendor (Entry: {}) but `incrtime`=0, ignore", maxcount, item_id, vendor_entry);
10095 return false;
10096 }
10097 else if (maxcount == 0 && incrtime > 0)
10098 {
10099 if (player)
10100 ChatHandler(player->GetSession()).PSendSysMessage("MaxCount == 0 but IncrTime<>= 0");
10101 else
10102 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` has `maxcount`=0 for item {} of vendor (Entry: {}) but `incrtime`<>0, ignore", item_id, vendor_entry);
10103 return false;
10104 }
10105
10106 VendorItemData const* vItems = GetNpcVendorItemList(vendor_entry);
10107 if (!vItems)
10108 return true; // later checks for non-empty lists
10109
10110 if (vItems->FindItemCostPair(item_id, ExtendedCost))
10111 {
10112 if (player)
10113 ChatHandler(player->GetSession()).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, item_id, ExtendedCost);
10114 else
10115 LOG_ERROR("sql.sql", "Table `npc_vendor` has duplicate items {} (with extended cost {}) for vendor (Entry: {}), ignoring", item_id, ExtendedCost, vendor_entry);
10116 return false;
10117 }
10118
10119 return true;
10120}
DBCStorage< ItemExtendedCostEntry > sItemExtendedCostStore(ItemExtendedCostEntryfmt)
@ LANG_ITEM_ALREADY_IN_LIST
Definition Language.h:253
@ LANG_ITEM_NOT_FOUND
Definition Language.h:250
@ LANG_EXTENDED_COST_NOT_EXIST
Definition Language.h:378
Definition Chat.h:37
void PSendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:211
VendorItemData const * GetNpcVendorItemList(uint32 entry) const
Definition ObjectMgr.h:1411
WorldSession * GetSession() const
Definition Player.h:1993
VendorItem const * FindItemCostPair(uint32 item_id, uint32 extendedCost) const
Definition Creature.cpp:103

References VendorItemData::FindItemCostPair(), GetNpcVendorItemList(), Player::GetSession(), LANG_EXTENDED_COST_NOT_EXIST, LANG_ITEM_ALREADY_IN_LIST, LANG_ITEM_NOT_FOUND, LOG_ERROR, ChatHandler::PSendSysMessage(), sItemExtendedCostStore, and sObjectMgr.

Referenced by LoadReferenceVendor(), and LoadVendors().

◆ LoadAccessRequirements()

void ObjectMgr::LoadAccessRequirements ( )
7289{
7290 uint32 oldMSTime = getMSTime();
7291
7292 if (!_accessRequirementStore.empty())
7293 {
7294 for (DungeonProgressionRequirementsContainer::iterator itr = _accessRequirementStore.begin(); itr != _accessRequirementStore.end(); ++itr)
7295 {
7296 std::unordered_map<uint8, DungeonProgressionRequirements*> difficulties = itr->second;
7297 for (auto difficultiesItr = difficulties.begin(); difficultiesItr != difficulties.end(); ++difficultiesItr)
7298 {
7299 for (auto questItr = difficultiesItr->second->quests.begin(); questItr != difficultiesItr->second->quests.end(); ++questItr)
7300 {
7301 delete* questItr;
7302 }
7303
7304 for (auto achievementItr = difficultiesItr->second->achievements.begin(); achievementItr != difficultiesItr->second->achievements.end(); ++achievementItr)
7305 {
7306 delete* achievementItr;
7307 }
7308
7309 for (auto itemsItr = difficultiesItr->second->items.begin(); itemsItr != difficultiesItr->second->items.end(); ++itemsItr)
7310 {
7311 delete* itemsItr;
7312 }
7313
7314 delete difficultiesItr->second;
7315 }
7316 }
7317
7318 _accessRequirementStore.clear(); // need for reload case
7319 }
7320 // 0 1 2 3 4 5
7321 QueryResult access_template_result = WorldDatabase.Query("SELECT id, map_id, difficulty, min_level, max_level, min_avg_item_level FROM dungeon_access_template");
7322 if (!access_template_result)
7323 {
7324 LOG_WARN("server.loading", ">> Loaded 0 access requirement definitions. DB table `dungeon_access_template` is empty.");
7325 LOG_INFO("server.loading", " ");
7326 return;
7327 }
7328
7329 uint32 count = 0;
7330 uint32 countProgressionRequirements = 0;
7331
7332 do
7333 {
7334 Field* fields = access_template_result->Fetch();
7335
7336 //Get the common variables for the access requirements
7337 uint8 dungeon_access_id = fields[0].Get<uint8>();
7338 uint32 mapid = fields[1].Get<uint32>();
7339 uint8 difficulty = fields[2].Get<uint8>();
7340
7341 //Set up the access requirements
7343 ar->levelMin = fields[3].Get<uint8>();
7344 ar->levelMax = fields[4].Get<uint8>();
7345 ar->reqItemLevel = fields[5].Get<uint16>();
7346
7347 // 0 1 2 3 4 6
7348 QueryResult progression_requirements_results = WorldDatabase.Query("SELECT requirement_type, requirement_id, requirement_note, faction, priority, leader_only FROM dungeon_access_requirements where dungeon_access_id = {}", dungeon_access_id);
7349 if (progression_requirements_results)
7350 {
7351 do
7352 {
7353 Field* progression_requirement_row = progression_requirements_results->Fetch();
7354
7355 const uint8 requirement_type = progression_requirement_row[0].Get<uint8>();
7356 const uint32 requirement_id = progression_requirement_row[1].Get<uint32>();
7357 const std::string requirement_note = progression_requirement_row[2].Get<std::string>();
7358 const uint8 requirement_faction = progression_requirement_row[3].Get<uint8>();
7359 const uint8 requirement_priority = progression_requirement_row[4].IsNull() ? UINT8_MAX : progression_requirement_row[4].Get<uint8>();
7360 const bool requirement_checkLeaderOnly = progression_requirement_row[5].Get<bool>();
7361
7362 ProgressionRequirement* progression_requirement = new ProgressionRequirement();
7363 progression_requirement->id = requirement_id;
7364 progression_requirement->note = requirement_note;
7365 progression_requirement->faction = (TeamId)requirement_faction;
7366 progression_requirement->priority = requirement_priority;
7367 progression_requirement->checkLeaderOnly = requirement_checkLeaderOnly;
7368
7369 std::vector<ProgressionRequirement*>* currentRequirementsList = nullptr;
7370
7371 switch (requirement_type)
7372 {
7373 case 0:
7374 {
7375 //Achievement
7376 if (!sAchievementStore.LookupEntry(progression_requirement->id))
7377 {
7378 LOG_ERROR("sql.sql", "Required achievement {} for faction {} does not exist for map {} difficulty {}, remove or fix this achievement requirement.", progression_requirement->id, requirement_faction, mapid, difficulty);
7379 break;
7380 }
7381
7382 currentRequirementsList = &ar->achievements;
7383 break;
7384 }
7385 case 1:
7386 {
7387 //Quest
7388 if (!GetQuestTemplate(progression_requirement->id))
7389 {
7390 LOG_ERROR("sql.sql", "Required quest {} for faction {} does not exist for map {} difficulty {}, remove or fix this quest requirement.", progression_requirement->id, requirement_faction, mapid, difficulty);
7391 break;
7392 }
7393
7394 currentRequirementsList = &ar->quests;
7395 break;
7396 }
7397 case 2:
7398 {
7399 //Item
7400 ItemTemplate const* pProto = GetItemTemplate(progression_requirement->id);
7401 if (!pProto)
7402 {
7403 LOG_ERROR("sql.sql", "Required item {} for faction {} does not exist for map {} difficulty {}, remove or fix this item requirement.", progression_requirement->id, requirement_faction, mapid, difficulty);
7404 break;
7405 }
7406
7407 currentRequirementsList = &ar->items;
7408 break;
7409 }
7410 default:
7411 LOG_ERROR("sql.sql", "requirement_type of {} is not valid for map {} difficulty {}. Please use 0 for achievements, 1 for quest, 2 for items or remove this entry from the db.", requirement_type, mapid, difficulty);
7412 break;
7413 }
7414
7415 //Check if array is valid and delete the progression requirement
7416 if (!currentRequirementsList)
7417 {
7418 delete progression_requirement;
7419 continue;
7420 }
7421
7422 //Insert into the array
7423 if (currentRequirementsList->size() > requirement_priority)
7424 {
7425 currentRequirementsList->insert(currentRequirementsList->begin() + requirement_priority, progression_requirement);
7426 }
7427 else
7428 {
7429 currentRequirementsList->push_back(progression_requirement);
7430 }
7431
7432 } while (progression_requirements_results->NextRow());
7433 }
7434
7435 //Sort all arrays for priority
7436 auto sortFunction = [](const ProgressionRequirement* const a, const ProgressionRequirement* const b) {return a->priority > b->priority; };
7437 std::sort(ar->achievements.begin(), ar->achievements.end(), sortFunction);
7438 std::sort(ar->quests.begin(), ar->quests.end(), sortFunction);
7439 std::sort(ar->items.begin(), ar->items.end(), sortFunction);
7440
7441 countProgressionRequirements += ar->achievements.size();
7442 countProgressionRequirements += ar->quests.size();
7443 countProgressionRequirements += ar->items.size();
7444 count++;
7445
7446 _accessRequirementStore[mapid][difficulty] = ar;
7447 } while (access_template_result->NextRow());
7448
7449 LOG_INFO("server.loading", ">> Loaded {} Rows From dungeon_access_template And {} Rows From dungeon_access_requirements in {} ms", count, countProgressionRequirements, GetMSTimeDiffToNow(oldMSTime));
7450 LOG_INFO("server.loading", " ");
7451}
DBCStorage< AchievementEntry > sAchievementStore(Achievementfmt)
std::shared_ptr< ResultSet > QueryResult
Definition DatabaseEnvFwd.h:27
#define LOG_WARN(filterType__,...)
Definition Log.h:162
TeamId
Definition SharedDefines.h:770
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:131
uint32 getMSTime()
Definition Timer.h:103
Class used to access individual fields of database query result.
Definition Field.h:98
bool IsNull() const
Definition Field.h:106
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition Field.h:112
ItemTemplate const * GetItemTemplate(uint32 entry)
Definition ObjectMgr.cpp:3758
Quest const * GetQuestTemplate(uint32 quest_id) const
Definition ObjectMgr.h:834
Definition Player.h:929
Definition ItemTemplate.h:619
Definition Player.h:920
uint32 priority
Definition Player.h:924

References _accessRequirementStore, Field::Get(), GetItemTemplate(), getMSTime(), GetMSTimeDiffToNow(), GetQuestTemplate(), Field::IsNull(), LOG_ERROR, LOG_INFO, LOG_WARN, ProgressionRequirement::priority, sAchievementStore, and WorldDatabase.

◆ LoadAcoreStrings()

bool ObjectMgr::LoadAcoreStrings ( )
9238{
9239 uint32 oldMSTime = getMSTime();
9240
9241 _acoreStringStore.clear(); // for reload case
9242 QueryResult result = WorldDatabase.Query("SELECT entry, content_default, locale_koKR, locale_frFR, locale_deDE, locale_zhCN, locale_zhTW, locale_esES, locale_esMX, locale_ruRU FROM acore_string");
9243 if (!result)
9244 {
9245 LOG_WARN("server.loading", ">> Loaded 0 acore strings. DB table `acore_strings` is empty.");
9246 LOG_INFO("server.loading", " ");
9247 return false;
9248 }
9249
9250 do
9251 {
9252 Field* fields = result->Fetch();
9253
9254 uint32 entry = fields[0].Get<uint32>();
9255
9256 AcoreString& data = _acoreStringStore[entry];
9257
9258 data.Content.resize(DEFAULT_LOCALE + 1);
9259
9260 for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
9261 AddLocaleString(fields[i + 1].Get<std::string>(), LocaleConstant(i), data.Content);
9262 } while (result->NextRow());
9263
9264 LOG_INFO("server.loading", ">> Loaded {} Acore Strings in {} ms", (uint32)_acoreStringStore.size(), GetMSTimeDiffToNow(oldMSTime));
9265 LOG_INFO("server.loading", " ");
9266
9267 return true;
9268}
LocaleConstant
Definition Common.h:117
@ TOTAL_LOCALES
Definition Common.h:128
static void AddLocaleString(std::string &&s, LocaleConstant locale, std::vector< std::string > &data)
Definition ObjectMgr.cpp:380

References _acoreStringStore, AddLocaleString(), AcoreString::Content, DEFAULT_LOCALE, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_INFO, LOG_WARN, TOTAL_LOCALES, and WorldDatabase.

◆ LoadAreaTriggers()

void ObjectMgr::LoadAreaTriggers ( )
7178{
7179 uint32 oldMSTime = getMSTime();
7180
7181 _areaTriggerStore.clear();
7182
7183 QueryResult result = WorldDatabase.Query("SELECT entry, map, x, y, z, radius, length, width, height, orientation FROM areatrigger");
7184
7185 if (!result)
7186 {
7187 LOG_WARN("server.loading", ">> Loaded 0 area trigger definitions. DB table `areatrigger` is empty.");
7188 LOG_INFO("server.loading", " ");
7189 return;
7190 }
7191
7192 uint32 count = 0;
7193
7194 do
7195 {
7196 Field* fields = result->Fetch();
7197
7198 ++count;
7199
7200 AreaTrigger at;
7201
7202 at.entry = fields[0].Get<uint32>();
7203 at.map = fields[1].Get<uint32>();
7204 at.x = fields[2].Get<float>();
7205 at.y = fields[3].Get<float>();
7206 at.z = fields[4].Get<float>();
7207 at.radius = fields[5].Get<float>();
7208 at.length = fields[6].Get<float>();
7209 at.width = fields[7].Get<float>();
7210 at.height = fields[8].Get<float>();
7211 at.orientation = fields[9].Get<float>();
7212
7213 MapEntry const* mapEntry = sMapStore.LookupEntry(at.map);
7214 if (!mapEntry)
7215 {
7216 LOG_ERROR("sql.sql", "Area trigger (ID:{}) map (ID: {}) does not exist in `Map.dbc`.", at.entry, at.map);
7217 continue;
7218 }
7219
7220 _areaTriggerStore[at.entry] = at;
7221 } while (result->NextRow());
7222
7223 LOG_INFO("server.loading", ">> Loaded {} Area Trigger Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7224 LOG_INFO("server.loading", " ");
7225}
float height
Definition ObjectMgr.h:430
float x
Definition ObjectMgr.h:424
float y
Definition ObjectMgr.h:425
float orientation
Definition ObjectMgr.h:431
float length
Definition ObjectMgr.h:428
uint32 entry
Definition ObjectMgr.h:422
float radius
Definition ObjectMgr.h:427
float z
Definition ObjectMgr.h:426
float width
Definition ObjectMgr.h:429

References _areaTriggerStore, AreaTrigger::entry, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), AreaTrigger::height, AreaTrigger::length, LOG_ERROR, LOG_INFO, LOG_WARN, AreaTrigger::map, AreaTrigger::orientation, AreaTrigger::radius, sMapStore, AreaTrigger::width, WorldDatabase, AreaTrigger::x, AreaTrigger::y, and AreaTrigger::z.

◆ LoadAreaTriggerScripts()

void ObjectMgr::LoadAreaTriggerScripts ( )
7036{
7037 uint32 oldMSTime = getMSTime();
7038
7039 _areaTriggerScriptStore.clear(); // need for reload case
7040 QueryResult result = WorldDatabase.Query("SELECT entry, ScriptName FROM areatrigger_scripts");
7041
7042 if (!result)
7043 {
7044 LOG_WARN("server.loading", ">> Loaded 0 Areatrigger Scripts. DB Table `areatrigger_scripts` Is Empty.");
7045 LOG_INFO("server.loading", " ");
7046 return;
7047 }
7048
7049 uint32 count = 0;
7050
7051 do
7052 {
7053 ++count;
7054
7055 Field* fields = result->Fetch();
7056
7057 uint32 Trigger_ID = fields[0].Get<uint32>();
7058 std::string scriptName = fields[1].Get<std::string>();
7059
7060 AreaTrigger const* atEntry = GetAreaTrigger(Trigger_ID);
7061 if (!atEntry)
7062 {
7063 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
7064 continue;
7065 }
7066 _areaTriggerScriptStore[Trigger_ID] = GetScriptId(scriptName);
7067 } while (result->NextRow());
7068
7069 LOG_INFO("server.loading", ">> Loaded {} Areatrigger Scripts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7070 LOG_INFO("server.loading", " ");
7071}
uint32 GetScriptId(std::string const &name)
Definition ObjectMgr.cpp:10184

References _areaTriggerScriptStore, Field::Get(), GetAreaTrigger(), getMSTime(), GetMSTimeDiffToNow(), GetScriptId(), LOG_ERROR, LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadAreaTriggerTeleports()

void ObjectMgr::LoadAreaTriggerTeleports ( )
7228{
7229 uint32 oldMSTime = getMSTime();
7230
7231 _areaTriggerTeleportStore.clear(); // need for reload case
7232
7233 // 0 1 2 3 4 5
7234 QueryResult result = WorldDatabase.Query("SELECT ID, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM areatrigger_teleport");
7235
7236 if (!result)
7237 {
7238 LOG_WARN("server.loading", ">> Loaded 0 area trigger teleport definitions. DB table `areatrigger_teleport` is empty.");
7239 LOG_INFO("server.loading", " ");
7240 return;
7241 }
7242
7243 uint32 count = 0;
7244
7245 do
7246 {
7247 Field* fields = result->Fetch();
7248
7249 ++count;
7250
7251 uint32 Trigger_ID = fields[0].Get<uint32>();
7252
7254
7255 at.target_mapId = fields[1].Get<uint16>();
7256 at.target_X = fields[2].Get<float>();
7257 at.target_Y = fields[3].Get<float>();
7258 at.target_Z = fields[4].Get<float>();
7259 at.target_Orientation = fields[5].Get<float>();
7260
7261 AreaTrigger const* atEntry = GetAreaTrigger(Trigger_ID);
7262 if (!atEntry)
7263 {
7264 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
7265 continue;
7266 }
7267
7268 MapEntry const* mapEntry = sMapStore.LookupEntry(at.target_mapId);
7269 if (!mapEntry)
7270 {
7271 LOG_ERROR("sql.sql", "Area trigger (ID:{}) target map (ID: {}) does not exist in `Map.dbc`.", Trigger_ID, at.target_mapId);
7272 continue;
7273 }
7274
7275 if (at.target_X == 0 && at.target_Y == 0 && at.target_Z == 0)
7276 {
7277 LOG_ERROR("sql.sql", "Area trigger (ID:{}) target coordinates not provided.", Trigger_ID);
7278 continue;
7279 }
7280
7281 _areaTriggerTeleportStore[Trigger_ID] = at;
7282 } while (result->NextRow());
7283
7284 LOG_INFO("server.loading", ">> Loaded {} Area Trigger Teleport Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7285 LOG_INFO("server.loading", " ");
7286}
Definition ObjectMgr.h:412
uint32 target_mapId
Definition ObjectMgr.h:413

References _areaTriggerTeleportStore, Field::Get(), GetAreaTrigger(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, sMapStore, AreaTriggerTeleport::target_mapId, and WorldDatabase.

◆ LoadBroadcastTextLocales()

void ObjectMgr::LoadBroadcastTextLocales ( )
10284{
10285 uint32 oldMSTime = getMSTime();
10286
10287 // 0 1 2 3
10288 QueryResult result = WorldDatabase.Query("SELECT ID, locale, MaleText, FemaleText FROM broadcast_text_locale");
10289
10290 if (!result)
10291 {
10292 LOG_WARN("server.loading", ">> Loaded 0 broadcast text locales. DB table `broadcast_text_locale` is empty.");
10293 LOG_INFO("server.loading", " ");
10294 return;
10295 }
10296
10297 uint32 locales_count = 0;
10298 do
10299 {
10300 Field* fields = result->Fetch();
10301
10302 uint32 id = fields[0].Get<uint32>();
10303
10304 BroadcastTextContainer::iterator bct = _broadcastTextStore.find(id);
10305 if (bct == _broadcastTextStore.end())
10306 {
10307 LOG_ERROR("sql.sql", "BroadcastText (Id: {}) found in table `broadcast_text_locale` but does not exist in `broadcast_text`. Skipped!", id);
10308 continue;
10309 }
10310
10311 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
10312 if (locale == LOCALE_enUS)
10313 continue;
10314
10315 AddLocaleString(fields[2].Get<std::string>(), locale, bct->second.MaleText);
10316 AddLocaleString(fields[3].Get<std::string>(), locale, bct->second.FemaleText);
10317 locales_count++;
10318 } while (result->NextRow());
10319
10320 LOG_INFO("server.loading", ">> Loaded {} Broadcast Text Locales in {} ms", locales_count, GetMSTimeDiffToNow(oldMSTime));
10321 LOG_INFO("server.loading", " ");
10322}
LocaleConstant GetLocaleByName(const std::string &name)
Definition Common.cpp:42

References _broadcastTextStore, AddLocaleString(), Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), LOCALE_enUS, LOG_ERROR, LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadBroadcastTexts()

void ObjectMgr::LoadBroadcastTexts ( )
10199{
10200 uint32 oldMSTime = getMSTime();
10201
10202 _broadcastTextStore.clear(); // for reload case
10203
10204 // 0 1 2 3 4 5 6 7 8 9 10 11 12
10205 QueryResult result = WorldDatabase.Query("SELECT ID, LanguageID, MaleText, FemaleText, EmoteID1, EmoteID2, EmoteID3, EmoteDelay1, EmoteDelay2, EmoteDelay3, SoundEntriesID, EmotesID, Flags FROM broadcast_text");
10206 if (!result)
10207 {
10208 LOG_WARN("server.loading", ">> Loaded 0 broadcast texts. DB table `broadcast_text` is empty.");
10209 LOG_INFO("server.loading", " ");
10210 return;
10211 }
10212
10213 _broadcastTextStore.rehash(result->GetRowCount());
10214
10215 do
10216 {
10217 Field* fields = result->Fetch();
10218
10219 BroadcastText bct;
10220
10221 bct.Id = fields[0].Get<uint32>();
10222 bct.LanguageID = fields[1].Get<uint32>();
10223 bct.MaleText[DEFAULT_LOCALE] = fields[2].Get<std::string>();
10224 bct.FemaleText[DEFAULT_LOCALE] = fields[3].Get<std::string>();
10225 bct.EmoteId1 = fields[4].Get<uint32>();
10226 bct.EmoteId2 = fields[5].Get<uint32>();
10227 bct.EmoteId3 = fields[6].Get<uint32>();
10228 bct.EmoteDelay1 = fields[7].Get<uint32>();
10229 bct.EmoteDelay2 = fields[8].Get<uint32>();
10230 bct.EmoteDelay3 = fields[9].Get<uint32>();
10231 bct.SoundEntriesId = fields[10].Get<uint32>();
10232 bct.EmotesID = fields[11].Get<uint32>();
10233 bct.Flags = fields[12].Get<uint32>();
10234
10235 if (bct.SoundEntriesId)
10236 {
10237 if (!sSoundEntriesStore.LookupEntry(bct.SoundEntriesId))
10238 {
10239 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has SoundEntriesId {} but sound does not exist.", bct.Id, bct.SoundEntriesId);
10240 bct.SoundEntriesId = 0;
10241 }
10242 }
10243
10245 {
10246 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` using Language {} but Language does not exist.", bct.Id, bct.LanguageID);
10248 }
10249
10250 if (bct.EmoteId1)
10251 {
10252 if (!sEmotesStore.LookupEntry(bct.EmoteId1))
10253 {
10254 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has EmoteId1 {} but emote does not exist.", bct.Id, bct.EmoteId1);
10255 bct.EmoteId1 = 0;
10256 }
10257 }
10258
10259 if (bct.EmoteId2)
10260 {
10261 if (!sEmotesStore.LookupEntry(bct.EmoteId2))
10262 {
10263 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has EmoteId2 {} but emote does not exist.", bct.Id, bct.EmoteId2);
10264 bct.EmoteId2 = 0;
10265 }
10266 }
10267
10268 if (bct.EmoteId3)
10269 {
10270 if (!sEmotesStore.LookupEntry(bct.EmoteId3))
10271 {
10272 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has EmoteId3 {} but emote does not exist.", bct.Id, bct.EmoteId3);
10273 bct.EmoteId3 = 0;
10274 }
10275 }
10276
10277 _broadcastTextStore[bct.Id] = bct;
10278 } while (result->NextRow());
10279
10280 LOG_INFO("server.loading", ">> Loaded {} Broadcast Texts in {} ms", _broadcastTextStore.size(), GetMSTimeDiffToNow(oldMSTime));
10281}
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
DBCStorage< EmotesEntry > sEmotesStore(EmotesEntryfmt)
LanguageDesc const * GetLanguageDescByID(uint32 lang)
Definition ObjectMgr.cpp:253
@ LANG_UNIVERSAL
Definition SharedDefines.h:746
Definition ObjectMgr.h:435
uint32 EmoteDelay2
Definition ObjectMgr.h:450
uint32 Id
Definition ObjectMgr.h:442
std::vector< std::string > FemaleText
Definition ObjectMgr.h:445
uint32 EmotesID
Definition ObjectMgr.h:453
uint32 LanguageID
Definition ObjectMgr.h:443
uint32 EmoteId2
Definition ObjectMgr.h:447
uint32 EmoteDelay1
Definition ObjectMgr.h:449
uint32 SoundEntriesId
Definition ObjectMgr.h:452
std::vector< std::string > MaleText
Definition ObjectMgr.h:444
uint32 EmoteId3
Definition ObjectMgr.h:448
uint32 EmoteId1
Definition ObjectMgr.h:446
uint32 EmoteDelay3
Definition ObjectMgr.h:451
uint32 Flags
Definition ObjectMgr.h:454

References _broadcastTextStore, DEFAULT_LOCALE, BroadcastText::EmoteDelay1, BroadcastText::EmoteDelay2, BroadcastText::EmoteDelay3, BroadcastText::EmoteId1, BroadcastText::EmoteId2, BroadcastText::EmoteId3, BroadcastText::EmotesID, BroadcastText::FemaleText, BroadcastText::Flags, Field::Get(), GetLanguageDescByID(), getMSTime(), GetMSTimeDiffToNow(), BroadcastText::Id, LANG_UNIVERSAL, BroadcastText::LanguageID, LOG_DEBUG, LOG_INFO, LOG_WARN, BroadcastText::MaleText, sEmotesStore, BroadcastText::SoundEntriesId, sSoundEntriesStore, and WorldDatabase.

◆ LoadCreatureAddons()

void ObjectMgr::LoadCreatureAddons ( )
1254{
1255 uint32 oldMSTime = getMSTime();
1256
1257 // 0 1 2 3 4 5 6 7
1258 QueryResult result = WorldDatabase.Query("SELECT guid, path_id, mount, bytes1, bytes2, emote, visibilityDistanceType, auras FROM creature_addon");
1259
1260 if (!result)
1261 {
1262 LOG_WARN("server.loading", ">> Loaded 0 creature addon definitions. DB table `creature_addon` is empty.");
1263 LOG_INFO("server.loading", " ");
1264 return;
1265 }
1266
1267 uint32 count = 0;
1268 do
1269 {
1270 Field* fields = result->Fetch();
1271
1272 ObjectGuid::LowType guid = fields[0].Get<uint32>();
1273
1274 CreatureData const* creData = GetCreatureData(guid);
1275 if (!creData)
1276 {
1277 LOG_ERROR("sql.sql", "Creature (GUID: {}) does not exist but has a record in `creature_addon`", guid);
1278 continue;
1279 }
1280
1281 CreatureAddon& creatureAddon = _creatureAddonStore[guid];
1282
1283 creatureAddon.path_id = fields[1].Get<uint32>();
1284 if (creData->movementType == WAYPOINT_MOTION_TYPE && !creatureAddon.path_id)
1285 {
1286 const_cast<CreatureData*>(creData)->movementType = IDLE_MOTION_TYPE;
1287 LOG_ERROR("sql.sql", "Creature (GUID {}) has movement type set to WAYPOINT_MOTION_TYPE but no path assigned", guid);
1288 }
1289
1290 creatureAddon.mount = fields[2].Get<uint32>();
1291 creatureAddon.bytes1 = fields[3].Get<uint32>();
1292 creatureAddon.bytes2 = fields[4].Get<uint32>();
1293 creatureAddon.emote = fields[5].Get<uint32>();
1294 creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[6].Get<uint8>());
1295
1296 for (std::string_view aura : Acore::Tokenize(fields[7].Get<std::string_view>(), ' ', false))
1297 {
1298 SpellInfo const* spellInfo = nullptr;
1299
1300 if (Optional<uint32> spellId = Acore::StringTo<uint32>(aura))
1301 {
1302 spellInfo = sSpellMgr->GetSpellInfo(*spellId);
1303 }
1304
1305 if (!spellInfo)
1306 {
1307 LOG_ERROR("sql.sql", "Creature (GUID: {}) has wrong spell '{}' defined in `auras` field in `creature_addon`.", guid, aura);
1308 continue;
1309 }
1310
1311 if (std::find(creatureAddon.auras.begin(), creatureAddon.auras.end(), spellInfo->Id) != creatureAddon.auras.end())
1312 {
1313 LOG_ERROR("sql.sql", "Creature (GUID: {}) has duplicate aura (spell {}) in `auras` field in `creature_addon`.", guid, spellInfo->Id);
1314 continue;
1315 }
1316
1317 if (spellInfo->GetDuration() > 0)
1318 {
1319 LOG_DEBUG/*ERROR*/("sql.sql", "Creature (Entry: {}) has temporary aura (spell {}) in `auras` field in `creature_template_addon`.", guid, spellInfo->Id);
1320 // continue;
1321 }
1322
1323 creatureAddon.auras.push_back(spellInfo->Id);
1324 }
1325
1326 if (creatureAddon.mount)
1327 {
1328 if (!sCreatureDisplayInfoStore.LookupEntry(creatureAddon.mount))
1329 {
1330 LOG_ERROR("sql.sql", "Creature (GUID: {}) has invalid displayInfoId ({}) for mount defined in `creature_addon`", guid, creatureAddon.mount);
1331 creatureAddon.mount = 0;
1332 }
1333 }
1334
1335 if (!sEmotesStore.LookupEntry(creatureAddon.emote))
1336 {
1337 LOG_ERROR("sql.sql", "Creature (GUID: {}) has invalid emote ({}) defined in `creature_addon`.", guid, creatureAddon.emote);
1338 creatureAddon.emote = 0;
1339 }
1340
1342 {
1343 LOG_ERROR("sql.sql", "Creature (GUID: {}) has invalid visibilityDistanceType ({}) defined in `creature_addon`.", guid, AsUnderlyingType(creatureAddon.visibilityDistanceType));
1345 }
1346
1347 ++count;
1348 } while (result->NextRow());
1349
1350 LOG_INFO("server.loading", ">> Loaded {} Creature Addons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1351 LOG_INFO("server.loading", " ");
1352}
DBCStorage< CreatureDisplayInfoEntry > sCreatureDisplayInfoStore(CreatureDisplayInfofmt)
@ WAYPOINT_MOTION_TYPE
Definition MotionMaster.h:41
VisibilityDistanceType
Definition ObjectDefines.h:62
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:24
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition Util.h:610
uint32 Id
Definition SpellInfo.h:320
int32 GetDuration() const
Definition SpellInfo.cpp:2232
Definition AsioHacksFwd.h:47
std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition Tokenize.cpp:20
STL namespace.
Definition CreatureData.h:436
std::vector< uint32 > auras
Definition CreatureData.h:442
uint32 mount
Definition CreatureData.h:438
uint32 emote
Definition CreatureData.h:441
uint32 path_id
Definition CreatureData.h:437
VisibilityDistanceType visibilityDistanceType
Definition CreatureData.h:443
uint32 bytes1
Definition CreatureData.h:439
uint32 bytes2
Definition CreatureData.h:440

References _creatureAddonStore, AsUnderlyingType(), CreatureAddon::auras, CreatureAddon::bytes1, CreatureAddon::bytes2, CreatureAddon::emote, Field::Get(), GetCreatureData(), SpellInfo::GetDuration(), getMSTime(), GetMSTimeDiffToNow(), SpellInfo::Id, IDLE_MOTION_TYPE, LOG_DEBUG, LOG_ERROR, LOG_INFO, LOG_WARN, Max, CreatureAddon::mount, Normal, CreatureAddon::path_id, sCreatureDisplayInfoStore, sEmotesStore, sSpellMgr, Acore::Tokenize(), CreatureAddon::visibilityDistanceType, WAYPOINT_MOTION_TYPE, and WorldDatabase.

◆ LoadCreatureClassLevelStats()

void ObjectMgr::LoadCreatureClassLevelStats ( )
10351{
10352 uint32 oldMSTime = getMSTime();
10353
10354 QueryResult result = WorldDatabase.Query("SELECT level, class, basehp0, basehp1, basehp2, basemana, basearmor, attackpower, rangedattackpower, damage_base, damage_exp1, damage_exp2 FROM creature_classlevelstats");
10355
10356 if (!result)
10357 {
10358 LOG_WARN("server.loading", ">> Loaded 0 creature base stats. DB table `creature_classlevelstats` is empty.");
10359 LOG_INFO("server.loading", " ");
10360 return;
10361 }
10362
10363 uint32 count = 0;
10364 do
10365 {
10366 Field* fields = result->Fetch();
10367
10368 uint8 Level = fields[0].Get<uint8>();
10369 uint8 Class = fields[1].Get<uint8>();
10370
10371 if (!Class || ((1 << (Class - 1)) & CLASSMASK_ALL_CREATURES) == 0)
10372 LOG_ERROR("sql.sql", "Creature base stats for level {} has invalid class {}", Level, Class);
10373
10374 CreatureBaseStats stats;
10375
10376 for (uint8 i = 0; i < MAX_EXPANSIONS; ++i)
10377 {
10378 stats.BaseHealth[i] = fields[2 + i].Get<uint32>();
10379
10380 if (stats.BaseHealth[i] == 0)
10381 {
10382 LOG_ERROR("sql.sql", "Creature base stats for class {}, level {} has invalid zero base HP[{}] - set to 1", Class, Level, i);
10383 stats.BaseHealth[i] = 1;
10384 }
10385
10386 // xinef: if no data is available, get them from lower expansions
10387 if (stats.BaseHealth[i] <= 1)
10388 {
10389 for (uint8 j = i; j > 0;)
10390 {
10391 --j;
10392 if (stats.BaseHealth[j] > 1)
10393 {
10394 stats.BaseHealth[i] = stats.BaseHealth[j];
10395 break;
10396 }
10397 }
10398 }
10399
10400 stats.BaseDamage[i] = fields[9 + i].Get<float>();
10401 if (stats.BaseDamage[i] < 0.0f)
10402 {
10403 LOG_ERROR("sql.sql", "Creature base stats for class {}, level {} has invalid negative base damage[{}] - set to 0.0", Class, Level, i);
10404 stats.BaseDamage[i] = 0.0f;
10405 }
10406 }
10407
10408 stats.BaseMana = fields[5].Get<uint32>();
10409 stats.BaseArmor = fields[6].Get<uint32>();
10410
10411 stats.AttackPower = fields[7].Get<uint32>();
10412 stats.RangedAttackPower = fields[8].Get<uint32>();
10413
10415
10416 ++count;
10417 } while (result->NextRow());
10418
10420 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
10421 {
10422 for (uint16 lvl = itr->second.minlevel; lvl <= itr->second.maxlevel; ++lvl)
10423 {
10424 if (_creatureBaseStatsStore.find(MAKE_PAIR16(lvl, itr->second.unit_class)) == _creatureBaseStatsStore.end())
10425 LOG_ERROR("sql.sql", "Missing base stats for creature class {} level {}", itr->second.unit_class, lvl);
10426 }
10427 }
10428
10429 LOG_INFO("server.loading", ">> Loaded {} Creature Base Stats in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10430 LOG_INFO("server.loading", " ");
10431}
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
Definition CreatureData.h:288
@ Class
Requires the player to be a specific class.
@ Level
Requires the player to be at least a specific level.
CreatureTemplateContainer const * GetCreatureTemplates() const
Definition ObjectMgr.h:769
uint32 BaseMana
Definition CreatureData.h:301
float BaseDamage[MAX_EXPANSIONS]
Definition CreatureData.h:305
uint32 RangedAttackPower
Definition CreatureData.h:304
uint32 AttackPower
Definition CreatureData.h:303
uint32 BaseHealth[MAX_EXPANSIONS]
Definition CreatureData.h:300
float BaseArmor
Definition CreatureData.h:302

References _creatureBaseStatsStore, CreatureBaseStats::AttackPower, CreatureBaseStats::BaseArmor, CreatureBaseStats::BaseDamage, CreatureBaseStats::BaseHealth, CreatureBaseStats::BaseMana, Class, CLASSMASK_ALL_CREATURES, Field::Get(), GetCreatureTemplates(), getMSTime(), GetMSTimeDiffToNow(), Level, LOG_ERROR, LOG_INFO, LOG_WARN, MAKE_PAIR16(), MAX_EXPANSIONS, CreatureBaseStats::RangedAttackPower, and WorldDatabase.

◆ LoadCreatureCustomIDs()

void ObjectMgr::LoadCreatureCustomIDs ( )

Load config option Creatures.CustomIDs into Store.

944{
945 // Hack for modules
946 std::string stringCreatureIds = sConfigMgr->GetOption<std::string>("Creatures.CustomIDs", "190010,55005,999991,25462,98888,601014,34567,34568");
947 std::vector<std::string_view> CustomCreatures = Acore::Tokenize(stringCreatureIds, ',', false);
948
949 for (auto& itr : CustomCreatures)
950 {
951 _creatureCustomIDsStore.push_back(Acore::StringTo<uint32>(itr).value());
952 }
953}
#define sConfigMgr
Definition Config.h:93

References _creatureCustomIDsStore, sConfigMgr, and Acore::Tokenize().

◆ LoadCreatureDataFromDB()

CreatureData const * ObjectMgr::LoadCreatureDataFromDB ( ObjectGuid::LowType  spawnId)

Loads a single creature spawn entry from the database into the data store cache.

This is needed as a prerequisite for Creature::LoadCreatureFromDB(), which reads from the in-memory cache (via GetCreatureData()) rather than querying the DB itself. For spawns not loaded during server startup, this method populates the cache so that Creature::LoadCreatureFromDB() can then create the live entity.

Returns the cached data if already loaded, or nullptr if the spawn doesn't exist or fails validation.

Parameters
spawnIdThe creature spawn GUID to load.
Returns
Pointer to the cached CreatureData, or nullptr on failure.
2429{
2430 CreatureData const* data = GetCreatureData(spawnId);
2431 if (data)
2432 return data;
2433
2434 QueryResult result = WorldDatabase.Query("SELECT creature.guid, id1, id2, id3, map, equipment_id, "
2435 "position_x, position_y, position_z, orientation, spawntimesecs, wander_distance, "
2436 "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, "
2437 "creature.npcflag, creature.unit_flags, creature.dynamicflags, creature.ScriptName "
2438 "FROM creature WHERE creature.guid = {}", spawnId);
2439
2440 if (!result)
2441 return nullptr;
2442
2443 Field* fields = result->Fetch();
2444 uint32 id1 = fields[1].Get<uint32>();
2445 uint32 id2 = fields[2].Get<uint32>();
2446 uint32 id3 = fields[3].Get<uint32>();
2447
2448 CreatureTemplate const* cInfo = GetCreatureTemplate(id1);
2449 if (!cInfo)
2450 {
2451 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non-existing creature entry {} in id1 field, skipped.", spawnId, id1);
2452 return nullptr;
2453 }
2454
2455 if (id2 && !GetCreatureTemplate(id2))
2456 {
2457 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non-existing creature entry {} in id2 field, skipped.", spawnId, id2);
2458 return nullptr;
2459 }
2460
2461 if (id3 && !GetCreatureTemplate(id3))
2462 {
2463 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non-existing creature entry {} in id3 field, skipped.", spawnId, id3);
2464 return nullptr;
2465 }
2466
2467 if (!id2 && id3)
2468 {
2469 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with creature entry {} in id3 field but no entry in id2 field, skipped.", spawnId, id3);
2470 return nullptr;
2471 }
2472
2474 creatureData.id1 = id1;
2475 creatureData.id2 = id2;
2476 creatureData.id3 = id3;
2477 creatureData.mapid = fields[4].Get<uint16>();
2478 creatureData.equipmentId = fields[5].Get<int8>();
2479 creatureData.posX = fields[6].Get<float>();
2480 creatureData.posY = fields[7].Get<float>();
2481 creatureData.posZ = fields[8].Get<float>();
2482 creatureData.orientation = fields[9].Get<float>();
2483 creatureData.spawntimesecs = fields[10].Get<uint32>();
2484 creatureData.wander_distance = fields[11].Get<float>();
2485 creatureData.currentwaypoint = fields[12].Get<uint32>();
2486 creatureData.curhealth = fields[13].Get<uint32>();
2487 creatureData.curmana = fields[14].Get<uint32>();
2488 creatureData.movementType = fields[15].Get<uint8>();
2489 creatureData.spawnMask = fields[16].Get<uint8>();
2490 creatureData.phaseMask = fields[17].Get<uint32>();
2491 creatureData.npcflag = fields[18].Get<uint32>();
2492 creatureData.unit_flags = fields[19].Get<uint32>();
2493 creatureData.dynamicflags = fields[20].Get<uint32>();
2494 creatureData.ScriptId = GetScriptId(fields[21].Get<std::string>());
2495
2496 if (!creatureData.ScriptId)
2497 creatureData.ScriptId = cInfo->ScriptID;
2498
2499 MapEntry const* mapEntry = sMapStore.LookupEntry(creatureData.mapid);
2500 if (!mapEntry)
2501 {
2502 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) that spawned at non-existing map (Id: {}), skipped.", spawnId, creatureData.mapid);
2503 _creatureDataStore.erase(spawnId);
2504 return nullptr;
2505 }
2506
2507 if (mapEntry->IsRaid() && creatureData.spawntimesecs >= 7 * DAY && creatureData.spawntimesecs < 14 * DAY)
2508 creatureData.spawntimesecs = 14 * DAY;
2509
2510 bool ok = true;
2511 for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff)
2512 {
2513 if (_difficultyEntries[diff].find(id1) != _difficultyEntries[diff].end() ||
2514 _difficultyEntries[diff].find(id2) != _difficultyEntries[diff].end() ||
2515 _difficultyEntries[diff].find(id3) != _difficultyEntries[diff].end())
2516 {
2517 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) that is listed as difficulty {} template (Entries: {}, {}, {}) in `creature_template`, skipped.",
2518 spawnId, diff + 1, id1, id2, id3);
2519 ok = false;
2520 }
2521 }
2522
2523 if (!ok)
2524 {
2525 _creatureDataStore.erase(spawnId);
2526 return nullptr;
2527 }
2528
2529 if (creatureData.equipmentId != 0)
2530 {
2531 if (!GetEquipmentInfo(id1, creatureData.equipmentId) ||
2532 (id2 && !GetEquipmentInfo(id2, creatureData.equipmentId)) ||
2533 (id3 && !GetEquipmentInfo(id3, creatureData.equipmentId)))
2534 {
2535 LOG_ERROR("sql.sql", "Table `creature` has creature (Entries: {}, {}, {}) with equipment_id {} not found in table `creature_equip_template`, set to no equipment.",
2536 id1, id2, id3, creatureData.equipmentId);
2537 creatureData.equipmentId = 0;
2538 }
2539 }
2540
2541 if (creatureData.movementType >= MAX_DB_MOTION_TYPE)
2542 {
2543 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with wrong movement generator type ({}), set to IDLE.",
2544 spawnId, id1, id2, id3, creatureData.movementType);
2545 creatureData.movementType = IDLE_MOTION_TYPE;
2546 }
2547
2548 if (creatureData.wander_distance < 0.0f)
2549 {
2550 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with `wander_distance`< 0, set to 0.",
2551 spawnId, id1, id2, id3);
2552 creatureData.wander_distance = 0.0f;
2553 }
2554 else if (creatureData.movementType == RANDOM_MOTION_TYPE)
2555 {
2556 if (creatureData.wander_distance == 0.0f)
2557 {
2558 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with `MovementType`=1 (random movement) but with `wander_distance`=0, replace by idle movement type (0).",
2559 spawnId, id1, id2, id3);
2560 creatureData.movementType = IDLE_MOTION_TYPE;
2561 }
2562 }
2563 else if (creatureData.movementType == IDLE_MOTION_TYPE)
2564 {
2565 if (creatureData.wander_distance != 0.0f)
2566 {
2567 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with `MovementType`=0 (idle) have `wander_distance`<>0, set to 0.",
2568 spawnId, id1, id2, id3);
2569 creatureData.wander_distance = 0.0f;
2570 }
2571 }
2572
2573 if (creatureData.phaseMask == 0)
2574 {
2575 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with `phaseMask`=0 (not visible for anyone), set to 1.",
2576 spawnId, id1, id2, id3);
2577 creatureData.phaseMask = 1;
2578 }
2579
2580 return &creatureData;
2581}
constexpr auto DAY
Definition Common.h:49
std::int8_t int8
Definition Define.h:105
@ RANDOM_MOTION_TYPE
Definition MotionMaster.h:40
EquipmentInfo const * GetEquipmentInfo(uint32 entry, int8 &id)
Definition ObjectMgr.cpp:1445
ObjectData const creatureData[]
Definition instance_blackwing_lair.cpp:45
bool IsRaid() const
Definition DBCStructure.h:1354

References _creatureDataStore, _difficultyEntries, creatureData, DAY, Field::Get(), GetCreatureData(), GetCreatureTemplate(), GetEquipmentInfo(), GetScriptId(), IDLE_MOTION_TYPE, MapEntry::IsRaid(), LOG_ERROR, MAX_DB_MOTION_TYPE, MAX_DIFFICULTY, RANDOM_MOTION_TYPE, sMapStore, and WorldDatabase.

◆ LoadCreatureDefaultTrainers()

void ObjectMgr::LoadCreatureDefaultTrainers ( )
9744{
9745 uint32 oldMSTime = getMSTime();
9746
9748
9749 if (QueryResult result = WorldDatabase.Query("SELECT CreatureId, TrainerId FROM creature_default_trainer"))
9750 {
9751 do
9752 {
9753 Field* fields = result->Fetch();
9754 uint32 creatureId = fields[0].Get<uint32>();
9755 uint32 trainerId = fields[1].Get<uint32>();
9756
9757 if (!GetCreatureTemplate(creatureId))
9758 {
9759 LOG_ERROR("sql.sql", "Table `creature_default_trainer` references non-existing creature template (CreatureId: %u), ignoring", creatureId);
9760 continue;
9761 }
9762
9763 _creatureDefaultTrainers[creatureId] = trainerId;
9764
9765 } while (result->NextRow());
9766 }
9767
9768 LOG_INFO("server.loading", ">> Loaded {} default trainers in {} ms", _creatureDefaultTrainers.size(), GetMSTimeDiffToNow(oldMSTime));
9769}

References _creatureDefaultTrainers, Field::Get(), GetCreatureTemplate(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, and WorldDatabase.

◆ LoadCreatureLocales()

void ObjectMgr::LoadCreatureLocales ( )
392{
393 uint32 oldMSTime = getMSTime();
394
395 _creatureLocaleStore.clear(); // need for reload case
396
397 // 0 1 2 3
398 QueryResult result = WorldDatabase.Query("SELECT entry, locale, Name, Title FROM creature_template_locale");
399 if (!result)
400 return;
401
402 do
403 {
404 Field* fields = result->Fetch();
405
406 uint32 ID = fields[0].Get<uint32>();
407
408 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
409 if (locale == LOCALE_enUS)
410 continue;
411
413 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
414 AddLocaleString(fields[3].Get<std::string>(), locale, data.Title);
415 } while (result->NextRow());
416
417 LOG_INFO("server.loading", ">> Loaded {} Creature Locale Strings in {} ms", (unsigned long)_creatureLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
418}
Definition CreatureData.h:339
std::vector< std::string > Title
Definition CreatureData.h:341
std::vector< std::string > Name
Definition CreatureData.h:340

References _creatureLocaleStore, AddLocaleString(), Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), LOCALE_enUS, LOG_INFO, CreatureLocale::Name, CreatureLocale::Title, and WorldDatabase.

◆ LoadCreatureModelInfo()

void ObjectMgr::LoadCreatureModelInfo ( )
1702{
1703 uint32 oldMSTime = getMSTime();
1704
1705 // 0 1 2 3 4
1706 QueryResult result = WorldDatabase.Query("SELECT DisplayID, BoundingRadius, CombatReach, Gender, DisplayID_Other_Gender FROM creature_model_info");
1707
1708 if (!result)
1709 {
1710 LOG_WARN("server.loading", ">> Loaded 0 creature model definitions. DB table `creature_model_info` is empty.");
1711 LOG_INFO("server.loading", " ");
1712 return;
1713 }
1714
1715 _creatureModelStore.rehash(result->GetRowCount());
1716 uint32 count = 0;
1717
1718 // List of ModelDataIDs that use Invisible models
1719 uint32 triggerCreatureModelDataID[14] = { 1731, 1752, 2206, 2296, 2372, 2382, 2481, 2512, 2513, 2611, 2636, 2790, 3230, 3274 };
1720
1721 do
1722 {
1723 Field* fields = result->Fetch();
1724
1725 uint32 displayId = fields[0].Get<uint32>();
1726 CreatureDisplayInfoEntry const* creatureDisplay = sCreatureDisplayInfoStore.LookupEntry(displayId);
1727 uint32 modelId = fields[0].Get<uint32>();
1728
1729 CreatureModelInfo& modelInfo = _creatureModelStore[modelId];
1730
1731 modelInfo.bounding_radius = fields[1].Get<float>();
1732 modelInfo.combat_reach = fields[2].Get<float>();
1733 modelInfo.gender = fields[3].Get<uint8>();
1734 modelInfo.modelid_other_gender = fields[4].Get<uint32>();
1735 modelInfo.is_trigger = false;
1736
1737 // Checks
1738
1739 if (!sCreatureDisplayInfoStore.LookupEntry(modelId))
1740 LOG_ERROR("sql.sql", "Table `creature_model_info` has model for not existed display id ({}).", modelId);
1741
1742 if (modelInfo.gender > GENDER_NONE)
1743 {
1744 LOG_ERROR("sql.sql", "Table `creature_model_info` has wrong gender ({}) for display id ({}).", uint32(modelInfo.gender), modelId);
1745 modelInfo.gender = GENDER_MALE;
1746 }
1747
1748 if (modelInfo.modelid_other_gender && !sCreatureDisplayInfoStore.LookupEntry(modelInfo.modelid_other_gender))
1749 {
1750 LOG_ERROR("sql.sql", "Table `creature_model_info` has not existed alt.gender model ({}) for existed display id ({}).", modelInfo.modelid_other_gender, modelId);
1751 modelInfo.modelid_other_gender = 0;
1752 }
1753
1754 if (modelInfo.combat_reach < 0.1f)
1755 modelInfo.combat_reach = DEFAULT_COMBAT_REACH;
1756
1757 if (CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(creatureDisplay->ModelId))
1758 {
1759 for (uint32 i = 0; i < 14; i++)
1760 {
1761 if (modelData->Id == triggerCreatureModelDataID[i])
1762 {
1763 modelInfo.is_trigger = true;
1764 break;
1765 }
1766 }
1767 }
1768
1769 ++count;
1770 } while (result->NextRow());
1771
1772 LOG_INFO("server.loading", ">> Loaded {} Creature Model Based Info in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1773 LOG_INFO("server.loading", " ");
1774}
DBCStorage< CreatureModelDataEntry > sCreatureModelDataStore(CreatureModelDatafmt)
#define DEFAULT_COMBAT_REACH
Definition ObjectDefines.h:45
@ GENDER_MALE
Definition SharedDefines.h:61
Definition DBCStructure.h:721
Definition DBCStructure.h:775
float bounding_radius
Definition CreatureData.h:395

References _creatureModelStore, CreatureModelInfo::bounding_radius, DEFAULT_COMBAT_REACH, GENDER_MALE, GENDER_NONE, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, sCreatureDisplayInfoStore, sCreatureModelDataStore, and WorldDatabase.

◆ LoadCreatureMovementOverrides()

void ObjectMgr::LoadCreatureMovementOverrides ( )
1550{
1551 uint32 oldMSTime = getMSTime();
1552
1554
1555 // Load the data from creature_movement_override and if NULL fallback to creature_template_movement
1556 QueryResult result = WorldDatabase.Query("SELECT cmo.SpawnId,"
1557 "COALESCE(cmo.Ground, ctm.Ground),"
1558 "COALESCE(cmo.Swim, ctm.Swim),"
1559 "COALESCE(cmo.Flight, ctm.Flight),"
1560 "COALESCE(cmo.Rooted, ctm.Rooted),"
1561 "COALESCE(cmo.Chase, ctm.Chase),"
1562 "COALESCE(cmo.Random, ctm.Random),"
1563 "COALESCE(cmo.InteractionPauseTimer, ctm.InteractionPauseTimer) "
1564 "FROM creature_movement_override AS cmo "
1565 "LEFT JOIN creature AS c ON c.guid = cmo.SpawnId "
1566 "LEFT JOIN creature_template_movement AS ctm ON ctm.CreatureId = c.id1");
1567 if (!result)
1568 {
1569 LOG_WARN("server.loading", ">> Loaded 0 creature movement overrides. DB table `creature_movement_override` is empty!");
1570 return;
1571 }
1572
1573 do
1574 {
1575 Field* fields = result->Fetch();
1576 ObjectGuid::LowType spawnId = fields[0].Get<uint32>();
1577 if (!GetCreatureData(spawnId))
1578 {
1579 LOG_ERROR("sql.sql", "Creature (GUID: {}) does not exist but has a record in `creature_movement_override`", spawnId);
1580 continue;
1581 }
1582
1584 if (!fields[1].IsNull())
1585 {
1586 movement.Ground = static_cast<CreatureGroundMovementType>(fields[1].Get<uint8>());
1587 }
1588
1589 if (!fields[2].IsNull())
1590 {
1591 movement.Swim = fields[2].Get<bool>();
1592 }
1593
1594 if (!fields[3].IsNull())
1595 {
1596 movement.Flight = static_cast<CreatureFlightMovementType>(fields[3].Get<uint8>());
1597 }
1598
1599 if (!fields[4].IsNull())
1600 {
1601 movement.Rooted = fields[4].Get<bool>();
1602 }
1603
1604 if (!fields[5].IsNull())
1605 {
1606 movement.Chase = static_cast<CreatureChaseMovementType>(fields[5].Get<uint8>());
1607 }
1608
1609 if (!fields[6].IsNull())
1610 {
1611 movement.Random = static_cast<CreatureRandomMovementType>(fields[6].Get<uint8>());
1612 }
1613
1614 if (!fields[7].IsNull())
1615 {
1616 movement.InteractionPauseTimer = fields[7].Get<uint32>();
1617 }
1618
1619 CheckCreatureMovement("creature_movement_override", spawnId, movement);
1620 } while (result->NextRow());
1621
1622 LOG_INFO("server.loading", ">> Loaded {} Movement Overrides in {} ms", _creatureMovementOverrides.size(), GetMSTimeDiffToNow(oldMSTime));
1623 LOG_INFO("server.loading", " ");
1624}
CreatureFlightMovementType
Definition CreatureData.h:92
CreatureChaseMovementType
Definition CreatureData.h:101
CreatureGroundMovementType
Definition CreatureData.h:83
CreatureRandomMovementType
Definition CreatureData.h:110
Definition CreatureData.h:119
bool Swim
Definition CreatureData.h:124
bool Rooted
Definition CreatureData.h:125
uint32 InteractionPauseTimer
Definition CreatureData.h:128

References _creatureMovementOverrides, CreatureMovementData::Chase, CheckCreatureMovement(), CreatureMovementData::Flight, Field::Get(), GetCreatureData(), getMSTime(), GetMSTimeDiffToNow(), CreatureMovementData::Ground, CreatureMovementData::InteractionPauseTimer, LOG_ERROR, LOG_INFO, LOG_WARN, CreatureMovementData::Random, CreatureMovementData::Rooted, CreatureMovementData::Swim, and WorldDatabase.

◆ LoadCreatureQuestEnders()

void ObjectMgr::LoadCreatureQuestEnders ( )
8673{
8674 LoadQuestRelationsHelper(_creatureQuestInvolvedRelations, "creature_questender", false, false);
8675
8676 for (QuestRelations::iterator itr = _creatureQuestInvolvedRelations.begin(); itr != _creatureQuestInvolvedRelations.end(); ++itr)
8677 {
8678 CreatureTemplate const* cInfo = GetCreatureTemplate(itr->first);
8679 if (!cInfo)
8680 LOG_ERROR("sql.sql", "Table `creature_questender` have data for not existed creature entry ({}) and existed quest {}", itr->first, itr->second);
8681 else if (!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER))
8682 LOG_ERROR("sql.sql", "Table `creature_questender` has creature entry ({}) for quest {}, but npcflag does not include UNIT_NPC_FLAG_QUESTGIVER", itr->first, itr->second);
8683 }
8684}
@ UNIT_NPC_FLAG_QUESTGIVER
Definition UnitDefines.h:320
void LoadQuestRelationsHelper(QuestRelations &map, std::string const &table, bool starter, bool go)
Definition ObjectMgr.cpp:8585

References _creatureQuestInvolvedRelations, GetCreatureTemplate(), LoadQuestRelationsHelper(), LOG_ERROR, CreatureTemplate::npcflag, and UNIT_NPC_FLAG_QUESTGIVER.

Referenced by LoadQuestStartersAndEnders().

◆ LoadCreatureQuestItems()

void ObjectMgr::LoadCreatureQuestItems ( )
10752{
10753 uint32 oldMSTime = getMSTime();
10754
10755 // 0 1 2
10756 QueryResult result = WorldDatabase.Query("SELECT CreatureEntry, ItemId, Idx FROM creature_questitem ORDER BY Idx ASC");
10757
10758 if (!result)
10759 {
10760 LOG_WARN("server.loading", ">> Loaded 0 creature quest items. DB table `creature_questitem` is empty.");
10761 return;
10762 }
10763
10764 uint32 count = 0;
10765 do
10766 {
10767 Field* fields = result->Fetch();
10768
10769 uint32 entry = fields[0].Get<uint32>();
10770 uint32 item = fields[1].Get<uint32>();
10771 uint32 idx = fields[2].Get<uint32>();
10772
10773 CreatureTemplate const* creatureInfo = GetCreatureTemplate(entry);
10774 if (!creatureInfo)
10775 {
10776 LOG_ERROR("sql.sql", "Table `creature_questitem` has data for nonexistent creature (entry: {}, idx: {}), skipped", entry, idx);
10777 continue;
10778 };
10779
10780 ItemEntry const* dbcData = sItemStore.LookupEntry(item);
10781 if (!dbcData)
10782 {
10783 LOG_ERROR("sql.sql", "Table `creature_questitem` has nonexistent item (ID: {}) in creature (entry: {}, idx: {}), skipped", item, entry, idx);
10784 continue;
10785 };
10786
10787 _creatureQuestItemStore[entry].push_back(item);
10788
10789 ++count;
10790 } while (result->NextRow());
10791
10792 LOG_INFO("server.loading", ">> Loaded {} Creature Quest Items in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10793 LOG_INFO("server.loading", " ");
10794}
DBCStorage< ItemEntry > sItemStore(Itemfmt)
Definition DBCStructure.h:1143

References _creatureQuestItemStore, Field::Get(), GetCreatureTemplate(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, sItemStore, and WorldDatabase.

◆ LoadCreatureQuestStarters()

void ObjectMgr::LoadCreatureQuestStarters ( )
8659{
8660 LoadQuestRelationsHelper(_creatureQuestRelations, "creature_queststarter", true, false);
8661
8662 for (QuestRelations::iterator itr = _creatureQuestRelations.begin(); itr != _creatureQuestRelations.end(); ++itr)
8663 {
8664 CreatureTemplate const* cInfo = GetCreatureTemplate(itr->first);
8665 if (!cInfo)
8666 LOG_ERROR("sql.sql", "Table `creature_queststarter` have data for not existed creature entry ({}) and existed quest {}", itr->first, itr->second);
8667 else if (!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER))
8668 LOG_ERROR("sql.sql", "Table `creature_queststarter` has creature entry ({}) for quest {}, but npcflag does not include UNIT_NPC_FLAG_QUESTGIVER", itr->first, itr->second);
8669 }
8670}

References _creatureQuestRelations, GetCreatureTemplate(), LoadQuestRelationsHelper(), LOG_ERROR, CreatureTemplate::npcflag, and UNIT_NPC_FLAG_QUESTGIVER.

Referenced by LoadQuestStartersAndEnders().

◆ LoadCreatures()

void ObjectMgr::LoadCreatures ( )
2228{
2229 uint32 oldMSTime = getMSTime();
2230
2231 // 0 1 2 3 4 5 6 7 8 9 10 11
2232 QueryResult result = WorldDatabase.Query("SELECT creature.guid, id1, id2, id3, map, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, wander_distance, "
2233 // 12 13 14 15 16 17 18 19 20 21 22
2234 "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags, "
2235 // 23
2236 "creature.ScriptName "
2237 "FROM creature "
2238 "LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid "
2239 "LEFT OUTER JOIN pool_creature ON creature.guid = pool_creature.guid");
2240
2241 if (!result)
2242 {
2243 LOG_WARN("server.loading", ">> Loaded 0 creatures. DB table `creature` is empty.");
2244 LOG_INFO("server.loading", " ");
2245 return;
2246 }
2247
2249 LOG_INFO("server.loading", "Calculating zone and area fields. This may take a moment...");
2250
2251 // Build single time for check spawnmask
2252 std::map<uint32, uint32> spawnMasks;
2253 for (uint32 i = 0; i < sMapStore.GetNumRows(); ++i)
2254 if (sMapStore.LookupEntry(i))
2255 for (int k = 0; k < MAX_DIFFICULTY; ++k)
2257 spawnMasks[i] |= (1 << k);
2258
2259 _creatureDataStore.rehash(result->GetRowCount());
2260 uint32 count = 0;
2261 do
2262 {
2263 Field* fields = result->Fetch();
2264
2265 ObjectGuid::LowType spawnId = fields[0].Get<uint32>();
2266 uint32 id1 = fields[1].Get<uint32>();
2267 uint32 id2 = fields[2].Get<uint32>();
2268 uint32 id3 = fields[3].Get<uint32>();
2269
2270 CreatureTemplate const* cInfo = GetCreatureTemplate(id1);
2271 if (!cInfo)
2272 {
2273 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non existing creature entry {} in id1 field, skipped.", spawnId, id1);
2274 continue;
2275 }
2276 CreatureTemplate const* cInfo2 = GetCreatureTemplate(id2);
2277 if (!cInfo2 && id2)
2278 {
2279 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non existing creature entry {} in id2 field, skipped.", spawnId, id2);
2280 continue;
2281 }
2282 CreatureTemplate const* cInfo3 = GetCreatureTemplate(id3);
2283 if (!cInfo3 && id3)
2284 {
2285 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non existing creature entry {} in id3 field, skipped.", spawnId, id3);
2286 continue;
2287 }
2288 if (!id2 && id3)
2289 {
2290 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with creature entry {} in id3 field but no entry in id2 field, skipped.", spawnId, id3);
2291 continue;
2292 }
2293 CreatureData& data = _creatureDataStore[spawnId];
2294 data.id1 = id1;
2295 data.id2 = id2;
2296 data.id3 = id3;
2297 data.mapid = fields[4].Get<uint16>();
2298 data.equipmentId = fields[5].Get<int8>();
2299 data.posX = fields[6].Get<float>();
2300 data.posY = fields[7].Get<float>();
2301 data.posZ = fields[8].Get<float>();
2302 data.orientation = fields[9].Get<float>();
2303 data.spawntimesecs = fields[10].Get<uint32>();
2304 data.wander_distance = fields[11].Get<float>();
2305 data.currentwaypoint = fields[12].Get<uint32>();
2306 data.curhealth = fields[13].Get<uint32>();
2307 data.curmana = fields[14].Get<uint32>();
2308 data.movementType = fields[15].Get<uint8>();
2309 data.spawnMask = fields[16].Get<uint8>();
2310 data.phaseMask = fields[17].Get<uint32>();
2311 int16 gameEvent = fields[18].Get<int16>();
2312 uint32 PoolId = fields[19].Get<uint32>();
2313 data.npcflag = fields[20].Get<uint32>();
2314 data.unit_flags = fields[21].Get<uint32>();
2315 data.dynamicflags = fields[22].Get<uint32>();
2316 data.ScriptId = GetScriptId(fields[23].Get<std::string>());
2317
2318 if (!data.ScriptId)
2319 data.ScriptId = cInfo->ScriptID;
2320
2321 MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid);
2322 if (!mapEntry)
2323 {
2324 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {}) that spawned at not existed map (Id: {}), skipped.", spawnId, data.mapid);
2325 continue;
2326 }
2327
2328 // pussywizard: 7 days means no reaspawn, so set it to 14 days, because manual id reset may be late
2329 if (mapEntry->IsRaid() && data.spawntimesecs >= 7 * DAY && data.spawntimesecs < 14 * DAY)
2330 data.spawntimesecs = 14 * DAY;
2331
2332 // Skip spawnMask check for transport maps
2333 if (!_transportMaps.count(data.mapid) && data.spawnMask & ~spawnMasks[data.mapid])
2334 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {}) that have wrong spawn mask {} including not supported difficulty modes for map (Id: {}).",
2335 spawnId, data.spawnMask, data.mapid);
2336
2337 bool ok = true;
2338 for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff)
2339 {
2340 if ((_difficultyEntries[diff].find(data.id1) != _difficultyEntries[diff].end()) || (_difficultyEntries[diff].find(data.id2) != _difficultyEntries[diff].end()) || (_difficultyEntries[diff].find(data.id3) != _difficultyEntries[diff].end()))
2341 {
2342 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {}) that listed as difficulty {} template (Entries: {}, {}, {}) in `creature_template`, skipped.",
2343 spawnId, diff + 1, data.id1, data.id2, data.id3);
2344 ok = false;
2345 }
2346 }
2347 if (!ok)
2348 continue;
2349
2350 // -1 random, 0 no equipment,
2351 if (data.equipmentId != 0)
2352 {
2353 if ((!GetEquipmentInfo(data.id1, data.equipmentId)) || (data.id2 && !GetEquipmentInfo(data.id2, data.equipmentId)) || (data.id3 && !GetEquipmentInfo(data.id3, data.equipmentId)))
2354 {
2355 LOG_ERROR("sql.sql", "Table `creature` have creature (Entries: {}, {}, {}) one or more with equipment_id {} not found in table `creature_equip_template`, set to no equipment.",
2356 data.id1, data.id2, data.id3, data.equipmentId);
2357 data.equipmentId = 0;
2358 }
2359 }
2361 {
2362 if (!mapEntry->IsDungeon())
2363 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entries: {}, {}, {}) with a `creature_template`.`flags_extra` in one or more entries including CREATURE_FLAG_EXTRA_INSTANCE_BIND but creature are not in instance.",
2364 spawnId, data.id1, data.id2, data.id3);
2365 }
2366 if (data.movementType >= MAX_DB_MOTION_TYPE)
2367 {
2368 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with wrong movement generator type ({}), ignored and set to IDLE.", spawnId, data.id1, data.id2, data.id3, data.movementType);
2370 }
2371 if (data.wander_distance < 0.0f)
2372 {
2373 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entries: {}, {}, {}) with `wander_distance`< 0, set to 0.", spawnId, data.id1, data.id2, data.id3);
2374 data.wander_distance = 0.0f;
2375 }
2376 else if (data.movementType == RANDOM_MOTION_TYPE)
2377 {
2378 if (data.wander_distance == 0.0f)
2379 {
2380 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entries: {}, {}, {}) with `MovementType`=1 (random movement) but with `wander_distance`=0, replace by idle movement type (0).",
2381 spawnId, data.id1, data.id2, data.id3);
2383 }
2384 }
2385 else if (data.movementType == IDLE_MOTION_TYPE)
2386 {
2387 if (data.wander_distance != 0.0f)
2388 {
2389 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entries: {}, {}, {}) with `MovementType`=0 (idle) have `wander_distance`<>0, set to 0.", spawnId, data.id1, data.id2, data.id3);
2390 data.wander_distance = 0.0f;
2391 }
2392 }
2393
2394 if (data.phaseMask == 0)
2395 {
2396 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entries: {}, {}, {}) with `phaseMask`=0 (not visible for anyone), set to 1.", spawnId, data.id1, data.id2, data.id3);
2397 data.phaseMask = 1;
2398 }
2399
2401 {
2402 uint32 zoneId = sMapMgr->GetZoneId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
2403 uint32 areaId = sMapMgr->GetAreaId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
2404
2406
2407 stmt->SetData(0, zoneId);
2408 stmt->SetData(1, areaId);
2409 stmt->SetData(2, spawnId);
2410
2411 WorldDatabase.Execute(stmt);
2412 }
2413
2414 // Add to grid if not managed by the game event or pool system
2415 if (gameEvent == 0 && PoolId == 0)
2416 AddCreatureToGrid(spawnId, &data);
2417
2418 ++count;
2419 } while (result->NextRow());
2420
2421 LOG_INFO("server.loading", ">> Loaded {} Creatures in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2422 LOG_INFO("server.loading", " ");
2423}
@ CREATURE_FLAG_EXTRA_INSTANCE_BIND
Definition CreatureData.h:45
Difficulty
Definition DBCEnums.h:266
MapDifficulty const * GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
Definition DBCStores.cpp:761
std::int16_t int16
Definition Define.h:104
@ CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA
Definition WorldConfig.h:113
@ WORLD_UPD_CREATURE_ZONE_AREA_DATA
Definition WorldDatabase.h:114
uint32 ScriptId
Definition CreatureData.h:389
bool HasFlagsExtra(uint32 flag) const
Definition CreatureData.h:279

References _creatureDataStore, _difficultyEntries, _transportMaps, AddCreatureToGrid(), CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA, CREATURE_FLAG_EXTRA_INSTANCE_BIND, CreatureData::curhealth, CreatureData::curmana, CreatureData::currentwaypoint, DAY, CreatureData::dynamicflags, CreatureData::equipmentId, Field::Get(), GetCreatureTemplate(), GetEquipmentInfo(), GetMapDifficultyData(), getMSTime(), GetMSTimeDiffToNow(), GetScriptId(), CreatureTemplate::HasFlagsExtra(), CreatureData::id1, CreatureData::id2, CreatureData::id3, IDLE_MOTION_TYPE, MapEntry::IsDungeon(), MapEntry::IsRaid(), LOG_ERROR, LOG_INFO, LOG_WARN, CreatureData::mapid, MAX_DB_MOTION_TYPE, MAX_DIFFICULTY, CreatureData::movementType, CreatureData::npcflag, CreatureData::orientation, CreatureData::phaseMask, CreatureData::posX, CreatureData::posY, CreatureData::posZ, RANDOM_MOTION_TYPE, CreatureData::ScriptId, PreparedStatementBase::SetData(), sMapMgr, sMapStore, CreatureData::spawnMask, CreatureData::spawntimesecs, sWorld, CreatureData::unit_flags, CreatureData::wander_distance, WORLD_UPD_CREATURE_ZONE_AREA_DATA, and WorldDatabase.

◆ LoadCreatureSparring()

void ObjectMgr::LoadCreatureSparring ( )
2584{
2585 uint32 oldMSTime = getMSTime();
2586
2587 QueryResult result = WorldDatabase.Query("SELECT GUID, SparringPCT FROM creature_sparring");
2588
2589 if (!result)
2590 {
2591 LOG_WARN("server.loading", ">> Loaded 0 sparring data. DB table `creature_sparring` is empty.");
2592 LOG_INFO("server.loading", " ");
2593 return;
2594 }
2595
2596 uint32 count = 0;
2597 do
2598 {
2599 Field* fields = result->Fetch();
2600
2601 ObjectGuid::LowType spawnId = fields[0].Get<uint32>();
2602 float sparringHealthPct = fields[1].Get<float>();
2603
2604 if (!GetCreatureData(spawnId))
2605 {
2606 LOG_ERROR("sql.sql", "Entry {} has a record in `creature_sparring` but doesn't exist in `creatures` table");
2607 continue;
2608 }
2609
2610 _creatureSparringStore[spawnId].push_back(sparringHealthPct);
2611
2612 ++count;
2613 } while (result->NextRow());
2614
2615 LOG_INFO("server.loading", ">> Loaded {} sparring data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2616 LOG_INFO("server.loading", " ");
2617}

References _creatureSparringStore, Field::Get(), GetCreatureData(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadCreatureTemplate()

void ObjectMgr::LoadCreatureTemplate ( Field fields,
bool  triggerHook = false 
)

Loads a creature template from a database result.

Parameters
fieldsDatabase result
triggerHookIf true, will trigger the OnAfterDatabaseLoadCreatureTemplates hook. Useful if you are not calling the hook yourself.
583{
584 uint32 entry = fields[0].Get<uint32>();
585
586 CreatureTemplate& creatureTemplate = _creatureTemplateStore[entry];
587
588 // enlarge the fast cache as necessary
589 if (_creatureTemplateStoreFast.size() < entry + 1)
590 {
591 _creatureTemplateStoreFast.resize(entry + 1, nullptr);
592 }
593
594 // load a pointer to this creatureTemplate into the fast cache
595 _creatureTemplateStoreFast[entry] = &creatureTemplate;
596
597 // build the creatureTemplate
598 creatureTemplate.Entry = entry;
599
600 for (uint8 i = 0; i < MAX_DIFFICULTY - 1; ++i)
601 {
602 creatureTemplate.DifficultyEntry[i] = fields[1 + i].Get<uint32>();
603 }
604
605 for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i)
606 {
607 creatureTemplate.KillCredit[i] = fields[4 + i].Get<uint32>();
608 }
609 creatureTemplate.Name = fields[6].Get<std::string>();
610 creatureTemplate.SubName = fields[7].Get<std::string>();
611 creatureTemplate.IconName = fields[8].Get<std::string>();
612 creatureTemplate.GossipMenuId = fields[9].Get<uint32>();
613 creatureTemplate.minlevel = fields[10].Get<uint8>();
614 creatureTemplate.maxlevel = fields[11].Get<uint8>();
615 creatureTemplate.expansion = uint32(fields[12].Get<int16>());
616 creatureTemplate.faction = uint32(fields[13].Get<uint16>());
617 creatureTemplate.npcflag = fields[14].Get<uint32>();
618 creatureTemplate.speed_walk = fields[15].Get<float>();
619 creatureTemplate.speed_run = fields[16].Get<float>();
620 creatureTemplate.speed_swim = fields[17].Get<float>();
621 creatureTemplate.speed_flight = fields[18].Get<float>();
622 creatureTemplate.detection_range = fields[19].Get<float>();
623 creatureTemplate.scale = fields[20].Get<float>();
624 creatureTemplate.rank = uint32(fields[21].Get<uint8>());
625 creatureTemplate.dmgschool = uint32(fields[22].Get<int8>());
626 creatureTemplate.DamageModifier = fields[23].Get<float>();
627 creatureTemplate.BaseAttackTime = fields[24].Get<uint32>();
628 creatureTemplate.RangeAttackTime = fields[25].Get<uint32>();
629 creatureTemplate.BaseVariance = fields[26].Get<float>();
630 creatureTemplate.RangeVariance = fields[27].Get<float>();
631 creatureTemplate.unit_class = uint32(fields[28].Get<uint8>());
632 creatureTemplate.unit_flags = fields[29].Get<uint32>();
633 creatureTemplate.unit_flags2 = fields[30].Get<uint32>();
634 creatureTemplate.dynamicflags = fields[31].Get<uint32>();
635 creatureTemplate.family = uint32(fields[32].Get<uint8>());
636 creatureTemplate.type = uint32(fields[33].Get<uint8>());
637 creatureTemplate.type_flags = fields[34].Get<uint32>();
638 creatureTemplate.lootid = fields[35].Get<uint32>();
639 creatureTemplate.pickpocketLootId = fields[36].Get<uint32>();
640 creatureTemplate.SkinLootId = fields[37].Get<uint32>();
641
642 for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
643 {
644 creatureTemplate.resistance[i] = 0;
645 }
646
647 for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
648 {
649 creatureTemplate.spells[i] = 0;
650 }
651
652 creatureTemplate.PetSpellDataId = fields[38].Get<uint32>();
653 creatureTemplate.VehicleId = fields[39].Get<uint32>();
654 creatureTemplate.mingold = fields[40].Get<uint32>();
655 creatureTemplate.maxgold = fields[41].Get<uint32>();
656 creatureTemplate.AIName = fields[42].Get<std::string>();
657 creatureTemplate.MovementType = uint32(fields[43].Get<uint8>());
658 if (!fields[44].IsNull())
659 {
660 creatureTemplate.Movement.Ground = static_cast<CreatureGroundMovementType>(fields[44].Get<uint8>());
661 }
662
663 creatureTemplate.Movement.Swim = fields[45].Get<bool>();
664 if (!fields[46].IsNull())
665 {
666 creatureTemplate.Movement.Flight = static_cast<CreatureFlightMovementType>(fields[46].Get<uint8>());
667 }
668
669 creatureTemplate.Movement.Rooted = fields[47].Get<bool>();
670 if (!fields[48].IsNull())
671 {
672 creatureTemplate.Movement.Chase = static_cast<CreatureChaseMovementType>(fields[48].Get<uint8>());
673 }
674 if (!fields[49].IsNull())
675 {
676 creatureTemplate.Movement.Random = static_cast<CreatureRandomMovementType>(fields[49].Get<uint8>());
677 }
678 if (!fields[50].IsNull())
679 {
680 creatureTemplate.Movement.InteractionPauseTimer = fields[50].Get<uint32>();
681 }
682
683 creatureTemplate.HoverHeight = fields[51].Get<float>();
684 creatureTemplate.ModHealth = fields[52].Get<float>();
685 creatureTemplate.ModMana = fields[53].Get<float>();
686 creatureTemplate.ModArmor = fields[54].Get<float>();
687 creatureTemplate.ModExperience = fields[55].Get<float>();
688 creatureTemplate.RacialLeader = fields[56].Get<bool>();
689 creatureTemplate.movementId = fields[57].Get<uint32>();
690 creatureTemplate.RegenHealth = fields[58].Get<bool>();
691 creatureTemplate.MechanicImmuneMask = fields[59].Get<uint32>();
692 creatureTemplate.SpellSchoolImmuneMask = fields[60].Get<uint8>();
693 creatureTemplate.flags_extra = fields[61].Get<uint32>();
694 creatureTemplate.ScriptID = GetScriptId(fields[62].Get<std::string>());
695
696 // useful if the creature template load is being triggered from outside this class
697 if (triggerHook)
698 {
699 sScriptMgr->OnAfterDatabaseLoadCreatureTemplates(_creatureTemplateStoreFast);
700 }
701}
#define sScriptMgr
Definition ScriptMgr.h:719
@ SPELL_SCHOOL_HOLY
Definition SharedDefines.h:295
uint32 Entry
Definition CreatureData.h:187

References _creatureTemplateStore, _creatureTemplateStoreFast, CreatureTemplate::Entry, Field::Get(), GetScriptId(), MAX_CREATURE_SPELLS, MAX_DIFFICULTY, MAX_KILL_CREDIT, MAX_SPELL_SCHOOL, SPELL_SCHOOL_HOLY, and sScriptMgr.

Referenced by LoadCreatureTemplates().

◆ LoadCreatureTemplateAddons()

void ObjectMgr::LoadCreatureTemplateAddons ( )
848{
849 uint32 oldMSTime = getMSTime();
850
851 // 0 1 2 3 4 5 6 7
852 QueryResult result = WorldDatabase.Query("SELECT entry, path_id, mount, bytes1, bytes2, emote, visibilityDistanceType, auras FROM creature_template_addon");
853
854 if (!result)
855 {
856 LOG_WARN("server.loading", ">> Loaded 0 creature template addon definitions. DB table `creature_template_addon` is empty.");
857 LOG_INFO("server.loading", " ");
858 return;
859 }
860
861 uint32 count = 0;
862 do
863 {
864 Field* fields = result->Fetch();
865
866 uint32 entry = fields[0].Get<uint32>();
867
868 if (!GetCreatureTemplate(entry))
869 {
870 LOG_ERROR("sql.sql", "Creature template (Entry: {}) does not exist but has a record in `creature_template_addon`", entry);
871 continue;
872 }
873
874 CreatureAddon& creatureAddon = _creatureTemplateAddonStore[entry];
875
876 creatureAddon.path_id = fields[1].Get<uint32>();
877 creatureAddon.mount = fields[2].Get<uint32>();
878 creatureAddon.bytes1 = fields[3].Get<uint32>();
879 creatureAddon.bytes2 = fields[4].Get<uint32>();
880 creatureAddon.emote = fields[5].Get<uint32>();
881 creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[6].Get<uint8>());
882
883 for (std::string_view aura : Acore::Tokenize(fields[7].Get<std::string_view>(), ' ', false))
884 {
885 SpellInfo const* spellInfo = nullptr;
886
887 if (Optional<uint32> spellId = Acore::StringTo<uint32>(aura))
888 {
889 spellInfo = sSpellMgr->GetSpellInfo(*spellId);
890 }
891
892 if (!spellInfo)
893 {
894 LOG_ERROR("sql.sql", "Creature (Entry: {}) has wrong spell '{}' defined in `auras` field in `creature_template_addon`.", entry, aura);
895 continue;
896 }
897
898 if (std::find(creatureAddon.auras.begin(), creatureAddon.auras.end(), spellInfo->Id) != creatureAddon.auras.end())
899 {
900 LOG_ERROR("sql.sql", "Creature (Entry: {}) has duplicate aura (spell {}) in `auras` field in `creature_template_addon`.", entry, spellInfo->Id);
901 continue;
902 }
903
904 if (spellInfo->GetDuration() > 0)
905 {
906 LOG_DEBUG/*ERROR*/("sql.sql", "Creature (Entry: {}) has temporary aura (spell {}) in `auras` field in `creature_template_addon`.", entry, spellInfo->Id);
907 // continue;
908 }
909
910 creatureAddon.auras.push_back(spellInfo->Id);
911 }
912
913 if (creatureAddon.mount)
914 {
915 if (!sCreatureDisplayInfoStore.LookupEntry(creatureAddon.mount))
916 {
917 LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid displayInfoId ({}) for mount defined in `creature_template_addon`", entry, creatureAddon.mount);
918 creatureAddon.mount = 0;
919 }
920 }
921
922 if (!sEmotesStore.LookupEntry(creatureAddon.emote))
923 {
924 LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid emote ({}) defined in `creature_addon`.", entry, creatureAddon.emote);
925 creatureAddon.emote = 0;
926 }
927
929 {
930 LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid visibilityDistanceType ({}) defined in `creature_template_addon`.", entry, AsUnderlyingType(creatureAddon.visibilityDistanceType));
932 }
933 ++count;
934 } while (result->NextRow());
935
936 LOG_INFO("server.loading", ">> Loaded {} Creature Template Addons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
937 LOG_INFO("server.loading", " ");
938}

References _creatureTemplateAddonStore, AsUnderlyingType(), CreatureAddon::auras, CreatureAddon::bytes1, CreatureAddon::bytes2, CreatureAddon::emote, Field::Get(), GetCreatureTemplate(), SpellInfo::GetDuration(), getMSTime(), GetMSTimeDiffToNow(), SpellInfo::Id, LOG_DEBUG, LOG_ERROR, LOG_INFO, LOG_WARN, Max, CreatureAddon::mount, Normal, CreatureAddon::path_id, sCreatureDisplayInfoStore, sEmotesStore, sSpellMgr, Acore::Tokenize(), CreatureAddon::visibilityDistanceType, and WorldDatabase.

◆ LoadCreatureTemplateModels()

void ObjectMgr::LoadCreatureTemplateModels ( )
704{
705 uint32 oldMSTime = getMSTime();
706
707 // 0 1 2 3
708 QueryResult result = WorldDatabase.Query("SELECT CreatureID, CreatureDisplayID, DisplayScale, Probability FROM creature_template_model ORDER BY Idx ASC");
709
710 if (!result)
711 {
712 LOG_INFO("server.loading", ">> Loaded 0 creature template model definitions. DB table `creature_template_model` is empty.");
713 return;
714 }
715
716 uint32 count = 0;
717 do
718 {
719 Field* fields = result->Fetch();
720
721 uint32 creatureId = fields[0].Get<uint32>();
722 uint32 creatureDisplayId = fields[1].Get<uint32>();
723 float displayScale = fields[2].Get<float>();
724 float probability = fields[3].Get<float>();
725
726 CreatureTemplate const* cInfo = GetCreatureTemplate(creatureId);
727 if (!cInfo)
728 {
729 LOG_ERROR("sql.sql", "Creature template (Entry: {}) does not exist but has a record in `creature_template_model`", creatureId);
730 continue;
731 }
732
733 CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(creatureDisplayId);
734 if (!displayEntry)
735 {
736 LOG_ERROR("sql.sql", "Creature (Entry: {}) lists non-existing CreatureDisplayID id ({}), this can crash the client.", creatureId, creatureDisplayId);
737 continue;
738 }
739
740 CreatureModelInfo const* modelInfo = GetCreatureModelInfo(creatureDisplayId);
741 if (!modelInfo)
742 LOG_ERROR("sql.sql", "No model data exist for `CreatureDisplayID` = {} listed by creature (Entry: {}).", creatureDisplayId, creatureId);
743
744 if (displayScale <= 0.0f)
745 displayScale = 1.0f;
746
747 const_cast<CreatureTemplate*>(cInfo)->Models.emplace_back(creatureDisplayId, displayScale, probability);
748
749 ++count;
750 } while (result->NextRow());
751
752 LOG_INFO("server.loading", ">> Loaded {} creature template models in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
753}

References Field::Get(), GetCreatureModelInfo(), GetCreatureTemplate(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, sCreatureDisplayInfoStore, and WorldDatabase.

Referenced by LoadCreatureTemplates().

◆ LoadCreatureTemplateResistances()

void ObjectMgr::LoadCreatureTemplateResistances ( )
756{
757 uint32 oldMSTime = getMSTime();
758
759 // 0 1 2
760 QueryResult result = WorldDatabase.Query("SELECT CreatureID, School, Resistance FROM creature_template_resistance");
761
762 if (!result)
763 {
764 LOG_WARN("server.loading", ">> Loaded 0 creature template resistance definitions. DB table `creature_template_resistance` is empty.");
765 LOG_INFO("server.loading", " ");
766 return;
767 }
768
769 uint32 count = 0;
770
771 do
772 {
773 Field* fields = result->Fetch();
774
775 uint32 creatureID = fields[0].Get<uint32>();
776 uint8 school = fields[1].Get<uint8>();
777
778 if (school == SPELL_SCHOOL_NORMAL || school >= MAX_SPELL_SCHOOL)
779 {
780 LOG_ERROR("sql.sql", "creature_template_resistance has resistance definitions for creature {} but this school {} doesn't exist", creatureID, school);
781 continue;
782 }
783
784 CreatureTemplateContainer::iterator itr = _creatureTemplateStore.find(creatureID);
785 if (itr == _creatureTemplateStore.end())
786 {
787 LOG_ERROR("sql.sql", "creature_template_resistance has resistance definitions for creature {} but this creature doesn't exist", creatureID);
788 continue;
789 }
790
791 CreatureTemplate& creatureTemplate = itr->second;
792 creatureTemplate.resistance[school] = fields[2].Get<int16>();
793
794 ++count;
795 } while (result->NextRow());
796
797 LOG_INFO("server.loading", ">> Loaded {} Creature Template Resistances in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
798 LOG_INFO("server.loading", " ");
799}
int32 resistance[MAX_SPELL_SCHOOL]
Definition CreatureData.h:223

References _creatureTemplateStore, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, MAX_SPELL_SCHOOL, CreatureTemplate::resistance, SPELL_SCHOOL_NORMAL, and WorldDatabase.

Referenced by LoadCreatureTemplates().

◆ LoadCreatureTemplates()

void ObjectMgr::LoadCreatureTemplates ( )
521{
522 uint32 oldMSTime = getMSTime();
523
524// 0 1 2 3 4 5 6 7 8
525 QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, name, subname, IconName, "
526// 9 10 11 12 13 14 15 16 17 18 19 20 21 22
527 "gossip_menu_id, minlevel, maxlevel, exp, faction, npcflag, speed_walk, speed_run, speed_swim, speed_flight, detection_range, scale, `rank`, dmgschool, "
528// 23 24 25 26 27 28 29 30 31 32
529 "DamageModifier, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, dynamicflags, family, "
530// 33 34 35 36 37
531 "type, type_flags, lootid, pickpocketloot, skinloot, "
532// 38 39 40 41 42 43 44 45 46 47
533 "PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, ctm.Ground, ctm.Swim, ctm.Flight, ctm.Rooted, "
534// 48 49 50 51 52 53 54 55 56 57 58 59
535 "ctm.Chase, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, ManaModifier, ArmorModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, "
536// 60 61 62
537 "spell_school_immune_mask, flags_extra, ScriptName "
538 "FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId ORDER BY entry DESC;");
539
540 if (!result)
541 {
542 LOG_WARN("server.loading", ">> Loaded 0 creature template definitions. DB table `creature_template` is empty.");
543 return;
544 }
545
546 _creatureTemplateStore.rehash(result->GetRowCount());
548
549 uint32 count = 0;
550 do
551 {
552 Field* fields = result->Fetch();
553 LoadCreatureTemplate(fields);
554 ++count;
555 } while (result->NextRow());
556
557 // We load the creature models after loading but before checking
559
560 sScriptMgr->OnAfterDatabaseLoadCreatureTemplates(_creatureTemplateStoreFast);
561
564
565 // Checking needs to be done after loading because of the difficulty self referencing
566 for (CreatureTemplateContainer::iterator itr = _creatureTemplateStore.begin(); itr != _creatureTemplateStore.end(); ++itr)
567 {
568 CheckCreatureTemplate(&itr->second);
569 itr->second.InitializeQueryData();
570 }
571
572 LOG_INFO("server.loading", ">> Loaded {} Creature Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
573 LOG_INFO("server.loading", " ");
574}
void LoadCreatureTemplateResistances()
Definition ObjectMgr.cpp:755
void LoadCreatureTemplateSpells()
Definition ObjectMgr.cpp:801
void CheckCreatureTemplate(CreatureTemplate const *cInfo)
Definition ObjectMgr.cpp:955
void LoadCreatureTemplate(Field *fields, bool triggerHook=false)
Loads a creature template from a database result.
Definition ObjectMgr.cpp:582
void LoadCreatureTemplateModels()
Definition ObjectMgr.cpp:703

References _creatureTemplateStore, _creatureTemplateStoreFast, CheckCreatureTemplate(), getMSTime(), GetMSTimeDiffToNow(), LoadCreatureTemplate(), LoadCreatureTemplateModels(), LoadCreatureTemplateResistances(), LoadCreatureTemplateSpells(), LOG_INFO, LOG_WARN, sScriptMgr, and WorldDatabase.

◆ LoadCreatureTemplateSpells()

void ObjectMgr::LoadCreatureTemplateSpells ( )
802{
803 uint32 oldMSTime = getMSTime();
804
805 // 0 1 2
806 QueryResult result = WorldDatabase.Query("SELECT CreatureID, `Index`, Spell FROM creature_template_spell");
807
808 if (!result)
809 {
810 LOG_WARN("server.loading", ">> Loaded 0 creature template spell definitions. DB table `creature_template_spell` is empty.");
811 LOG_INFO("server.loading", " ");
812 return;
813 }
814
815 uint32 count = 0;
816
817 do
818 {
819 Field* fields = result->Fetch();
820
821 uint32 creatureID = fields[0].Get<uint32>();
822 uint8 index = fields[1].Get<uint8>();
823
824 if (index >= MAX_CREATURE_SPELLS)
825 {
826 LOG_ERROR("sql.sql", "creature_template_spell has spell definitions for creature {} with a incorrect index {}", creatureID, index);
827 continue;
828 }
829
830 CreatureTemplateContainer::iterator itr = _creatureTemplateStore.find(creatureID);
831 if (itr == _creatureTemplateStore.end())
832 {
833 LOG_ERROR("sql.sql", "creature_template_spell has spell definitions for creature {} but this creature doesn't exist", creatureID);
834 continue;
835 }
836
837 CreatureTemplate& creatureTemplate = itr->second;
838 creatureTemplate.spells[index] = fields[2].Get<uint32>();
839
840 ++count;
841 } while (result->NextRow());
842
843 LOG_INFO("server.loading", ">> Loaded {} Creature Template Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
844 LOG_INFO("server.loading", " ");
845}
uint32 spells[MAX_CREATURE_SPELLS]
Definition CreatureData.h:224

References _creatureTemplateStore, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, MAX_CREATURE_SPELLS, CreatureTemplate::spells, and WorldDatabase.

Referenced by LoadCreatureTemplates().

◆ LoadEquipmentTemplates()

void ObjectMgr::LoadEquipmentTemplates ( )
1472{
1473 uint32 oldMSTime = getMSTime();
1474
1475 // 0 1 2 3 4
1476 QueryResult result = WorldDatabase.Query("SELECT CreatureID, ID, ItemID1, ItemID2, ItemID3 FROM creature_equip_template");
1477
1478 if (!result)
1479 {
1480 LOG_WARN("server.loading", ">> Loaded 0 creature equipment templates. DB table `creature_equip_template` is empty!");
1481 LOG_INFO("server.loading", " ");
1482 return;
1483 }
1484
1485 uint32 count = 0;
1486 do
1487 {
1488 Field* fields = result->Fetch();
1489
1490 uint32 entry = fields[0].Get<uint32>();
1491
1492 if (!GetCreatureTemplate(entry))
1493 {
1494 LOG_ERROR("sql.sql", "Creature template (CreatureID: {}) does not exist but has a record in `creature_equip_template`", entry);
1495 continue;
1496 }
1497
1498 uint8 id = fields[1].Get<uint8>();
1499 if (!id)
1500 {
1501 LOG_ERROR("sql.sql", "Creature equipment template with id 0 found for creature {}, skipped.", entry);
1502 continue;
1503 }
1504
1505 EquipmentInfo& equipmentInfo = _equipmentInfoStore[entry][id];
1506
1507 equipmentInfo.ItemEntry[0] = fields[2].Get<uint32>();
1508 equipmentInfo.ItemEntry[1] = fields[3].Get<uint32>();
1509 equipmentInfo.ItemEntry[2] = fields[4].Get<uint32>();
1510
1511 for (uint8 i = 0; i < MAX_EQUIPMENT_ITEMS; ++i)
1512 {
1513 if (!equipmentInfo.ItemEntry[i])
1514 continue;
1515
1516 ItemEntry const* dbcItem = sItemStore.LookupEntry(equipmentInfo.ItemEntry[i]);
1517
1518 if (!dbcItem)
1519 {
1520 LOG_ERROR("sql.sql", "Unknown item (ID={}) in creature_equip_template.ItemID{} for CreatureID = {} and ID = {}, forced to 0.",
1521 equipmentInfo.ItemEntry[i], i + 1, entry, id);
1522 equipmentInfo.ItemEntry[i] = 0;
1523 continue;
1524 }
1525
1526 if (dbcItem->InventoryType != INVTYPE_WEAPON &&
1527 dbcItem->InventoryType != INVTYPE_SHIELD &&
1528 dbcItem->InventoryType != INVTYPE_RANGED &&
1529 dbcItem->InventoryType != INVTYPE_2HWEAPON &&
1532 dbcItem->InventoryType != INVTYPE_HOLDABLE &&
1533 dbcItem->InventoryType != INVTYPE_THROWN &&
1535 {
1536 LOG_ERROR("sql.sql", "Item (ID={}) in creature_equip_template.ItemID{} for CreatureID = {} and ID = {} is not equipable in a hand, forced to 0.",
1537 equipmentInfo.ItemEntry[i], i + 1, entry, id);
1538 equipmentInfo.ItemEntry[i] = 0;
1539 }
1540 }
1541
1542 ++count;
1543 } while (result->NextRow());
1544
1545 LOG_INFO("server.loading", ">> Loaded {} Equipment Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1546 LOG_INFO("server.loading", " ");
1547}
#define MAX_EQUIPMENT_ITEMS
Definition CreatureData.h:35
@ INVTYPE_HOLDABLE
Definition ItemTemplate.h:279
@ INVTYPE_RANGED
Definition ItemTemplate.h:271
@ INVTYPE_THROWN
Definition ItemTemplate.h:281
@ INVTYPE_RANGEDRIGHT
Definition ItemTemplate.h:282
@ INVTYPE_WEAPON
Definition ItemTemplate.h:269
@ INVTYPE_WEAPONMAINHAND
Definition ItemTemplate.h:277
@ INVTYPE_WEAPONOFFHAND
Definition ItemTemplate.h:278
@ INVTYPE_2HWEAPON
Definition ItemTemplate.h:273
@ INVTYPE_SHIELD
Definition ItemTemplate.h:270
Definition CreatureData.h:356
uint32 ItemEntry[MAX_EQUIPMENT_ITEMS]
Definition CreatureData.h:357
uint32 InventoryType
Definition DBCStructure.h:1150

References _equipmentInfoStore, Field::Get(), GetCreatureTemplate(), getMSTime(), GetMSTimeDiffToNow(), ItemEntry::InventoryType, INVTYPE_2HWEAPON, INVTYPE_HOLDABLE, INVTYPE_RANGED, INVTYPE_RANGEDRIGHT, INVTYPE_SHIELD, INVTYPE_THROWN, INVTYPE_WEAPON, INVTYPE_WEAPONMAINHAND, INVTYPE_WEAPONOFFHAND, EquipmentInfo::ItemEntry, LOG_ERROR, LOG_INFO, LOG_WARN, MAX_EQUIPMENT_ITEMS, sItemStore, and WorldDatabase.

◆ LoadEventScripts()

void ObjectMgr::LoadEventScripts ( )
6084{
6086
6087 std::set<uint32> evt_scripts;
6088 // Load all possible script entries from gameobjects
6090 for (GameObjectTemplateContainer::const_iterator itr = gotc->begin(); itr != gotc->end(); ++itr)
6091 if (uint32 eventId = itr->second.GetEventScriptId())
6092 evt_scripts.insert(eventId);
6093
6094 // Load all possible script entries from spells
6095 for (uint32 i = 1; i < sSpellMgr->GetSpellInfoStoreSize(); ++i)
6096 if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(i))
6097 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
6098 if (spell->Effects[j].Effect == SPELL_EFFECT_SEND_EVENT)
6099 if (spell->Effects[j].MiscValue)
6100 evt_scripts.insert(spell->Effects[j].MiscValue);
6101
6102 for (std::size_t path_idx = 0; path_idx < sTaxiPathNodesByPath.size(); ++path_idx)
6103 {
6104 for (std::size_t node_idx = 0; node_idx < sTaxiPathNodesByPath[path_idx].size(); ++node_idx)
6105 {
6106 TaxiPathNodeEntry const* node = sTaxiPathNodesByPath[path_idx][node_idx];
6107
6108 if (node->arrivalEventID)
6109 evt_scripts.insert(node->arrivalEventID);
6110
6111 if (node->departureEventID)
6112 evt_scripts.insert(node->departureEventID);
6113 }
6114 }
6115
6116 // Then check if all scripts are in above list of possible script entries
6117 for (ScriptMapMap::const_iterator itr = sEventScripts.begin(); itr != sEventScripts.end(); ++itr)
6118 {
6119 std::set<uint32>::const_iterator itr2 = evt_scripts.find(itr->first);
6120 if (itr2 == evt_scripts.end())
6121 LOG_ERROR("sql.sql", "Table `event_scripts` has script (Id: {}) not referring to any gameobject_template type 10 data2 field, type 3 data6 field, type 13 data 2 field or any spell effect {}",
6122 itr->first, SPELL_EFFECT_SEND_EVENT);
6123 }
6124}
TaxiPathNodesByPath sTaxiPathNodesByPath
Definition DBCStores.cpp:187
#define MAX_SPELL_EFFECTS
Definition DBCStructure.h:1637
std::unordered_map< uint32, GameObjectTemplate > GameObjectTemplateContainer
Definition GameObject.h:42
ScriptMapMap sEventScripts
Definition ObjectMgr.cpp:60
@ SCRIPTS_EVENT
Definition ObjectMgr.h:150
@ SPELL_EFFECT_SEND_EVENT
Definition SharedDefines.h:850
GameObjectTemplateContainer const * GetGameObjectTemplates() const
Definition ObjectMgr.h:761
void LoadScripts(ScriptsType type)
Definition ObjectMgr.cpp:5741
Definition DBCStructure.h:1973
uint32 arrivalEventID
Definition DBCStructure.h:1983
uint32 departureEventID
Definition DBCStructure.h:1984

References TaxiPathNodeEntry::arrivalEventID, TaxiPathNodeEntry::departureEventID, GetGameObjectTemplates(), LoadScripts(), LOG_ERROR, MAX_SPELL_EFFECTS, SCRIPTS_EVENT, sEventScripts, SPELL_EFFECT_SEND_EVENT, sSpellMgr, and sTaxiPathNodesByPath.

◆ LoadExplorationBaseXP()

void ObjectMgr::LoadExplorationBaseXP ( )
7965{
7966 uint32 oldMSTime = getMSTime();
7967
7968 QueryResult result = WorldDatabase.Query("SELECT level, basexp FROM exploration_basexp");
7969
7970 if (!result)
7971 {
7972 LOG_WARN("server.loading", ">> Loaded 0 BaseXP definitions. DB table `exploration_basexp` is empty.");
7973 LOG_INFO("server.loading", " ");
7974 return;
7975 }
7976
7977 uint32 count = 0;
7978
7979 do
7980 {
7981 Field* fields = result->Fetch();
7982 uint8 level = fields[0].Get<uint8>();
7983 uint32 basexp = fields[1].Get<int32>();
7984 _baseXPTable[level] = basexp;
7985 ++count;
7986 } while (result->NextRow());
7987
7988 LOG_INFO("server.loading", ">> Loaded {} BaseXP Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7989 LOG_INFO("server.loading", " ");
7990}
std::int32_t int32
Definition Define.h:103

References _baseXPTable, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadFactionChangeAchievements()

void ObjectMgr::LoadFactionChangeAchievements ( )
10434{
10435 uint32 oldMSTime = getMSTime();
10436
10437 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_achievement");
10438
10439 if (!result)
10440 {
10441 LOG_WARN("server.loading", ">> Loaded 0 faction change achievement pairs. DB table `player_factionchange_achievement` is empty.");
10442 LOG_INFO("server.loading", " ");
10443 return;
10444 }
10445
10446 uint32 count = 0;
10447
10448 do
10449 {
10450 Field* fields = result->Fetch();
10451
10452 uint32 alliance = fields[0].Get<uint32>();
10453 uint32 horde = fields[1].Get<uint32>();
10454
10455 if (!sAchievementStore.LookupEntry(alliance))
10456 LOG_ERROR("sql.sql", "Achievement {} (alliance_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", alliance);
10457 else if (!sAchievementStore.LookupEntry(horde))
10458 LOG_ERROR("sql.sql", "Achievement {} (horde_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", horde);
10459 else
10460 FactionChangeAchievements[alliance] = horde;
10461
10462 ++count;
10463 } while (result->NextRow());
10464
10465 LOG_INFO("server.loading", ">> Loaded {} faction change achievement pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10466 LOG_INFO("server.loading", " ");
10467}
CharacterConversionMap FactionChangeAchievements
Definition ObjectMgr.h:1467

References FactionChangeAchievements, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, sAchievementStore, and WorldDatabase.

◆ LoadFactionChangeItems()

void ObjectMgr::LoadFactionChangeItems ( )
10470{
10471 uint32 oldMSTime = getMSTime();
10472
10473 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_items");
10474
10475 if (!result)
10476 {
10477 LOG_WARN("server.loading", ">> Loaded 0 faction change item pairs. DB table `player_factionchange_items` is empty.");
10478 LOG_INFO("server.loading", " ");
10479 return;
10480 }
10481
10482 uint32 count = 0;
10483
10484 do
10485 {
10486 Field* fields = result->Fetch();
10487
10488 uint32 alliance = fields[0].Get<uint32>();
10489 uint32 horde = fields[1].Get<uint32>();
10490
10491 if (!GetItemTemplate(alliance))
10492 LOG_ERROR("sql.sql", "Item {} (alliance_id) referenced in `player_factionchange_items` does not exist, pair skipped!", alliance);
10493 else if (!GetItemTemplate(horde))
10494 LOG_ERROR("sql.sql", "Item {} (horde_id) referenced in `player_factionchange_items` does not exist, pair skipped!", horde);
10495 else
10496 FactionChangeItems[alliance] = horde;
10497
10498 ++count;
10499 } while (result->NextRow());
10500
10501 LOG_INFO("server.loading", ">> Loaded {} faction change item pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10502 LOG_INFO("server.loading", " ");
10503}
CharacterConversionMap FactionChangeItems
Definition ObjectMgr.h:1468

References FactionChangeItems, Field::Get(), GetItemTemplate(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadFactionChangeQuests()

void ObjectMgr::LoadFactionChangeQuests ( )
10506{
10507 uint32 oldMSTime = getMSTime();
10508
10509 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_quests");
10510
10511 if (!result)
10512 {
10513 LOG_WARN("server.loading", ">> Loaded 0 faction change quest pairs. DB table `player_factionchange_quests` is empty.");
10514 LOG_INFO("server.loading", " ");
10515 return;
10516 }
10517
10518 uint32 count = 0;
10519
10520 do
10521 {
10522 Field* fields = result->Fetch();
10523
10524 uint32 alliance = fields[0].Get<uint32>();
10525 uint32 horde = fields[1].Get<uint32>();
10526
10527 if (!GetQuestTemplate(alliance))
10528 LOG_ERROR("sql.sql", "Quest {} (alliance_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", alliance);
10529 else if (!GetQuestTemplate(horde))
10530 LOG_ERROR("sql.sql", "Quest {} (horde_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", horde);
10531 else
10532 FactionChangeQuests[alliance] = horde;
10533
10534 ++count;
10535 } while (result->NextRow());
10536
10537 LOG_INFO("server.loading", ">> Loaded {} faction change quest pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10538 LOG_INFO("server.loading", " ");
10539}
CharacterConversionMap FactionChangeQuests
Definition ObjectMgr.h:1469

References FactionChangeQuests, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), GetQuestTemplate(), LOG_ERROR, LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadFactionChangeReputations()

void ObjectMgr::LoadFactionChangeReputations ( )
10542{
10543 uint32 oldMSTime = getMSTime();
10544
10545 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_reputations");
10546
10547 if (!result)
10548 {
10549 LOG_WARN("server.loading", ">> Loaded 0 faction change reputation pairs. DB table `player_factionchange_reputations` is empty.");
10550 LOG_INFO("server.loading", " ");
10551 return;
10552 }
10553
10554 uint32 count = 0;
10555
10556 do
10557 {
10558 Field* fields = result->Fetch();
10559
10560 uint32 alliance = fields[0].Get<uint32>();
10561 uint32 horde = fields[1].Get<uint32>();
10562
10563 if (!sFactionStore.LookupEntry(alliance))
10564 LOG_ERROR("sql.sql", "Reputation {} (alliance_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", alliance);
10565 else if (!sFactionStore.LookupEntry(horde))
10566 LOG_ERROR("sql.sql", "Reputation {} (horde_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", horde);
10567 else
10568 FactionChangeReputation[alliance] = horde;
10569
10570 ++count;
10571 } while (result->NextRow());
10572
10573 LOG_INFO("server.loading", ">> Loaded {} faction change reputation pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10574 LOG_INFO("server.loading", " ");
10575}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
CharacterConversionMap FactionChangeReputation
Definition ObjectMgr.h:1470

References FactionChangeReputation, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, sFactionStore, and WorldDatabase.

◆ LoadFactionChangeSpells()

void ObjectMgr::LoadFactionChangeSpells ( )
10578{
10579 uint32 oldMSTime = getMSTime();
10580
10581 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_spells");
10582
10583 if (!result)
10584 {
10585 LOG_WARN("server.loading", ">> Loaded 0 faction change spell pairs. DB table `player_factionchange_spells` is empty.");
10586 LOG_INFO("server.loading", " ");
10587 return;
10588 }
10589
10590 uint32 count = 0;
10591
10592 do
10593 {
10594 Field* fields = result->Fetch();
10595
10596 uint32 alliance = fields[0].Get<uint32>();
10597 uint32 horde = fields[1].Get<uint32>();
10598
10599 if (!sSpellMgr->GetSpellInfo(alliance))
10600 LOG_ERROR("sql.sql", "Spell {} (alliance_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", alliance);
10601 else if (!sSpellMgr->GetSpellInfo(horde))
10602 LOG_ERROR("sql.sql", "Spell {} (horde_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", horde);
10603 else
10604 FactionChangeSpells[alliance] = horde;
10605
10606 ++count;
10607 } while (result->NextRow());
10608
10609 LOG_INFO("server.loading", ">> Loaded {} faction change spell pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10610 LOG_INFO("server.loading", " ");
10611}
CharacterConversionMap FactionChangeSpells
Definition ObjectMgr.h:1471

References FactionChangeSpells, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, sSpellMgr, and WorldDatabase.

◆ LoadFactionChangeTitles()

void ObjectMgr::LoadFactionChangeTitles ( )
10614{
10615 uint32 oldMSTime = getMSTime();
10616
10617 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_titles");
10618
10619 if (!result)
10620 {
10621 LOG_WARN("server.loading", ">> Loaded 0 faction change title pairs. DB table `player_factionchange_title` is empty.");
10622 return;
10623 }
10624
10625 uint32 count = 0;
10626
10627 do
10628 {
10629 Field* fields = result->Fetch();
10630
10631 uint32 alliance = fields[0].Get<uint32>();
10632 uint32 horde = fields[1].Get<uint32>();
10633
10634 if (!sCharTitlesStore.LookupEntry(alliance))
10635 LOG_ERROR("sql.sql", "Title {} (alliance_id) referenced in `player_factionchange_title` does not exist, pair skipped!", alliance);
10636 else if (!sCharTitlesStore.LookupEntry(horde))
10637 LOG_ERROR("sql.sql", "Title {} (horde_id) referenced in `player_factionchange_title` does not exist, pair skipped!", horde);
10638 else
10639 FactionChangeTitles[alliance] = horde;
10640
10641 ++count;
10642 } while (result->NextRow());
10643
10644 LOG_INFO("server.loading", ">> Loaded {} faction change title pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10645 LOG_INFO("server.loading", " ");
10646}
DBCStorage< CharTitlesEntry > sCharTitlesStore(CharTitlesEntryfmt)
CharacterConversionMap FactionChangeTitles
Definition ObjectMgr.h:1472

References FactionChangeTitles, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, sCharTitlesStore, and WorldDatabase.

◆ LoadFishingBaseSkillLevel()

void ObjectMgr::LoadFishingBaseSkillLevel ( )
9287{
9288 uint32 oldMSTime = getMSTime();
9289
9290 _fishingBaseForAreaStore.clear(); // for reload case
9291
9292 QueryResult result = WorldDatabase.Query("SELECT entry, skill FROM skill_fishing_base_level");
9293
9294 if (!result)
9295 {
9296 LOG_WARN("server.loading", ">> Loaded 0 areas for fishing base skill level. DB table `skill_fishing_base_level` is empty.");
9297 LOG_INFO("server.loading", " ");
9298 return;
9299 }
9300
9301 uint32 count = 0;
9302
9303 do
9304 {
9305 Field* fields = result->Fetch();
9306 uint32 entry = fields[0].Get<uint32>();
9307 int32 skill = fields[1].Get<int16>();
9308
9309 AreaTableEntry const* fArea = sAreaTableStore.LookupEntry(entry);
9310 if (!fArea)
9311 {
9312 LOG_ERROR("sql.sql", "AreaId {} defined in `skill_fishing_base_level` does not exist", entry);
9313 continue;
9314 }
9315
9316 _fishingBaseForAreaStore[entry] = skill;
9317 ++count;
9318 } while (result->NextRow());
9319
9320 LOG_INFO("server.loading", ">> Loaded {} areas for fishing base skill level in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9321 LOG_INFO("server.loading", " ");
9322}

References _fishingBaseForAreaStore, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, sAreaTableStore, and WorldDatabase.

◆ LoadGameObjectAddons()

void ObjectMgr::LoadGameObjectAddons ( )
1355{
1356 uint32 oldMSTime = getMSTime();
1357
1358 // 0 1 2 3 4 5 6
1359 QueryResult result = WorldDatabase.Query("SELECT guid, parent_rotation0, parent_rotation1, parent_rotation2, parent_rotation3, invisibilityType, invisibilityValue FROM gameobject_addon");
1360
1361 if (!result)
1362 {
1363 LOG_WARN("server.loading", ">> Loaded 0 gameobject addon definitions. DB table `gameobject_addon` is empty.");
1364 LOG_INFO("server.loading", " ");
1365 return;
1366 }
1367
1368 uint32 count = 0;
1369 do
1370 {
1371 Field* fields = result->Fetch();
1372
1373 ObjectGuid::LowType guid = fields[0].Get<uint32>();
1374
1375 const GameObjectData* goData = GetGameObjectData(guid);
1376 if (!goData)
1377 {
1378 LOG_ERROR("sql.sql", "GameObject (GUID: {}) does not exist but has a record in `gameobject_addon`", guid);
1379 continue;
1380 }
1381
1382 GameObjectAddon& gameObjectAddon = _gameObjectAddonStore[guid];
1383 gameObjectAddon.ParentRotation = QuaternionData(fields[1].Get<float>(), fields[2].Get<float>(), fields[3].Get<float>(), fields[4].Get<float>());
1384 gameObjectAddon.invisibilityType = InvisibilityType(fields[5].Get<uint8>());
1385 gameObjectAddon.InvisibilityValue = fields[6].Get<uint32>();
1386
1387 if (gameObjectAddon.invisibilityType >= TOTAL_INVISIBILITY_TYPES)
1388 {
1389 LOG_ERROR("sql.sql", "GameObject (GUID: {}) has invalid InvisibilityType in `gameobject_addon`", guid);
1390 gameObjectAddon.invisibilityType = INVISIBILITY_GENERAL;
1391 gameObjectAddon.InvisibilityValue = 0;
1392 }
1393
1394 if (gameObjectAddon.invisibilityType && !gameObjectAddon.InvisibilityValue)
1395 {
1396 LOG_ERROR("sql.sql", "GameObject (GUID: {}) has InvisibilityType set but has no InvisibilityValue in `gameobject_addon`, set to 1", guid);
1397 gameObjectAddon.InvisibilityValue = 1;
1398 }
1399
1400 if (!gameObjectAddon.ParentRotation.IsUnit())
1401 {
1402 LOG_ERROR("sql.sql", "GameObject (GUID: {}) has invalid parent rotation in `gameobject_addon`, set to default", guid);
1403 gameObjectAddon.ParentRotation = QuaternionData();
1404 }
1405
1406 ++count;
1407 } while (result->NextRow());
1408
1409 LOG_INFO("server.loading", ">> Loaded {} Gameobject Addons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1410 LOG_INFO("server.loading", " ");
1411}
InvisibilityType
Definition SharedDefines.h:1265
@ TOTAL_INVISIBILITY_TYPES
Definition SharedDefines.h:1279
@ INVISIBILITY_GENERAL
Definition SharedDefines.h:1266
Definition GameObjectData.h:696
QuaternionData ParentRotation
Definition GameObjectData.h:697
uint32 InvisibilityValue
Definition GameObjectData.h:699
InvisibilityType invisibilityType
Definition GameObjectData.h:698
Definition GameObjectData.h:682
bool IsUnit() const
Definition GameObject.cpp:41

References _gameObjectAddonStore, Field::Get(), GetGameObjectData(), getMSTime(), GetMSTimeDiffToNow(), INVISIBILITY_GENERAL, GameObjectAddon::invisibilityType, GameObjectAddon::InvisibilityValue, QuaternionData::IsUnit(), LOG_ERROR, LOG_INFO, LOG_WARN, GameObjectAddon::ParentRotation, TOTAL_INVISIBILITY_TYPES, and WorldDatabase.

◆ LoadGameObjectDataFromDB()

GameObjectData const * ObjectMgr::LoadGameObjectDataFromDB ( ObjectGuid::LowType  spawnId)

Loads a single gameobject spawn entry from the database into the data store cache.

This is needed as a prerequisite for GameObject::LoadGameObjectFromDB(), which reads from the in-memory cache (via GetGameObjectData()) rather than querying the DB itself. For spawns not loaded during server startup, this method populates the cache so that GameObject::LoadGameObjectFromDB() can then create the live entity.

Returns the cached data if already loaded, or nullptr if the spawn doesn't exist or fails validation.

Parameters
spawnIdThe gameobject spawn GUID to load.
Returns
Pointer to the cached GameObjectData, or nullptr on failure.
2936{
2937 GameObjectData const* data = GetGameObjectData(spawnId);
2938 if (data)
2939 return data;
2940
2941 QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
2942 "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, "
2943 "ScriptName "
2944 "FROM gameobject WHERE gameobject.guid = {}", spawnId);
2945
2946 if (!result)
2947 return nullptr;
2948
2949 Field* fields = result->Fetch();
2950 uint32 entry = fields[1].Get<uint32>();
2951
2952 GameObjectTemplate const* gInfo = GetGameObjectTemplate(entry);
2953 if (!gInfo)
2954 {
2955 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {}) with non-existing gameobject entry {}, skipped.", spawnId, entry);
2956 return nullptr;
2957 }
2958
2959 if (gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId))
2960 {
2961 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry {} GoType: {}) with an invalid displayId ({}), not loaded.",
2962 spawnId, entry, gInfo->type, gInfo->displayId);
2963 return nullptr;
2964 }
2965
2966 GameObjectData& goData = _gameObjectDataStore[spawnId];
2967 goData.id = entry;
2968 goData.mapid = fields[2].Get<uint16>();
2969 goData.posX = fields[3].Get<float>();
2970 goData.posY = fields[4].Get<float>();
2971 goData.posZ = fields[5].Get<float>();
2972 goData.orientation = fields[6].Get<float>();
2973 goData.rotation.x = fields[7].Get<float>();
2974 goData.rotation.y = fields[8].Get<float>();
2975 goData.rotation.z = fields[9].Get<float>();
2976 goData.rotation.w = fields[10].Get<float>();
2977 goData.spawntimesecs = fields[11].Get<int32>();
2978 goData.animprogress = fields[12].Get<uint8>();
2979 goData.artKit = 0;
2980 goData.ScriptId = GetScriptId(fields[16].Get<std::string>());
2981
2982 if (!goData.ScriptId)
2983 goData.ScriptId = gInfo->ScriptId;
2984
2985 MapEntry const* mapEntry = sMapStore.LookupEntry(goData.mapid);
2986 if (!mapEntry)
2987 {
2988 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) spawned on a non-existing map (Id: {}), skipped.", spawnId, entry, goData.mapid);
2989 _gameObjectDataStore.erase(spawnId);
2990 return nullptr;
2991 }
2992
2993 if (goData.spawntimesecs == 0 && gInfo->IsDespawnAtAction())
2994 {
2995 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with `spawntimesecs` (0) value, but the gameobject is marked as despawnable at action.", spawnId, entry);
2996 }
2997
2998 uint32 go_state = fields[13].Get<uint8>();
2999 if (go_state >= MAX_GO_STATE)
3000 {
3001 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid `state` ({}) value, skipped.", spawnId, entry, go_state);
3002 _gameObjectDataStore.erase(spawnId);
3003 return nullptr;
3004 }
3005 goData.go_state = GOState(go_state);
3006
3007 goData.spawnMask = fields[14].Get<uint8>();
3008 goData.phaseMask = fields[15].Get<uint32>();
3009
3010 if (goData.rotation.x < -1.0f || goData.rotation.x > 1.0f)
3011 {
3012 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationX ({}) value, skipped.", spawnId, entry, goData.rotation.x);
3013 _gameObjectDataStore.erase(spawnId);
3014 return nullptr;
3015 }
3016
3017 if (goData.rotation.y < -1.0f || goData.rotation.y > 1.0f)
3018 {
3019 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationY ({}) value, skipped.", spawnId, entry, goData.rotation.y);
3020 _gameObjectDataStore.erase(spawnId);
3021 return nullptr;
3022 }
3023
3024 if (goData.rotation.z < -1.0f || goData.rotation.z > 1.0f)
3025 {
3026 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationZ ({}) value, skipped.", spawnId, entry, goData.rotation.z);
3027 _gameObjectDataStore.erase(spawnId);
3028 return nullptr;
3029 }
3030
3031 if (goData.rotation.w < -1.0f || goData.rotation.w > 1.0f)
3032 {
3033 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationW ({}) value, skipped.", spawnId, entry, goData.rotation.w);
3034 _gameObjectDataStore.erase(spawnId);
3035 return nullptr;
3036 }
3037
3038 if (fabs(goData.rotation.x * goData.rotation.x + goData.rotation.y * goData.rotation.y +
3039 goData.rotation.z * goData.rotation.z + goData.rotation.w * goData.rotation.w - 1.0f) >= 1e-5f)
3040 {
3041 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotation quaternion (non-unit), defaulting to orientation on Z axis only", spawnId, entry);
3042 goData.rotation = G3D::Quat(G3D::Matrix3::fromEulerAnglesZYX(goData.orientation, 0.0f, 0.0f));
3043 }
3044
3045 if (!MapMgr::IsValidMapCoord(goData.mapid, goData.posX, goData.posY, goData.posZ, goData.orientation))
3046 {
3047 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid coordinates, skipped.", spawnId, entry);
3048 _gameObjectDataStore.erase(spawnId);
3049 return nullptr;
3050 }
3051
3052 if (goData.phaseMask == 0)
3053 {
3054 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with `phaseMask`=0 (not visible for anyone), set to 1.", spawnId, entry);
3055 goData.phaseMask = 1;
3056 }
3057
3058 return &goData;
3059}
DBCStorage< GameObjectDisplayInfoEntry > sGameObjectDisplayInfoStore(GameObjectDisplayInfofmt)
#define MAX_GO_STATE
Definition GameObjectData.h:27
GOState
Definition GameObjectData.h:704
static bool IsValidMapCoord(uint32 mapid, Position const &pos)
Definition MapMgr.h:90
uint32 ScriptId
Definition GameObjectData.h:723

References _gameObjectDataStore, GameObjectData::animprogress, GameObjectData::artKit, Field::Get(), GetGameObjectData(), GetGameObjectTemplate(), GetScriptId(), GameObjectData::go_state, GameObjectData::id, MapMgr::IsValidMapCoord(), LOG_ERROR, GameObjectData::mapid, MAX_GO_STATE, GameObjectData::orientation, GameObjectData::phaseMask, GameObjectData::posX, GameObjectData::posY, GameObjectData::posZ, GameObjectData::rotation, GameObjectData::ScriptId, sGameObjectDisplayInfoStore, sMapStore, GameObjectData::spawnMask, GameObjectData::spawntimesecs, and WorldDatabase.

◆ LoadGameObjectForQuests()

void ObjectMgr::LoadGameObjectForQuests ( )
9073{
9074 uint32 oldMSTime = getMSTime();
9075
9076 if (GetGameObjectTemplates()->empty())
9077 {
9078 LOG_WARN("server.loading", ">> Loaded 0 GameObjects for quests");
9079 LOG_INFO("server.loading", " ");
9080 return;
9081 }
9082
9083 uint32 count = 0;
9084
9085 // collect GO entries for GO that must activated
9087 for (GameObjectTemplateContainer::iterator itr = gotc->begin(); itr != gotc->end(); ++itr)
9088 {
9089 itr->second.IsForQuests = false;
9090 switch (itr->second.type)
9091 {
9093 itr->second.IsForQuests = true;
9094 ++count;
9095 break;
9097 {
9098 // scan GO chest with loot including quest items
9099 uint32 loot_id = (itr->second.GetLootId());
9100
9101 // find quest loot for GO
9102 if (itr->second.chest.questId || LootTemplates_Gameobject.HaveQuestLootFor(loot_id))
9103 {
9104 itr->second.IsForQuests = true;
9105 ++count;
9106 }
9107 break;
9108 }
9110 {
9111 if (itr->second._generic.questID > 0) //quests objects
9112 {
9113 itr->second.IsForQuests = true;
9114 ++count;
9115 }
9116 break;
9117 }
9119 {
9120 if (itr->second.spellFocus.questID > 0) //quests objects
9121 {
9122 itr->second.IsForQuests = true;
9123 ++count;
9124 }
9125 break;
9126 }
9128 {
9129 if (itr->second.goober.questId > 0) //quests objects
9130 {
9131 itr->second.IsForQuests = true;
9132 ++count;
9133 }
9134 break;
9135 }
9136 default:
9137 break;
9138 }
9139 }
9140
9141 LOG_INFO("server.loading", ">> Loaded {} GameObjects for quests in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9142 LOG_INFO("server.loading", " ");
9143}
LootStore LootTemplates_Gameobject("gameobject_loot_template", "gameobject entry", true)
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition SharedDefines.h:1579
@ GAMEOBJECT_TYPE_GENERIC
Definition SharedDefines.h:1576
@ GAMEOBJECT_TYPE_CHEST
Definition SharedDefines.h:1574
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition SharedDefines.h:1573
@ GAMEOBJECT_TYPE_GOOBER
Definition SharedDefines.h:1581
bool HaveQuestLootFor(uint32 loot_id) const
Definition LootMgr.cpp:218

References GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_GENERIC, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_QUESTGIVER, GAMEOBJECT_TYPE_SPELL_FOCUS, GetGameObjectTemplates(), getMSTime(), GetMSTimeDiffToNow(), LootStore::HaveQuestLootFor(), LOG_INFO, LOG_WARN, and LootTemplates_Gameobject.

◆ LoadGameObjectLocales()

void ObjectMgr::LoadGameObjectLocales ( )
7609{
7610 uint32 oldMSTime = getMSTime();
7611
7612 _gameObjectLocaleStore.clear(); // need for reload case
7613
7614 // 0 1 2 3
7615 QueryResult result = WorldDatabase.Query("SELECT entry, locale, name, castBarCaption FROM gameobject_template_locale");
7616 if (!result)
7617 return;
7618
7619 do
7620 {
7621 Field* fields = result->Fetch();
7622
7623 uint32 ID = fields[0].Get<uint32>();
7624
7625 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
7626 if (locale == LOCALE_enUS)
7627 continue;
7628
7630 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
7631 AddLocaleString(fields[3].Get<std::string>(), locale, data.CastBarCaption);
7632 } while (result->NextRow());
7633
7634 LOG_INFO("server.loading", ">> Loaded {} Gameobject Locale Strings in {} ms", (uint32)_gameObjectLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
7635}
Definition GameObjectData.h:676
std::vector< std::string > Name
Definition GameObjectData.h:677
std::vector< std::string > CastBarCaption
Definition GameObjectData.h:678

References _gameObjectLocaleStore, AddLocaleString(), GameObjectLocale::CastBarCaption, Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), LOCALE_enUS, LOG_INFO, GameObjectLocale::Name, and WorldDatabase.

◆ LoadGameobjectQuestEnders()

void ObjectMgr::LoadGameobjectQuestEnders ( )
8645{
8646 LoadQuestRelationsHelper(_goQuestInvolvedRelations, "gameobject_questender", false, true);
8647
8648 for (QuestRelations::iterator itr = _goQuestInvolvedRelations.begin(); itr != _goQuestInvolvedRelations.end(); ++itr)
8649 {
8650 GameObjectTemplate const* goInfo = GetGameObjectTemplate(itr->first);
8651 if (!goInfo)
8652 LOG_ERROR("sql.sql", "Table `gameobject_questender` have data for not existed gameobject entry ({}) and existed quest {}", itr->first, itr->second);
8653 else if (goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER)
8654 LOG_ERROR("sql.sql", "Table `gameobject_questender` have data gameobject entry ({}) for quest {}, but GO is not GAMEOBJECT_TYPE_QUESTGIVER", itr->first, itr->second);
8655 }
8656}

References _goQuestInvolvedRelations, GAMEOBJECT_TYPE_QUESTGIVER, GetGameObjectTemplate(), LoadQuestRelationsHelper(), LOG_ERROR, and GameObjectTemplate::type.

Referenced by LoadQuestStartersAndEnders().

◆ LoadGameObjectQuestItems()

void ObjectMgr::LoadGameObjectQuestItems ( )
10707{
10708 uint32 oldMSTime = getMSTime();
10709
10710 // 0 1 2
10711 QueryResult result = WorldDatabase.Query("SELECT GameObjectEntry, ItemId, Idx FROM gameobject_questitem ORDER BY Idx ASC");
10712
10713 if (!result)
10714 {
10715 LOG_WARN("server.loading", ">> Loaded 0 gameobject quest items. DB table `gameobject_questitem` is empty.");
10716 return;
10717 }
10718
10719 uint32 count = 0;
10720 do
10721 {
10722 Field* fields = result->Fetch();
10723
10724 uint32 entry = fields[0].Get<uint32>();
10725 uint32 item = fields[1].Get<uint32>();
10726 uint32 idx = fields[2].Get<uint32>();
10727
10728 GameObjectTemplate const* goInfo = GetGameObjectTemplate(entry);
10729 if (!goInfo)
10730 {
10731 LOG_ERROR("sql.sql", "Table `gameobject_questitem` has data for nonexistent gameobject (entry: {}, idx: {}), skipped", entry, idx);
10732 continue;
10733 };
10734
10735 ItemEntry const* dbcData = sItemStore.LookupEntry(item);
10736 if (!dbcData)
10737 {
10738 LOG_ERROR("sql.sql", "Table `gameobject_questitem` has nonexistent item (ID: {}) in gameobject (entry: {}, idx: {}), skipped", item, entry, idx);
10739 continue;
10740 };
10741
10742 _gameObjectQuestItemStore[entry].push_back(item);
10743
10744 ++count;
10745 } while (result->NextRow());
10746
10747 LOG_INFO("server.loading", ">> Loaded {} Gameobject Quest Items in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10748 LOG_INFO("server.loading", " ");
10749}

References _gameObjectQuestItemStore, Field::Get(), GetGameObjectTemplate(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, sItemStore, and WorldDatabase.

◆ LoadGameobjectQuestStarters()

void ObjectMgr::LoadGameobjectQuestStarters ( )
8631{
8632 LoadQuestRelationsHelper(_goQuestRelations, "gameobject_queststarter", true, true);
8633
8634 for (QuestRelations::iterator itr = _goQuestRelations.begin(); itr != _goQuestRelations.end(); ++itr)
8635 {
8636 GameObjectTemplate const* goInfo = GetGameObjectTemplate(itr->first);
8637 if (!goInfo)
8638 LOG_ERROR("sql.sql", "Table `gameobject_queststarter` have data for not existed gameobject entry ({}) and existed quest {}", itr->first, itr->second);
8639 else if (goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER)
8640 LOG_ERROR("sql.sql", "Table `gameobject_queststarter` have data gameobject entry ({}) for quest {}, but GO is not GAMEOBJECT_TYPE_QUESTGIVER", itr->first, itr->second);
8641 }
8642}

References _goQuestRelations, GAMEOBJECT_TYPE_QUESTGIVER, GetGameObjectTemplate(), LoadQuestRelationsHelper(), LOG_ERROR, and GameObjectTemplate::type.

Referenced by LoadQuestStartersAndEnders().

◆ LoadGameobjects()

void ObjectMgr::LoadGameobjects ( )
2754{
2755 uint32 oldMSTime = getMSTime();
2756
2757 // 0 1 2 3 4 5 6
2758 QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
2759 // 7 8 9 10 11 12 13 14 15 16 17
2760 "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, eventEntry, pool_entry, "
2761 // 18
2762 "ScriptName "
2763 "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid "
2764 "LEFT OUTER JOIN pool_gameobject ON gameobject.guid = pool_gameobject.guid");
2765
2766 if (!result)
2767 {
2768 LOG_WARN("server.loading", ">> Loaded 0 gameobjects. DB table `gameobject` is empty.");
2769 LOG_INFO("server.loading", " ");
2770 return;
2771 }
2772
2774 LOG_INFO("server.loading", "Calculating zone and area fields. This may take a moment...");
2775
2776 // build single time for check spawnmask
2777 std::map<uint32, uint32> spawnMasks;
2778 for (uint32 i = 0; i < sMapStore.GetNumRows(); ++i)
2779 if (sMapStore.LookupEntry(i))
2780 for (int k = 0; k < MAX_DIFFICULTY; ++k)
2782 spawnMasks[i] |= (1 << k);
2783
2784 _gameObjectDataStore.rehash(result->GetRowCount());
2785 do
2786 {
2787 Field* fields = result->Fetch();
2788
2789 ObjectGuid::LowType guid = fields[0].Get<uint32>();
2790 uint32 entry = fields[1].Get<uint32>();
2791
2792 GameObjectTemplate const* gInfo = GetGameObjectTemplate(entry);
2793 if (!gInfo)
2794 {
2795 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {}) with non existing gameobject entry {}, skipped.", guid, entry);
2796 continue;
2797 }
2798
2799 if (!gInfo->displayId)
2800 {
2801 switch (gInfo->type)
2802 {
2805 break;
2806 default:
2807 LOG_ERROR("sql.sql", "Gameobject (GUID: {} Entry {} GoType: {}) doesn't have a displayId ({}), not loaded.", guid, entry, gInfo->type, gInfo->displayId);
2808 break;
2809 }
2810 }
2811
2812 if (gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId))
2813 {
2814 LOG_ERROR("sql.sql", "Gameobject (GUID: {} Entry {} GoType: {}) has an invalid displayId ({}), not loaded.", guid, entry, gInfo->type, gInfo->displayId);
2815 continue;
2816 }
2817
2819
2820 data.id = entry;
2821 data.mapid = fields[2].Get<uint16>();
2822 data.posX = fields[3].Get<float>();
2823 data.posY = fields[4].Get<float>();
2824 data.posZ = fields[5].Get<float>();
2825 data.orientation = fields[6].Get<float>();
2826 data.rotation.x = fields[7].Get<float>();
2827 data.rotation.y = fields[8].Get<float>();
2828 data.rotation.z = fields[9].Get<float>();
2829 data.rotation.w = fields[10].Get<float>();
2830 data.spawntimesecs = fields[11].Get<int32>();
2831 data.ScriptId = GetScriptId(fields[18].Get<std::string>());
2832 if (!data.ScriptId)
2833 data.ScriptId = gInfo->ScriptId;
2834
2835 MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid);
2836 if (!mapEntry)
2837 {
2838 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) spawned on a non-existed map (Id: {}), skip", guid, data.id, data.mapid);
2839 continue;
2840 }
2841
2842 if (data.spawntimesecs == 0 && gInfo->IsDespawnAtAction())
2843 {
2844 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with `spawntimesecs` (0) value, but the gameobejct is marked as despawnable at action.", guid, data.id);
2845 }
2846
2847 data.animprogress = fields[12].Get<uint8>();
2848 data.artKit = 0;
2849
2850 uint32 go_state = fields[13].Get<uint8>();
2851 if (go_state >= MAX_GO_STATE)
2852 {
2853 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid `state` ({}) value, skip", guid, data.id, go_state);
2854 continue;
2855 }
2856 data.go_state = GOState(go_state);
2857
2858 data.spawnMask = fields[14].Get<uint8>();
2859
2860 if (!_transportMaps.count(data.mapid) && data.spawnMask & ~spawnMasks[data.mapid])
2861 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) that has wrong spawn mask {} including not supported difficulty modes for map (Id: {}), skip", guid, data.id, data.spawnMask, data.mapid);
2862
2863 data.phaseMask = fields[15].Get<uint32>();
2864 int16 gameEvent = fields[16].Get<int16>();
2865 uint32 PoolId = fields[17].Get<uint32>();
2866
2867 if (data.rotation.x < -1.0f || data.rotation.x > 1.0f)
2868 {
2869 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationX ({}) value, skip", guid, data.id, data.rotation.x);
2870 continue;
2871 }
2872
2873 if (data.rotation.y < -1.0f || data.rotation.y > 1.0f)
2874 {
2875 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationY ({}) value, skip", guid, data.id, data.rotation.y);
2876 continue;
2877 }
2878
2879 if (data.rotation.z < -1.0f || data.rotation.z > 1.0f)
2880 {
2881 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationZ ({}) value, skip", guid, data.id, data.rotation.z);
2882 continue;
2883 }
2884
2885 if (data.rotation.w < -1.0f || data.rotation.w > 1.0f)
2886 {
2887 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationW ({}) value, skip", guid, data.id, data.rotation.w);
2888 continue;
2889 }
2890
2891 if (fabs(data.rotation.x * data.rotation.x + data.rotation.y * data.rotation.y +
2892 data.rotation.z * data.rotation.z + data.rotation.w * data.rotation.w - 1.0f) >= 1e-5f)
2893 {
2894 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotation quaternion (non-unit), defaulting to orientation on Z axis only", guid, data.id);
2895 data.rotation = G3D::Quat(G3D::Matrix3::fromEulerAnglesZYX(data.orientation, 0.0f, 0.0f));
2896 }
2897
2898 if (!MapMgr::IsValidMapCoord(data.mapid, data.posX, data.posY, data.posZ, data.orientation))
2899 {
2900 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid coordinates, skip", guid, data.id);
2901 continue;
2902 }
2903
2904 if (data.phaseMask == 0)
2905 {
2906 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with `phaseMask`=0 (not visible for anyone), set to 1.", guid, data.id);
2907 data.phaseMask = 1;
2908 }
2909
2911 {
2912 uint32 zoneId = sMapMgr->GetZoneId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
2913 uint32 areaId = sMapMgr->GetAreaId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
2914
2916
2917 stmt->SetData(0, zoneId);
2918 stmt->SetData(1, areaId);
2919 stmt->SetData(2, guid);
2920
2921 WorldDatabase.Execute(stmt);
2922 }
2923
2924 if (gameEvent == 0 && PoolId == 0) // if not this is to be managed by GameEvent System or Pool system
2925 AddGameobjectToGrid(guid, &data);
2926 } while (result->NextRow());
2927
2928 LOG_INFO("server.loading", ">> Loaded {} Gameobjects in {} ms", (unsigned long)_gameObjectDataStore.size(), GetMSTimeDiffToNow(oldMSTime));
2929 LOG_INFO("server.loading", " ");
2930}
@ GAMEOBJECT_TYPE_TRAP
Definition SharedDefines.h:1577
@ CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA
Definition WorldConfig.h:114
@ WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA
Definition WorldDatabase.h:115

References _gameObjectDataStore, _transportMaps, AddGameobjectToGrid(), GameObjectData::animprogress, GameObjectData::artKit, CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA, GAMEOBJECT_TYPE_SPELL_FOCUS, GAMEOBJECT_TYPE_TRAP, Field::Get(), GetGameObjectTemplate(), GetMapDifficultyData(), getMSTime(), GetMSTimeDiffToNow(), GetScriptId(), GameObjectData::go_state, GameObjectData::id, MapMgr::IsValidMapCoord(), LOG_ERROR, LOG_INFO, LOG_WARN, GameObjectData::mapid, MAX_DIFFICULTY, MAX_GO_STATE, GameObjectData::orientation, GameObjectData::phaseMask, GameObjectData::posX, GameObjectData::posY, GameObjectData::posZ, GameObjectData::rotation, GameObjectData::ScriptId, PreparedStatementBase::SetData(), sGameObjectDisplayInfoStore, sMapMgr, sMapStore, GameObjectData::spawnMask, GameObjectData::spawntimesecs, sWorld, WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA, and WorldDatabase.

◆ LoadGameObjectTemplate()

void ObjectMgr::LoadGameObjectTemplate ( )
7697{
7698 uint32 oldMSTime = getMSTime();
7699
7700 // 0 1 2 3 4 5 6 7
7701 QueryResult result = WorldDatabase.Query("SELECT entry, type, displayId, name, IconName, castBarCaption, unk1, size, "
7702 // 8 9 10 11 12 13 14 15 16 17 18 19 20
7703 "Data0, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11, Data12, "
7704 // 21 22 23 24 25 26 27 28 29 30 31 32 33
7705 "Data13, Data14, Data15, Data16, Data17, Data18, Data19, Data20, Data21, Data22, Data23, AIName, ScriptName "
7706 "FROM gameobject_template");
7707
7708 if (!result)
7709 {
7710 LOG_WARN("server.loading", ">> Loaded 0 gameobject definitions. DB table `gameobject_template` is empty.");
7711 LOG_INFO("server.loading", " ");
7712 return;
7713 }
7714
7715 _gameObjectTemplateStore.rehash(result->GetRowCount());
7716 uint32 count = 0;
7717 do
7718 {
7719 Field* fields = result->Fetch();
7720
7721 uint32 entry = fields[0].Get<uint32>();
7722
7724
7725 got.entry = entry;
7726 got.type = uint32(fields[1].Get<uint8>());
7727 got.displayId = fields[2].Get<uint32>();
7728 got.name = fields[3].Get<std::string>();
7729 got.IconName = fields[4].Get<std::string>();
7730 got.castBarCaption = fields[5].Get<std::string>();
7731 got.unk1 = fields[6].Get<std::string>();
7732 got.size = fields[7].Get<float>();
7733
7734 for (uint8 i = 0; i < MAX_GAMEOBJECT_DATA; ++i)
7735 got.raw.data[i] = fields[8 + i].Get<int32>(); // data1 and data6 can be -1
7736
7737 got.AIName = fields[32].Get<std::string>();
7738 got.ScriptId = GetScriptId(fields[33].Get<std::string>());
7739 got.IsForQuests = false;
7740
7741 // Checks
7742 if (!got.AIName.empty() && !sGameObjectAIRegistry->HasItem(got.AIName))
7743 {
7744 LOG_ERROR("sql.sql", "GameObject (Entry: {}) has non-registered `AIName` '{}' set, removing", got.entry, got.AIName);
7745 }
7746
7747 switch (got.type)
7748 {
7749 case GAMEOBJECT_TYPE_DOOR: //0
7750 {
7751 if (got.door.lockId)
7752 CheckGOLockId(&got, got.door.lockId, 1);
7753 CheckGONoDamageImmuneId(&got, got.door.noDamageImmune, 3);
7754 break;
7755 }
7756 case GAMEOBJECT_TYPE_BUTTON: //1
7757 {
7758 if (got.button.lockId)
7759 CheckGOLockId(&got, got.button.lockId, 1);
7760 CheckGONoDamageImmuneId(&got, got.button.noDamageImmune, 4);
7761 break;
7762 }
7764 {
7765 if (got.questgiver.lockId)
7766 CheckGOLockId(&got, got.questgiver.lockId, 0);
7767 CheckGONoDamageImmuneId(&got, got.questgiver.noDamageImmune, 5);
7768 break;
7769 }
7770 case GAMEOBJECT_TYPE_CHEST: //3
7771 {
7772 if (got.chest.lockId)
7773 CheckGOLockId(&got, got.chest.lockId, 0);
7774
7775 CheckGOConsumable(&got, got.chest.consumable, 3);
7776
7777 if (got.chest.linkedTrapId) // linked trap
7778 CheckGOLinkedTrapId(&got, got.chest.linkedTrapId, 7);
7779 break;
7780 }
7781 case GAMEOBJECT_TYPE_TRAP: //6
7782 {
7783 if (got.trap.lockId)
7784 CheckGOLockId(&got, got.trap.lockId, 0);
7785 break;
7786 }
7787 case GAMEOBJECT_TYPE_CHAIR: //7
7788 CheckAndFixGOChairHeightId(&got, got.chair.height, 1);
7789 break;
7791 {
7792 if (got.spellFocus.focusId)
7793 {
7794 if (!sSpellFocusObjectStore.LookupEntry(got.spellFocus.focusId))
7795 LOG_ERROR("sql.sql", "GameObject (Entry: {} GoType: {}) have data0={} but SpellFocus (Id: {}) not exist.",
7796 entry, got.type, got.spellFocus.focusId, got.spellFocus.focusId);
7797 }
7798
7799 if (got.spellFocus.linkedTrapId) // linked trap
7800 CheckGOLinkedTrapId(&got, got.spellFocus.linkedTrapId, 2);
7801 break;
7802 }
7803 case GAMEOBJECT_TYPE_GOOBER: //10
7804 {
7805 if (got.goober.lockId)
7806 CheckGOLockId(&got, got.goober.lockId, 0);
7807
7808 CheckGOConsumable(&got, got.goober.consumable, 3);
7809
7810 if (got.goober.pageId) // pageId
7811 {
7812 if (!GetPageText(got.goober.pageId))
7813 LOG_ERROR("sql.sql", "GameObject (Entry: {} GoType: {}) have data7={} but PageText (Entry {}) not exist.",
7814 entry, got.type, got.goober.pageId, got.goober.pageId);
7815 }
7816 CheckGONoDamageImmuneId(&got, got.goober.noDamageImmune, 11);
7817 if (got.goober.linkedTrapId) // linked trap
7818 CheckGOLinkedTrapId(&got, got.goober.linkedTrapId, 12);
7819 break;
7820 }
7822 {
7823 if (got.areadamage.lockId)
7824 CheckGOLockId(&got, got.areadamage.lockId, 0);
7825 break;
7826 }
7827 case GAMEOBJECT_TYPE_CAMERA: //13
7828 {
7829 if (got.camera.lockId)
7830 CheckGOLockId(&got, got.camera.lockId, 0);
7831 break;
7832 }
7834 {
7835 if (got.moTransport.taxiPathId)
7836 {
7837 if (got.moTransport.taxiPathId >= sTaxiPathNodesByPath.size() || sTaxiPathNodesByPath[got.moTransport.taxiPathId].empty())
7838 LOG_ERROR("sql.sql", "GameObject (Entry: {} GoType: {}) have data0={} but TaxiPath (Id: {}) not exist.",
7839 entry, got.type, got.moTransport.taxiPathId, got.moTransport.taxiPathId);
7840 }
7841 if (uint32 transportMap = got.moTransport.mapID)
7842 _transportMaps.insert(transportMap);
7843 break;
7844 }
7846 break;
7848 {
7849 // always must have spell
7850 CheckGOSpellId(&got, got.spellcaster.spellId, 0);
7851 break;
7852 }
7853 case GAMEOBJECT_TYPE_FLAGSTAND: //24
7854 {
7855 if (got.flagstand.lockId)
7856 CheckGOLockId(&got, got.flagstand.lockId, 0);
7857 CheckGONoDamageImmuneId(&got, got.flagstand.noDamageImmune, 5);
7858 break;
7859 }
7861 {
7862 if (got.fishinghole.lockId)
7863 CheckGOLockId(&got, got.fishinghole.lockId, 4);
7864 break;
7865 }
7866 case GAMEOBJECT_TYPE_FLAGDROP: //26
7867 {
7868 if (got.flagdrop.lockId)
7869 CheckGOLockId(&got, got.flagdrop.lockId, 0);
7870 CheckGONoDamageImmuneId(&got, got.flagdrop.noDamageImmune, 3);
7871 break;
7872 }
7874 CheckAndFixGOChairHeightId(&got, got.barberChair.chairheight, 0);
7875 break;
7876 }
7877
7878 ++count;
7879 } while (result->NextRow());
7880
7881 LOG_INFO("server.loading", ">> Loaded {} Game Object Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7882 LOG_INFO("server.loading", " ");
7883}
DBCStorage< SpellFocusObjectEntry > sSpellFocusObjectStore(SpellFocusObjectfmt)
#define sGameObjectAIRegistry
Definition GameObjectAIFactory.h:49
void CheckGONoDamageImmuneId(GameObjectTemplate *goTemplate, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7677
void CheckGOSpellId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7656
void CheckAndFixGOChairHeightId(GameObjectTemplate const *goInfo, uint32 const &dataN, uint32 N)
Definition ObjectMgr.cpp:7665
void CheckGOConsumable(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7686
void CheckGOLinkedTrapId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7646
void CheckGOLockId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7637
@ GAMEOBJECT_TYPE_CAMERA
Definition SharedDefines.h:1584
@ GAMEOBJECT_TYPE_BUTTON
Definition SharedDefines.h:1572
@ GAMEOBJECT_TYPE_MO_TRANSPORT
Definition SharedDefines.h:1586
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition SharedDefines.h:1589
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition SharedDefines.h:1596
@ GAMEOBJECT_TYPE_FLAGDROP
Definition SharedDefines.h:1597
@ GAMEOBJECT_TYPE_SPELLCASTER
Definition SharedDefines.h:1593
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition SharedDefines.h:1595
@ GAMEOBJECT_TYPE_CHAIR
Definition SharedDefines.h:1578
@ GAMEOBJECT_TYPE_AREADAMAGE
Definition SharedDefines.h:1583
@ GAMEOBJECT_TYPE_BARBER_CHAIR
Definition SharedDefines.h:1603
@ GAMEOBJECT_TYPE_DOOR
Definition SharedDefines.h:1571
#define MAX_GAMEOBJECT_DATA
Definition SharedDefines.h:1610
PageText const * GetPageText(uint32 pageEntry)
Definition ObjectMgr.cpp:6325
uint32 entry
Definition GameObjectData.h:32

References _gameObjectTemplateStore, _transportMaps, CheckAndFixGOChairHeightId(), CheckGOConsumable(), CheckGOLinkedTrapId(), CheckGOLockId(), CheckGONoDamageImmuneId(), CheckGOSpellId(), GameObjectTemplate::entry, GAMEOBJECT_TYPE_AREADAMAGE, GAMEOBJECT_TYPE_BARBER_CHAIR, GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_CAMERA, GAMEOBJECT_TYPE_CHAIR, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_FLAGDROP, GAMEOBJECT_TYPE_FLAGSTAND, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_MO_TRANSPORT, GAMEOBJECT_TYPE_QUESTGIVER, GAMEOBJECT_TYPE_SPELL_FOCUS, GAMEOBJECT_TYPE_SPELLCASTER, GAMEOBJECT_TYPE_SUMMONING_RITUAL, GAMEOBJECT_TYPE_TRAP, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), GetPageText(), GetScriptId(), LOG_ERROR, LOG_INFO, LOG_WARN, MAX_GAMEOBJECT_DATA, sGameObjectAIRegistry, sSpellFocusObjectStore, sTaxiPathNodesByPath, and WorldDatabase.

◆ LoadGameObjectTemplateAddons()

void ObjectMgr::LoadGameObjectTemplateAddons ( )
7886{
7887 uint32 oldMSTime = getMSTime();
7888
7889 // 0 1 2 3 4 5 6 7 8
7890 QueryResult result = WorldDatabase.Query("SELECT entry, faction, flags, mingold, maxgold, artkit0, artkit1, artkit2, artkit3 FROM gameobject_template_addon");
7891
7892 if (!result)
7893 {
7894 LOG_WARN("server.loading", ">> Loaded 0 gameobject template addon definitions. DB table `gameobject_template_addon` is empty.");
7895 LOG_INFO("server.loading", " ");
7896 return;
7897 }
7898
7899 uint32 count = 0;
7900 do
7901 {
7902 Field* fields = result->Fetch();
7903
7904 uint32 entry = fields[0].Get<uint32>();
7905
7906 GameObjectTemplate const* got = GetGameObjectTemplate(entry);
7907 if (!got)
7908 {
7909 LOG_ERROR("sql.sql",
7910 "GameObject template (Entry: {}) does not exist but has a record in `gameobject_template_addon`",
7911 entry);
7912 continue;
7913 }
7914
7916 gameObjectAddon.faction = uint32(fields[1].Get<uint16>());
7917 gameObjectAddon.flags = fields[2].Get<uint32>();
7918 gameObjectAddon.mingold = fields[3].Get<uint32>();
7919 gameObjectAddon.maxgold = fields[4].Get<uint32>();
7920
7921 for (uint32 i = 0; i < gameObjectAddon.artKits.size(); i++)
7922 {
7923 uint32 artKitID = fields[5 + i].Get<uint32>();
7924 if (!artKitID)
7925 continue;
7926
7927 if (!sGameObjectArtKitStore.LookupEntry(artKitID))
7928 {
7929 LOG_ERROR("sql.sql", "GameObject (Entry: {}) has invalid `artkit{}` {} defined, set to zero instead.", entry, i, artKitID);
7930 continue;
7931 }
7932
7933 gameObjectAddon.artKits[i] = artKitID;
7934 }
7935
7936 // checks
7937 if (gameObjectAddon.faction && !sFactionTemplateStore.LookupEntry(gameObjectAddon.faction))
7938 LOG_ERROR("sql.sql",
7939 "GameObject (Entry: {}) has invalid faction ({}) defined in `gameobject_template_addon`.",
7940 entry, gameObjectAddon.faction);
7941
7942 if (gameObjectAddon.maxgold > 0)
7943 {
7944 switch (got->type)
7945 {
7948 break;
7949 default:
7950 LOG_ERROR("sql.sql",
7951 "GameObject (Entry {} GoType: {}) cannot be looted but has maxgold set in `gameobject_template_addon`.",
7952 entry, got->type);
7953 break;
7954 }
7955 }
7956
7957 ++count;
7958 } while (result->NextRow());
7959
7960 LOG_INFO("server.loading", ">> Loaded {} Game Object Template Addons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7961 LOG_INFO("server.loading", " ");
7962}
DBCStorage< GameObjectArtKitEntry > sGameObjectArtKitStore(GameObjectArtKitfmt)
Definition GameObjectData.h:666
uint32 mingold
Definition GameObjectData.h:670
uint32 flags
Definition GameObjectData.h:669
uint32 faction
Definition GameObjectData.h:668
std::array< uint32, 4 > artKits
Definition GameObjectData.h:672
uint32 maxgold
Definition GameObjectData.h:671

References _gameObjectTemplateAddonStore, GameObjectTemplateAddon::artKits, GameObjectTemplateAddon::faction, GameObjectTemplateAddon::flags, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_FISHINGHOLE, Field::Get(), GetGameObjectTemplate(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, GameObjectTemplateAddon::maxgold, GameObjectTemplateAddon::mingold, sFactionTemplateStore, sGameObjectArtKitStore, and WorldDatabase.

◆ LoadGameTele()

void ObjectMgr::LoadGameTele ( )
9427{
9428 uint32 oldMSTime = getMSTime();
9429
9430 _gameTeleStore.clear(); // for reload case
9431
9432 // 0 1 2 3 4 5 6
9433 QueryResult result = WorldDatabase.Query("SELECT id, position_x, position_y, position_z, orientation, map, name FROM game_tele");
9434
9435 if (!result)
9436 {
9437 LOG_WARN("server.loading", ">> Loaded 0 GameTeleports. DB table `game_tele` is empty!");
9438 LOG_INFO("server.loading", " ");
9439 return;
9440 }
9441
9442 uint32 count = 0;
9443
9444 do
9445 {
9446 Field* fields = result->Fetch();
9447
9448 uint32 id = fields[0].Get<uint32>();
9449
9450 GameTele gt;
9451
9452 gt.position_x = fields[1].Get<float>();
9453 gt.position_y = fields[2].Get<float>();
9454 gt.position_z = fields[3].Get<float>();
9455 gt.orientation = fields[4].Get<float>();
9456 gt.mapId = fields[5].Get<uint16>();
9457 gt.name = fields[6].Get<std::string>();
9458
9459 if (!MapMgr::IsValidMapCoord(gt.mapId, gt.position_x, gt.position_y, gt.position_z, gt.orientation))
9460 {
9461 LOG_ERROR("sql.sql", "Wrong position for id {} (name: {}) in `game_tele` table, ignoring.", id, gt.name);
9462 continue;
9463 }
9464
9465 if (!Utf8toWStr(gt.name, gt.wnameLow))
9466 {
9467 LOG_ERROR("sql.sql", "Wrong UTF8 name for id {} in `game_tele` table, ignoring.", id);
9468 continue;
9469 }
9470
9471 wstrToLower(gt.wnameLow);
9472
9473 _gameTeleStore[id] = gt;
9474
9475 ++count;
9476 } while (result->NextRow());
9477
9478 LOG_INFO("server.loading", ">> Loaded {} GameTeleports in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9479 LOG_INFO("server.loading", " ");
9480}
float position_x
Definition ObjectMgr.h:134

References _gameTeleStore, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), MapMgr::IsValidMapCoord(), LOG_ERROR, LOG_INFO, LOG_WARN, GameTele::position_x, Utf8toWStr(), WorldDatabase, and wstrToLower().

◆ LoadGossipMenu()

void ObjectMgr::LoadGossipMenu ( )
9871{
9872 uint32 oldMSTime = getMSTime();
9873
9874 _gossipMenusStore.clear();
9875
9876 QueryResult result = WorldDatabase.Query("SELECT MenuID, TextID FROM gossip_menu");
9877
9878 if (!result)
9879 {
9880 LOG_WARN("server.loading", ">> Loaded 0 gossip_menu entries. DB table `gossip_menu` is empty!");
9881 LOG_INFO("server.loading", " ");
9882 return;
9883 }
9884
9885 do
9886 {
9887 Field* fields = result->Fetch();
9888
9889 GossipMenus gMenu;
9890
9891 gMenu.MenuID = fields[0].Get<uint32>();
9892 gMenu.TextID = fields[1].Get<uint32>();
9893
9894 if (!GetGossipText(gMenu.TextID))
9895 {
9896 LOG_ERROR("sql.sql", "Table gossip_menu entry {} are using non-existing TextID {}", gMenu.MenuID, gMenu.TextID);
9897 continue;
9898 }
9899
9900 _gossipMenusStore.insert(GossipMenusContainer::value_type(gMenu.MenuID, gMenu));
9901 } while (result->NextRow());
9902
9903 LOG_INFO("server.loading", ">> Loaded {} gossip_menu entries in {} ms", (uint32)_gossipMenusStore.size(), GetMSTimeDiffToNow(oldMSTime));
9904 LOG_INFO("server.loading", " ");
9905}
GossipText const * GetGossipText(uint32 Text_ID) const
Definition ObjectMgr.cpp:6503
Definition ObjectMgr.h:625
uint32 TextID
Definition ObjectMgr.h:627
uint32 MenuID
Definition ObjectMgr.h:626

References _gossipMenusStore, Field::Get(), GetGossipText(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, GossipMenus::MenuID, GossipMenus::TextID, and WorldDatabase.

◆ LoadGossipMenuItems()

void ObjectMgr::LoadGossipMenuItems ( )
9908{
9909 uint32 oldMSTime = getMSTime();
9910
9911 _gossipMenuItemsStore.clear();
9912
9913 QueryResult result = WorldDatabase.Query(
9914 // 0 1 2 3 4 5 6 7 8 9 10 11 12
9915 "SELECT MenuID, OptionID, OptionIcon, OptionText, OptionBroadcastTextID, OptionType, OptionNpcFlag, ActionMenuID, ActionPoiID, BoxCoded, BoxMoney, BoxText, BoxBroadcastTextID "
9916 "FROM gossip_menu_option ORDER BY MenuID, OptionID");
9917
9918 if (!result)
9919 {
9920 LOG_WARN("server.loading", ">> Loaded 0 gossip_menu_option IDs. DB table `gossip_menu_option` is empty!");
9921 LOG_INFO("server.loading", " ");
9922 return;
9923 }
9924
9925 do
9926 {
9927 Field* fields = result->Fetch();
9928
9929 GossipMenuItems gMenuItem;
9930
9931 gMenuItem.MenuID = fields[0].Get<uint32>();
9932 gMenuItem.OptionID = fields[1].Get<uint16>();
9933 gMenuItem.OptionIcon = fields[2].Get<uint32>();
9934 gMenuItem.OptionText = fields[3].Get<std::string>();
9935 gMenuItem.OptionBroadcastTextID = fields[4].Get<uint32>();
9936 gMenuItem.OptionType = fields[5].Get<uint8>();
9937 gMenuItem.OptionNpcFlag = fields[6].Get<uint32>();
9938 gMenuItem.ActionMenuID = fields[7].Get<uint32>();
9939 gMenuItem.ActionPoiID = fields[8].Get<uint32>();
9940 gMenuItem.BoxCoded = fields[9].Get<bool>();
9941 gMenuItem.BoxMoney = fields[10].Get<uint32>();
9942 gMenuItem.BoxText = fields[11].Get<std::string>();
9943 gMenuItem.BoxBroadcastTextID = fields[12].Get<uint32>();
9944
9945 if (gMenuItem.OptionIcon >= GOSSIP_ICON_MAX)
9946 {
9947 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} has unknown icon id {}. Replacing with GOSSIP_ICON_CHAT", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.OptionIcon);
9948 gMenuItem.OptionIcon = GOSSIP_ICON_CHAT;
9949 }
9950
9952 {
9953 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} has non-existing or incompatible OptionBroadcastTextID {}, ignoring.", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.OptionBroadcastTextID);
9954 gMenuItem.OptionBroadcastTextID = 0;
9955 }
9956
9957 if (gMenuItem.OptionType >= GOSSIP_OPTION_MAX)
9958 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} has unknown option id {}. Option will not be used", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.OptionType);
9959
9960 if (gMenuItem.ActionPoiID && !GetPointOfInterest(gMenuItem.ActionPoiID))
9961 {
9962 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} use non-existing ActionPoiID {}, ignoring", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.ActionPoiID);
9963 gMenuItem.ActionPoiID = 0;
9964 }
9965
9966 if (gMenuItem.BoxBroadcastTextID && !GetBroadcastText(gMenuItem.BoxBroadcastTextID))
9967 {
9968 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} has non-existing or incompatible BoxBroadcastTextID {}, ignoring.", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.BoxBroadcastTextID);
9969 gMenuItem.BoxBroadcastTextID = 0;
9970 }
9971
9972 _gossipMenuItemsStore.insert(GossipMenuItemsContainer::value_type(gMenuItem.MenuID, gMenuItem));
9973 } while (result->NextRow());
9974
9975 // Warn if any trainer creature templates reference a GossipMenuId that has no gossip_menu_option entries
9976 // This will cause the gossip menu to fallback to MenuID 0 at runtime which will display: "I wish to unlearn my talents."
9977 std::set<uint32> checkedMenuIds;
9978 for (auto const& [entry, tmpl] : _creatureTemplateStore)
9979 {
9980 uint32 menuId = tmpl.GossipMenuId;
9981 if (!menuId)
9982 continue;
9983
9984 if (!(tmpl.npcflag & UNIT_NPC_FLAG_TRAINER))
9985 continue;
9986
9987 if (checkedMenuIds.contains(menuId))
9988 continue;
9989
9990 checkedMenuIds.insert(menuId);
9991
9992 auto [first, second] = _gossipMenuItemsStore.equal_range(menuId);
9993 if (first == second)
9994 LOG_WARN("server.loading", "Trainer creature template references GossipMenuId {} has no `gossip_menu_option` entries. This will fallback to MenuID 0.", menuId);
9995 }
9996
9997 LOG_INFO("server.loading", ">> Loaded {} gossip_menu_option entries in {} ms", uint32(_gossipMenuItemsStore.size()), GetMSTimeDiffToNow(oldMSTime));
9998 LOG_INFO("server.loading", " ");
9999}
@ GOSSIP_ICON_CHAT
Definition GossipDef.h:61
@ GOSSIP_ICON_MAX
Definition GossipDef.h:82
@ GOSSIP_OPTION_MAX
Definition GossipDef.h:56
@ UNIT_NPC_FLAG_TRAINER
Definition UnitDefines.h:323
PointOfInterest const * GetPointOfInterest(uint32 id) const
Definition ObjectMgr.h:928
BroadcastText const * GetBroadcastText(uint32 id) const
Definition ObjectMgr.h:1211
Definition ObjectMgr.h:607
uint8 OptionIcon
Definition ObjectMgr.h:610
uint32 BoxBroadcastTextID
Definition ObjectMgr.h:621
std::string OptionText
Definition ObjectMgr.h:611
uint32 ActionMenuID
Definition ObjectMgr.h:615
bool BoxCoded
Definition ObjectMgr.h:617
uint32 MenuID
Definition ObjectMgr.h:608
uint32 OptionNpcFlag
Definition ObjectMgr.h:614
uint32 ActionPoiID
Definition ObjectMgr.h:616
uint32 BoxMoney
Definition ObjectMgr.h:618
std::string BoxText
Definition ObjectMgr.h:619
uint32 OptionID
Definition ObjectMgr.h:609
uint32 OptionType
Definition ObjectMgr.h:613
uint32 OptionBroadcastTextID
Definition ObjectMgr.h:612

References _creatureTemplateStore, _gossipMenuItemsStore, GossipMenuItems::ActionMenuID, GossipMenuItems::ActionPoiID, GossipMenuItems::BoxBroadcastTextID, GossipMenuItems::BoxCoded, GossipMenuItems::BoxMoney, GossipMenuItems::BoxText, Field::Get(), GetBroadcastText(), getMSTime(), GetMSTimeDiffToNow(), GetPointOfInterest(), GOSSIP_ICON_CHAT, GOSSIP_ICON_MAX, GOSSIP_OPTION_MAX, LOG_ERROR, LOG_INFO, LOG_WARN, GossipMenuItems::MenuID, GossipMenuItems::OptionBroadcastTextID, GossipMenuItems::OptionIcon, GossipMenuItems::OptionID, GossipMenuItems::OptionNpcFlag, GossipMenuItems::OptionText, GossipMenuItems::OptionType, UNIT_NPC_FLAG_TRAINER, and WorldDatabase.

◆ LoadGossipMenuItemsLocales()

void ObjectMgr::LoadGossipMenuItemsLocales ( )
421{
422 uint32 oldMSTime = getMSTime();
423
424 _gossipMenuItemsLocaleStore.clear(); // need for reload case
425
426 // 0 1 2 3 4
427 QueryResult result = WorldDatabase.Query("SELECT MenuID, OptionID, Locale, OptionText, BoxText FROM gossip_menu_option_locale");
428
429 if (!result)
430 return;
431
432 do
433 {
434 Field* fields = result->Fetch();
435
436 uint32 MenuID = fields[0].Get<uint32>();
437 uint16 OptionID = fields[1].Get<uint16>();
438
439 LocaleConstant locale = GetLocaleByName(fields[2].Get<std::string>());
440 if (locale == LOCALE_enUS)
441 continue;
442
444 AddLocaleString(fields[3].Get<std::string>(), locale, data.OptionText);
445 AddLocaleString(fields[4].Get<std::string>(), locale, data.BoxText);
446 } while (result->NextRow());
447
448 LOG_INFO("server.loading", ">> Loaded {} Gossip Menu Option Locale Strings in {} ms", (uint32)_gossipMenuItemsLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
449}
Definition CreatureData.h:345
std::vector< std::string > BoxText
Definition CreatureData.h:347
std::vector< std::string > OptionText
Definition CreatureData.h:346

References _gossipMenuItemsLocaleStore, AddLocaleString(), GossipMenuItemsLocale::BoxText, Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), LOCALE_enUS, LOG_INFO, MAKE_PAIR32(), GossipMenuItemsLocale::OptionText, and WorldDatabase.

◆ LoadGossipText()

void ObjectMgr::LoadGossipText ( )
6512{
6513 uint32 oldMSTime = getMSTime();
6514
6515 QueryResult result = WorldDatabase.Query("SELECT ID, "
6516 "text0_0, text0_1, BroadcastTextID0, lang0, Probability0, em0_0, em0_1, em0_2, em0_3, em0_4, em0_5, "
6517 "text1_0, text1_1, BroadcastTextID1, lang1, Probability1, em1_0, em1_1, em1_2, em1_3, em1_4, em1_5, "
6518 "text2_0, text2_1, BroadcastTextID2, lang2, Probability2, em2_0, em2_1, em2_2, em2_3, em2_4, em2_5, "
6519 "text3_0, text3_1, BroadcastTextID3, lang3, Probability3, em3_0, em3_1, em3_2, em3_3, em3_4, em3_5, "
6520 "text4_0, text4_1, BroadcastTextID4, lang4, Probability4, em4_0, em4_1, em4_2, em4_3, em4_4, em4_5, "
6521 "text5_0, text5_1, BroadcastTextID5, lang5, Probability5, em5_0, em5_1, em5_2, em5_3, em5_4, em5_5, "
6522 "text6_0, text6_1, BroadcastTextID6, lang6, Probability6, em6_0, em6_1, em6_2, em6_3, em6_4, em6_5, "
6523 "text7_0, text7_1, BroadcastTextID7, lang7, Probability7, em7_0, em7_1, em7_2, em7_3, em7_4, em7_5 "
6524 "FROM npc_text");
6525
6526 if (!result)
6527 {
6528 LOG_WARN("server.loading", ">> Loaded 0 npc texts, table is empty!");
6529 LOG_INFO("server.loading", " ");
6530 return;
6531 }
6532
6533 _gossipTextStore.rehash(result->GetRowCount());
6534
6535 uint32 count = 0;
6536 uint8 cic;
6537
6538 do
6539 {
6540 cic = 0;
6541
6542 Field* fields = result->Fetch();
6543
6544 uint32 id = fields[cic++].Get<uint32>();
6545 if (!id)
6546 {
6547 LOG_ERROR("sql.sql", "Table `npc_text` has record wit reserved id 0, ignore.");
6548 continue;
6549 }
6550
6551 GossipText& gText = _gossipTextStore[id];
6552
6553 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
6554 {
6555 gText.Options[i].Text_0 = fields[cic++].Get<std::string>();
6556 gText.Options[i].Text_1 = fields[cic++].Get<std::string>();
6557 gText.Options[i].BroadcastTextID = fields[cic++].Get<uint32>();
6558 gText.Options[i].Language = fields[cic++].Get<uint8>();
6559 gText.Options[i].Probability = fields[cic++].Get<float>();
6560
6561 for (uint8 j = 0; j < MAX_GOSSIP_TEXT_EMOTES; ++j)
6562 {
6563 gText.Options[i].Emotes[j]._Delay = fields[cic++].Get<uint16>();
6564 gText.Options[i].Emotes[j]._Emote = fields[cic++].Get<uint16>();
6565 }
6566 }
6567
6568 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; i++)
6569 {
6570 if (gText.Options[i].BroadcastTextID)
6571 {
6573 {
6574 LOG_ERROR("sql.sql", "GossipText (Id: {}) in table `npc_text` has non-existing or incompatible BroadcastTextID{} {}.", id, i, gText.Options[i].BroadcastTextID);
6575 gText.Options[i].BroadcastTextID = 0;
6576 }
6577 }
6578 }
6579
6580 count++;
6581 } while (result->NextRow());
6582
6583 LOG_INFO("server.loading", ">> Loaded {} Npc Texts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6584 LOG_INFO("server.loading", " ");
6585}
#define MAX_GOSSIP_TEXT_OPTIONS
Definition NPCHandler.h:42
#define MAX_GOSSIP_TEXT_EMOTES
Definition NPCHandler.h:30
std::string Text_0
Definition NPCHandler.h:34
QEmote Emotes[MAX_GOSSIP_TEXT_EMOTES]
Definition NPCHandler.h:39
uint32 Language
Definition NPCHandler.h:37
float Probability
Definition NPCHandler.h:38
uint32 BroadcastTextID
Definition NPCHandler.h:36
std::string Text_1
Definition NPCHandler.h:35
Definition NPCHandler.h:45
GossipTextOption Options[MAX_GOSSIP_TEXT_OPTIONS]
Definition NPCHandler.h:46
uint32 _Emote
Definition NPCHandler.h:26
uint32 _Delay
Definition NPCHandler.h:27

References QEmote::_Delay, QEmote::_Emote, _gossipTextStore, GossipTextOption::BroadcastTextID, GossipTextOption::Emotes, Field::Get(), GetBroadcastText(), getMSTime(), GetMSTimeDiffToNow(), GossipTextOption::Language, LOG_ERROR, LOG_INFO, LOG_WARN, MAX_GOSSIP_TEXT_EMOTES, MAX_GOSSIP_TEXT_OPTIONS, GossipText::Options, GossipTextOption::Probability, GossipTextOption::Text_0, GossipTextOption::Text_1, and WorldDatabase.

◆ LoadInstanceEncounters()

void ObjectMgr::LoadInstanceEncounters ( )
6419{
6420 uint32 oldMSTime = getMSTime();
6421
6422 // 0 1 2 3
6423 QueryResult result = WorldDatabase.Query("SELECT entry, creditType, creditEntry, lastEncounterDungeon FROM instance_encounters");
6424 if (!result)
6425 {
6426 LOG_WARN("server.loading", ">> Loaded 0 instance encounters, table is empty!");
6427 LOG_INFO("server.loading", " ");
6428 return;
6429 }
6430
6431 uint32 count = 0;
6432 std::map<uint32, DungeonEncounterEntry const*> dungeonLastBosses;
6433 do
6434 {
6435 Field* fields = result->Fetch();
6436 uint32 entry = fields[0].Get<uint32>();
6437 uint8 creditType = fields[1].Get<uint8>();
6438 uint32 creditEntry = fields[2].Get<uint32>();
6439 uint32 lastEncounterDungeon = fields[3].Get<uint16>();
6440 DungeonEncounterEntry const* dungeonEncounter = sDungeonEncounterStore.LookupEntry(entry);
6441 if (!dungeonEncounter)
6442 {
6443 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid encounter id {}, skipped!", entry);
6444 continue;
6445 }
6446
6447 if (lastEncounterDungeon && !sLFGMgr->GetLFGDungeonEntry(lastEncounterDungeon))
6448 {
6449 LOG_ERROR("sql.sql", "Table `instance_encounters` has an encounter {} ({}) marked as final for invalid dungeon id {}, skipped!", entry, dungeonEncounter->encounterName[0], lastEncounterDungeon);
6450 continue;
6451 }
6452
6453 std::map<uint32, DungeonEncounterEntry const*>::const_iterator itr = dungeonLastBosses.find(lastEncounterDungeon);
6454 if (lastEncounterDungeon)
6455 {
6456 if (itr != dungeonLastBosses.end())
6457 {
6458 LOG_ERROR("sql.sql", "Table `instance_encounters` specified encounter {} ({}) as last encounter but {} ({}) is already marked as one, skipped!", entry, dungeonEncounter->encounterName[0], itr->second->id, itr->second->encounterName[0]);
6459 continue;
6460 }
6461
6462 dungeonLastBosses[lastEncounterDungeon] = dungeonEncounter;
6463 }
6464
6465 switch (creditType)
6466 {
6468 {
6469 CreatureTemplate const* creatureInfo = GetCreatureTemplate(creditEntry);
6470 if (!creatureInfo)
6471 {
6472 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid creature (entry {}) linked to the encounter {} ({}), skipped!", creditEntry, entry, dungeonEncounter->encounterName[0]);
6473 continue;
6474 }
6475 const_cast<CreatureTemplate*>(creatureInfo)->flags_extra |= CREATURE_FLAG_EXTRA_DUNGEON_BOSS;
6476 break;
6477 }
6479 {
6480 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(creditEntry);
6481 if (!spellInfo)
6482 {
6483 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid spell (entry {}) linked to the encounter {} ({}), skipped!", creditEntry, entry, dungeonEncounter->encounterName[0]);
6484 continue;
6485 }
6486 const_cast<SpellInfo*>(spellInfo)->AttributesCu |= SPELL_ATTR0_CU_ENCOUNTER_REWARD;
6487 break;
6488 }
6489 default:
6490 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid credit type ({}) for encounter {} ({}), skipped!", creditType, entry, dungeonEncounter->encounterName[0]);
6491 continue;
6492 }
6493
6494 DungeonEncounterList& encounters = _dungeonEncounterStore[MAKE_PAIR32(dungeonEncounter->mapId, dungeonEncounter->difficulty)];
6495 encounters.push_back(new DungeonEncounter(dungeonEncounter, EncounterCreditType(creditType), creditEntry, lastEncounterDungeon));
6496 ++count;
6497 } while (result->NextRow());
6498
6499 LOG_INFO("server.loading", ">> Loaded {} Instance Encounters in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6500 LOG_INFO("server.loading", " ");
6501}
@ CREATURE_FLAG_EXTRA_DUNGEON_BOSS
Definition CreatureData.h:73
DBCStorage< DungeonEncounterEntry > sDungeonEncounterStore(DungeonEncounterfmt)
#define sLFGMgr
Definition LFGMgr.h:646
EncounterCreditType
Definition Map.h:157
@ ENCOUNTER_CREDIT_KILL_CREATURE
Definition Map.h:158
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition Map.h:159
std::list< DungeonEncounter const * > DungeonEncounterList
Definition ObjectMgr.h:711
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition SpellInfo.h:207
Definition DBCStructure.h:866
Definition ObjectMgr.h:701

References _dungeonEncounterStore, CREATURE_FLAG_EXTRA_DUNGEON_BOSS, ENCOUNTER_CREDIT_CAST_SPELL, ENCOUNTER_CREDIT_KILL_CREATURE, Field::Get(), GetCreatureTemplate(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, MAKE_PAIR32(), sDungeonEncounterStore, sLFGMgr, SPELL_ATTR0_CU_ENCOUNTER_REWARD, sSpellMgr, and WorldDatabase.

◆ LoadInstanceTemplate()

void ObjectMgr::LoadInstanceTemplate ( )
6368{
6369 uint32 oldMSTime = getMSTime();
6370
6371 // 0 1 2 4
6372 QueryResult result = WorldDatabase.Query("SELECT map, parent, script, allowMount FROM instance_template");
6373
6374 if (!result)
6375 {
6376 LOG_WARN("server.loading", ">> Loaded 0 instance templates. DB table `instance_template` is empty!");
6377 LOG_INFO("server.loading", " ");
6378 return;
6379 }
6380
6381 uint32 count = 0;
6382 do
6383 {
6384 Field* fields = result->Fetch();
6385
6386 uint16 mapID = fields[0].Get<uint16>();
6387
6388 if (!MapMgr::IsValidMAP(mapID, true))
6389 {
6390 LOG_ERROR("sql.sql", "ObjectMgr::LoadInstanceTemplate: bad mapid {} for template!", mapID);
6391 continue;
6392 }
6393
6394 InstanceTemplate instanceTemplate;
6395
6396 instanceTemplate.AllowMount = fields[3].Get<bool>();
6397 instanceTemplate.Parent = uint32(fields[1].Get<uint16>());
6398 instanceTemplate.ScriptId = GetScriptId(fields[2].Get<std::string>());
6399
6400 _instanceTemplateStore[mapID] = instanceTemplate;
6401
6402 ++count;
6403 } while (result->NextRow());
6404
6405 LOG_INFO("server.loading", ">> Loaded {} Instance Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6406 LOG_INFO("server.loading", " ");
6407}
static bool IsValidMAP(uint32 mapid, bool startUp)
Definition MapMgr.cpp:311
bool AllowMount
Definition Map.h:124
uint32 ScriptId
Definition Map.h:123

References _instanceTemplateStore, InstanceTemplate::AllowMount, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), GetScriptId(), MapMgr::IsValidMAP(), LOG_ERROR, LOG_INFO, LOG_WARN, InstanceTemplate::Parent, InstanceTemplate::ScriptId, and WorldDatabase.

◆ LoadItemLocales()

void ObjectMgr::LoadItemLocales ( )
3090{
3091 uint32 oldMSTime = getMSTime();
3092
3093 _itemLocaleStore.clear(); // need for reload case
3094
3095 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Name, Description FROM item_template_locale");
3096 if (!result)
3097 return;
3098
3099 do
3100 {
3101 Field* fields = result->Fetch();
3102
3103 uint32 ID = fields[0].Get<uint32>();
3104
3105 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
3106 if (locale == LOCALE_enUS)
3107 continue;
3108
3109 ItemLocale& data = _itemLocaleStore[ID];
3110 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
3111 AddLocaleString(fields[3].Get<std::string>(), locale, data.Description);
3112 } while (result->NextRow());
3113
3114 LOG_INFO("server.loading", ">> Loaded {} Item Locale Strings in {} ms", (uint32)_itemLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
3115}
Definition ItemTemplate.h:834
std::vector< std::string > Description
Definition ItemTemplate.h:836
std::vector< std::string > Name
Definition ItemTemplate.h:835

References _itemLocaleStore, AddLocaleString(), ItemLocale::Description, Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), LOCALE_enUS, LOG_INFO, ItemLocale::Name, and WorldDatabase.

◆ LoadItemSetNameLocales()

void ObjectMgr::LoadItemSetNameLocales ( )
3764{
3765 uint32 oldMSTime = getMSTime();
3766
3767 _itemSetNameLocaleStore.clear(); // need for reload case
3768
3769 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Name FROM item_set_names_locale");
3770
3771 if (!result)
3772 return;
3773
3774 do
3775 {
3776 Field* fields = result->Fetch();
3777
3778 uint32 ID = fields[0].Get<uint32>();
3779
3780 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
3781 if (locale == LOCALE_enUS)
3782 continue;
3783
3785 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
3786 } while (result->NextRow());
3787
3788 LOG_INFO("server.loading", ">> Loaded {} Item Set Name Locale Strings in {} ms", uint32(_itemSetNameLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime));
3789}
Definition ItemTemplate.h:846
std::vector< std::string > Name
Definition ItemTemplate.h:847

References _itemSetNameLocaleStore, AddLocaleString(), Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), LOCALE_enUS, LOG_INFO, ItemSetNameLocale::Name, and WorldDatabase.

◆ LoadItemSetNames()

void ObjectMgr::LoadItemSetNames ( )
3792{
3793 uint32 oldMSTime = getMSTime();
3794
3795 _itemSetNameStore.clear(); // needed for reload case
3796
3797 std::set<uint32> itemSetItems;
3798
3799 // fill item set member ids
3800 for (uint32 entryId = 0; entryId < sItemSetStore.GetNumRows(); ++entryId)
3801 {
3802 ItemSetEntry const* setEntry = sItemSetStore.LookupEntry(entryId);
3803 if (!setEntry)
3804 continue;
3805
3806 for (uint32 i = 0; i < MAX_ITEM_SET_ITEMS; ++i)
3807 if (setEntry->itemId[i])
3808 itemSetItems.insert(setEntry->itemId[i]);
3809 }
3810
3811 // 0 1 2
3812 QueryResult result = WorldDatabase.Query("SELECT `entry`, `name`, `InventoryType` FROM `item_set_names`");
3813
3814 if (!result)
3815 {
3816 LOG_WARN("server.loading", ">> Loaded 0 item set names. DB table `item_set_names` is empty.");
3817 LOG_INFO("server.loading", " ");
3818 return;
3819 }
3820
3821 _itemSetNameStore.rehash(result->GetRowCount());
3822 uint32 count = 0;
3823
3824 do
3825 {
3826 Field* fields = result->Fetch();
3827
3828 uint32 entry = fields[0].Get<uint32>();
3829 if (itemSetItems.find(entry) == itemSetItems.end())
3830 {
3831 LOG_ERROR("sql.sql", "Item set name (Entry: {}) not found in ItemSet.dbc, data useless.", entry);
3832 continue;
3833 }
3834
3835 ItemSetNameEntry& data = _itemSetNameStore[entry];
3836 data.name = fields[1].Get<std::string>();
3837
3838 uint32 invType = fields[2].Get<uint8>();
3839 if (invType >= MAX_INVTYPE)
3840 {
3841 LOG_ERROR("sql.sql", "Item set name (Entry: {}) has wrong InventoryType value ({})", entry, invType);
3842 invType = INVTYPE_NON_EQUIP;
3843 }
3844
3845 data.InventoryType = invType;
3846 itemSetItems.erase(entry);
3847 ++count;
3848 } while (result->NextRow());
3849
3850 if (!itemSetItems.empty())
3851 {
3852 ItemTemplate const* pProto;
3853 for (std::set<uint32>::iterator itr = itemSetItems.begin(); itr != itemSetItems.end(); ++itr)
3854 {
3855 uint32 entry = *itr;
3856 // add data from item_template if available
3857 pProto = GetItemTemplate(entry);
3858 if (pProto)
3859 {
3860 LOG_ERROR("sql.sql", "Item set part (Entry: {}) does not have entry in `item_set_names`, adding data from `item_template`.", entry);
3861 ItemSetNameEntry& data = _itemSetNameStore[entry];
3862 data.name = pProto->Name1;
3863 data.InventoryType = pProto->InventoryType;
3864 ++count;
3865 }
3866 else
3867 LOG_ERROR("sql.sql", "Item set part (Entry: {}) does not have entry in `item_set_names`, set will not display properly.", entry);
3868 }
3869 }
3870
3871 LOG_INFO("server.loading", ">> Loaded {} Item Set Names in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3872 LOG_INFO("server.loading", " ");
3873}
DBCStorage< ItemSetEntry > sItemSetStore(ItemSetEntryfmt)
#define MAX_ITEM_SET_ITEMS
Definition DBCStructure.h:1228
@ INVTYPE_NON_EQUIP
Definition ItemTemplate.h:256
#define MAX_INVTYPE
Definition ItemTemplate.h:287
Definition DBCStructure.h:1232
uint32 itemId[MAX_ITEM_SET_ITEMS]
Definition DBCStructure.h:1236
Definition ItemTemplate.h:840
uint32 InventoryType
Definition ItemTemplate.h:842
std::string name
Definition ItemTemplate.h:841
std::string Name1
Definition ItemTemplate.h:624
uint32 InventoryType
Definition ItemTemplate.h:632

References _itemSetNameStore, Field::Get(), GetItemTemplate(), getMSTime(), GetMSTimeDiffToNow(), ItemTemplate::InventoryType, ItemSetNameEntry::InventoryType, INVTYPE_NON_EQUIP, ItemSetEntry::itemId, LOG_ERROR, LOG_INFO, LOG_WARN, MAX_INVTYPE, MAX_ITEM_SET_ITEMS, ItemSetNameEntry::name, ItemTemplate::Name1, sItemSetStore, and WorldDatabase.

◆ LoadItemTemplates()

void ObjectMgr::LoadItemTemplates ( )
3142{
3143 uint32 oldMSTime = getMSTime();
3144
3145 // 0 1 2 3 4 5 6 7 8 9 10 11 12
3146 QueryResult result = WorldDatabase.Query("SELECT entry, class, subclass, SoundOverrideSubclass, name, displayid, Quality, Flags, FlagsExtra, BuyCount, BuyPrice, SellPrice, InventoryType, "
3147 // 13 14 15 16 17 18 19 20
3148 "AllowableClass, AllowableRace, ItemLevel, RequiredLevel, RequiredSkill, RequiredSkillRank, requiredspell, requiredhonorrank, "
3149 // 21 22 23 24 25 26 27
3150 "RequiredCityRank, RequiredReputationFaction, RequiredReputationRank, maxcount, stackable, ContainerSlots, stat_type1, "
3151 // 28 29 30 31 32 33 34 35 36 37
3152 "stat_value1, stat_type2, stat_value2, stat_type3, stat_value3, stat_type4, stat_value4, stat_type5, stat_value5, stat_type6, "
3153 // 38 39 40 41 42 43 44 45 46
3154 "stat_value6, stat_type7, stat_value7, stat_type8, stat_value8, stat_type9, stat_value9, stat_type10, stat_value10, "
3155 // 47 48 49 50 51 52 53 54 55 56 57
3156 "ScalingStatDistribution, ScalingStatValue, dmg_min1, dmg_max1, dmg_type1, dmg_min2, dmg_max2, dmg_type2, armor, holy_res, fire_res, "
3157 // 58 59 60 61 62 63 64 65 66 67
3158 "nature_res, frost_res, shadow_res, arcane_res, delay, ammo_type, RangedModRange, spellid_1, spelltrigger_1, spellcharges_1, "
3159 // 68 69 70 71 72 73 74
3160 "spellppmRate_1, spellcooldown_1, spellcategory_1, spellcategorycooldown_1, spellid_2, spelltrigger_2, spellcharges_2, "
3161 // 75 76 77 78 79 80 81
3162 "spellppmRate_2, spellcooldown_2, spellcategory_2, spellcategorycooldown_2, spellid_3, spelltrigger_3, spellcharges_3, "
3163 // 82 83 84 85 86 87 88
3164 "spellppmRate_3, spellcooldown_3, spellcategory_3, spellcategorycooldown_3, spellid_4, spelltrigger_4, spellcharges_4, "
3165 // 89 90 91 92 93 94 95
3166 "spellppmRate_4, spellcooldown_4, spellcategory_4, spellcategorycooldown_4, spellid_5, spelltrigger_5, spellcharges_5, "
3167 // 96 97 98 99 100 101 102 103 104
3168 "spellppmRate_5, spellcooldown_5, spellcategory_5, spellcategorycooldown_5, bonding, description, PageText, LanguageID, PageMaterial, "
3169 // 105 106 107 108 109 110 111 112 113 114 115 116
3170 "startquest, lockid, Material, sheath, RandomProperty, RandomSuffix, block, itemset, MaxDurability, area, Map, BagFamily, "
3171 // 117 118 119 120 121 122 123 124
3172 "TotemCategory, socketColor_1, socketContent_1, socketColor_2, socketContent_2, socketColor_3, socketContent_3, socketBonus, "
3173 // 125 126 127 128 129 130 131 132
3174 "GemProperties, RequiredDisenchantSkill, ArmorDamageModifier, duration, ItemLimitCategory, HolidayId, ScriptName, DisenchantID, "
3175 // 133 134 135 136
3176 "FoodType, minMoneyLoot, maxMoneyLoot, flagsCustom FROM item_template");
3177
3178 if (!result)
3179 {
3180 LOG_WARN("server.loading", ">> Loaded 0 item templates. DB table `item_template` is empty.");
3181 LOG_INFO("server.loading", " ");
3182 return;
3183 }
3184
3185 _itemTemplateStore.reserve(result->GetRowCount());
3186 uint32 count = 0;
3187 // original inspiration https://github.com/TrinityCore/TrinityCore/commit/0c44bd33ee7b42c924859139a9f4b04cf2b91261
3188 bool enforceDBCAttributes = sWorld->getBoolConfig(CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES);
3189
3190 do
3191 {
3192 Field* fields = result->Fetch();
3193
3194 uint32 entry = fields[0].Get<uint32>();
3195
3196 ItemTemplate& itemTemplate = _itemTemplateStore[entry];
3197
3198 itemTemplate.ItemId = entry;
3199 itemTemplate.Class = uint32(fields[1].Get<uint8>());
3200 itemTemplate.SubClass = uint32(fields[2].Get<uint8>());
3201 itemTemplate.SoundOverrideSubclass = int32(fields[3].Get<int8>());
3202 itemTemplate.Name1 = fields[4].Get<std::string>();
3203 itemTemplate.DisplayInfoID = fields[5].Get<uint32>();
3204 itemTemplate.Quality = uint32(fields[6].Get<uint8>());
3205 itemTemplate.Flags = ItemFlags(fields[7].Get<uint32>());
3206 itemTemplate.Flags2 = ItemFlags2(fields[8].Get<uint32>());
3207 itemTemplate.BuyCount = uint32(fields[9].Get<uint8>());
3208 itemTemplate.BuyPrice = int32(fields[10].Get<int64>());
3209 itemTemplate.SellPrice = uint32(fields[11].Get<uint32>());
3210 itemTemplate.InventoryType = uint32(fields[12].Get<uint8>());
3211 itemTemplate.AllowableClass = fields[13].Get<int32>();
3212 itemTemplate.AllowableRace = fields[14].Get<int32>();
3213 itemTemplate.ItemLevel = uint32(fields[15].Get<uint16>());
3214 itemTemplate.RequiredLevel = uint32(fields[16].Get<uint8>());
3215 itemTemplate.RequiredSkill = uint32(fields[17].Get<uint16>());
3216 itemTemplate.RequiredSkillRank = uint32(fields[18].Get<uint16>());
3217 itemTemplate.RequiredSpell = fields[19].Get<uint32>();
3218 itemTemplate.RequiredHonorRank = fields[20].Get<uint32>();
3219 itemTemplate.RequiredCityRank = fields[21].Get<uint32>();
3220 itemTemplate.RequiredReputationFaction = uint32(fields[22].Get<uint16>());
3221 itemTemplate.RequiredReputationRank = uint32(fields[23].Get<uint16>());
3222 itemTemplate.MaxCount = fields[24].Get<int32>();
3223 itemTemplate.Stackable = fields[25].Get<int32>();
3224 itemTemplate.ContainerSlots = uint32(fields[26].Get<uint8>());
3225
3226 uint8 statsCount = 0;
3227 while (statsCount < MAX_ITEM_PROTO_STATS)
3228 {
3229 uint32 statType = uint32(fields[27 + statsCount * 2].Get<uint8>());
3230 int32 statValue = fields[28 + statsCount * 2].Get<int32>();
3231 if (statType == 0)
3232 break;
3233
3234 itemTemplate.ItemStat[statsCount].ItemStatType = statType;
3235 itemTemplate.ItemStat[statsCount].ItemStatValue = statValue;
3236 statsCount++;
3237 }
3238 itemTemplate.StatsCount = statsCount;
3239
3240 itemTemplate.ScalingStatDistribution = uint32(fields[47].Get<uint16>());
3241 itemTemplate.ScalingStatValue = fields[48].Get<int32>();
3242
3243 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
3244 {
3245 itemTemplate.Damage[i].DamageMin = fields[49 + i * 3].Get<float>();
3246 itemTemplate.Damage[i].DamageMax = fields[50 + i * 3].Get<float>();
3247 itemTemplate.Damage[i].DamageType = uint32(fields[51 + i * 3].Get<uint8>());
3248 }
3249
3250 itemTemplate.Armor = fields[55].Get<uint32>();
3251 itemTemplate.HolyRes = fields[56].Get<int32>();
3252 itemTemplate.FireRes = fields[57].Get<int32>();
3253 itemTemplate.NatureRes = fields[58].Get<int32>();
3254 itemTemplate.FrostRes = fields[59].Get<int32>();
3255 itemTemplate.ShadowRes = fields[60].Get<int32>();
3256 itemTemplate.ArcaneRes = fields[61].Get<int32>();
3257 itemTemplate.Delay = uint32(fields[62].Get<uint16>());
3258 itemTemplate.AmmoType = uint32(fields[63].Get<uint8>());
3259 itemTemplate.RangedModRange = fields[64].Get<float>();
3260
3261 for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
3262 {
3263 itemTemplate.Spells[i].SpellId = fields[65 + i * 7 ].Get<int32>();
3264 itemTemplate.Spells[i].SpellTrigger = uint32(fields[66 + i * 7].Get<uint8>());
3265 itemTemplate.Spells[i].SpellCharges = int32(fields[67 + i * 7].Get<int16>());
3266 itemTemplate.Spells[i].SpellPPMRate = fields[68 + i * 7].Get<float>();
3267 itemTemplate.Spells[i].SpellCooldown = fields[69 + i * 7].Get<int32>();
3268 itemTemplate.Spells[i].SpellCategory = uint32(fields[70 + i * 7].Get<uint16>());
3269 itemTemplate.Spells[i].SpellCategoryCooldown = fields[71 + i * 7].Get<int32>();
3270 }
3271
3272 itemTemplate.Bonding = uint32(fields[100].Get<uint8>());
3273 itemTemplate.Description = fields[101].Get<std::string>();
3274 itemTemplate.PageText = fields[102].Get<uint32>();
3275 itemTemplate.LanguageID = uint32(fields[103].Get<uint8>());
3276 itemTemplate.PageMaterial = uint32(fields[104].Get<uint8>());
3277 itemTemplate.StartQuest = fields[105].Get<uint32>();
3278 itemTemplate.LockID = fields[106].Get<uint32>();
3279 itemTemplate.Material = int32(fields[107].Get<int8>());
3280 itemTemplate.Sheath = uint32(fields[108].Get<uint8>());
3281 itemTemplate.RandomProperty = fields[109].Get<int32>();
3282 itemTemplate.RandomSuffix = fields[110].Get<int32>();
3283 itemTemplate.Block = fields[111].Get<uint32>();
3284 itemTemplate.ItemSet = fields[112].Get<uint32>();
3285 itemTemplate.MaxDurability = uint32(fields[113].Get<uint16>());
3286 itemTemplate.Area = fields[114].Get<uint32>();
3287 itemTemplate.Map = uint32(fields[115].Get<uint16>());
3288 itemTemplate.BagFamily = fields[116].Get<uint32>();
3289 itemTemplate.TotemCategory = fields[117].Get<uint32>();
3290
3291 for (uint8 i = 0; i < MAX_ITEM_PROTO_SOCKETS; ++i)
3292 {
3293 itemTemplate.Socket[i].Color = uint32(fields[118 + i * 2].Get<uint8>());
3294 itemTemplate.Socket[i].Content = fields[119 + i * 2].Get<uint32>();
3295 }
3296
3297 itemTemplate.socketBonus = fields[124].Get<uint32>();
3298 itemTemplate.GemProperties = fields[125].Get<uint32>();
3299 itemTemplate.RequiredDisenchantSkill = uint32(fields[126].Get<int16>());
3300 itemTemplate.ArmorDamageModifier = fields[127].Get<float>();
3301 itemTemplate.Duration = fields[128].Get<uint32>();
3302 itemTemplate.ItemLimitCategory = uint32(fields[129].Get<int16>());
3303 itemTemplate.HolidayId = fields[130].Get<uint32>();
3304 itemTemplate.ScriptId = GetScriptId(fields[131].Get<std::string>());
3305 itemTemplate.DisenchantID = fields[132].Get<uint32>();
3306 itemTemplate.FoodType = uint32(fields[133].Get<uint8>());
3307 itemTemplate.MinMoneyLoot = fields[134].Get<uint32>();
3308 itemTemplate.MaxMoneyLoot = fields[135].Get<uint32>();
3309 itemTemplate.FlagsCu = ItemFlagsCustom(fields[136].Get<uint32>());
3310
3311 // Checks
3312 ItemEntry const* dbcitem = sItemStore.LookupEntry(entry);
3313
3314 if (!dbcitem)
3315 {
3316 LOG_DEBUG("sql.sql", "Item (Entry: {}) does not exist in item.dbc! (not correct id?).", entry);
3317 continue;
3318 }
3319
3320 if (enforceDBCAttributes)
3321 {
3322 if (itemTemplate.Class != dbcitem->ClassID)
3323 {
3324 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Class value ({}), must be ({}).", entry, itemTemplate.Class, dbcitem->ClassID);
3325 itemTemplate.Class = dbcitem->ClassID;
3326 }
3327 if (itemTemplate.SubClass != dbcitem->SubclassID)
3328 {
3329 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Subclass value ({}) for class {}, must be ({}).", entry, itemTemplate.SubClass, itemTemplate.Class, dbcitem->SubclassID);
3330 itemTemplate.SubClass = dbcitem->SubclassID;
3331 }
3332 if (itemTemplate.SoundOverrideSubclass != dbcitem->SoundOverrideSubclassID)
3333 {
3334 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct SoundOverrideSubclass ({}), must be {}.", entry, itemTemplate.SoundOverrideSubclass, dbcitem->SoundOverrideSubclassID);
3335 itemTemplate.SoundOverrideSubclass = dbcitem->SoundOverrideSubclassID;
3336 }
3337 if (itemTemplate.Material != dbcitem->Material)
3338 {
3339 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct material ({}), must be {}.", entry, itemTemplate.Material, dbcitem->Material);
3340 itemTemplate.Material = dbcitem->Material;
3341 }
3342 if (itemTemplate.InventoryType != dbcitem->InventoryType)
3343 {
3344 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong InventoryType value ({}), must be {}.", entry, itemTemplate.InventoryType, dbcitem->InventoryType);
3345 itemTemplate.InventoryType = dbcitem->InventoryType;
3346 }
3347 if (itemTemplate.DisplayInfoID != dbcitem->DisplayInfoID)
3348 {
3349 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct display id ({}), must be {}.", entry, itemTemplate.DisplayInfoID, dbcitem->DisplayInfoID);
3350 itemTemplate.DisplayInfoID = dbcitem->DisplayInfoID;
3351 }
3352 if (itemTemplate.Sheath != dbcitem->SheatheType)
3353 {
3354 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Sheath ({}), must be {}.", entry, itemTemplate.Sheath, dbcitem->SheatheType);
3355 itemTemplate.Sheath = dbcitem->SheatheType;
3356 }
3357 }
3358
3359 if (itemTemplate.Quality >= MAX_ITEM_QUALITY)
3360 {
3361 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Quality value ({})", entry, itemTemplate.Quality);
3362 itemTemplate.Quality = ITEM_QUALITY_NORMAL;
3363 }
3364
3365 if (itemTemplate.HasFlag2(ITEM_FLAG2_FACTION_HORDE))
3366 {
3367 if (FactionEntry const* faction = sFactionStore.LookupEntry(HORDE))
3368 if ((itemTemplate.AllowableRace & faction->BaseRepRaceMask[0]) == 0)
3369 LOG_ERROR("sql.sql", "Item (Entry: {}) has value ({}) in `AllowableRace` races, not compatible with ITEM_FLAG2_FACTION_HORDE ({}) in Flags field, item cannot be equipped or used by these races.",
3370 entry, itemTemplate.AllowableRace, ITEM_FLAG2_FACTION_HORDE);
3371
3372 if (itemTemplate.HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE))
3373 LOG_ERROR("sql.sql", "Item (Entry: {}) has value ({}) in `Flags2` flags (ITEM_FLAG2_FACTION_ALLIANCE) and ITEM_FLAG2_FACTION_HORDE ({}) in Flags field, this is a wrong combination.",
3375 }
3376 else if (itemTemplate.HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE))
3377 {
3378 if (FactionEntry const* faction = sFactionStore.LookupEntry(ALLIANCE))
3379 if ((itemTemplate.AllowableRace & faction->BaseRepRaceMask[0]) == 0)
3380 LOG_ERROR("sql.sql", "Item (Entry: {}) has value ({}) in `AllowableRace` races, not compatible with ITEM_FLAG2_FACTION_ALLIANCE ({}) in Flags field, item cannot be equipped or used by these races.",
3381 entry, itemTemplate.AllowableRace, ITEM_FLAG2_FACTION_ALLIANCE);
3382 }
3383
3384 if (itemTemplate.BuyCount <= 0)
3385 {
3386 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong BuyCount value ({}), set to default(1).", entry, itemTemplate.BuyCount);
3387 itemTemplate.BuyCount = 1;
3388 }
3389
3390 if (itemTemplate.RequiredSkill >= MAX_SKILL_TYPE)
3391 {
3392 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong RequiredSkill value ({})", entry, itemTemplate.RequiredSkill);
3393 itemTemplate.RequiredSkill = 0;
3394 }
3395
3396 {
3397 // can be used in equip slot, as page read use in inventory, or spell casting at use
3398 bool req = itemTemplate.InventoryType != INVTYPE_NON_EQUIP || itemTemplate.PageText;
3399 if (!req)
3400 for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
3401 {
3402 if (itemTemplate.Spells[j].SpellId)
3403 {
3404 req = true;
3405 break;
3406 }
3407 }
3408
3409 if (req)
3410 {
3411 if (!(itemTemplate.AllowableClass & CLASSMASK_ALL_PLAYABLE))
3412 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have any playable classes ({}) in `AllowableClass` and can't be equipped or used.", entry, itemTemplate.AllowableClass);
3413
3414 if (!(itemTemplate.AllowableRace & RACEMASK_ALL_PLAYABLE))
3415 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have any playable races ({}) in `AllowableRace` and can't be equipped or used.", entry, itemTemplate.AllowableRace);
3416 }
3417 }
3418
3419 if (itemTemplate.RequiredSpell && !sSpellMgr->GetSpellInfo(itemTemplate.RequiredSpell))
3420 {
3421 LOG_ERROR("sql.sql", "Item (Entry: {}) has a wrong (non-existing) spell in RequiredSpell ({})", entry, itemTemplate.RequiredSpell);
3422 itemTemplate.RequiredSpell = 0;
3423 }
3424
3425 if (itemTemplate.RequiredReputationRank >= MAX_REPUTATION_RANK)
3426 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong reputation rank in RequiredReputationRank ({}), item can't be used.", entry, itemTemplate.RequiredReputationRank);
3427
3428 if (itemTemplate.RequiredReputationFaction)
3429 {
3430 if (!sFactionStore.LookupEntry(itemTemplate.RequiredReputationFaction))
3431 {
3432 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (not existing) faction in RequiredReputationFaction ({})", entry, itemTemplate.RequiredReputationFaction);
3433 itemTemplate.RequiredReputationFaction = 0;
3434 }
3435
3436 if (itemTemplate.RequiredReputationRank == MIN_REPUTATION_RANK)
3437 LOG_ERROR("sql.sql", "Item (Entry: {}) has min. reputation rank in RequiredReputationRank (0) but RequiredReputationFaction > 0, faction setting is useless.", entry);
3438 }
3439
3440 if (itemTemplate.MaxCount < -1)
3441 {
3442 LOG_ERROR("sql.sql", "Item (Entry: {}) has too large negative in maxcount ({}), replace by value (-1) no storing limits.", entry, itemTemplate.MaxCount);
3443 itemTemplate.MaxCount = -1;
3444 }
3445
3446 if (itemTemplate.Stackable == 0)
3447 {
3448 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong value in stackable ({}), replace by default 1.", entry, itemTemplate.Stackable);
3449 itemTemplate.Stackable = 1;
3450 }
3451 else if (itemTemplate.Stackable < -1)
3452 {
3453 LOG_ERROR("sql.sql", "Item (Entry: {}) has too large negative in stackable ({}), replace by value (-1) no stacking limits.", entry, itemTemplate.Stackable);
3454 itemTemplate.Stackable = -1;
3455 }
3456
3457 if (itemTemplate.ContainerSlots > MAX_BAG_SIZE)
3458 {
3459 LOG_ERROR("sql.sql", "Item (Entry: {}) has too large value in ContainerSlots ({}), replace by hardcoded limit ({}).", entry, itemTemplate.ContainerSlots, MAX_BAG_SIZE);
3460 itemTemplate.ContainerSlots = MAX_BAG_SIZE;
3461 }
3462
3463 for (uint8 j = 0; j < itemTemplate.StatsCount; ++j)
3464 {
3465 // for ItemStatValue != 0
3466 if (itemTemplate.ItemStat[j].ItemStatValue && itemTemplate.ItemStat[j].ItemStatType >= MAX_ITEM_MOD)
3467 {
3468 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (non-existing?) stat_type{} ({})", entry, j + 1, itemTemplate.ItemStat[j].ItemStatType);
3469 itemTemplate.ItemStat[j].ItemStatType = 0;
3470 }
3471
3472 switch (itemTemplate.ItemStat[j].ItemStatType)
3473 {
3476 // Skip warning for specific items: 13113 (Feathermoon Headdress - Blizzard oversight), 34967 (test item)
3477 if (entry != 13113 && entry != 34967)
3478 LOG_WARN("sql.sql", "Item (Entry: {}) has deprecated stat_type{} ({})", entry, j + 1, itemTemplate.ItemStat[j].ItemStatType);
3479
3480 break;
3481 default:
3482 break;
3483 }
3484 }
3485
3486 for (uint8 j = 0; j < MAX_ITEM_PROTO_DAMAGES; ++j)
3487 {
3488 if (itemTemplate.Damage[j].DamageType >= MAX_SPELL_SCHOOL)
3489 {
3490 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong dmg_type{} ({})", entry, j + 1, itemTemplate.Damage[j].DamageType);
3491 itemTemplate.Damage[j].DamageType = 0;
3492 }
3493 }
3494
3495 // special format
3496 if ((itemTemplate.Spells[0].SpellId == 483) || (itemTemplate.Spells[0].SpellId == 55884))
3497 {
3498 // spell_1
3499 if (itemTemplate.Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
3500 {
3501 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong item spell trigger value in spelltrigger_{} ({}) for special learning format", entry, 0 + 1, itemTemplate.Spells[0].SpellTrigger);
3502 itemTemplate.Spells[0].SpellId = 0;
3503 itemTemplate.Spells[0].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3504 itemTemplate.Spells[1].SpellId = 0;
3505 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3506 }
3507
3508 // spell_2 have learning spell
3509 if (itemTemplate.Spells[1].SpellTrigger != ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
3510 {
3511 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong item spell trigger value in spelltrigger_{} ({}) for special learning format.", entry, 1 + 1, itemTemplate.Spells[1].SpellTrigger);
3512 itemTemplate.Spells[0].SpellId = 0;
3513 itemTemplate.Spells[1].SpellId = 0;
3514 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3515 }
3516 else if (!itemTemplate.Spells[1].SpellId)
3517 {
3518 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have an expected spell in spellid_{} in special learning format.", entry, 1 + 1);
3519 itemTemplate.Spells[0].SpellId = 0;
3520 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3521 }
3522 else if (itemTemplate.Spells[1].SpellId != -1)
3523 {
3524 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemTemplate.Spells[1].SpellId);
3525 if (!spellInfo && !sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, itemTemplate.Spells[1].SpellId, nullptr))
3526 {
3527 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (not existing) spell in spellid_{} ({})", entry, 1 + 1, itemTemplate.Spells[1].SpellId);
3528 itemTemplate.Spells[0].SpellId = 0;
3529 itemTemplate.Spells[1].SpellId = 0;
3530 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3531 }
3532 // allowed only in special format
3533 else if ((itemTemplate.Spells[1].SpellId == 483) || (itemTemplate.Spells[1].SpellId == 55884))
3534 {
3535 LOG_ERROR("sql.sql", "Item (Entry: {}) has broken spell in spellid_{} ({})", entry, 1 + 1, itemTemplate.Spells[1].SpellId);
3536 itemTemplate.Spells[0].SpellId = 0;
3537 itemTemplate.Spells[1].SpellId = 0;
3538 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3539 }
3540 }
3541
3542 // spell_3*, spell_4*, spell_5* is empty
3543 for (uint8 j = 2; j < MAX_ITEM_PROTO_SPELLS; ++j)
3544 {
3545 if (itemTemplate.Spells[j].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
3546 {
3547 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong item spell trigger value in spelltrigger_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellTrigger);
3548 itemTemplate.Spells[j].SpellId = 0;
3549 itemTemplate.Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3550 }
3551 else if (itemTemplate.Spells[j].SpellId != 0)
3552 {
3553 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong spell in spellid_{} ({}) for learning special format", entry, j + 1, itemTemplate.Spells[j].SpellId);
3554 itemTemplate.Spells[j].SpellId = 0;
3555 }
3556 }
3557 }
3558 // normal spell list
3559 else
3560 {
3561 for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
3562 {
3563 if (itemTemplate.Spells[j].SpellTrigger >= MAX_ITEM_SPELLTRIGGER || itemTemplate.Spells[j].SpellTrigger == ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
3564 {
3565 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong item spell trigger value in spelltrigger_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellTrigger);
3566 itemTemplate.Spells[j].SpellId = 0;
3567 itemTemplate.Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3568 }
3569
3570 if (itemTemplate.Spells[j].SpellId && itemTemplate.Spells[j].SpellId != -1)
3571 {
3572 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemTemplate.Spells[j].SpellId);
3573 if (!spellInfo && !sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, itemTemplate.Spells[j].SpellId, nullptr))
3574 {
3575 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (not existing) spell in spellid_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellId);
3576 itemTemplate.Spells[j].SpellId = 0;
3577 }
3578 // allowed only in special format
3579 else if ((itemTemplate.Spells[j].SpellId == 483) || (itemTemplate.Spells[j].SpellId == 55884))
3580 {
3581 LOG_ERROR("sql.sql", "Item (Entry: {}) has broken spell in spellid_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellId);
3582 itemTemplate.Spells[j].SpellId = 0;
3583 }
3584 }
3585 }
3586 }
3587
3588 if (itemTemplate.Bonding >= MAX_BIND_TYPE)
3589 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Bonding value ({})", entry, itemTemplate.Bonding);
3590
3591 if (itemTemplate.PageText && !GetPageText(itemTemplate.PageText))
3592 LOG_ERROR("sql.sql", "Item (Entry: {}) has non existing first page (Id:{})", entry, itemTemplate.PageText);
3593
3594 if (itemTemplate.LockID && !sLockStore.LookupEntry(itemTemplate.LockID))
3595 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong LockID ({})", entry, itemTemplate.LockID);
3596
3597 if (itemTemplate.RandomProperty)
3598 {
3599 // To be implemented later
3600 if (itemTemplate.RandomProperty == -1)
3601 itemTemplate.RandomProperty = 0;
3602
3603 else if (!sItemRandomPropertiesStore.LookupEntry(GetItemEnchantMod(itemTemplate.RandomProperty)))
3604 {
3605 LOG_ERROR("sql.sql", "Item (Entry: {}) has unknown (wrong or not listed in `item_enchantment_template`) RandomProperty ({})", entry, itemTemplate.RandomProperty);
3606 itemTemplate.RandomProperty = 0;
3607 }
3608 }
3609
3610 if (itemTemplate.RandomSuffix && !sItemRandomSuffixStore.LookupEntry(GetItemEnchantMod(itemTemplate.RandomSuffix)))
3611 {
3612 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong RandomSuffix ({})", entry, itemTemplate.RandomSuffix);
3613 itemTemplate.RandomSuffix = 0;
3614 }
3615
3616 if (itemTemplate.ItemSet && !sItemSetStore.LookupEntry(itemTemplate.ItemSet))
3617 {
3618 LOG_ERROR("sql.sql", "Item (Entry: {}) have wrong ItemSet ({})", entry, itemTemplate.ItemSet);
3619 itemTemplate.ItemSet = 0;
3620 }
3621
3622 if (itemTemplate.Area && !sAreaTableStore.LookupEntry(itemTemplate.Area))
3623 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Area ({})", entry, itemTemplate.Area);
3624
3625 if (itemTemplate.Map && !sMapStore.LookupEntry(itemTemplate.Map))
3626 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Map ({})", entry, itemTemplate.Map);
3627
3628 if (itemTemplate.BagFamily)
3629 {
3630 // check bits
3631 for (uint32 j = 0; j < sizeof(itemTemplate.BagFamily) * 8; ++j)
3632 {
3633 uint32 mask = 1 << j;
3634 if ((itemTemplate.BagFamily & mask) == 0)
3635 continue;
3636
3637 ItemBagFamilyEntry const* bf = sItemBagFamilyStore.LookupEntry(j + 1);
3638 if (!bf)
3639 {
3640 LOG_ERROR("sql.sql", "Item (Entry: {}) has bag family bit set not listed in ItemBagFamily.dbc, remove bit", entry);
3641 itemTemplate.BagFamily &= ~mask;
3642 continue;
3643 }
3644
3646 {
3647 CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemTemplate.ItemId);
3648 if (!ctEntry)
3649 {
3650 LOG_ERROR("sql.sql", "Item (Entry: {}) has currency bag family bit set in BagFamily but not listed in CurrencyTypes.dbc, remove bit", entry);
3651 itemTemplate.BagFamily &= ~mask;
3652 }
3653 }
3654 }
3655 }
3656
3657 if (itemTemplate.TotemCategory && !sTotemCategoryStore.LookupEntry(itemTemplate.TotemCategory))
3658 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong TotemCategory ({})", entry, itemTemplate.TotemCategory);
3659
3660 for (uint8 j = 0; j < MAX_ITEM_PROTO_SOCKETS; ++j)
3661 {
3662 if (itemTemplate.Socket[j].Color && (itemTemplate.Socket[j].Color & SOCKET_COLOR_ALL) != itemTemplate.Socket[j].Color)
3663 {
3664 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong socketColor_{} ({})", entry, j + 1, itemTemplate.Socket[j].Color);
3665 itemTemplate.Socket[j].Color = 0;
3666 }
3667 }
3668
3669 if (itemTemplate.GemProperties && !sGemPropertiesStore.LookupEntry(itemTemplate.GemProperties))
3670 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong GemProperties ({})", entry, itemTemplate.GemProperties);
3671
3672 if (itemTemplate.FoodType >= MAX_PET_DIET)
3673 {
3674 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong FoodType value ({})", entry, itemTemplate.FoodType);
3675 itemTemplate.FoodType = 0;
3676 }
3677
3678 if (itemTemplate.ItemLimitCategory && !sItemLimitCategoryStore.LookupEntry(itemTemplate.ItemLimitCategory))
3679 {
3680 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong LimitCategory value ({})", entry, itemTemplate.ItemLimitCategory);
3681 itemTemplate.ItemLimitCategory = 0;
3682 }
3683
3684 if (itemTemplate.HolidayId && !sHolidaysStore.LookupEntry(itemTemplate.HolidayId))
3685 {
3686 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong HolidayId value ({})", entry, itemTemplate.HolidayId);
3687 itemTemplate.HolidayId = 0;
3688 }
3689
3690 if (itemTemplate.HasFlagCu(ITEM_FLAGS_CU_DURATION_REAL_TIME) && !itemTemplate.Duration)
3691 {
3692 LOG_ERROR("sql.sql", "Item (Entry {}) has flag ITEM_FLAGS_CU_DURATION_REAL_TIME but it does not have duration limit", entry);
3693 itemTemplate.FlagsCu = static_cast<ItemFlagsCustom>(static_cast<uint32>(itemTemplate.FlagsCu) & ~ITEM_FLAGS_CU_DURATION_REAL_TIME);
3694 }
3695
3696 // Set after checks to ensure valid item quality
3697 itemTemplate.BuyPrice *= sWorld->getRate(qualityToBuyValueConfig[itemTemplate.Quality]);
3698 itemTemplate.SellPrice *= sWorld->getRate(qualityToSellValueConfig[itemTemplate.Quality]);
3699
3700 // Fill categories map
3701 for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
3702 if (itemTemplate.Spells[i].SpellId && itemTemplate.Spells[i].SpellCategory && itemTemplate.Spells[i].SpellCategoryCooldown)
3703 {
3704 SpellCategoryStore::iterator ct = sSpellsByCategoryStore.find(itemTemplate.Spells[i].SpellCategory);
3705 if (ct != sSpellsByCategoryStore.end())
3706 {
3707 ct->second.emplace(true, itemTemplate.Spells[i].SpellId);
3708 }
3709 else
3710 sSpellsByCategoryStore[itemTemplate.Spells[i].SpellCategory].emplace(true, itemTemplate.Spells[i].SpellId);
3711 }
3712
3713 ++count;
3714 } while (result->NextRow());
3715
3716 // pussywizard:
3717 {
3718 uint32 max = 0;
3719 for (ItemTemplateContainer::const_iterator itr = _itemTemplateStore.begin(); itr != _itemTemplateStore.end(); ++itr)
3720 if (itr->first > max)
3721 max = itr->first;
3722 if (max)
3723 {
3724 _itemTemplateStoreFast.clear();
3725 _itemTemplateStoreFast.resize(max + 1, nullptr);
3726 for (ItemTemplateContainer::iterator itr = _itemTemplateStore.begin(); itr != _itemTemplateStore.end(); ++itr)
3727 _itemTemplateStoreFast[itr->first] = &(itr->second);
3728 }
3729 }
3730
3731 // Check if item templates for DBC referenced character start outfit are present
3732 std::set<uint32> notFoundOutfit;
3733 for (uint32 i = 1; i < sCharStartOutfitStore.GetNumRows(); ++i)
3734 {
3735 CharStartOutfitEntry const* entry = sCharStartOutfitStore.LookupEntry(i);
3736 if (!entry)
3737 continue;
3738
3739 for (int j = 0; j < MAX_OUTFIT_ITEMS; ++j)
3740 {
3741 if (entry->ItemId[j] <= 0)
3742 continue;
3743
3744 uint32 item_id = entry->ItemId[j];
3745
3746 if (!GetItemTemplate(item_id))
3747 notFoundOutfit.insert(item_id);
3748 }
3749 }
3750
3751 for (std::set<uint32>::const_iterator itr = notFoundOutfit.begin(); itr != notFoundOutfit.end(); ++itr)
3752 LOG_ERROR("sql.sql", "Item (Entry: {}) does not exist in `item_template` but is referenced in `CharStartOutfit.dbc`", *itr);
3753
3754 LOG_INFO("server.loading", ">> Loaded {} Item Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3755 LOG_INFO("server.loading", " ");
3756}
#define MAX_BAG_SIZE
Definition Bag.h:22
DBCStorage< ItemLimitCategoryEntry > sItemLimitCategoryStore(ItemLimitCategoryEntryfmt)
SpellCategoryStore sSpellsByCategoryStore
Definition DBCStores.cpp:152
DBCStorage< CharStartOutfitEntry > sCharStartOutfitStore(CharStartOutfitEntryfmt)
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
DBCStorage< ItemBagFamilyEntry > sItemBagFamilyStore(ItemBagFamilyfmt)
DBCStorage< HolidaysEntry > sHolidaysStore(Holidaysfmt)
DBCStorage< ItemRandomSuffixEntry > sItemRandomSuffixStore(ItemRandomSuffixfmt)
DBCStorage< TotemCategoryEntry > sTotemCategoryStore(TotemCategoryEntryfmt)
DBCStorage< GemPropertiesEntry > sGemPropertiesStore(GemPropertiesEntryfmt)
DBCStorage< ItemRandomPropertiesEntry > sItemRandomPropertiesStore(ItemRandomPropertiesfmt)
DBCStorage< CurrencyTypesEntry > sCurrencyTypesStore(CurrencyTypesfmt)
#define MAX_OUTFIT_ITEMS
Definition DBCStructure.h:617
#define sDisableMgr
Definition DisableMgr.h:88
@ DISABLE_TYPE_SPELL
Definition DisableMgr.h:28
uint32 GetItemEnchantMod(int32 entry)
Definition ItemEnchantmentMgr.cpp:84
ItemFlags2
Definition ItemTemplate.h:182
@ ITEM_FLAG2_FACTION_HORDE
Definition ItemTemplate.h:183
@ ITEM_FLAG2_FACTION_ALLIANCE
Definition ItemTemplate.h:184
@ ITEM_SPELLTRIGGER_LEARN_SPELL_ID
Definition ItemTemplate.h:88
@ ITEM_SPELLTRIGGER_ON_USE
Definition ItemTemplate.h:77
@ BAG_FAMILY_MASK_CURRENCY_TOKENS
Definition ItemTemplate.h:240
ItemFlags
Definition ItemTemplate.h:146
@ ITEM_MOD_SPELL_HEALING_DONE
Definition ItemTemplate.h:63
@ ITEM_MOD_SPELL_DAMAGE_DONE
Definition ItemTemplate.h:64
#define MAX_ITEM_PROTO_SOCKETS
Definition ItemTemplate.h:614
#define MAX_ITEM_PROTO_DAMAGES
Definition ItemTemplate.h:613
#define MAX_ITEM_PROTO_SPELLS
Definition ItemTemplate.h:615
ItemFlagsCustom
Definition ItemTemplate.h:218
@ ITEM_FLAGS_CU_DURATION_REAL_TIME
Definition ItemTemplate.h:219
#define SOCKET_COLOR_ALL
Definition ItemTemplate.h:252
#define MAX_BIND_TYPE
Definition ItemTemplate.h:103
#define MAX_ITEM_SPELLTRIGGER
Definition ItemTemplate.h:91
#define MAX_ITEM_PROTO_STATS
Definition ItemTemplate.h:616
#define MAX_ITEM_MOD
Definition ItemTemplate.h:73
ServerConfigs const qualityToSellValueConfig[MAX_ITEM_QUALITY]
Definition ObjectMgr.cpp:3129
ServerConfigs const qualityToBuyValueConfig[MAX_ITEM_QUALITY]
Definition ObjectMgr.cpp:3117
#define MAX_REPUTATION_RANK
Definition SharedDefines.h:256
#define MIN_REPUTATION_RANK
Definition SharedDefines.h:255
#define MAX_PET_DIET
Definition SharedDefines.h:3471
@ ITEM_QUALITY_NORMAL
Definition SharedDefines.h:341
#define MAX_ITEM_QUALITY
Definition SharedDefines.h:350
#define MAX_SKILL_TYPE
Definition SharedDefines.h:3258
@ ALLIANCE
Definition SharedDefines.h:779
@ HORDE
Definition SharedDefines.h:778
#define CLASSMASK_ALL_PLAYABLE
Definition SharedDefines.h:157
#define RACEMASK_ALL_PLAYABLE
Definition SharedDefines.h:97
@ CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES
Definition WorldConfig.h:98
Definition DBCStructure.h:620
int32 ItemId[MAX_OUTFIT_ITEMS]
Definition DBCStructure.h:626
Definition DBCStructure.h:835
Definition DBCStructure.h:907
Definition DBCStructure.h:1155
int32 SoundOverrideSubclassID
Definition DBCStructure.h:1147
uint32 SheatheType
Definition DBCStructure.h:1151
uint32 DisplayInfoID
Definition DBCStructure.h:1149
uint32 ClassID
Definition DBCStructure.h:1145
int32 Material
Definition DBCStructure.h:1148
uint32 SubclassID
Definition DBCStructure.h:1146
uint32 ItemId
Definition ItemTemplate.h:620

References _itemTemplateStore, _itemTemplateStoreFast, ALLIANCE, BAG_FAMILY_MASK_CURRENCY_TOKENS, ItemEntry::ClassID, CLASSMASK_ALL_PLAYABLE, CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES, DISABLE_TYPE_SPELL, ItemEntry::DisplayInfoID, Field::Get(), GetItemEnchantMod(), GetItemTemplate(), getMSTime(), GetMSTimeDiffToNow(), GetPageText(), GetScriptId(), HORDE, ItemEntry::InventoryType, INVTYPE_NON_EQUIP, ITEM_FLAG2_FACTION_ALLIANCE, ITEM_FLAG2_FACTION_HORDE, ITEM_FLAGS_CU_DURATION_REAL_TIME, ITEM_MOD_SPELL_DAMAGE_DONE, ITEM_MOD_SPELL_HEALING_DONE, ITEM_QUALITY_NORMAL, ITEM_SPELLTRIGGER_LEARN_SPELL_ID, ITEM_SPELLTRIGGER_ON_USE, ItemTemplate::ItemId, CharStartOutfitEntry::ItemId, LOG_DEBUG, LOG_ERROR, LOG_INFO, LOG_WARN, ItemEntry::Material, MAX_BAG_SIZE, MAX_BIND_TYPE, MAX_ITEM_MOD, MAX_ITEM_PROTO_DAMAGES, MAX_ITEM_PROTO_SOCKETS, MAX_ITEM_PROTO_SPELLS, MAX_ITEM_PROTO_STATS, MAX_ITEM_QUALITY, MAX_ITEM_SPELLTRIGGER, MAX_OUTFIT_ITEMS, MAX_PET_DIET, MAX_REPUTATION_RANK, MAX_SKILL_TYPE, MAX_SPELL_SCHOOL, MIN_REPUTATION_RANK, qualityToBuyValueConfig, qualityToSellValueConfig, RACEMASK_ALL_PLAYABLE, sAreaTableStore, sCharStartOutfitStore, sCurrencyTypesStore, sDisableMgr, sFactionStore, sGemPropertiesStore, ItemEntry::SheatheType, sHolidaysStore, sItemBagFamilyStore, sItemLimitCategoryStore, sItemRandomPropertiesStore, sItemRandomSuffixStore, sItemSetStore, sItemStore, sLockStore, sMapStore, SOCKET_COLOR_ALL, ItemEntry::SoundOverrideSubclassID, sSpellMgr, sSpellsByCategoryStore, sTotemCategoryStore, ItemEntry::SubclassID, sWorld, and WorldDatabase.

◆ LoadLinkedRespawn()

void ObjectMgr::LoadLinkedRespawn ( )
1910{
1911 uint32 oldMSTime = getMSTime();
1912
1913 _linkedRespawnStore.clear();
1914 // 0 1 2
1915 QueryResult result = WorldDatabase.Query("SELECT guid, linkedGuid, linkType FROM linked_respawn ORDER BY guid ASC");
1916
1917 if (!result)
1918 {
1919 LOG_WARN("server.loading", ">> Loaded 0 linked respawns. DB table `linked_respawn` is empty.");
1920 LOG_INFO("server.loading", " ");
1921 return;
1922 }
1923
1924 do
1925 {
1926 Field* fields = result->Fetch();
1927
1928 ObjectGuid::LowType guidLow = fields[0].Get<uint32>();
1929 ObjectGuid::LowType linkedGuidLow = fields[1].Get<uint32>();
1930 uint8 linkType = fields[2].Get<uint8>();
1931
1932 ObjectGuid guid, linkedGuid;
1933 bool error = false;
1934 switch (linkType)
1935 {
1937 {
1938 const CreatureData* slave = GetCreatureData(guidLow);
1939 if (!slave)
1940 {
1941 LOG_ERROR("sql.sql", "LinkedRespawn: Creature (guid) {} not found in creature table", guidLow);
1942 error = true;
1943 break;
1944 }
1945
1946 const CreatureData* master = GetCreatureData(linkedGuidLow);
1947 if (!master)
1948 {
1949 LOG_ERROR("sql.sql", "LinkedRespawn: Creature (linkedGuid) {} not found in creature table", linkedGuidLow);
1950 error = true;
1951 break;
1952 }
1953
1954 MapEntry const* const map = sMapStore.LookupEntry(master->mapid);
1955 if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
1956 {
1957 LOG_ERROR("sql.sql", "LinkedRespawn: Creature '{}' linking to Creature '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1958 error = true;
1959 break;
1960 }
1961
1962 if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
1963 {
1964 LOG_ERROR("sql.sql", "LinkedRespawn: Creature '{}' linking to Creature '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1965 error = true;
1966 break;
1967 }
1968
1969 guid = ObjectGuid::Create<HighGuid::Unit>(slave->id1, guidLow);
1970 linkedGuid = ObjectGuid::Create<HighGuid::Unit>(master->id1, linkedGuidLow);
1971 break;
1972 }
1973 case CREATURE_TO_GO:
1974 {
1975 const CreatureData* slave = GetCreatureData(guidLow);
1976 if (!slave)
1977 {
1978 LOG_ERROR("sql.sql", "LinkedRespawn: Creature (guid) {} not found in creature table", guidLow);
1979 error = true;
1980 break;
1981 }
1982
1983 const GameObjectData* master = GetGameObjectData(linkedGuidLow);
1984 if (!master)
1985 {
1986 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (linkedGuid) {} not found in gameobject table", linkedGuidLow);
1987 error = true;
1988 break;
1989 }
1990
1991 MapEntry const* const map = sMapStore.LookupEntry(master->mapid);
1992 if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
1993 {
1994 LOG_ERROR("sql.sql", "LinkedRespawn: Creature '{}' linking to Gameobject '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1995 error = true;
1996 break;
1997 }
1998
1999 if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
2000 {
2001 LOG_ERROR("sql.sql", "LinkedRespawn: Creature '{}' linking to Gameobject '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
2002 error = true;
2003 break;
2004 }
2005
2006 guid = ObjectGuid::Create<HighGuid::Unit>(slave->id1, guidLow);
2007 linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->id, linkedGuidLow);
2008 break;
2009 }
2010 case GO_TO_GO:
2011 {
2012 const GameObjectData* slave = GetGameObjectData(guidLow);
2013 if (!slave)
2014 {
2015 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (guid) {} not found in gameobject table", guidLow);
2016 error = true;
2017 break;
2018 }
2019
2020 const GameObjectData* master = GetGameObjectData(linkedGuidLow);
2021 if (!master)
2022 {
2023 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (linkedGuid) {} not found in gameobject table", linkedGuidLow);
2024 error = true;
2025 break;
2026 }
2027
2028 MapEntry const* const map = sMapStore.LookupEntry(master->mapid);
2029 if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
2030 {
2031 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '{}' linking to Gameobject '{}' on an unpermitted map.", guidLow, linkedGuidLow);
2032 error = true;
2033 break;
2034 }
2035
2036 if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
2037 {
2038 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '{}' linking to Gameobject '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
2039 error = true;
2040 break;
2041 }
2042
2043 guid = ObjectGuid::Create<HighGuid::GameObject>(slave->id, guidLow);
2044 linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->id, linkedGuidLow);
2045 break;
2046 }
2047 case GO_TO_CREATURE:
2048 {
2049 const GameObjectData* slave = GetGameObjectData(guidLow);
2050 if (!slave)
2051 {
2052 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (guid) {} not found in gameobject table", guidLow);
2053 error = true;
2054 break;
2055 }
2056
2057 const CreatureData* master = GetCreatureData(linkedGuidLow);
2058 if (!master)
2059 {
2060 LOG_ERROR("sql.sql", "LinkedRespawn: Creature (linkedGuid) {} not found in creature table", linkedGuidLow);
2061 error = true;
2062 break;
2063 }
2064
2065 MapEntry const* const map = sMapStore.LookupEntry(master->mapid);
2066 if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
2067 {
2068 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '{}' linking to Creature '{}' on an unpermitted map.", guidLow, linkedGuidLow);
2069 error = true;
2070 break;
2071 }
2072
2073 if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
2074 {
2075 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '{}' linking to Creature '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
2076 error = true;
2077 break;
2078 }
2079
2080 guid = ObjectGuid::Create<HighGuid::GameObject>(slave->id, guidLow);
2081 linkedGuid = ObjectGuid::Create<HighGuid::Unit>(master->id1, linkedGuidLow);
2082 break;
2083 }
2084 }
2085
2086 if (!error)
2087 _linkedRespawnStore[guid] = linkedGuid;
2088 } while (result->NextRow());
2089
2090 LOG_INFO("server.loading", ">> Loaded {} Linked Respawns In {} ms", uint64(_linkedRespawnStore.size()), GetMSTimeDiffToNow(oldMSTime));
2091 LOG_INFO("server.loading", " ");
2092}
Definition ObjectGuid.h:118
bool Instanceable() const
Definition DBCStructure.h:1353

References _linkedRespawnStore, CREATURE_TO_CREATURE, CREATURE_TO_GO, Field::Get(), GetCreatureData(), GetGameObjectData(), getMSTime(), GetMSTimeDiffToNow(), GO_TO_CREATURE, GO_TO_GO, GameObjectData::id, CreatureData::id1, MapEntry::Instanceable(), LOG_ERROR, LOG_INFO, LOG_WARN, CreatureData::mapid, GameObjectData::mapid, sMapStore, CreatureData::spawnMask, GameObjectData::spawnMask, and WorldDatabase.

◆ LoadMailLevelRewards()

void ObjectMgr::LoadMailLevelRewards ( )
9567{
9568 uint32 oldMSTime = getMSTime();
9569
9570 _mailLevelRewardStore.clear(); // for reload case
9571
9572 // 0 1 2 3
9573 QueryResult result = WorldDatabase.Query("SELECT level, raceMask, mailTemplateId, senderEntry FROM mail_level_reward");
9574
9575 if (!result)
9576 {
9577 LOG_WARN("server.loading", ">> Loaded 0 level dependent mail rewards. DB table `mail_level_reward` is empty.");
9578 LOG_INFO("server.loading", " ");
9579 return;
9580 }
9581
9582 uint32 count = 0;
9583
9584 do
9585 {
9586 Field* fields = result->Fetch();
9587
9588 uint8 level = fields[0].Get<uint8>();
9589 uint32 raceMask = fields[1].Get<uint32>();
9590 uint32 mailTemplateId = fields[2].Get<uint32>();
9591 uint32 senderEntry = fields[3].Get<uint32>();
9592
9593 if (level > MAX_LEVEL)
9594 {
9595 LOG_ERROR("sql.sql", "Table `mail_level_reward` have data for level {} that more supported by client ({}), ignoring.", level, MAX_LEVEL);
9596 continue;
9597 }
9598
9599 if (!(raceMask & RACEMASK_ALL_PLAYABLE))
9600 {
9601 LOG_ERROR("sql.sql", "Table `mail_level_reward` have raceMask ({}) for level {} that not include any player races, ignoring.", raceMask, level);
9602 continue;
9603 }
9604
9605 if (!sMailTemplateStore.LookupEntry(mailTemplateId))
9606 {
9607 LOG_ERROR("sql.sql", "Table `mail_level_reward` have invalid mailTemplateId ({}) for level {} that invalid not include any player races, ignoring.", mailTemplateId, level);
9608 continue;
9609 }
9610
9611 if (!GetCreatureTemplate(senderEntry))
9612 {
9613 LOG_ERROR("sql.sql", "Table `mail_level_reward` have not existed sender creature entry ({}) for level {} that invalid not include any player races, ignoring.", senderEntry, level);
9614 continue;
9615 }
9616
9617 _mailLevelRewardStore[level].push_back(MailLevelReward(raceMask, mailTemplateId, senderEntry));
9618
9619 ++count;
9620 } while (result->NextRow());
9621
9622 LOG_INFO("server.loading", ">> Loaded {} Level Dependent Mail Rewards in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9623 LOG_INFO("server.loading", " ");
9624}
#define MAX_LEVEL
Definition DBCEnums.h:39
DBCStorage< MailTemplateEntry > sMailTemplateStore(MailTemplateEntryfmt)
Definition ObjectMgr.h:544

References _mailLevelRewardStore, Field::Get(), GetCreatureTemplate(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, MAX_LEVEL, RACEMASK_ALL_PLAYABLE, sMailTemplateStore, and WorldDatabase.

◆ LoadModuleStrings()

bool ObjectMgr::LoadModuleStrings ( )
9146{
9147 uint32 oldMSTime = getMSTime();
9148
9149 _moduleStringStore.clear(); // for reload case
9150 QueryResult result = WorldDatabase.Query("SELECT module, id, string FROM module_string");
9151 if (!result)
9152 {
9153 LOG_WARN("server.loading", ">> Loaded 0 module strings. DB table `module_string` is empty.");
9154 LOG_INFO("server.loading", " ");
9155 return false;
9156 }
9157
9158 do
9159 {
9160 Field* fields = result->Fetch();
9161
9162 std::string module = fields[0].Get<std::string>();
9163 uint32 id = fields[1].Get<uint32>();
9164
9165 std::pair<std::string, uint32> pairKey = std::make_pair(module, id);
9166 ModuleString& data = _moduleStringStore[pairKey];
9167
9168 AddLocaleString(fields[2].Get<std::string>(), LOCALE_enUS, data.Content);
9169 } while (result->NextRow());
9170
9171 LOG_INFO("server.loading", ">> Loaded {} Module Strings in {} ms", _moduleStringStore.size(), GetMSTimeDiffToNow(oldMSTime));
9172 LOG_INFO("server.loading", " ");
9173
9174 return true;
9175}

References _moduleStringStore, AddLocaleString(), ModuleString::Content, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOCALE_enUS, LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadModuleStringsLocale()

bool ObjectMgr::LoadModuleStringsLocale ( )
9178{
9179 uint32 oldMSTime = getMSTime();
9180
9181 QueryResult result = WorldDatabase.Query("SELECT module, id, locale, string FROM module_string_locale");
9182 if (!result)
9183 {
9184 LOG_WARN("server.loading", ">> Loaded 0 module strings locale. DB table `module_string_locale` is empty.");
9185 LOG_INFO("server.loading", " ");
9186 return false;
9187 }
9188
9189 uint32 localeCount = 0;
9190 do
9191 {
9192 Field* fields = result->Fetch();
9193
9194 std::string module = fields[0].Get<std::string>();
9195 uint32 id = fields[1].Get<uint32>();
9196
9197 std::pair<std::string, uint32> pairKey = std::make_pair(module, id);
9198 ModuleString& data = _moduleStringStore[pairKey];
9199
9200 ModuleStringContainer::iterator ms = _moduleStringStore.find(pairKey);
9201 if (ms == _moduleStringStore.end())
9202 {
9203 LOG_ERROR("sql.sql", "ModuleString (Module: {} Id: {}) found in table `module_string_locale` but does not exist in `module_string`. Skipped!", module, id);
9204 continue;
9205 }
9206
9207 LocaleConstant locale = GetLocaleByName(fields[2].Get<std::string>());
9208 if (locale == LOCALE_enUS)
9209 continue;
9210
9211 AddLocaleString(fields[3].Get<std::string>(), locale, data.Content);
9212 localeCount++;
9213 } while (result->NextRow());
9214
9215 LOG_INFO("server.loading", ">> Loaded {} Module Strings Locales in {} ms", localeCount, GetMSTimeDiffToNow(oldMSTime));
9216 LOG_INFO("server.loading", " ");
9217
9218 return true;
9219}

References _moduleStringStore, AddLocaleString(), ModuleString::Content, Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), LOCALE_enUS, LOG_ERROR, LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadNPCSpellClickSpells()

void ObjectMgr::LoadNPCSpellClickSpells ( )
8499{
8500 uint32 oldMSTime = getMSTime();
8501
8502 _spellClickInfoStore.clear();
8503 // 0 1 2 3
8504 QueryResult result = WorldDatabase.Query("SELECT npc_entry, spell_id, cast_flags, user_type FROM npc_spellclick_spells");
8505
8506 if (!result)
8507 {
8508 LOG_WARN("server.loading", ">> Loaded 0 spellclick spells. DB table `npc_spellclick_spells` is empty.");
8509 LOG_INFO("server.loading", " ");
8510 return;
8511 }
8512
8513 uint32 count = 0;
8514
8515 do
8516 {
8517 Field* fields = result->Fetch();
8518
8519 uint32 npc_entry = fields[0].Get<uint32>();
8520 CreatureTemplate const* cInfo = GetCreatureTemplate(npc_entry);
8521 if (!cInfo)
8522 {
8523 LOG_ERROR("sql.sql", "Table npc_spellclick_spells references unknown creature_template {}. Skipping entry.", npc_entry);
8524 continue;
8525 }
8526
8527 uint32 spellid = fields[1].Get<uint32>();
8528 SpellInfo const* spellinfo = sSpellMgr->GetSpellInfo(spellid);
8529 if (!spellinfo)
8530 {
8531 LOG_ERROR("sql.sql", "Table npc_spellclick_spells references unknown spellid {}. Skipping entry.", spellid);
8532 continue;
8533 }
8534
8535 uint8 userType = fields[3].Get<uint16>();
8536 if (userType >= SPELL_CLICK_USER_MAX)
8537 LOG_ERROR("sql.sql", "Table npc_spellclick_spells references unknown user type {}. Skipping entry.", uint32(userType));
8538
8539 uint8 castFlags = fields[2].Get<uint8>();
8540 SpellClickInfo info;
8541 info.spellId = spellid;
8542 info.castFlags = castFlags;
8543 info.userType = SpellClickUserTypes(userType);
8544 _spellClickInfoStore.insert(SpellClickInfoContainer::value_type(npc_entry, info));
8545
8546 ++count;
8547 } while (result->NextRow());
8548
8549 // all spellclick data loaded, now we check if there are creatures with NPC_FLAG_SPELLCLICK but with no data
8550 // NOTE: It *CAN* be the other way around: no spellclick flag but with spellclick data, in case of creature-only vehicle accessories
8552 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
8553 {
8554 if ((itr->second.npcflag & UNIT_NPC_FLAG_SPELLCLICK) && _spellClickInfoStore.find(itr->second.Entry) == _spellClickInfoStore.end())
8555 {
8556 LOG_ERROR("sql.sql", "npc_spellclick_spells: Creature template {} has UNIT_NPC_FLAG_SPELLCLICK but no data in spellclick table! Removing flag", itr->second.Entry);
8557 const_cast<CreatureTemplate*>(&itr->second)->npcflag &= ~UNIT_NPC_FLAG_SPELLCLICK;
8558 }
8559 }
8560
8561 LOG_INFO("server.loading", ">> Loaded {} Spellclick Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8562 LOG_INFO("server.loading", " ");
8563}
SpellClickUserTypes
Definition SharedDefines.h:691
@ SPELL_CLICK_USER_MAX
Definition SharedDefines.h:696
@ UNIT_NPC_FLAG_SPELLCLICK
Definition UnitDefines.h:343
Definition ObjectMgr.h:399
uint32 spellId
Definition ObjectMgr.h:400

References _spellClickInfoStore, Field::Get(), GetCreatureTemplate(), GetCreatureTemplates(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, SPELL_CLICK_USER_MAX, SpellClickInfo::spellId, sSpellMgr, UNIT_NPC_FLAG_SPELLCLICK, and WorldDatabase.

◆ LoadNpcTextLocales()

void ObjectMgr::LoadNpcTextLocales ( )
6588{
6589 uint32 oldMSTime = getMSTime();
6590
6591 _npcTextLocaleStore.clear(); // need for reload case
6592
6593 QueryResult result = WorldDatabase.Query("SELECT ID, Locale, "
6594 // 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
6595 "Text0_0, Text0_1, Text1_0, Text1_1, Text2_0, Text2_1, Text3_0, Text3_1, Text4_0, Text4_1, Text5_0, Text5_1, Text6_0, Text6_1, Text7_0, Text7_1 "
6596 "FROM npc_text_locale");
6597
6598 if (!result)
6599 return;
6600
6601 do
6602 {
6603 Field* fields = result->Fetch();
6604
6605 uint32 ID = fields[0].Get<uint32>();
6606
6607 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
6608 if (locale == LOCALE_enUS)
6609 continue;
6610
6612 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
6613 {
6614 AddLocaleString(fields[2 + i * 2].Get<std::string>(), locale, data.Text_0[i]);
6615 AddLocaleString(fields[3 + i * 2].Get<std::string>(), locale, data.Text_1[i]);
6616 }
6617 } while (result->NextRow());
6618
6619 LOG_INFO("server.loading", ">> Loaded {} Npc Text Locale Strings in {} ms", (uint32)_npcTextLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
6620}
Definition NPCHandler.h:55
std::vector< std::vector< std::string > > Text_1
Definition NPCHandler.h:59
std::vector< std::vector< std::string > > Text_0
Definition NPCHandler.h:58

References _npcTextLocaleStore, AddLocaleString(), Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), LOCALE_enUS, LOG_INFO, MAX_GOSSIP_TEXT_OPTIONS, NpcTextLocale::Text_0, NpcTextLocale::Text_1, and WorldDatabase.

◆ LoadPageTextLocales()

void ObjectMgr::LoadPageTextLocales ( )
6335{
6336 uint32 oldMSTime = getMSTime();
6337
6338 _pageTextLocaleStore.clear(); // need for reload case
6339
6340 // 0 1 2
6341 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Text FROM page_text_locale");
6342
6343 if (!result)
6344 {
6345 LOG_WARN("server.loading", ">> Loaded 0 page texts. DB table `page_text_locale` is empty!");
6346 LOG_INFO("server.loading", " ");
6347 return;
6348 }
6349
6350 do
6351 {
6352 Field* fields = result->Fetch();
6353
6354 uint32 ID = fields[0].Get<uint32>();
6355
6356 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
6357 if (locale == LOCALE_enUS)
6358 continue;
6359
6361 AddLocaleString(fields[2].Get<std::string>(), locale, data.Text);
6362 } while (result->NextRow());
6363
6364 LOG_INFO("server.loading", ">> Loaded {} Page Text Locale Strings in {} ms", (uint32)_pageTextLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
6365}
Definition NPCHandler.h:50
std::vector< std::string > Text
Definition NPCHandler.h:51

References _pageTextLocaleStore, AddLocaleString(), Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), LOCALE_enUS, LOG_INFO, LOG_WARN, PageTextLocale::Text, and WorldDatabase.

◆ LoadPageTexts()

void ObjectMgr::LoadPageTexts ( )
6285{
6286 uint32 oldMSTime = getMSTime();
6287
6288 // 0 1 2
6289 QueryResult result = WorldDatabase.Query("SELECT ID, Text, NextPageID FROM page_text");
6290
6291 if (!result)
6292 {
6293 LOG_WARN("server.loading", ">> Loaded 0 page texts. DB table `page_text` is empty!");
6294 LOG_INFO("server.loading", " ");
6295 return;
6296 }
6297
6298 uint32 count = 0;
6299 do
6300 {
6301 Field* fields = result->Fetch();
6302
6303 PageText& pageText = _pageTextStore[fields[0].Get<uint32>()];
6304
6305 pageText.Text = fields[1].Get<std::string>();
6306 pageText.NextPage = fields[2].Get<uint32>();
6307
6308 ++count;
6309 } while (result->NextRow());
6310
6311 for (PageTextContainer::const_iterator itr = _pageTextStore.begin(); itr != _pageTextStore.end(); ++itr)
6312 {
6313 if (itr->second.NextPage)
6314 {
6315 PageTextContainer::const_iterator itr2 = _pageTextStore.find(itr->second.NextPage);
6316 if (itr2 == _pageTextStore.end())
6317 LOG_ERROR("sql.sql", "Page text (Id: {}) has not existing next page (Id: {})", itr->first, itr->second.NextPage);
6318 }
6319 }
6320
6321 LOG_INFO("server.loading", ">> Loaded {} Page Texts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6322 LOG_INFO("server.loading", " ");
6323}
Definition ObjectMgr.h:58
std::string Text
Definition ObjectMgr.h:59
uint32 NextPage
Definition ObjectMgr.h:60

References _pageTextStore, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, PageText::NextPage, PageText::Text, and WorldDatabase.

◆ LoadPetLevelInfo()

void ObjectMgr::LoadPetLevelInfo ( )
4032{
4033 uint32 oldMSTime = getMSTime();
4034
4035 // 0 1 2 3 4 5 6 7 8 9 10 11
4036 QueryResult result = WorldDatabase.Query("SELECT creature_entry, level, hp, mana, str, agi, sta, inte, spi, armor, min_dmg, max_dmg FROM pet_levelstats");
4037
4038 if (!result)
4039 {
4040 LOG_WARN("server.loading", ">> Loaded 0 level pet stats definitions. DB table `pet_levelstats` is empty.");
4041 LOG_INFO("server.loading", " ");
4042 return;
4043 }
4044
4045 uint32 count = 0;
4046
4047 do
4048 {
4049 Field* fields = result->Fetch();
4050
4051 uint32 creature_id = fields[0].Get<uint32>();
4052 if (!GetCreatureTemplate(creature_id))
4053 {
4054 LOG_ERROR("sql.sql", "Wrong creature id {} in `pet_levelstats` table, ignoring.", creature_id);
4055 continue;
4056 }
4057
4058 uint32 current_level = fields[1].Get<uint8>();
4059 if (current_level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4060 {
4061 if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
4062 LOG_ERROR("sql.sql", "Wrong (> {}) level {} in `pet_levelstats` table, ignoring.", STRONG_MAX_LEVEL, current_level);
4063 else
4064 {
4065 LOG_DEBUG("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `pet_levelstats` table, ignoring.", current_level);
4066 ++count; // make result loading percent "expected" correct in case disabled detail mode for example.
4067 }
4068 continue;
4069 }
4070 else if (current_level < 1)
4071 {
4072 LOG_ERROR("sql.sql", "Wrong (<1) level {} in `pet_levelstats` table, ignoring.", current_level);
4073 continue;
4074 }
4075
4076 PetLevelInfo*& pInfoMapEntry = _petInfoStore[creature_id];
4077
4078 if (!pInfoMapEntry)
4079 pInfoMapEntry = new PetLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)];
4080
4081 // data for level 1 stored in [0] array element, ...
4082 PetLevelInfo* pLevelInfo = &pInfoMapEntry[current_level - 1];
4083
4084 pLevelInfo->health = fields[2].Get<uint32>();
4085 pLevelInfo->mana = fields[3].Get<uint32>();
4086 pLevelInfo->armor = fields[9].Get<uint32>();
4087 pLevelInfo->min_dmg = fields[10].Get<uint32>();
4088 pLevelInfo->max_dmg = fields[11].Get<uint32>();
4089 for (uint8 i = 0; i < MAX_STATS; i++)
4090 {
4091 pLevelInfo->stats[i] = fields[i + 4].Get<uint32>();
4092 }
4093
4094 ++count;
4095 } while (result->NextRow());
4096
4097 // Fill gaps and check integrity
4098 for (PetLevelInfoContainer::iterator itr = _petInfoStore.begin(); itr != _petInfoStore.end(); ++itr)
4099 {
4100 PetLevelInfo* pInfo = itr->second;
4101
4102 // fatal error if no level 1 data
4103 if (!pInfo || pInfo[0].health == 0)
4104 {
4105 LOG_ERROR("sql.sql", "Creature {} does not have pet stats data for Level 1!", itr->first);
4106 exit(1);
4107 }
4108
4109 // fill level gaps
4110 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4111 {
4112 if (pInfo[level].health == 0)
4113 {
4114 LOG_ERROR("sql.sql", "Creature {} has no data for Level {} pet stats data, using data of Level {}.", itr->first, level + 1, level);
4115 pInfo[level] = pInfo[level - 1];
4116 }
4117 }
4118 }
4119
4120 LOG_INFO("server.loading", ">> Loaded {} Level Pet Stats Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4121 LOG_INFO("server.loading", " ");
4122}
#define STRONG_MAX_LEVEL
Definition DBCEnums.h:43
#define MAX_STATS
Definition SharedDefines.h:276
Definition ObjectMgr.h:529
uint32 max_dmg
Definition ObjectMgr.h:540
uint32 mana
Definition ObjectMgr.h:537
uint32 min_dmg
Definition ObjectMgr.h:539
uint32 health
Definition ObjectMgr.h:536
std::array< uint32, MAX_STATS > stats
Definition ObjectMgr.h:535
uint32 armor
Definition ObjectMgr.h:538

References _petInfoStore, PetLevelInfo::armor, CONFIG_MAX_PLAYER_LEVEL, Field::Get(), GetCreatureTemplate(), getMSTime(), GetMSTimeDiffToNow(), PetLevelInfo::health, LOG_DEBUG, LOG_ERROR, LOG_INFO, LOG_WARN, PetLevelInfo::mana, PetLevelInfo::max_dmg, MAX_STATS, PetLevelInfo::min_dmg, PetLevelInfo::stats, STRONG_MAX_LEVEL, sWorld, and WorldDatabase.

◆ LoadPetNames()

void ObjectMgr::LoadPetNames ( )
8005{
8006 uint32 oldMSTime = getMSTime();
8007 // 0 1 2
8008 QueryResult result = WorldDatabase.Query("SELECT word, entry, half FROM pet_name_generation");
8009
8010 if (!result)
8011 {
8012 LOG_WARN("server.loading", ">> Loaded 0 pet name parts. DB table `pet_name_generation` is empty!");
8013 LOG_INFO("server.loading", " ");
8014 return;
8015 }
8016
8017 uint32 count = 0;
8018
8019 do
8020 {
8021 Field* fields = result->Fetch();
8022 std::string word = fields[0].Get<std::string>();
8023 uint32 entry = fields[1].Get<uint32>();
8024 bool half = fields[2].Get<bool>();
8025 if (half)
8026 _petHalfName1[entry].push_back(word);
8027 else
8028 _petHalfName0[entry].push_back(word);
8029 ++count;
8030 } while (result->NextRow());
8031
8032 LOG_INFO("server.loading", ">> Loaded {} Pet Name Parts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8033 LOG_INFO("server.loading", " ");
8034}

References _petHalfName0, _petHalfName1, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadPetNamesLocales()

void ObjectMgr::LoadPetNamesLocales ( )
452{
453 uint32 oldMSTime = getMSTime();
454
455 // 0 1 2 3
456 QueryResult result = WorldDatabase.Query("SELECT Locale, Word, Entry, Half FROM pet_name_generation_locale");
457
458 if (!result)
459 {
460 LOG_WARN("server.loading", ">> Loaded 0 pet name locales parts. DB table `pet_name_generation_locale` is empty!");
461 LOG_INFO("server.loading", " ");
462 return;
463 }
464
465 uint32 count = 0;
466
467 do
468 {
469 Field* fields = result->Fetch();
470 LocaleConstant locale = GetLocaleByName(fields[0].Get<std::string>());
471 std::string word = fields[1].Get<std::string>();
472
473 uint32 entry = fields[2].Get<uint32>();
474 bool half = fields[3].Get<bool>();
475 std::pair<uint32, LocaleConstant> pairkey = std::make_pair(entry, locale);
476 if (half)
477 {
478 _petHalfLocaleName1[pairkey].push_back(word);
479 }
480 else
481 {
482 _petHalfLocaleName0[pairkey].push_back(word);
483 }
484 ++count;
485 } while (result->NextRow());
486
487 LOG_INFO("server.loading", ">> Loaded {} Pet Name Locales Parts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
488 LOG_INFO("server.loading", " ");
489}

References _petHalfLocaleName0, _petHalfLocaleName1, Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadPetNumber()

void ObjectMgr::LoadPetNumber ( )
8037{
8038 uint32 oldMSTime = getMSTime();
8039
8040 QueryResult result = CharacterDatabase.Query("SELECT MAX(id) FROM character_pet");
8041 if (result)
8042 {
8043 Field* fields = result->Fetch();
8044 _hiPetNumber = fields[0].Get<uint32>() + 1;
8045 }
8046
8047 LOG_INFO("server.loading", ">> Loaded The Max Pet Number: {} in {} ms", _hiPetNumber - 1, GetMSTimeDiffToNow(oldMSTime));
8048 LOG_INFO("server.loading", " ");
8049}

References _hiPetNumber, CharacterDatabase, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), and LOG_INFO.

◆ LoadPlayerInfo()

void ObjectMgr::LoadPlayerInfo ( )
4171{
4172 // Load playercreate
4173 {
4174 uint32 oldMSTime = getMSTime();
4175 // 0 1 2 3 4 5 6
4176 QueryResult result = WorldDatabase.Query("SELECT race, class, map, zone, position_x, position_y, position_z, orientation FROM playercreateinfo");
4177
4178 if (!result)
4179 {
4180 LOG_INFO("server.loading", " ");
4181 LOG_WARN("server.loading", ">> Loaded 0 player create definitions. DB table `playercreateinfo` is empty.");
4182 exit(1);
4183 }
4184 else
4185 {
4186 uint32 count = 0;
4187
4188 do
4189 {
4190 Field* fields = result->Fetch();
4191
4192 uint32 current_race = fields[0].Get<uint8>();
4193 uint32 current_class = fields[1].Get<uint8>();
4194 uint32 mapId = fields[2].Get<uint16>();
4195 uint32 areaId = fields[3].Get<uint32>(); // zone
4196 float positionX = fields[4].Get<float>();
4197 float positionY = fields[5].Get<float>();
4198 float positionZ = fields[6].Get<float>();
4199 float orientation = fields[7].Get<float>();
4200
4201 if (current_race >= MAX_RACES)
4202 {
4203 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo` table, ignoring.", current_race);
4204 continue;
4205 }
4206
4207 ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(current_race);
4208 if (!rEntry)
4209 {
4210 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo` table, ignoring.", current_race);
4211 continue;
4212 }
4213
4214 if (current_class >= MAX_CLASSES)
4215 {
4216 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo` table, ignoring.", current_class);
4217 continue;
4218 }
4219
4220 if (!sChrClassesStore.LookupEntry(current_class))
4221 {
4222 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo` table, ignoring.", current_class);
4223 continue;
4224 }
4225
4226 // accept DB data only for valid position (and non instanceable)
4227 if (!MapMgr::IsValidMapCoord(mapId, positionX, positionY, positionZ, orientation))
4228 {
4229 LOG_ERROR("sql.sql", "Wrong home position for class {} race {} pair in `playercreateinfo` table, ignoring.", current_class, current_race);
4230 continue;
4231 }
4232
4233 if (sMapStore.LookupEntry(mapId)->Instanceable())
4234 {
4235 LOG_ERROR("sql.sql", "Home position in instanceable map for class {} race {} pair in `playercreateinfo` table, ignoring.", current_class, current_race);
4236 continue;
4237 }
4238
4239 PlayerInfo* info = new PlayerInfo();
4240 info->mapId = mapId;
4241 info->areaId = areaId;
4242 info->positionX = positionX;
4243 info->positionY = positionY;
4244 info->positionZ = positionZ;
4245 info->orientation = orientation;
4246 info->displayId_m = rEntry->model_m;
4247 info->displayId_f = rEntry->model_f;
4248 _playerInfo[current_race][current_class] = info;
4249
4250 ++count;
4251 } while (result->NextRow());
4252
4253 LOG_INFO("server.loading", ">> Loaded {} Player Create Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4254 LOG_INFO("server.loading", " ");
4255 }
4256 }
4257
4258 // Load playercreate items
4259 LOG_INFO("server.loading", "Loading Player Create Items Data...");
4260 {
4261 uint32 oldMSTime = getMSTime();
4262 // 0 1 2 3
4263 QueryResult result = WorldDatabase.Query("SELECT race, class, itemid, amount FROM playercreateinfo_item");
4264
4265 if (!result)
4266 {
4267 LOG_WARN("server.loading", ">> Loaded 0 Custom Player Create Items. DB Table `playercreateinfo_item` Is Empty.");
4268 LOG_INFO("server.loading", " ");
4269 }
4270 else
4271 {
4272 uint32 count = 0;
4273
4274 do
4275 {
4276 Field* fields = result->Fetch();
4277
4278 uint32 current_race = fields[0].Get<uint8>();
4279 if (current_race >= MAX_RACES)
4280 {
4281 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo_item` table, ignoring.", current_race);
4282 continue;
4283 }
4284
4285 uint32 current_class = fields[1].Get<uint8>();
4286 if (current_class >= MAX_CLASSES)
4287 {
4288 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo_item` table, ignoring.", current_class);
4289 continue;
4290 }
4291
4292 uint32 item_id = fields[2].Get<uint32>();
4293
4294 if (!GetItemTemplate(item_id))
4295 {
4296 LOG_ERROR("sql.sql", "Item id {} (race {} class {}) in `playercreateinfo_item` table but not listed in `item_template`, ignoring.", item_id, current_race, current_class);
4297 continue;
4298 }
4299
4300 int32 amount = fields[3].Get<int32>();
4301
4302 if (!amount)
4303 {
4304 LOG_ERROR("sql.sql", "Item id {} (class {} race {}) have amount == 0 in `playercreateinfo_item` table, ignoring.", item_id, current_race, current_class);
4305 continue;
4306 }
4307
4308 if (!current_race || !current_class)
4309 {
4310 uint32 min_race = current_race ? current_race : 1;
4311 uint32 max_race = current_race ? current_race + 1 : MAX_RACES;
4312 uint32 min_class = current_class ? current_class : 1;
4313 uint32 max_class = current_class ? current_class + 1 : MAX_CLASSES;
4314 for (uint32 r = min_race; r < max_race; ++r)
4315 for (uint32 c = min_class; c < max_class; ++c)
4316 PlayerCreateInfoAddItemHelper(r, c, item_id, amount);
4317 }
4318 else
4319 PlayerCreateInfoAddItemHelper(current_race, current_class, item_id, amount);
4320
4321 ++count;
4322 } while (result->NextRow());
4323
4324 LOG_INFO("server.loading", ">> Loaded {} Custom Player Create Items in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4325 LOG_INFO("server.loading", " ");
4326 }
4327 }
4328
4329 // Load playercreate skills
4330 LOG_INFO("server.loading", "Loading Player Create Skill Data...");
4331 {
4332 uint32 oldMSTime = getMSTime();
4333
4334 QueryResult result = WorldDatabase.Query("SELECT raceMask, classMask, skill, `rank` FROM playercreateinfo_skills");
4335
4336 if (!result)
4337 {
4338 LOG_WARN("server.loading", ">> Loaded 0 Player Create Skills. DB Table `playercreateinfo_skills` Is Empty.");
4339 }
4340 else
4341 {
4342 uint32 count = 0;
4343
4344 do
4345 {
4346 Field* fields = result->Fetch();
4347 uint32 raceMask = fields[0].Get<uint32>();
4348 uint32 classMask = fields[1].Get<uint32>();
4350 skill.SkillId = fields[2].Get<uint16>();
4351 skill.Rank = fields[3].Get<uint16>();
4352
4353 if (skill.Rank >= MAX_SKILL_STEP)
4354 {
4355 LOG_ERROR("sql.sql", "Skill rank value {} set for skill {} raceMask {} classMask {} is too high, max allowed value is {}", skill.Rank, skill.SkillId, raceMask, classMask, MAX_SKILL_STEP);
4356 continue;
4357 }
4358
4359 if (raceMask != 0 && !(raceMask & RACEMASK_ALL_PLAYABLE))
4360 {
4361 LOG_ERROR("sql.sql", "Wrong race mask {} in `playercreateinfo_skills` table, ignoring.", raceMask);
4362 continue;
4363 }
4364
4365 if (classMask != 0 && !(classMask & CLASSMASK_ALL_PLAYABLE))
4366 {
4367 LOG_ERROR("sql.sql", "Wrong class mask {} in `playercreateinfo_skills` table, ignoring.", classMask);
4368 continue;
4369 }
4370
4371 if (!sSkillLineStore.LookupEntry(skill.SkillId))
4372 {
4373 LOG_ERROR("sql.sql", "Wrong skill id {} in `playercreateinfo_skills` table, ignoring.", skill.SkillId);
4374 continue;
4375 }
4376
4377 for (uint32 raceIndex = RACE_HUMAN; raceIndex < MAX_RACES; ++raceIndex)
4378 {
4379 if (raceMask == 0 || ((1 << (raceIndex - 1)) & raceMask))
4380 {
4381 for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex)
4382 {
4383 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
4384 {
4385 if (!GetSkillRaceClassInfo(skill.SkillId, raceIndex, classIndex))
4386 continue;
4387
4388 if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
4389 {
4390 info->skills.push_back(skill);
4391 ++count;
4392 }
4393 }
4394 }
4395 }
4396 }
4397 } while (result->NextRow());
4398
4399 LOG_INFO("server.loading", ">> Loaded {} Player Create Skills in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4400 LOG_INFO("server.loading", " ");
4401 }
4402 }
4403
4404 // Load playercreate spells
4405 LOG_INFO("server.loading", "Loading Player Create Spell Data...");
4406 {
4407 uint32 oldMSTime = getMSTime();
4408
4409 QueryResult result = WorldDatabase.Query("SELECT racemask, classmask, Spell FROM playercreateinfo_spell_custom");
4410
4411 if (!result)
4412 {
4413 LOG_WARN("server.loading", ">> Loaded 0 player create spells. DB table `playercreateinfo_spell_custom` is empty.");
4414 }
4415 else
4416 {
4417 uint32 count = 0;
4418
4419 do
4420 {
4421 Field* fields = result->Fetch();
4422 uint32 raceMask = fields[0].Get<uint32>();
4423 uint32 classMask = fields[1].Get<uint32>();
4424 uint32 spellId = fields[2].Get<uint32>();
4425
4426 if (raceMask != 0 && !(raceMask & RACEMASK_ALL_PLAYABLE))
4427 {
4428 LOG_ERROR("sql.sql", "Wrong race mask {} in `playercreateinfo_spell_custom` table, ignoring.", raceMask);
4429 continue;
4430 }
4431
4432 if (classMask != 0 && !(classMask & CLASSMASK_ALL_PLAYABLE))
4433 {
4434 LOG_ERROR("sql.sql", "Wrong class mask {} in `playercreateinfo_spell_custom` table, ignoring.", classMask);
4435 continue;
4436 }
4437
4438 for (uint32 raceIndex = RACE_HUMAN; raceIndex < MAX_RACES; ++raceIndex)
4439 {
4440 if (raceMask == 0 || ((1 << (raceIndex - 1)) & raceMask))
4441 {
4442 for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex)
4443 {
4444 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
4445 {
4446 if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
4447 {
4448 info->customSpells.push_back(spellId);
4449 ++count;
4450 }
4451 }
4452 }
4453 }
4454 }
4455 } while (result->NextRow());
4456
4457 LOG_INFO("server.loading", ">> Loaded {} Custom Player Create Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4458 LOG_INFO("server.loading", " ");
4459 }
4460 }
4461
4462 // Load playercreate cast spell
4463 LOG_INFO("server.loading", "Loading Player Create Cast Spell Data...");
4464 {
4465 uint32 oldMSTime = getMSTime();
4466
4467 QueryResult result = WorldDatabase.Query("SELECT raceMask, classMask, spell FROM playercreateinfo_cast_spell");
4468
4469 if (!result)
4470 {
4471 LOG_WARN("server.loading", ">> Loaded 0 Player Create Cast Spells. DB Table `playercreateinfo_cast_spell` Is Empty.");
4472 }
4473 else
4474 {
4475 uint32 count = 0;
4476
4477 do
4478 {
4479 Field* fields = result->Fetch();
4480 uint32 raceMask = fields[0].Get<uint32>();
4481 uint32 classMask = fields[1].Get<uint32>();
4482 uint32 spellId = fields[2].Get<uint32>();
4483
4484 if (raceMask != 0 && !(raceMask & RACEMASK_ALL_PLAYABLE))
4485 {
4486 LOG_ERROR("sql.sql", "Wrong race mask {} in `playercreateinfo_cast_spell` table, ignoring.", raceMask);
4487 continue;
4488 }
4489
4490 if (classMask != 0 && !(classMask & CLASSMASK_ALL_PLAYABLE))
4491 {
4492 LOG_ERROR("sql.sql", "Wrong class mask {} in `playercreateinfo_cast_spell` table, ignoring.", classMask);
4493 continue;
4494 }
4495
4496 for (uint32 raceIndex = RACE_HUMAN; raceIndex < MAX_RACES; ++raceIndex)
4497 {
4498 if (raceMask == 0 || ((1 << (raceIndex - 1)) & raceMask))
4499 {
4500 for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex)
4501 {
4502 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
4503 {
4504 if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
4505 {
4506 info->castSpells.push_back(spellId);
4507 ++count;
4508 }
4509 }
4510 }
4511 }
4512 }
4513 } while (result->NextRow());
4514
4515 LOG_INFO("server.loading", ">> Loaded {} Player Create Cast Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4516 LOG_INFO("server.loading", " ");
4517 }
4518 }
4519
4520 // Load playercreate actions
4521 LOG_INFO("server.loading", "Loading Player Create Action Data...");
4522 {
4523 uint32 oldMSTime = getMSTime();
4524
4525 // 0 1 2 3 4
4526 QueryResult result = WorldDatabase.Query("SELECT race, class, button, action, type FROM playercreateinfo_action");
4527
4528 if (!result)
4529 {
4530 LOG_WARN("server.loading", ">> Loaded 0 Player Create Actions. DB Table `playercreateinfo_action` Is Empty.");
4531 LOG_INFO("server.loading", " ");
4532 }
4533 else
4534 {
4535 uint32 count = 0;
4536
4537 do
4538 {
4539 Field* fields = result->Fetch();
4540
4541 uint32 current_race = fields[0].Get<uint8>();
4542 if (current_race >= MAX_RACES)
4543 {
4544 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo_action` table, ignoring.", current_race);
4545 continue;
4546 }
4547
4548 uint32 current_class = fields[1].Get<uint8>();
4549 if (current_class >= MAX_CLASSES)
4550 {
4551 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo_action` table, ignoring.", current_class);
4552 continue;
4553 }
4554
4555 if (PlayerInfo* info = _playerInfo[current_race][current_class])
4556 info->action.push_back(PlayerCreateInfoAction(fields[2].Get<uint16>(), fields[3].Get<uint32>(), fields[4].Get<uint16>()));
4557
4558 ++count;
4559 } while (result->NextRow());
4560
4561 LOG_INFO("server.loading", ">> Loaded {} Player Create Actions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4562 LOG_INFO("server.loading", " ");
4563 }
4564 }
4565
4566 // Loading levels data (class/race dependent)
4567 LOG_INFO("server.loading", "Loading Player Create Level Stats Data...");
4568 {
4569 struct RaceStats
4570 {
4571 int16 StatModifier[MAX_STATS];
4572 };
4573
4574 std::array<RaceStats, MAX_RACES> raceStatModifiers;
4575
4576 uint32 oldMSTime = getMSTime();
4577
4578 // 0 1 2 3 4 5
4579 QueryResult raceStatsResult = WorldDatabase.Query("SELECT Race, Strength, Agility, Stamina, Intellect, Spirit FROM player_race_stats");
4580
4581 if (!raceStatsResult)
4582 {
4583 LOG_WARN("server.loading", ">> Loaded 0 race stats definitions. DB table `player_race_stats` is empty.");
4584 LOG_INFO("server.loading", " ");
4585 exit(1);
4586 }
4587
4588 do
4589 {
4590 Field* fields = raceStatsResult->Fetch();
4591
4592 uint32 current_race = fields[0].Get<uint8>();
4593 if (current_race >= MAX_RACES)
4594 {
4595 LOG_ERROR("sql.sql", "Wrong race {} in `player_race_stats` table, ignoring.", current_race);
4596 continue;
4597 }
4598
4599 for (uint32 i = 0; i < MAX_STATS; ++i)
4600 raceStatModifiers[current_race].StatModifier[i] = fields[i + 1].Get<int16>();
4601
4602 } while (raceStatsResult->NextRow());
4603
4604 // 0 1 2 3 4 5 6 7 8
4605 QueryResult result = WorldDatabase.Query("SELECT Class, Level, Strength, Agility, Stamina, Intellect, Spirit, BaseHP, BaseMana FROM player_class_stats");
4606
4607 if (!result)
4608 {
4609 LOG_ERROR("server.loading", ">> Loaded 0 level stats definitions. DB table `player_class_stats` is empty.");
4610 exit(1);
4611 }
4612
4613 uint32 count = 0;
4614
4615 do
4616 {
4617 Field* fields = result->Fetch();
4618
4619 uint32 current_class = fields[0].Get<uint8>();
4620 if (current_class >= MAX_CLASSES)
4621 {
4622 LOG_ERROR("sql.sql", "Wrong class {} in `player_class_stats` table, ignoring.", current_class);
4623 continue;
4624 }
4625
4626 uint32 current_level = fields[1].Get<uint8>();
4627 if (current_level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4628 {
4629 if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
4630 LOG_ERROR("sql.sql", "Wrong (> {}) level {} in `player_class_stats` table, ignoring.", STRONG_MAX_LEVEL, current_level);
4631 else
4632 LOG_DEBUG("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_class_stats` table, ignoring.", current_level);
4633
4634 continue;
4635 }
4636
4637 for (std::size_t race = 0; race < raceStatModifiers.size(); ++race)
4638 {
4639 if (PlayerInfo* info = _playerInfo[race][current_class])
4640 {
4641 if (!info->levelInfo)
4642 info->levelInfo = new PlayerLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)];
4643
4644 PlayerLevelInfo& levelInfo = info->levelInfo[current_level - 1];
4645 for (int i = 0; i < MAX_STATS; ++i)
4646 levelInfo.stats[i] = fields[i + 2].Get<uint16>() + raceStatModifiers[race].StatModifier[i];
4647 }
4648 }
4649
4650 PlayerClassInfo* info = _playerClassInfo[current_class];
4651 if (!info)
4652 {
4653 info = new PlayerClassInfo();
4655 _playerClassInfo[current_class] = info;
4656 }
4657
4658 PlayerClassLevelInfo& levelInfo = info->levelInfo[current_level - 1];
4659
4660 levelInfo.basehealth = fields[7].Get<uint32>();
4661 levelInfo.basemana = fields[8].Get<uint32>();
4662
4663 ++count;
4664 } while (result->NextRow());
4665
4666 // Fill gaps and check integrity
4667 for (int race = 0; race < MAX_RACES; ++race)
4668 {
4669 // skip non existed races
4670 if (!sChrRacesStore.LookupEntry(race))
4671 continue;
4672
4673 for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
4674 {
4675 // skip non existed classes
4676 if (!sChrClassesStore.LookupEntry(class_))
4677 continue;
4678
4679 PlayerClassInfo* pClassInfo = _playerClassInfo[class_];
4680 PlayerInfo* info = _playerInfo[race][class_];
4681 if (!info)
4682 continue;
4683
4684 // skip expansion races if not playing with expansion
4685 if (sWorld->getIntConfig(CONFIG_EXPANSION) < EXPANSION_THE_BURNING_CRUSADE && (race == RACE_BLOODELF || race == RACE_DRAENEI))
4686 continue;
4687
4688 // skip expansion classes if not playing with expansion
4690 continue;
4691
4692 // fatal error if no initial stats data
4693 if (!info->levelInfo || (info->levelInfo[sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL) - 1].stats[0] == 0 && class_ != CLASS_DEATH_KNIGHT) || (info->levelInfo[sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL) - 1].stats[0] == 0 && class_ == CLASS_DEATH_KNIGHT))
4694 {
4695 LOG_ERROR("sql.sql", "Race {} class {} initial level does not have stats data!", race, class_);
4696 exit(1);
4697 }
4698
4699 // fatal error if no initial health/mana data
4700 if (!pClassInfo->levelInfo || (pClassInfo->levelInfo[sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL) - 1].basehealth == 0 && class_ != CLASS_DEATH_KNIGHT) || (pClassInfo->levelInfo[sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL) - 1].basehealth == 0 && class_ == CLASS_DEATH_KNIGHT))
4701 {
4702 LOG_ERROR("sql.sql", "Class {} initial level does not have health/mana data!", class_);
4703 exit(1);
4704 }
4705
4706 // fill level gaps for stats
4707 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4708 {
4709 if ((info->levelInfo[level].stats[0] == 0 && class_ != CLASS_DEATH_KNIGHT) || (level >= sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL) && info->levelInfo[level].stats[0] == 0 && class_ == CLASS_DEATH_KNIGHT))
4710 {
4711 LOG_ERROR("sql.sql", "Race {} class {} level {} does not have stats data. Using stats data of level {}.", race, class_, level + 1, level);
4712 info->levelInfo[level] = info->levelInfo[level - 1];
4713 }
4714 }
4715
4716 // fill level gaps for health/mana
4717 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4718 {
4719 if ((pClassInfo->levelInfo[level].basehealth == 0 && class_ != CLASS_DEATH_KNIGHT) || (level >= sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL) && pClassInfo->levelInfo[level].basehealth == 0 && class_ == CLASS_DEATH_KNIGHT))
4720 {
4721 LOG_ERROR("sql.sql", "Class {} level {} does not have health/mana data. Using stats data of level {}.", class_, level + 1, level);
4722 pClassInfo->levelInfo[level] = pClassInfo->levelInfo[level - 1];
4723 }
4724 }
4725 }
4726 }
4727
4728 LOG_INFO("server.loading", ">> Loaded {} Level Stats Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4729 LOG_INFO("server.loading", " ");
4730 }
4731
4732 // Loading xp per level data
4733 LOG_INFO("server.loading", "Loading Player Create XP Data...");
4734 {
4735 uint32 oldMSTime = getMSTime();
4736
4737 _playerXPperLevel.resize(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
4738 for (uint8 level = 0; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4739 _playerXPperLevel[level] = 0;
4740
4741 // 0 1
4742 QueryResult result = WorldDatabase.Query("SELECT Level, Experience FROM player_xp_for_level");
4743
4744 if (!result)
4745 {
4746 LOG_WARN("server.loading", ">> Loaded 0 xp for level definitions. DB table `player_xp_for_level` is empty.");
4747 LOG_INFO("server.loading", " ");
4748 exit(1);
4749 }
4750
4751 uint32 count = 0;
4752
4753 do
4754 {
4755 Field* fields = result->Fetch();
4756
4757 uint32 current_level = fields[0].Get<uint8>();
4758 uint32 current_xp = fields[1].Get<uint32>();
4759
4760 if (current_level >= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4761 {
4762 if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
4763 LOG_ERROR("sql.sql", "Wrong (> {}) level {} in `player_xp_for_level` table, ignoring.", STRONG_MAX_LEVEL, current_level);
4764 else
4765 {
4766 LOG_DEBUG("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_xp_for_levels` table, ignoring.", current_level);
4767 ++count; // make result loading percent "expected" correct in case disabled detail mode for example.
4768 }
4769 continue;
4770 }
4771 //PlayerXPperLevel
4772 _playerXPperLevel[current_level] = current_xp;
4773 ++count;
4774 } while (result->NextRow());
4775
4776 // fill level gaps
4777 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4778 {
4779 if (_playerXPperLevel[level] == 0)
4780 {
4781 LOG_ERROR("sql.sql", "Level {} does not have XP for level data. Using data of level [{}] + 100.", level + 1, level);
4782 _playerXPperLevel[level] = _playerXPperLevel[level - 1] + 100;
4783 }
4784 }
4785
4786 LOG_INFO("server.loading", ">> Loaded {} XP For Level Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4787 LOG_INFO("server.loading", " ");
4788 }
4789}
SkillRaceClassInfoEntry const * GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_)
Definition DBCStores.cpp:895
DBCStorage< ChrRacesEntry > sChrRacesStore(ChrRacesEntryfmt)
DBCStorage< SkillLineEntry > sSkillLineStore(SkillLinefmt)
DBCStorage< ChrClassesEntry > sChrClassesStore(ChrClassesEntryfmt)
#define MAX_SKILL_STEP
Definition DBCStructure.h:1580
@ CLASS_DEATH_KNIGHT
Definition SharedDefines.h:146
@ RACE_DRAENEI
Definition SharedDefines.h:81
@ RACE_BLOODELF
Definition SharedDefines.h:80
@ RACE_HUMAN
Definition SharedDefines.h:71
@ EXPANSION_THE_BURNING_CRUSADE
Definition SharedDefines.h:54
@ EXPANSION_WRATH_OF_THE_LICH_KING
Definition SharedDefines.h:55
@ CONFIG_START_HEROIC_PLAYER_LEVEL
Definition WorldConfig.h:193
@ CONFIG_START_PLAYER_LEVEL
Definition WorldConfig.h:192
@ CONFIG_EXPANSION
Definition WorldConfig.h:229
void PlayerCreateInfoAddItemHelper(uint32 race_, uint32 class_, uint32 itemId, int32 count)
Definition ObjectMgr.cpp:4136
Definition DBCStructure.h:679
uint32 model_f
Definition DBCStructure.h:685
uint32 model_m
Definition DBCStructure.h:684
Definition Player.h:277
uint32 basehealth
Definition Player.h:279
uint32 basemana
Definition Player.h:280
Definition Player.h:303
Definition Player.h:315
uint16 SkillId
Definition Player.h:316
float orientation
Definition Player.h:332
uint16 displayId_m
Definition Player.h:333
float positionX
Definition Player.h:329
uint32 areaId
Definition Player.h:328
float positionY
Definition Player.h:330
float positionZ
Definition Player.h:331
uint32 mapId
Definition Player.h:327
uint16 displayId_f
Definition Player.h:334
Definition Player.h:291

References _playerClassInfo, _playerInfo, _playerXPperLevel, PlayerInfo::areaId, PlayerClassLevelInfo::basehealth, PlayerClassLevelInfo::basemana, CLASS_DEATH_KNIGHT, CLASS_WARRIOR, CLASSMASK_ALL_PLAYABLE, CONFIG_EXPANSION, CONFIG_MAX_PLAYER_LEVEL, CONFIG_START_HEROIC_PLAYER_LEVEL, CONFIG_START_PLAYER_LEVEL, PlayerInfo::displayId_f, PlayerInfo::displayId_m, EXPANSION_THE_BURNING_CRUSADE, EXPANSION_WRATH_OF_THE_LICH_KING, Field::Get(), GetItemTemplate(), getMSTime(), GetMSTimeDiffToNow(), GetSkillRaceClassInfo(), MapMgr::IsValidMapCoord(), PlayerClassInfo::levelInfo, PlayerInfo::levelInfo, LOG_DEBUG, LOG_ERROR, LOG_INFO, LOG_WARN, PlayerInfo::mapId, MAX_CLASSES, MAX_RACES, MAX_SKILL_STEP, MAX_STATS, ChrRacesEntry::model_f, ChrRacesEntry::model_m, PlayerInfo::orientation, PlayerCreateInfoAddItemHelper(), PlayerInfo::positionX, PlayerInfo::positionY, PlayerInfo::positionZ, RACE_BLOODELF, RACE_DRAENEI, RACE_HUMAN, RACEMASK_ALL_PLAYABLE, sChrClassesStore, sChrRacesStore, PlayerCreateInfoSkill::SkillId, sMapStore, sSkillLineStore, PlayerLevelInfo::stats, STRONG_MAX_LEVEL, sWorld, and WorldDatabase.

◆ LoadPlayerShapeshiftModels()

void ObjectMgr::LoadPlayerShapeshiftModels ( )
1836{
1837 uint32 oldMSTime = getMSTime();
1838
1839 QueryResult result = WorldDatabase.Query("SELECT ShapeshiftID, RaceID, CustomizationID, GenderID, ModelID from player_shapeshift_model");
1840
1841 if (!result)
1842 {
1843 LOG_INFO("server.loading", ">> Loaded 0 player shapeshift model records. DB table `player_shapeshift_model` is empty.");
1844 return;
1845 }
1846
1847 uint32 count = 0;
1848 do
1849 {
1850 Field* fields = result->Fetch();
1851
1852 ShapeshiftForm shapeshiftForm = ShapeshiftForm(fields[0].Get<uint8>());
1853 uint8 race = fields[1].Get<uint8>();
1854 uint8 customizationID = fields[2].Get<uint8>();
1855 uint8 genderID = Gender(fields[3].Get<uint8>());
1856 uint32 modelId = fields[4].Get<uint32>();
1857
1858 ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race);
1859 if (!raceEntry)
1860 {
1861 LOG_ERROR("sql.sql", "Race {} defined in `player_shapeshift_model` does not exists, skipped.", uint32(race));
1862 continue;
1863 }
1864
1865 CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(modelId);
1866 if (!displayEntry)
1867 {
1868 LOG_ERROR("sql.sql", "ShapeshiftForm: {}, Race: {} defined in `player_shapeshift_model` has non-existing model ({}), skipped.", shapeshiftForm, race, modelId);
1869 continue;
1870 }
1871
1872 _playerShapeshiftModel[std::make_tuple(shapeshiftForm, race, customizationID, genderID)] = modelId;
1873 ++count;
1874 } while (result->NextRow());
1875
1876 LOG_INFO("server.loading", ">> Loaded {} player totem model records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1877 LOG_INFO("server.loading", " ");
1878}
Gender
Definition SharedDefines.h:60
ShapeshiftForm
Definition UnitDefines.h:68

References _playerShapeshiftModel, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, sChrRacesStore, sCreatureDisplayInfoStore, and WorldDatabase.

◆ LoadPlayerTotemModels()

void ObjectMgr::LoadPlayerTotemModels ( )
1777{
1778 uint32 oldMSTime = getMSTime();
1779
1780 QueryResult result = WorldDatabase.Query("SELECT TotemID, RaceID, ModelID from player_totem_model");
1781
1782 if (!result)
1783 {
1784 LOG_INFO("server.loading", ">> Loaded 0 player totem model records. DB table `player_totem_model` is empty.");
1785 return;
1786 }
1787
1788 uint32 count = 0;
1789 do
1790 {
1791 Field* fields = result->Fetch();
1792
1793 SummonSlot totemSlot = SummonSlot(fields[0].Get<uint8>());
1794 uint8 race = fields[1].Get<uint8>();
1795 uint32 displayId = fields[2].Get<uint32>();
1796
1797 if (totemSlot < SUMMON_SLOT_TOTEM_FIRE || totemSlot >= MAX_TOTEM_SLOT)
1798 {
1799 LOG_ERROR("sql.sql", "Wrong TotemSlot {} in `player_totem_model` table, skipped.", totemSlot);
1800 continue;
1801 }
1802
1803 ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race);
1804 if (!raceEntry)
1805 {
1806 LOG_ERROR("sql.sql", "Race {} defined in `player_totem_model` does not exists, skipped.", uint32(race));
1807 continue;
1808 }
1809
1810 CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(displayId);
1811 if (!displayEntry)
1812 {
1813 LOG_ERROR("sql.sql", "TotemSlot: {} defined in `player_totem_model` has non-existing model ({}), skipped.", totemSlot, displayId);
1814 continue;
1815 }
1816
1817 _playerTotemModel[std::make_pair(totemSlot, Races(race))] = displayId;
1818 ++count;
1819 } while (result->NextRow());
1820
1821 LOG_INFO("server.loading", ">> Loaded {} player totem model records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1822 LOG_INFO("server.loading", " ");
1823}
#define MAX_TOTEM_SLOT
Definition SharedDefines.h:3562
SummonSlot
Definition SharedDefines.h:3550
Races
Definition SharedDefines.h:69

References _playerTotemModel, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, MAX_TOTEM_SLOT, sChrRacesStore, sCreatureDisplayInfoStore, and WorldDatabase.

◆ LoadPointOfInterestLocales()

void ObjectMgr::LoadPointOfInterestLocales ( )
492{
493 uint32 oldMSTime = getMSTime();
494
495 _pointOfInterestLocaleStore.clear(); // need for reload case
496
497 // 0 1 2
498 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Name FROM points_of_interest_locale");
499
500 if (!result)
501 return;
502
503 do
504 {
505 Field* fields = result->Fetch();
506
507 uint32 ID = fields[0].Get<uint32>();
508
509 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
510 if (locale == LOCALE_enUS)
511 continue;
512
514 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
515 } while (result->NextRow());
516
517 LOG_INFO("server.loading", ">> Loaded {} Points Of Interest Locale Strings in {} ms", (uint32)_pointOfInterestLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
518}
Definition CreatureData.h:351
std::vector< std::string > Name
Definition CreatureData.h:352

References _pointOfInterestLocaleStore, AddLocaleString(), Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), LOCALE_enUS, LOG_INFO, PointOfInterestLocale::Name, and WorldDatabase.

◆ LoadPointsOfInterest()

void ObjectMgr::LoadPointsOfInterest ( )
8368{
8369 uint32 oldMSTime = getMSTime();
8370
8371 _pointsOfInterestStore.clear(); // need for reload case
8372
8373 uint32 count = 0;
8374
8375 // 0 1 2 3 4 5 6
8376 QueryResult result = WorldDatabase.Query("SELECT ID, PositionX, PositionY, Icon, Flags, Importance, Name FROM points_of_interest");
8377
8378 if (!result)
8379 {
8380 LOG_WARN("server.loading", ">> Loaded 0 Points of Interest definitions. DB table `points_of_interest` is empty.");
8381 LOG_INFO("server.loading", " ");
8382 return;
8383 }
8384
8385 do
8386 {
8387 Field* fields = result->Fetch();
8388
8389 uint32 point_id = fields[0].Get<uint32>();
8390
8391 PointOfInterest POI;
8392 POI.ID = point_id;
8393 POI.PositionX = fields[1].Get<float>();
8394 POI.PositionY = fields[2].Get<float>();
8395 POI.Icon = fields[3].Get<uint32>();
8396 POI.Flags = fields[4].Get<uint32>();
8397 POI.Importance = fields[5].Get<uint32>();
8398 POI.Name = fields[6].Get<std::string>();
8399
8400 if (!Acore::IsValidMapCoord(POI.PositionX, POI.PositionY))
8401 {
8402 LOG_ERROR("sql.sql", "Table `points_of_interest` (ID: {}) have invalid coordinates (X: {} Y: {}), ignored.", point_id, POI.PositionX, POI.PositionY);
8403 continue;
8404 }
8405
8406 _pointsOfInterestStore[point_id] = POI;
8407
8408 ++count;
8409 } while (result->NextRow());
8410
8411 LOG_INFO("server.loading", ">> Loaded {} Points of Interest Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8412 LOG_INFO("server.loading", " ");
8413}
bool IsValidMapCoord(float c)
Definition GridDefines.h:210
Definition ObjectMgr.h:589
uint32 ID
Definition ObjectMgr.h:590

References _pointsOfInterestStore, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), PointOfInterest::ID, Acore::IsValidMapCoord(), LOG_ERROR, LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadProfanityNamesFromDB()

void ObjectMgr::LoadProfanityNamesFromDB ( )
8790{
8791 uint32 oldMSTime = getMSTime();
8792
8793 _profanityNamesStore.clear(); // need for reload case
8794
8795 QueryResult result = CharacterDatabase.Query("SELECT name FROM profanity_name");
8796
8797 if (!result)
8798 {
8799 LOG_WARN("server.loading", ">> Loaded 0 profanity names. DB table `profanity_name` is empty!");
8800 return;
8801 }
8802
8803 uint32 count = 0;
8804
8805 Field* fields;
8806 do
8807 {
8808 fields = result->Fetch();
8809 std::string name = fields[0].Get<std::string>();
8810
8811 std::wstring wstr;
8812 if (!Utf8toWStr (name, wstr))
8813 {
8814 LOG_ERROR("sql.sql", "Table `profanity_name` have invalid name: {}", name);
8815 continue;
8816 }
8817
8818 wstrToLower(wstr);
8819
8820 _profanityNamesStore.insert(wstr);
8821 ++count;
8822 } while (result->NextRow());
8823
8824 LOG_INFO("server.loading", ">> Loaded {} profanity names from DB in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8825}

References _profanityNamesStore, CharacterDatabase, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, Utf8toWStr(), and wstrToLower().

◆ LoadProfanityNamesFromDBC()

void ObjectMgr::LoadProfanityNamesFromDBC ( )
8828{
8829 if (!sWorld->getBoolConfig(CONFIG_STRICT_NAMES_PROFANITY))
8830 {
8831 LOG_WARN("server.loading", ">> Loaded 0 profanity names from DBC. Config option disabled.");
8832 return;
8833 }
8834
8835 uint32 oldMSTime = getMSTime();
8836
8837 uint32 count = 0;
8838
8839 for (NamesProfanityEntry const* profanityStore : sNamesProfanityStore)
8840 {
8841 std::wstring wstr;
8842
8843 Utf8toWStr(profanityStore->Pattern, wstr);
8844
8845 // DBC does not have clean entries, remove the junk.
8846 boost::algorithm::replace_all(wstr, "\\<", "");
8847 boost::algorithm::replace_all(wstr, "\\>", "");
8848
8849 _profanityNamesStore.insert(wstr);
8850 count++;
8851 }
8852
8853 LOG_INFO("server.loading", ">> Loaded {} profanity names from DBC in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8854 LOG_INFO("server.loading", " ");
8855}
DBCStorage< NamesProfanityEntry > sNamesProfanityStore(NamesProfanityfmt)
@ CONFIG_STRICT_NAMES_PROFANITY
Definition WorldConfig.h:142
Definition DBCStructure.h:1405

References _profanityNamesStore, CONFIG_STRICT_NAMES_PROFANITY, getMSTime(), GetMSTimeDiffToNow(), LOG_INFO, LOG_WARN, sNamesProfanityStore, sWorld, and Utf8toWStr().

◆ LoadQuestAreaTriggers()

void ObjectMgr::LoadQuestAreaTriggers ( )
6746{
6747 uint32 oldMSTime = getMSTime();
6748
6749 _questAreaTriggerStore.clear(); // need for reload case
6750
6751 QueryResult result = WorldDatabase.Query("SELECT id, quest FROM areatrigger_involvedrelation");
6752
6753 if (!result)
6754 {
6755 LOG_WARN("server.loading", ">> Loaded 0 quest trigger points. DB table `areatrigger_involvedrelation` is empty.");
6756 LOG_INFO("server.loading", " ");
6757 return;
6758 }
6759
6760 uint32 count = 0;
6761
6762 do
6763 {
6764 ++count;
6765
6766 Field* fields = result->Fetch();
6767
6768 uint32 trigger_ID = fields[0].Get<uint32>();
6769 uint32 quest_ID = fields[1].Get<uint32>();
6770
6771 AreaTrigger const* atEntry = GetAreaTrigger(trigger_ID);
6772 if (!atEntry)
6773 {
6774 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", trigger_ID);
6775 continue;
6776 }
6777
6778 Quest const* quest = GetQuestTemplate(quest_ID);
6779
6780 if (!quest)
6781 {
6782 LOG_ERROR("sql.sql", "Table `areatrigger_involvedrelation` has record (id: {}) for not existing quest {}", trigger_ID, quest_ID);
6783 continue;
6784 }
6785
6787 {
6788 LOG_ERROR("sql.sql", "Table `areatrigger_involvedrelation` has record (id: {}) for not quest {}, but quest not have specialflag QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT. Trigger or quest flags must be fixed, quest modified to require objective.", trigger_ID, quest_ID);
6789
6790 // this will prevent quest completing without objective
6791 const_cast<Quest*>(quest)->SetSpecialFlag(QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT);
6792
6793 // continue; - quest modified to required objective and trigger can be allowed.
6794 }
6795
6796 _questAreaTriggerStore[trigger_ID] = quest_ID;
6797 } while (result->NextRow());
6798
6799 LOG_INFO("server.loading", ">> Loaded {} Quest Trigger Points in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6800 LOG_INFO("server.loading", " ");
6801}
@ QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT
Definition QuestDef.h:161
Definition QuestDef.h:210
bool HasSpecialFlag(uint32 flag) const
Definition QuestDef.h:224

References _questAreaTriggerStore, Field::Get(), GetAreaTrigger(), getMSTime(), GetMSTimeDiffToNow(), GetQuestTemplate(), Quest::HasSpecialFlag(), LOG_ERROR, LOG_INFO, LOG_WARN, QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT, and WorldDatabase.

◆ LoadQuestGreetings()

void ObjectMgr::LoadQuestGreetings ( )
6822{
6823 uint32 oldMSTime = getMSTime();
6824
6825 _questGreetingStore.clear(); // For reload case
6826
6827 // 0 1 2 3 4
6828 QueryResult result = WorldDatabase.Query("SELECT ID, Type, GreetEmoteType, GreetEmoteDelay, Greeting FROM quest_greeting");
6829 if (!result)
6830 {
6831 LOG_WARN("server.loading", ">> Loaded 0 quest greetings. DB table `quest_greeting` is empty.");
6832 return;
6833 }
6834
6835 do
6836 {
6837 Field* fields = result->Fetch();
6838
6839 uint32 id = fields[0].Get<uint32>();
6840 uint8 type = fields[1].Get<uint8>();
6841 switch (type)
6842 {
6843 case 0: // Creature
6844 if (!GetCreatureTemplate(id))
6845 {
6846 LOG_ERROR("sql.sql", "Table `quest_greeting`: creature template entry {} does not exist.", id);
6847 continue;
6848 }
6849 break;
6850 case 1: // GameObject
6851 if (!GetGameObjectTemplate(id))
6852 {
6853 LOG_ERROR("sql.sql", "Table `quest_greeting`: gameobject template entry {} does not exist.", id);
6854 continue;
6855 }
6856 break;
6857 default:
6858 LOG_ERROR("sql.sql", "Table `quest_greeting` has unknown type {} for id {}, skipped.", type, id);
6859 continue;
6860 }
6861
6862 std::pair<uint32, uint8> pairKey = std::make_pair(id, type);
6863 QuestGreeting& data = _questGreetingStore[pairKey];
6864
6865 data.EmoteType = fields[2].Get<uint16>();
6866 data.EmoteDelay = fields[3].Get<uint32>();
6867 AddLocaleString(fields[4].Get<std::string>(), LOCALE_enUS, data.Greeting);
6868 }
6869 while (result->NextRow());
6870
6871 LOG_INFO("server.loading", ">> Loaded {} quest_greeting in {} ms", _questGreetingStore.size(), GetMSTimeDiffToNow(oldMSTime));
6872 LOG_INFO("server.loading", " ");
6873}
Definition ObjectMgr.h:600
uint32 EmoteDelay
Definition ObjectMgr.h:602
std::vector< std::string > Greeting
Definition ObjectMgr.h:603
uint16 EmoteType
Definition ObjectMgr.h:601

References _questGreetingStore, AddLocaleString(), QuestGreeting::EmoteDelay, QuestGreeting::EmoteType, Field::Get(), GetCreatureTemplate(), GetGameObjectTemplate(), getMSTime(), GetMSTimeDiffToNow(), QuestGreeting::Greeting, LOCALE_enUS, LOG_ERROR, LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadQuestGreetingsLocales()

void ObjectMgr::LoadQuestGreetingsLocales ( )
6876{
6877 uint32 oldMSTime = getMSTime();
6878
6879 // 0 1 2 3
6880 QueryResult result = WorldDatabase.Query("SELECT ID, Type, Locale, Greeting FROM quest_greeting_locale");
6881 if (!result)
6882 {
6883 LOG_WARN("server.loading", ">> Loaded 0 quest_greeting locales. DB table `quest_greeting_locale` is empty.");
6884 return;
6885 }
6886
6887 uint32 localeCount = 0;
6888 do
6889 {
6890 Field* fields = result->Fetch();
6891
6892 uint32 id = fields[0].Get<uint32>();
6893 uint8 type = fields[1].Get<uint8>();
6894 switch (type)
6895 {
6896 case 0: // Creature
6897 if (!GetCreatureTemplate(id))
6898 {
6899 LOG_ERROR("sql.sql", "Table `quest_greeting_locale`: creature template entry {} does not exist.", id);
6900 continue;
6901 }
6902 break;
6903 case 1: // GameObject
6904 if (!GetGameObjectTemplate(id))
6905 {
6906 LOG_ERROR("sql.sql", "Table `quest_greeting_locale`: gameobject template entry {} does not exist.", id);
6907 continue;
6908 }
6909 break;
6910 default:
6911 continue;
6912 }
6913
6914 std::pair<uint32, uint8> pairKey = std::make_pair(id, type);
6915 QuestGreeting& data = _questGreetingStore[pairKey];
6916
6917 QuestGreetingContainer::iterator qgc = _questGreetingStore.find(pairKey);
6918 if (qgc == _questGreetingStore.end())
6919 {
6920 LOG_ERROR("sql.sql", "QuestGreeting (Id: {} Type: {}) found in table `quest_greeting_locale` but does not exist in `quest_greeting`. Skipped!", id, type);
6921 continue;
6922 }
6923
6924 LocaleConstant locale = GetLocaleByName(fields[2].Get<std::string>());
6925 if (locale == LOCALE_enUS)
6926 continue;
6927
6928 AddLocaleString(fields[3].Get<std::string>(), locale, data.Greeting);
6929 localeCount++;
6930 } while (result->NextRow());
6931
6932 LOG_INFO("server.loading", ">> Loaded {} quest greeting Locale Strings in {} ms", localeCount, GetMSTimeDiffToNow(oldMSTime));
6933 LOG_INFO("server.loading", " ");
6934}

References _questGreetingStore, AddLocaleString(), Field::Get(), GetCreatureTemplate(), GetGameObjectTemplate(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), QuestGreeting::Greeting, LOCALE_enUS, LOG_ERROR, LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadQuestLocales()

void ObjectMgr::LoadQuestLocales ( )
5706{
5707 uint32 oldMSTime = getMSTime();
5708
5709 _questLocaleStore.clear(); // need for reload case
5710
5711 // 0 1 2 3 4 5 6 7 8 9 10
5712 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Title, Details, Objectives, EndText, CompletedText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4 FROM quest_template_locale");
5713
5714 if (!result)
5715 return;
5716
5717 do
5718 {
5719 Field* fields = result->Fetch();
5720
5721 uint32 ID = fields[0].Get<uint32>();
5722
5723 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
5724 if (locale == LOCALE_enUS)
5725 continue;
5726
5727 QuestLocale& data = _questLocaleStore[ID];
5728 AddLocaleString(fields[2].Get<std::string>(), locale, data.Title);
5729 AddLocaleString(fields[3].Get<std::string>(), locale, data.Details);
5730 AddLocaleString(fields[4].Get<std::string>(), locale, data.Objectives);
5731 AddLocaleString(fields[5].Get<std::string>(), locale, data.AreaDescription);
5732 AddLocaleString(fields[6].Get<std::string>(), locale, data.CompletedText);
5733
5734 for (uint8 i = 0; i < 4; ++i)
5735 AddLocaleString(fields[i + 7].Get<std::string>(), locale, data.ObjectiveText[i]);
5736 } while (result->NextRow());
5737
5738 LOG_INFO("server.loading", ">> Loaded {} Quest Locale Strings in {} ms", (uint32)_questLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
5739}
Definition QuestDef.h:183
std::vector< std::string > AreaDescription
Definition QuestDef.h:191
std::vector< std::string > CompletedText
Definition QuestDef.h:192
std::vector< std::string > Title
Definition QuestDef.h:186
std::vector< std::string > Objectives
Definition QuestDef.h:188
std::vector< std::vector< std::string > > ObjectiveText
Definition QuestDef.h:193
std::vector< std::string > Details
Definition QuestDef.h:187

References _questLocaleStore, AddLocaleString(), QuestLocale::AreaDescription, QuestLocale::CompletedText, QuestLocale::Details, Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), LOCALE_enUS, LOG_INFO, QuestLocale::Objectives, QuestLocale::ObjectiveText, QuestLocale::Title, and WorldDatabase.

◆ LoadQuestMoneyRewards()

void ObjectMgr::LoadQuestMoneyRewards ( )
10797{
10798 uint32 oldMSTime = getMSTime();
10799
10800 _questMoneyRewards.clear();
10801
10802 // 0 1 2 3 4 5 6 7 8 9 10
10803 QueryResult result = WorldDatabase.Query("SELECT `Level`, Money0, Money1, Money2, Money3, Money4, Money5, Money6, Money7, Money8, Money9 FROM `quest_money_reward` ORDER BY `Level`");
10804 if (!result)
10805 {
10806 LOG_WARN("server.loading", ">> Loaded 0 quest money rewards. DB table `quest_money_reward` is empty.");
10807 return;
10808 }
10809
10810 uint32 count = 0;
10811 do
10812 {
10813 Field* fields = result->Fetch();
10814 uint32 Level = fields[0].Get<uint32>();
10815
10816 QuestMoneyRewardArray& questMoneyReward = _questMoneyRewards[Level];
10817 questMoneyReward.fill(0);
10818
10819 for (uint8 i = 0; i < MAX_QUEST_MONEY_REWARDS; ++i)
10820 {
10821 questMoneyReward[i] = fields[1 + i].Get<uint32>();
10822 ++count;
10823 }
10824 } while (result->NextRow());
10825
10826 LOG_INFO("server.loading", ">> Loaded {} Quest Money Rewards in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10827 LOG_INFO("server.loading", " ");
10828}
std::array< uint32, MAX_QUEST_MONEY_REWARDS > QuestMoneyRewardArray
Definition ObjectMgr.h:719

References _questMoneyRewards, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), Level, LOG_INFO, LOG_WARN, MAX_QUEST_MONEY_REWARDS, and WorldDatabase.

◆ LoadQuestOfferRewardLocale()

void ObjectMgr::LoadQuestOfferRewardLocale ( )
6937{
6938 uint32 oldMSTime = getMSTime();
6939
6940 _questOfferRewardLocaleStore.clear(); // need for reload case
6941
6942 // 0 1 2
6943 QueryResult result = WorldDatabase.Query("SELECT Id, locale, RewardText FROM quest_offer_reward_locale");
6944 if (!result)
6945 return;
6946
6947 do
6948 {
6949 Field* fields = result->Fetch();
6950
6951 uint32 id = fields[0].Get<uint32>();
6952 std::string localeName = fields[1].Get<std::string>();
6953
6954 LocaleConstant locale = GetLocaleByName(localeName);
6955 if (locale == LOCALE_enUS)
6956 continue;
6957
6959 AddLocaleString(fields[2].Get<std::string>(), locale, data.RewardText);
6960 } while (result->NextRow());
6961
6962 LOG_INFO("server.loading", ">> Loaded {} Quest Offer Reward Locale Strings in {} ms", _questOfferRewardLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
6963}
Definition QuestDef.h:202
std::vector< std::string > RewardText
Definition QuestDef.h:203

References _questOfferRewardLocaleStore, AddLocaleString(), Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), LOCALE_enUS, LOG_INFO, QuestOfferRewardLocale::RewardText, and WorldDatabase.

◆ LoadQuestPOI()

void ObjectMgr::LoadQuestPOI ( )
8416{
8417 if (!sWorld->getBoolConfig(CONFIG_QUEST_POI_ENABLED))
8418 {
8419 LOG_INFO("server.loading", ">> Loaded 0 quest POI definitions. Disabled by config.");
8420 LOG_INFO("server.loading", " ");
8421 return;
8422 }
8423
8424 uint32 oldMSTime = getMSTime();
8425
8426 _questPOIStore.clear(); // need for reload case
8427
8428 uint32 count = 0;
8429
8430 // 0 1 2 3 4 5 6 7
8431 QueryResult result = WorldDatabase.Query("SELECT QuestID, id, ObjectiveIndex, MapID, WorldMapAreaId, Floor, Priority, Flags FROM quest_poi order by QuestID");
8432
8433 if (!result)
8434 {
8435 LOG_WARN("server.loading", ">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty.");
8436 LOG_INFO("server.loading", " ");
8437 return;
8438 }
8439
8440 // 0 1 2 3
8441 QueryResult points = WorldDatabase.Query("SELECT QuestID, Idx1, X, Y FROM quest_poi_points ORDER BY QuestID DESC, Idx2");
8442
8443 std::vector<std::vector<std::vector<QuestPOIPoint> > > POIs;
8444
8445 if (points)
8446 {
8447 // The first result should have the highest questId
8448 Field* fields = points->Fetch();
8449 uint32 questIdMax = fields[0].Get<uint32>();
8450 POIs.resize(questIdMax + 1);
8451
8452 do
8453 {
8454 fields = points->Fetch();
8455
8456 uint32 questId = fields[0].Get<uint32>();
8457 uint32 id = fields[1].Get<uint32>();
8458 int32 x = fields[2].Get<int32>();
8459 int32 y = fields[3].Get<int32>();
8460
8461 if (POIs[questId].size() <= id + 1)
8462 POIs[questId].resize(id + 10);
8463
8464 QuestPOIPoint point(x, y);
8465 POIs[questId][id].push_back(point);
8466 } while (points->NextRow());
8467 }
8468
8469 do
8470 {
8471 Field* fields = result->Fetch();
8472
8473 uint32 questId = fields[0].Get<uint32>();
8474 uint32 id = fields[1].Get<uint32>();
8475 int32 objIndex = fields[2].Get<int32>();
8476 uint32 mapId = fields[3].Get<uint32>();
8477 uint32 WorldMapAreaId = fields[4].Get<uint32>();
8478 uint32 FloorId = fields[5].Get<uint32>();
8479 uint32 unk3 = fields[6].Get<uint32>();
8480 uint32 unk4 = fields[7].Get<uint32>();
8481
8482 QuestPOI POI(id, objIndex, mapId, WorldMapAreaId, FloorId, unk3, unk4);
8483 if (questId < POIs.size() && id < POIs[questId].size())
8484 {
8485 POI.points = POIs[questId][id];
8486 _questPOIStore[questId].push_back(POI);
8487 }
8488 else
8489 LOG_ERROR("sql.sql", "Table quest_poi references unknown quest points for quest {} POI id {}", questId, id);
8490
8491 ++count;
8492 } while (result->NextRow());
8493
8494 LOG_INFO("server.loading", ">> Loaded {} Quest POI definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8495 LOG_INFO("server.loading", " ");
8496}
@ CONFIG_QUEST_POI_ENABLED
Definition WorldConfig.h:135
Definition ObjectMgr.h:639
Definition ObjectMgr.h:648

References _questPOIStore, CONFIG_QUEST_POI_ENABLED, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, sWorld, and WorldDatabase.

◆ LoadQuestRelationsHelper()

void ObjectMgr::LoadQuestRelationsHelper ( QuestRelations map,
std::string const &  table,
bool  starter,
bool  go 
)
private
8586{
8587 uint32 oldMSTime = getMSTime();
8588
8589 map.clear(); // need for reload case
8590
8591 uint32 count = 0;
8592
8593 QueryResult result = WorldDatabase.Query("SELECT id, quest, pool_entry FROM {} qr LEFT JOIN pool_quest pq ON qr.quest = pq.entry", table);
8594
8595 if (!result)
8596 {
8597 LOG_WARN("server.loading", ">> Loaded 0 quest relations from `{}`, table is empty.", table);
8598 LOG_INFO("server.loading", " ");
8599 return;
8600 }
8601
8602 PooledQuestRelation* poolRelationMap = go ? &sPoolMgr->mQuestGORelation : &sPoolMgr->mQuestCreatureRelation;
8603 if (starter)
8604 poolRelationMap->clear();
8605
8606 do
8607 {
8608 uint32 id = result->Fetch()[0].Get<uint32>();
8609 uint32 quest = result->Fetch()[1].Get<uint32>();
8610 uint32 poolId = result->Fetch()[2].Get<uint32>();
8611
8612 if (_questTemplates.find(quest) == _questTemplates.end())
8613 {
8614 LOG_ERROR("sql.sql", "Table `{}`: Quest {} listed for entry {} does not exist.", table, quest, id);
8615 continue;
8616 }
8617
8618 if (!poolId || !starter)
8619 map.insert(QuestRelations::value_type(id, quest));
8620 else if (starter)
8621 poolRelationMap->insert(PooledQuestRelation::value_type(quest, id));
8622
8623 ++count;
8624 } while (result->NextRow());
8625
8626 LOG_INFO("server.loading", ">> Loaded {} Quest Relations From {} in {} ms", count, table, GetMSTimeDiffToNow(oldMSTime));
8627 LOG_INFO("server.loading", " ");
8628}
#define sPoolMgr
Definition PoolMgr.h:163
std::multimap< uint32, uint32 > PooledQuestRelation
Definition PoolMgr.h:98

References _questTemplates, getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, sPoolMgr, and WorldDatabase.

Referenced by LoadCreatureQuestEnders(), LoadCreatureQuestStarters(), LoadGameobjectQuestEnders(), and LoadGameobjectQuestStarters().

◆ LoadQuestRequestItemsLocale()

void ObjectMgr::LoadQuestRequestItemsLocale ( )
6966{
6967 uint32 oldMSTime = getMSTime();
6968
6969 _questRequestItemsLocaleStore.clear(); // need for reload case
6970
6971 // 0 1 2
6972 QueryResult result = WorldDatabase.Query("SELECT Id, locale, CompletionText FROM quest_request_items_locale");
6973 if (!result)
6974 return;
6975
6976 do
6977 {
6978 Field* fields = result->Fetch();
6979
6980 uint32 id = fields[0].Get<uint32>();
6981 std::string localeName = fields[1].Get<std::string>();
6982
6983 LocaleConstant locale = GetLocaleByName(localeName);
6984 if (locale == LOCALE_enUS)
6985 continue;
6986
6988 AddLocaleString(fields[2].Get<std::string>(), locale, data.CompletionText);
6989 } while (result->NextRow());
6990
6991 LOG_INFO("server.loading", ">> Loaded {} Quest Request Items Locale Strings in {} ms", _questRequestItemsLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
6992}
Definition QuestDef.h:197
std::vector< std::string > CompletionText
Definition QuestDef.h:198

References _questRequestItemsLocaleStore, AddLocaleString(), QuestRequestItemsLocale::CompletionText, Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), LOCALE_enUS, LOG_INFO, and WorldDatabase.

◆ LoadQuests()

void ObjectMgr::LoadQuests ( )
4896{
4897 uint32 oldMSTime = getMSTime();
4898
4899 // For reload case
4900 for (QuestMap::const_iterator itr = _questTemplates.begin(); itr != _questTemplates.end(); ++itr)
4901 delete itr->second;
4902 _questTemplates.clear();
4903
4904 mExclusiveQuestGroups.clear();
4905
4906 QueryResult result = WorldDatabase.Query("SELECT "
4907 //0 1 2 3 4 5 6 7 8
4908 "ID, QuestType, QuestLevel, MinLevel, QuestSortID, QuestInfoID, SuggestedGroupNum, TimeAllowed, AllowableRaces,"
4909 // 9 10 11 12
4910 "RequiredFactionId1, RequiredFactionId2, RequiredFactionValue1, RequiredFactionValue2, "
4911 // 13 14 15 16 17 18 19 20
4912 "RewardNextQuest, RewardXPDifficulty, RewardMoney, RewardMoneyDifficulty, RewardDisplaySpell, RewardSpell, RewardHonor, RewardKillHonor, "
4913 // 21 22 23 24 25 26
4914 "StartItem, Flags, RewardTitle, RequiredPlayerKills, RewardTalents, RewardArenaPoints, "
4915 // 27 28 29 30 31 32 33 34
4916 "RewardItem1, RewardAmount1, RewardItem2, RewardAmount2, RewardItem3, RewardAmount3, RewardItem4, RewardAmount4, "
4917 // 35 36 37 38 39 40 41 42 43 44 45 46
4918 "RewardChoiceItemID1, RewardChoiceItemQuantity1, RewardChoiceItemID2, RewardChoiceItemQuantity2, RewardChoiceItemID3, RewardChoiceItemQuantity3, RewardChoiceItemID4, RewardChoiceItemQuantity4, RewardChoiceItemID5, RewardChoiceItemQuantity5, RewardChoiceItemID6, RewardChoiceItemQuantity6, "
4919 // 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
4920 "RewardFactionID1, RewardFactionValue1, RewardFactionOverride1, RewardFactionID2, RewardFactionValue2, RewardFactionOverride2, RewardFactionID3, RewardFactionValue3, RewardFactionOverride3, RewardFactionID4, RewardFactionValue4, RewardFactionOverride4, RewardFactionID5, RewardFactionValue5, RewardFactionOverride5,"
4921 // 61 63 64 65
4922 "POIContinent, POIx, POIy, POIPriority, "
4923 // 66 67 68 69 70
4924 "LogTitle, LogDescription, QuestDescription, AreaDescription, QuestCompletionLog, "
4925 // 71 72 73 74 75 76 77 78
4926 "RequiredNpcOrGo1, RequiredNpcOrGo2, RequiredNpcOrGo3, RequiredNpcOrGo4, RequiredNpcOrGoCount1, RequiredNpcOrGoCount2, RequiredNpcOrGoCount3, RequiredNpcOrGoCount4, "
4927 // 79 80 81 82 83 84 85 86
4928 "ItemDrop1, ItemDrop2, ItemDrop3, ItemDrop4, ItemDropQuantity1, ItemDropQuantity2, ItemDropQuantity3, ItemDropQuantity4, "
4929 // 87 88 89 90 91 92 93 94 95 96 97 98
4930 "RequiredItemId1, RequiredItemId2, RequiredItemId3, RequiredItemId4, RequiredItemId5, RequiredItemId6, RequiredItemCount1, RequiredItemCount2, RequiredItemCount3, RequiredItemCount4, RequiredItemCount5, RequiredItemCount6, "
4931 // 99 100 101 102 103
4932 "Unknown0, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4"
4933 " FROM quest_template");
4934 if (!result)
4935 {
4936 LOG_WARN("server.loading", ">> Loaded 0 quests definitions. DB table `quest_template` is empty.");
4937 LOG_INFO("server.loading", " ");
4938 return;
4939 }
4940
4941 // create multimap previous quest for each existed quest
4942 // some quests can have many previous maps set by NextQuestId in previous quest
4943 // for example set of race quests can lead to single not race specific quest
4944 do
4945 {
4946 Field* fields = result->Fetch();
4947
4948 Quest* newQuest = new Quest(fields);
4949 _questTemplates[newQuest->GetQuestId()] = newQuest;
4950 } while (result->NextRow());
4951
4952 // pussywizard:
4953 {
4954 uint32 max = 0;
4955 for (QuestMap::const_iterator itr = _questTemplates.begin(); itr != _questTemplates.end(); ++itr)
4956 if (itr->first > max)
4957 max = itr->first;
4958 if (max)
4959 {
4960 _questTemplatesFast.clear();
4961 _questTemplatesFast.resize(max + 1, nullptr);
4962 for (QuestMap::iterator itr = _questTemplates.begin(); itr != _questTemplates.end(); ++itr)
4963 _questTemplatesFast[itr->first] = itr->second;
4964 }
4965 }
4966
4967 for (QuestMap::iterator itr = _questTemplates.begin(); itr != _questTemplates.end(); ++itr)
4968 itr->second->InitializeQueryData();
4969
4970 std::map<uint32, uint32> usedMailTemplates;
4971
4972 // Load `quest_details`
4973 // 0 1 2 3 4 5 6 7 8
4974 result = WorldDatabase.Query("SELECT ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4 FROM quest_details");
4975
4976 if (!result)
4977 {
4978 LOG_WARN("server.loading", ">> Loaded 0 quest details. DB table `quest_details` is empty.");
4979 }
4980 else
4981 {
4982 do
4983 {
4984 Field* fields = result->Fetch();
4985 uint32 questId = fields[0].Get<uint32>();
4986
4987 auto itr = _questTemplates.find(questId);
4988 if (itr != _questTemplates.end())
4989 itr->second->LoadQuestDetails(fields);
4990 else
4991 LOG_ERROR("sql.sql", "Table `quest_details` has data for quest {} but such quest does not exist", questId);
4992 } while (result->NextRow());
4993 }
4994
4995 // Load `quest_request_items`
4996 // 0 1 2 3
4997 result = WorldDatabase.Query("SELECT ID, EmoteOnComplete, EmoteOnIncomplete, CompletionText FROM quest_request_items");
4998
4999 if (!result)
5000 {
5001 LOG_WARN("server.loading", ">> Loaded 0 quest request items. DB table `quest_request_items` is empty.");
5002 }
5003 else
5004 {
5005 do
5006 {
5007 Field* fields = result->Fetch();
5008 uint32 questId = fields[0].Get<uint32>();
5009
5010 auto itr = _questTemplates.find(questId);
5011 if (itr != _questTemplates.end())
5012 itr->second->LoadQuestRequestItems(fields);
5013 else
5014 LOG_ERROR("sql.sql", "Table `quest_request_items` has data for quest {} but such quest does not exist", questId);
5015 } while (result->NextRow());
5016 }
5017
5018 // Load `quest_offer_reward`
5019 // 0 1 2 3 4 5 6 7 8 9
5020 result = WorldDatabase.Query("SELECT ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4, RewardText FROM quest_offer_reward");
5021
5022 if (!result)
5023 {
5024 LOG_WARN("server.loading", ">> Loaded 0 quest reward emotes. DB table `quest_offer_reward` is empty.");
5025 }
5026 else
5027 {
5028 do
5029 {
5030 Field* fields = result->Fetch();
5031 uint32 questId = fields[0].Get<uint32>();
5032
5033 auto itr = _questTemplates.find(questId);
5034 if (itr != _questTemplates.end())
5035 itr->second->LoadQuestOfferReward(fields);
5036 else
5037 LOG_ERROR("sql.sql", "Table `quest_offer_reward` has data for quest {} but such quest does not exist", questId);
5038 } while (result->NextRow());
5039 }
5040
5041 // Load `quest_template_addon`
5042 // 0 1 2 3 4 5 6 7 8
5043 result = WorldDatabase.Query("SELECT ID, MaxLevel, AllowableClasses, SourceSpellID, PrevQuestID, NextQuestID, ExclusiveGroup, BreadcrumbForQuestId, RewardMailTemplateID, "
5044 //9 10 11 12 13 14 15 16 17 18
5045 "RewardMailDelay, RequiredSkillID, RequiredSkillPoints, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, ProvidedItemCount, RewardMailSenderEntry, SpecialFlags FROM quest_template_addon LEFT JOIN quest_mail_sender ON Id=QuestId");
5046
5047 if (!result)
5048 {
5049 LOG_WARN("server.loading", ">> Loaded 0 quest template addons. DB table `quest_template_addon` is empty.");
5050 }
5051 else
5052 {
5053 do
5054 {
5055 Field* fields = result->Fetch();
5056 uint32 questId = fields[0].Get<uint32>();
5057
5058 auto itr = _questTemplates.find(questId);
5059 if (itr != _questTemplates.end())
5060 itr->second->LoadQuestTemplateAddon(fields);
5061 else
5062 LOG_ERROR("sql.sql", "Table `quest_template_addon` has data for quest {} but such quest does not exist", questId);
5063 } while (result->NextRow());
5064 }
5065
5066 // Post processing
5067 for (QuestMap::iterator iter = _questTemplates.begin(); iter != _questTemplates.end(); ++iter)
5068 {
5069 // skip post-loading checks for disabled quests
5070 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_QUEST, iter->first, nullptr))
5071 continue;
5072
5073 Quest* qinfo = iter->second;
5074
5075 // additional quest integrity checks (GO, creature_template and item_template must be loaded already)
5076
5077 if (qinfo->GetQuestMethod() >= 3)
5078 LOG_ERROR("sql.sql", "Quest {} has `Method` = {}, expected values are 0, 1 or 2.", qinfo->GetQuestId(), qinfo->GetQuestMethod());
5079
5081 {
5082 LOG_ERROR("sql.sql", "Quest {} has `SpecialFlags` = {} > max allowed value. Correct `SpecialFlags` to value <= {}",
5085 }
5086
5087 if (qinfo->Flags & QUEST_FLAGS_DAILY && qinfo->Flags & QUEST_FLAGS_WEEKLY)
5088 {
5089 LOG_ERROR("sql.sql", "Weekly Quest {} is marked as daily quest in `Flags`, removed daily flag.", qinfo->GetQuestId());
5090 qinfo->Flags &= ~QUEST_FLAGS_DAILY;
5091 }
5092
5093 if (qinfo->Flags & QUEST_FLAGS_DAILY)
5094 {
5096 {
5097 LOG_ERROR("sql.sql", "Daily Quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->GetQuestId());
5099 }
5100 }
5101
5102 if (qinfo->Flags & QUEST_FLAGS_WEEKLY)
5103 {
5105 {
5106 LOG_ERROR("sql.sql", "Weekly Quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->GetQuestId());
5108 }
5109 }
5110
5112 {
5114 {
5115 LOG_ERROR("sql.sql", "Monthly quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->GetQuestId());
5117 }
5118 }
5119
5120 if (qinfo->Flags & QUEST_FLAGS_TRACKING)
5121 {
5122 // at auto-reward can be rewarded only RewardChoiceItemId[0]
5123 for (int j = 1; j < QUEST_REWARD_CHOICES_COUNT; ++j )
5124 {
5125 if (uint32 id = qinfo->RewardChoiceItemId[j])
5126 {
5127 LOG_ERROR("sql.sql", "Quest {} has `RewardChoiceItemId{}` = {} but item from `RewardChoiceItemId{}` can't be rewarded with quest flag QUEST_FLAGS_TRACKING.",
5128 qinfo->GetQuestId(), j + 1, id, j + 1);
5129 // no changes, quest ignore this data
5130 }
5131 }
5132 }
5133
5134 // client quest log visual (area case)
5135 if (qinfo->ZoneOrSort > 0)
5136 {
5137 if (!sAreaTableStore.LookupEntry(qinfo->ZoneOrSort))
5138 {
5139 LOG_ERROR("sql.sql", "Quest {} has `ZoneOrSort` = {} (zone case) but zone with this id does not exist.",
5140 qinfo->GetQuestId(), qinfo->ZoneOrSort);
5141 // no changes, quest not dependent from this value but can have problems at client
5142 }
5143 }
5144 // client quest log visual (sort case)
5145 if (qinfo->ZoneOrSort < 0)
5146 {
5147 QuestSortEntry const* qSort = sQuestSortStore.LookupEntry(-int32(qinfo->ZoneOrSort));
5148 if (!qSort)
5149 {
5150 LOG_ERROR("sql.sql", "Quest {} has `ZoneOrSort` = {} (sort case) but quest sort with this id does not exist.",
5151 qinfo->GetQuestId(), qinfo->ZoneOrSort);
5152 // no changes, quest not dependent from this value but can have problems at client (note some may be 0, we must allow this so no check)
5153 }
5154 //check for proper RequiredSkillId value (skill case)
5155 if (uint32 skill_id = SkillByQuestSort(-int32(qinfo->ZoneOrSort)))
5156 {
5157 if (qinfo->RequiredSkillId != skill_id)
5158 {
5159 LOG_ERROR("sql.sql", "Quest {} has `ZoneOrSort` = {} but `RequiredSkillId` does not have a corresponding value ({}).",
5160 qinfo->GetQuestId(), qinfo->ZoneOrSort, skill_id);
5161 //override, and force proper value here?
5162 }
5163 }
5164 }
5165
5166 // RequiredClasses, can be 0/CLASSMASK_ALL_PLAYABLE to allow any class
5167 if (qinfo->RequiredClasses)
5168 {
5170 {
5171 LOG_ERROR("sql.sql", "Quest {} does not contain any playable classes in `RequiredClasses` ({}), value set to 0 (all classes).", qinfo->GetQuestId(), qinfo->RequiredClasses);
5172 qinfo->RequiredClasses = 0;
5173 }
5174 }
5175 // AllowableRaces, can be 0/RACEMASK_ALL_PLAYABLE to allow any race
5176 if (qinfo->AllowableRaces)
5177 {
5178 if (!(qinfo->AllowableRaces & RACEMASK_ALL_PLAYABLE))
5179 {
5180 LOG_ERROR("sql.sql", "Quest {} does not contain any playable races in `AllowableRaces` ({}), value set to 0 (all races).", qinfo->GetQuestId(), qinfo->AllowableRaces);
5181 qinfo->AllowableRaces = 0;
5182 }
5183 }
5184 // RequiredSkillId, can be 0
5185 if (qinfo->RequiredSkillId)
5186 {
5187 if (!sSkillLineStore.LookupEntry(qinfo->RequiredSkillId))
5188 {
5189 LOG_ERROR("sql.sql", "Quest {} has `RequiredSkillId` = {} but this skill does not exist",
5190 qinfo->GetQuestId(), qinfo->RequiredSkillId);
5191 }
5192 }
5193
5194 if (qinfo->RequiredSkillPoints)
5195 {
5196 if (qinfo->RequiredSkillPoints > sWorld->GetConfigMaxSkillValue())
5197 {
5198 LOG_ERROR("sql.sql", "Quest {} has `RequiredSkillPoints` = {} but max possible skill is {}, quest can't be done.",
5199 qinfo->GetQuestId(), qinfo->RequiredSkillPoints, sWorld->GetConfigMaxSkillValue());
5200 // no changes, quest can't be done for this requirement
5201 }
5202 }
5203 // else Skill quests can have 0 skill level, this is ok
5204
5205 if (qinfo->RequiredFactionId2 && !sFactionStore.LookupEntry(qinfo->RequiredFactionId2))
5206 {
5207 LOG_ERROR("sql.sql", "Quest {} has `RequiredFactionId2` = {} but faction template {} does not exist, quest can't be done.",
5208 qinfo->GetQuestId(), qinfo->RequiredFactionId2, qinfo->RequiredFactionId2);
5209 // no changes, quest can't be done for this requirement
5210 }
5211
5212 if (qinfo->RequiredFactionId1 && !sFactionStore.LookupEntry(qinfo->RequiredFactionId1))
5213 {
5214 LOG_ERROR("sql.sql", "Quest {} has `RequiredFactionId1` = {} but faction template {} does not exist, quest can't be done.",
5215 qinfo->GetQuestId(), qinfo->RequiredFactionId1, qinfo->RequiredFactionId1);
5216 // no changes, quest can't be done for this requirement
5217 }
5218
5219 if (qinfo->RequiredMinRepFaction && !sFactionStore.LookupEntry(qinfo->RequiredMinRepFaction))
5220 {
5221 LOG_ERROR("sql.sql", "Quest {} has `RequiredMinRepFaction` = {} but faction template {} does not exist, quest can't be done.",
5222 qinfo->GetQuestId(), qinfo->RequiredMinRepFaction, qinfo->RequiredMinRepFaction);
5223 // no changes, quest can't be done for this requirement
5224 }
5225
5226 if (qinfo->RequiredMaxRepFaction && !sFactionStore.LookupEntry(qinfo->RequiredMaxRepFaction))
5227 {
5228 LOG_ERROR("sql.sql", "Quest {} has `RequiredMaxRepFaction` = {} but faction template {} does not exist, quest can't be done.",
5229 qinfo->GetQuestId(), qinfo->RequiredMaxRepFaction, qinfo->RequiredMaxRepFaction);
5230 // no changes, quest can't be done for this requirement
5231 }
5232
5234 {
5235 LOG_ERROR("sql.sql", "Quest {} has `RequiredMinRepValue` = {} but max reputation is {}, quest can't be done.",
5237 // no changes, quest can't be done for this requirement
5238 }
5239
5240 if (qinfo->RequiredMinRepValue && qinfo->RequiredMaxRepValue && qinfo->RequiredMaxRepValue <= qinfo->RequiredMinRepValue)
5241 {
5242 LOG_ERROR("sql.sql", "Quest {} has `RequiredMaxRepValue` = {} and `RequiredMinRepValue` = {}, quest can't be done.",
5243 qinfo->GetQuestId(), qinfo->RequiredMaxRepValue, qinfo->RequiredMinRepValue);
5244 // no changes, quest can't be done for this requirement
5245 }
5246
5247 if (!qinfo->RequiredFactionId1 && qinfo->RequiredFactionValue1 != 0)
5248 {
5249 LOG_ERROR("sql.sql", "Quest {} has `RequiredFactionValue1` = {} but `RequiredFactionId1` is 0, value has no effect",
5250 qinfo->GetQuestId(), qinfo->RequiredFactionValue1);
5251 // warning
5252 }
5253
5254 if (!qinfo->RequiredFactionId2 && qinfo->RequiredFactionValue2 != 0)
5255 {
5256 LOG_ERROR("sql.sql", "Quest {} has `RequiredFactionValue2` = {} but `RequiredFactionId2` is 0, value has no effect",
5257 qinfo->GetQuestId(), qinfo->RequiredFactionValue2);
5258 // warning
5259 }
5260
5261 if (!qinfo->RequiredMinRepFaction && qinfo->RequiredMinRepValue != 0)
5262 {
5263 LOG_ERROR("sql.sql", "Quest {} has `RequiredMinRepValue` = {} but `RequiredMinRepFaction` is 0, value has no effect",
5264 qinfo->GetQuestId(), qinfo->RequiredMinRepValue);
5265 // warning
5266 }
5267
5268 if (!qinfo->RequiredMaxRepFaction && qinfo->RequiredMaxRepValue != 0)
5269 {
5270 LOG_ERROR("sql.sql", "Quest {} has `RequiredMaxRepValue` = {} but `RequiredMaxRepFaction` is 0, value has no effect",
5271 qinfo->GetQuestId(), qinfo->RequiredMaxRepValue);
5272 // warning
5273 }
5274
5275 if (qinfo->RewardTitleId && !sCharTitlesStore.LookupEntry(qinfo->RewardTitleId))
5276 {
5277 LOG_ERROR("sql.sql", "Quest {} has `RewardTitleId` = {} but CharTitle Id {} does not exist, quest can't be rewarded with title.",
5278 qinfo->GetQuestId(), qinfo->GetCharTitleId(), qinfo->GetCharTitleId());
5279 qinfo->RewardTitleId = 0;
5280 // quest can't reward this title
5281 }
5282
5283 if (qinfo->StartItem)
5284 {
5285 if (!GetItemTemplate(qinfo->StartItem))
5286 {
5287 LOG_ERROR("sql.sql", "Quest {} has `StartItem` = {} but item with entry {} does not exist, quest can't be done.",
5288 qinfo->GetQuestId(), qinfo->StartItem, qinfo->StartItem);
5289 qinfo->StartItem = 0; // quest can't be done for this requirement
5290 }
5291 else if (qinfo->StartItemCount == 0)
5292 {
5293 LOG_ERROR("sql.sql", "Quest {} has `StartItem` = {} but `StartItemCount` = 0, set to 1 but need fix in DB.",
5294 qinfo->GetQuestId(), qinfo->StartItem);
5295 qinfo->StartItemCount = 1; // update to 1 for allow quest work for backward compatibility with DB
5296 }
5297 }
5298 else if (qinfo->StartItemCount > 0)
5299 {
5300 LOG_ERROR("sql.sql", "Quest {} has `StartItem` = 0 but `StartItemCount` = {}, useless value.",
5301 qinfo->GetQuestId(), qinfo->StartItemCount);
5302 qinfo->StartItemCount = 0; // no quest work changes in fact
5303 }
5304
5305 if (qinfo->SourceSpellid)
5306 {
5307 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->SourceSpellid);
5308 if (!spellInfo)
5309 {
5310 LOG_ERROR("sql.sql", "Quest {} has `SourceSpellid` = {} but spell {} doesn't exist, quest can't be done.",
5311 qinfo->GetQuestId(), qinfo->SourceSpellid, qinfo->SourceSpellid);
5312 qinfo->SourceSpellid = 0; // quest can't be done for this requirement
5313 }
5314 else if (!SpellMgr::ComputeIsSpellValid(spellInfo))
5315 {
5316 LOG_ERROR("sql.sql", "Quest {} has `SourceSpellid` = {} but spell {} is broken, quest can't be done.",
5317 qinfo->GetQuestId(), qinfo->SourceSpellid, qinfo->SourceSpellid);
5318 qinfo->SourceSpellid = 0; // quest can't be done for this requirement
5319 }
5320 }
5321
5322 for (uint8 j = 0; j < QUEST_ITEM_OBJECTIVES_COUNT; ++j)
5323 {
5324 uint32 id = qinfo->RequiredItemId[j];
5325 if (id)
5326 {
5327 if (qinfo->RequiredItemCount[j] == 0)
5328 {
5329 LOG_ERROR("sql.sql", "Quest {} has `RequiredItemId{}` = {} but `RequiredItemCount{}` = 0, quest can't be done.",
5330 qinfo->GetQuestId(), j + 1, id, j + 1);
5331 // no changes, quest can't be done for this requirement
5332 }
5333
5335
5336 if (!GetItemTemplate(id))
5337 {
5338 LOG_ERROR("sql.sql", "Quest {} has `RequiredItemId{}` = {} but item with entry {} does not exist, quest can't be done.",
5339 qinfo->GetQuestId(), j + 1, id, id);
5340 qinfo->RequiredItemCount[j] = 0; // prevent incorrect work of quest
5341 }
5342 }
5343 else if (qinfo->RequiredItemCount[j] > 0)
5344 {
5345 LOG_ERROR("sql.sql", "Quest {} has `RequiredItemId{}` = 0 but `RequiredItemCount{}` = {}, quest can't be done.",
5346 qinfo->GetQuestId(), j + 1, j + 1, qinfo->RequiredItemCount[j]);
5347 qinfo->RequiredItemCount[j] = 0; // prevent incorrect work of quest
5348 }
5349 }
5350
5351 for (uint8 j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j)
5352 {
5353 uint32 id = qinfo->ItemDrop[j];
5354 if (id)
5355 {
5356 if (!GetItemTemplate(id))
5357 {
5358 LOG_ERROR("sql.sql", "Quest {} has `ItemDrop{}` = {} but item with entry {} does not exist, quest can't be done.",
5359 qinfo->GetQuestId(), j + 1, id, id);
5360 // no changes, quest can't be done for this requirement
5361 }
5362 }
5363 else
5364 {
5365 if (qinfo->ItemDropQuantity[j] > 0)
5366 {
5367 LOG_ERROR("sql.sql", "Quest {} has `ItemDrop{}` = 0 but `ItemDropQuantity{}` = {}.",
5368 qinfo->GetQuestId(), j + 1, j + 1, qinfo->ItemDropQuantity[j]);
5369 // no changes, quest ignore this data
5370 }
5371 }
5372 }
5373
5374 for (uint8 j = 0; j < QUEST_OBJECTIVES_COUNT; ++j)
5375 {
5376 int32 id = qinfo->RequiredNpcOrGo[j];
5377 if (id < 0 && !GetGameObjectTemplate(-id))
5378 {
5379 LOG_ERROR("sql.sql", "Quest {} has `RequiredNpcOrGo{}` = {} but gameobject {} does not exist, quest can't be done.",
5380 qinfo->GetQuestId(), j + 1, id, uint32(-id));
5381 qinfo->RequiredNpcOrGo[j] = 0; // quest can't be done for this requirement
5382 }
5383
5384 if (id > 0 && !GetCreatureTemplate(id))
5385 {
5386 LOG_ERROR("sql.sql", "Quest {} has `RequiredNpcOrGo{}` = {} but creature with entry {} does not exist, quest can't be done.",
5387 qinfo->GetQuestId(), j + 1, id, uint32(id));
5388 qinfo->RequiredNpcOrGo[j] = 0; // quest can't be done for this requirement
5389 }
5390
5391 if (id)
5392 {
5393 // In fact SpeakTo and Kill are quite same: either you can speak to mob:SpeakTo or you can't:Kill/Cast
5394
5396
5397 if (!qinfo->RequiredNpcOrGoCount[j])
5398 {
5399 LOG_ERROR("sql.sql", "Quest {} has `RequiredNpcOrGo{}` = {} but `RequiredNpcOrGoCount{}` = 0, quest can't be done.",
5400 qinfo->GetQuestId(), j + 1, id, j + 1);
5401 // no changes, quest can be incorrectly done, but we already report this
5402 }
5403 }
5404 else if (qinfo->RequiredNpcOrGoCount[j] > 0)
5405 {
5406 LOG_ERROR("sql.sql", "Quest {} has `RequiredNpcOrGo{}` = 0 but `RequiredNpcOrGoCount{}` = {}.",
5407 qinfo->GetQuestId(), j + 1, j + 1, qinfo->RequiredNpcOrGoCount[j]);
5408 // no changes, quest ignore this data
5409 }
5410 }
5411
5412 for (uint8 j = 0; j < QUEST_REWARD_CHOICES_COUNT; ++j)
5413 {
5414 uint32 id = qinfo->RewardChoiceItemId[j];
5415 if (id)
5416 {
5417 if (!GetItemTemplate(id))
5418 {
5419 LOG_ERROR("sql.sql", "Quest {} has `RewardChoiceItemId{}` = {} but item with entry {} does not exist, quest will not reward this item.",
5420 qinfo->GetQuestId(), j + 1, id, id);
5421 qinfo->RewardChoiceItemId[j] = 0; // no changes, quest will not reward this
5422 }
5423
5424 if (!qinfo->RewardChoiceItemCount[j])
5425 {
5426 LOG_ERROR("sql.sql", "Quest {} has `RewardChoiceItemId{}` = {} but `RewardChoiceItemCount{}` = 0, quest can't be done.",
5427 qinfo->GetQuestId(), j + 1, id, j + 1);
5428 // no changes, quest can't be done
5429 }
5430 }
5431 else if (qinfo->RewardChoiceItemCount[j] > 0)
5432 {
5433 LOG_ERROR("sql.sql", "Quest {} has `RewardChoiceItemId{}` = 0 but `RewardChoiceItemCount{}` = {}.",
5434 qinfo->GetQuestId(), j + 1, j + 1, qinfo->RewardChoiceItemCount[j]);
5435 // no changes, quest ignore this data
5436 }
5437 }
5438
5439 for (uint8 j = 0; j < QUEST_REWARDS_COUNT; ++j)
5440 {
5441 if (!qinfo->RewardItemId[0] && qinfo->RewardItemId[j])
5442 {
5443 LOG_ERROR("sql.sql", "Quest {} has no `RewardItemId1` but has `RewardItem{}`. Reward item will not be loaded.",
5444 qinfo->GetQuestId(), j + 1);
5445 }
5446 if (!qinfo->RewardItemId[1] && j > 1 && qinfo->RewardItemId[j])
5447 {
5448 LOG_ERROR("sql.sql", "Quest {} has no `RewardItemId2` but has `RewardItem{}`. Reward item will not be loaded.",
5449 qinfo->GetQuestId(), j + 1);
5450 }
5451 if (!qinfo->RewardItemId[2] && j > 2 && qinfo->RewardItemId[j])
5452 {
5453 LOG_ERROR("sql.sql", "Quest {} has no `RewardItemId3` but has `RewardItem{}`. Reward item will not be loaded.",
5454 qinfo->GetQuestId(), j + 1);
5455 }
5456 }
5457
5458 for (uint8 j = 0; j < QUEST_REWARDS_COUNT; ++j)
5459 {
5460 uint32 id = qinfo->RewardItemId[j];
5461 if (id)
5462 {
5463 if (!GetItemTemplate(id))
5464 {
5465 LOG_ERROR("sql.sql", "Quest {} has `RewardItemId{}` = {} but item with entry {} does not exist, quest will not reward this item.",
5466 qinfo->GetQuestId(), j + 1, id, id);
5467 qinfo->RewardItemId[j] = 0; // no changes, quest will not reward this item
5468 }
5469
5470 if (!qinfo->RewardItemIdCount[j])
5471 {
5472 LOG_ERROR("sql.sql", "Quest {} has `RewardItemId{}` = {} but `RewardItemIdCount{}` = 0, quest will not reward this item.",
5473 qinfo->GetQuestId(), j + 1, id, j + 1);
5474 // no changes
5475 }
5476 }
5477 else if (qinfo->RewardItemIdCount[j] > 0)
5478 {
5479 LOG_ERROR("sql.sql", "Quest {} has `RewardItemId{}` = 0 but `RewardItemIdCount{}` = {}.",
5480 qinfo->GetQuestId(), j + 1, j + 1, qinfo->RewardItemIdCount[j]);
5481 // no changes, quest ignore this data
5482 }
5483 }
5484
5485 for (uint8 j = 0; j < QUEST_REPUTATIONS_COUNT; ++j)
5486 {
5487 if (qinfo->RewardFactionId[j])
5488 {
5489 if (std::abs(qinfo->RewardFactionValueId[j]) > 9)
5490 {
5491 LOG_ERROR("sql.sql", "Quest {} has RewardFactionValueId{} = {}. That is outside the range of valid values (-9 to 9).", qinfo->GetQuestId(), j + 1, qinfo->RewardFactionValueId[j]);
5492 }
5493 if (!sFactionStore.LookupEntry(qinfo->RewardFactionId[j]))
5494 {
5495 LOG_ERROR("sql.sql", "Quest {} has `RewardFactionId{}` = {} but raw faction (faction.dbc) {} does not exist, quest will not reward reputation for this faction.", qinfo->GetQuestId(), j + 1, qinfo->RewardFactionId[j], qinfo->RewardFactionId[j]);
5496 qinfo->RewardFactionId[j] = 0; // quest will not reward this
5497 }
5498 }
5499
5500 else if (qinfo->RewardFactionValueIdOverride[j] != 0)
5501 {
5502 LOG_ERROR("sql.sql", "Quest {} has `RewardFactionId{}` = 0 but `RewardFactionValueIdOverride{}` = {}.",
5503 qinfo->GetQuestId(), j + 1, j + 1, qinfo->RewardFactionValueIdOverride[j]);
5504 // no changes, quest ignore this data
5505 }
5506 }
5507
5508 if (qinfo->RewardDisplaySpell)
5509 {
5510 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardDisplaySpell);
5511
5512 if (!spellInfo)
5513 {
5514 LOG_ERROR("sql.sql", "Quest {} has `RewardDisplaySpell` = {} but spell {} does not exist, spell removed as display reward.",
5515 qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell);
5516 qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest
5517 }
5518
5519 else if (!SpellMgr::ComputeIsSpellValid(spellInfo))
5520 {
5521 LOG_ERROR("sql.sql", "Quest {} has `RewardDisplaySpell` = {} but spell {} is broken, quest will not have a spell reward.",
5522 qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell);
5523 qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest
5524 }
5525
5526 else if (GetTalentSpellCost(qinfo->RewardDisplaySpell))
5527 {
5528 LOG_ERROR("sql.sql", "Quest {} has `RewardDisplaySpell` = {} but spell {} is talent, quest will not have a spell reward.",
5529 qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell);
5530 qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest
5531 }
5532 }
5533
5534 if (qinfo->RewardSpell > 0)
5535 {
5536 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardSpell);
5537
5538 if (!spellInfo)
5539 {
5540 LOG_ERROR("sql.sql", "Quest {} has `RewardSpell` = {} but spell {} does not exist, quest will not have a spell reward.",
5541 qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
5542 qinfo->RewardSpell = 0; // no spell will be casted on player
5543 }
5544
5545 else if (!SpellMgr::ComputeIsSpellValid(spellInfo))
5546 {
5547 LOG_ERROR("sql.sql", "Quest {} has `RewardSpell` = {} but spell {} is broken, quest will not have a spell reward.",
5548 qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
5549 qinfo->RewardSpell = 0; // no spell will be casted on player
5550 }
5551
5552 else if (GetTalentSpellCost(qinfo->RewardSpell))
5553 {
5554 LOG_ERROR("sql.sql", "Quest {} has `RewardDisplaySpell` = {} but spell {} is talent, quest will not have a spell reward.",
5555 qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
5556 qinfo->RewardSpell = 0; // no spell will be casted on player
5557 }
5558 }
5559
5560 if (qinfo->RewardMailTemplateId)
5561 {
5562 if (!sMailTemplateStore.LookupEntry(qinfo->RewardMailTemplateId))
5563 {
5564 LOG_ERROR("sql.sql", "Quest {} has `RewardMailTemplateId` = {} but mail template {} does not exist, quest will not have a mail reward.",
5565 qinfo->GetQuestId(), qinfo->RewardMailTemplateId, qinfo->RewardMailTemplateId);
5566 qinfo->RewardMailTemplateId = 0; // no mail will send to player
5567 qinfo->RewardMailDelay = 0; // no mail will send to player
5568 qinfo->RewardMailSenderEntry = 0;
5569 }
5570 else if (usedMailTemplates.find(qinfo->RewardMailTemplateId) != usedMailTemplates.end())
5571 {
5572 std::map<uint32, uint32>::const_iterator used_mt_itr = usedMailTemplates.find(qinfo->RewardMailTemplateId);
5573 LOG_ERROR("sql.sql", "Quest {} has `RewardMailTemplateId` = {} but mail template {} already used for quest {}, quest will not have a mail reward.",
5574 qinfo->GetQuestId(), qinfo->RewardMailTemplateId, qinfo->RewardMailTemplateId, used_mt_itr->second);
5575 qinfo->RewardMailTemplateId = 0; // no mail will send to player
5576 qinfo->RewardMailDelay = 0; // no mail will send to player
5577 qinfo->RewardMailSenderEntry = 0;
5578 }
5579 else
5580 usedMailTemplates[qinfo->RewardMailTemplateId] = qinfo->GetQuestId();
5581 }
5582
5583 if (qinfo->RewardNextQuest)
5584 {
5585 QuestMap::iterator qNextItr = _questTemplates.find(qinfo->RewardNextQuest);
5586 if (qNextItr == _questTemplates.end())
5587 {
5588 LOG_ERROR("sql.sql", "Quest {} has `RewardNextQuest` = {} but quest {} does not exist, quest chain will not work.",
5589 qinfo->GetQuestId(), qinfo->RewardNextQuest, qinfo->RewardNextQuest);
5590 qinfo->RewardNextQuest = 0;
5591 }
5592 else
5593 qNextItr->second->prevChainQuests.push_back(qinfo->GetQuestId());
5594 }
5595
5596 // fill additional data stores
5597 if (qinfo->PrevQuestId)
5598 {
5599 if (_questTemplates.find(std::abs(qinfo->GetPrevQuestId())) == _questTemplates.end())
5600 {
5601 LOG_ERROR("sql.sql", "Quest {} has PrevQuestId {}, but no such quest", qinfo->GetQuestId(), qinfo->GetPrevQuestId());
5602 }
5603 else
5604 {
5605 qinfo->prevQuests.push_back(qinfo->PrevQuestId);
5606 }
5607 }
5608
5609 if (qinfo->NextQuestId)
5610 {
5611 QuestMap::iterator qNextItr = _questTemplates.find(qinfo->GetNextQuestId());
5612 if (qNextItr == _questTemplates.end())
5613 {
5614 LOG_ERROR("sql.sql", "Quest {} has NextQuestId {}, but no such quest", qinfo->GetQuestId(), qinfo->GetNextQuestId());
5615 }
5616 else
5617 qNextItr->second->prevQuests.push_back(static_cast<int32>(qinfo->GetQuestId()));
5618 }
5619
5620 if (qinfo->ExclusiveGroup)
5621 mExclusiveQuestGroups.insert(std::pair<int32, uint32>(qinfo->ExclusiveGroup, qinfo->GetQuestId()));
5622
5623 if (uint32 breadcrumbForQuestId = qinfo->GetBreadcrumbForQuestId())
5624 {
5625 if (_questTemplates.find(breadcrumbForQuestId) == _questTemplates.end())
5626 LOG_ERROR("sql.sql", "Quest {} has BreadcrumbForQuestId {}, but no such quest exists", qinfo->GetQuestId(), breadcrumbForQuestId);
5627 else
5628 _breadcrumbsForQuest[breadcrumbForQuestId].push_back(qinfo->GetQuestId());
5629
5630 if (qinfo->GetNextQuestId())
5631 LOG_ERROR("sql.sql", "Quest {} is a breadcrumb quest but also has NextQuestID {} set", qinfo->GetQuestId(), qinfo->GetNextQuestId());
5632 if (qinfo->GetExclusiveGroup())
5633 LOG_ERROR("sql.sql", "Quest {} is a breadcrumb quest but also has ExclusiveGroup {} set", qinfo->GetQuestId(), qinfo->GetExclusiveGroup());
5634 }
5635
5636 if (qinfo->TimeAllowed)
5638 if (qinfo->RequiredPlayerKills)
5640 }
5641
5642 for (auto const& [questId, quest] : _questTemplates)
5643 {
5644 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_QUEST, questId, nullptr))
5645 continue;
5646
5647 uint32 breadcrumbForQuestId = quest->GetBreadcrumbForQuestId();
5648 if (!breadcrumbForQuestId)
5649 continue;
5650
5651 std::set<uint32> visitedQuests;
5652 visitedQuests.insert(questId);
5653
5654 while (breadcrumbForQuestId)
5655 {
5656 if (!visitedQuests.insert(breadcrumbForQuestId).second)
5657 {
5658 LOG_ERROR("sql.sql", "Breadcrumb quests {} and {} form a loop", questId, breadcrumbForQuestId);
5659 break;
5660 }
5661
5662 Quest const* targetQuest = GetQuestTemplate(breadcrumbForQuestId);
5663 if (!targetQuest)
5664 break;
5665
5666 breadcrumbForQuestId = targetQuest->GetBreadcrumbForQuestId();
5667 }
5668 }
5669
5670 // check QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT for spell with SPELL_EFFECT_QUEST_COMPLETE
5671 for (uint32 i = 0; i < sSpellMgr->GetSpellInfoStoreSize(); ++i)
5672 {
5673 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(i);
5674 if (!spellInfo)
5675 continue;
5676
5677 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
5678 {
5679 if (spellInfo->Effects[j].Effect != SPELL_EFFECT_QUEST_COMPLETE)
5680 continue;
5681
5682 uint32 quest_id = spellInfo->Effects[j].MiscValue;
5683
5684 Quest const* quest = GetQuestTemplate(quest_id);
5685
5686 // some quest referenced in spells not exist (outdated spells)
5687 if (!quest)
5688 continue;
5689
5691 {
5692 LOG_ERROR("sql.sql", "Spell (id: {}) have SPELL_EFFECT_QUEST_COMPLETE for quest {}, but quest not have specialflag QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT. Quest flags must be fixed, quest modified to enable objective.", spellInfo->Id, quest_id);
5693
5694 // this will prevent quest completing without objective
5695 // xinef: remove this, leave error but do not break the quest
5696 // const_cast<Quest*>(quest)->SetSpecialFlag(QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT);
5697 }
5698 }
5699 }
5700
5701 LOG_INFO("server.loading", ">> Loaded {} Quests Definitions in {} ms", (unsigned long)_questTemplates.size(), GetMSTimeDiffToNow(oldMSTime));
5702 LOG_INFO("server.loading", " ");
5703}
uint32 GetTalentSpellCost(uint32 spellId)
Definition DBCStores.cpp:686
DBCStorage< QuestSortEntry > sQuestSortStore(QuestSortEntryfmt)
@ DISABLE_TYPE_QUEST
Definition DisableMgr.h:29
#define QUEST_REWARDS_COUNT
Definition QuestDef.h:39
#define QUEST_ITEM_OBJECTIVES_COUNT
Definition QuestDef.h:36
#define QUEST_OBJECTIVES_COUNT
Definition QuestDef.h:35
@ QUEST_FLAGS_TRACKING
Definition QuestDef.h:142
@ QUEST_FLAGS_DAILY
Definition QuestDef.h:144
@ QUEST_FLAGS_WEEKLY
Definition QuestDef.h:147
#define QUEST_REPUTATIONS_COUNT
Definition QuestDef.h:41
#define QUEST_SOURCE_ITEM_IDS_COUNT
Definition QuestDef.h:37
#define QUEST_REWARD_CHOICES_COUNT
Definition QuestDef.h:38
@ QUEST_SPECIAL_FLAGS_CAST
Definition QuestDef.h:165
@ QUEST_SPECIAL_FLAGS_TIMED
Definition QuestDef.h:178
@ QUEST_SPECIAL_FLAGS_DELIVER
Definition QuestDef.h:175
@ QUEST_SPECIAL_FLAGS_REPEATABLE
Definition QuestDef.h:160
@ QUEST_SPECIAL_FLAGS_KILL
Definition QuestDef.h:177
@ QUEST_SPECIAL_FLAGS_DB_ALLOWED
Definition QuestDef.h:171
@ QUEST_SPECIAL_FLAGS_SPEAKTO
Definition QuestDef.h:176
@ QUEST_SPECIAL_FLAGS_MONTHLY
Definition QuestDef.h:164
@ QUEST_SPECIAL_FLAGS_PLAYER_KILL
Definition QuestDef.h:179
@ SPELL_EFFECT_QUEST_COMPLETE
Definition SharedDefines.h:805
uint32 SkillByQuestSort(int32 QuestSort)
Definition SharedDefines.h:3280
ExclusiveQuestGroups mExclusiveQuestGroups
Definition ObjectMgr.h:1146
uint32 ItemDropQuantity[QUEST_SOURCE_ITEM_IDS_COUNT]
Definition QuestDef.h:304
uint32 RewardMailDelay
Definition QuestDef.h:396
uint32 RewardMailSenderEntry
Definition QuestDef.h:404
int32 RequiredNpcOrGo[QUEST_OBJECTIVES_COUNT]
Definition QuestDef.h:305
uint32 RequiredMaxRepFaction
Definition QuestDef.h:401
uint32 SourceSpellid
Definition QuestDef.h:390
uint32 RequiredMinRepFaction
Definition QuestDef.h:399
int32 RequiredFactionValue2
Definition QuestDef.h:356
int32 RequiredFactionValue1
Definition QuestDef.h:354
int32 ZoneOrSort
Definition QuestDef.h:348
uint32 RequiredNpcOrGoCount[QUEST_OBJECTIVES_COUNT]
Definition QuestDef.h:306
uint32 StartItemCount
Definition QuestDef.h:403
void SetSpecialFlag(uint32 flag)
Definition QuestDef.h:225
uint32 GetCharTitleId() const
Definition QuestDef.h:254
uint32 RewardTitleId
Definition QuestDef.h:360
uint32 RewardItemIdCount[QUEST_REWARDS_COUNT]
Definition QuestDef.h:310
uint32 RewardChoiceItemId[QUEST_REWARD_CHOICES_COUNT]
Definition QuestDef.h:307
uint32 NextQuestId
Definition QuestDef.h:392
uint32 RewardMailTemplateId
Definition QuestDef.h:395
uint32 ItemDrop[QUEST_SOURCE_ITEM_IDS_COUNT]
Definition QuestDef.h:303
int32 RewardFactionValueIdOverride[QUEST_REPUTATIONS_COUNT]
Definition QuestDef.h:313
uint32 RequiredSkillPoints
Definition QuestDef.h:398
int32 RewardSpell
Definition QuestDef.h:379
uint32 RewardChoiceItemCount[QUEST_REWARD_CHOICES_COUNT]
Definition QuestDef.h:308
uint32 AllowableRaces
Definition QuestDef.h:352
uint32 RewardNextQuest
Definition QuestDef.h:364
uint32 RequiredPlayerKills
Definition QuestDef.h:361
int32 GetPrevQuestId() const
Definition QuestDef.h:249
uint32 StartItem
Definition QuestDef.h:366
uint32 GetQuestId() const
Definition QuestDef.h:228
int32 RequiredMaxRepValue
Definition QuestDef.h:402
uint32 RequiredClasses
Definition QuestDef.h:389
uint32 Flags
Definition QuestDef.h:359
uint32 RequiredItemCount[QUEST_ITEM_OBJECTIVES_COUNT]
Definition QuestDef.h:302
uint32 GetBreadcrumbForQuestId() const
Definition QuestDef.h:252
int32 GetExclusiveGroup() const
Definition QuestDef.h:251
uint32 TimeAllowed
Definition QuestDef.h:358
uint32 RequiredFactionId1
Definition QuestDef.h:353
uint32 RequiredFactionId2
Definition QuestDef.h:355
PrevQuests prevQuests
Definition QuestDef.h:325
uint32 RewardDisplaySpell
Definition QuestDef.h:378
uint32 RequiredItemId[QUEST_ITEM_OBJECTIVES_COUNT]
Definition QuestDef.h:301
int32 PrevQuestId
Definition QuestDef.h:391
uint32 GetNextQuestId() const
Definition QuestDef.h:250
uint32 RewardFactionId[QUEST_REPUTATIONS_COUNT]
Definition QuestDef.h:311
int32 ExclusiveGroup
Definition QuestDef.h:393
uint32 RequiredSkillId
Definition QuestDef.h:397
int32 RewardFactionValueId[QUEST_REPUTATIONS_COUNT]
Definition QuestDef.h:312
uint32 RewardItemId[QUEST_REWARDS_COUNT]
Definition QuestDef.h:309
uint32 GetQuestMethod() const
Definition QuestDef.h:229
int32 RequiredMinRepValue
Definition QuestDef.h:400
uint32 SpecialFlags
Definition QuestDef.h:405
static const int32 Reputation_Cap
Definition ReputationMgr.h:67
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition SpellInfo.h:393
Definition DBCStructure.h:1445

References _breadcrumbsForQuest, _questTemplates, _questTemplatesFast, Quest::AllowableRaces, CLASSMASK_ALL_PLAYABLE, SpellMgr::ComputeIsSpellValid(), DISABLE_TYPE_QUEST, SpellInfo::Effects, Quest::ExclusiveGroup, Quest::Flags, Field::Get(), Quest::GetBreadcrumbForQuestId(), Quest::GetCharTitleId(), GetCreatureTemplate(), Quest::GetExclusiveGroup(), GetGameObjectTemplate(), GetItemTemplate(), getMSTime(), GetMSTimeDiffToNow(), Quest::GetNextQuestId(), Quest::GetPrevQuestId(), Quest::GetQuestId(), Quest::GetQuestMethod(), GetQuestTemplate(), GetTalentSpellCost(), Quest::HasSpecialFlag(), SpellInfo::Id, Quest::ItemDrop, Quest::ItemDropQuantity, LOG_ERROR, LOG_INFO, LOG_WARN, MAX_SPELL_EFFECTS, mExclusiveQuestGroups, Quest::NextQuestId, Quest::PrevQuestId, Quest::prevQuests, QUEST_FLAGS_DAILY, QUEST_FLAGS_TRACKING, QUEST_FLAGS_WEEKLY, QUEST_ITEM_OBJECTIVES_COUNT, QUEST_OBJECTIVES_COUNT, QUEST_REPUTATIONS_COUNT, QUEST_REWARD_CHOICES_COUNT, QUEST_REWARDS_COUNT, QUEST_SOURCE_ITEM_IDS_COUNT, QUEST_SPECIAL_FLAGS_CAST, QUEST_SPECIAL_FLAGS_DB_ALLOWED, QUEST_SPECIAL_FLAGS_DELIVER, QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT, QUEST_SPECIAL_FLAGS_KILL, QUEST_SPECIAL_FLAGS_MONTHLY, QUEST_SPECIAL_FLAGS_PLAYER_KILL, QUEST_SPECIAL_FLAGS_REPEATABLE, QUEST_SPECIAL_FLAGS_SPEAKTO, QUEST_SPECIAL_FLAGS_TIMED, RACEMASK_ALL_PLAYABLE, ReputationMgr::Reputation_Cap, Quest::RequiredClasses, Quest::RequiredFactionId1, Quest::RequiredFactionId2, Quest::RequiredFactionValue1, Quest::RequiredFactionValue2, Quest::RequiredItemCount, Quest::RequiredItemId, Quest::RequiredMaxRepFaction, Quest::RequiredMaxRepValue, Quest::RequiredMinRepFaction, Quest::RequiredMinRepValue, Quest::RequiredNpcOrGo, Quest::RequiredNpcOrGoCount, Quest::RequiredPlayerKills, Quest::RequiredSkillId, Quest::RequiredSkillPoints, Quest::RewardChoiceItemCount, Quest::RewardChoiceItemId, Quest::RewardDisplaySpell, Quest::RewardFactionId, Quest::RewardFactionValueId, Quest::RewardFactionValueIdOverride, Quest::RewardItemId, Quest::RewardItemIdCount, Quest::RewardMailDelay, Quest::RewardMailSenderEntry, Quest::RewardMailTemplateId, Quest::RewardNextQuest, Quest::RewardSpell, Quest::RewardTitleId, sAreaTableStore, sCharTitlesStore, sDisableMgr, Quest::SetSpecialFlag(), sFactionStore, SkillByQuestSort(), sMailTemplateStore, Quest::SourceSpellid, Quest::SpecialFlags, SPELL_EFFECT_QUEST_COMPLETE, sQuestSortStore, sSkillLineStore, sSpellMgr, Quest::StartItem, Quest::StartItemCount, sWorld, Quest::TimeAllowed, WorldDatabase, and Quest::ZoneOrSort.

◆ LoadQuestStartersAndEnders()

void ObjectMgr::LoadQuestStartersAndEnders ( )
inline
957 {
958 LOG_INFO("server.loading", "Loading GO Start Quest Data...");
960 LOG_INFO("server.loading", "Loading GO End Quest Data...");
962 LOG_INFO("server.loading", "Loading Creature Start Quest Data...");
964 LOG_INFO("server.loading", "Loading Creature End Quest Data...");
966 }
void LoadCreatureQuestEnders()
Definition ObjectMgr.cpp:8672
void LoadGameobjectQuestEnders()
Definition ObjectMgr.cpp:8644
void LoadGameobjectQuestStarters()
Definition ObjectMgr.cpp:8630
void LoadCreatureQuestStarters()
Definition ObjectMgr.cpp:8658

References LoadCreatureQuestEnders(), LoadCreatureQuestStarters(), LoadGameobjectQuestEnders(), LoadGameobjectQuestStarters(), and LOG_INFO.

◆ LoadReferenceVendor()

int ObjectMgr::LoadReferenceVendor ( int32  vendor,
int32  item_id,
std::set< uint32 > *  skip_vendors 
)
9781{
9782 // find all items from the reference vendor
9784 stmt->SetData(0, uint32(item));
9785 PreparedQueryResult result = WorldDatabase.Query(stmt);
9786
9787 if (!result)
9788 return 0;
9789
9790 uint32 count = 0;
9791 do
9792 {
9793 Field* fields = result->Fetch();
9794
9795 int32 item_id = fields[0].Get<int32>();
9796
9797 // if item is a negative, its a reference
9798 if (item_id < 0)
9799 count += LoadReferenceVendor(vendor, -item_id, skip_vendors);
9800 else
9801 {
9802 int32 maxcount = fields[1].Get<uint8>();
9803 uint32 incrtime = fields[2].Get<uint32>();
9804 uint32 ExtendedCost = fields[3].Get<uint32>();
9805
9806 if (!IsVendorItemValid(vendor, item_id, maxcount, incrtime, ExtendedCost, nullptr, skip_vendors))
9807 continue;
9808
9809 VendorItemData& vList = _cacheVendorItemStore[vendor];
9810
9811 vList.AddItem(item_id, maxcount, incrtime, ExtendedCost);
9812 ++count;
9813 }
9814 } while (result->NextRow());
9815
9816 return count;
9817}
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition DatabaseEnvFwd.h:45
@ WORLD_SEL_NPC_VENDOR_REF
Definition WorldDatabase.h:45
bool IsVendorItemValid(uint32 vendor_entry, uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost, Player *player=nullptr, std::set< uint32 > *skip_vendors=nullptr, uint32 ORnpcflag=0) const
Definition ObjectMgr.cpp:10042
int LoadReferenceVendor(int32 vendor, int32 item_id, std::set< uint32 > *skip_vendors)
Definition ObjectMgr.cpp:9780

References _cacheVendorItemStore, VendorItemData::AddItem(), Field::Get(), IsVendorItemValid(), LoadReferenceVendor(), PreparedStatementBase::SetData(), WORLD_SEL_NPC_VENDOR_REF, and WorldDatabase.

Referenced by LoadReferenceVendor(), and LoadVendors().

◆ LoadReputationOnKill()

void ObjectMgr::LoadReputationOnKill ( )
8177{
8178 uint32 oldMSTime = getMSTime();
8179
8180 // For reload case
8181 _repOnKillStore.clear();
8182
8183 uint32 count = 0;
8184
8185 // 0 1 2
8186 QueryResult result = WorldDatabase.Query("SELECT creature_id, RewOnKillRepFaction1, RewOnKillRepFaction2, "
8187 // 3 4 5 6 7 8 9
8188 "IsTeamAward1, MaxStanding1, RewOnKillRepValue1, IsTeamAward2, MaxStanding2, RewOnKillRepValue2, TeamDependent "
8189 "FROM creature_onkill_reputation");
8190
8191 if (!result)
8192 {
8193 LOG_WARN("server.loading", ">> Loaded 0 creature award reputation definitions. DB table `creature_onkill_reputation` is empty.");
8194 LOG_INFO("server.loading", " ");
8195 return;
8196 }
8197
8198 do
8199 {
8200 Field* fields = result->Fetch();
8201
8202 uint32 creature_id = fields[0].Get<uint32>();
8203
8204 ReputationOnKillEntry repOnKill;
8205 repOnKill.RepFaction1 = fields[1].Get<int16>();
8206 repOnKill.RepFaction2 = fields[2].Get<int16>();
8207 repOnKill.IsTeamAward1 = fields[3].Get<bool>();
8208 repOnKill.ReputationMaxCap1 = fields[4].Get<uint8>();
8209 repOnKill.RepValue1 = fields[5].Get<float>();
8210 repOnKill.IsTeamAward2 = fields[6].Get<bool>();
8211 repOnKill.ReputationMaxCap2 = fields[7].Get<uint8>();
8212 repOnKill.RepValue2 = fields[8].Get<float>();
8213 repOnKill.TeamDependent = fields[9].Get<uint8>();
8214
8215 if (!GetCreatureTemplate(creature_id))
8216 {
8217 LOG_ERROR("sql.sql", "Table `creature_onkill_reputation` have data for not existed creature entry ({}), skipped", creature_id);
8218 continue;
8219 }
8220
8221 if (repOnKill.RepFaction1)
8222 {
8223 FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(repOnKill.RepFaction1);
8224 if (!factionEntry1)
8225 {
8226 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.RepFaction1);
8227 continue;
8228 }
8229 }
8230
8231 if (repOnKill.RepFaction2)
8232 {
8233 FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(repOnKill.RepFaction2);
8234 if (!factionEntry2)
8235 {
8236 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.RepFaction2);
8237 continue;
8238 }
8239 }
8240
8241 _repOnKillStore[creature_id] = repOnKill;
8242
8243 ++count;
8244 } while (result->NextRow());
8245
8246 LOG_INFO("server.loading", ">> Loaded {} Creature Award Reputation Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8247 LOG_INFO("server.loading", " ");
8248}
Definition ObjectMgr.h:569
uint32 RepFaction1
Definition ObjectMgr.h:570

References _repOnKillStore, Field::Get(), GetCreatureTemplate(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, ReputationOnKillEntry::RepFaction1, sFactionStore, and WorldDatabase.

◆ LoadReputationRewardRate()

void ObjectMgr::LoadReputationRewardRate ( )
8089{
8090 uint32 oldMSTime = getMSTime();
8091
8092 _repRewardRateStore.clear(); // for reload case
8093
8094 uint32 count = 0; // 0 1 2 3 4 5 6 7
8095 QueryResult result = WorldDatabase.Query("SELECT faction, quest_rate, quest_daily_rate, quest_weekly_rate, quest_monthly_rate, quest_repeatable_rate, creature_rate, spell_rate FROM reputation_reward_rate");
8096 if (!result)
8097 {
8098 LOG_INFO("server.loading", ">> Loaded `reputation_reward_rate`, table is empty!");
8099 return;
8100 }
8101
8102 do
8103 {
8104 Field* fields = result->Fetch();
8105
8106 uint32 factionId = fields[0].Get<uint32>();
8107
8108 RepRewardRate repRate;
8109
8110 repRate.questRate = fields[1].Get<float>();
8111 repRate.questDailyRate = fields[2].Get<float>();
8112 repRate.questWeeklyRate = fields[3].Get<float>();
8113 repRate.questMonthlyRate = fields[4].Get<float>();
8114 repRate.questRepeatableRate = fields[5].Get<float>();
8115 repRate.creatureRate = fields[6].Get<float>();
8116 repRate.spellRate = fields[7].Get<float>();
8117
8118 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
8119 if (!factionEntry)
8120 {
8121 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_reward_rate`", factionId);
8122 continue;
8123 }
8124
8125 if (repRate.questRate < 0.0f)
8126 {
8127 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_rate with invalid rate {}, skipping data for faction {}", repRate.questRate, factionId);
8128 continue;
8129 }
8130
8131 if (repRate.questDailyRate < 0.0f)
8132 {
8133 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_daily_rate with invalid rate {}, skipping data for faction {}", repRate.questDailyRate, factionId);
8134 continue;
8135 }
8136
8137 if (repRate.questWeeklyRate < 0.0f)
8138 {
8139 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_weekly_rate with invalid rate {}, skipping data for faction {}", repRate.questWeeklyRate, factionId);
8140 continue;
8141 }
8142
8143 if (repRate.questMonthlyRate < 0.0f)
8144 {
8145 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_monthly_rate with invalid rate {}, skipping data for faction {}", repRate.questMonthlyRate, factionId);
8146 continue;
8147 }
8148
8149 if (repRate.questRepeatableRate < 0.0f)
8150 {
8151 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_repeatable_rate with invalid rate {}, skipping data for faction {}", repRate.questRepeatableRate, factionId);
8152 continue;
8153 }
8154
8155 if (repRate.creatureRate < 0.0f)
8156 {
8157 LOG_ERROR("sql.sql", "Table reputation_reward_rate has creature_rate with invalid rate {}, skipping data for faction {}", repRate.creatureRate, factionId);
8158 continue;
8159 }
8160
8161 if (repRate.spellRate < 0.0f)
8162 {
8163 LOG_ERROR("sql.sql", "Table reputation_reward_rate has spell_rate with invalid rate {}, skipping data for faction {}", repRate.spellRate, factionId);
8164 continue;
8165 }
8166
8167 _repRewardRateStore[factionId] = repRate;
8168
8169 ++count;
8170 } while (result->NextRow());
8171
8172 LOG_INFO("server.loading", ">> Loaded {} Reputation Reward Rate in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8173 LOG_INFO("server.loading", " ");
8174}
Definition ObjectMgr.h:558
float questRate
Definition ObjectMgr.h:559

References _repRewardRateStore, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, RepRewardRate::questRate, sFactionStore, and WorldDatabase.

◆ LoadReputationSpilloverTemplate()

void ObjectMgr::LoadReputationSpilloverTemplate ( )
8251{
8252 uint32 oldMSTime = getMSTime();
8253
8254 _repSpilloverTemplateStore.clear(); // for reload case
8255
8256 uint32 count = 0; // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
8257 QueryResult result = WorldDatabase.Query("SELECT faction, faction1, rate_1, rank_1, faction2, rate_2, rank_2, faction3, rate_3, rank_3, faction4, rate_4, rank_4, faction5, rate_5, rank_5, faction6, rate_6, rank_6 FROM reputation_spillover_template");
8258
8259 if (!result)
8260 {
8261 LOG_INFO("server.loading", ">> Loaded `reputation_spillover_template`, table is empty.");
8262 LOG_INFO("server.loading", " ");
8263 return;
8264 }
8265
8266 do
8267 {
8268 Field* fields = result->Fetch();
8269
8270 uint32 factionId = fields[0].Get<uint16>();
8271
8272 RepSpilloverTemplate repTemplate;
8273
8274 repTemplate.faction[0] = fields[1].Get<uint16>();
8275 repTemplate.faction_rate[0] = fields[2].Get<float>();
8276 repTemplate.faction_rank[0] = fields[3].Get<uint8>();
8277 repTemplate.faction[1] = fields[4].Get<uint16>();
8278 repTemplate.faction_rate[1] = fields[5].Get<float>();
8279 repTemplate.faction_rank[1] = fields[6].Get<uint8>();
8280 repTemplate.faction[2] = fields[7].Get<uint16>();
8281 repTemplate.faction_rate[2] = fields[8].Get<float>();
8282 repTemplate.faction_rank[2] = fields[9].Get<uint8>();
8283 repTemplate.faction[3] = fields[10].Get<uint16>();
8284 repTemplate.faction_rate[3] = fields[11].Get<float>();
8285 repTemplate.faction_rank[3] = fields[12].Get<uint8>();
8286 repTemplate.faction[4] = fields[13].Get<uint16>();
8287 repTemplate.faction_rate[4] = fields[14].Get<float>();
8288 repTemplate.faction_rank[4] = fields[15].Get<uint8>();
8289 repTemplate.faction[5] = fields[16].Get<uint16>();
8290 repTemplate.faction_rate[5] = fields[17].Get<float>();
8291 repTemplate.faction_rank[5] = fields[18].Get<uint8>();
8292
8293 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
8294
8295 if (!factionEntry)
8296 {
8297 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", factionId);
8298 continue;
8299 }
8300
8301 if (factionEntry->team == 0)
8302 {
8303 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} in `reputation_spillover_template` does not belong to any team, skipping", factionId);
8304 continue;
8305 }
8306
8307 for (uint32 i = 0; i < MAX_SPILLOVER_FACTIONS; ++i)
8308 {
8309 if (repTemplate.faction[i])
8310 {
8311 FactionEntry const* factionSpillover = sFactionStore.LookupEntry(repTemplate.faction[i]);
8312
8313 if (!factionSpillover)
8314 {
8315 LOG_ERROR("sql.sql", "Spillover faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template` for faction {}, skipping", repTemplate.faction[i], factionId);
8316 continue;
8317 }
8318
8319 if (factionSpillover->reputationListID < 0)
8320 {
8321 LOG_ERROR("sql.sql", "Spillover faction (faction.dbc) {} for faction {} in `reputation_spillover_template` can not be listed for client, and then useless, skipping", repTemplate.faction[i], factionId);
8322 continue;
8323 }
8324
8325 if (repTemplate.faction_rank[i] >= MAX_REPUTATION_RANK)
8326 {
8327 LOG_ERROR("sql.sql", "Rank {} used in `reputation_spillover_template` for spillover faction {} is not valid, skipping", repTemplate.faction_rank[i], repTemplate.faction[i]);
8328 continue;
8329 }
8330 }
8331 }
8332
8333 FactionEntry const* factionEntry0 = sFactionStore.LookupEntry(repTemplate.faction[0]);
8334 if (repTemplate.faction[0] && !factionEntry0)
8335 {
8336 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[0]);
8337 continue;
8338 }
8339 FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(repTemplate.faction[1]);
8340 if (repTemplate.faction[1] && !factionEntry1)
8341 {
8342 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[1]);
8343 continue;
8344 }
8345 FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(repTemplate.faction[2]);
8346 if (repTemplate.faction[2] && !factionEntry2)
8347 {
8348 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[2]);
8349 continue;
8350 }
8351 FactionEntry const* factionEntry3 = sFactionStore.LookupEntry(repTemplate.faction[3]);
8352 if (repTemplate.faction[3] && !factionEntry3)
8353 {
8354 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[3]);
8355 continue;
8356 }
8357
8358 _repSpilloverTemplateStore[factionId] = repTemplate;
8359
8360 ++count;
8361 } while (result->NextRow());
8362
8363 LOG_INFO("server.loading", ">> Loaded {} Reputation Spillover Template in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8364 LOG_INFO("server.loading", " ");
8365}
#define MAX_SPILLOVER_FACTIONS
Definition SharedDefines.h:258
int32 reputationListID
Definition DBCStructure.h:909
Definition ObjectMgr.h:582
uint32 faction[MAX_SPILLOVER_FACTIONS]
Definition ObjectMgr.h:583

References _repSpilloverTemplateStore, RepSpilloverTemplate::faction, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, MAX_REPUTATION_RANK, MAX_SPILLOVER_FACTIONS, FactionEntry::reputationListID, sFactionStore, and WorldDatabase.

◆ LoadReservedPlayerNamesDB()

void ObjectMgr::LoadReservedPlayerNamesDB ( )
8687{
8688 uint32 oldMSTime = getMSTime();
8689
8690 _reservedNamesStore.clear(); // need for reload case
8691
8692 QueryResult result = CharacterDatabase.Query("SELECT name FROM reserved_name");
8693
8694 if (!result)
8695 {
8696 LOG_WARN("server.loading", ">> Loaded 0 reserved names. DB table `reserved_name` is empty!");
8697 return;
8698 }
8699
8700 uint32 count = 0;
8701
8702 Field* fields;
8703 do
8704 {
8705 fields = result->Fetch();
8706 std::string name = fields[0].Get<std::string>();
8707
8708 std::wstring wstr;
8709 if (!Utf8toWStr (name, wstr))
8710 {
8711 LOG_ERROR("sql.sql", "Table `reserved_name` have invalid name: {}", name);
8712 continue;
8713 }
8714
8715 wstrToLower(wstr);
8716
8717 _reservedNamesStore.insert(wstr);
8718 ++count;
8719 } while (result->NextRow());
8720
8721 LOG_INFO("server.loading", ">> Loaded {} reserved names from DB in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8722}

References _reservedNamesStore, CharacterDatabase, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, Utf8toWStr(), and wstrToLower().

◆ LoadReservedPlayerNamesDBC()

void ObjectMgr::LoadReservedPlayerNamesDBC ( )
8725{
8726 if (!sWorld->getBoolConfig(CONFIG_STRICT_NAMES_RESERVED))
8727 {
8728 LOG_WARN("server.loading", ">> Loaded 0 reserved names from DBC. Config option disabled.");
8729 return;
8730 }
8731
8732 uint32 oldMSTime = getMSTime();
8733
8734 uint32 count = 0;
8735
8736 for (NamesReservedEntry const* reservedStore : sNamesReservedStore)
8737 {
8738 std::wstring wstr;
8739
8740 Utf8toWStr(reservedStore->Pattern, wstr);
8741
8742 // DBC does not have clean entries, remove the junk.
8743 boost::algorithm::replace_all(wstr, "\\<", "");
8744 boost::algorithm::replace_all(wstr, "\\>", "");
8745
8746 _reservedNamesStore.insert(wstr);
8747 count++;
8748 }
8749
8750 LOG_INFO("server.loading", ">> Loaded {} reserved names from DBC in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8751 LOG_INFO("server.loading", " ");
8752}
DBCStorage< NamesReservedEntry > sNamesReservedStore(NamesReservedfmt)
@ CONFIG_STRICT_NAMES_RESERVED
Definition WorldConfig.h:141
Definition DBCStructure.h:1398

References _reservedNamesStore, CONFIG_STRICT_NAMES_RESERVED, getMSTime(), GetMSTimeDiffToNow(), LOG_INFO, LOG_WARN, sNamesReservedStore, sWorld, and Utf8toWStr().

◆ LoadScriptNames()

void ObjectMgr::LoadScriptNames ( )
10123{
10124 uint32 oldMSTime = getMSTime();
10125
10126 // We insert an empty placeholder here so we can use the
10127 // script id 0 as dummy for "no script found".
10128 _scriptNamesStore.emplace_back("");
10129
10130 QueryResult result = WorldDatabase.Query(
10131 "SELECT DISTINCT(ScriptName) FROM achievement_criteria_data WHERE ScriptName <> '' AND type = 11 "
10132 "UNION "
10133 "SELECT DISTINCT(ScriptName) FROM battleground_template WHERE ScriptName <> '' "
10134 "UNION "
10135 "SELECT DISTINCT(ScriptName) FROM creature WHERE ScriptName <> '' "
10136 "UNION "
10137 "SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' "
10138 "UNION "
10139 "SELECT DISTINCT(ScriptName) FROM gameobject WHERE ScriptName <> '' "
10140 "UNION "
10141 "SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' "
10142 "UNION "
10143 "SELECT DISTINCT(ScriptName) FROM item_template WHERE ScriptName <> '' "
10144 "UNION "
10145 "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
10146 "UNION "
10147 "SELECT DISTINCT(ScriptName) FROM spell_script_names WHERE ScriptName <> '' "
10148 "UNION "
10149 "SELECT DISTINCT(ScriptName) FROM transports WHERE ScriptName <> '' "
10150 "UNION "
10151 "SELECT DISTINCT(ScriptName) FROM game_weather WHERE ScriptName <> '' "
10152 "UNION "
10153 "SELECT DISTINCT(ScriptName) FROM conditions WHERE ScriptName <> '' "
10154 "UNION "
10155 "SELECT DISTINCT(ScriptName) FROM outdoorpvp_template WHERE ScriptName <> '' "
10156 "UNION "
10157 "SELECT DISTINCT(script) FROM instance_template WHERE script <> ''");
10158
10159 if (!result)
10160 {
10161 LOG_INFO("server.loading", " ");
10162 LOG_ERROR("sql.sql", ">> Loaded empty set of Script Names!");
10163 return;
10164 }
10165
10166 _scriptNamesStore.reserve(result->GetRowCount() + 1);
10167
10168 do
10169 {
10170 _scriptNamesStore.push_back((*result)[0].Get<std::string>());
10171 } while (result->NextRow());
10172
10173 std::sort(_scriptNamesStore.begin(), _scriptNamesStore.end());
10174 LOG_INFO("server.loading", ">> Loaded {} ScriptNames in {} ms", _scriptNamesStore.size(), GetMSTimeDiffToNow(oldMSTime));
10175 LOG_INFO("server.loading", " ");
10176}

References _scriptNamesStore, getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, and WorldDatabase.

◆ LoadScripts()

void ObjectMgr::LoadScripts ( ScriptsType  type)
private
5742{
5743 uint32 oldMSTime = getMSTime();
5744
5745 ScriptMapMap* scripts = GetScriptsMapByType(type);
5746 if (!scripts)
5747 return;
5748
5749 std::string tableName = GetScriptsTableNameByType(type);
5750 if (tableName.empty())
5751 return;
5752
5753 if (sScriptMgr->IsScriptScheduled()) // function cannot be called when scripts are in use.
5754 return;
5755
5756 LOG_INFO("server.loading", "Loading {}...", tableName);
5757
5758 scripts->clear(); // need for reload support
5759
5760 bool isSpellScriptTable = (type == SCRIPTS_SPELL);
5761 // 0 1 2 3 4 5 6 7 8 9
5762 QueryResult result = WorldDatabase.Query("SELECT id, delay, command, datalong, datalong2, dataint, x, y, z, o{} FROM {}", isSpellScriptTable ? ", effIndex" : "", tableName);
5763
5764 if (!result)
5765 {
5766 LOG_WARN("server.loading", ">> Loaded 0 script definitions. DB table `{}` is empty!", tableName);
5767 LOG_INFO("server.loading", " ");
5768 return;
5769 }
5770
5771 uint32 count = 0;
5772
5773 do
5774 {
5775 Field* fields = result->Fetch();
5776 ScriptInfo tmp;
5777 tmp.type = type;
5778 tmp.id = fields[0].Get<uint32>();
5779 if (isSpellScriptTable)
5780 tmp.id |= fields[10].Get<uint8>() << 24;
5781 tmp.delay = fields[1].Get<uint32>();
5782 tmp.command = ScriptCommands(fields[2].Get<uint32>());
5783 tmp.Raw.nData[0] = fields[3].Get<uint32>();
5784 tmp.Raw.nData[1] = fields[4].Get<uint32>();
5785 tmp.Raw.nData[2] = fields[5].Get<int32>();
5786 tmp.Raw.fData[0] = fields[6].Get<float>();
5787 tmp.Raw.fData[1] = fields[7].Get<float>();
5788 tmp.Raw.fData[2] = fields[8].Get<float>();
5789 tmp.Raw.fData[3] = fields[9].Get<float>();
5790
5791 // generic command args check
5792 switch (tmp.command)
5793 {
5795 {
5797 {
5798 LOG_ERROR("sql.sql", "Table `{}` has invalid talk type (datalong = {}) in SCRIPT_COMMAND_TALK for script id {}",
5799 tableName, tmp.Talk.ChatType, tmp.id);
5800 continue;
5801 }
5803 {
5804 LOG_ERROR("sql.sql", "Table `{}` has invalid talk text id (dataint = {}) in SCRIPT_COMMAND_TALK for script id {}",
5805 tableName, tmp.Talk.TextID, tmp.id);
5806 continue;
5807 }
5808 break;
5809 }
5810
5812 {
5813 if (!sEmotesStore.LookupEntry(tmp.Emote.EmoteID))
5814 {
5815 LOG_ERROR("sql.sql", "Table `{}` has invalid emote id (datalong = {}) in SCRIPT_COMMAND_EMOTE for script id {}",
5816 tableName, tmp.Emote.EmoteID, tmp.id);
5817 continue;
5818 }
5819 break;
5820 }
5821
5823 {
5824 if (!sMapStore.LookupEntry(tmp.TeleportTo.MapID))
5825 {
5826 LOG_ERROR("sql.sql", "Table `{}` has invalid map (Id: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
5827 tableName, tmp.TeleportTo.MapID, tmp.id);
5828 continue;
5829 }
5830
5832 {
5833 LOG_ERROR("sql.sql", "Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
5834 tableName, tmp.TeleportTo.DestX, tmp.TeleportTo.DestY, tmp.TeleportTo.DestZ, tmp.TeleportTo.Orientation, tmp.id);
5835 continue;
5836 }
5837 break;
5838 }
5839
5841 {
5842 Quest const* quest = GetQuestTemplate(tmp.QuestExplored.QuestID);
5843 if (!quest)
5844 {
5845 LOG_ERROR("sql.sql", "Table `{}` has invalid quest (ID: {}) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id {}",
5846 tableName, tmp.QuestExplored.QuestID, tmp.id);
5847 continue;
5848 }
5849
5851 {
5852 LOG_ERROR("sql.sql", "Table `{}` has quest (ID: {}) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id {}, but quest not have specialflag QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT in quest flags. Script command or quest flags wrong. Quest modified to require objective.",
5853 tableName, tmp.QuestExplored.QuestID, tmp.id);
5854
5855 // this will prevent quest completing without objective
5856 const_cast<Quest*>(quest)->SetSpecialFlag(QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT);
5857
5858 // continue; - quest objective requirement set and command can be allowed
5859 }
5860
5862 {
5863 LOG_ERROR("sql.sql", "Table `{}` has too large distance ({}) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id {}",
5864 tableName, tmp.QuestExplored.Distance, tmp.id);
5865 continue;
5866 }
5867
5869 {
5870 LOG_ERROR("sql.sql", "Table `{}` has too large distance ({}) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id {}, max distance is {} or 0 for disable distance check",
5872 continue;
5873 }
5874
5876 {
5877 LOG_ERROR("sql.sql", "Table `{}` has too small distance ({}) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id {}, min distance is {} or 0 for disable distance check",
5878 tableName, tmp.QuestExplored.Distance, tmp.id, INTERACTION_DISTANCE);
5879 continue;
5880 }
5881
5882 break;
5883 }
5884
5886 {
5888 {
5889 LOG_ERROR("sql.sql", "Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_KILL_CREDIT for script id {}",
5890 tableName, tmp.KillCredit.CreatureEntry, tmp.id);
5891 continue;
5892 }
5893 break;
5894 }
5895
5897 {
5899 if (!data)
5900 {
5901 LOG_ERROR("sql.sql", "Table `{}` has invalid gameobject (GUID: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5902 tableName, tmp.RespawnGameobject.GOGuid, tmp.id);
5903 continue;
5904 }
5905
5906 GameObjectTemplate const* info = GetGameObjectTemplate(data->id);
5907 if (!info)
5908 {
5909 LOG_ERROR("sql.sql", "Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5910 tableName, tmp.RespawnGameobject.GOGuid, data->id, tmp.id);
5911 continue;
5912 }
5913
5914 if (info->type == GAMEOBJECT_TYPE_FISHINGNODE ||
5916 info->type == GAMEOBJECT_TYPE_DOOR ||
5917 info->type == GAMEOBJECT_TYPE_BUTTON ||
5918 info->type == GAMEOBJECT_TYPE_TRAP)
5919 {
5920 LOG_ERROR("sql.sql", "Table `{}` have gameobject type ({}) unsupported by command SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5921 tableName, info->entry, tmp.id);
5922 continue;
5923 }
5924 break;
5925 }
5926
5928 {
5930 {
5931 LOG_ERROR("sql.sql", "Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
5933 continue;
5934 }
5935
5937 if (!GetCreatureTemplate(entry))
5938 {
5939 LOG_ERROR("sql.sql", "Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
5940 tableName, tmp.TempSummonCreature.CreatureEntry, tmp.id);
5941 continue;
5942 }
5943 break;
5944 }
5945
5948 {
5950 if (!data)
5951 {
5952 LOG_ERROR("sql.sql", "Table `{}` has invalid gameobject (GUID: {}) in {} for script id {}",
5953 tableName, tmp.ToggleDoor.GOGuid, GetScriptCommandName(tmp.command), tmp.id);
5954 continue;
5955 }
5956
5957 GameObjectTemplate const* info = GetGameObjectTemplate(data->id);
5958 if (!info)
5959 {
5960 LOG_ERROR("sql.sql", "Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in {} for script id {}",
5961 tableName, tmp.ToggleDoor.GOGuid, data->id, GetScriptCommandName(tmp.command), tmp.id);
5962 continue;
5963 }
5964
5965 if (info->type != GAMEOBJECT_TYPE_DOOR)
5966 {
5967 LOG_ERROR("sql.sql", "Table `{}` has gameobject type ({}) non supported by command {} for script id {}",
5968 tableName, info->entry, GetScriptCommandName(tmp.command), tmp.id);
5969 continue;
5970 }
5971
5972 break;
5973 }
5974
5976 {
5977 if (!sSpellMgr->GetSpellInfo(tmp.RemoveAura.SpellID))
5978 {
5979 LOG_ERROR("sql.sql", "Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
5980 tableName, tmp.RemoveAura.SpellID, tmp.id);
5981 continue;
5982 }
5983 if (tmp.RemoveAura.Flags & ~0x1) // 1 bits (0, 1)
5984 {
5985 LOG_ERROR("sql.sql", "Table `{}` using unknown flags in datalong2 ({}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
5986 tableName, tmp.RemoveAura.Flags, tmp.id);
5987 continue;
5988 }
5989 break;
5990 }
5991
5993 {
5994 if (!sSpellMgr->GetSpellInfo(tmp.CastSpell.SpellID))
5995 {
5996 LOG_ERROR("sql.sql", "Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5997 tableName, tmp.CastSpell.SpellID, tmp.id);
5998 continue;
5999 }
6000 if (tmp.CastSpell.Flags > 4) // targeting type
6001 {
6002 LOG_ERROR("sql.sql", "Table `{}` using unknown target in datalong2 ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
6003 tableName, tmp.CastSpell.Flags, tmp.id);
6004 continue;
6005 }
6006 if (tmp.CastSpell.Flags != 4 && tmp.CastSpell.CreatureEntry & ~0x1) // 1 bit (0, 1)
6007 {
6008 LOG_ERROR("sql.sql", "Table `{}` using unknown flags in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
6009 tableName, tmp.CastSpell.CreatureEntry, tmp.id);
6010 continue;
6011 }
6012 else if (tmp.CastSpell.Flags == 4 && !GetCreatureTemplate(tmp.CastSpell.CreatureEntry))
6013 {
6014 LOG_ERROR("sql.sql", "Table `{}` using invalid creature entry in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
6015 tableName, tmp.CastSpell.CreatureEntry, tmp.id);
6016 continue;
6017 }
6018 break;
6019 }
6020
6022 {
6024 {
6025 LOG_ERROR("sql.sql", "Table `{}` has nonexistent item (entry: {}) in SCRIPT_COMMAND_CREATE_ITEM for script id {}",
6026 tableName, tmp.CreateItem.ItemEntry, tmp.id);
6027 continue;
6028 }
6029 if (!tmp.CreateItem.Amount)
6030 {
6031 LOG_ERROR("sql.sql", "Table `{}` SCRIPT_COMMAND_CREATE_ITEM but amount is {} for script id {}",
6032 tableName, tmp.CreateItem.Amount, tmp.id);
6033 continue;
6034 }
6035 break;
6036 }
6037 default:
6038 break;
6039 }
6040
6041 if (scripts->find(tmp.id) == scripts->end())
6042 {
6043 ScriptMap emptyMap;
6044 (*scripts)[tmp.id] = emptyMap;
6045 }
6046 (*scripts)[tmp.id].insert(std::pair<uint32, ScriptInfo>(tmp.delay, tmp));
6047
6048 ++count;
6049 } while (result->NextRow());
6050
6051 LOG_INFO("server.loading", ">> Loaded {} script definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6052 LOG_INFO("server.loading", " ");
6053}
@ CHAT_TYPE_WHISPER
Definition CreatureData.h:421
#define DEFAULT_VISIBILITY_DISTANCE
Definition ObjectDefines.h:39
#define INTERACTION_DISTANCE
Definition ObjectDefines.h:24
std::multimap< uint32, ScriptInfo > ScriptMap
Definition ObjectMgr.h:386
ScriptMapMap * GetScriptsMapByType(ScriptsType type)
Definition ObjectMgr.cpp:83
ScriptCommands
Definition ObjectMgr.h:92
@ SCRIPT_COMMAND_EMOTE
Definition ObjectMgr.h:94
@ SCRIPT_COMMAND_CREATE_ITEM
Definition ObjectMgr.h:110
@ SCRIPT_COMMAND_CLOSE_DOOR
Definition ObjectMgr.h:105
@ SCRIPT_COMMAND_CAST_SPELL
Definition ObjectMgr.h:108
@ SCRIPT_COMMAND_RESPAWN_GAMEOBJECT
Definition ObjectMgr.h:102
@ SCRIPT_COMMAND_QUEST_EXPLORED
Definition ObjectMgr.h:100
@ SCRIPT_COMMAND_TALK
Definition ObjectMgr.h:93
@ SCRIPT_COMMAND_OPEN_DOOR
Definition ObjectMgr.h:104
@ SCRIPT_COMMAND_TELEPORT_TO
Definition ObjectMgr.h:99
@ SCRIPT_COMMAND_TEMP_SUMMON_CREATURE
Definition ObjectMgr.h:103
@ SCRIPT_COMMAND_KILL_CREDIT
Definition ObjectMgr.h:101
@ SCRIPT_COMMAND_REMOVE_AURA
Definition ObjectMgr.h:107
std::string GetScriptCommandName(ScriptCommands command)
Definition ObjectMgr.cpp:103
std::map< uint32, ScriptMap > ScriptMapMap
Definition ObjectMgr.h:387
std::string GetScriptsTableNameByType(ScriptsType type)
Definition ObjectMgr.cpp:63
@ SCRIPTS_SPELL
Definition ObjectMgr.h:149
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition SharedDefines.h:1588
@ CHAT_MSG_RAID_BOSS_WHISPER
Definition SharedDefines.h:3434
Definition ObjectMgr.h:191
float Orientation
Definition ObjectMgr.h:251
uint32 Flags
Definition ObjectMgr.h:208
ScriptsType type
Definition ObjectMgr.h:192
struct ScriptInfo::@269::@279 KillCredit
uint32 QuestID
Definition ObjectMgr.h:256
struct ScriptInfo::@269::@282 ToggleDoor
int32 TextID
Definition ObjectMgr.h:209
struct ScriptInfo::@269::@271 Raw
struct ScriptInfo::@269::@277 TeleportTo
float DestX
Definition ObjectMgr.h:230
uint32 ItemEntry
Definition ObjectMgr.h:317
uint32 ChatType
Definition ObjectMgr.h:207
struct ScriptInfo::@269::@283 RemoveAura
uint32 id
Definition ObjectMgr.h:193
uint32 delay
Definition ObjectMgr.h:194
float fData[4]
Definition ObjectMgr.h:202
float PosY
Definition ObjectMgr.h:279
ScriptCommands command
Definition ObjectMgr.h:195
float DestY
Definition ObjectMgr.h:231
uint32 MapID
Definition ObjectMgr.h:244
uint32 nData[3]
Definition ObjectMgr.h:201
struct ScriptInfo::@269::@273 Emote
float PosZ
Definition ObjectMgr.h:280
struct ScriptInfo::@269::@280 RespawnGameobject
struct ScriptInfo::@269::@281 TempSummonCreature
struct ScriptInfo::@269::@278 QuestExplored
float PosX
Definition ObjectMgr.h:278
struct ScriptInfo::@269::@286 CreateItem
uint32 Distance
Definition ObjectMgr.h:257
uint32 SpellID
Definition ObjectMgr.h:295
struct ScriptInfo::@269::@284 CastSpell
float DestZ
Definition ObjectMgr.h:232
uint32 GOGuid
Definition ObjectMgr.h:268
uint32 CreatureEntry
Definition ObjectMgr.h:262
uint32 Amount
Definition ObjectMgr.h:318
struct ScriptInfo::@269::@272 Talk
uint32 EmoteID
Definition ObjectMgr.h:214

References ScriptInfo::Amount, ScriptInfo::CastSpell, CHAT_MSG_RAID_BOSS_WHISPER, CHAT_TYPE_WHISPER, ScriptInfo::ChatType, ScriptInfo::command, ScriptInfo::CreateItem, ScriptInfo::CreatureEntry, DEFAULT_VISIBILITY_DISTANCE, ScriptInfo::delay, ScriptInfo::DestX, ScriptInfo::DestY, ScriptInfo::DestZ, ScriptInfo::Distance, ScriptInfo::Emote, ScriptInfo::EmoteID, GameObjectTemplate::entry, ScriptInfo::fData, ScriptInfo::Flags, GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_FISHINGNODE, GAMEOBJECT_TYPE_TRAP, Field::Get(), GetBroadcastText(), GetCreatureTemplate(), GetGameObjectData(), GetGameObjectTemplate(), GetItemTemplate(), getMSTime(), GetMSTimeDiffToNow(), GetQuestTemplate(), GetScriptCommandName(), GetScriptsMapByType(), GetScriptsTableNameByType(), ScriptInfo::GOGuid, Quest::HasSpecialFlag(), GameObjectData::id, ScriptInfo::id, INTERACTION_DISTANCE, Acore::IsValidMapCoord(), ScriptInfo::ItemEntry, ScriptInfo::KillCredit, LOG_ERROR, LOG_INFO, LOG_WARN, ScriptInfo::MapID, ScriptInfo::nData, ScriptInfo::Orientation, ScriptInfo::PosX, ScriptInfo::PosY, ScriptInfo::PosZ, QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT, ScriptInfo::QuestExplored, ScriptInfo::QuestID, ScriptInfo::Raw, ScriptInfo::RemoveAura, ScriptInfo::RespawnGameobject, SCRIPT_COMMAND_CAST_SPELL, SCRIPT_COMMAND_CLOSE_DOOR, SCRIPT_COMMAND_CREATE_ITEM, SCRIPT_COMMAND_EMOTE, SCRIPT_COMMAND_KILL_CREDIT, SCRIPT_COMMAND_OPEN_DOOR, SCRIPT_COMMAND_QUEST_EXPLORED, SCRIPT_COMMAND_REMOVE_AURA, SCRIPT_COMMAND_RESPAWN_GAMEOBJECT, SCRIPT_COMMAND_TALK, SCRIPT_COMMAND_TELEPORT_TO, SCRIPT_COMMAND_TEMP_SUMMON_CREATURE, SCRIPTS_SPELL, sEmotesStore, sMapStore, ScriptInfo::SpellID, sScriptMgr, sSpellMgr, ScriptInfo::Talk, ScriptInfo::TeleportTo, ScriptInfo::TempSummonCreature, ScriptInfo::TextID, ScriptInfo::ToggleDoor, GameObjectTemplate::type, ScriptInfo::type, and WorldDatabase.

Referenced by LoadEventScripts(), LoadSpellScripts(), and LoadWaypointScripts().

◆ LoadSpellScriptNames()

void ObjectMgr::LoadSpellScriptNames ( )
6155{
6156 uint32 oldMSTime = getMSTime();
6157
6158 _spellScriptsStore.clear(); // need for reload case
6159
6160 QueryResult result = WorldDatabase.Query("SELECT spell_id, ScriptName FROM spell_script_names");
6161
6162 if (!result)
6163 {
6164 LOG_WARN("server.loading", ">> Loaded 0 spell script names. DB table `spell_script_names` is empty!");
6165 LOG_INFO("server.loading", " ");
6166 return;
6167 }
6168
6169 uint32 count = 0;
6170
6171 do
6172 {
6173 Field* fields = result->Fetch();
6174
6175 int32 spellId = fields[0].Get<int32>();
6176 std::string scriptName = fields[1].Get<std::string>();
6177
6178 bool allRanks = false;
6179 if (spellId <= 0)
6180 {
6181 allRanks = true;
6182 spellId = -spellId;
6183 }
6184
6185 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
6186 if (!spellInfo)
6187 {
6188 LOG_ERROR("sql.sql", "Scriptname: `{}` spell (spell_id:{}) does not exist in `Spell.dbc`.", scriptName, fields[0].Get<int32>());
6189 continue;
6190 }
6191
6192 if (allRanks)
6193 {
6194 if (sSpellMgr->GetFirstSpellInChain(spellId) != uint32(spellId))
6195 {
6196 LOG_ERROR("sql.sql", "Scriptname: `{}` spell (spell_id:{}) is not first rank of spell.", scriptName, fields[0].Get<int32>());
6197 continue;
6198 }
6199 while (spellInfo)
6200 {
6201 _spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, GetScriptId(scriptName)));
6202 spellInfo = spellInfo->GetNextRankSpell();
6203 }
6204 }
6205 else
6206 _spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, GetScriptId(scriptName)));
6207 ++count;
6208 } while (result->NextRow());
6209
6210 LOG_INFO("server.loading", ">> Loaded {} spell script names in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6211 LOG_INFO("server.loading", " ");
6212}
SpellInfo const * GetNextRankSpell() const
Definition SpellInfo.cpp:2409

References _spellScriptsStore, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), SpellInfo::GetNextRankSpell(), GetScriptId(), SpellInfo::Id, LOG_ERROR, LOG_INFO, LOG_WARN, sSpellMgr, and WorldDatabase.

◆ LoadSpellScripts()

void ObjectMgr::LoadSpellScripts ( )
6056{
6058
6059 // check ids
6060 for (ScriptMapMap::const_iterator itr = sSpellScripts.begin(); itr != sSpellScripts.end(); ++itr)
6061 {
6062 uint32 spellId = uint32(itr->first) & 0x00FFFFFF;
6063 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
6064
6065 if (!spellInfo)
6066 {
6067 LOG_ERROR("sql.sql", "Table `spell_scripts` has not existing spell (Id: {}) as script id", spellId);
6068 continue;
6069 }
6070
6071 SpellEffIndex i = SpellEffIndex((uint32(itr->first) >> 24) & 0x000000FF);
6072 if (uint32(i) >= MAX_SPELL_EFFECTS)
6073 {
6074 LOG_ERROR("sql.sql", "Table `spell_scripts` has too high effect index {} for spell (Id: {}) as script id", uint32(i), spellId);
6075 }
6076
6077 //check for correct spellEffect
6078 if (!spellInfo->Effects[i].Effect || (spellInfo->Effects[i].Effect != SPELL_EFFECT_SCRIPT_EFFECT && spellInfo->Effects[i].Effect != SPELL_EFFECT_DUMMY))
6079 LOG_ERROR("sql.sql", "Table `spell_scripts` - spell {} effect {} is not SPELL_EFFECT_SCRIPT_EFFECT or SPELL_EFFECT_DUMMY", spellId, uint32(i));
6080 }
6081}
ScriptMapMap sSpellScripts
Definition ObjectMgr.cpp:59
SpellEffIndex
Definition SharedDefines.h:30
@ SPELL_EFFECT_DUMMY
Definition SharedDefines.h:792
@ SPELL_EFFECT_SCRIPT_EFFECT
Definition SharedDefines.h:866

References SpellInfo::Effects, LoadScripts(), LOG_ERROR, MAX_SPELL_EFFECTS, SCRIPTS_SPELL, SPELL_EFFECT_DUMMY, SPELL_EFFECT_SCRIPT_EFFECT, sSpellMgr, and sSpellScripts.

◆ LoadTavernAreaTriggers()

void ObjectMgr::LoadTavernAreaTriggers ( )
6995{
6996 uint32 oldMSTime = getMSTime();
6997
6998 _tavernAreaTriggerStore.clear(); // need for reload case
6999
7000 QueryResult result = WorldDatabase.Query("SELECT id, faction FROM areatrigger_tavern");
7001
7002 if (!result)
7003 {
7004 LOG_WARN("server.loading", ">> Loaded 0 tavern triggers. DB table `areatrigger_tavern` is empty.");
7005 LOG_INFO("server.loading", " ");
7006 return;
7007 }
7008
7009 uint32 count = 0;
7010
7011 do
7012 {
7013 ++count;
7014
7015 Field* fields = result->Fetch();
7016
7017 uint32 Trigger_ID = fields[0].Get<uint32>();
7018
7019 AreaTrigger const* atEntry = GetAreaTrigger(Trigger_ID);
7020 if (!atEntry)
7021 {
7022 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
7023 continue;
7024 }
7025
7026 uint32 faction = fields[1].Get<uint32>();
7027
7028 _tavernAreaTriggerStore.emplace(Trigger_ID, faction);
7029 } while (result->NextRow());
7030
7031 LOG_INFO("server.loading", ">> Loaded {} Tavern Triggers in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7032 LOG_INFO("server.loading", " ");
7033}

References _tavernAreaTriggerStore, Field::Get(), GetAreaTrigger(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadTempSummons()

void ObjectMgr::LoadTempSummons ( )
2142{
2143 uint32 oldMSTime = getMSTime();
2144
2145 // 0 1 2 3 4 5 6 7 8 9
2146 QueryResult result = WorldDatabase.Query("SELECT summonerId, summonerType, groupId, entry, position_x, position_y, position_z, orientation, summonType, summonTime FROM creature_summon_groups");
2147
2148 if (!result)
2149 {
2150 LOG_WARN("server.loading", ">> Loaded 0 temp summons. DB table `creature_summon_groups` is empty.");
2151 return;
2152 }
2153
2154 uint32 count = 0;
2155 do
2156 {
2157 Field* fields = result->Fetch();
2158
2159 uint32 summonerId = fields[0].Get<uint32>();
2160 SummonerType summonerType = SummonerType(fields[1].Get<uint8>());
2161 uint8 group = fields[2].Get<uint8>();
2162
2163 switch (summonerType)
2164 {
2166 if (!GetCreatureTemplate(summonerId))
2167 {
2168 LOG_ERROR("sql.sql", "Table `creature_summon_groups` has summoner with non existing entry {} for creature summoner type, skipped.", summonerId);
2169 continue;
2170 }
2171 break;
2173 if (!GetGameObjectTemplate(summonerId))
2174 {
2175 LOG_ERROR("sql.sql", "Table `creature_summon_groups` has summoner with non existing entry {} for gameobject summoner type, skipped.", summonerId);
2176 continue;
2177 }
2178 break;
2179 case SUMMONER_TYPE_MAP:
2180 if (!sMapStore.LookupEntry(summonerId))
2181 {
2182 LOG_ERROR("sql.sql", "Table `creature_summon_groups` has summoner with non existing entry {} for map summoner type, skipped.", summonerId);
2183 continue;
2184 }
2185 break;
2186 default:
2187 LOG_ERROR("sql.sql", "Table `creature_summon_groups` has unhandled summoner type {} for summoner {}, skipped.", summonerType, summonerId);
2188 continue;
2189 }
2190
2191 TempSummonData data;
2192 data.entry = fields[3].Get<uint32>();
2193
2194 if (!GetCreatureTemplate(data.entry))
2195 {
2196 LOG_ERROR("sql.sql", "Table `creature_summon_groups` has creature in group [Summoner ID: {}, Summoner Type: {}, Group ID: {}] with non existing creature entry {}, skipped.", summonerId, summonerType, group, data.entry);
2197 continue;
2198 }
2199
2200 float posX = fields[4].Get<float>();
2201 float posY = fields[5].Get<float>();
2202 float posZ = fields[6].Get<float>();
2203 float orientation = fields[7].Get<float>();
2204
2205 data.pos.Relocate(posX, posY, posZ, orientation);
2206
2207 data.type = TempSummonType(fields[8].Get<uint8>());
2208
2210 {
2211 LOG_ERROR("sql.sql", "Table `creature_summon_groups` has unhandled temp summon type {} in group [Summoner ID: {}, Summoner Type: {}, Group ID: {}] for creature entry {}, skipped.", data.type, summonerId, summonerType, group, data.entry);
2212 continue;
2213 }
2214
2215 data.time = fields[9].Get<uint32>();
2216
2217 TempSummonGroupKey key(summonerId, summonerType, group);
2218 _tempSummonDataStore[key].push_back(data);
2219
2220 ++count;
2221 } while (result->NextRow());
2222
2223 LOG_INFO("server.loading", ">> Loaded {} Temporary Summons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2224 LOG_INFO("server.loading", " ");
2225}
TempSummonType
Definition Object.h:47
@ TEMPSUMMON_MANUAL_DESPAWN
Definition Object.h:55
SummonerType
Definition TemporarySummon.h:24
@ SUMMONER_TYPE_MAP
Definition TemporarySummon.h:27
@ SUMMONER_TYPE_CREATURE
Definition TemporarySummon.h:25
@ SUMMONER_TYPE_GAMEOBJECT
Definition TemporarySummon.h:26
void Relocate(float x, float y)
Definition Position.h:77
Stores data for temp summons.
Definition TemporarySummon.h:32
TempSummonType type
Summon type, see TempSummonType for available types.
Definition TemporarySummon.h:35
uint32 time
Despawn time, usable only with certain temp summon types.
Definition TemporarySummon.h:36
uint32 entry
Entry of summoned creature.
Definition TemporarySummon.h:33
Position pos
Position, where should be creature spawned.
Definition TemporarySummon.h:34

References _tempSummonDataStore, TempSummonData::entry, Field::Get(), GetCreatureTemplate(), GetGameObjectTemplate(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, TempSummonData::pos, Position::Relocate(), sMapStore, SUMMONER_TYPE_CREATURE, SUMMONER_TYPE_GAMEOBJECT, SUMMONER_TYPE_MAP, TEMPSUMMON_MANUAL_DESPAWN, TempSummonData::time, TempSummonData::type, and WorldDatabase.

◆ LoadTrainers()

void ObjectMgr::LoadTrainers ( )
9627{
9628 uint32 oldMSTime = getMSTime();
9629
9630 // For reload case
9631 _trainers.clear();
9632
9633 std::unordered_map<int32, std::vector<Trainer::Spell>> spellsByTrainer;
9634 if (QueryResult trainerSpellsResult = WorldDatabase.Query("SELECT TrainerId, SpellId, MoneyCost, ReqSkillLine, ReqSkillRank, ReqAbility1, ReqAbility2, ReqAbility3, ReqLevel FROM trainer_spell"))
9635 {
9636 do
9637 {
9638 Field* fields = trainerSpellsResult->Fetch();
9639
9640 Trainer::Spell spell;
9641 uint32 trainerId = fields[0].Get<uint32>();
9642 spell.SpellId = fields[1].Get<uint32>();
9643 spell.MoneyCost = fields[2].Get<uint32>();
9644 spell.ReqSkillLine = fields[3].Get<uint32>();
9645 spell.ReqSkillRank = fields[4].Get<uint32>();
9646 spell.ReqAbility[0] = fields[5].Get<uint32>();
9647 spell.ReqAbility[1] = fields[6].Get<uint32>();
9648 spell.ReqAbility[2] = fields[7].Get<uint32>();
9649 spell.ReqLevel = fields[8].Get<uint8>();
9650
9651 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell.SpellId);
9652 if (!spellInfo)
9653 {
9654 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing spell (SpellId: {}) for TrainerId {}, ignoring", spell.SpellId, trainerId);
9655 continue;
9656 }
9657
9658 if (GetTalentSpellCost(spell.SpellId))
9659 {
9660 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing spell (SpellId: {}) which is a talent, for TrainerId {}, ignoring", spell.SpellId, trainerId);
9661 continue;
9662 }
9663
9664 if (spell.ReqSkillLine && !sSkillLineStore.LookupEntry(spell.ReqSkillLine))
9665 {
9666 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing skill (ReqSkillLine: {}) for TrainerId {} and SpellId {}, ignoring",
9667 spell.ReqSkillLine, spell.SpellId, trainerId);
9668 continue;
9669 }
9670
9671 bool allReqValid = true;
9672 for (std::size_t i = 0; i < spell.ReqAbility.size(); ++i)
9673 {
9674 uint32 requiredSpell = spell.ReqAbility[i];
9675 if (requiredSpell && !sSpellMgr->GetSpellInfo(requiredSpell))
9676 {
9677 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing spell (ReqAbility {} : {}) for TrainerId {} and SpellId {}, ignoring",
9678 i + 1, requiredSpell, trainerId, spell.SpellId);
9679 allReqValid = false;
9680 }
9681 }
9682
9683 if (!allReqValid)
9684 continue;
9685
9686 spellsByTrainer[trainerId].push_back(spell);
9687 } while (trainerSpellsResult->NextRow());
9688 }
9689
9690 if (QueryResult trainersResult = WorldDatabase.Query("SELECT Id, Type, Requirement, Greeting FROM trainer"))
9691 {
9692 do
9693 {
9694 Field* fields = trainersResult->Fetch();
9695
9696 uint32 trainerId = fields[0].Get<uint32>();
9697 Trainer::Type trainerType = Trainer::Type(fields[1].Get<uint8>());
9698 uint32 requirement = fields[2].Get<uint32>();
9699 std::string greeting = fields[3].Get<std::string>();
9700 std::vector<Trainer::Spell> spells;
9701 auto spellsItr = spellsByTrainer.find(trainerId);
9702 if (spellsItr != spellsByTrainer.end())
9703 {
9704 spells = std::move(spellsItr->second);
9705 spellsByTrainer.erase(spellsItr);
9706 }
9707
9708 _trainers.emplace(std::piecewise_construct, std::forward_as_tuple(trainerId), std::forward_as_tuple(trainerId, trainerType, requirement, std::move(greeting), std::move(spells)));
9709 } while (trainersResult->NextRow());
9710 }
9711
9712 for (auto const& unusedSpells : spellsByTrainer)
9713 {
9714 for (Trainer::Spell const& unusedSpell : unusedSpells.second)
9715 {
9716 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing trainer (TrainerId: {}) for SpellId {}, ignoring", unusedSpells.first, unusedSpell.SpellId);
9717 }
9718 }
9719
9720 if (QueryResult trainerLocalesResult = WorldDatabase.Query("SELECT Id, locale, Greeting_lang FROM trainer_locale"))
9721 {
9722 do
9723 {
9724 Field* fields = trainerLocalesResult->Fetch();
9725 uint32 trainerId = fields[0].Get<uint32>();
9726 std::string localeName = fields[1].Get<std::string>();
9727
9728 LocaleConstant locale = GetLocaleByName(localeName);
9729 if (locale == LOCALE_enUS)
9730 continue;
9731
9733 trainer->AddGreetingLocale(locale, fields[2].Get<std::string>());
9734 else
9735 LOG_ERROR("sql.sql", "Table `trainer_locale` references non-existing trainer (TrainerId: {}) for locale %s, ignoring",
9736 trainerId, localeName.c_str());
9737 } while (trainerLocalesResult->NextRow());
9738 }
9739
9740 LOG_INFO("server.loading", ">> Loaded {} Trainers in {} ms", _trainers.size(), GetMSTimeDiffToNow(oldMSTime));
9741}
Definition Trainer.h:66
Type
Definition Trainer.h:32
Definition Trainer.h:54
uint32 ReqSkillLine
Definition Trainer.h:57
std::array< uint32, 3 > ReqAbility
Definition Trainer.h:59
uint8 ReqLevel
Definition Trainer.h:60
uint32 ReqSkillRank
Definition Trainer.h:58
uint32 SpellId
Definition Trainer.h:55
uint32 MoneyCost
Definition Trainer.h:56

References _trainers, Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), GetTalentSpellCost(), LOCALE_enUS, LOG_ERROR, LOG_INFO, Acore::Containers::MapGetValuePtr(), Trainer::Spell::MoneyCost, Trainer::Spell::ReqAbility, Trainer::Spell::ReqLevel, Trainer::Spell::ReqSkillLine, Trainer::Spell::ReqSkillRank, Trainer::Spell::SpellId, sSkillLineStore, sSpellMgr, and WorldDatabase.

◆ LoadVehicleAccessories()

void ObjectMgr::LoadVehicleAccessories ( )
3932{
3933 uint32 oldMSTime = getMSTime();
3934
3935 _vehicleAccessoryStore.clear(); // needed for reload case
3936
3937 uint32 count = 0;
3938
3939 // 0 1 2 3 4 5
3940 QueryResult result = WorldDatabase.Query("SELECT `guid`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer` FROM `vehicle_accessory`");
3941
3942 if (!result)
3943 {
3944 LOG_WARN("server.loading", ">> Loaded 0 Vehicle Accessories in {} ms", GetMSTimeDiffToNow(oldMSTime));
3945 LOG_INFO("server.loading", " ");
3946 return;
3947 }
3948
3949 do
3950 {
3951 Field* fields = result->Fetch();
3952
3953 uint32 uiGUID = fields[0].Get<uint32>();
3954 uint32 uiAccessory = fields[1].Get<uint32>();
3955 int8 uiSeat = int8(fields[2].Get<int16>());
3956 bool bMinion = fields[3].Get<bool>();
3957 uint8 uiSummonType = fields[4].Get<uint8>();
3958 uint32 uiSummonTimer = fields[5].Get<uint32>();
3959
3960 if (!GetCreatureTemplate(uiAccessory))
3961 {
3962 LOG_ERROR("sql.sql", "Table `vehicle_accessory`: Accessory {} does not exist.", uiAccessory);
3963 continue;
3964 }
3965
3966 _vehicleAccessoryStore[uiGUID].push_back(VehicleAccessory(uiAccessory, uiSeat, bMinion, uiSummonType, uiSummonTimer));
3967
3968 ++count;
3969 } while (result->NextRow());
3970
3971 LOG_INFO("server.loading", ">> Loaded {} Vehicle Accessories in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3972 LOG_INFO("server.loading", " ");
3973}
Definition VehicleDefines.h:115

References _vehicleAccessoryStore, Field::Get(), GetCreatureTemplate(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadVehicleSeatAddon()

void ObjectMgr::LoadVehicleSeatAddon ( )
3976{
3977 uint32 oldMSTime = getMSTime();
3978
3979 _vehicleSeatAddonStore.clear(); // needed for reload case
3980
3981 uint32 count = 0;
3982
3983 // 0 1 2 3 4 5 6
3984 QueryResult result = WorldDatabase.Query("SELECT `SeatEntry`, `SeatOrientation`, `ExitParamX`, `ExitParamY`, `ExitParamZ`, `ExitParamO`, `ExitParamValue` FROM `vehicle_seat_addon`");
3985
3986 if (!result)
3987 {
3988 LOG_ERROR("server.loading", ">> Loaded 0 vehicle seat addons. DB table `vehicle_seat_addon` is empty.");
3989 return;
3990 }
3991
3992 do
3993 {
3994 Field* fields = result->Fetch();
3995
3996 uint32 seatID = fields[0].Get<uint32>();
3997 float orientation = fields[1].Get<float>();
3998 float exitX = fields[2].Get<float>();
3999 float exitY = fields[3].Get<float>();
4000 float exitZ = fields[4].Get<float>();
4001 float exitO = fields[5].Get<float>();
4002 uint8 exitParam = fields[6].Get<uint8>();
4003
4004 if (!sVehicleSeatStore.LookupEntry(seatID))
4005 {
4006 LOG_ERROR("sql.sql", "Table `vehicle_seat_addon`: SeatID: {} does not exist in VehicleSeat.dbc. Skipping entry.", seatID);
4007 continue;
4008 }
4009
4010 // Sanitizing values
4011 if (orientation > float(M_PI * 2))
4012 {
4013 LOG_ERROR("sql.sql", "Table `vehicle_seat_addon`: SeatID: {} is using invalid angle offset value ({}). Set Value to 0.", seatID, orientation);
4014 orientation = 0.0f;
4015 }
4016
4018 {
4019 LOG_ERROR("sql.sql", "Table `vehicle_seat_addon`: SeatID: {} is using invalid exit parameter value ({}). Setting to 0 (none).", seatID, exitParam);
4020 continue;
4021 }
4022
4023 _vehicleSeatAddonStore[seatID] = VehicleSeatAddon(orientation, exitX, exitY, exitZ, exitO, exitParam);
4024
4025 ++count;
4026 } while (result->NextRow());
4027
4028 LOG_INFO("server.loading", ">> Loaded {} Vehicle Seat Addon entries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4029}
DBCStorage< VehicleSeatEntry > sVehicleSeatStore(VehicleSeatEntryfmt)
Definition VehicleDefines.h:86

References _vehicleSeatAddonStore, AsUnderlyingType(), Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, sVehicleSeatStore, VehicleExitParamMax, and WorldDatabase.

◆ LoadVehicleTemplateAccessories()

void ObjectMgr::LoadVehicleTemplateAccessories ( )
3876{
3877 uint32 oldMSTime = getMSTime();
3878
3879 _vehicleTemplateAccessoryStore.clear(); // needed for reload case
3880
3881 uint32 count = 0;
3882
3883 // 0 1 2 3 4 5
3884 QueryResult result = WorldDatabase.Query("SELECT `entry`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer` FROM `vehicle_template_accessory`");
3885
3886 if (!result)
3887 {
3888 LOG_WARN("server.loading", ">> Loaded 0 vehicle template accessories. DB table `vehicle_template_accessory` is empty.");
3889 LOG_INFO("server.loading", " ");
3890 return;
3891 }
3892
3893 do
3894 {
3895 Field* fields = result->Fetch();
3896
3897 uint32 uiEntry = fields[0].Get<uint32>();
3898 uint32 uiAccessory = fields[1].Get<uint32>();
3899 int8 uiSeat = int8(fields[2].Get<int8>());
3900 bool bMinion = fields[3].Get<bool>();
3901 uint8 uiSummonType = fields[4].Get<uint8>();
3902 uint32 uiSummonTimer = fields[5].Get<uint32>();
3903
3904 if (!GetCreatureTemplate(uiEntry))
3905 {
3906 LOG_ERROR("sql.sql", "Table `vehicle_template_accessory`: creature template entry {} does not exist.", uiEntry);
3907 continue;
3908 }
3909
3910 if (!GetCreatureTemplate(uiAccessory))
3911 {
3912 LOG_ERROR("sql.sql", "Table `vehicle_template_accessory`: Accessory {} does not exist.", uiAccessory);
3913 continue;
3914 }
3915
3916 if (_spellClickInfoStore.find(uiEntry) == _spellClickInfoStore.end())
3917 {
3918 LOG_ERROR("sql.sql", "Table `vehicle_template_accessory`: creature template entry {} has no data in npc_spellclick_spells", uiEntry);
3919 continue;
3920 }
3921
3922 _vehicleTemplateAccessoryStore[uiEntry].push_back(VehicleAccessory(uiAccessory, uiSeat, bMinion, uiSummonType, uiSummonTimer));
3923
3924 ++count;
3925 } while (result->NextRow());
3926
3927 LOG_INFO("server.loading", ">> Loaded {} Vehicle Template Accessories in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3928 LOG_INFO("server.loading", " ");
3929}

References _spellClickInfoStore, _vehicleTemplateAccessoryStore, Field::Get(), GetCreatureTemplate(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadVendors()

void ObjectMgr::LoadVendors ( )
9820{
9821 uint32 oldMSTime = getMSTime();
9822
9823 // For reload case
9824 for (CacheVendorItemContainer::iterator itr = _cacheVendorItemStore.begin(); itr != _cacheVendorItemStore.end(); ++itr)
9825 itr->second.Clear();
9826 _cacheVendorItemStore.clear();
9827
9828 std::set<uint32> skip_vendors;
9829
9830 QueryResult result = WorldDatabase.Query("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor ORDER BY entry, slot ASC, item, ExtendedCost");
9831 if (!result)
9832 {
9833 LOG_INFO("server.loading", " ");
9834 LOG_WARN("server.loading", ">> Loaded 0 Vendors. DB table `npc_vendor` is empty!");
9835 return;
9836 }
9837
9838 uint32 count = 0;
9839
9840 do
9841 {
9842 Field* fields = result->Fetch();
9843
9844 uint32 entry = fields[0].Get<uint32>();
9845 int32 item_id = fields[1].Get<int32>();
9846
9847 // if item is a negative, its a reference
9848 if (item_id < 0)
9849 count += LoadReferenceVendor(entry, -item_id, &skip_vendors);
9850 else
9851 {
9852 uint32 maxcount = fields[2].Get<uint8>();
9853 uint32 incrtime = fields[3].Get<uint32>();
9854 uint32 ExtendedCost = fields[4].Get<uint32>();
9855
9856 if (!IsVendorItemValid(entry, item_id, maxcount, incrtime, ExtendedCost, nullptr, &skip_vendors))
9857 continue;
9858
9859 VendorItemData& vList = _cacheVendorItemStore[entry];
9860
9861 vList.AddItem(item_id, maxcount, incrtime, ExtendedCost);
9862 ++count;
9863 }
9864 } while (result->NextRow());
9865
9866 LOG_INFO("server.loading", ">> Loaded {} Vendors in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9867 LOG_INFO("server.loading", " ");
9868}

References _cacheVendorItemStore, VendorItemData::AddItem(), Field::Get(), getMSTime(), GetMSTimeDiffToNow(), IsVendorItemValid(), LoadReferenceVendor(), LOG_INFO, LOG_WARN, and WorldDatabase.

◆ LoadWaypointScripts()

void ObjectMgr::LoadWaypointScripts ( )
6128{
6130
6131 std::set<uint32> actionSet;
6132
6133 for (ScriptMapMap::const_iterator itr = sWaypointScripts.begin(); itr != sWaypointScripts.end(); ++itr)
6134 actionSet.insert(itr->first);
6135
6137 PreparedQueryResult result = WorldDatabase.Query(stmt);
6138
6139 if (result)
6140 {
6141 do
6142 {
6143 Field* fields = result->Fetch();
6144 uint32 action = fields[0].Get<uint32>();
6145
6146 actionSet.erase(action);
6147 } while (result->NextRow());
6148 }
6149
6150 for (std::set<uint32>::iterator itr = actionSet.begin(); itr != actionSet.end(); ++itr)
6151 LOG_ERROR("sql.sql", "There is no waypoint which links to the waypoint script {}", *itr);
6152}
ScriptMapMap sWaypointScripts
Definition ObjectMgr.cpp:61
@ SCRIPTS_WAYPOINT
Definition ObjectMgr.h:151
@ WORLD_SEL_WAYPOINT_DATA_ACTION
Definition WorldDatabase.h:69

References Field::Get(), LoadScripts(), LOG_ERROR, SCRIPTS_WAYPOINT, sWaypointScripts, WORLD_SEL_WAYPOINT_DATA_ACTION, and WorldDatabase.

◆ NewGOData()

GameObjectData & ObjectMgr::NewGOData ( ObjectGuid::LowType  guid)
inline
1328{ return _gameObjectDataStore[guid]; }

References _gameObjectDataStore.

Referenced by AddGOData().

◆ NewOrExistCreatureData()

CreatureData & ObjectMgr::NewOrExistCreatureData ( ObjectGuid::LowType  spawnId)
inline
1228{ return _creatureDataStore[spawnId]; }

References _creatureDataStore.

Referenced by AddCreData().

◆ PlayerCreateInfoAddItemHelper()

void ObjectMgr::PlayerCreateInfoAddItemHelper ( uint32  race_,
uint32  class_,
uint32  itemId,
int32  count 
)
private
4137{
4138 if (!_playerInfo[race_][class_])
4139 return;
4140
4141 if (count > 0)
4142 _playerInfo[race_][class_]->item.push_back(PlayerCreateInfoItem(itemId, count));
4143 else
4144 {
4145 if (count < -1)
4146 LOG_ERROR("sql.sql", "Invalid count {} specified on item {} be removed from original player create info (use -1)!", count, itemId);
4147
4148 for (uint32 gender = 0; gender < GENDER_NONE; ++gender)
4149 {
4150 if (CharStartOutfitEntry const* entry = GetCharStartOutfitEntry(race_, class_, gender))
4151 {
4152 bool found = false;
4153 for (uint8 x = 0; x < MAX_OUTFIT_ITEMS; ++x)
4154 {
4155 if (entry->ItemId[x] > 0 && uint32(entry->ItemId[x]) == itemId)
4156 {
4157 found = true;
4158 const_cast<CharStartOutfitEntry*>(entry)->ItemId[x] = 0;
4159 break;
4160 }
4161 }
4162
4163 if (!found)
4164 LOG_ERROR("sql.sql", "Item {} specified to be removed from original create info not found in dbc!", itemId);
4165 }
4166 }
4167 }
4168}
CharStartOutfitEntry const * GetCharStartOutfitEntry(uint8 race, uint8 class_, uint8 gender)
Definition DBCStores.cpp:842
Definition Player.h:267
PlayerCreateInfoItems item
Definition Player.h:335

References _playerInfo, GENDER_NONE, GetCharStartOutfitEntry(), PlayerInfo::item, LOG_ERROR, and MAX_OUTFIT_ITEMS.

Referenced by LoadPlayerInfo().

◆ RemoveCreatureFromGrid()

void ObjectMgr::RemoveCreatureFromGrid ( ObjectGuid::LowType  guid,
CreatureData const *  data 
)
2634{
2635 uint8 mask = data->spawnMask;
2636 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
2637 {
2638 if (mask & 1)
2639 {
2640 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
2641 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
2642 cell_guids.creatures.erase(guid);
2643 }
2644 }
2645}

References _mapObjectGuidsStore, Acore::ComputeGridCoord(), CellObjectGuids::creatures, CoordPair< LIMIT >::GetId(), MAKE_PAIR32(), CreatureData::mapid, CreatureData::posX, CreatureData::posY, and CreatureData::spawnMask.

Referenced by DeleteCreatureData().

◆ RemoveGameobjectFromGrid()

void ObjectMgr::RemoveGameobjectFromGrid ( ObjectGuid::LowType  guid,
GameObjectData const *  data 
)
3076{
3077 uint8 mask = data->spawnMask;
3078 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
3079 {
3080 if (mask & 1)
3081 {
3082 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
3083 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
3084 cell_guids.gameobjects.erase(guid);
3085 }
3086 }
3087}

References _mapObjectGuidsStore, Acore::ComputeGridCoord(), CellObjectGuids::gameobjects, CoordPair< LIMIT >::GetId(), MAKE_PAIR32(), GameObjectData::mapid, GameObjectData::posX, GameObjectData::posY, and GameObjectData::spawnMask.

Referenced by DeleteGOData().

◆ RemoveVendorItem()

bool ObjectMgr::RemoveVendorItem ( uint32  entry,
uint32  item,
bool  persist = true 
)
10021{
10022 CacheVendorItemContainer::iterator iter = _cacheVendorItemStore.find(entry);
10023 if (iter == _cacheVendorItemStore.end())
10024 return false;
10025
10026 if (!iter->second.RemoveItem(item))
10027 return false;
10028
10029 if (persist)
10030 {
10032
10033 stmt->SetData(0, entry);
10034 stmt->SetData(1, item);
10035
10036 WorldDatabase.Execute(stmt);
10037 }
10038
10039 return true;
10040}
@ WORLD_DEL_NPC_VENDOR
Definition WorldDatabase.h:44

References _cacheVendorItemStore, PreparedStatementBase::SetData(), WORLD_DEL_NPC_VENDOR, and WorldDatabase.

◆ ReturnOrDeleteOldMails()

void ObjectMgr::ReturnOrDeleteOldMails ( bool  serverUp)
6623{
6624 uint32 oldMSTime = getMSTime();
6625
6626 time_t curTime = GameTime::GetGameTime().count();
6627
6629 stmt->SetData(0, uint32(curTime));
6630 PreparedQueryResult result = CharacterDatabase.Query(stmt);
6631 if (!result)
6632 return;
6633
6634 std::map<uint32 /*messageId*/, MailItemInfoVec> itemsCache;
6635 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_EXPIRED_MAIL_ITEMS);
6636 stmt->SetData(0, uint32(curTime));
6637 if (PreparedQueryResult items = CharacterDatabase.Query(stmt))
6638 {
6639 MailItemInfo item;
6640 do
6641 {
6642 Field* fields = items->Fetch();
6643 item.item_guid = fields[0].Get<uint32>();
6644 item.item_template = fields[1].Get<uint32>();
6645 uint32 mailId = fields[2].Get<uint32>();
6646 itemsCache[mailId].push_back(item);
6647 } while (items->NextRow());
6648 }
6649
6650 uint32 deletedCount = 0;
6651 uint32 returnedCount = 0;
6652 do
6653 {
6654 Field* fields = result->Fetch();
6655 Mail* m = new Mail;
6656 m->messageID = fields[0].Get<uint32>();
6657 m->messageType = fields[1].Get<uint8>();
6658 m->sender = fields[2].Get<uint32>();
6659 m->receiver = fields[3].Get<uint32>();
6660 bool has_items = fields[4].Get<bool>();
6661 m->expire_time = time_t(fields[5].Get<uint32>());
6662 m->deliver_time = time_t(0);
6663 m->stationery = fields[6].Get<uint8>();
6664 m->checked = fields[7].Get<uint8>();
6665 m->mailTemplateId = fields[8].Get<int16>();
6666
6667 Player* player = nullptr;
6668 if (serverUp)
6670
6671 if (player) // don't modify mails of a logged in player
6672 {
6673 delete m;
6674 continue;
6675 }
6676
6677 // Delete or return mail
6678 if (has_items)
6679 {
6680 // read items from cache
6681 m->items.swap(itemsCache[m->messageID]);
6682
6683 // If it is mail from non-player, or if it's already return mail, it shouldn't be returned, but deleted
6684 if (!m->IsSentByPlayer() || m->IsSentByGM() || (m->IsCODPayment() || m->IsReturnedMail()))
6685 {
6686 for (auto const& mailedItem : m->items)
6687 {
6688 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE);
6689 stmt->SetData(0, mailedItem.item_guid);
6690 CharacterDatabase.Execute(stmt);
6691 }
6692
6693 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID);
6694 stmt->SetData(0, m->messageID);
6695 CharacterDatabase.Execute(stmt);
6696 }
6697 else
6698 {
6699 // Mail will be returned
6700 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_MAIL_RETURNED);
6701 stmt->SetData(0, m->receiver);
6702 stmt->SetData(1, m->sender);
6703 stmt->SetData(2, uint32(curTime + 30 * DAY));
6704 stmt->SetData(3, uint32(curTime));
6706 stmt->SetData(5, m->messageID);
6707 CharacterDatabase.Execute(stmt);
6708 for (auto const& mailedItem : m->items)
6709 {
6710 // Update receiver in mail items for its proper delivery, and in instance_item for avoid lost item at sender delete
6711 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_MAIL_ITEM_RECEIVER);
6712 stmt->SetData(0, m->sender);
6713 stmt->SetData(1, mailedItem.item_guid);
6714 CharacterDatabase.Execute(stmt);
6715
6716 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_OWNER);
6717 stmt->SetData(0, m->sender);
6718 stmt->SetData(1, mailedItem.item_guid);
6719 CharacterDatabase.Execute(stmt);
6720 }
6721
6722 // xinef: update global data
6723 sCharacterCache->IncreaseCharacterMailCount(ObjectGuid(HighGuid::Player, m->sender));
6724 sCharacterCache->DecreaseCharacterMailCount(ObjectGuid(HighGuid::Player, m->receiver));
6725
6726 delete m;
6727 ++returnedCount;
6728 continue;
6729 }
6730 }
6731
6732 sCharacterCache->DecreaseCharacterMailCount(ObjectGuid(HighGuid::Player, m->receiver));
6733
6734 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_BY_ID);
6735 stmt->SetData(0, m->messageID);
6736 CharacterDatabase.Execute(stmt);
6737 delete m;
6738 ++deletedCount;
6739 } while (result->NextRow());
6740
6741 LOG_INFO("server.loading", ">> Processed {} expired mails: {} deleted and {} returned in {} ms", deletedCount + returnedCount, deletedCount, returnedCount, GetMSTimeDiffToNow(oldMSTime));
6742 LOG_INFO("server.loading", " ");
6743}
#define sCharacterCache
Definition CharacterCache.h:83
@ CHAR_UPD_ITEM_OWNER
Definition CharacterDatabase.h:118
@ CHAR_DEL_ITEM_INSTANCE
Definition CharacterDatabase.h:127
@ CHAR_UPD_MAIL_RETURNED
Definition CharacterDatabase.h:116
@ CHAR_SEL_EXPIRED_MAIL
Definition CharacterDatabase.h:114
@ CHAR_SEL_EXPIRED_MAIL_ITEMS
Definition CharacterDatabase.h:115
@ CHAR_DEL_MAIL_BY_ID
Definition CharacterDatabase.h:110
@ CHAR_DEL_MAIL_ITEM_BY_ID
Definition CharacterDatabase.h:382
@ CHAR_UPD_MAIL_ITEM_RECEIVER
Definition CharacterDatabase.h:117
std::vector< MailItemInfo > MailItemInfoVec
Definition Mail.h:164
@ MAIL_CHECK_MASK_RETURNED
Definition Mail.h:48
Definition Player.h:1066
Seconds GetGameTime()
Definition GameTime.cpp:38
Player * FindPlayerByLowGUID(ObjectGuid::LowType lowguid)
Definition ObjectAccessor.cpp:251
Definition Mail.h:160
ObjectGuid::LowType item_guid
Definition Mail.h:161
uint32 item_template
Definition Mail.h:162
Definition Mail.h:167
bool IsSentByGM() const
Definition Mail.h:208
bool IsCODPayment() const
Definition Mail.h:209
ObjectGuid::LowType receiver
Definition Mail.h:173
uint8 messageType
Definition Mail.h:169
bool IsSentByPlayer() const
Definition Mail.h:207
uint32 messageID
Definition Mail.h:168
time_t expire_time
Definition Mail.h:178
uint32 sender
Definition Mail.h:172
uint8 stationery
Definition Mail.h:170
std::vector< MailItemInfo > items
Definition Mail.h:176
time_t deliver_time
Definition Mail.h:179
bool IsReturnedMail() const
Definition Mail.h:210
uint32 checked
Definition Mail.h:182
uint16 mailTemplateId
Definition Mail.h:171

References CHAR_DEL_ITEM_INSTANCE, CHAR_DEL_MAIL_BY_ID, CHAR_DEL_MAIL_ITEM_BY_ID, CHAR_SEL_EXPIRED_MAIL, CHAR_SEL_EXPIRED_MAIL_ITEMS, CHAR_UPD_ITEM_OWNER, CHAR_UPD_MAIL_ITEM_RECEIVER, CHAR_UPD_MAIL_RETURNED, CharacterDatabase, Mail::checked, DAY, Mail::deliver_time, Mail::expire_time, ObjectAccessor::FindPlayerByLowGUID(), Field::Get(), GameTime::GetGameTime(), getMSTime(), GetMSTimeDiffToNow(), Mail::IsCODPayment(), Mail::IsReturnedMail(), Mail::IsSentByGM(), Mail::IsSentByPlayer(), MailItemInfo::item_guid, MailItemInfo::item_template, Mail::items, LOG_INFO, MAIL_CHECK_MASK_RETURNED, Mail::mailTemplateId, Mail::messageID, Mail::messageType, Player, Mail::receiver, sCharacterCache, Mail::sender, PreparedStatementBase::SetData(), and Mail::stationery.

◆ SetCreatureLinkedRespawn()

bool ObjectMgr::SetCreatureLinkedRespawn ( ObjectGuid::LowType  guid,
ObjectGuid::LowType  linkedGuid 
)
2095{
2096 if (!guidLow)
2097 return false;
2098
2099 CreatureData const* master = GetCreatureData(guidLow);
2100 ObjectGuid guid = ObjectGuid::Create<HighGuid::Unit>(master->id1, guidLow);
2101
2102 if (!linkedGuidLow) // we're removing the linking
2103 {
2104 _linkedRespawnStore.erase(guid);
2106 stmt->SetData(0, guidLow);
2107 WorldDatabase.Execute(stmt);
2108 return true;
2109 }
2110
2111 CreatureData const* slave = GetCreatureData(linkedGuidLow);
2112 if (!slave)
2113 {
2114 LOG_ERROR("sql.sql", "Creature '{}' linking to non-existent creature '{}'.", guidLow, linkedGuidLow);
2115 return false;
2116 }
2117
2118 MapEntry const* map = sMapStore.LookupEntry(master->mapid);
2119 if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
2120 {
2121 LOG_ERROR("sql.sql", "Creature '{}' linking to '{}' on an unpermitted map.", guidLow, linkedGuidLow);
2122 return false;
2123 }
2124
2125 if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
2126 {
2127 LOG_ERROR("sql.sql", "LinkedRespawn: Creature '{}' linking to '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
2128 return false;
2129 }
2130
2131 ObjectGuid linkedGuid = ObjectGuid::Create<HighGuid::Unit>(slave->id1, linkedGuidLow);
2132
2133 _linkedRespawnStore[guid] = linkedGuid;
2135 stmt->SetData(0, guidLow);
2136 stmt->SetData(1, linkedGuidLow);
2137 WorldDatabase.Execute(stmt);
2138 return true;
2139}
@ WORLD_REP_CREATURE_LINKED_RESPAWN
Definition WorldDatabase.h:33
@ WORLD_DEL_CRELINKED_RESPAWN
Definition WorldDatabase.h:32

References _linkedRespawnStore, GetCreatureData(), CreatureData::id1, MapEntry::Instanceable(), LOG_ERROR, CreatureData::mapid, PreparedStatementBase::SetData(), sMapStore, CreatureData::spawnMask, WORLD_DEL_CRELINKED_RESPAWN, WORLD_REP_CREATURE_LINKED_RESPAWN, and WorldDatabase.

◆ SetDBCLocaleIndex()

void ObjectMgr::SetDBCLocaleIndex ( LocaleConstant  locale)
inline
1368{ DBCLocaleIndex = locale; }

References DBCLocaleIndex.

◆ SetHighestGuids()

void ObjectMgr::SetHighestGuids ( )
7505{
7506 QueryResult result = CharacterDatabase.Query("SELECT MAX(guid) FROM characters");
7507 if (result)
7508 GetGuidSequenceGenerator<HighGuid::Player>().Set((*result)[0].Get<uint32>() + 1);
7509
7510 result = CharacterDatabase.Query("SELECT MAX(guid) FROM item_instance");
7511 if (result)
7512 GetGuidSequenceGenerator<HighGuid::Item>().Set((*result)[0].Get<uint32>() + 1);
7513
7514 // Cleanup other tables from not existed guids ( >= _hiItemGuid)
7515 CharacterDatabase.Execute("DELETE FROM character_inventory WHERE item >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7516 CharacterDatabase.Execute("DELETE FROM mail_items WHERE item_guid >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7517 CharacterDatabase.Execute("DELETE FROM auctionhouse WHERE itemguid >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7518 CharacterDatabase.Execute("DELETE FROM guild_bank_item WHERE item_guid >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7519
7520 result = WorldDatabase.Query("SELECT MAX(guid) FROM transports");
7521 if (result)
7522 GetGuidSequenceGenerator<HighGuid::Mo_Transport>().Set((*result)[0].Get<uint32>() + 1);
7523
7524 result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse");
7525 if (result)
7526 _auctionId = (*result)[0].Get<uint32>() + 1;
7527
7528 result = CharacterDatabase.Query("SELECT MAX(id) FROM mail");
7529 if (result)
7530 _mailId = (*result)[0].Get<uint32>() + 1;
7531
7532 result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team");
7533 if (result)
7534 sArenaTeamMgr->SetNextArenaTeamId((*result)[0].Get<uint32>() + 1);
7535
7536 result = CharacterDatabase.Query("SELECT MAX(fight_id) FROM log_arena_fights");
7537 if (result)
7538 sArenaTeamMgr->SetLastArenaLogId((*result)[0].Get<uint32>());
7539
7540 result = CharacterDatabase.Query("SELECT MAX(setguid) FROM character_equipmentsets");
7541 if (result)
7542 _equipmentSetGuid = (*result)[0].Get<uint64>() + 1;
7543
7544 result = CharacterDatabase.Query("SELECT MAX(guildId) FROM guild");
7545 if (result)
7546 sGuildMgr->SetNextGuildId((*result)[0].Get<uint32>() + 1);
7547
7548 result = WorldDatabase.Query("SELECT MAX(guid) FROM creature");
7549 if (result)
7550 _creatureSpawnId = (*result)[0].Get<uint32>() + 1;
7551
7552 result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject");
7553 if (result)
7554 _gameObjectSpawnId = (*result)[0].Get<uint32>() + 1;
7555}
#define sArenaTeamMgr
Definition ArenaTeamMgr.h:69
#define sGuildMgr
Definition GuildMgr.h:51

References _auctionId, _creatureSpawnId, _equipmentSetGuid, _gameObjectSpawnId, _mailId, CharacterDatabase, sArenaTeamMgr, sGuildMgr, and WorldDatabase.

◆ ValidateSpellScripts()

void ObjectMgr::ValidateSpellScripts ( )
6215{
6216 uint32 oldMSTime = getMSTime();
6217
6218 if (_spellScriptsStore.empty())
6219 {
6220 LOG_INFO("server.loading", ">> Validated 0 scripts.");
6221 LOG_INFO("server.loading", " ");
6222 return;
6223 }
6224
6225 uint32 count = 0;
6226
6227 for (SpellScriptsContainer::iterator itr = _spellScriptsStore.begin(); itr != _spellScriptsStore.end();)
6228 {
6229 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
6230 std::vector<std::pair<SpellScriptLoader*, SpellScriptsContainer::iterator> > SpellScriptLoaders;
6231 sScriptMgr->CreateSpellScriptLoaders(itr->first, SpellScriptLoaders);
6232 itr = _spellScriptsStore.upper_bound(itr->first);
6233
6234 for (std::vector<std::pair<SpellScriptLoader*, SpellScriptsContainer::iterator> >::iterator sitr = SpellScriptLoaders.begin(); sitr != SpellScriptLoaders.end(); ++sitr)
6235 {
6236 SpellScript* spellScript = sitr->first->GetSpellScript();
6237 AuraScript* auraScript = sitr->first->GetAuraScript();
6238 bool valid = true;
6239 if (!spellScript && !auraScript)
6240 {
6241 LOG_ERROR("sql.sql", "Functions GetSpellScript() and GetAuraScript() of script `{}` do not return objects - script skipped", GetScriptName(sitr->second->second));
6242 valid = false;
6243 }
6244 if (spellScript)
6245 {
6246 spellScript->_Init(&sitr->first->GetName(), spellInfo->Id);
6247 spellScript->_Register();
6248 if (!spellScript->_Validate(spellInfo))
6249 valid = false;
6250 delete spellScript;
6251 }
6252 if (auraScript)
6253 {
6254 auraScript->_Init(&sitr->first->GetName(), spellInfo->Id);
6255 auraScript->_Register();
6256 if (!auraScript->_Validate(spellInfo))
6257 valid = false;
6258 delete auraScript;
6259 }
6260 if (!valid)
6261 {
6262 _spellScriptsStore.erase(sitr->second);
6263 }
6264 }
6265 ++count;
6266 }
6267
6268 LOG_INFO("server.loading", ">> Validated {} scripts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6269 LOG_INFO("server.loading", " ");
6270}
Definition SpellScript.h:517
bool _Validate(SpellInfo const *entry) override
Definition SpellScript.cpp:662
std::string const & GetScriptName(uint32 id) const
Definition ObjectMgr.cpp:10178
Definition SpellScript.h:182
bool _Validate(SpellInfo const *entry) override
Definition SpellScript.cpp:316
virtual void _Register()
Definition SpellScript.cpp:45
virtual void _Init(std::string const *scriptname, uint32 spellId)
Definition SpellScript.cpp:59

References _SpellScript::_Init(), _SpellScript::_Register(), _spellScriptsStore, SpellScript::_Validate(), AuraScript::_Validate(), getMSTime(), GetMSTimeDiffToNow(), GetScriptName(), SpellInfo::Id, LOG_ERROR, LOG_INFO, sScriptMgr, and sSpellMgr.

Friends And Related Symbol Documentation

◆ PlayerDumpReader

friend class PlayerDumpReader
friend

Member Data Documentation

◆ _accessRequirementStore

DungeonProgressionRequirementsContainer ObjectMgr::_accessRequirementStore
private

◆ _acoreStringStore

AcoreStringContainer ObjectMgr::_acoreStringStore
private

Referenced by GetAcoreString(), and LoadAcoreStrings().

◆ _areaTriggerScriptStore

AreaTriggerScriptContainer ObjectMgr::_areaTriggerScriptStore
private

◆ _areaTriggerStore

AreaTriggerContainer ObjectMgr::_areaTriggerStore
private

Referenced by GetAreaTrigger(), and LoadAreaTriggers().

◆ _areaTriggerTeleportStore

◆ _auctionId

uint32 ObjectMgr::_auctionId
private

◆ _baseXPTable

BaseXPContainer ObjectMgr::_baseXPTable
private

Referenced by GetBaseXP(), and LoadExplorationBaseXP().

◆ _breadcrumbsForQuest

BreadcrumbQuestMap ObjectMgr::_breadcrumbsForQuest

◆ _broadcastTextStore

BroadcastTextContainer ObjectMgr::_broadcastTextStore
private

◆ _cacheVendorItemStore

◆ _creatureAddonStore

CreatureAddonContainer ObjectMgr::_creatureAddonStore
private

◆ _creatureBaseStatsStore

CreatureBaseStatsContainer ObjectMgr::_creatureBaseStatsStore
private

◆ _creatureCustomIDsStore

CreatureCustomIDsContainer ObjectMgr::_creatureCustomIDsStore
private

◆ _creatureDataStore

◆ _creatureDefaultTrainers

std::unordered_map<uint32, uint32> ObjectMgr::_creatureDefaultTrainers
private

◆ _creatureLocaleStore

CreatureLocaleContainer ObjectMgr::_creatureLocaleStore
private

◆ _creatureModelStore

CreatureModelContainer ObjectMgr::_creatureModelStore
private

◆ _creatureMovementOverrides

std::unordered_map<ObjectGuid::LowType, CreatureMovementData> ObjectMgr::_creatureMovementOverrides
private

◆ _creatureQuestInvolvedRelations

◆ _creatureQuestItemStore

CreatureQuestItemMap ObjectMgr::_creatureQuestItemStore
private

◆ _creatureQuestRelations

QuestRelations ObjectMgr::_creatureQuestRelations
private

◆ _creatureSparringStore

CreatureSparringContainer ObjectMgr::_creatureSparringStore
private

◆ _creatureSpawnId

ObjectGuid::LowType ObjectMgr::_creatureSpawnId
private

◆ _creatureTemplateAddonStore

CreatureAddonContainer ObjectMgr::_creatureTemplateAddonStore
private

◆ _creatureTemplateStore

◆ _creatureTemplateStoreFast

std::vector<CreatureTemplate*> ObjectMgr::_creatureTemplateStoreFast
private

◆ _difficultyEntries

std::set<uint32> ObjectMgr::_difficultyEntries[MAX_DIFFICULTY - 1]
private

◆ _dungeonEncounterStore

DungeonEncounterContainer ObjectMgr::_dungeonEncounterStore
private

◆ _emptyCellObjectGuids

CellObjectGuids ObjectMgr::_emptyCellObjectGuids
private

Referenced by GetGridObjectGuids().

◆ _emptyCellObjectGuidsMap

CellObjectGuidsMap ObjectMgr::_emptyCellObjectGuidsMap
private

Referenced by GetMapObjectGuids().

◆ _equipmentInfoStore

EquipmentInfoContainer ObjectMgr::_equipmentInfoStore
private

◆ _equipmentSetGuid

uint64 ObjectMgr::_equipmentSetGuid
private

◆ _fishingBaseForAreaStore

◆ _gameObjectAddonStore

GameObjectAddonContainer ObjectMgr::_gameObjectAddonStore
private

◆ _gameObjectDataStore

◆ _gameObjectLocaleStore

GameObjectLocaleContainer ObjectMgr::_gameObjectLocaleStore
private

◆ _gameObjectQuestItemStore

GameObjectQuestItemMap ObjectMgr::_gameObjectQuestItemStore
private

◆ _gameObjectSpawnId

ObjectGuid::LowType ObjectMgr::_gameObjectSpawnId
private

◆ _gameObjectTemplateAddonStore

GameObjectTemplateAddonContainer ObjectMgr::_gameObjectTemplateAddonStore
private

◆ _gameObjectTemplateStore

GameObjectTemplateContainer ObjectMgr::_gameObjectTemplateStore
private

◆ _gameTeleStore

◆ _goQuestInvolvedRelations

QuestRelations ObjectMgr::_goQuestInvolvedRelations
private

◆ _goQuestRelations

QuestRelations ObjectMgr::_goQuestRelations
private

◆ _gossipMenuItemsLocaleStore

GossipMenuItemsLocaleContainer ObjectMgr::_gossipMenuItemsLocaleStore
private

◆ _gossipMenuItemsStore

◆ _gossipMenusStore

GossipMenusContainer ObjectMgr::_gossipMenusStore
private

◆ _gossipTextStore

GossipTextContainer ObjectMgr::_gossipTextStore
private

Referenced by GetGossipText(), and LoadGossipText().

◆ _guidGenerators

std::map<HighGuid, std::unique_ptr<ObjectGuidGeneratorBase> > ObjectMgr::_guidGenerators
private

◆ _hasDifficultyEntries

std::set<uint32> ObjectMgr::_hasDifficultyEntries[MAX_DIFFICULTY - 1]
private

Referenced by CheckCreatureTemplate().

◆ _hiPetNumber

uint32 ObjectMgr::_hiPetNumber
private

Referenced by GeneratePetNumber(), and LoadPetNumber().

◆ _hiPetNumberMutex

std::mutex ObjectMgr::_hiPetNumberMutex
private

Referenced by GeneratePetNumber().

◆ _instanceTemplateStore

InstanceTemplateContainer ObjectMgr::_instanceTemplateStore
private

◆ _itemLocaleStore

ItemLocaleContainer ObjectMgr::_itemLocaleStore
private

Referenced by GetItemLocale(), and LoadItemLocales().

◆ _itemSetNameLocaleStore

ItemSetNameLocaleContainer ObjectMgr::_itemSetNameLocaleStore
private

◆ _itemSetNameStore

ItemSetNameContainer ObjectMgr::_itemSetNameStore
private

◆ _itemTemplateStore

ItemTemplateContainer ObjectMgr::_itemTemplateStore
private

◆ _itemTemplateStoreFast

std::vector<ItemTemplate*> ObjectMgr::_itemTemplateStoreFast
private

◆ _linkedRespawnStore

LinkedRespawnContainer ObjectMgr::_linkedRespawnStore
private

◆ _mailId

uint32 ObjectMgr::_mailId
private

Referenced by GenerateMailID(), and SetHighestGuids().

◆ _mailIdMutex

std::mutex ObjectMgr::_mailIdMutex
private

Referenced by GenerateMailID().

◆ _mailLevelRewardStore

MailLevelRewardContainer ObjectMgr::_mailLevelRewardStore
private

◆ _mapObjectGuidsStore

◆ _moduleStringStore

ModuleStringContainer ObjectMgr::_moduleStringStore
private

◆ _npcTextLocaleStore

NpcTextLocaleContainer ObjectMgr::_npcTextLocaleStore
private

◆ _pageTextLocaleStore

PageTextLocaleContainer ObjectMgr::_pageTextLocaleStore
private

◆ _pageTextStore

PageTextContainer ObjectMgr::_pageTextStore
private

Referenced by GetPageText(), and LoadPageTexts().

◆ _petHalfLocaleName0

HalfNameContainerLocale ObjectMgr::_petHalfLocaleName0
private

◆ _petHalfLocaleName1

HalfNameContainerLocale ObjectMgr::_petHalfLocaleName1
private

◆ _petHalfName0

HalfNameContainer ObjectMgr::_petHalfName0
private

Referenced by GeneratePetName(), and LoadPetNames().

◆ _petHalfName1

HalfNameContainer ObjectMgr::_petHalfName1
private

Referenced by GeneratePetName(), and LoadPetNames().

◆ _petInfoStore

PetLevelInfoContainer ObjectMgr::_petInfoStore
private

◆ _playerClassInfo

◆ _playerInfo

◆ _playerShapeshiftModel

PlayerShapeshiftModelMap ObjectMgr::_playerShapeshiftModel
private

◆ _playerTotemModel

PlayerTotemModelMap ObjectMgr::_playerTotemModel
private

◆ _playerXPperLevel

PlayerXPperLevel ObjectMgr::_playerXPperLevel
private

Referenced by GetXPForLevel(), and LoadPlayerInfo().

◆ _pointOfInterestLocaleStore

PointOfInterestLocaleContainer ObjectMgr::_pointOfInterestLocaleStore
private

◆ _pointsOfInterestStore

PointOfInterestContainer ObjectMgr::_pointsOfInterestStore
private

◆ _profanityNamesStore

◆ _questAreaTriggerStore

QuestAreaTriggerContainer ObjectMgr::_questAreaTriggerStore
private

◆ _questGreetingStore

QuestGreetingContainer ObjectMgr::_questGreetingStore
private

◆ _questLocaleStore

QuestLocaleContainer ObjectMgr::_questLocaleStore
private

Referenced by GetQuestLocale(), and LoadQuestLocales().

◆ _questMoneyRewards

QuestMoneyRewardStore ObjectMgr::_questMoneyRewards
private

◆ _questOfferRewardLocaleStore

QuestOfferRewardLocaleContainer ObjectMgr::_questOfferRewardLocaleStore
private

◆ _questPOIStore

QuestPOIContainer ObjectMgr::_questPOIStore
private

Referenced by GetQuestPOIVector(), and LoadQuestPOI().

◆ _questRequestItemsLocaleStore

QuestRequestItemsLocaleContainer ObjectMgr::_questRequestItemsLocaleStore
private

◆ _questTemplates

QuestMap ObjectMgr::_questTemplates
private

◆ _questTemplatesFast

std::vector<Quest*> ObjectMgr::_questTemplatesFast
private

Referenced by GetQuestTemplate(), and LoadQuests().

◆ _repOnKillStore

RepOnKillContainer ObjectMgr::_repOnKillStore
private

◆ _repRewardRateStore

RepRewardRateContainer ObjectMgr::_repRewardRateStore
private

◆ _repSpilloverTemplateStore

RepSpilloverTemplateContainer ObjectMgr::_repSpilloverTemplateStore
private

◆ _reservedNamesStore

◆ _scriptNamesStore

ScriptNameContainer ObjectMgr::_scriptNamesStore
private

◆ _spellClickInfoStore

◆ _spellScriptsStore

SpellScriptsContainer ObjectMgr::_spellScriptsStore
private

◆ _tavernAreaTriggerStore

TavernAreaTriggerContainer ObjectMgr::_tavernAreaTriggerStore
private

◆ _tempSummonDataStore

TempSummonDataContainer ObjectMgr::_tempSummonDataStore
private

Stores temp summon data grouped by summoner's entry, summoner's type and group id.

Referenced by GetSummonGroup(), and LoadTempSummons().

◆ _trainers

std::unordered_map<uint32, Trainer::Trainer> ObjectMgr::_trainers
private

Referenced by GetTrainer(), and LoadTrainers().

◆ _transportMaps

std::set<uint32> ObjectMgr::_transportMaps
private

◆ _vehicleAccessoryStore

VehicleAccessoryContainer ObjectMgr::_vehicleAccessoryStore
private

◆ _vehicleSeatAddonStore

VehicleSeatAddonContainer ObjectMgr::_vehicleSeatAddonStore
private

◆ _vehicleTemplateAccessoryStore

VehicleAccessoryContainer ObjectMgr::_vehicleTemplateAccessoryStore
private

◆ DBCLocaleIndex

LocaleConstant ObjectMgr::DBCLocaleIndex
private

◆ FactionChangeAchievements

CharacterConversionMap ObjectMgr::FactionChangeAchievements

◆ FactionChangeItems

CharacterConversionMap ObjectMgr::FactionChangeItems

Referenced by LoadFactionChangeItems().

◆ FactionChangeQuests

CharacterConversionMap ObjectMgr::FactionChangeQuests

Referenced by LoadFactionChangeQuests().

◆ FactionChangeReputation

CharacterConversionMap ObjectMgr::FactionChangeReputation

◆ FactionChangeSpells

CharacterConversionMap ObjectMgr::FactionChangeSpells

Referenced by LoadFactionChangeSpells().

◆ FactionChangeTitles

CharacterConversionMap ObjectMgr::FactionChangeTitles

Referenced by LoadFactionChangeTitles().

◆ GameobjectInstanceSavedStateList

std::vector<GameobjectInstanceSavedState> ObjectMgr::GameobjectInstanceSavedStateList
private

◆ mExclusiveQuestGroups

ExclusiveQuestGroups ObjectMgr::mExclusiveQuestGroups

Referenced by LoadQuests().


The documentation for this class was generated from the following files: