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)
 
uint32 GetNearestTaxiNode (WorldLocation const &loc, 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 LoadGameObjectSummons ()
 
void LoadSpawnGroupTemplates ()
 
void LoadSpawnGroups ()
 
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
 
std::vector< GameObjectSummonData > const * GetGameObjectSummonGroup (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
 
SpawnData const * GetSpawnData (SpawnObjectType type, ObjectGuid::LowType spawnId) const
 
SpawnGroupTemplateData const * GetSpawnGroupData (uint32 groupId) const
 
SpawnGroupTemplateData const * GetDefaultSpawnGroup () const
 
SpawnGroupTemplateData const * GetLegacySpawnGroup () const
 
std::pair< SpawnGroupLinkContainer::const_iterator, SpawnGroupLinkContainer::const_iterator > GetSpawnDataForGroup (uint32 groupId) const
 
void OnDeleteSpawnData (SpawnData const *data)
 
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)
 
void LoadChatFilter ()
 
bool IsChatFiltered (std::string_view text) const
 
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)
 
std::vector< Trainer::Trainer const * > const & GetClassTrainers (uint8 classId) const
 
VendorItemData const * GetNpcVendorItemList (uint32 entry) const
 
void AddVendorItem (uint32 entry, uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedCost, bool persist=true)
 
bool RemoveVendorItem (uint32 entry, uint32 item, bool persist=true)
 
bool IsVendorItemValid (uint32 vendor_entry, uint32 item, uint32 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
 
std::unique_ptr< Acore::AhoCorasick< wchar_t > > _chatFilterAutomaton
 
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]
 
std::vector< std::vector< PlayerInfo * > > _playerInfo
 
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
 
SpawnGroupDataContainer _spawnGroupDataStore
 
SpawnGroupLinkContainer _spawnGroupMapStore
 
GameObjectLocaleContainer _gameObjectLocaleStore
 
GameObjectTemplateContainer _gameObjectTemplateStore
 
GameObjectTemplateAddonContainer _gameObjectTemplateAddonStore
 
TempSummonDataContainer _tempSummonDataStore
 Stores temp summon data grouped by summoner's entry, summoner's type and group id.
 
GameObjectSummonDataContainer _goSummonDataStore
 Stores gameobject 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< uint8, std::vector< Trainer::Trainer const * > > _classTrainers
 
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 
1708 {
1710 CREATURE_TO_GO, // Creature is dependant on GO
1711 GO_TO_GO,
1712 GO_TO_CREATURE, // GO is dependant on creature
1713 };
@ CREATURE_TO_GO
Definition ObjectMgr.h:1710
@ CREATURE_TO_CREATURE
Definition ObjectMgr.h:1709
@ GO_TO_GO
Definition ObjectMgr.h:1711
@ GO_TO_CREATURE
Definition ObjectMgr.h:1712

Constructor & Destructor Documentation

◆ ObjectMgr()

ObjectMgr::ObjectMgr ( )
private
300 :
301 _auctionId(1),
303 _mailId(1),
304 _hiPetNumber(1),
308{
309 for (uint8 i = 0; i < MAX_CLASSES; ++i)
310 {
311 _playerClassInfo[i] = nullptr;
312 }
313
314 // Initialize default spawn groups
317}
@ LOCALE_enUS
Definition Common.h:118
std::uint8_t uint8
Definition Define.h:109
#define MAX_CLASSES
Definition SharedDefines.h:140
SpawnGroupFlags
Definition SpawnData.h:42
@ SPAWNGROUP_FLAG_COMPATIBILITY_MODE
Definition SpawnData.h:45
@ SPAWNGROUP_FLAG_SYSTEM
Definition SpawnData.h:44
constexpr uint32 SPAWNGROUP_MAP_UNSET
Definition SpawnData.h:55
SpawnGroupDataContainer _spawnGroupDataStore
Definition ObjectMgr.h:1674
ObjectGuid::LowType _gameObjectSpawnId
Definition ObjectMgr.h:1541
uint32 _mailId
Definition ObjectMgr.h:1535
ObjectGuid::LowType _creatureSpawnId
Definition ObjectMgr.h:1540
LocaleConstant DBCLocaleIndex
Definition ObjectMgr.h:1611
PlayerClassInfo * _playerClassInfo[MAX_CLASSES]
Definition ObjectMgr.h:1631
uint64 _equipmentSetGuid
Definition ObjectMgr.h:1534
uint32 _auctionId
Definition ObjectMgr.h:1533
uint32 _hiPetNumber
Definition ObjectMgr.h:1537

References _playerClassInfo, _spawnGroupDataStore, MAX_CLASSES, SPAWNGROUP_FLAG_COMPATIBILITY_MODE, SPAWNGROUP_FLAG_SYSTEM, and SPAWNGROUP_MAP_UNSET.

◆ ~ObjectMgr()

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

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

Member Function Documentation

◆ AddCreatureToGrid()

void ObjectMgr::AddCreatureToGrid ( ObjectGuid::LowType  guid,
CreatureData const *  data 
)
2783{
2784 uint8 mask = data->spawnMask;
2785 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
2786 {
2787 if (mask & 1)
2788 {
2789 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
2790 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
2791 cell_guids.creatures.insert(guid);
2792 }
2793 }
2794}
uint32 MAKE_PAIR32(uint16 l, uint16 h)
Definition ObjectDefines.h:88
MapObjectGuids _mapObjectGuidsStore
Definition ObjectMgr.h:1656
GridCoord ComputeGridCoord(float x, float y)
Definition GridDefines.h:185
Definition ObjectMgr.h:481
CellGuidSet creatures
Definition ObjectMgr.h:482
Definition GridDefines.h:88
uint32 GetId() const
Definition GridDefines.h:150

References _mapObjectGuidsStore, Acore::ComputeGridCoord(), CellObjectGuids::creatures, CoordPair< LIMIT >::GetId(), MAKE_PAIR32(), SpawnData::mapid, SpawnData::posX, SpawnData::posY, and SpawnData::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 
)
2864{
2865 CreatureTemplate const* cInfo = GetCreatureTemplate(entry);
2866 if (!cInfo)
2867 return 0;
2868
2869 uint32 level = cInfo->minlevel == cInfo->maxlevel ? cInfo->minlevel : urand(cInfo->minlevel, cInfo->maxlevel); // Only used for extracting creature base stats
2870 CreatureBaseStats const* stats = GetCreatureBaseStats(level, cInfo->unit_class);
2871 Map* map = sMapMgr->CreateBaseMap(mapId);
2872 if (!map)
2873 return 0;
2874
2876 CreatureData& data = NewOrExistCreatureData(spawnId);
2877 data.spawnId = spawnId;
2878 data.spawnMask = spawnId;
2879 data.id = entry;
2880 data.id2 = 0;
2881 data.id3 = 0;
2882 data.mapid = mapId;
2883 data.displayid = 0;
2884 data.equipmentId = 0;
2885 data.posX = x;
2886 data.posY = y;
2887 data.posZ = z;
2888 data.orientation = o;
2889 data.spawntimesecs = spawntimedelay;
2890 data.wander_distance = 0;
2891 data.currentwaypoint = 0;
2892 data.curhealth = stats->GenerateHealth(cInfo);
2893 data.curmana = stats->GenerateMana(cInfo);
2894 data.movementType = cInfo->MovementType;
2895 data.spawnMask = 1;
2897 data.dbData = false;
2898 data.npcflag = cInfo->npcflag;
2899 data.unit_flags = cInfo->unit_flags;
2900 data.dynamicflags = cInfo->dynamicflags;
2901
2902 AddCreatureToGrid(spawnId, &data);
2903
2904 // Spawn if necessary (loaded grids only)
2905 if (!map->Instanceable() && map->IsGridLoaded(x, y))
2906 {
2907 Creature* creature = new Creature();
2908 if (!creature->LoadCreatureFromDB(spawnId, map, true, true))
2909 {
2910 LOG_ERROR("sql.sql", "AddCreature: Cannot add creature entry {} to map", entry);
2911 delete creature;
2912 return 0;
2913 }
2914 }
2915
2916 return spawnId;
2917}
std::uint32_t uint32
Definition Define.h:107
#define LOG_ERROR(filterType__,...)
Definition Log.h:145
#define sMapMgr
Definition MapMgr.h:220
@ PHASEMASK_NORMAL
Definition Object.h:63
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:1677
Definition Map.h:166
bool IsGridLoaded(GridCoord const &gridCoord) const
Definition Map.cpp:203
bool Instanceable() const
Definition Map.h:296
uint32 LowType
Definition ObjectGuid.h:122
CreatureBaseStats const * GetCreatureBaseStats(uint8 level, uint8 unitClass)
Definition ObjectMgr.cpp:10773
void AddCreatureToGrid(ObjectGuid::LowType guid, CreatureData const *data)
Definition ObjectMgr.cpp:2782
ObjectGuid::LowType GenerateCreatureSpawnId()
Definition ObjectMgr.cpp:7778
CreatureData & NewOrExistCreatureData(ObjectGuid::LowType spawnId)
Definition ObjectMgr.h:1246
CreatureTemplate const * GetCreatureTemplate(uint32 entry)
Definition ObjectMgr.cpp:11138
Definition CreatureData.h:298
uint32 GenerateMana(CreatureTemplate const *info) const
Definition CreatureData.h:318
uint32 GenerateHealth(CreatureTemplate const *info) const
Definition CreatureData.h:313
Definition CreatureData.h:370
float wander_distance
Definition CreatureData.h:378
uint32 spawntimesecs
Definition CreatureData.h:377
uint32 dynamicflags
Definition CreatureData.h:385
uint32 id
Definition CreatureData.h:372
uint32 npcflag
Definition CreatureData.h:383
uint32 displayid
Definition CreatureData.h:375
uint8 movementType
Definition CreatureData.h:382
uint32 unit_flags
Definition CreatureData.h:384
uint32 id2
Definition CreatureData.h:373
uint32 curhealth
Definition CreatureData.h:380
uint32 curmana
Definition CreatureData.h:381
uint32 id3
Definition CreatureData.h:374
int8 equipmentId
Definition CreatureData.h:376
uint32 currentwaypoint
Definition CreatureData.h:379
Definition CreatureData.h:187
uint32 unit_flags
Definition CreatureData.h:214
uint8 minlevel
Definition CreatureData.h:196
uint8 maxlevel
Definition CreatureData.h:197
uint32 MovementType
Definition CreatureData.h:230
uint32 npcflag
Definition CreatureData.h:200
uint32 unit_class
Definition CreatureData.h:213
uint32 dynamicflags
Definition CreatureData.h:216
float posX
Definition SpawnData.h:71
float posY
Definition SpawnData.h:72
uint32 phaseMask
Definition SpawnData.h:70
uint8 spawnMask
Definition SpawnData.h:75
bool dbData
Definition SpawnData.h:77
ObjectGuid::LowType spawnId
Definition SpawnData.h:68
float orientation
Definition SpawnData.h:74
uint16 mapid
Definition SpawnData.h:69
float posZ
Definition SpawnData.h:73

References AddCreatureToGrid(), CreatureData::curhealth, CreatureData::curmana, CreatureData::currentwaypoint, SpawnData::dbData, CreatureData::displayid, CreatureTemplate::dynamicflags, CreatureData::dynamicflags, CreatureData::equipmentId, GenerateCreatureSpawnId(), CreatureBaseStats::GenerateHealth(), CreatureBaseStats::GenerateMana(), GetCreatureBaseStats(), GetCreatureTemplate(), CreatureData::id, CreatureData::id2, CreatureData::id3, Map::Instanceable(), Map::IsGridLoaded(), Creature::LoadCreatureFromDB(), LOG_ERROR, SpawnData::mapid, CreatureTemplate::maxlevel, CreatureTemplate::minlevel, CreatureTemplate::MovementType, CreatureData::movementType, NewOrExistCreatureData(), CreatureTemplate::npcflag, CreatureData::npcflag, SpawnData::orientation, SpawnData::phaseMask, PHASEMASK_NORMAL, SpawnData::posX, SpawnData::posY, SpawnData::posZ, sMapMgr, SpawnData::spawnId, SpawnData::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 
)
3235{
3236 uint8 mask = data->spawnMask;
3237 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
3238 {
3239 if (mask & 1)
3240 {
3241 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
3242 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
3243 cell_guids.gameobjects.insert(guid);
3244 }
3245 }
3246}
CellGuidSet gameobjects
Definition ObjectMgr.h:483

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

Referenced by AddGOData(), and LoadGameobjects().

◆ AddGameTele()

bool ObjectMgr::AddGameTele ( GameTele data)
9943{
9944 // find max id
9945 uint32 new_id = 0;
9946 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9947 if (itr->first > new_id)
9948 new_id = itr->first;
9949
9950 // use next
9951 ++new_id;
9952
9953 if (!Utf8toWStr(tele.name, tele.wnameLow))
9954 return false;
9955
9956 wstrToLower(tele.wnameLow);
9957
9958 _gameTeleStore[new_id] = tele;
9959
9961
9962 stmt->SetData(0, new_id);
9963 stmt->SetData(1, tele.position_x);
9964 stmt->SetData(2, tele.position_y);
9965 stmt->SetData(3, tele.position_z);
9966 stmt->SetData(4, tele.orientation);
9967 stmt->SetData(5, uint16(tele.mapId));
9968 stmt->SetData(6, tele.name);
9969
9970 WorldDatabase.Execute(stmt);
9971
9972 return true;
9973}
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:1599
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 
)
2811{
2812 GameObjectTemplate const* goinfo = GetGameObjectTemplate(entry);
2813 if (!goinfo)
2814 return 0;
2815
2816 Map* map = sMapMgr->CreateBaseMap(mapId);
2817 if (!map)
2818 return 0;
2819
2821
2822 GameObjectData& data = NewGOData(spawnId);
2823 data.spawnId = spawnId;
2824 data.id = entry;
2825 data.mapid = mapId;
2826 data.posX = x;
2827 data.posY = y;
2828 data.posZ = z;
2829 data.orientation = o;
2830 data.rotation.x = rotation0;
2831 data.rotation.y = rotation1;
2832 data.rotation.z = rotation2;
2833 data.rotation.w = rotation3;
2834 data.spawntimesecs = spawntimedelay;
2835 data.animprogress = 100;
2836 data.spawnMask = 1;
2837 data.go_state = GO_STATE_READY;
2839 data.artKit = goinfo->type == GAMEOBJECT_TYPE_CAPTURE_POINT ? 21 : 0;
2840 data.dbData = false;
2841 data.spawnGroupId = 0;
2842
2843 AddGameobjectToGrid(spawnId, &data);
2844
2845 // Spawn if necessary (loaded grids only)
2846 // We use spawn coords to spawn
2847 if (!map->Instanceable() && map->IsGridLoaded(x, y))
2848 {
2850 if (!go->LoadGameObjectFromDB(spawnId, map))
2851 {
2852 LOG_ERROR("sql.sql", "AddGOData: cannot add gameobject entry {} to map", entry);
2853 delete go;
2854 return 0;
2855 }
2856 }
2857
2858 LOG_DEBUG("maps", "AddGOData: spawnId {} entry {} map {} x {} y {} z {} o {}", spawnId, entry, mapId, x, y, z, o);
2859
2860 return spawnId;
2861}
@ GO_STATE_READY
Definition GameObjectData.h:709
#define LOG_DEBUG(filterType__,...)
Definition Log.h:157
@ GAMEOBJECT_TYPE_CAPTURE_POINT
Definition SharedDefines.h:1593
Definition GameObject.h:120
virtual bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map *map, bool addToMap=true)
Definition GameObject.cpp:1099
void AddGameobjectToGrid(ObjectGuid::LowType guid, GameObjectData const *data)
Definition ObjectMgr.cpp:3234
GameObjectTemplate const * GetGameObjectTemplate(uint32 entry)
Definition ObjectMgr.cpp:11114
ObjectGuid::LowType GenerateGameObjectSpawnId()
Definition ObjectMgr.cpp:7788
GameObjectData & NewGOData(ObjectGuid::LowType guid)
Definition ObjectMgr.h:1361
bool IsGameObjectStaticTransport(uint32 entry)
Definition ObjectMgr.cpp:11123
Definition Transport.h:115
Definition GameObjectData.h:715
uint8 artKit
Definition GameObjectData.h:722
int32 spawntimesecs
Definition GameObjectData.h:719
G3D::Quat rotation
Definition GameObjectData.h:718
uint32 animprogress
Definition GameObjectData.h:720
uint32 id
Definition GameObjectData.h:717
GOState go_state
Definition GameObjectData.h:721
Definition GameObjectData.h:32
uint32 type
Definition GameObjectData.h:34
uint32 spawnGroupId
Definition SpawnData.h:78

References AddGameobjectToGrid(), GameObjectData::animprogress, GameObjectData::artKit, SpawnData::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, SpawnData::mapid, NewGOData(), SpawnData::orientation, SpawnData::phaseMask, PHASEMASK_NORMAL, SpawnData::posX, SpawnData::posY, SpawnData::posZ, GameObjectData::rotation, sMapMgr, SpawnData::spawnGroupId, SpawnData::spawnId, SpawnData::spawnMask, GameObjectData::spawntimesecs, and GameObjectTemplate::type.

◆ AddLocaleString()

◆ AddProfanityPlayerName()

void ObjectMgr::AddProfanityPlayerName ( std::string const &  name)
9243{
9244 if (!IsProfanityName(name))
9245 {
9246 std::wstring wstr;
9247 if (!Utf8toWStr(name, wstr))
9248 {
9249 LOG_ERROR("server", "Could not add invalid name to profanity player names: {}", name);
9250 return;
9251 }
9252 wstrToLower(wstr);
9253
9254 _profanityNamesStore.insert(wstr);
9255
9257 stmt->SetData(0, name);
9258 CharacterDatabase.Execute(stmt);
9259 }
9260}
@ CHAR_INS_PROFANITY_PLAYER_NAME
Definition CharacterDatabase.h:524
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition DatabaseEnv.cpp:21
ProfanityNamesContainer _profanityNamesStore
Definition ObjectMgr.h:1594
bool IsProfanityName(std::string_view name) const
Definition ObjectMgr.cpp:9227

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

◆ AddReservedPlayerName()

void ObjectMgr::AddReservedPlayerName ( std::string const &  name)
9140{
9141 if (!IsReservedName(name))
9142 {
9143 std::wstring wstr;
9144 if (!Utf8toWStr(name, wstr))
9145 {
9146 LOG_ERROR("server", "Could not add invalid name to reserved player names: {}", name);
9147 return;
9148 }
9149 wstrToLower(wstr);
9150
9151 _reservedNamesStore.insert(wstr);
9152
9154 stmt->SetData(0, name);
9155 CharacterDatabase.Execute(stmt);
9156 }
9157}
@ CHAR_INS_RESERVED_PLAYER_NAME
Definition CharacterDatabase.h:523
bool IsReservedName(std::string_view name) const
Definition ObjectMgr.cpp:9124
ReservedNamesContainer _reservedNamesStore
Definition ObjectMgr.h:1590

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

◆ AddVendorItem()

void ObjectMgr::AddVendorItem ( uint32  entry,
uint32  item,
uint32  maxcount,
uint32  incrtime,
uint32  extendedCost,
bool  persist = true 
)
10451{
10452 VendorItemData& vList = _cacheVendorItemStore[entry];
10453 vList.AddItem(item, maxcount, incrtime, extendedCost);
10454
10455 if (persist)
10456 {
10458
10459 stmt->SetData(0, entry);
10460 stmt->SetData(1, item);
10461 stmt->SetData(2, maxcount);
10462 stmt->SetData(3, incrtime);
10463 stmt->SetData(4, extendedCost);
10464
10465 WorldDatabase.Execute(stmt);
10466 }
10467}
@ WORLD_INS_NPC_VENDOR
Definition WorldDatabase.h:43
Definition CreatureData.h:460
void AddItem(uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost)
Definition CreatureData.h:472

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
5005{
5006 // base data (last known level)
5007 *info = _playerInfo[race][_class]->levelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) - 1];
5008
5009 // if conversion from uint32 to uint8 causes unexpected behaviour, change lvl to uint32
5010 for (uint8 lvl = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) - 1; lvl < level; ++lvl)
5011 {
5012 switch (_class)
5013 {
5014 case CLASS_WARRIOR:
5015 info->stats[STAT_STRENGTH] += (lvl > 23 ? 2 : (lvl > 1 ? 1 : 0));
5016 info->stats[STAT_STAMINA] += (lvl > 23 ? 2 : (lvl > 1 ? 1 : 0));
5017 info->stats[STAT_AGILITY] += (lvl > 36 ? 1 : (lvl > 6 && (lvl % 2) ? 1 : 0));
5018 info->stats[STAT_INTELLECT] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
5019 info->stats[STAT_SPIRIT] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
5020 break;
5021 case CLASS_PALADIN:
5022 info->stats[STAT_STRENGTH] += (lvl > 3 ? 1 : 0);
5023 info->stats[STAT_STAMINA] += (lvl > 33 ? 2 : (lvl > 1 ? 1 : 0));
5024 info->stats[STAT_AGILITY] += (lvl > 38 ? 1 : (lvl > 7 && !(lvl % 2) ? 1 : 0));
5025 info->stats[STAT_INTELLECT] += (lvl > 6 && (lvl % 2) ? 1 : 0);
5026 info->stats[STAT_SPIRIT] += (lvl > 7 ? 1 : 0);
5027 break;
5028 case CLASS_HUNTER:
5029 info->stats[STAT_STRENGTH] += (lvl > 4 ? 1 : 0);
5030 info->stats[STAT_STAMINA] += (lvl > 4 ? 1 : 0);
5031 info->stats[STAT_AGILITY] += (lvl > 33 ? 2 : (lvl > 1 ? 1 : 0));
5032 info->stats[STAT_INTELLECT] += (lvl > 8 && (lvl % 2) ? 1 : 0);
5033 info->stats[STAT_SPIRIT] += (lvl > 38 ? 1 : (lvl > 9 && !(lvl % 2) ? 1 : 0));
5034 break;
5035 case CLASS_ROGUE:
5036 info->stats[STAT_STRENGTH] += (lvl > 5 ? 1 : 0);
5037 info->stats[STAT_STAMINA] += (lvl > 4 ? 1 : 0);
5038 info->stats[STAT_AGILITY] += (lvl > 16 ? 2 : (lvl > 1 ? 1 : 0));
5039 info->stats[STAT_INTELLECT] += (lvl > 8 && !(lvl % 2) ? 1 : 0);
5040 info->stats[STAT_SPIRIT] += (lvl > 38 ? 1 : (lvl > 9 && !(lvl % 2) ? 1 : 0));
5041 break;
5042 case CLASS_PRIEST:
5043 info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
5044 info->stats[STAT_STAMINA] += (lvl > 5 ? 1 : 0);
5045 info->stats[STAT_AGILITY] += (lvl > 38 ? 1 : (lvl > 8 && (lvl % 2) ? 1 : 0));
5046 info->stats[STAT_INTELLECT] += (lvl > 22 ? 2 : (lvl > 1 ? 1 : 0));
5047 info->stats[STAT_SPIRIT] += (lvl > 3 ? 1 : 0);
5048 break;
5049 case CLASS_SHAMAN:
5050 info->stats[STAT_STRENGTH] += (lvl > 34 ? 1 : (lvl > 6 && (lvl % 2) ? 1 : 0));
5051 info->stats[STAT_STAMINA] += (lvl > 4 ? 1 : 0);
5052 info->stats[STAT_AGILITY] += (lvl > 7 && !(lvl % 2) ? 1 : 0);
5053 info->stats[STAT_INTELLECT] += (lvl > 5 ? 1 : 0);
5054 info->stats[STAT_SPIRIT] += (lvl > 4 ? 1 : 0);
5055 break;
5056 case CLASS_MAGE:
5057 info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
5058 info->stats[STAT_STAMINA] += (lvl > 5 ? 1 : 0);
5059 info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
5060 info->stats[STAT_INTELLECT] += (lvl > 24 ? 2 : (lvl > 1 ? 1 : 0));
5061 info->stats[STAT_SPIRIT] += (lvl > 33 ? 2 : (lvl > 2 ? 1 : 0));
5062 break;
5063 case CLASS_WARLOCK:
5064 info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
5065 info->stats[STAT_STAMINA] += (lvl > 38 ? 2 : (lvl > 3 ? 1 : 0));
5066 info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
5067 info->stats[STAT_INTELLECT] += (lvl > 33 ? 2 : (lvl > 2 ? 1 : 0));
5068 info->stats[STAT_SPIRIT] += (lvl > 38 ? 2 : (lvl > 3 ? 1 : 0));
5069 break;
5070 case CLASS_DRUID:
5071 info->stats[STAT_STRENGTH] += (lvl > 38 ? 2 : (lvl > 6 && (lvl % 2) ? 1 : 0));
5072 info->stats[STAT_STAMINA] += (lvl > 32 ? 2 : (lvl > 4 ? 1 : 0));
5073 info->stats[STAT_AGILITY] += (lvl > 38 ? 2 : (lvl > 8 && (lvl % 2) ? 1 : 0));
5074 info->stats[STAT_INTELLECT] += (lvl > 38 ? 3 : (lvl > 4 ? 1 : 0));
5075 info->stats[STAT_SPIRIT] += (lvl > 38 ? 3 : (lvl > 5 ? 1 : 0));
5076 }
5077 }
5078}
@ CLASS_HUNTER
Definition SharedDefines.h:128
@ CLASS_DRUID
Definition SharedDefines.h:136
@ CLASS_SHAMAN
Definition SharedDefines.h:132
@ CLASS_PRIEST
Definition SharedDefines.h:130
@ CLASS_WARRIOR
Definition SharedDefines.h:126
@ CLASS_WARLOCK
Definition SharedDefines.h:134
@ CLASS_MAGE
Definition SharedDefines.h:133
@ CLASS_PALADIN
Definition SharedDefines.h:127
@ CLASS_ROGUE
Definition SharedDefines.h:129
@ STAT_SPIRIT
Definition SharedDefines.h:250
@ STAT_INTELLECT
Definition SharedDefines.h:249
@ STAT_AGILITY
Definition SharedDefines.h:247
@ STAT_STRENGTH
Definition SharedDefines.h:246
@ STAT_STAMINA
Definition SharedDefines.h:248
@ CONFIG_MAX_PLAYER_LEVEL
Definition WorldConfig.h:193
#define sWorld
Definition World.h:317

References _playerInfo, CLASS_DRUID, CLASS_HUNTER, CLASS_MAGE, CLASS_PALADIN, CLASS_PRIEST, CLASS_ROGUE, CLASS_SHAMAN, CLASS_WARLOCK, CLASS_WARRIOR, CONFIG_MAX_PLAYER_LEVEL, 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 
)
9762{
9763 AreaTableEntry const* fArea = sAreaTableStore.LookupEntry(entry);
9764 if (!fArea)
9765 {
9766 LOG_ERROR("sql.sql", "AreaId {} defined in `skill_fishing_base_level` does not exist", entry);
9767 return;
9768 }
9769
9770 _fishingBaseForAreaStore[entry] = skill;
9771
9772 LOG_INFO("server.loading", ">> Fishing base skill level of area {} changed to {}", entry, skill);
9773 LOG_INFO("server.loading", " ");
9774}
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
#define LOG_INFO(filterType__,...)
Definition Log.h:153
FishingBaseSkillContainer _fishingBaseForAreaStore
Definition ObjectMgr.h:1644
Definition DBCStructure.h:519

References _fishingBaseForAreaStore, LOG_ERROR, LOG_INFO, and sAreaTableStore.

◆ CheckCreatureMovement()

void ObjectMgr::CheckCreatureMovement ( char const *  table,
uint64  id,
CreatureMovementData creatureMovement 
)
1236{
1237 if (creatureMovement.Ground >= CreatureGroundMovementType::Max)
1238 {
1239 LOG_ERROR("sql.sql", "`{}`.`Ground` wrong value ({}) for Id {}, setting to Run.", table, uint32(creatureMovement.Ground), id);
1240 creatureMovement.Ground = CreatureGroundMovementType::Run;
1241 }
1242
1243 if (creatureMovement.Flight >= CreatureFlightMovementType::Max)
1244 {
1245 LOG_ERROR("sql.sql", "`{}`.`Flight` wrong value ({}) for Id {}, setting to None.", table, uint32(creatureMovement.Flight), id);
1246 creatureMovement.Flight = CreatureFlightMovementType::None;
1247 }
1248
1249 if (creatureMovement.Chase >= CreatureChaseMovementType::Max)
1250 {
1251 LOG_ERROR("sql.sql", "`{}`.`Chase` wrong value ({}) for Id {}, setting to Run.", table, uint32(creatureMovement.Chase), id);
1252 creatureMovement.Chase = CreatureChaseMovementType::Run;
1253 }
1254
1255 if (creatureMovement.Random >= CreatureRandomMovementType::Max)
1256 {
1257 LOG_ERROR("sql.sql", "`{}`.`Random` wrong value ({}) for Id {}, setting to Walk.", table, uint32(creatureMovement.Random), id);
1258 creatureMovement.Random = CreatureRandomMovementType::Walk;
1259 }
1260}
CreatureRandomMovementType Random
Definition CreatureData.h:128
CreatureFlightMovementType Flight
Definition CreatureData.h:124
CreatureChaseMovementType Chase
Definition CreatureData.h:127
CreatureGroundMovementType Ground
Definition CreatureData.h:123

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

Referenced by LoadCreatureTemplates().

◆ CheckDeclinedNames()

bool ObjectMgr::CheckDeclinedNames ( std::wstring  w_ownname,
DeclinedName const &  names 
)
static
9777{
9778 // get main part of the name
9779 std::wstring mainpart = GetMainPartOfName(w_ownname, 0);
9780 // prepare flags
9781 bool x = true;
9782 bool y = true;
9783
9784 // check declined names
9785 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
9786 {
9787 std::wstring wname;
9788 if (!Utf8toWStr(names.name[i], wname))
9789 return false;
9790
9791 if (mainpart != GetMainPartOfName(wname, i + 1))
9792 x = false;
9793
9794 if (w_ownname != wname)
9795 y = false;
9796 }
9797 return (x || y);
9798}
#define MAX_DECLINED_NAME_CASES
Definition Unit.h:546
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
9482{
9483 std::wstring wname;
9484 if (!Utf8toWStr(name, wname))
9485 return PET_NAME_INVALID;
9486
9487 if (wname.size() > MAX_PET_NAME)
9488 return PET_NAME_TOO_LONG;
9489
9490 uint32 minName = sWorld->getIntConfig(CONFIG_MIN_PET_NAME);
9491 if (wname.size() < minName)
9492 return PET_NAME_TOO_SHORT;
9493
9494 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_PET_NAMES);
9495 if (!isValidString(wname, strictMask, false))
9497
9498 // Check Reserved Name
9499 if (sObjectMgr->IsReservedName(name))
9500 return PET_NAME_RESERVED;
9501
9502 // Check Profanity Name
9503 if (sObjectMgr->IsProfanityName(name))
9504 return PET_NAME_PROFANE;
9505
9506 return PET_NAME_SUCCESS;
9507}
bool isValidString(std::wstring wstr, uint32 strictMask, bool numericOrSpace, bool create=false)
Definition ObjectMgr.cpp:9366
#define sObjectMgr
Definition ObjectMgr.h:1732
#define MAX_PET_NAME
Definition ObjectMgr.h:689
@ 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:180
@ CONFIG_MIN_PET_NAME
Definition WorldConfig.h:183

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(), and pet_commandscript::HandlePetRenameCommand().

◆ CheckPlayerName()

uint8 ObjectMgr::CheckPlayerName ( std::string_view  name,
bool  create = false 
)
static
9403{
9404 std::wstring wname;
9405
9406 // Check for invalid characters
9407 if (!Utf8toWStr(name, wname))
9409
9410 // Check for too long name
9411 if (wname.size() > MAX_PLAYER_NAME)
9412 return CHAR_NAME_TOO_LONG;
9413
9414 // Check for too short name
9415 uint32 minName = sWorld->getIntConfig(CONFIG_MIN_PLAYER_NAME);
9416 if (wname.size() < minName)
9417 return CHAR_NAME_TOO_SHORT;
9418
9419 // Check for mixed languages
9420 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_PLAYER_NAMES);
9421 if (!isValidString(wname, strictMask, false, create))
9423
9424 // Check for three consecutive letters
9425 wstrToLower(wname);
9426 for (std::size_t i = 2; i < wname.size(); ++i)
9427 if (wname[i] == wname[i - 1] && wname[i] == wname[i - 2])
9429
9430 // Check Reserved Name
9431 if (sObjectMgr->IsReservedName(name))
9432 return CHAR_NAME_RESERVED;
9433
9434 // Check Profanity Name
9435 if (sObjectMgr->IsProfanityName(name))
9436 return CHAR_NAME_PROFANE;
9437
9438 return CHAR_NAME_SUCCESS;
9439}
#define MAX_PLAYER_NAME
Definition ObjectMgr.h:687
@ CHAR_NAME_TOO_SHORT
Definition SharedDefines.h:3671
@ CHAR_NAME_THREE_CONSECUTIVE
Definition SharedDefines.h:3679
@ CHAR_NAME_INVALID_CHARACTER
Definition SharedDefines.h:3673
@ CHAR_NAME_TOO_LONG
Definition SharedDefines.h:3672
@ CHAR_NAME_RESERVED
Definition SharedDefines.h:3676
@ CHAR_NAME_MIXED_LANGUAGES
Definition SharedDefines.h:3674
@ CHAR_NAME_PROFANE
Definition SharedDefines.h:3675
@ CHAR_NAME_SUCCESS
Definition SharedDefines.h:3668
@ CONFIG_STRICT_PLAYER_NAMES
Definition WorldConfig.h:177
@ CONFIG_MIN_PLAYER_NAME
Definition WorldConfig.h:181

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
1660{
1661 npcflag = cinfo->npcflag;
1662 unit_flags = cinfo->unit_flags;
1663 dynamicflags = cinfo->dynamicflags;
1664
1665 if (data)
1666 {
1667 if (data->npcflag)
1668 npcflag = data->npcflag;
1669
1670 if (data->unit_flags)
1671 unit_flags = data->unit_flags;
1672
1673 if (data->dynamicflags)
1674 dynamicflags = data->dynamicflags;
1675 }
1676}

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
1645{
1646 // Load creature model (display id)
1647 if (data && data->displayid)
1648 if (CreatureModel const* model = cinfo->GetModelWithDisplayId(data->displayid))
1649 return model;
1650
1651 if (!cinfo->HasFlagsExtra(CREATURE_FLAG_EXTRA_TRIGGER))
1652 if (CreatureModel const* model = cinfo->GetRandomValidModel())
1653 return model;
1654
1655 // Triggers by default receive the invisible model
1656 return cinfo->GetFirstInvisibleModel();
1657}
@ CREATURE_FLAG_EXTRA_TRIGGER
Definition CreatureData.h:53

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)
8756{
8757 // remove mapid*cellid -> guid_set map
8758 CreatureData const* data = GetCreatureData(guid);
8759 if (data)
8760 RemoveCreatureFromGrid(guid, data);
8761
8762 _creatureDataStore.erase(guid);
8763}
CreatureDataContainer _creatureDataStore
Definition ObjectMgr.h:1659
void RemoveCreatureFromGrid(ObjectGuid::LowType guid, CreatureData const *data)
Definition ObjectMgr.cpp:2796
CreatureData const * GetCreatureData(ObjectGuid::LowType spawnId) const
Definition ObjectMgr.h:1237

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

◆ DeleteGameTele()

bool ObjectMgr::DeleteGameTele ( std::string_view  name)
9976{
9977 // explicit name case
9978 std::wstring wname;
9979 if (!Utf8toWStr(name, wname))
9980 return false;
9981
9982 // converting string that we try to find to lower case
9983 wstrToLower(wname);
9984
9985 for (GameTeleContainer::iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9986 {
9987 if (itr->second.wnameLow == wname)
9988 {
9990
9991 stmt->SetData(0, itr->second.name);
9992
9993 WorldDatabase.Execute(stmt);
9994
9995 _gameTeleStore.erase(itr);
9996 return true;
9997 }
9998 }
9999
10000 return false;
10001}
@ 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)
8766{
8767 // remove mapid*cellid -> guid_set map
8768 GameObjectData const* data = GetGameObjectData(guid);
8769 if (data)
8770 RemoveGameobjectFromGrid(guid, data);
8771
8772 _gameObjectDataStore.erase(guid);
8773}
GameObjectData const * GetGameObjectData(ObjectGuid::LowType spawnId) const
Definition ObjectMgr.h:1272
GameObjectDataContainer _gameObjectDataStore
Definition ObjectMgr.h:1673
void RemoveGameobjectFromGrid(ObjectGuid::LowType guid, GameObjectData const *data)
Definition ObjectMgr.cpp:3248

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

◆ GenerateAuctionID()

uint32 ObjectMgr::GenerateAuctionID ( )
7748{
7749 if (_auctionId >= 0xFFFFFFFE)
7750 {
7751 LOG_ERROR("server.worldserver", "Auctions ids overflow!! Can't continue, shutting down server. ");
7753 }
7754 return _auctionId++;
7755}
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 ( )
7779{
7780 if (_creatureSpawnId >= uint32(0xFFFFFF))
7781 {
7782 LOG_ERROR("server.worldserver", "Creature spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info.");
7784 }
7785 return _creatureSpawnId++;
7786}

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

Referenced by AddCreData().

◆ GenerateEquipmentSetGuid()

uint64 ObjectMgr::GenerateEquipmentSetGuid ( )
7758{
7759 if (_equipmentSetGuid >= uint64(0xFFFFFFFFFFFFFFFELL))
7760 {
7761 LOG_ERROR("server.worldserver", "EquipmentSet guid overflow!! Can't continue, shutting down server. ");
7763 }
7764 return _equipmentSetGuid++;
7765}
std::uint64_t uint64
Definition Define.h:106

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

◆ GenerateGameObjectSpawnId()

uint32 ObjectMgr::GenerateGameObjectSpawnId ( )
7789{
7790 if (_gameObjectSpawnId >= uint32(0xFFFFFF))
7791 {
7792 LOG_ERROR("server.worldserver", "GameObject spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7794 }
7795 return _gameObjectSpawnId++;
7796}

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

Referenced by AddGOData().

◆ GenerateMailID()

uint32 ObjectMgr::GenerateMailID ( )
7768{
7769 if (_mailId >= 0xFFFFFFFE)
7770 {
7771 LOG_ERROR("server.worldserver", "Mail ids overflow!! Can't continue, shutting down server. ");
7773 }
7774 std::lock_guard<std::mutex> guard(_mailIdMutex);
7775 return _mailId++;
7776}
std::mutex _mailIdMutex
Definition ObjectMgr.h:1536

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

◆ GeneratePetName()

std::string ObjectMgr::GeneratePetName ( uint32  entry)
8255{
8256 std::vector<std::string>& list0 = _petHalfName0[entry];
8257 std::vector<std::string>& list1 = _petHalfName1[entry];
8258
8259 if (list0.empty() || list1.empty())
8260 {
8261 CreatureTemplate const* cinfo = GetCreatureTemplate(entry);
8262 char const* petname = GetPetName(cinfo->family, sWorld->GetDefaultDbcLocale());
8263 if (!petname)
8264 return cinfo->Name;
8265
8266 return std::string(petname);
8267 }
8268
8269 return *(list0.begin() + urand(0, list0.size() - 1)) + *(list1.begin() + urand(0, list1.size() - 1));
8270}
char const * GetPetName(uint32 petfamily, uint32 dbclang)
Definition DBCStores.cpp:665
HalfNameContainer _petHalfName1
Definition ObjectMgr.h:1648
HalfNameContainer _petHalfName0
Definition ObjectMgr.h:1647
std::string Name
Definition CreatureData.h:192

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

Referenced by GeneratePetNameLocale().

◆ GeneratePetNameLocale()

std::string ObjectMgr::GeneratePetNameLocale ( uint32  entry,
LocaleConstant  locale 
)
8242{
8243 std::vector<std::string>& list0 = _petHalfLocaleName0[std::make_pair(entry, locale)];
8244 std::vector<std::string>& list1 = _petHalfLocaleName1[std::make_pair(entry, locale)];
8245
8246 if (list0.empty() || list1.empty())
8247 {
8248 return GeneratePetName(entry);
8249 }
8250
8251 return *(list0.begin() + urand(0, list0.size() - 1)) + *(list1.begin() + urand(0, list1.size() - 1));
8252}
HalfNameContainerLocale _petHalfLocaleName0
Definition ObjectMgr.h:1650
HalfNameContainerLocale _petHalfLocaleName1
Definition ObjectMgr.h:1651
std::string GeneratePetName(uint32 entry)
Definition ObjectMgr.cpp:8254

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

◆ GeneratePetNumber()

uint32 ObjectMgr::GeneratePetNumber ( )
8273{
8274 std::lock_guard<std::mutex> guard(_hiPetNumberMutex);
8275 return ++_hiPetNumber;
8276}
std::mutex _hiPetNumberMutex
Definition ObjectMgr.h:1538

References _hiPetNumber, and _hiPetNumberMutex.

◆ GetAccessRequirement()

DungeonProgressionRequirements const * ObjectMgr::GetAccessRequirement ( uint32  mapid,
Difficulty  difficulty 
) const
inline
885 {
886 DungeonProgressionRequirementsContainer::const_iterator itr = _accessRequirementStore.find(mapid);
887 if (itr != _accessRequirementStore.end())
888 {
889 std::unordered_map<uint8, DungeonProgressionRequirements*> difficultiesProgressionRequirements = itr->second;
890 auto difficultiesItr = difficultiesProgressionRequirements.find(difficulty);
891 if (difficultiesItr != difficultiesProgressionRequirements.end())
892 {
893 return difficultiesItr->second;
894 }
895 }
896 return nullptr;
897 }

References _accessRequirementStore.

◆ GetAcoreString() [1/2]

AcoreString const * ObjectMgr::GetAcoreString ( uint32  entry) const
inline
1391 {
1392 AcoreStringContainer::const_iterator itr = _acoreStringStore.find(entry);
1393 if (itr == _acoreStringStore.end())
1394 return nullptr;
1395
1396 return &itr->second;
1397 }
AcoreStringContainer _acoreStringStore
Definition ObjectMgr.h:1695

References _acoreStringStore.

Referenced by GetAcoreString(), and GetAcoreStringForDBCLocale().

◆ GetAcoreString() [2/2]

std::string ObjectMgr::GetAcoreString ( uint32  entry,
LocaleConstant  locale 
) const
9708{
9709 AcoreString const* as = GetAcoreString(entry);
9710 if (as && !as->Content.empty())
9711 {
9712 if (as->Content.size() > std::size_t(locale) && !as->Content[locale].empty())
9713 return as->Content[locale];
9714
9715 return as->Content[DEFAULT_LOCALE];
9716 }
9717
9718 std::string msg = Acore::StringFormat("No entry for acore_string ({}) in DB.", entry);
9719 LOG_ERROR("sql.sql", msg);
9720 return msg;
9721}
#define DEFAULT_LOCALE
Definition Common.h:131
AcoreString const * GetAcoreString(uint32 entry) const
Definition ObjectMgr.h:1390
std::string StringFormat(FormatStringView fmt, Args &&... args)
Default AC string format function.
Definition StringFormat.h:44
Definition ObjectMgr.h:504
std::vector< std::string > Content
Definition ObjectMgr.h:505

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

◆ GetAcoreStringForDBCLocale()

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

References DBCLocaleIndex, and GetAcoreString().

◆ GetAllAreaTriggerScriptData()

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

References _areaTriggerScriptStore.

◆ GetAllCreatureData()

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

References _creatureDataStore.

◆ GetAllGOData()

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

References _gameObjectDataStore.

◆ GetAreaTrigger()

AreaTrigger const * ObjectMgr::GetAreaTrigger ( uint32  trigger) const
inline
869 {
870 AreaTriggerContainer::const_iterator itr = _areaTriggerStore.find(trigger);
871 if (itr != _areaTriggerStore.end())
872 return &itr->second;
873 return nullptr;
874 }
AreaTriggerContainer _areaTriggerStore
Definition ObjectMgr.h:1567

References _areaTriggerStore.

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

◆ GetAreaTriggerScriptId()

uint32 ObjectMgr::GetAreaTriggerScriptId ( uint32  trigger_id)
9801{
9802 AreaTriggerScriptContainer::const_iterator i = _areaTriggerScriptStore.find(trigger_id);
9803 if (i != _areaTriggerScriptStore.end())
9804 return i->second;
9805 return 0;
9806}

References _areaTriggerScriptStore.

◆ GetAreaTriggerTeleport()

AreaTriggerTeleport const * ObjectMgr::GetAreaTriggerTeleport ( uint32  trigger) const
inline
877 {
878 AreaTriggerTeleportContainer::const_iterator itr = _areaTriggerTeleportStore.find(trigger);
879 if (itr != _areaTriggerTeleportStore.end())
880 return &itr->second;
881 return nullptr;
882 }
AreaTriggerTeleportContainer _areaTriggerTeleportStore
Definition ObjectMgr.h:1568

References _areaTriggerTeleportStore.

◆ GetBaseReputationOf()

int32 ObjectMgr::GetBaseReputationOf ( FactionEntry const *  factionEntry,
uint8  race,
uint8  playerClass 
)
9815{
9816 if (!factionEntry)
9817 return 0;
9818
9819 uint32 raceMask = (1 << (race - 1));
9820 uint32 classMask = (1 << (playerClass - 1));
9821
9822 for (int i = 0; i < 4; i++)
9823 {
9824 if ((!factionEntry->BaseRepClassMask[i] ||
9825 factionEntry->BaseRepClassMask[i] & classMask) &&
9826 (!factionEntry->BaseRepRaceMask[i] ||
9827 factionEntry->BaseRepRaceMask[i] & raceMask))
9828 return factionEntry->BaseRepValue[i];
9829 }
9830
9831 return 0;
9832}

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

◆ GetBaseXP()

uint32 ObjectMgr::GetBaseXP ( uint8  level)
8183{
8184 return _baseXPTable[level] ? _baseXPTable[level] : 0;
8185}
BaseXPContainer _baseXPTable
Definition ObjectMgr.h:1641

References _baseXPTable.

◆ GetBreadcrumbsForQuest()

std::vector< uint32 > const * ObjectMgr::GetBreadcrumbsForQuest ( uint32  questId) const
inline
1161 {
1162 auto itr = _breadcrumbsForQuest.find(questId);
1163 if (itr != _breadcrumbsForQuest.end())
1164 return &itr->second;
1165
1166 return nullptr;
1167 }
BreadcrumbQuestMap _breadcrumbsForQuest
Definition ObjectMgr.h:1158

References _breadcrumbsForQuest.

◆ GetBroadcastText()

BroadcastText const * ObjectMgr::GetBroadcastText ( uint32  id) const
inline
1230 {
1231 BroadcastTextContainer::const_iterator itr = _broadcastTextStore.find(id);
1232 if (itr != _broadcastTextStore.end())
1233 return &itr->second;
1234 return nullptr;
1235 }
BroadcastTextContainer _broadcastTextStore
Definition ObjectMgr.h:1684

References _broadcastTextStore.

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

◆ GetClassTrainers()

std::vector< Trainer::Trainer const * > const & ObjectMgr::GetClassTrainers ( uint8  classId) const
inline
1447{ return _classTrainers.at(classId); }
std::unordered_map< uint8, std::vector< Trainer::Trainer const * > > _classTrainers
Definition ObjectMgr.h:1701

References _classTrainers.

◆ GetCreatureAddon()

CreatureAddon const * ObjectMgr::GetCreatureAddon ( ObjectGuid::LowType  lowguid)
1432{
1433 CreatureAddonContainer::const_iterator itr = _creatureAddonStore.find(lowguid);
1434 if (itr != _creatureAddonStore.end())
1435 return &(itr->second);
1436
1437 return nullptr;
1438}
CreatureAddonContainer _creatureAddonStore
Definition ObjectMgr.h:1664

References _creatureAddonStore.

◆ GetCreatureBaseStats()

CreatureBaseStats const * ObjectMgr::GetCreatureBaseStats ( uint8  level,
uint8  unitClass 
)
10774{
10775 CreatureBaseStatsContainer::const_iterator it = _creatureBaseStatsStore.find(MAKE_PAIR16(level, unitClass));
10776
10777 if (it != _creatureBaseStatsStore.end())
10778 return &(it->second);
10779
10780 struct DefaultCreatureBaseStats : public CreatureBaseStats
10781 {
10782 DefaultCreatureBaseStats()
10783 {
10784 BaseArmor = 1;
10785 for (uint8 j = 0; j < MAX_EXPANSIONS; ++j)
10786 {
10787 BaseHealth[j] = 1;
10788 BaseDamage[j] = 0.0f;
10789 }
10790 BaseMana = 0;
10791 AttackPower = 0;
10792 RangedAttackPower = 0;
10793 Strength = 0;
10794 Agility = 0;
10795 Stamina = 0;
10796 Intellect = 0;
10797 Spirit = 0;
10798 }
10799 };
10800 static const DefaultCreatureBaseStats defStats;
10801 return &defStats;
10802}
uint16 MAKE_PAIR16(uint8 l, uint8 h)
Definition ObjectDefines.h:83
CreatureBaseStatsContainer _creatureBaseStatsStore
Definition ObjectMgr.h:1625

References _creatureBaseStatsStore, MAKE_PAIR16(), and MAX_EXPANSIONS.

Referenced by AddCreData().

◆ GetCreatureData()

CreatureData const * ObjectMgr::GetCreatureData ( ObjectGuid::LowType  spawnId) const
inline
1238 {
1239 CreatureDataContainer::const_iterator itr = _creatureDataStore.find(spawnId);
1240 if (itr == _creatureDataStore.end()) return nullptr;
1241 return &itr->second;
1242 }

References _creatureDataStore.

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

◆ GetCreatureLocale()

CreatureLocale const * ObjectMgr::GetCreatureLocale ( uint32  entry) const
inline
1294 {
1295 CreatureLocaleContainer::const_iterator itr = _creatureLocaleStore.find(entry);
1296 if (itr == _creatureLocaleStore.end()) return nullptr;
1297 return &itr->second;
1298 }
CreatureLocaleContainer _creatureLocaleStore
Definition ObjectMgr.h:1672

References _creatureLocaleStore.

◆ GetCreatureModelInfo()

CreatureModelInfo const * ObjectMgr::GetCreatureModelInfo ( uint32  modelId) const
1636{
1637 CreatureModelContainer::const_iterator itr = _creatureModelStore.find(modelId);
1638 if (itr != _creatureModelStore.end())
1639 return &(itr->second);
1640
1641 return nullptr;
1642}
CreatureModelContainer _creatureModelStore
Definition ObjectMgr.h:1663

References _creatureModelStore.

Referenced by GetCreatureModelRandomGender(), and LoadCreatureTemplateModels().

◆ GetCreatureModelRandomGender()

CreatureModelInfo const * ObjectMgr::GetCreatureModelRandomGender ( CreatureModel model,
CreatureTemplate const *  creatureTemplate 
) const
1679{
1680 CreatureModelInfo const* modelInfo = GetCreatureModelInfo(model->CreatureDisplayID);
1681 if (!modelInfo)
1682 return nullptr;
1683
1684 // If a model for another gender exists, 50% chance to use it
1685 if (modelInfo->modelid_other_gender != 0 && urand(0, 1) == 0)
1686 {
1687 CreatureModelInfo const* minfo_tmp = GetCreatureModelInfo(modelInfo->modelid_other_gender);
1688 if (!minfo_tmp)
1689 LOG_ERROR("sql.sql", "Model (Entry: {}) has modelid_other_gender {} not found in table `creature_model_info`. ", model->CreatureDisplayID, modelInfo->modelid_other_gender);
1690 else
1691 {
1692 // Model ID changed
1693 model->CreatureDisplayID = modelInfo->modelid_other_gender;
1694 if (creatureTemplate)
1695 {
1696 auto itr = std::find_if(creatureTemplate->Models.begin(), creatureTemplate->Models.end(), [&](CreatureModel const& templateModel)
1697 {
1698 return templateModel.CreatureDisplayID == modelInfo->modelid_other_gender;
1699 });
1700 if (itr != creatureTemplate->Models.end())
1701 *model = *itr;
1702 }
1703 return minfo_tmp;
1704 }
1705 }
1706
1707 return modelInfo;
1708}
CreatureModelInfo const * GetCreatureModelInfo(uint32 modelId) const
Definition ObjectMgr.cpp:1635
Definition CreatureData.h:389
uint32 modelid_other_gender
Definition CreatureData.h:393
uint32 CreatureDisplayID
Definition CreatureData.h:180

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
1450{
1452}
std::unordered_map< ObjectGuid::LowType, CreatureMovementData > _creatureMovementOverrides
Definition ObjectMgr.h:1666
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
1014 {
1015 return _creatureQuestInvolvedRelations.equal_range(creature_entry);
1016 }
QuestRelations _creatureQuestInvolvedRelations
Definition ObjectMgr.h:1586

References _creatureQuestInvolvedRelations.

◆ GetCreatureQuestInvolvedRelationMap()

QuestRelations * ObjectMgr::GetCreatureQuestInvolvedRelationMap ( )
inline
1004 {
1006 }

References _creatureQuestInvolvedRelations.

◆ GetCreatureQuestItemList()

CreatureQuestItemList const * ObjectMgr::GetCreatureQuestItemList ( uint32  id) const
inline
832 {
833 CreatureQuestItemMap::const_iterator itr = _creatureQuestItemStore.find(id);
834 if (itr != _creatureQuestItemStore.end())
835 return &itr->second;
836 return nullptr;
837 }
CreatureQuestItemMap _creatureQuestItemStore
Definition ObjectMgr.h:1669

References _creatureQuestItemStore.

◆ GetCreatureQuestItemMap()

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

References _creatureQuestItemStore.

◆ GetCreatureQuestRelationBounds()

QuestRelationBounds ObjectMgr::GetCreatureQuestRelationBounds ( uint32  creature_entry)
inline
1009 {
1010 return _creatureQuestRelations.equal_range(creature_entry);
1011 }
QuestRelations _creatureQuestRelations
Definition ObjectMgr.h:1585

References _creatureQuestRelations.

◆ GetCreatureQuestRelationMap()

QuestRelations * ObjectMgr::GetCreatureQuestRelationMap ( )
inline
999 {
1001 }

References _creatureQuestRelations.

◆ GetCreatureTemplate()

◆ GetCreatureTemplateAddon()

CreatureAddon const * ObjectMgr::GetCreatureTemplateAddon ( uint32  entry)
1441{
1442 CreatureAddonContainer::const_iterator itr = _creatureTemplateAddonStore.find(entry);
1443 if (itr != _creatureTemplateAddonStore.end())
1444 return &(itr->second);
1445
1446 return nullptr;
1447}
CreatureAddonContainer _creatureTemplateAddonStore
Definition ObjectMgr.h:1665

References _creatureTemplateAddonStore.

◆ GetCreatureTemplates()

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

References _creatureTemplateStore.

Referenced by LoadCreatureClassLevelStats(), and LoadNPCSpellClickSpells().

◆ GetDBCLocaleIndex()

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

References DBCLocaleIndex.

◆ GetDefaultSpawnGroup()

SpawnGroupTemplateData const * ObjectMgr::GetDefaultSpawnGroup ( ) const
inline
1285{ return &_spawnGroupDataStore.at(0); }

References _spawnGroupDataStore.

◆ GetDungeonEncounterList()

DungeonEncounterList const * ObjectMgr::GetDungeonEncounterList ( uint32  mapId,
Difficulty  difficulty 
)
inline
953 {
954 std::unordered_map<uint32, DungeonEncounterList>::const_iterator itr = _dungeonEncounterStore.find(MAKE_PAIR32(mapId, difficulty));
955 if (itr != _dungeonEncounterStore.end())
956 return &itr->second;
957 return nullptr;
958 }

References _dungeonEncounterStore, and MAKE_PAIR32().

◆ GetEquipmentInfo()

EquipmentInfo const * ObjectMgr::GetEquipmentInfo ( uint32  entry,
int8 id 
)
1455{
1456 EquipmentInfoContainer::const_iterator itr = _equipmentInfoStore.find(entry);
1457 if (itr == _equipmentInfoStore.end())
1458 return nullptr;
1459
1460 if (itr->second.empty())
1461 return nullptr;
1462
1463 if (id == -1) // select a random element
1464 {
1465 EquipmentInfoContainerInternal::const_iterator ritr = itr->second.begin();
1466 std::advance(ritr, urand(0u, itr->second.size() - 1));
1467 id = std::distance(itr->second.begin(), ritr) + 1;
1468 return &ritr->second;
1469 }
1470 else
1471 {
1472 EquipmentInfoContainerInternal::const_iterator itr2 = itr->second.find(id);
1473 if (itr2 != itr->second.end())
1474 return &itr2->second;
1475 }
1476
1477 return nullptr;
1478}
EquipmentInfoContainer _equipmentInfoStore
Definition ObjectMgr.h:1670

References _equipmentInfoStore, and urand().

Referenced by LoadCreatureDataFromDB(), and LoadCreatures().

◆ GetFishingBaseSkillLevel()

int32 ObjectMgr::GetFishingBaseSkillLevel ( uint32  entry) const
inline
1127 {
1128 FishingBaseSkillContainer::const_iterator itr = _fishingBaseForAreaStore.find(entry);
1129 return itr != _fishingBaseForAreaStore.end() ? itr->second : 0;
1130 }

References _fishingBaseForAreaStore.

◆ GetGameObjectAddon()

GameObjectAddon const * ObjectMgr::GetGameObjectAddon ( ObjectGuid::LowType  lowguid)
1423{
1424 GameObjectAddonContainer::const_iterator itr = _gameObjectAddonStore.find(lowguid);
1425 if (itr != _gameObjectAddonStore.end())
1426 return &(itr->second);
1427
1428 return nullptr;
1429}
GameObjectAddonContainer _gameObjectAddonStore
Definition ObjectMgr.h:1667

References _gameObjectAddonStore.

◆ GetGameObjectData()

GameObjectData const * ObjectMgr::GetGameObjectData ( ObjectGuid::LowType  spawnId) const
inline
1273 {
1274 GameObjectDataContainer::const_iterator itr = _gameObjectDataStore.find(spawnId);
1275 if (itr == _gameObjectDataStore.end()) return nullptr;
1276 return &itr->second;
1277 }

References _gameObjectDataStore.

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

◆ GetGameObjectLocale()

GameObjectLocale const * ObjectMgr::GetGameObjectLocale ( uint32  entry) const
inline
1300 {
1301 GameObjectLocaleContainer::const_iterator itr = _gameObjectLocaleStore.find(entry);
1302 if (itr == _gameObjectLocaleStore.end()) return nullptr;
1303 return &itr->second;
1304 }
GameObjectLocaleContainer _gameObjectLocaleStore
Definition ObjectMgr.h:1676

References _gameObjectLocaleStore.

◆ GetGameObjectQuestItemList()

GameObjectQuestItemList const * ObjectMgr::GetGameObjectQuestItemList ( uint32  id) const
inline
823 {
824 GameObjectQuestItemMap::const_iterator itr = _gameObjectQuestItemStore.find(id);
825 if (itr != _gameObjectQuestItemStore.end())
826 return &itr->second;
827 return nullptr;
828 }
GameObjectQuestItemMap _gameObjectQuestItemStore
Definition ObjectMgr.h:1668

References _gameObjectQuestItemStore.

◆ GetGameObjectQuestItemMap()

GameObjectQuestItemMap const * ObjectMgr::GetGameObjectQuestItemMap ( ) const
inline

◆ GetGameObjectSummonGroup()

std::vector< GameObjectSummonData > const * ObjectMgr::GetGameObjectSummonGroup ( uint32  summonerId,
SummonerType  summonerType,
uint8  group 
) const
inline
1221 {
1222 GameObjectSummonDataContainer::const_iterator itr = _goSummonDataStore.find(TempSummonGroupKey(summonerId, summonerType, group));
1223 if (itr != _goSummonDataStore.end())
1224 return &itr->second;
1225
1226 return nullptr;
1227 }
GameObjectSummonDataContainer _goSummonDataStore
Stores gameobject summon data grouped by summoner's entry, summoner's type and group id.
Definition ObjectMgr.h:1682
Key for storing temp summon data in TempSummonDataContainer.
Definition ObjectMgr.h:67

References _goSummonDataStore.

◆ GetGameObjectTemplate()

GameObjectTemplate const * ObjectMgr::GetGameObjectTemplate ( uint32  entry)
11115{
11116 GameObjectTemplateContainer::const_iterator itr = _gameObjectTemplateStore.find(entry);
11117 if (itr != _gameObjectTemplateStore.end())
11118 return &(itr->second);
11119
11120 return nullptr;
11121}
GameObjectTemplateContainer _gameObjectTemplateStore
Definition ObjectMgr.h:1677

References _gameObjectTemplateStore.

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

◆ GetGameObjectTemplateAddon()

GameObjectTemplateAddon const * ObjectMgr::GetGameObjectTemplateAddon ( uint32  entry) const
11130{
11131 auto itr = _gameObjectTemplateAddonStore.find(entry);
11132 if (itr != _gameObjectTemplateAddonStore.end())
11133 return &itr->second;
11134
11135 return nullptr;
11136}
GameObjectTemplateAddonContainer _gameObjectTemplateAddonStore
Definition ObjectMgr.h:1678

References _gameObjectTemplateAddonStore.

◆ GetGameObjectTemplates()

GameObjectTemplateContainer const * ObjectMgr::GetGameObjectTemplates ( ) const
inline

◆ GetGameTele() [1/2]

GameTele const * ObjectMgr::GetGameTele ( std::string_view  name,
bool  exactSearch = false 
) const
9920{
9921 // explicit name case
9922 std::wstring wname;
9923 if (!Utf8toWStr(name, wname))
9924 return nullptr;
9925
9926 // converting string that we try to find to lower case
9927 wstrToLower(wname);
9928
9929 // Alternative first GameTele what contains wnameLow as substring in case no GameTele location found
9930 const GameTele* alt = nullptr;
9931 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9932 {
9933 if (itr->second.wnameLow == wname)
9934 return &itr->second;
9935 else if (!exactSearch && !alt && itr->second.wnameLow.find(wname) != std::wstring::npos)
9936 alt = &itr->second;
9937 }
9938
9939 return alt;
9940}
Definition ObjectMgr.h:135

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

◆ GetGameTele() [2/2]

GameTele const * ObjectMgr::GetGameTele ( uint32  id) const
inline
1436 {
1437 GameTeleContainer::const_iterator itr = _gameTeleStore.find(id);
1438 if (itr == _gameTeleStore.end()) return nullptr;
1439 return &itr->second;
1440 }

References _gameTeleStore.

◆ GetGameTeleMap()

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

References _gameTeleStore.

◆ GetGenerator()

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

◆ GetGoBackTrigger()

AreaTriggerTeleport const * ObjectMgr::GetGoBackTrigger ( uint32  Map) const
7647{
7648 bool useParentDbValue = false;
7649 uint32 parentId = 0;
7650 MapEntry const* mapEntry = sMapStore.LookupEntry(Map);
7651 if (!mapEntry || mapEntry->entrance_map < 0)
7652 return nullptr;
7653
7654 if (mapEntry->IsDungeon())
7655 {
7656 InstanceTemplate const* iTemplate = sObjectMgr->GetInstanceTemplate(Map);
7657
7658 if (!iTemplate)
7659 return nullptr;
7660
7661 parentId = iTemplate->Parent;
7662 useParentDbValue = true;
7663 }
7664
7665 uint32 entrance_map = uint32(mapEntry->entrance_map);
7666 for (AreaTriggerTeleportContainer::const_iterator itr = _areaTriggerTeleportStore.begin(); itr != _areaTriggerTeleportStore.end(); ++itr)
7667 if ((!useParentDbValue && itr->second.target_mapId == entrance_map) || (useParentDbValue && itr->second.target_mapId == parentId))
7668 {
7669 AreaTrigger const* atEntry = GetAreaTrigger(itr->first);
7670 if (atEntry && atEntry->map == Map)
7671 return &itr->second;
7672 }
7673 return nullptr;
7674}
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
AreaTrigger const * GetAreaTrigger(uint32 trigger) const
Definition ObjectMgr.h:868
Definition ObjectMgr.h:423
uint32 map
Definition ObjectMgr.h:425
Definition Map.h:124
uint32 Parent
Definition Map.h:125
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
994 {
995 return _goQuestInvolvedRelations.equal_range(go_entry);
996 }
QuestRelations _goQuestInvolvedRelations
Definition ObjectMgr.h:1584

References _goQuestInvolvedRelations.

◆ GetGOQuestInvolvedRelationMap()

QuestRelations * ObjectMgr::GetGOQuestInvolvedRelationMap ( )
inline
984 {
986 }

References _goQuestInvolvedRelations.

◆ GetGOQuestRelationBounds()

QuestRelationBounds ObjectMgr::GetGOQuestRelationBounds ( uint32  go_entry)
inline
989 {
990 return _goQuestRelations.equal_range(go_entry);
991 }
QuestRelations _goQuestRelations
Definition ObjectMgr.h:1583

References _goQuestRelations.

◆ GetGOQuestRelationMap()

QuestRelations * ObjectMgr::GetGOQuestRelationMap ( )
inline
979 {
980 return &_goQuestRelations;
981 }

References _goQuestRelations.

◆ GetGossipMenuItemsLocale()

GossipMenuItemsLocale const * ObjectMgr::GetGossipMenuItemsLocale ( uint32  entry) const
inline
1330 {
1331 GossipMenuItemsLocaleContainer::const_iterator itr = _gossipMenuItemsLocaleStore.find(entry);
1332 if (itr == _gossipMenuItemsLocaleStore.end()) return nullptr;
1333 return &itr->second;
1334 }
GossipMenuItemsLocaleContainer _gossipMenuItemsLocaleStore
Definition ObjectMgr.h:1696

References _gossipMenuItemsLocaleStore.

◆ GetGossipMenuItemsMapBounds()

GossipMenuItemsMapBounds ObjectMgr::GetGossipMenuItemsMapBounds ( uint32  uiMenuId) const
inline
1483 {
1484 return _gossipMenuItemsStore.equal_range(uiMenuId);
1485 }
GossipMenuItemsContainer _gossipMenuItemsStore
Definition ObjectMgr.h:1578

References _gossipMenuItemsStore.

◆ GetGossipMenuItemsMapBoundsNonConst()

GossipMenuItemsMapBoundsNonConst ObjectMgr::GetGossipMenuItemsMapBoundsNonConst ( uint32  uiMenuId)
inline
1487 {
1488 return _gossipMenuItemsStore.equal_range(uiMenuId);
1489 }

References _gossipMenuItemsStore.

◆ GetGossipMenusMapBounds()

GossipMenusMapBounds ObjectMgr::GetGossipMenusMapBounds ( uint32  uiMenuId) const
inline
1473 {
1474 return _gossipMenusStore.equal_range(uiMenuId);
1475 }
GossipMenusContainer _gossipMenusStore
Definition ObjectMgr.h:1577

References _gossipMenusStore.

◆ GetGossipMenusMapBoundsNonConst()

GossipMenusMapBoundsNonConst ObjectMgr::GetGossipMenusMapBoundsNonConst ( uint32  uiMenuId)
inline
1478 {
1479 return _gossipMenusStore.equal_range(uiMenuId);
1480 }

References _gossipMenusStore.

◆ GetGossipText()

GossipText const * ObjectMgr::GetGossipText ( uint32  Text_ID) const
6689{
6690 GossipTextContainer::const_iterator itr = _gossipTextStore.find(Text_ID);
6691 if (itr != _gossipTextStore.end())
6692 return &itr->second;
6693 return nullptr;
6694}
GossipTextContainer _gossipTextStore
Definition ObjectMgr.h:1565

References _gossipTextStore.

Referenced by LoadGossipMenu().

◆ GetGridObjectGuids()

CellObjectGuids const & ObjectMgr::GetGridObjectGuids ( uint16  mapid,
uint8  spawnMode,
uint32  gridId 
)
inline
1183 {
1184 MapObjectGuids::const_iterator itr1 = _mapObjectGuidsStore.find(MAKE_PAIR32(mapid, spawnMode));
1185 if (itr1 != _mapObjectGuidsStore.end())
1186 {
1187 CellObjectGuidsMap::const_iterator itr2 = itr1->second.find(gridId);
1188 if (itr2 != itr1->second.end())
1189 return itr2->second;
1190 }
1191 return _emptyCellObjectGuids;
1192 }
CellObjectGuids _emptyCellObjectGuids
Definition ObjectMgr.h:1658

References _emptyCellObjectGuids, _mapObjectGuidsStore, and MAKE_PAIR32().

◆ GetGuidSequenceGenerator()

template<HighGuid high>
ObjectGuidGeneratorBase & ObjectMgr::GetGuidSequenceGenerator ( )
inlineprivate
1546 {
1547 auto itr = _guidGenerators.find(high);
1548 if (itr == _guidGenerators.end())
1549 itr = _guidGenerators.insert(std::make_pair(high, std::unique_ptr<ObjectGuidGenerator<high>>(new ObjectGuidGenerator<high>()))).first;
1550
1551 return *itr->second;
1552 }
Definition ObjectGuid.h:297
std::map< HighGuid, std::unique_ptr< ObjectGuidGeneratorBase > > _guidGenerators
Definition ObjectMgr.h:1554

References _guidGenerators.

◆ GetInstanceTemplate()

InstanceTemplate const * ObjectMgr::GetInstanceTemplate ( uint32  mapId)
6595{
6596 InstanceTemplateContainer::const_iterator itr = _instanceTemplateStore.find(uint16(mapID));
6597 if (itr != _instanceTemplateStore.end())
6598 return &(itr->second);
6599
6600 return nullptr;
6601}
InstanceTemplateContainer _instanceTemplateStore
Definition ObjectMgr.h:1614

References _instanceTemplateStore.

◆ GetItemLocale()

ItemLocale const * ObjectMgr::GetItemLocale ( uint32  entry) const
inline
1306 {
1307 ItemLocaleContainer::const_iterator itr = _itemLocaleStore.find(entry);
1308 if (itr == _itemLocaleStore.end()) return nullptr;
1309 return &itr->second;
1310 }
ItemLocaleContainer _itemLocaleStore
Definition ObjectMgr.h:1687

References _itemLocaleStore.

◆ GetItemSetNameEntry()

ItemSetNameEntry const * ObjectMgr::GetItemSetNameEntry ( uint32  itemId)
inline
794 {
795 ItemSetNameContainer::iterator itr = _itemSetNameStore.find(itemId);
796 if (itr != _itemSetNameStore.end())
797 return &itr->second;
798 return nullptr;
799 }
ItemSetNameContainer _itemSetNameStore
Definition ObjectMgr.h:1654

References _itemSetNameStore.

◆ GetItemSetNameLocale()

ItemSetNameLocale const * ObjectMgr::GetItemSetNameLocale ( uint32  entry) const
inline
1312 {
1313 ItemSetNameLocaleContainer::const_iterator itr = _itemSetNameLocaleStore.find(entry);
1314 if (itr == _itemSetNameLocaleStore.end())return nullptr;
1315 return &itr->second;
1316 }
ItemSetNameLocaleContainer _itemSetNameLocaleStore
Definition ObjectMgr.h:1688

References _itemSetNameLocaleStore.

◆ GetItemTemplate()

ItemTemplate const * ObjectMgr::GetItemTemplate ( uint32  entry)
3934{
3935 return entry < _itemTemplateStoreFast.size() ? _itemTemplateStoreFast[entry] : nullptr;
3936}
std::vector< ItemTemplate * > _itemTemplateStoreFast
Definition ObjectMgr.h:1686

References _itemTemplateStoreFast.

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

◆ GetItemTemplateStore()

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

References _itemTemplateStore.

◆ GetItemTemplateStoreFast()

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

References _itemTemplateStoreFast.

◆ GetLegacySpawnGroup()

SpawnGroupTemplateData const * ObjectMgr::GetLegacySpawnGroup ( ) const
inline
1286{ return &_spawnGroupDataStore.at(1); }

References _spawnGroupDataStore.

◆ GetLinkedRespawnGuid()

ObjectGuid ObjectMgr::GetLinkedRespawnGuid ( ObjectGuid  guid) const
inline
1264 {
1265 LinkedRespawnContainer::const_iterator itr = _linkedRespawnStore.find(guid);
1266 if (itr == _linkedRespawnStore.end())
1267 return ObjectGuid::Empty;
1268 return itr->second;
1269 }
static ObjectGuid const Empty
Definition ObjectGuid.h:120
LinkedRespawnContainer _linkedRespawnStore
Definition ObjectMgr.h:1671

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
1500 {
1501 if (data.size() > std::size_t(loc_idx) && !data[loc_idx].empty())
1502 value = data[loc_idx];
1503 }

◆ GetLocaleString() [2/2]

◆ GetMailLevelReward()

MailLevelReward const * ObjectMgr::GetMailLevelReward ( uint32  level,
uint32  raceMask 
)
inline
1170 {
1171 MailLevelRewardContainer::const_iterator map_itr = _mailLevelRewardStore.find(level);
1172 if (map_itr == _mailLevelRewardStore.end())
1173 return nullptr;
1174
1175 for (const auto & set_itr : map_itr->second)
1176 if (set_itr.raceMask & raceMask)
1177 return &set_itr;
1178
1179 return nullptr;
1180 }
MailLevelRewardContainer _mailLevelRewardStore
Definition ObjectMgr.h:1623

References _mailLevelRewardStore.

◆ GetMapEntranceTrigger()

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

Searches for the areatrigger which teleports players to the given map

7680{
7681 for (AreaTriggerTeleportContainer::const_iterator itr = _areaTriggerTeleportStore.begin(); itr != _areaTriggerTeleportStore.end(); ++itr)
7682 {
7683 if (itr->second.target_mapId == Map) // Id is used to determine correct Scarlet Monastery instance
7684 {
7685 // xinef: no need to check, already done at loading
7686 //AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(itr->first);
7687 //if (atEntry)
7688 return &itr->second;
7689 }
7690 }
7691 return nullptr;
7692}

References _areaTriggerTeleportStore.

◆ GetMapObjectGuids()

CellObjectGuidsMap const & ObjectMgr::GetMapObjectGuids ( uint16  mapid,
uint8  spawnMode 
)
inline
1195 {
1196 MapObjectGuids::const_iterator itr1 = _mapObjectGuidsStore.find(MAKE_PAIR32(mapid, spawnMode));
1197 if (itr1 != _mapObjectGuidsStore.end())
1198 return itr1->second;
1200 }
CellObjectGuidsMap _emptyCellObjectGuidsMap
Definition ObjectMgr.h:1657

References _emptyCellObjectGuidsMap, _mapObjectGuidsStore, and MAKE_PAIR32().

◆ GetModelForShapeshift()

uint32 ObjectMgr::GetModelForShapeshift ( ShapeshiftForm  form,
Player player 
) const
1890{
1891 uint8 customizationID;
1892
1893 if (player->GetTeamId() == TEAM_ALLIANCE)
1894 customizationID = player->GetByteValue(PLAYER_BYTES, 3); // Use Hair Color
1895 else
1896 customizationID = player->GetByteValue(PLAYER_BYTES, 0); // Use Skin Color
1897
1898 // getGender() tracks the active display model; real gender lives in PLAYER_BYTES_3
1900
1901 auto itr = _playerShapeshiftModel.find(std::make_tuple(form, player->getRace(), customizationID, gender));
1902 if (itr != _playerShapeshiftModel.end())
1903 return itr->second; // Explicit combination
1904
1905 itr = _playerShapeshiftModel.find(std::make_tuple(form, player->getRace(), customizationID, GENDER_NONE));
1906 if (itr != _playerShapeshiftModel.end())
1907 return itr->second; // Combination applied to both genders
1908
1909 itr = _playerShapeshiftModel.find(std::make_tuple(form, player->getRace(), 255, gender));
1910 if (itr != _playerShapeshiftModel.end())
1911 return itr->second; // Default gender-dependent model
1912
1913 itr = _playerShapeshiftModel.find(std::make_tuple(form, player->getRace(), 255, GENDER_NONE));
1914 if (itr != _playerShapeshiftModel.end())
1915 return itr->second; // Last resort
1916
1917 LOG_DEBUG("entities.player", "ShapeshiftForm {} with RaceID ({}) have no shapeshift model data defined, using fallback data.", form, player->getRace());
1918 return 0;
1919}
@ PLAYER_BYTES_3_OFFSET_GENDER
Definition Player.h:513
@ GENDER_NONE
Definition SharedDefines.h:63
@ TEAM_ALLIANCE
Definition SharedDefines.h:748
@ PLAYER_BYTES_3
Definition UpdateFields.h:183
@ PLAYER_BYTES
Definition UpdateFields.h:181
PlayerShapeshiftModelMap _playerShapeshiftModel
Definition ObjectMgr.h:1719
uint8 GetByteValue(uint16 index, uint8 offset) const
Definition Object.cpp:312
TeamId GetTeamId(bool original=false) const
Definition Player.h:2131
uint8 getRace(bool original=false) const
Definition Unit.cpp:17047

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

◆ GetModelForTotem()

uint32 ObjectMgr::GetModelForTotem ( SummonSlot  totemSlot,
Races  race 
) const
1835{
1836 auto itr = _playerTotemModel.find(std::make_pair(totemSlot, race));
1837 if (itr != _playerTotemModel.end())
1838 return itr->second;
1839
1840 LOG_ERROR("misc", "TotemSlot {} with RaceID ({}) have no totem model data defined, set to default model.", totemSlot, race);
1841 return 0;
1842}
PlayerTotemModelMap _playerTotemModel
Definition ObjectMgr.h:1717

References _playerTotemModel, and LOG_ERROR.

◆ GetModuleString() [1/2]

ModuleString const * ObjectMgr::GetModuleString ( std::string  module,
uint32  id 
) const
inline
1380 {
1381 std::pair<std::string, uint32> pairKey = std::make_pair(module, id);
1382 ModuleStringContainer::const_iterator itr = _moduleStringStore.find(pairKey);
1383 if (itr == _moduleStringStore.end())
1384 return nullptr;
1385
1386 return &itr->second;
1387 }
ModuleStringContainer _moduleStringStore
Definition ObjectMgr.h:1694

References _moduleStringStore.

Referenced by GetModuleString().

◆ GetModuleString() [2/2]

std::string const * ObjectMgr::GetModuleString ( std::string  module,
uint32  id,
LocaleConstant  locale 
) const
9659{
9660 ModuleString const* ms = GetModuleString(module, id);
9661 if (ms && !ms->Content.empty())
9662 {
9663 if (ms->Content.size() > size_t(locale) && !ms->Content[locale].empty())
9664 return &ms->Content[locale];
9665
9666 return &ms->Content[DEFAULT_LOCALE];
9667 }
9668
9669 LOG_ERROR("sql.sql", "Module string module {} id {} not found in DB.", module, id);
9670
9671 return (std::string*)"error";
9672}
ModuleString const * GetModuleString(std::string module, uint32 id) const
Definition ObjectMgr.h:1379
Definition ObjectMgr.h:499
std::vector< std::string > Content
Definition ObjectMgr.h:500

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

◆ GetNearestTaxiNode() [1/2]

uint32 ObjectMgr::GetNearestTaxiNode ( float  x,
float  y,
float  z,
uint32  mapid,
uint32  teamId 
)
7264{
7265 bool found = false;
7266 float dist = 10000;
7267 uint32 id = 0;
7268
7269 for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
7270 {
7271 TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i);
7272
7273 if (!node || node->map_id != mapid || (!node->MountCreatureID[teamId == TEAM_ALLIANCE ? 1 : 0] && node->MountCreatureID[0] != 32981)) // dk flight
7274 continue;
7275
7276 uint8 field = (uint8)((i - 1) / 32);
7277 uint32 submask = 1 << ((i - 1) % 32);
7278
7279 // skip not taxi network nodes
7280 if (field >= TaxiMaskSize || (sTaxiNodesMask[field] & submask) == 0)
7281 {
7282 continue;
7283 }
7284
7285 float dist2 = (node->x - x) * (node->x - x) + (node->y - y) * (node->y - y) + (node->z - z) * (node->z - z);
7286 if (found)
7287 {
7288 if (dist2 < dist)
7289 {
7290 dist = dist2;
7291 id = i;
7292 }
7293 }
7294 else
7295 {
7296 found = true;
7297 dist = dist2;
7298 id = i;
7299 }
7300 }
7301
7302 return id;
7303}
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.

Referenced by GetNearestTaxiNode().

◆ GetNearestTaxiNode() [2/2]

uint32 ObjectMgr::GetNearestTaxiNode ( WorldLocation const &  loc,
uint32  teamId 
)
7259{
7260 return GetNearestTaxiNode(loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetMapId(), teamId);
7261}
uint32 GetNearestTaxiNode(float x, float y, float z, uint32 mapid, uint32 teamId)
Definition ObjectMgr.cpp:7263

References WorldLocation::GetMapId(), GetNearestTaxiNode(), Position::GetPositionX(), Position::GetPositionY(), and Position::GetPositionZ().

◆ GetNpcTextLocale()

NpcTextLocale const * ObjectMgr::GetNpcTextLocale ( uint32  entry) const
inline
1354 {
1355 NpcTextLocaleContainer::const_iterator itr = _npcTextLocaleStore.find(entry);
1356 if (itr == _npcTextLocaleStore.end()) return nullptr;
1357 return &itr->second;
1358 }
NpcTextLocaleContainer _npcTextLocaleStore
Definition ObjectMgr.h:1692

References _npcTextLocaleStore.

◆ GetNpcVendorItemList()

VendorItemData const * ObjectMgr::GetNpcVendorItemList ( uint32  entry) const
inline
1450 {
1451 CacheVendorItemContainer::const_iterator iter = _cacheVendorItemStore.find(entry);
1452 if (iter == _cacheVendorItemStore.end())
1453 return nullptr;
1454
1455 return &iter->second;
1456 }

References _cacheVendorItemStore.

Referenced by IsVendorItemValid().

◆ GetPageText()

PageText const * ObjectMgr::GetPageText ( uint32  pageEntry)
6511{
6512 PageTextContainer::const_iterator itr = _pageTextStore.find(pageEntry);
6513 if (itr != _pageTextStore.end())
6514 return &(itr->second);
6515
6516 return nullptr;
6517}
PageTextContainer _pageTextStore
Definition ObjectMgr.h:1613

References _pageTextStore.

Referenced by LoadGameObjectTemplate(), and LoadItemTemplates().

◆ GetPageTextLocale()

PageTextLocale const * ObjectMgr::GetPageTextLocale ( uint32  entry) const
inline
1318 {
1319 PageTextLocaleContainer::const_iterator itr = _pageTextLocaleStore.find(entry);
1320 if (itr == _pageTextLocaleStore.end()) return nullptr;
1321 return &itr->second;
1322 }
PageTextLocaleContainer _pageTextLocaleStore
Definition ObjectMgr.h:1693

References _pageTextLocaleStore.

◆ GetPetLevelInfo()

PetLevelInfo const * ObjectMgr::GetPetLevelInfo ( uint32  creature_id,
uint8  level 
) const
4300{
4301 if (level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4302 level = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
4303
4304 PetLevelInfoContainer::const_iterator itr = _petInfoStore.find(creature_id);
4305 if (itr == _petInfoStore.end())
4306 return nullptr;
4307
4308 return &itr->second[level - 1]; // data for level 1 stored in [0] array element, ...
4309}

References _petInfoStore, CONFIG_MAX_PLAYER_LEVEL, and sWorld.

◆ GetPlayerClassInfo()

PlayerClassInfo const * ObjectMgr::GetPlayerClassInfo ( uint32  class_) const
inline
806 {
807 if (class_ >= MAX_CLASSES)
808 return nullptr;
809 return _playerClassInfo[class_];
810 }

References _playerClassInfo, and MAX_CLASSES.

◆ GetPlayerClassLevelInfo()

void ObjectMgr::GetPlayerClassLevelInfo ( uint32  class_,
uint8  level,
PlayerClassLevelInfo info 
) const
4977{
4978 if (level < 1 || class_ >= MAX_CLASSES)
4979 return;
4980
4981 PlayerClassInfo const* pInfo = _playerClassInfo[class_];
4982
4983 if (level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4984 level = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
4985
4986 *info = pInfo->levelInfo[level - 1];
4987}
Definition Player.h:283

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

◆ GetPlayerInfo()

PlayerInfo const * ObjectMgr::GetPlayerInfo ( uint32  race,
uint32  class_ 
) const
11161{
11162 if (race >= sRaceMgr->GetMaxRaces())
11163 return nullptr;
11164 if (class_ >= MAX_CLASSES)
11165 return nullptr;
11166 PlayerInfo const* info = _playerInfo[race][class_];
11167 if (!info)
11168 return nullptr;
11169 return info;
11170}
Definition Player.h:322

References _playerInfo, MAX_CLASSES, and sRaceMgr.

◆ GetPlayerLevelInfo()

void ObjectMgr::GetPlayerLevelInfo ( uint32  race,
uint32  class_,
uint8  level,
PlayerLevelInfo info 
) const
4990{
4991 if (level < 1 || race >= sRaceMgr->GetMaxRaces() || class_ >= MAX_CLASSES)
4992 return;
4993
4994 PlayerInfo const* pInfo = _playerInfo[race][class_];
4995 if (!pInfo)
4996 return;
4997
4998 if (level <= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4999 *info = pInfo->levelInfo[level - 1];
5000 else
5001 BuildPlayerLevelInfo(race, class_, level, info);
5002}
void BuildPlayerLevelInfo(uint8 race, uint8 class_, uint8 level, PlayerLevelInfo *plinfo) const
Definition ObjectMgr.cpp:5004
PlayerLevelInfo * levelInfo
Definition Player.h:340

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

◆ GetPointOfInterest()

PointOfInterest const * ObjectMgr::GetPointOfInterest ( uint32  id) const
inline
935 {
936 PointOfInterestContainer::const_iterator itr = _pointsOfInterestStore.find(id);
937 if (itr != _pointsOfInterestStore.end())
938 return &itr->second;
939 return nullptr;
940 }
PointOfInterestContainer _pointsOfInterestStore
Definition ObjectMgr.h:1579

References _pointsOfInterestStore.

Referenced by LoadGossipMenuItems().

◆ GetPointOfInterestLocale()

PointOfInterestLocale const * ObjectMgr::GetPointOfInterestLocale ( uint32  poi_id) const
inline
1336 {
1337 PointOfInterestLocaleContainer::const_iterator itr = _pointOfInterestLocaleStore.find(poi_id);
1338 if (itr == _pointOfInterestLocaleStore.end()) return nullptr;
1339 return &itr->second;
1340 }
PointOfInterestLocaleContainer _pointOfInterestLocaleStore
Definition ObjectMgr.h:1697

References _pointOfInterestLocaleStore.

◆ GetQuestForAreaTrigger()

uint32 ObjectMgr::GetQuestForAreaTrigger ( uint32  Trigger_ID) const
inline
848 {
849 QuestAreaTriggerContainer::const_iterator itr = _questAreaTriggerStore.find(Trigger_ID);
850 if (itr != _questAreaTriggerStore.end())
851 return itr->second;
852 return 0;
853 }
QuestAreaTriggerContainer _questAreaTriggerStore
Definition ObjectMgr.h:1563

References _questAreaTriggerStore.

◆ GetQuestGreeting()

QuestGreeting const * ObjectMgr::GetQuestGreeting ( TypeID  type,
uint32  id 
) const
6989{
6990 uint8 typeIndex;
6991 if (type == TYPEID_UNIT)
6992 typeIndex = 0;
6993 else if (type == TYPEID_GAMEOBJECT)
6994 typeIndex = 1;
6995 else
6996 return nullptr;
6997
6998 std::pair<uint32, uint8> pairKey = std::make_pair(id, typeIndex);
6999 QuestGreetingContainer::const_iterator itr = _questGreetingStore.find(pairKey);
7000 if (itr == _questGreetingStore.end())
7001 return nullptr;
7002
7003 return &itr->second;
7004}
@ TYPEID_GAMEOBJECT
Definition ObjectGuid.h:37
@ TYPEID_UNIT
Definition ObjectGuid.h:35
QuestGreetingContainer _questGreetingStore
Definition ObjectMgr.h:1566

References _questGreetingStore, TYPEID_GAMEOBJECT, and TYPEID_UNIT.

◆ GetQuestLocale()

QuestLocale const * ObjectMgr::GetQuestLocale ( uint32  entry) const
inline
1324 {
1325 QuestLocaleContainer::const_iterator itr = _questLocaleStore.find(entry);
1326 if (itr == _questLocaleStore.end()) return nullptr;
1327 return &itr->second;
1328 }
QuestLocaleContainer _questLocaleStore
Definition ObjectMgr.h:1689

References _questLocaleStore.

◆ GetQuestMoneyReward()

uint32 ObjectMgr::GetQuestMoneyReward ( uint8  level,
uint32  questMoneyDifficulty 
) const
11297{
11298 if (questMoneyDifficulty < MAX_QUEST_MONEY_REWARDS)
11299 {
11300 auto const& itr = _questMoneyRewards.find(level);
11301 if (itr != _questMoneyRewards.end())
11302 {
11303 return itr->second.at(questMoneyDifficulty);
11304 }
11305 }
11306
11307 return 0;
11308}
static constexpr uint32 MAX_QUEST_MONEY_REWARDS
Definition ObjectMgr.h:723
QuestMoneyRewardStore _questMoneyRewards
Definition ObjectMgr.h:1721

References _questMoneyRewards, and MAX_QUEST_MONEY_REWARDS.

◆ GetQuestOfferRewardLocale()

QuestOfferRewardLocale const * ObjectMgr::GetQuestOfferRewardLocale ( uint32  entry) const
inline
1342 {
1343 auto itr = _questOfferRewardLocaleStore.find(entry);
1344 if (itr == _questOfferRewardLocaleStore.end()) return nullptr;
1345 return &itr->second;
1346 }
QuestOfferRewardLocaleContainer _questOfferRewardLocaleStore
Definition ObjectMgr.h:1690

References _questOfferRewardLocaleStore.

◆ GetQuestPOIVector()

QuestPOIVector const * ObjectMgr::GetQuestPOIVector ( uint32  questId)
inline
943 {
944 QuestPOIContainer::const_iterator itr = _questPOIStore.find(questId);
945 if (itr != _questPOIStore.end())
946 return &itr->second;
947 return nullptr;
948 }
QuestPOIContainer _questPOIStore
Definition ObjectMgr.h:1581

References _questPOIStore.

◆ GetQuestRequestItemsLocale()

QuestRequestItemsLocale const * ObjectMgr::GetQuestRequestItemsLocale ( uint32  entry) const
inline
1348 {
1349 auto itr = _questRequestItemsLocaleStore.find(entry);
1350 if (itr == _questRequestItemsLocaleStore.end()) return nullptr;
1351 return &itr->second;
1352 }
QuestRequestItemsLocaleContainer _questRequestItemsLocaleStore
Definition ObjectMgr.h:1691

References _questRequestItemsLocaleStore.

◆ GetQuestTemplate()

Quest const * ObjectMgr::GetQuestTemplate ( uint32  quest_id) const
inline
841 {
842 return quest_id < _questTemplatesFast.size() ? _questTemplatesFast[quest_id] : nullptr;
843 }
std::vector< Quest * > _questTemplatesFast
Definition ObjectMgr.h:1557

References _questTemplatesFast.

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

◆ GetQuestTemplates()

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

References _questTemplates.

◆ GetRepRewardRate()

RepRewardRate const * ObjectMgr::GetRepRewardRate ( uint32  factionId) const
inline
907 {
908 RepRewardRateContainer::const_iterator itr = _repRewardRateStore.find(factionId);
909 if (itr != _repRewardRateStore.end())
910 return &itr->second;
911
912 return nullptr;
913 }
RepRewardRateContainer _repRewardRateStore
Definition ObjectMgr.h:1573

References _repRewardRateStore.

◆ GetRepSpilloverTemplate()

RepSpilloverTemplate const * ObjectMgr::GetRepSpilloverTemplate ( uint32  factionId) const
inline
926 {
927 RepSpilloverTemplateContainer::const_iterator itr = _repSpilloverTemplateStore.find(factionId);
928 if (itr != _repSpilloverTemplateStore.end())
929 return &itr->second;
930
931 return nullptr;
932 }
RepSpilloverTemplateContainer _repSpilloverTemplateStore
Definition ObjectMgr.h:1575

References _repSpilloverTemplateStore.

◆ GetReputationOnKilEntry()

ReputationOnKillEntry const * ObjectMgr::GetReputationOnKilEntry ( uint32  id) const
inline
916 {
917 RepOnKillContainer::const_iterator itr = _repOnKillStore.find(id);
918 if (itr != _repOnKillStore.end())
919 return &itr->second;
920 return nullptr;
921 }
RepOnKillContainer _repOnKillStore
Definition ObjectMgr.h:1574

References _repOnKillStore.

◆ GetScriptId()

uint32 ObjectMgr::GetScriptId ( std::string const &  name)
10634{
10635 // use binary search to find the script name in the sorted vector
10636 // assume "" is the first element
10637 if (name.empty())
10638 return 0;
10639
10640 ScriptNameContainer::const_iterator itr = std::lower_bound(_scriptNamesStore.begin(), _scriptNamesStore.end(), name);
10641 if (itr == _scriptNamesStore.end() || (*itr != name))
10642 return 0;
10643
10644 return uint32(itr - _scriptNamesStore.begin());
10645}
ScriptNameContainer _scriptNamesStore
Definition ObjectMgr.h:1601

References _scriptNamesStore.

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

◆ GetScriptName()

std::string const & ObjectMgr::GetScriptName ( uint32  id) const
10628{
10629 static std::string const empty = "";
10630 return (id < _scriptNamesStore.size()) ? _scriptNamesStore[id] : empty;
10631}

References _scriptNamesStore.

Referenced by ValidateSpellScripts().

◆ GetScriptNames()

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

References _scriptNamesStore.

◆ GetSparringData()

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

References _creatureSparringStore.

◆ GetSpawnData()

SpawnData const * ObjectMgr::GetSpawnData ( SpawnObjectType  type,
ObjectGuid::LowType  spawnId 
) const
8776{
8777 switch (type)
8778 {
8780 return GetCreatureData(spawnId);
8782 return GetGameObjectData(spawnId);
8783 default:
8784 return nullptr;
8785 }
8786}
@ SPAWN_TYPE_GAMEOBJECT
Definition SpawnData.h:28
@ SPAWN_TYPE_CREATURE
Definition SpawnData.h:27

References GetCreatureData(), GetGameObjectData(), SPAWN_TYPE_CREATURE, and SPAWN_TYPE_GAMEOBJECT.

Referenced by LoadSpawnGroups().

◆ GetSpawnDataForGroup()

std::pair< SpawnGroupLinkContainer::const_iterator, SpawnGroupLinkContainer::const_iterator > ObjectMgr::GetSpawnDataForGroup ( uint32  groupId) const
inline
1288 {
1289 return _spawnGroupMapStore.equal_range(groupId);
1290 }
SpawnGroupLinkContainer _spawnGroupMapStore
Definition ObjectMgr.h:1675

References _spawnGroupMapStore.

◆ GetSpawnGroupData()

SpawnGroupTemplateData const * ObjectMgr::GetSpawnGroupData ( uint32  groupId) const
inline
1281 {
1282 auto itr = _spawnGroupDataStore.find(groupId);
1283 return itr != _spawnGroupDataStore.end() ? &itr->second : nullptr;
1284 }

References _spawnGroupDataStore.

◆ GetSpellClickInfoMapBounds()

SpellClickInfoMapBounds ObjectMgr::GetSpellClickInfoMapBounds ( uint32  creature_id) const
inline
1468 {
1469 return _spellClickInfoStore.equal_range(creature_id);
1470 }
SpellClickInfoContainer _spellClickInfoStore
Definition ObjectMgr.h:1603

References _spellClickInfoStore.

◆ GetSpellScriptsBounds()

SpellScriptsBounds ObjectMgr::GetSpellScriptsBounds ( uint32  spell_id)
9809{
9810 return SpellScriptsBounds(_spellScriptsStore.lower_bound(spell_id), _spellScriptsStore.upper_bound(spell_id));
9811}
std::pair< SpellScriptsContainer::iterator, SpellScriptsContainer::iterator > SpellScriptsBounds
Definition ObjectMgr.h:391
SpellScriptsContainer _spellScriptsStore
Definition ObjectMgr.h:1605

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
1212 {
1213 TempSummonDataContainer::const_iterator itr = _tempSummonDataStore.find(TempSummonGroupKey(summonerId, summonerType, group));
1214 if (itr != _tempSummonDataStore.end())
1215 return &itr->second;
1216
1217 return nullptr;
1218 }
TempSummonDataContainer _tempSummonDataStore
Stores temp summon data grouped by summoner's entry, summoner's type and group id.
Definition ObjectMgr.h:1680

References _tempSummonDataStore.

◆ GetTaxiMountDisplayId()

uint32 ObjectMgr::GetTaxiMountDisplayId ( uint32  id,
TeamId  teamId,
bool  allowed_alt_team = false 
)
7330{
7331 CreatureModel mountModel;
7332 CreatureTemplate const* mount_info = nullptr;
7333
7334 // select mount creature id
7335 TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id);
7336 if (node)
7337 {
7338 uint32 mount_entry = node->MountCreatureID[teamId == TEAM_ALLIANCE ? 1 : 0];
7339
7340 // Fix for Alliance not being able to use Acherus taxi
7341 // only one mount type for both sides
7342 if (mount_entry == 0 && allowed_alt_team)
7343 {
7344 // Simply reverse the selection. At least one team in theory should have a valid mount ID to choose.
7345 mount_entry = node->MountCreatureID[teamId];
7346 }
7347
7348 mount_info = GetCreatureTemplate(mount_entry);
7349 if (mount_info)
7350 {
7351 CreatureModel const* model = mount_info->GetRandomValidModel();
7352 if (!model)
7353 {
7354 LOG_ERROR("sql.sql", "No displayid found for the taxi mount with the entry {}! Can't load it!", mount_entry);
7355 return 0;
7356 }
7357 mountModel = *model;
7358 }
7359 }
7360
7361 // minfo is not actually used but the mount_id was updated
7362 GetCreatureModelRandomGender(&mountModel, mount_info);
7363
7364 return mountModel.CreatureDisplayID;
7365}
CreatureModelInfo const * GetCreatureModelRandomGender(CreatureModel *model, CreatureTemplate const *creatureTemplate) const
Definition ObjectMgr.cpp:1678
CreatureModel const * GetRandomValidModel() const
Definition Creature.cpp:120

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 
)
7306{
7307 TaxiPathSetBySource::iterator src_i = sTaxiPathSetBySource.find(source);
7308 if (src_i == sTaxiPathSetBySource.end())
7309 {
7310 path = 0;
7311 cost = 0;
7312 return;
7313 }
7314
7315 TaxiPathSetForSource& pathSet = src_i->second;
7316
7317 TaxiPathSetForSource::iterator dest_i = pathSet.find(destination);
7318 if (dest_i == pathSet.end())
7319 {
7320 path = 0;
7321 cost = 0;
7322 return;
7323 }
7324
7325 cost = dest_i->second->price;
7326 path = dest_i->second->ID;
7327}
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)
10221{
10222 auto itr = _creatureDefaultTrainers.find(creatureId);
10223 if (itr != _creatureDefaultTrainers.end())
10224 return Acore::Containers::MapGetValuePtr(_trainers, itr->second);
10225
10226 return nullptr;
10227}
std::unordered_map< uint32, uint32 > _creatureDefaultTrainers
Definition ObjectMgr.h:1702
std::unordered_map< uint32, Trainer::Trainer > _trainers
Definition ObjectMgr.h:1700

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

◆ GetVehicleAccessoryList()

VehicleAccessoryList const * ObjectMgr::GetVehicleAccessoryList ( Vehicle veh) const
11144{
11145 if (Creature* cre = veh->GetBase()->ToCreature())
11146 {
11147 // Give preference to GUID-based accessories
11148 VehicleAccessoryContainer::const_iterator itr = _vehicleAccessoryStore.find(cre->GetSpawnId());
11149 if (itr != _vehicleAccessoryStore.end())
11150 return &itr->second;
11151 }
11152
11153 // Otherwise return entry-based
11154 VehicleAccessoryContainer::const_iterator itr = _vehicleTemplateAccessoryStore.find(veh->GetCreatureEntry());
11155 if (itr != _vehicleTemplateAccessoryStore.end())
11156 return &itr->second;
11157 return nullptr;
11158}
VehicleAccessoryContainer _vehicleAccessoryStore
Definition ObjectMgr.h:1608
VehicleAccessoryContainer _vehicleTemplateAccessoryStore
Definition ObjectMgr.h:1607
Creature * ToCreature()
Definition Object.h:206
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
1522 {
1523 VehicleSeatAddonContainer::const_iterator itr = _vehicleSeatAddonStore.find(seatId);
1524 if (itr == _vehicleSeatAddonStore.end())
1525 return nullptr;
1526
1527 return &itr->second;
1528 }
VehicleSeatAddonContainer _vehicleSeatAddonStore
Definition ObjectMgr.h:1609

References _vehicleSeatAddonStore.

◆ GetXPForLevel()

uint32 ObjectMgr::GetXPForLevel ( uint8  level) const
8188{
8189 if (level < _playerXPperLevel.size())
8190 return _playerXPperLevel[level];
8191 return 0;
8192}
PlayerXPperLevel _playerXPperLevel
Definition ObjectMgr.h:1638

References _playerXPperLevel.

◆ InitializeSpellInfoPrecomputedData()

void ObjectMgr::InitializeSpellInfoPrecomputedData ( )
6458{
6459 uint32 limit = sSpellStore.GetNumRows();
6460 for(uint32 i = 0; i <= limit; ++i)
6461 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(i))
6462 {
6463 const_cast<SpellInfo*>(spellInfo)->SetStackableWithRanks(spellInfo->ComputeIsStackableWithRanks());
6464 const_cast<SpellInfo*>(spellInfo)->SetCritCapable(spellInfo->ComputeIsCritCapable());
6465 const_cast<SpellInfo*>(spellInfo)->SetSpellValid(SpellMgr::ComputeIsSpellValid(spellInfo, false));
6466 }
6467}
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
Definition SpellInfo.h:340
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:419

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

◆ instance()

ObjectMgr * ObjectMgr::instance ( )
static
378{
379 static ObjectMgr instance;
380 return &instance;
381}
Definition ObjectMgr.h:730
static ObjectMgr * instance()
Definition ObjectMgr.cpp:377

References instance().

Referenced by instance().

◆ IsChatFiltered()

bool ObjectMgr::IsChatFiltered ( std::string_view  text) const
9316{
9317 if (!_chatFilterAutomaton || text.empty())
9318 return false;
9319
9320 std::wstring wtext;
9321 if (!Utf8toWStr(text, wtext))
9322 return false;
9323
9324 wstrToLower(wtext);
9325
9326 return _chatFilterAutomaton->ContainsAny(wtext);
9327}
std::unique_ptr< Acore::AhoCorasick< wchar_t > > _chatFilterAutomaton
Definition ObjectMgr.h:1597

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

◆ IsGameObjectStaticTransport()

bool ObjectMgr::IsGameObjectStaticTransport ( uint32  entry)
11124{
11125 GameObjectTemplate const* goinfo = GetGameObjectTemplate(entry);
11126 return goinfo && goinfo->type == GAMEOBJECT_TYPE_TRANSPORT;
11127}
@ GAMEOBJECT_TYPE_TRANSPORT
Definition SharedDefines.h:1575

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

Referenced by AddGOData().

◆ IsProfanityName()

bool ObjectMgr::IsProfanityName ( std::string_view  name) const
9228{
9229 // pussywizard
9230 if (name.size() >= 2 && (name[name.size() - 2] == 'G' || name[name.size() - 2] == 'g') && (name[name.size() - 1] == 'M' || name[name.size() - 1] == 'm'))
9231 return true;
9232
9233 std::wstring wstr;
9234 if (!Utf8toWStr (name, wstr))
9235 return false;
9236
9237 wstrToLower(wstr);
9238
9239 return _profanityNamesStore.find(wstr) != _profanityNamesStore.end();
9240}

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

Referenced by AddProfanityPlayerName().

◆ IsReservedName()

bool ObjectMgr::IsReservedName ( std::string_view  name) const
9125{
9126 // pussywizard
9127 if (name.size() >= 2 && (name[name.size() - 2] == 'G' || name[name.size() - 2] == 'g') && (name[name.size() - 1] == 'M' || name[name.size() - 1] == 'm'))
9128 return true;
9129
9130 std::wstring wstr;
9131 if (!Utf8toWStr (name, wstr))
9132 return false;
9133
9134 wstrToLower(wstr);
9135
9136 return _reservedNamesStore.find(wstr) != _reservedNamesStore.end();
9137}

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

Referenced by AddReservedPlayerName().

◆ IsTavernAreaTrigger()

bool ObjectMgr::IsTavernAreaTrigger ( uint32  triggerID,
uint32  faction 
) const
inline
856 {
857 auto itr = _tavernAreaTriggerStore.find(triggerID);
858 if (itr != _tavernAreaTriggerStore.end())
859 {
860 return (itr->second & faction) != 0;
861 }
862
863 return false;
864 }
TavernAreaTriggerContainer _tavernAreaTriggerStore
Definition ObjectMgr.h:1564

References _tavernAreaTriggerStore.

◆ IsTransportMap()

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

References _transportMaps.

◆ IsValidChannelName()

bool ObjectMgr::IsValidChannelName ( std::string const &  name)
static
9468{
9469 std::wstring wname;
9470 if (!Utf8toWStr(name, wname))
9471 return false;
9472
9473 if (wname.size() > MAX_CHANNEL_NAME)
9474 return false;
9475
9476 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_CHANNEL_NAMES);
9477
9478 return isValidString(wname, strictMask, true);
9479}
#define MAX_CHANNEL_NAME
Definition ObjectMgr.h:691
@ CONFIG_STRICT_CHANNEL_NAMES
Definition WorldConfig.h:179

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

◆ IsValidCharterName()

bool ObjectMgr::IsValidCharterName ( std::string_view  name)
static
9442{
9443 std::wstring wname;
9444 if (!Utf8toWStr(name, wname))
9445 return false;
9446
9447 if (wname.size() > MAX_CHARTER_NAME)
9448 return false;
9449
9450 uint32 minName = sWorld->getIntConfig(CONFIG_MIN_CHARTER_NAME);
9451 if (wname.size() < minName)
9452 return false;
9453
9454 // Check Reserved Name
9455 if (sObjectMgr->IsReservedName(name))
9456 return false;
9457
9458 // Check Profanity Name
9459 if (sObjectMgr->IsProfanityName(name))
9460 return false;
9461
9462 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_CHARTER_NAMES);
9463
9464 return isValidString(wname, strictMask, true);
9465}
#define MAX_CHARTER_NAME
Definition ObjectMgr.h:690
@ CONFIG_MIN_CHARTER_NAME
Definition WorldConfig.h:182
@ CONFIG_STRICT_CHARTER_NAMES
Definition WorldConfig.h:178

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,
uint32  maxcount,
uint32  ptime,
uint32  ExtendedCost,
Player player = nullptr,
std::set< uint32 > *  skip_vendors = nullptr,
uint32  ORnpcflag = 0 
) const
10492{
10493 /*
10494 CreatureTemplate const* cInfo = GetCreatureTemplate(vendor_entry);
10495 if (!cInfo)
10496 {
10497 if (player)
10498 ChatHandler(player->GetSession()).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
10499 else
10500 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have data for not existed creature template (Entry: {}), ignore", vendor_entry);
10501 return false;
10502 }
10503
10504 if (!((cInfo->npcflag | ORnpcflag) & UNIT_NPC_FLAG_VENDOR))
10505 {
10506 if (!skip_vendors || skip_vendors->count(vendor_entry) == 0)
10507 {
10508 if (player)
10509 ChatHandler(player->GetSession()).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
10510 else
10511 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have data for not creature template (Entry: {}) without vendor flag, ignore", vendor_entry);
10512
10513 if (skip_vendors)
10514 skip_vendors->insert(vendor_entry);
10515 }
10516 return false;
10517 }
10518 */
10519
10520 if (!sObjectMgr->GetItemTemplate(item_id))
10521 {
10522 if (player)
10524 else
10525 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` for Vendor (Entry: {}) have in item list non-existed item ({}), ignore", vendor_entry, item_id);
10526 return false;
10527 }
10528
10529 if (ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost))
10530 {
10531 if (player)
10533 else
10534 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have Item (Entry: {}) with wrong ExtendedCost ({}) for vendor ({}), ignore", item_id, ExtendedCost, vendor_entry);
10535 return false;
10536 }
10537
10538 if (maxcount > 0 && incrtime == 0)
10539 {
10540 if (player)
10541 ChatHandler(player->GetSession()).PSendSysMessage("MaxCount != 0 ({}) but IncrTime == 0", maxcount);
10542 else
10543 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);
10544 return false;
10545 }
10546 else if (maxcount == 0 && incrtime > 0)
10547 {
10548 if (player)
10549 ChatHandler(player->GetSession()).PSendSysMessage("MaxCount == 0 but IncrTime<>= 0");
10550 else
10551 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);
10552 return false;
10553 }
10554
10555 VendorItemData const* vItems = GetNpcVendorItemList(vendor_entry);
10556 if (!vItems)
10557 return true; // later checks for non-empty lists
10558
10559 if (vItems->FindItemCostPair(item_id, ExtendedCost))
10560 {
10561 if (player)
10562 ChatHandler(player->GetSession()).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, item_id, ExtendedCost);
10563 else
10564 LOG_ERROR("sql.sql", "Table `npc_vendor` has duplicate items {} (with extended cost {}) for vendor (Entry: {}), ignoring", item_id, ExtendedCost, vendor_entry);
10565 return false;
10566 }
10567
10568 return true;
10569}
DBCStorage< ItemExtendedCostEntry > sItemExtendedCostStore(ItemExtendedCostEntryfmt)
@ LANG_ITEM_ALREADY_IN_LIST
Definition Language.h:256
@ LANG_ITEM_NOT_FOUND
Definition Language.h:253
@ LANG_EXTENDED_COST_NOT_EXIST
Definition Language.h:381
Definition Chat.h:37
void PSendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:219
VendorItemData const * GetNpcVendorItemList(uint32 entry) const
Definition ObjectMgr.h:1449
WorldSession * GetSession() const
Definition Player.h:2023
VendorItem const * FindItemCostPair(uint32 item_id, uint32 extendedCost) const
Definition Creature.cpp:104

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 ( )
7479{
7480 uint32 oldMSTime = getMSTime();
7481
7482 if (!_accessRequirementStore.empty())
7483 {
7484 for (DungeonProgressionRequirementsContainer::iterator itr = _accessRequirementStore.begin(); itr != _accessRequirementStore.end(); ++itr)
7485 {
7486 std::unordered_map<uint8, DungeonProgressionRequirements*> difficulties = itr->second;
7487 for (auto difficultiesItr = difficulties.begin(); difficultiesItr != difficulties.end(); ++difficultiesItr)
7488 {
7489 for (auto questItr = difficultiesItr->second->quests.begin(); questItr != difficultiesItr->second->quests.end(); ++questItr)
7490 {
7491 delete* questItr;
7492 }
7493
7494 for (auto achievementItr = difficultiesItr->second->achievements.begin(); achievementItr != difficultiesItr->second->achievements.end(); ++achievementItr)
7495 {
7496 delete* achievementItr;
7497 }
7498
7499 for (auto itemsItr = difficultiesItr->second->items.begin(); itemsItr != difficultiesItr->second->items.end(); ++itemsItr)
7500 {
7501 delete* itemsItr;
7502 }
7503
7504 delete difficultiesItr->second;
7505 }
7506 }
7507
7508 _accessRequirementStore.clear(); // need for reload case
7509 }
7510 // 0 1 2 3 4 5
7511 QueryResult access_template_result = WorldDatabase.Query("SELECT id, map_id, difficulty, min_level, max_level, min_avg_item_level FROM dungeon_access_template");
7512 if (!access_template_result)
7513 {
7514 LOG_WARN("server.loading", ">> Loaded 0 access requirement definitions. DB table `dungeon_access_template` is empty.");
7515 LOG_INFO("server.loading", " ");
7516 return;
7517 }
7518
7519 uint32 count = 0;
7520 uint32 countProgressionRequirements = 0;
7521
7522 do
7523 {
7524 Field* fields = access_template_result->Fetch();
7525
7526 //Get the common variables for the access requirements
7527 uint8 dungeon_access_id = fields[0].Get<uint8>();
7528 uint32 mapid = fields[1].Get<uint32>();
7529 uint8 difficulty = fields[2].Get<uint8>();
7530
7531 //Set up the access requirements
7533 ar->levelMin = fields[3].Get<uint8>();
7534 ar->levelMax = fields[4].Get<uint8>();
7535 ar->reqItemLevel = fields[5].Get<uint16>();
7536
7537 // 0 1 2 3 4 6
7538 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);
7539 if (progression_requirements_results)
7540 {
7541 do
7542 {
7543 Field* progression_requirement_row = progression_requirements_results->Fetch();
7544
7545 const uint8 requirement_type = progression_requirement_row[0].Get<uint8>();
7546 const uint32 requirement_id = progression_requirement_row[1].Get<uint32>();
7547 const std::string requirement_note = progression_requirement_row[2].Get<std::string>();
7548 const uint8 requirement_faction = progression_requirement_row[3].Get<uint8>();
7549 const uint8 requirement_priority = progression_requirement_row[4].IsNull() ? UINT8_MAX : progression_requirement_row[4].Get<uint8>();
7550 const bool requirement_checkLeaderOnly = progression_requirement_row[5].Get<bool>();
7551
7552 ProgressionRequirement* progression_requirement = new ProgressionRequirement();
7553 progression_requirement->id = requirement_id;
7554 progression_requirement->note = requirement_note;
7555 progression_requirement->faction = (TeamId)requirement_faction;
7556 progression_requirement->priority = requirement_priority;
7557 progression_requirement->checkLeaderOnly = requirement_checkLeaderOnly;
7558
7559 std::vector<ProgressionRequirement*>* currentRequirementsList = nullptr;
7560
7561 switch (requirement_type)
7562 {
7563 case 0:
7564 {
7565 //Achievement
7566 if (!sAchievementStore.LookupEntry(progression_requirement->id))
7567 {
7568 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);
7569 break;
7570 }
7571
7572 currentRequirementsList = &ar->achievements;
7573 break;
7574 }
7575 case 1:
7576 {
7577 //Quest
7578 if (!GetQuestTemplate(progression_requirement->id))
7579 {
7580 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);
7581 break;
7582 }
7583
7584 currentRequirementsList = &ar->quests;
7585 break;
7586 }
7587 case 2:
7588 {
7589 //Item
7590 ItemTemplate const* pProto = GetItemTemplate(progression_requirement->id);
7591 if (!pProto)
7592 {
7593 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);
7594 break;
7595 }
7596
7597 currentRequirementsList = &ar->items;
7598 break;
7599 }
7600 default:
7601 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);
7602 break;
7603 }
7604
7605 //Check if array is valid and delete the progression requirement
7606 if (!currentRequirementsList)
7607 {
7608 delete progression_requirement;
7609 continue;
7610 }
7611
7612 //Insert into the array
7613 if (currentRequirementsList->size() > requirement_priority)
7614 {
7615 currentRequirementsList->insert(currentRequirementsList->begin() + requirement_priority, progression_requirement);
7616 }
7617 else
7618 {
7619 currentRequirementsList->push_back(progression_requirement);
7620 }
7621
7622 } while (progression_requirements_results->NextRow());
7623 }
7624
7625 //Sort all arrays for priority
7626 auto sortFunction = [](const ProgressionRequirement* const a, const ProgressionRequirement* const b) {return a->priority > b->priority; };
7627 std::sort(ar->achievements.begin(), ar->achievements.end(), sortFunction);
7628 std::sort(ar->quests.begin(), ar->quests.end(), sortFunction);
7629 std::sort(ar->items.begin(), ar->items.end(), sortFunction);
7630
7631 countProgressionRequirements += ar->achievements.size();
7632 countProgressionRequirements += ar->quests.size();
7633 countProgressionRequirements += ar->items.size();
7634 count++;
7635
7636 _accessRequirementStore[mapid][difficulty] = ar;
7637 } while (access_template_result->NextRow());
7638
7639 LOG_INFO("server.loading", ">> Loaded {} Rows From dungeon_access_template And {} Rows From dungeon_access_requirements in {} ms", count, countProgressionRequirements, GetMSTimeDiffToNow(oldMSTime));
7640 LOG_INFO("server.loading", " ");
7641}
DBCStorage< AchievementEntry > sAchievementStore(Achievementfmt)
std::shared_ptr< ResultSet > QueryResult
Definition DatabaseEnvFwd.h:27
#define LOG_WARN(filterType__,...)
Definition Log.h:149
TeamId
Definition SharedDefines.h:747
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:3933
Quest const * GetQuestTemplate(uint32 quest_id) const
Definition ObjectMgr.h:840
Definition Player.h:935
Definition ItemTemplate.h:619
Definition Player.h:926
uint32 priority
Definition Player.h:930

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 ( )
9675{
9676 uint32 oldMSTime = getMSTime();
9677
9678 _acoreStringStore.clear(); // for reload case
9679 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");
9680 if (!result)
9681 {
9682 LOG_WARN("server.loading", ">> Loaded 0 acore strings. DB table `acore_strings` is empty.");
9683 LOG_INFO("server.loading", " ");
9684 return false;
9685 }
9686
9687 do
9688 {
9689 Field* fields = result->Fetch();
9690
9691 uint32 entry = fields[0].Get<uint32>();
9692
9693 AcoreString& data = _acoreStringStore[entry];
9694
9695 data.Content.resize(DEFAULT_LOCALE + 1);
9696
9697 for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
9698 AddLocaleString(fields[i + 1].Get<std::string>(), LocaleConstant(i), data.Content);
9699 } while (result->NextRow());
9700
9701 LOG_INFO("server.loading", ">> Loaded {} Acore Strings in {} ms", (uint32)_acoreStringStore.size(), GetMSTimeDiffToNow(oldMSTime));
9702 LOG_INFO("server.loading", " ");
9703
9704 return true;
9705}
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:383

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

◆ LoadAreaTriggers()

void ObjectMgr::LoadAreaTriggers ( )
7368{
7369 uint32 oldMSTime = getMSTime();
7370
7371 _areaTriggerStore.clear();
7372
7373 QueryResult result = WorldDatabase.Query("SELECT entry, map, x, y, z, radius, length, width, height, orientation FROM areatrigger");
7374
7375 if (!result)
7376 {
7377 LOG_WARN("server.loading", ">> Loaded 0 area trigger definitions. DB table `areatrigger` is empty.");
7378 LOG_INFO("server.loading", " ");
7379 return;
7380 }
7381
7382 uint32 count = 0;
7383
7384 do
7385 {
7386 Field* fields = result->Fetch();
7387
7388 ++count;
7389
7390 AreaTrigger at;
7391
7392 at.entry = fields[0].Get<uint32>();
7393 at.map = fields[1].Get<uint32>();
7394 at.x = fields[2].Get<float>();
7395 at.y = fields[3].Get<float>();
7396 at.z = fields[4].Get<float>();
7397 at.radius = fields[5].Get<float>();
7398 at.length = fields[6].Get<float>();
7399 at.width = fields[7].Get<float>();
7400 at.height = fields[8].Get<float>();
7401 at.orientation = fields[9].Get<float>();
7402
7403 MapEntry const* mapEntry = sMapStore.LookupEntry(at.map);
7404 if (!mapEntry)
7405 {
7406 LOG_ERROR("sql.sql", "Area trigger (ID:{}) map (ID: {}) does not exist in `Map.dbc`.", at.entry, at.map);
7407 continue;
7408 }
7409
7410 _areaTriggerStore[at.entry] = at;
7411 } while (result->NextRow());
7412
7413 LOG_INFO("server.loading", ">> Loaded {} Area Trigger Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7414 LOG_INFO("server.loading", " ");
7415}
float height
Definition ObjectMgr.h:432
float x
Definition ObjectMgr.h:426
float y
Definition ObjectMgr.h:427
float orientation
Definition ObjectMgr.h:433
float length
Definition ObjectMgr.h:430
uint32 entry
Definition ObjectMgr.h:424
float radius
Definition ObjectMgr.h:429
float z
Definition ObjectMgr.h:428
float width
Definition ObjectMgr.h:431

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 ( )
7221{
7222 uint32 oldMSTime = getMSTime();
7223
7224 _areaTriggerScriptStore.clear(); // need for reload case
7225 QueryResult result = WorldDatabase.Query("SELECT entry, ScriptName FROM areatrigger_scripts");
7226
7227 if (!result)
7228 {
7229 LOG_WARN("server.loading", ">> Loaded 0 Areatrigger Scripts. DB Table `areatrigger_scripts` Is Empty.");
7230 LOG_INFO("server.loading", " ");
7231 return;
7232 }
7233
7234 uint32 count = 0;
7235
7236 do
7237 {
7238 ++count;
7239
7240 Field* fields = result->Fetch();
7241
7242 uint32 Trigger_ID = fields[0].Get<uint32>();
7243 std::string scriptName = fields[1].Get<std::string>();
7244
7245 AreaTrigger const* atEntry = GetAreaTrigger(Trigger_ID);
7246 if (!atEntry)
7247 {
7248 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
7249 continue;
7250 }
7251 _areaTriggerScriptStore[Trigger_ID] = GetScriptId(scriptName);
7252 } while (result->NextRow());
7253
7254 LOG_INFO("server.loading", ">> Loaded {} Areatrigger Scripts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7255 LOG_INFO("server.loading", " ");
7256}
uint32 GetScriptId(std::string const &name)
Definition ObjectMgr.cpp:10633

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

◆ LoadAreaTriggerTeleports()

void ObjectMgr::LoadAreaTriggerTeleports ( )
7418{
7419 uint32 oldMSTime = getMSTime();
7420
7421 _areaTriggerTeleportStore.clear(); // need for reload case
7422
7423 // 0 1 2 3 4 5
7424 QueryResult result = WorldDatabase.Query("SELECT ID, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM areatrigger_teleport");
7425
7426 if (!result)
7427 {
7428 LOG_WARN("server.loading", ">> Loaded 0 area trigger teleport definitions. DB table `areatrigger_teleport` is empty.");
7429 LOG_INFO("server.loading", " ");
7430 return;
7431 }
7432
7433 uint32 count = 0;
7434
7435 do
7436 {
7437 Field* fields = result->Fetch();
7438
7439 ++count;
7440
7441 uint32 Trigger_ID = fields[0].Get<uint32>();
7442
7444
7445 at.target_mapId = fields[1].Get<uint16>();
7446 at.target_X = fields[2].Get<float>();
7447 at.target_Y = fields[3].Get<float>();
7448 at.target_Z = fields[4].Get<float>();
7449 at.target_Orientation = fields[5].Get<float>();
7450
7451 AreaTrigger const* atEntry = GetAreaTrigger(Trigger_ID);
7452 if (!atEntry)
7453 {
7454 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
7455 continue;
7456 }
7457
7458 MapEntry const* mapEntry = sMapStore.LookupEntry(at.target_mapId);
7459 if (!mapEntry)
7460 {
7461 LOG_ERROR("sql.sql", "Area trigger (ID:{}) target map (ID: {}) does not exist in `Map.dbc`.", Trigger_ID, at.target_mapId);
7462 continue;
7463 }
7464
7465 if (at.target_X == 0 && at.target_Y == 0 && at.target_Z == 0)
7466 {
7467 LOG_ERROR("sql.sql", "Area trigger (ID:{}) target coordinates not provided.", Trigger_ID);
7468 continue;
7469 }
7470
7471 _areaTriggerTeleportStore[Trigger_ID] = at;
7472 } while (result->NextRow());
7473
7474 LOG_INFO("server.loading", ">> Loaded {} Area Trigger Teleport Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7475 LOG_INFO("server.loading", " ");
7476}
Definition ObjectMgr.h:414
uint32 target_mapId
Definition ObjectMgr.h:415

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

◆ LoadBroadcastTextLocales()

void ObjectMgr::LoadBroadcastTextLocales ( )
10733{
10734 uint32 oldMSTime = getMSTime();
10735
10736 // 0 1 2 3
10737 QueryResult result = WorldDatabase.Query("SELECT ID, locale, MaleText, FemaleText FROM broadcast_text_locale");
10738
10739 if (!result)
10740 {
10741 LOG_WARN("server.loading", ">> Loaded 0 broadcast text locales. DB table `broadcast_text_locale` is empty.");
10742 LOG_INFO("server.loading", " ");
10743 return;
10744 }
10745
10746 uint32 locales_count = 0;
10747 do
10748 {
10749 Field* fields = result->Fetch();
10750
10751 uint32 id = fields[0].Get<uint32>();
10752
10753 BroadcastTextContainer::iterator bct = _broadcastTextStore.find(id);
10754 if (bct == _broadcastTextStore.end())
10755 {
10756 LOG_ERROR("sql.sql", "BroadcastText (Id: {}) found in table `broadcast_text_locale` but does not exist in `broadcast_text`. Skipped!", id);
10757 continue;
10758 }
10759
10760 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
10761 if (locale == LOCALE_enUS)
10762 continue;
10763
10764 AddLocaleString(fields[2].Get<std::string>(), locale, bct->second.MaleText);
10765 AddLocaleString(fields[3].Get<std::string>(), locale, bct->second.FemaleText);
10766 locales_count++;
10767 } while (result->NextRow());
10768
10769 LOG_INFO("server.loading", ">> Loaded {} Broadcast Text Locales in {} ms", locales_count, GetMSTimeDiffToNow(oldMSTime));
10770 LOG_INFO("server.loading", " ");
10771}
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 ( )
10648{
10649 uint32 oldMSTime = getMSTime();
10650
10651 _broadcastTextStore.clear(); // for reload case
10652
10653 // 0 1 2 3 4 5 6 7 8 9 10 11 12
10654 QueryResult result = WorldDatabase.Query("SELECT ID, LanguageID, MaleText, FemaleText, EmoteID1, EmoteID2, EmoteID3, EmoteDelay1, EmoteDelay2, EmoteDelay3, SoundEntriesID, EmotesID, Flags FROM broadcast_text");
10655 if (!result)
10656 {
10657 LOG_WARN("server.loading", ">> Loaded 0 broadcast texts. DB table `broadcast_text` is empty.");
10658 LOG_INFO("server.loading", " ");
10659 return;
10660 }
10661
10662 _broadcastTextStore.rehash(result->GetRowCount());
10663
10664 do
10665 {
10666 Field* fields = result->Fetch();
10667
10668 BroadcastText bct;
10669
10670 bct.Id = fields[0].Get<uint32>();
10671 bct.LanguageID = fields[1].Get<uint32>();
10672 bct.MaleText[DEFAULT_LOCALE] = fields[2].Get<std::string>();
10673 bct.FemaleText[DEFAULT_LOCALE] = fields[3].Get<std::string>();
10674 bct.EmoteId1 = fields[4].Get<uint32>();
10675 bct.EmoteId2 = fields[5].Get<uint32>();
10676 bct.EmoteId3 = fields[6].Get<uint32>();
10677 bct.EmoteDelay1 = fields[7].Get<uint32>();
10678 bct.EmoteDelay2 = fields[8].Get<uint32>();
10679 bct.EmoteDelay3 = fields[9].Get<uint32>();
10680 bct.SoundEntriesId = fields[10].Get<uint32>();
10681 bct.EmotesID = fields[11].Get<uint32>();
10682 bct.Flags = fields[12].Get<uint32>();
10683
10684 if (bct.SoundEntriesId)
10685 {
10686 if (!sSoundEntriesStore.LookupEntry(bct.SoundEntriesId))
10687 {
10688 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has SoundEntriesId {} but sound does not exist.", bct.Id, bct.SoundEntriesId);
10689 bct.SoundEntriesId = 0;
10690 }
10691 }
10692
10694 {
10695 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` using Language {} but Language does not exist.", bct.Id, bct.LanguageID);
10697 }
10698
10699 if (bct.EmoteId1)
10700 {
10701 if (!sEmotesStore.LookupEntry(bct.EmoteId1))
10702 {
10703 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has EmoteId1 {} but emote does not exist.", bct.Id, bct.EmoteId1);
10704 bct.EmoteId1 = 0;
10705 }
10706 }
10707
10708 if (bct.EmoteId2)
10709 {
10710 if (!sEmotesStore.LookupEntry(bct.EmoteId2))
10711 {
10712 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has EmoteId2 {} but emote does not exist.", bct.Id, bct.EmoteId2);
10713 bct.EmoteId2 = 0;
10714 }
10715 }
10716
10717 if (bct.EmoteId3)
10718 {
10719 if (!sEmotesStore.LookupEntry(bct.EmoteId3))
10720 {
10721 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has EmoteId3 {} but emote does not exist.", bct.Id, bct.EmoteId3);
10722 bct.EmoteId3 = 0;
10723 }
10724 }
10725
10726 _broadcastTextStore[bct.Id] = bct;
10727 } while (result->NextRow());
10728
10729 LOG_INFO("server.loading", ">> Loaded {} Broadcast Texts in {} ms", _broadcastTextStore.size(), GetMSTimeDiffToNow(oldMSTime));
10730}
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
DBCStorage< EmotesEntry > sEmotesStore(EmotesEntryfmt)
LanguageDesc const * GetLanguageDescByID(uint32 lang)
Definition ObjectMgr.cpp:254
@ LANG_UNIVERSAL
Definition SharedDefines.h:723
Definition ObjectMgr.h:437
uint32 EmoteDelay2
Definition ObjectMgr.h:452
uint32 Id
Definition ObjectMgr.h:444
std::vector< std::string > FemaleText
Definition ObjectMgr.h:447
uint32 EmotesID
Definition ObjectMgr.h:455
uint32 LanguageID
Definition ObjectMgr.h:445
uint32 EmoteId2
Definition ObjectMgr.h:449
uint32 EmoteDelay1
Definition ObjectMgr.h:451
uint32 SoundEntriesId
Definition ObjectMgr.h:454
std::vector< std::string > MaleText
Definition ObjectMgr.h:446
uint32 EmoteId3
Definition ObjectMgr.h:450
uint32 EmoteId1
Definition ObjectMgr.h:448
uint32 EmoteDelay3
Definition ObjectMgr.h:453
uint32 Flags
Definition ObjectMgr.h:456

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.

◆ LoadChatFilter()

void ObjectMgr::LoadChatFilter ( )
9263{
9264 uint32 oldMSTime = getMSTime();
9265
9266 _chatFilterAutomaton.reset(); // need for reload case
9267
9269 PreparedQueryResult result = CharacterDatabase.Query(stmt);
9270
9271 if (!result)
9272 {
9273 LOG_WARN("server.loading", ">> Loaded 0 chat filter words. DB table `chat_filter` is empty!");
9274 LOG_INFO("server.loading", " ");
9275 return;
9276 }
9277
9278 auto automaton = std::make_unique<Acore::AhoCorasick<wchar_t>>();
9279 uint32 count = 0;
9280
9281 do
9282 {
9283 Field* fields = result->Fetch();
9284 std::string word = fields[1].Get<std::string>();
9285
9286 if (word.empty())
9287 continue;
9288
9289 std::wstring wstr;
9290 if (!Utf8toWStr(word, wstr))
9291 {
9292 LOG_ERROR("sql.sql", "Table `chat_filter` has invalid word: {}", word);
9293 continue;
9294 }
9295
9296 wstrToLower(wstr);
9297
9298 if (wstr.empty())
9299 continue;
9300
9301 automaton->Insert(wstr);
9302 ++count;
9303 } while (result->NextRow());
9304
9305 if (count > 0)
9306 {
9307 automaton->Build();
9308 _chatFilterAutomaton = std::move(automaton);
9309 }
9310
9311 LOG_INFO("server.loading", ">> Loaded {} chat filter words in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9312 LOG_INFO("server.loading", " ");
9313}
@ CHAR_SEL_CHAT_FILTER
Definition CharacterDatabase.h:526
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition DatabaseEnvFwd.h:45

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

◆ LoadCreatureAddons()

void ObjectMgr::LoadCreatureAddons ( )
1263{
1264 uint32 oldMSTime = getMSTime();
1265
1266 // 0 1 2 3 4 5 6 7
1267 QueryResult result = WorldDatabase.Query("SELECT guid, path_id, mount, bytes1, bytes2, emote, visibilityDistanceType, auras FROM creature_addon");
1268
1269 if (!result)
1270 {
1271 LOG_WARN("server.loading", ">> Loaded 0 creature addon definitions. DB table `creature_addon` is empty.");
1272 LOG_INFO("server.loading", " ");
1273 return;
1274 }
1275
1276 uint32 count = 0;
1277 do
1278 {
1279 Field* fields = result->Fetch();
1280
1281 ObjectGuid::LowType guid = fields[0].Get<uint32>();
1282
1283 CreatureData const* creData = GetCreatureData(guid);
1284 if (!creData)
1285 {
1286 LOG_ERROR("sql.sql", "Creature (GUID: {}) does not exist but has a record in `creature_addon`", guid);
1287 continue;
1288 }
1289
1290 CreatureAddon& creatureAddon = _creatureAddonStore[guid];
1291
1292 creatureAddon.path_id = fields[1].Get<uint32>();
1293 if (creData->movementType == WAYPOINT_MOTION_TYPE && !creatureAddon.path_id)
1294 {
1295 const_cast<CreatureData*>(creData)->movementType = IDLE_MOTION_TYPE;
1296 LOG_ERROR("sql.sql", "Creature (GUID {}) has movement type set to WAYPOINT_MOTION_TYPE but no path assigned", guid);
1297 }
1298
1299 creatureAddon.mount = fields[2].Get<uint32>();
1300 creatureAddon.bytes1 = fields[3].Get<uint32>();
1301 creatureAddon.bytes2 = fields[4].Get<uint32>();
1302 creatureAddon.emote = fields[5].Get<uint32>();
1303 creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[6].Get<uint8>());
1304
1305 for (std::string_view aura : Acore::Tokenize(fields[7].Get<std::string_view>(), ' ', false))
1306 {
1307 SpellInfo const* spellInfo = nullptr;
1308
1309 if (Optional<uint32> spellId = Acore::StringTo<uint32>(aura))
1310 {
1311 spellInfo = sSpellMgr->GetSpellInfo(*spellId);
1312 }
1313
1314 if (!spellInfo)
1315 {
1316 LOG_ERROR("sql.sql", "Creature (GUID: {}) has wrong spell '{}' defined in `auras` field in `creature_addon`.", guid, aura);
1317 continue;
1318 }
1319
1320 if (std::find(creatureAddon.auras.begin(), creatureAddon.auras.end(), spellInfo->Id) != creatureAddon.auras.end())
1321 {
1322 LOG_ERROR("sql.sql", "Creature (GUID: {}) has duplicate aura (spell {}) in `auras` field in `creature_addon`.", guid, spellInfo->Id);
1323 continue;
1324 }
1325
1326 if (spellInfo->GetDuration() > 0)
1327 {
1328 LOG_DEBUG/*ERROR*/("sql.sql", "Creature (Entry: {}) has temporary aura (spell {}) in `auras` field in `creature_template_addon`.", guid, spellInfo->Id);
1329 // continue;
1330 }
1331
1332 creatureAddon.auras.push_back(spellInfo->Id);
1333 }
1334
1335 if (creatureAddon.mount)
1336 {
1337 if (!sCreatureDisplayInfoStore.LookupEntry(creatureAddon.mount))
1338 {
1339 LOG_ERROR("sql.sql", "Creature (GUID: {}) has invalid displayInfoId ({}) for mount defined in `creature_addon`", guid, creatureAddon.mount);
1340 creatureAddon.mount = 0;
1341 }
1342 }
1343
1344 if (!sEmotesStore.LookupEntry(creatureAddon.emote))
1345 {
1346 LOG_ERROR("sql.sql", "Creature (GUID: {}) has invalid emote ({}) defined in `creature_addon`.", guid, creatureAddon.emote);
1347 creatureAddon.emote = 0;
1348 }
1349
1351 {
1352 LOG_ERROR("sql.sql", "Creature (GUID: {}) has invalid visibilityDistanceType ({}) defined in `creature_addon`.", guid, AsUnderlyingType(creatureAddon.visibilityDistanceType));
1354 }
1355
1356 ++count;
1357 } while (result->NextRow());
1358
1359 LOG_INFO("server.loading", ">> Loaded {} Creature Addons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1360 LOG_INFO("server.loading", " ");
1361}
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:344
int32 GetDuration() const
Definition SpellInfo.cpp:2738
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:431
std::vector< uint32 > auras
Definition CreatureData.h:437
uint32 mount
Definition CreatureData.h:433
uint32 emote
Definition CreatureData.h:436
uint32 path_id
Definition CreatureData.h:432
VisibilityDistanceType visibilityDistanceType
Definition CreatureData.h:438
uint32 bytes1
Definition CreatureData.h:434
uint32 bytes2
Definition CreatureData.h:435

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 ( )
10805{
10806 uint32 oldMSTime = getMSTime();
10807
10808 QueryResult result = WorldDatabase.Query("SELECT level, class, basehp0, basehp1, basehp2, basemana, basearmor, attackpower, rangedattackpower, damage_base, damage_exp1, damage_exp2, Strength, Agility, Stamina, Intellect, Spirit FROM creature_classlevelstats");
10809
10810 if (!result)
10811 {
10812 LOG_WARN("server.loading", ">> Loaded 0 creature base stats. DB table `creature_classlevelstats` is empty.");
10813 LOG_INFO("server.loading", " ");
10814 return;
10815 }
10816
10817 uint32 count = 0;
10818 do
10819 {
10820 Field* fields = result->Fetch();
10821
10822 uint8 Level = fields[0].Get<uint8>();
10823 uint8 Class = fields[1].Get<uint8>();
10824
10825 if (!Class || ((1 << (Class - 1)) & CLASSMASK_ALL_CREATURES) == 0)
10826 LOG_ERROR("sql.sql", "Creature base stats for level {} has invalid class {}", Level, Class);
10827
10828 CreatureBaseStats stats;
10829
10830 for (uint8 i = 0; i < MAX_EXPANSIONS; ++i)
10831 {
10832 stats.BaseHealth[i] = fields[2 + i].Get<uint32>();
10833
10834 if (stats.BaseHealth[i] == 0)
10835 {
10836 LOG_ERROR("sql.sql", "Creature base stats for class {}, level {} has invalid zero base HP[{}] - set to 1", Class, Level, i);
10837 stats.BaseHealth[i] = 1;
10838 }
10839
10840 // xinef: if no data is available, get them from lower expansions
10841 if (stats.BaseHealth[i] <= 1)
10842 {
10843 for (uint8 j = i; j > 0;)
10844 {
10845 --j;
10846 if (stats.BaseHealth[j] > 1)
10847 {
10848 stats.BaseHealth[i] = stats.BaseHealth[j];
10849 break;
10850 }
10851 }
10852 }
10853
10854 stats.BaseDamage[i] = fields[9 + i].Get<float>();
10855 if (stats.BaseDamage[i] < 0.0f)
10856 {
10857 LOG_ERROR("sql.sql", "Creature base stats for class {}, level {} has invalid negative base damage[{}] - set to 0.0", Class, Level, i);
10858 stats.BaseDamage[i] = 0.0f;
10859 }
10860 }
10861
10862 stats.BaseMana = fields[5].Get<uint32>();
10863 stats.BaseArmor = fields[6].Get<uint32>();
10864
10865 stats.AttackPower = fields[7].Get<uint32>();
10866 stats.RangedAttackPower = fields[8].Get<uint32>();
10867
10868 stats.Strength = fields[12].Get<uint32>();
10869 stats.Agility = fields[13].Get<uint32>();
10870 stats.Stamina = fields[14].Get<uint32>();
10871 stats.Intellect = fields[15].Get<uint32>();
10872 stats.Spirit = fields[16].Get<uint32>();
10873
10874 if (!stats.Strength || !stats.Agility || !stats.Stamina || !stats.Intellect || !stats.Spirit)
10875 {
10876 // Once these attributes are implemented, this should probably be uncommented.
10877 // LOG_WARN("server.loading", "Creature base attributes for class {}, level {} are missing!", Class, Level);
10878 }
10879
10881
10882 ++count;
10883 } while (result->NextRow());
10884
10886 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
10887 {
10888 for (uint16 lvl = itr->second.minlevel; lvl <= itr->second.maxlevel; ++lvl)
10889 {
10890 if (_creatureBaseStatsStore.find(MAKE_PAIR16(lvl, itr->second.unit_class)) == _creatureBaseStatsStore.end())
10891 LOG_ERROR("sql.sql", "Missing base stats for creature class {} level {}", itr->second.unit_class, lvl);
10892 }
10893 }
10894
10895 LOG_INFO("server.loading", ">> Loaded {} Creature Base Stats in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10896 LOG_INFO("server.loading", " ");
10897}
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
Definition CreatureData.h:287
@ 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:774
uint32 BaseMana
Definition CreatureData.h:300
uint32 Agility
Definition CreatureData.h:306
float BaseDamage[MAX_EXPANSIONS]
Definition CreatureData.h:304
uint32 RangedAttackPower
Definition CreatureData.h:303
uint32 AttackPower
Definition CreatureData.h:302
uint32 BaseHealth[MAX_EXPANSIONS]
Definition CreatureData.h:299
uint32 Strength
Definition CreatureData.h:305
float BaseArmor
Definition CreatureData.h:301
uint32 Spirit
Definition CreatureData.h:309
uint32 Stamina
Definition CreatureData.h:307
uint32 Intellect
Definition CreatureData.h:308

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

◆ LoadCreatureCustomIDs()

void ObjectMgr::LoadCreatureCustomIDs ( )

Load config option Creatures.CustomIDs into Store.

953{
954 // Hack for modules
955 std::string stringCreatureIds = sConfigMgr->GetOption<std::string>("Creatures.CustomIDs", "190010,55005,999991,25462,98888,601014,34567,34568");
956 std::vector<std::string_view> CustomCreatures = Acore::Tokenize(stringCreatureIds, ',', false);
957
958 for (auto& itr : CustomCreatures)
959 {
960 _creatureCustomIDsStore.push_back(Acore::StringTo<uint32>(itr).value());
961 }
962}
#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.
2574{
2575 CreatureData const* data = GetCreatureData(spawnId);
2576 if (data)
2577 return data;
2578
2579 QueryResult result = WorldDatabase.Query("SELECT creature.guid, id, map, equipment_id, "
2580 "position_x, position_y, position_z, orientation, spawntimesecs, wander_distance, "
2581 "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, "
2582 "creature.npcflag, creature.unit_flags, creature.dynamicflags, creature.ScriptName "
2583 "FROM creature WHERE creature.guid = {}", spawnId);
2584
2585 if (!result)
2586 return nullptr;
2587
2588 Field* fields = result->Fetch();
2589 uint32 creatureId = fields[1].Get<uint32>();
2590
2591 CreatureTemplate const* cInfo = GetCreatureTemplate(creatureId);
2592 if (!cInfo)
2593 {
2594 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non-existing creature entry {} in `id` field, skipped.", spawnId, creatureId);
2595 return nullptr;
2596 }
2597
2599 creatureData.id = creatureId;
2600 creatureData.mapid = fields[2].Get<uint16>();
2601 creatureData.equipmentId = fields[3].Get<int8>();
2602 creatureData.posX = fields[4].Get<float>();
2603 creatureData.posY = fields[5].Get<float>();
2604 creatureData.posZ = fields[6].Get<float>();
2605 creatureData.orientation = fields[7].Get<float>();
2606 creatureData.spawntimesecs = fields[8].Get<uint32>();
2607 creatureData.wander_distance = fields[9].Get<float>();
2608 creatureData.currentwaypoint = fields[10].Get<uint32>();
2609 creatureData.curhealth = fields[11].Get<uint32>();
2610 creatureData.curmana = fields[12].Get<uint32>();
2611 creatureData.movementType = fields[13].Get<uint8>();
2612 creatureData.spawnMask = fields[14].Get<uint8>();
2613 creatureData.phaseMask = fields[15].Get<uint32>();
2614 creatureData.npcflag = fields[16].Get<uint32>();
2615 creatureData.unit_flags = fields[17].Get<uint32>();
2616 creatureData.dynamicflags = fields[18].Get<uint32>();
2617 creatureData.ScriptId = GetScriptId(fields[19].Get<std::string>());
2618 creatureData.spawnGroupId = 0;
2619
2620 if (!creatureData.ScriptId)
2621 creatureData.ScriptId = cInfo->ScriptID;
2622
2623 // Load alternate entries from creature_multispawn
2624 QueryResult variantResult = WorldDatabase.Query("SELECT entry FROM creature_multispawn WHERE spawnId = {} ORDER BY entry", spawnId);
2625 if (variantResult)
2626 {
2627 do
2628 {
2629 uint32 variantEntry = variantResult->Fetch()[0].Get<uint32>();
2630 if (!GetCreatureTemplate(variantEntry))
2631 {
2632 LOG_ERROR("sql.sql", "Table `creature_multispawn` has creature (SpawnId: {}) with non-existing entry {}, skipped.", spawnId, variantEntry);
2633 continue;
2634 }
2635
2636 // Check difficulty entries for variant
2637 bool diffOk = true;
2638 for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && diffOk; ++diff)
2639 {
2640 if (_difficultyEntries[diff].find(variantEntry) != _difficultyEntries[diff].end())
2641 {
2642 LOG_ERROR("sql.sql", "Table `creature_multispawn` has creature (SpawnId: {}) with entry {} listed as difficulty template in `creature_template`, skipped.",
2643 spawnId, variantEntry);
2644 diffOk = false;
2645 }
2646 }
2647 if (!diffOk)
2648 continue;
2649
2650 // Validate equipment for variant entry
2651 if (creatureData.equipmentId != 0 && !GetEquipmentInfo(variantEntry, creatureData.equipmentId))
2652 {
2653 LOG_ERROR("sql.sql", "Table `creature_multispawn` has creature (SpawnId: {}) with entry {} where equipment_id {} not found in `creature_equip_template`.",
2654 spawnId, variantEntry, creatureData.equipmentId);
2655 }
2656
2657 if (!creatureData.id2)
2658 creatureData.id2 = variantEntry;
2659 else if (!creatureData.id3)
2660 creatureData.id3 = variantEntry;
2661 else
2662 LOG_ERROR("sql.sql", "Table `creature_multispawn` has more than 2 variant entries for creature (SpawnId: {}), extra entry {} skipped.", spawnId, variantEntry);
2663 } while (variantResult->NextRow());
2664 }
2665
2666 MapEntry const* mapEntry = sMapStore.LookupEntry(creatureData.mapid);
2667 if (!mapEntry)
2668 {
2669 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) that spawned at non-existing map (Id: {}), skipped.", spawnId, creatureData.mapid);
2670 _creatureDataStore.erase(spawnId);
2671 return nullptr;
2672 }
2673
2674 if (mapEntry->IsRaid() && creatureData.spawntimesecs >= 7 * DAY && creatureData.spawntimesecs < 14 * DAY)
2675 creatureData.spawntimesecs = 14 * DAY;
2676
2677 bool ok = true;
2678 for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff)
2679 {
2680 if (_difficultyEntries[diff].find(creatureId) != _difficultyEntries[diff].end())
2681 {
2682 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) that is listed as difficulty {} template (Entry: {}) in `creature_template`, skipped.",
2683 spawnId, diff + 1, creatureId);
2684 ok = false;
2685 }
2686 }
2687
2688 if (!ok)
2689 {
2690 _creatureDataStore.erase(spawnId);
2691 return nullptr;
2692 }
2693
2694 if (creatureData.equipmentId != 0)
2695 {
2696 if (!GetEquipmentInfo(creatureId, creatureData.equipmentId))
2697 {
2698 LOG_ERROR("sql.sql", "Table `creature` has creature (Entry: {}) with equipment_id {} not found in table `creature_equip_template`, set to no equipment.",
2699 creatureId, creatureData.equipmentId);
2700 creatureData.equipmentId = 0;
2701 }
2702 }
2703
2704 if (creatureData.movementType >= MAX_DB_MOTION_TYPE)
2705 {
2706 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entry: {}) with wrong movement generator type ({}), set to IDLE.",
2707 spawnId, creatureId, creatureData.movementType);
2708 creatureData.movementType = IDLE_MOTION_TYPE;
2709 }
2710
2711 if (creatureData.wander_distance < 0.0f)
2712 {
2713 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entry: {}) with `wander_distance`< 0, set to 0.",
2714 spawnId, creatureId);
2715 creatureData.wander_distance = 0.0f;
2716 }
2717 else if (creatureData.movementType == RANDOM_MOTION_TYPE)
2718 {
2719 if (creatureData.wander_distance == 0.0f)
2720 {
2721 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entry: {}) with `MovementType`=1 (random movement) but with `wander_distance`=0, replace by idle movement type (0).",
2722 spawnId, creatureId);
2723 creatureData.movementType = IDLE_MOTION_TYPE;
2724 }
2725 }
2726 else if (creatureData.movementType == IDLE_MOTION_TYPE)
2727 {
2728 if (creatureData.wander_distance != 0.0f)
2729 {
2730 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entry: {}) with `MovementType`=0 (idle) have `wander_distance`<>0, set to 0.",
2731 spawnId, creatureId);
2732 creatureData.wander_distance = 0.0f;
2733 }
2734 }
2735
2736 if (creatureData.phaseMask == 0)
2737 {
2738 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entry: {}) with `phaseMask`=0 (not visible for anyone), set to 1.",
2739 spawnId, creatureId);
2740 creatureData.phaseMask = 1;
2741 }
2742
2743 return &creatureData;
2744}
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:1454
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 ( )
10193{
10194 uint32 oldMSTime = getMSTime();
10195
10197
10198 if (QueryResult result = WorldDatabase.Query("SELECT CreatureId, TrainerId FROM creature_default_trainer"))
10199 {
10200 do
10201 {
10202 Field* fields = result->Fetch();
10203 uint32 creatureId = fields[0].Get<uint32>();
10204 uint32 trainerId = fields[1].Get<uint32>();
10205
10206 if (!GetCreatureTemplate(creatureId))
10207 {
10208 LOG_ERROR("sql.sql", "Table `creature_default_trainer` references non-existing creature template (CreatureId: %u), ignoring", creatureId);
10209 continue;
10210 }
10211
10212 _creatureDefaultTrainers[creatureId] = trainerId;
10213
10214 } while (result->NextRow());
10215 }
10216
10217 LOG_INFO("server.loading", ">> Loaded {} default trainers in {} ms", _creatureDefaultTrainers.size(), GetMSTimeDiffToNow(oldMSTime));
10218}

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

◆ LoadCreatureLocales()

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

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

◆ LoadCreatureModelInfo()

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

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

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 ( )
9043{
9044 LoadQuestRelationsHelper(_creatureQuestInvolvedRelations, "creature_questender", false, false);
9045
9046 for (QuestRelations::iterator itr = _creatureQuestInvolvedRelations.begin(); itr != _creatureQuestInvolvedRelations.end(); ++itr)
9047 {
9048 CreatureTemplate const* cInfo = GetCreatureTemplate(itr->first);
9049 if (!cInfo)
9050 LOG_ERROR("sql.sql", "Table `creature_questender` have data for not existed creature entry ({}) and existed quest {}", itr->first, itr->second);
9051 else if (!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER))
9052 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);
9053 }
9054}
@ UNIT_NPC_FLAG_QUESTGIVER
Definition UnitDefines.h:323
void LoadQuestRelationsHelper(QuestRelations &map, std::string const &table, bool starter, bool go)
Definition ObjectMgr.cpp:8955

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

Referenced by LoadQuestStartersAndEnders().

◆ LoadCreatureQuestItems()

void ObjectMgr::LoadCreatureQuestItems ( )
11218{
11219 uint32 oldMSTime = getMSTime();
11220
11221 // 0 1 2
11222 QueryResult result = WorldDatabase.Query("SELECT CreatureEntry, ItemId, Idx FROM creature_questitem ORDER BY Idx ASC");
11223
11224 if (!result)
11225 {
11226 LOG_WARN("server.loading", ">> Loaded 0 creature quest items. DB table `creature_questitem` is empty.");
11227 return;
11228 }
11229
11230 uint32 count = 0;
11231 do
11232 {
11233 Field* fields = result->Fetch();
11234
11235 uint32 entry = fields[0].Get<uint32>();
11236 uint32 item = fields[1].Get<uint32>();
11237 uint32 idx = fields[2].Get<uint32>();
11238
11239 CreatureTemplate const* creatureInfo = GetCreatureTemplate(entry);
11240 if (!creatureInfo)
11241 {
11242 LOG_ERROR("sql.sql", "Table `creature_questitem` has data for nonexistent creature (entry: {}, idx: {}), skipped", entry, idx);
11243 continue;
11244 };
11245
11246 ItemEntry const* dbcData = sItemStore.LookupEntry(item);
11247 if (!dbcData)
11248 {
11249 LOG_ERROR("sql.sql", "Table `creature_questitem` has nonexistent item (ID: {}) in creature (entry: {}, idx: {}), skipped", item, entry, idx);
11250 continue;
11251 };
11252
11253 _creatureQuestItemStore[entry].push_back(item);
11254
11255 ++count;
11256 } while (result->NextRow());
11257
11258 LOG_INFO("server.loading", ">> Loaded {} Creature Quest Items in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
11259 LOG_INFO("server.loading", " ");
11260}
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 ( )
9029{
9030 LoadQuestRelationsHelper(_creatureQuestRelations, "creature_queststarter", true, false);
9031
9032 for (QuestRelations::iterator itr = _creatureQuestRelations.begin(); itr != _creatureQuestRelations.end(); ++itr)
9033 {
9034 CreatureTemplate const* cInfo = GetCreatureTemplate(itr->first);
9035 if (!cInfo)
9036 LOG_ERROR("sql.sql", "Table `creature_queststarter` have data for not existed creature entry ({}) and existed quest {}", itr->first, itr->second);
9037 else if (!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER))
9038 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);
9039 }
9040}

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

Referenced by LoadQuestStartersAndEnders().

◆ LoadCreatures()

void ObjectMgr::LoadCreatures ( )
2321{
2322 uint32 oldMSTime = getMSTime();
2323
2324 // 0 1 2 3 4 5 6 7 8 9
2325 QueryResult result = WorldDatabase.Query("SELECT creature.guid, id, map, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, wander_distance, "
2326 // 10 11 12 13 14 15 16 17 18 19 20
2327 "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags, "
2328 // 21
2329 "creature.ScriptName "
2330 "FROM creature "
2331 "LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid "
2332 "LEFT OUTER JOIN pool_creature ON creature.guid = pool_creature.guid");
2333
2334 if (!result)
2335 {
2336 LOG_WARN("server.loading", ">> Loaded 0 creatures. DB table `creature` is empty.");
2337 LOG_INFO("server.loading", " ");
2338 return;
2339 }
2340
2342 LOG_INFO("server.loading", "Calculating zone and area fields. This may take a moment...");
2343
2344 // Build single time for check spawnmask
2345 std::map<uint32, uint32> spawnMasks;
2346 for (uint32 i = 0; i < sMapStore.GetNumRows(); ++i)
2347 if (sMapStore.LookupEntry(i))
2348 for (int k = 0; k < MAX_DIFFICULTY; ++k)
2350 spawnMasks[i] |= (1 << k);
2351
2352 _creatureDataStore.rehash(result->GetRowCount());
2353 uint32 count = 0;
2354 do
2355 {
2356 Field* fields = result->Fetch();
2357
2358 ObjectGuid::LowType spawnId = fields[0].Get<uint32>();
2359 uint32 creatureId = fields[1].Get<uint32>();
2360
2361 CreatureTemplate const* cInfo = GetCreatureTemplate(creatureId);
2362 if (!cInfo)
2363 {
2364 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non existing creature entry {} in `id` field, skipped.", spawnId, creatureId);
2365 continue;
2366 }
2367 CreatureData& data = _creatureDataStore[spawnId];
2368 data.spawnId = spawnId;
2369 data.id = creatureId;
2370 data.mapid = fields[2].Get<uint16>();
2371 data.equipmentId = fields[3].Get<int8>();
2372 data.posX = fields[4].Get<float>();
2373 data.posY = fields[5].Get<float>();
2374 data.posZ = fields[6].Get<float>();
2375 data.orientation = fields[7].Get<float>();
2376 data.spawntimesecs = fields[8].Get<uint32>();
2377 data.wander_distance = fields[9].Get<float>();
2378 data.currentwaypoint = fields[10].Get<uint32>();
2379 data.curhealth = fields[11].Get<uint32>();
2380 data.curmana = fields[12].Get<uint32>();
2381 data.movementType = fields[13].Get<uint8>();
2382 data.spawnMask = fields[14].Get<uint8>();
2383 data.phaseMask = fields[15].Get<uint32>();
2384 int16 gameEvent = fields[16].Get<int16>();
2385 uint32 PoolId = fields[17].Get<uint32>();
2386 data.npcflag = fields[18].Get<uint32>();
2387 data.unit_flags = fields[19].Get<uint32>();
2388 data.dynamicflags = fields[20].Get<uint32>();
2389 data.ScriptId = GetScriptId(fields[21].Get<std::string>());
2390 data.spawnGroupId = 0;
2391
2392 if (!data.ScriptId)
2393 data.ScriptId = cInfo->ScriptID;
2394
2395 MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid);
2396 if (!mapEntry)
2397 {
2398 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {}) that spawned at not existed map (Id: {}), skipped.", spawnId, data.mapid);
2399 continue;
2400 }
2401
2402 // pussywizard: 7 days means no reaspawn, so set it to 14 days, because manual id reset may be late
2403 if (mapEntry->IsRaid() && data.spawntimesecs >= 7 * DAY && data.spawntimesecs < 14 * DAY)
2404 data.spawntimesecs = 14 * DAY;
2405
2406 // Skip spawnMask check for transport maps
2407 if (!_transportMaps.count(data.mapid))
2408 {
2409 if (data.spawnMask & ~spawnMasks[data.mapid])
2410 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {}) that have wrong spawn mask {} including not supported difficulty modes for map (Id: {}).",
2411 spawnId, data.spawnMask, data.mapid);
2412 }
2413 else
2414 data.spawnGroupId = 1; // force compatibility group for transport spawns
2415
2416 bool ok = true;
2417 for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff)
2418 {
2419 if (_difficultyEntries[diff].find(data.id) != _difficultyEntries[diff].end())
2420 {
2421 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {}) that listed as difficulty {} template (Entry: {}) in `creature_template`, skipped.",
2422 spawnId, diff + 1, data.id);
2423 ok = false;
2424 }
2425 }
2426 if (!ok)
2427 continue;
2428
2429 // -1 random, 0 no equipment,
2430 if (data.equipmentId != 0)
2431 {
2432 if (!GetEquipmentInfo(data.id, data.equipmentId))
2433 {
2434 LOG_ERROR("sql.sql", "Table `creature` have creature (Entry: {}) with equipment_id {} not found in table `creature_equip_template`, set to no equipment.",
2435 data.id, data.equipmentId);
2436 data.equipmentId = 0;
2437 }
2438 }
2439 if (cInfo->HasFlagsExtra(CREATURE_FLAG_EXTRA_INSTANCE_BIND))
2440 {
2441 if (!mapEntry->IsDungeon())
2442 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entry: {}) with `creature_template`.`flags_extra` including CREATURE_FLAG_EXTRA_INSTANCE_BIND but creature are not in instance.",
2443 spawnId, data.id);
2444 }
2445 if (data.movementType >= MAX_DB_MOTION_TYPE)
2446 {
2447 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entry: {}) with wrong movement generator type ({}), ignored and set to IDLE.", spawnId, data.id, data.movementType);
2449 }
2450 if (data.wander_distance < 0.0f)
2451 {
2452 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entry: {}) with `wander_distance`< 0, set to 0.", spawnId, data.id);
2453 data.wander_distance = 0.0f;
2454 }
2455 else if (data.movementType == RANDOM_MOTION_TYPE)
2456 {
2457 if (data.wander_distance == 0.0f)
2458 {
2459 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entry: {}) with `MovementType`=1 (random movement) but with `wander_distance`=0, replace by idle movement type (0).",
2460 spawnId, data.id);
2462 }
2463 }
2464 else if (data.movementType == IDLE_MOTION_TYPE)
2465 {
2466 if (data.wander_distance != 0.0f)
2467 {
2468 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entry: {}) with `MovementType`=0 (idle) have `wander_distance`<>0, set to 0.", spawnId, data.id);
2469 data.wander_distance = 0.0f;
2470 }
2471 }
2472
2473 if (data.phaseMask == 0)
2474 {
2475 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entry: {}) with `phaseMask`=0 (not visible for anyone), set to 1.", spawnId, data.id);
2476 data.phaseMask = 1;
2477 }
2478
2480 {
2481 uint32 zoneId = sMapMgr->GetZoneId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
2482 uint32 areaId = sMapMgr->GetAreaId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
2483
2485
2486 stmt->SetData(0, zoneId);
2487 stmt->SetData(1, areaId);
2488 stmt->SetData(2, spawnId);
2489
2490 WorldDatabase.Execute(stmt);
2491 }
2492
2493 // Add to grid if not managed by the game event or pool system
2494 if (gameEvent == 0 && PoolId == 0)
2495 AddCreatureToGrid(spawnId, &data);
2496
2497 ++count;
2498 } while (result->NextRow());
2499
2500 // Load alternate entries from creature_multispawn
2501 QueryResult variantResult = WorldDatabase.Query("SELECT spawnId, entry FROM creature_multispawn ORDER BY spawnId");
2502 if (variantResult)
2503 {
2504 uint32 variantCount = 0;
2505 do
2506 {
2507 Field* fields = variantResult->Fetch();
2508 ObjectGuid::LowType spawnId = fields[0].Get<uint32>();
2509 uint32 entry = fields[1].Get<uint32>();
2510
2511 auto creatureDataIt = _creatureDataStore.find(spawnId);
2512 if (creatureDataIt == _creatureDataStore.end())
2513 {
2514 LOG_ERROR("sql.sql", "Table `creature_multispawn` has entry for non-existing creature spawn (SpawnId: {}), skipped.", spawnId);
2515 continue;
2516 }
2517
2518 CreatureData* data = &creatureDataIt->second;
2519
2520 CreatureTemplate const* variantInfo = GetCreatureTemplate(entry);
2521 if (!variantInfo)
2522 {
2523 LOG_ERROR("sql.sql", "Table `creature_multispawn` has creature (SpawnId: {}) with non-existing creature entry {}, skipped.", spawnId, entry);
2524 continue;
2525 }
2526
2527 // Check difficulty entries for variant
2528 bool diffOk = true;
2529 for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && diffOk; ++diff)
2530 {
2531 if (_difficultyEntries[diff].find(entry) != _difficultyEntries[diff].end())
2532 {
2533 LOG_ERROR("sql.sql", "Table `creature_multispawn` has creature (SpawnId: {}) with entry {} listed as difficulty template in `creature_template`, skipped.",
2534 spawnId, entry);
2535 diffOk = false;
2536 }
2537 }
2538 if (!diffOk)
2539 continue;
2540
2541 // Validate equipment for variant entry
2542 if (data->equipmentId != 0 && !GetEquipmentInfo(entry, data->equipmentId))
2543 {
2544 LOG_ERROR("sql.sql", "Table `creature_multispawn` has creature (SpawnId: {}) with entry {} where equipment_id {} not found in `creature_equip_template`.",
2545 spawnId, entry, data->equipmentId);
2546 }
2547
2548 // Populate id2/id3 fields
2549 if (!data->id2)
2550 {
2551 data->id2 = entry;
2552 ++variantCount;
2553 }
2554 else if (!data->id3)
2555 {
2556 data->id3 = entry;
2557 ++variantCount;
2558 }
2559 else
2560 LOG_ERROR("sql.sql", "Table `creature_multispawn` has more than 2 variant entries for creature (SpawnId: {}), extra entry {} skipped.", spawnId, entry);
2561 } while (variantResult->NextRow());
2562
2563 LOG_INFO("server.loading", ">> Loaded {} creature spawn variants", variantCount);
2564 }
2565
2566 LOG_INFO("server.loading", ">> Loaded {} Creatures in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2567 LOG_INFO("server.loading", " ");
2568}
@ CREATURE_FLAG_EXTRA_INSTANCE_BIND
Definition CreatureData.h:46
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:112
@ WORLD_UPD_CREATURE_ZONE_AREA_DATA
Definition WorldDatabase.h:114
uint32 ScriptId
Definition SpawnData.h:76

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(), CreatureData::id, CreatureData::id2, CreatureData::id3, IDLE_MOTION_TYPE, MapEntry::IsDungeon(), MapEntry::IsRaid(), LOG_ERROR, LOG_INFO, LOG_WARN, SpawnData::mapid, MAX_DB_MOTION_TYPE, MAX_DIFFICULTY, CreatureData::movementType, CreatureData::npcflag, SpawnData::orientation, SpawnData::phaseMask, SpawnData::posX, SpawnData::posY, SpawnData::posZ, RANDOM_MOTION_TYPE, SpawnData::ScriptId, PreparedStatementBase::SetData(), sMapMgr, sMapStore, SpawnData::spawnGroupId, SpawnData::spawnId, SpawnData::spawnMask, CreatureData::spawntimesecs, sWorld, CreatureData::unit_flags, CreatureData::wander_distance, WORLD_UPD_CREATURE_ZONE_AREA_DATA, and WorldDatabase.

◆ LoadCreatureSparring()

void ObjectMgr::LoadCreatureSparring ( )
2747{
2748 uint32 oldMSTime = getMSTime();
2749
2750 QueryResult result = WorldDatabase.Query("SELECT GUID, SparringPCT FROM creature_sparring");
2751
2752 if (!result)
2753 {
2754 LOG_WARN("server.loading", ">> Loaded 0 sparring data. DB table `creature_sparring` is empty.");
2755 LOG_INFO("server.loading", " ");
2756 return;
2757 }
2758
2759 uint32 count = 0;
2760 do
2761 {
2762 Field* fields = result->Fetch();
2763
2764 ObjectGuid::LowType spawnId = fields[0].Get<uint32>();
2765 float sparringHealthPct = fields[1].Get<float>();
2766
2767 if (!GetCreatureData(spawnId))
2768 {
2769 LOG_ERROR("sql.sql", "Entry {} has a record in `creature_sparring` but doesn't exist in `creatures` table");
2770 continue;
2771 }
2772
2773 _creatureSparringStore[spawnId].push_back(sparringHealthPct);
2774
2775 ++count;
2776 } while (result->NextRow());
2777
2778 LOG_INFO("server.loading", ">> Loaded {} sparring data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2779 LOG_INFO("server.loading", " ");
2780}

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.
586{
587 uint32 entry = fields[0].Get<uint32>();
588
589 CreatureTemplate& creatureTemplate = _creatureTemplateStore[entry];
590
591 // enlarge the fast cache as necessary
592 if (_creatureTemplateStoreFast.size() < entry + 1)
593 {
594 _creatureTemplateStoreFast.resize(entry + 1, nullptr);
595 }
596
597 // load a pointer to this creatureTemplate into the fast cache
598 _creatureTemplateStoreFast[entry] = &creatureTemplate;
599
600 // build the creatureTemplate
601 creatureTemplate.Entry = entry;
602
603 for (uint8 i = 0; i < MAX_DIFFICULTY - 1; ++i)
604 {
605 creatureTemplate.DifficultyEntry[i] = fields[1 + i].Get<uint32>();
606 }
607
608 for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i)
609 {
610 creatureTemplate.KillCredit[i] = fields[4 + i].Get<uint32>();
611 }
612 creatureTemplate.Name = fields[6].Get<std::string>();
613 creatureTemplate.SubName = fields[7].Get<std::string>();
614 creatureTemplate.IconName = fields[8].Get<std::string>();
615 creatureTemplate.GossipMenuId = fields[9].Get<uint32>();
616 creatureTemplate.minlevel = fields[10].Get<uint8>();
617 creatureTemplate.maxlevel = fields[11].Get<uint8>();
618 creatureTemplate.expansion = uint32(fields[12].Get<int16>());
619 creatureTemplate.faction = uint32(fields[13].Get<uint16>());
620 creatureTemplate.npcflag = fields[14].Get<uint32>();
621 creatureTemplate.speed_walk = fields[15].Get<float>();
622 creatureTemplate.speed_run = fields[16].Get<float>();
623 creatureTemplate.speed_swim = fields[17].Get<float>();
624 creatureTemplate.speed_flight = fields[18].Get<float>();
625 creatureTemplate.detection_range = fields[19].Get<float>();
626 creatureTemplate.rank = uint32(fields[20].Get<uint8>());
627 creatureTemplate.dmgschool = uint32(fields[21].Get<int8>());
628 creatureTemplate.DamageModifier = fields[22].Get<float>();
629 creatureTemplate.BaseAttackTime = fields[23].Get<uint32>();
630 creatureTemplate.RangeAttackTime = fields[24].Get<uint32>();
631 creatureTemplate.BaseVariance = fields[25].Get<float>();
632 creatureTemplate.RangeVariance = fields[26].Get<float>();
633 creatureTemplate.unit_class = uint32(fields[27].Get<uint8>());
634 creatureTemplate.unit_flags = fields[28].Get<uint32>();
635 creatureTemplate.unit_flags2 = fields[29].Get<uint32>();
636 creatureTemplate.dynamicflags = fields[30].Get<uint32>();
637 creatureTemplate.family = uint32(fields[31].Get<uint8>());
638 creatureTemplate.type = uint32(fields[32].Get<uint8>());
639 creatureTemplate.type_flags = fields[33].Get<uint32>();
640 creatureTemplate.lootid = fields[34].Get<uint32>();
641 creatureTemplate.pickpocketLootId = fields[35].Get<uint32>();
642 creatureTemplate.SkinLootId = fields[36].Get<uint32>();
643
644 for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
645 {
646 creatureTemplate.resistance[i] = 0;
647 }
648
649 for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
650 {
651 creatureTemplate.spells[i] = 0;
652 }
653
654 creatureTemplate.PetSpellDataId = fields[37].Get<uint32>();
655 creatureTemplate.VehicleId = fields[38].Get<uint32>();
656 creatureTemplate.mingold = fields[39].Get<uint32>();
657 creatureTemplate.maxgold = fields[40].Get<uint32>();
658 creatureTemplate.AIName = fields[41].Get<std::string>();
659 creatureTemplate.MovementType = uint32(fields[42].Get<uint8>());
660 if (!fields[43].IsNull())
661 {
662 creatureTemplate.Movement.Ground = static_cast<CreatureGroundMovementType>(fields[43].Get<uint8>());
663 }
664
665 creatureTemplate.Movement.Swim = fields[44].Get<bool>();
666 if (!fields[45].IsNull())
667 {
668 creatureTemplate.Movement.Flight = static_cast<CreatureFlightMovementType>(fields[45].Get<uint8>());
669 }
670
671 creatureTemplate.Movement.Rooted = fields[46].Get<bool>();
672 if (!fields[47].IsNull())
673 {
674 creatureTemplate.Movement.Chase = static_cast<CreatureChaseMovementType>(fields[47].Get<uint8>());
675 }
676 if (!fields[48].IsNull())
677 {
678 creatureTemplate.Movement.Random = static_cast<CreatureRandomMovementType>(fields[48].Get<uint8>());
679 }
680 if (!fields[49].IsNull())
681 {
682 creatureTemplate.Movement.InteractionPauseTimer = fields[49].Get<uint32>();
683 }
684
685 creatureTemplate.HoverHeight = fields[50].Get<float>();
686 creatureTemplate.ModHealth = fields[51].Get<float>();
687 creatureTemplate.ModMana = fields[52].Get<float>();
688 creatureTemplate.ModArmor = fields[53].Get<float>();
689 creatureTemplate.ModExperience = fields[54].Get<float>();
690 creatureTemplate.RacialLeader = fields[55].Get<bool>();
691 creatureTemplate.movementId = fields[56].Get<uint32>();
692 creatureTemplate.RegenHealth = fields[57].Get<bool>();
693 creatureTemplate.CreatureImmunitiesId = fields[58].Get<int32>();
694 creatureTemplate.flags_extra = fields[59].Get<uint32>();
695 creatureTemplate.ScriptID = GetScriptId(fields[60].Get<std::string>());
696
697 // Warn about deprecated immunity flags that should be moved to `creature_immunities` table
698 if (creatureTemplate.flags_extra & CREATURE_FLAG_EXTRA_NO_TAUNT)
699 LOG_WARN("server.loading", "Creature (Entry: {}) has deprecated flags_extra bit NO_TAUNT (0x100) set. This will be migrated to the `creature_immunities` table in a future update.", entry);
700 if (creatureTemplate.flags_extra & CREATURE_FLAG_EXTRA_AVOID_AOE)
701 LOG_WARN("server.loading", "Creature (Entry: {}) has deprecated flags_extra bit AVOID_AOE (0x400000) set. This will be migrated to the `creature_immunities` table in a future update.", entry);
702 if (creatureTemplate.flags_extra & CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK)
703 LOG_WARN("server.loading", "Creature (Entry: {}) has deprecated flags_extra bit IMMUNITY_KNOCKBACK (0x40000000) set. This will be migrated to the `creature_immunities` table in a future update.", entry);
704
705 // useful if the creature template load is being triggered from outside this class
706 if (triggerHook)
707 {
708 sScriptMgr->OnAfterDatabaseLoadCreatureTemplates(_creatureTemplateStoreFast);
709 }
710}
@ CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK
Definition CreatureData.h:76
@ CREATURE_FLAG_EXTRA_NO_TAUNT
Definition CreatureData.h:54
@ CREATURE_FLAG_EXTRA_AVOID_AOE
Definition CreatureData.h:68
std::int32_t int32
Definition Define.h:103
#define sScriptMgr
Definition ScriptMgr.h:740
@ SPELL_SCHOOL_HOLY
Definition SharedDefines.h:272
uint32 Entry
Definition CreatureData.h:188

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

Referenced by LoadCreatureTemplates().

◆ LoadCreatureTemplateAddons()

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

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

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

Referenced by LoadCreatureTemplates().

◆ LoadCreatureTemplateResistances()

void ObjectMgr::LoadCreatureTemplateResistances ( )
765{
766 uint32 oldMSTime = getMSTime();
767
768 // 0 1 2
769 QueryResult result = WorldDatabase.Query("SELECT CreatureID, School, Resistance FROM creature_template_resistance");
770
771 if (!result)
772 {
773 LOG_WARN("server.loading", ">> Loaded 0 creature template resistance definitions. DB table `creature_template_resistance` is empty.");
774 LOG_INFO("server.loading", " ");
775 return;
776 }
777
778 uint32 count = 0;
779
780 do
781 {
782 Field* fields = result->Fetch();
783
784 uint32 creatureID = fields[0].Get<uint32>();
785 uint8 school = fields[1].Get<uint8>();
786
787 if (school == SPELL_SCHOOL_NORMAL || school >= MAX_SPELL_SCHOOL)
788 {
789 LOG_ERROR("sql.sql", "creature_template_resistance has resistance definitions for creature {} but this school {} doesn't exist", creatureID, school);
790 continue;
791 }
792
793 CreatureTemplateContainer::iterator itr = _creatureTemplateStore.find(creatureID);
794 if (itr == _creatureTemplateStore.end())
795 {
796 LOG_ERROR("sql.sql", "creature_template_resistance has resistance definitions for creature {} but this creature doesn't exist", creatureID);
797 continue;
798 }
799
800 CreatureTemplate& creatureTemplate = itr->second;
801 creatureTemplate.resistance[school] = fields[2].Get<int16>();
802
803 ++count;
804 } while (result->NextRow());
805
806 LOG_INFO("server.loading", ">> Loaded {} Creature Template Resistances in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
807 LOG_INFO("server.loading", " ");
808}
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 ( )
524{
525 uint32 oldMSTime = getMSTime();
526
527// 0 1 2 3 4 5 6 7 8
528 QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, name, subname, IconName, "
529// 9 10 11 12 13 14 15 16 17 18 19 20 21
530 "gossip_menu_id, minlevel, maxlevel, exp, faction, npcflag, speed_walk, speed_run, speed_swim, speed_flight, detection_range, `rank`, dmgschool, "
531// 22 23 24 25 26 27 28 29 30 31
532 "DamageModifier, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, dynamicflags, family, "
533// 32 33 34 35 36
534 "type, type_flags, lootid, pickpocketloot, skinloot, "
535// 37 38 39 40 41 42 43 44 45 46
536 "PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, ctm.Ground, ctm.Swim, ctm.Flight, ctm.Rooted, "
537// 47 48 49 50 51 52 53 54 55 56 57
538 "ctm.Chase, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, ManaModifier, ArmorModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, "
539// 58 59 60
540 "CreatureImmunitiesId, flags_extra, ScriptName "
541 "FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId ORDER BY entry DESC;");
542
543 if (!result)
544 {
545 LOG_WARN("server.loading", ">> Loaded 0 creature template definitions. DB table `creature_template` is empty.");
546 return;
547 }
548
549 _creatureTemplateStore.rehash(result->GetRowCount());
551
552 uint32 count = 0;
553 do
554 {
555 Field* fields = result->Fetch();
556 LoadCreatureTemplate(fields);
557 ++count;
558 } while (result->NextRow());
559
560 // We load the creature models after loading but before checking
562
563 sScriptMgr->OnAfterDatabaseLoadCreatureTemplates(_creatureTemplateStoreFast);
564
567
568 // Checking needs to be done after loading because of the difficulty self referencing
569 for (CreatureTemplateContainer::iterator itr = _creatureTemplateStore.begin(); itr != _creatureTemplateStore.end(); ++itr)
570 {
571 CheckCreatureTemplate(&itr->second);
572 itr->second.InitializeQueryData();
573 }
574
575 LOG_INFO("server.loading", ">> Loaded {} Creature Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
576 LOG_INFO("server.loading", " ");
577}
void LoadCreatureTemplateResistances()
Definition ObjectMgr.cpp:764
void LoadCreatureTemplateSpells()
Definition ObjectMgr.cpp:810
void CheckCreatureTemplate(CreatureTemplate const *cInfo)
Definition ObjectMgr.cpp:964
void LoadCreatureTemplate(Field *fields, bool triggerHook=false)
Loads a creature template from a database result.
Definition ObjectMgr.cpp:585
void LoadCreatureTemplateModels()
Definition ObjectMgr.cpp:712

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

◆ LoadCreatureTemplateSpells()

void ObjectMgr::LoadCreatureTemplateSpells ( )
811{
812 uint32 oldMSTime = getMSTime();
813
814 // 0 1 2
815 QueryResult result = WorldDatabase.Query("SELECT CreatureID, `Index`, Spell FROM creature_template_spell");
816
817 if (!result)
818 {
819 LOG_WARN("server.loading", ">> Loaded 0 creature template spell definitions. DB table `creature_template_spell` is empty.");
820 LOG_INFO("server.loading", " ");
821 return;
822 }
823
824 uint32 count = 0;
825
826 do
827 {
828 Field* fields = result->Fetch();
829
830 uint32 creatureID = fields[0].Get<uint32>();
831 uint8 index = fields[1].Get<uint8>();
832
833 if (index >= MAX_CREATURE_SPELLS)
834 {
835 LOG_ERROR("sql.sql", "creature_template_spell has spell definitions for creature {} with a incorrect index {}", creatureID, index);
836 continue;
837 }
838
839 CreatureTemplateContainer::iterator itr = _creatureTemplateStore.find(creatureID);
840 if (itr == _creatureTemplateStore.end())
841 {
842 LOG_ERROR("sql.sql", "creature_template_spell has spell definitions for creature {} but this creature doesn't exist", creatureID);
843 continue;
844 }
845
846 CreatureTemplate& creatureTemplate = itr->second;
847 creatureTemplate.spells[index] = fields[2].Get<uint32>();
848
849 ++count;
850 } while (result->NextRow());
851
852 LOG_INFO("server.loading", ">> Loaded {} Creature Template Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
853 LOG_INFO("server.loading", " ");
854}
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 ( )
1481{
1482 uint32 oldMSTime = getMSTime();
1483
1484 // 0 1 2 3 4
1485 QueryResult result = WorldDatabase.Query("SELECT CreatureID, ID, ItemID1, ItemID2, ItemID3 FROM creature_equip_template");
1486
1487 if (!result)
1488 {
1489 LOG_WARN("server.loading", ">> Loaded 0 creature equipment templates. DB table `creature_equip_template` is empty!");
1490 LOG_INFO("server.loading", " ");
1491 return;
1492 }
1493
1494 uint32 count = 0;
1495 do
1496 {
1497 Field* fields = result->Fetch();
1498
1499 uint32 entry = fields[0].Get<uint32>();
1500
1501 if (!GetCreatureTemplate(entry))
1502 {
1503 LOG_ERROR("sql.sql", "Creature template (CreatureID: {}) does not exist but has a record in `creature_equip_template`", entry);
1504 continue;
1505 }
1506
1507 uint8 id = fields[1].Get<uint8>();
1508 if (!id)
1509 {
1510 LOG_ERROR("sql.sql", "Creature equipment template with id 0 found for creature {}, skipped.", entry);
1511 continue;
1512 }
1513
1514 EquipmentInfo& equipmentInfo = _equipmentInfoStore[entry][id];
1515
1516 equipmentInfo.ItemEntry[0] = fields[2].Get<uint32>();
1517 equipmentInfo.ItemEntry[1] = fields[3].Get<uint32>();
1518 equipmentInfo.ItemEntry[2] = fields[4].Get<uint32>();
1519
1520 for (uint8 i = 0; i < MAX_EQUIPMENT_ITEMS; ++i)
1521 {
1522 if (!equipmentInfo.ItemEntry[i])
1523 continue;
1524
1525 ItemEntry const* dbcItem = sItemStore.LookupEntry(equipmentInfo.ItemEntry[i]);
1526
1527 if (!dbcItem)
1528 {
1529 LOG_ERROR("sql.sql", "Unknown item (ID={}) in creature_equip_template.ItemID{} for CreatureID = {} and ID = {}, forced to 0.",
1530 equipmentInfo.ItemEntry[i], i + 1, entry, id);
1531 equipmentInfo.ItemEntry[i] = 0;
1532 continue;
1533 }
1534
1535 if (dbcItem->InventoryType != INVTYPE_WEAPON &&
1536 dbcItem->InventoryType != INVTYPE_SHIELD &&
1537 dbcItem->InventoryType != INVTYPE_RANGED &&
1538 dbcItem->InventoryType != INVTYPE_2HWEAPON &&
1541 dbcItem->InventoryType != INVTYPE_HOLDABLE &&
1542 dbcItem->InventoryType != INVTYPE_THROWN &&
1544 {
1545 LOG_ERROR("sql.sql", "Item (ID={}) in creature_equip_template.ItemID{} for CreatureID = {} and ID = {} is not equipable in a hand, forced to 0.",
1546 equipmentInfo.ItemEntry[i], i + 1, entry, id);
1547 equipmentInfo.ItemEntry[i] = 0;
1548 }
1549 }
1550
1551 ++count;
1552 } while (result->NextRow());
1553
1554 LOG_INFO("server.loading", ">> Loaded {} Equipment Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1555 LOG_INFO("server.loading", " ");
1556}
#define MAX_EQUIPMENT_ITEMS
Definition CreatureData.h:36
@ 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:360
uint32 ItemEntry[MAX_EQUIPMENT_ITEMS]
Definition CreatureData.h:361
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 ( )
6269{
6271
6272 std::set<uint32> evt_scripts;
6273 // Load all possible script entries from gameobjects
6275 for (GameObjectTemplateContainer::const_iterator itr = gotc->begin(); itr != gotc->end(); ++itr)
6276 if (uint32 eventId = itr->second.GetEventScriptId())
6277 evt_scripts.insert(eventId);
6278
6279 // Load all possible script entries from spells
6280 for (uint32 i = 1; i < sSpellMgr->GetSpellInfoStoreSize(); ++i)
6281 if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(i))
6282 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
6283 if (spell->Effects[j].Effect == SPELL_EFFECT_SEND_EVENT)
6284 if (spell->Effects[j].MiscValue)
6285 evt_scripts.insert(spell->Effects[j].MiscValue);
6286
6287 for (std::size_t path_idx = 0; path_idx < sTaxiPathNodesByPath.size(); ++path_idx)
6288 {
6289 for (std::size_t node_idx = 0; node_idx < sTaxiPathNodesByPath[path_idx].size(); ++node_idx)
6290 {
6291 TaxiPathNodeEntry const* node = sTaxiPathNodesByPath[path_idx][node_idx];
6292
6293 if (node->arrivalEventID)
6294 evt_scripts.insert(node->arrivalEventID);
6295
6296 if (node->departureEventID)
6297 evt_scripts.insert(node->departureEventID);
6298 }
6299 }
6300
6301 // Then check if all scripts are in above list of possible script entries
6302 for (ScriptMapMap::const_iterator itr = sEventScripts.begin(); itr != sEventScripts.end(); ++itr)
6303 {
6304 std::set<uint32>::const_iterator itr2 = evt_scripts.find(itr->first);
6305 if (itr2 == evt_scripts.end())
6306 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 {}",
6307 itr->first, SPELL_EFFECT_SEND_EVENT);
6308 }
6309}
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:61
@ SCRIPTS_EVENT
Definition ObjectMgr.h:152
@ SPELL_EFFECT_SEND_EVENT
Definition SharedDefines.h:827
GameObjectTemplateContainer const * GetGameObjectTemplates() const
Definition ObjectMgr.h:766
void LoadScripts(ScriptsType type)
Definition ObjectMgr.cpp:5926
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 ( )
8155{
8156 uint32 oldMSTime = getMSTime();
8157
8158 QueryResult result = WorldDatabase.Query("SELECT level, basexp FROM exploration_basexp");
8159
8160 if (!result)
8161 {
8162 LOG_WARN("server.loading", ">> Loaded 0 BaseXP definitions. DB table `exploration_basexp` is empty.");
8163 LOG_INFO("server.loading", " ");
8164 return;
8165 }
8166
8167 uint32 count = 0;
8168
8169 do
8170 {
8171 Field* fields = result->Fetch();
8172 uint8 level = fields[0].Get<uint8>();
8173 uint32 basexp = fields[1].Get<int32>();
8174 _baseXPTable[level] = basexp;
8175 ++count;
8176 } while (result->NextRow());
8177
8178 LOG_INFO("server.loading", ">> Loaded {} BaseXP Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8179 LOG_INFO("server.loading", " ");
8180}

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

◆ LoadFactionChangeAchievements()

void ObjectMgr::LoadFactionChangeAchievements ( )
10900{
10901 uint32 oldMSTime = getMSTime();
10902
10903 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_achievement");
10904
10905 if (!result)
10906 {
10907 LOG_WARN("server.loading", ">> Loaded 0 faction change achievement pairs. DB table `player_factionchange_achievement` is empty.");
10908 LOG_INFO("server.loading", " ");
10909 return;
10910 }
10911
10912 uint32 count = 0;
10913
10914 do
10915 {
10916 Field* fields = result->Fetch();
10917
10918 uint32 alliance = fields[0].Get<uint32>();
10919 uint32 horde = fields[1].Get<uint32>();
10920
10921 if (!sAchievementStore.LookupEntry(alliance))
10922 LOG_ERROR("sql.sql", "Achievement {} (alliance_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", alliance);
10923 else if (!sAchievementStore.LookupEntry(horde))
10924 LOG_ERROR("sql.sql", "Achievement {} (horde_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", horde);
10925 else
10926 FactionChangeAchievements[alliance] = horde;
10927
10928 ++count;
10929 } while (result->NextRow());
10930
10931 LOG_INFO("server.loading", ">> Loaded {} faction change achievement pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10932 LOG_INFO("server.loading", " ");
10933}
CharacterConversionMap FactionChangeAchievements
Definition ObjectMgr.h:1505

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

◆ LoadFactionChangeItems()

void ObjectMgr::LoadFactionChangeItems ( )
10936{
10937 uint32 oldMSTime = getMSTime();
10938
10939 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_items");
10940
10941 if (!result)
10942 {
10943 LOG_WARN("server.loading", ">> Loaded 0 faction change item pairs. DB table `player_factionchange_items` is empty.");
10944 LOG_INFO("server.loading", " ");
10945 return;
10946 }
10947
10948 uint32 count = 0;
10949
10950 do
10951 {
10952 Field* fields = result->Fetch();
10953
10954 uint32 alliance = fields[0].Get<uint32>();
10955 uint32 horde = fields[1].Get<uint32>();
10956
10957 if (!GetItemTemplate(alliance))
10958 LOG_ERROR("sql.sql", "Item {} (alliance_id) referenced in `player_factionchange_items` does not exist, pair skipped!", alliance);
10959 else if (!GetItemTemplate(horde))
10960 LOG_ERROR("sql.sql", "Item {} (horde_id) referenced in `player_factionchange_items` does not exist, pair skipped!", horde);
10961 else
10962 FactionChangeItems[alliance] = horde;
10963
10964 ++count;
10965 } while (result->NextRow());
10966
10967 LOG_INFO("server.loading", ">> Loaded {} faction change item pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10968 LOG_INFO("server.loading", " ");
10969}
CharacterConversionMap FactionChangeItems
Definition ObjectMgr.h:1506

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

◆ LoadFactionChangeQuests()

void ObjectMgr::LoadFactionChangeQuests ( )
10972{
10973 uint32 oldMSTime = getMSTime();
10974
10975 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_quests");
10976
10977 if (!result)
10978 {
10979 LOG_WARN("server.loading", ">> Loaded 0 faction change quest pairs. DB table `player_factionchange_quests` is empty.");
10980 LOG_INFO("server.loading", " ");
10981 return;
10982 }
10983
10984 uint32 count = 0;
10985
10986 do
10987 {
10988 Field* fields = result->Fetch();
10989
10990 uint32 alliance = fields[0].Get<uint32>();
10991 uint32 horde = fields[1].Get<uint32>();
10992
10993 if (!GetQuestTemplate(alliance))
10994 LOG_ERROR("sql.sql", "Quest {} (alliance_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", alliance);
10995 else if (!GetQuestTemplate(horde))
10996 LOG_ERROR("sql.sql", "Quest {} (horde_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", horde);
10997 else
10998 FactionChangeQuests[alliance] = horde;
10999
11000 ++count;
11001 } while (result->NextRow());
11002
11003 LOG_INFO("server.loading", ">> Loaded {} faction change quest pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
11004 LOG_INFO("server.loading", " ");
11005}
CharacterConversionMap FactionChangeQuests
Definition ObjectMgr.h:1507

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

◆ LoadFactionChangeReputations()

void ObjectMgr::LoadFactionChangeReputations ( )
11008{
11009 uint32 oldMSTime = getMSTime();
11010
11011 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_reputations");
11012
11013 if (!result)
11014 {
11015 LOG_WARN("server.loading", ">> Loaded 0 faction change reputation pairs. DB table `player_factionchange_reputations` is empty.");
11016 LOG_INFO("server.loading", " ");
11017 return;
11018 }
11019
11020 uint32 count = 0;
11021
11022 do
11023 {
11024 Field* fields = result->Fetch();
11025
11026 uint32 alliance = fields[0].Get<uint32>();
11027 uint32 horde = fields[1].Get<uint32>();
11028
11029 if (!sFactionStore.LookupEntry(alliance))
11030 LOG_ERROR("sql.sql", "Reputation {} (alliance_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", alliance);
11031 else if (!sFactionStore.LookupEntry(horde))
11032 LOG_ERROR("sql.sql", "Reputation {} (horde_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", horde);
11033 else
11034 FactionChangeReputation[alliance] = horde;
11035
11036 ++count;
11037 } while (result->NextRow());
11038
11039 LOG_INFO("server.loading", ">> Loaded {} faction change reputation pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
11040 LOG_INFO("server.loading", " ");
11041}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
CharacterConversionMap FactionChangeReputation
Definition ObjectMgr.h:1508

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

◆ LoadFactionChangeSpells()

void ObjectMgr::LoadFactionChangeSpells ( )
11044{
11045 uint32 oldMSTime = getMSTime();
11046
11047 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_spells");
11048
11049 if (!result)
11050 {
11051 LOG_WARN("server.loading", ">> Loaded 0 faction change spell pairs. DB table `player_factionchange_spells` is empty.");
11052 LOG_INFO("server.loading", " ");
11053 return;
11054 }
11055
11056 uint32 count = 0;
11057
11058 do
11059 {
11060 Field* fields = result->Fetch();
11061
11062 uint32 alliance = fields[0].Get<uint32>();
11063 uint32 horde = fields[1].Get<uint32>();
11064
11065 if (!sSpellMgr->GetSpellInfo(alliance))
11066 LOG_ERROR("sql.sql", "Spell {} (alliance_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", alliance);
11067 else if (!sSpellMgr->GetSpellInfo(horde))
11068 LOG_ERROR("sql.sql", "Spell {} (horde_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", horde);
11069 else
11070 FactionChangeSpells[alliance] = horde;
11071
11072 ++count;
11073 } while (result->NextRow());
11074
11075 LOG_INFO("server.loading", ">> Loaded {} faction change spell pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
11076 LOG_INFO("server.loading", " ");
11077}
CharacterConversionMap FactionChangeSpells
Definition ObjectMgr.h:1509

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

◆ LoadFactionChangeTitles()

void ObjectMgr::LoadFactionChangeTitles ( )
11080{
11081 uint32 oldMSTime = getMSTime();
11082
11083 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_titles");
11084
11085 if (!result)
11086 {
11087 LOG_WARN("server.loading", ">> Loaded 0 faction change title pairs. DB table `player_factionchange_title` is empty.");
11088 return;
11089 }
11090
11091 uint32 count = 0;
11092
11093 do
11094 {
11095 Field* fields = result->Fetch();
11096
11097 uint32 alliance = fields[0].Get<uint32>();
11098 uint32 horde = fields[1].Get<uint32>();
11099
11100 if (!sCharTitlesStore.LookupEntry(alliance))
11101 LOG_ERROR("sql.sql", "Title {} (alliance_id) referenced in `player_factionchange_title` does not exist, pair skipped!", alliance);
11102 else if (!sCharTitlesStore.LookupEntry(horde))
11103 LOG_ERROR("sql.sql", "Title {} (horde_id) referenced in `player_factionchange_title` does not exist, pair skipped!", horde);
11104 else
11105 FactionChangeTitles[alliance] = horde;
11106
11107 ++count;
11108 } while (result->NextRow());
11109
11110 LOG_INFO("server.loading", ">> Loaded {} faction change title pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
11111 LOG_INFO("server.loading", " ");
11112}
DBCStorage< CharTitlesEntry > sCharTitlesStore(CharTitlesEntryfmt)
CharacterConversionMap FactionChangeTitles
Definition ObjectMgr.h:1510

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

◆ LoadFishingBaseSkillLevel()

void ObjectMgr::LoadFishingBaseSkillLevel ( )
9724{
9725 uint32 oldMSTime = getMSTime();
9726
9727 _fishingBaseForAreaStore.clear(); // for reload case
9728
9729 QueryResult result = WorldDatabase.Query("SELECT entry, skill FROM skill_fishing_base_level");
9730
9731 if (!result)
9732 {
9733 LOG_WARN("server.loading", ">> Loaded 0 areas for fishing base skill level. DB table `skill_fishing_base_level` is empty.");
9734 LOG_INFO("server.loading", " ");
9735 return;
9736 }
9737
9738 uint32 count = 0;
9739
9740 do
9741 {
9742 Field* fields = result->Fetch();
9743 uint32 entry = fields[0].Get<uint32>();
9744 int32 skill = fields[1].Get<int16>();
9745
9746 AreaTableEntry const* fArea = sAreaTableStore.LookupEntry(entry);
9747 if (!fArea)
9748 {
9749 LOG_ERROR("sql.sql", "AreaId {} defined in `skill_fishing_base_level` does not exist", entry);
9750 continue;
9751 }
9752
9753 _fishingBaseForAreaStore[entry] = skill;
9754 ++count;
9755 } while (result->NextRow());
9756
9757 LOG_INFO("server.loading", ">> Loaded {} areas for fishing base skill level in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9758 LOG_INFO("server.loading", " ");
9759}

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

◆ LoadGameObjectAddons()

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

References _gameObjectAddonStore, Field::Get(), GetGameObjectData(), getMSTime(), GetMSTimeDiffToNow(), goData, 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.
3109{
3110 GameObjectData const* data = GetGameObjectData(spawnId);
3111 if (data)
3112 return data;
3113
3114 QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
3115 "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, "
3116 "ScriptName "
3117 "FROM gameobject WHERE gameobject.guid = {}", spawnId);
3118
3119 if (!result)
3120 return nullptr;
3121
3122 Field* fields = result->Fetch();
3123 uint32 entry = fields[1].Get<uint32>();
3124
3125 GameObjectTemplate const* gInfo = GetGameObjectTemplate(entry);
3126 if (!gInfo)
3127 {
3128 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {}) with non-existing gameobject entry {}, skipped.", spawnId, entry);
3129 return nullptr;
3130 }
3131
3132 if (gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId))
3133 {
3134 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry {} GoType: {}) with an invalid displayId ({}), not loaded.",
3135 spawnId, entry, gInfo->type, gInfo->displayId);
3136 return nullptr;
3137 }
3138
3140 goData.id = entry;
3141 goData.mapid = fields[2].Get<uint16>();
3142 goData.posX = fields[3].Get<float>();
3143 goData.posY = fields[4].Get<float>();
3144 goData.posZ = fields[5].Get<float>();
3145 goData.orientation = fields[6].Get<float>();
3146 goData.rotation.x = fields[7].Get<float>();
3147 goData.rotation.y = fields[8].Get<float>();
3148 goData.rotation.z = fields[9].Get<float>();
3149 goData.rotation.w = fields[10].Get<float>();
3150 goData.spawntimesecs = fields[11].Get<int32>();
3151 goData.animprogress = fields[12].Get<uint8>();
3152 goData.artKit = 0;
3153 goData.ScriptId = GetScriptId(fields[16].Get<std::string>());
3154
3155 if (!goData.ScriptId)
3156 goData.ScriptId = gInfo->ScriptId;
3157
3158 MapEntry const* mapEntry = sMapStore.LookupEntry(goData.mapid);
3159 if (!mapEntry)
3160 {
3161 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) spawned on a non-existing map (Id: {}), skipped.", spawnId, entry, goData.mapid);
3162 _gameObjectDataStore.erase(spawnId);
3163 return nullptr;
3164 }
3165
3166 if (goData.spawntimesecs == 0 && gInfo->IsDespawnAtAction())
3167 {
3168 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);
3169 }
3170
3171 uint32 go_state = fields[13].Get<uint8>();
3172 if (go_state >= MAX_GO_STATE)
3173 {
3174 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid `state` ({}) value, skipped.", spawnId, entry, go_state);
3175 _gameObjectDataStore.erase(spawnId);
3176 return nullptr;
3177 }
3178 goData.go_state = GOState(go_state);
3179
3180 goData.spawnMask = fields[14].Get<uint8>();
3181 goData.phaseMask = fields[15].Get<uint32>();
3182
3183 if (goData.rotation.x < -1.0f || goData.rotation.x > 1.0f)
3184 {
3185 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationX ({}) value, skipped.", spawnId, entry, goData.rotation.x);
3186 _gameObjectDataStore.erase(spawnId);
3187 return nullptr;
3188 }
3189
3190 if (goData.rotation.y < -1.0f || goData.rotation.y > 1.0f)
3191 {
3192 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationY ({}) value, skipped.", spawnId, entry, goData.rotation.y);
3193 _gameObjectDataStore.erase(spawnId);
3194 return nullptr;
3195 }
3196
3197 if (goData.rotation.z < -1.0f || goData.rotation.z > 1.0f)
3198 {
3199 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationZ ({}) value, skipped.", spawnId, entry, goData.rotation.z);
3200 _gameObjectDataStore.erase(spawnId);
3201 return nullptr;
3202 }
3203
3204 if (goData.rotation.w < -1.0f || goData.rotation.w > 1.0f)
3205 {
3206 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationW ({}) value, skipped.", spawnId, entry, goData.rotation.w);
3207 _gameObjectDataStore.erase(spawnId);
3208 return nullptr;
3209 }
3210
3211 if (fabs(goData.rotation.x * goData.rotation.x + goData.rotation.y * goData.rotation.y +
3212 goData.rotation.z * goData.rotation.z + goData.rotation.w * goData.rotation.w - 1.0f) >= 1e-5f)
3213 {
3214 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);
3215 goData.rotation = G3D::Quat(G3D::Matrix3::fromEulerAnglesZYX(goData.orientation, 0.0f, 0.0f));
3216 }
3217
3218 if (!MapMgr::IsValidMapCoord(goData.mapid, goData.posX, goData.posY, goData.posZ, goData.orientation))
3219 {
3220 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid coordinates, skipped.", spawnId, entry);
3221 _gameObjectDataStore.erase(spawnId);
3222 return nullptr;
3223 }
3224
3225 if (goData.phaseMask == 0)
3226 {
3227 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with `phaseMask`=0 (not visible for anyone), set to 1.", spawnId, entry);
3228 goData.phaseMask = 1;
3229 }
3230
3231 return &goData;
3232}
DBCStorage< GameObjectDisplayInfoEntry > sGameObjectDisplayInfoStore(GameObjectDisplayInfofmt)
#define MAX_GO_STATE
Definition GameObjectData.h:28
GOState
Definition GameObjectData.h:707
static bool IsValidMapCoord(uint32 mapid, Position const &pos)
Definition MapMgr.h:90

References _gameObjectDataStore, Field::Get(), GetGameObjectData(), GetGameObjectTemplate(), GetScriptId(), goData, MapMgr::IsValidMapCoord(), LOG_ERROR, MAX_GO_STATE, sGameObjectDisplayInfoStore, sMapStore, and WorldDatabase.

◆ LoadGameObjectForQuests()

void ObjectMgr::LoadGameObjectForQuests ( )
9510{
9511 uint32 oldMSTime = getMSTime();
9512
9513 if (GetGameObjectTemplates()->empty())
9514 {
9515 LOG_WARN("server.loading", ">> Loaded 0 GameObjects for quests");
9516 LOG_INFO("server.loading", " ");
9517 return;
9518 }
9519
9520 uint32 count = 0;
9521
9522 // collect GO entries for GO that must activated
9524 for (GameObjectTemplateContainer::iterator itr = gotc->begin(); itr != gotc->end(); ++itr)
9525 {
9526 itr->second.IsForQuests = false;
9527 switch (itr->second.type)
9528 {
9530 itr->second.IsForQuests = true;
9531 ++count;
9532 break;
9534 {
9535 // scan GO chest with loot including quest items
9536 uint32 loot_id = (itr->second.GetLootId());
9537
9538 // find quest loot for GO
9539 if (itr->second.chest.questId || LootTemplates_Gameobject.HaveQuestLootFor(loot_id))
9540 {
9541 itr->second.IsForQuests = true;
9542 ++count;
9543 }
9544 break;
9545 }
9547 {
9548 if (itr->second._generic.questID > 0) //quests objects
9549 {
9550 itr->second.IsForQuests = true;
9551 ++count;
9552 }
9553 break;
9554 }
9556 {
9557 if (itr->second.spellFocus.questID > 0) //quests objects
9558 {
9559 itr->second.IsForQuests = true;
9560 ++count;
9561 }
9562 break;
9563 }
9565 {
9566 if (itr->second.goober.questId > 0) //quests objects
9567 {
9568 itr->second.IsForQuests = true;
9569 ++count;
9570 }
9571 break;
9572 }
9573 default:
9574 break;
9575 }
9576 }
9577
9578 LOG_INFO("server.loading", ">> Loaded {} GameObjects for quests in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9579 LOG_INFO("server.loading", " ");
9580}
LootStore LootTemplates_Gameobject("gameobject_loot_template", "gameobject entry", true)
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition SharedDefines.h:1572
@ GAMEOBJECT_TYPE_GENERIC
Definition SharedDefines.h:1569
@ GAMEOBJECT_TYPE_CHEST
Definition SharedDefines.h:1567
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition SharedDefines.h:1566
@ GAMEOBJECT_TYPE_GOOBER
Definition SharedDefines.h:1574
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 ( )
7799{
7800 uint32 oldMSTime = getMSTime();
7801
7802 _gameObjectLocaleStore.clear(); // need for reload case
7803
7804 // 0 1 2 3
7805 QueryResult result = WorldDatabase.Query("SELECT entry, locale, name, castBarCaption FROM gameobject_template_locale");
7806 if (!result)
7807 return;
7808
7809 do
7810 {
7811 Field* fields = result->Fetch();
7812
7813 uint32 ID = fields[0].Get<uint32>();
7814
7815 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
7816 if (locale == LOCALE_enUS)
7817 continue;
7818
7820 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
7821 AddLocaleString(fields[3].Get<std::string>(), locale, data.CastBarCaption);
7822 } while (result->NextRow());
7823
7824 LOG_INFO("server.loading", ">> Loaded {} Gameobject Locale Strings in {} ms", (uint32)_gameObjectLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
7825}
Definition GameObjectData.h:677
std::vector< std::string > Name
Definition GameObjectData.h:678
std::vector< std::string > CastBarCaption
Definition GameObjectData.h:679

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

◆ LoadGameobjectQuestEnders()

void ObjectMgr::LoadGameobjectQuestEnders ( )
9015{
9016 LoadQuestRelationsHelper(_goQuestInvolvedRelations, "gameobject_questender", false, true);
9017
9018 for (QuestRelations::iterator itr = _goQuestInvolvedRelations.begin(); itr != _goQuestInvolvedRelations.end(); ++itr)
9019 {
9020 GameObjectTemplate const* goInfo = GetGameObjectTemplate(itr->first);
9021 if (!goInfo)
9022 LOG_ERROR("sql.sql", "Table `gameobject_questender` have data for not existed gameobject entry ({}) and existed quest {}", itr->first, itr->second);
9023 else if (goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER)
9024 LOG_ERROR("sql.sql", "Table `gameobject_questender` have data gameobject entry ({}) for quest {}, but GO is not GAMEOBJECT_TYPE_QUESTGIVER", itr->first, itr->second);
9025 }
9026}

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

Referenced by LoadQuestStartersAndEnders().

◆ LoadGameObjectQuestItems()

void ObjectMgr::LoadGameObjectQuestItems ( )
11173{
11174 uint32 oldMSTime = getMSTime();
11175
11176 // 0 1 2
11177 QueryResult result = WorldDatabase.Query("SELECT GameObjectEntry, ItemId, Idx FROM gameobject_questitem ORDER BY Idx ASC");
11178
11179 if (!result)
11180 {
11181 LOG_WARN("server.loading", ">> Loaded 0 gameobject quest items. DB table `gameobject_questitem` is empty.");
11182 return;
11183 }
11184
11185 uint32 count = 0;
11186 do
11187 {
11188 Field* fields = result->Fetch();
11189
11190 uint32 entry = fields[0].Get<uint32>();
11191 uint32 item = fields[1].Get<uint32>();
11192 uint32 idx = fields[2].Get<uint32>();
11193
11194 GameObjectTemplate const* goInfo = GetGameObjectTemplate(entry);
11195 if (!goInfo)
11196 {
11197 LOG_ERROR("sql.sql", "Table `gameobject_questitem` has data for nonexistent gameobject (entry: {}, idx: {}), skipped", entry, idx);
11198 continue;
11199 };
11200
11201 ItemEntry const* dbcData = sItemStore.LookupEntry(item);
11202 if (!dbcData)
11203 {
11204 LOG_ERROR("sql.sql", "Table `gameobject_questitem` has nonexistent item (ID: {}) in gameobject (entry: {}, idx: {}), skipped", item, entry, idx);
11205 continue;
11206 };
11207
11208 _gameObjectQuestItemStore[entry].push_back(item);
11209
11210 ++count;
11211 } while (result->NextRow());
11212
11213 LOG_INFO("server.loading", ">> Loaded {} Gameobject Quest Items in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
11214 LOG_INFO("server.loading", " ");
11215}

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

◆ LoadGameobjectQuestStarters()

void ObjectMgr::LoadGameobjectQuestStarters ( )
9001{
9002 LoadQuestRelationsHelper(_goQuestRelations, "gameobject_queststarter", true, true);
9003
9004 for (QuestRelations::iterator itr = _goQuestRelations.begin(); itr != _goQuestRelations.end(); ++itr)
9005 {
9006 GameObjectTemplate const* goInfo = GetGameObjectTemplate(itr->first);
9007 if (!goInfo)
9008 LOG_ERROR("sql.sql", "Table `gameobject_queststarter` have data for not existed gameobject entry ({}) and existed quest {}", itr->first, itr->second);
9009 else if (goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER)
9010 LOG_ERROR("sql.sql", "Table `gameobject_queststarter` have data gameobject entry ({}) for quest {}, but GO is not GAMEOBJECT_TYPE_QUESTGIVER", itr->first, itr->second);
9011 }
9012}

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

Referenced by LoadQuestStartersAndEnders().

◆ LoadGameobjects()

void ObjectMgr::LoadGameobjects ( )
2920{
2921 uint32 oldMSTime = getMSTime();
2922
2923 // 0 1 2 3 4 5 6
2924 QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
2925 // 7 8 9 10 11 12 13 14 15 16 17
2926 "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, eventEntry, pool_entry, "
2927 // 18
2928 "ScriptName "
2929 "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid "
2930 "LEFT OUTER JOIN pool_gameobject ON gameobject.guid = pool_gameobject.guid");
2931
2932 if (!result)
2933 {
2934 LOG_WARN("server.loading", ">> Loaded 0 gameobjects. DB table `gameobject` is empty.");
2935 LOG_INFO("server.loading", " ");
2936 return;
2937 }
2938
2940 LOG_INFO("server.loading", "Calculating zone and area fields. This may take a moment...");
2941
2942 // build single time for check spawnmask
2943 std::map<uint32, uint32> spawnMasks;
2944 for (uint32 i = 0; i < sMapStore.GetNumRows(); ++i)
2945 if (sMapStore.LookupEntry(i))
2946 for (int k = 0; k < MAX_DIFFICULTY; ++k)
2948 spawnMasks[i] |= (1 << k);
2949
2950 _gameObjectDataStore.rehash(result->GetRowCount());
2951 do
2952 {
2953 Field* fields = result->Fetch();
2954
2955 ObjectGuid::LowType guid = fields[0].Get<uint32>();
2956 uint32 entry = fields[1].Get<uint32>();
2957
2958 GameObjectTemplate const* gInfo = GetGameObjectTemplate(entry);
2959 if (!gInfo)
2960 {
2961 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {}) with non existing gameobject entry {}, skipped.", guid, entry);
2962 continue;
2963 }
2964
2965 if (!gInfo->displayId)
2966 {
2967 switch (gInfo->type)
2968 {
2971 break;
2972 default:
2973 LOG_ERROR("sql.sql", "Gameobject (GUID: {} Entry {} GoType: {}) doesn't have a displayId ({}), not loaded.", guid, entry, gInfo->type, gInfo->displayId);
2974 break;
2975 }
2976 }
2977
2978 if (gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId))
2979 {
2980 LOG_ERROR("sql.sql", "Gameobject (GUID: {} Entry {} GoType: {}) has an invalid displayId ({}), not loaded.", guid, entry, gInfo->type, gInfo->displayId);
2981 continue;
2982 }
2983
2985
2986 data.spawnId = guid;
2987 data.id = entry;
2988 data.mapid = fields[2].Get<uint16>();
2989 data.posX = fields[3].Get<float>();
2990 data.posY = fields[4].Get<float>();
2991 data.posZ = fields[5].Get<float>();
2992 data.orientation = fields[6].Get<float>();
2993 data.rotation.x = fields[7].Get<float>();
2994 data.rotation.y = fields[8].Get<float>();
2995 data.rotation.z = fields[9].Get<float>();
2996 data.rotation.w = fields[10].Get<float>();
2997 data.spawntimesecs = fields[11].Get<int32>();
2998 data.ScriptId = GetScriptId(fields[18].Get<std::string>());
2999 data.spawnGroupId = 0;
3000 if (!data.ScriptId)
3001 data.ScriptId = gInfo->ScriptId;
3002
3003 MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid);
3004 if (!mapEntry)
3005 {
3006 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) spawned on a non-existed map (Id: {}), skip", guid, data.id, data.mapid);
3007 continue;
3008 }
3009
3010 if (data.spawntimesecs == 0 && gInfo->IsDespawnAtAction())
3011 {
3012 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);
3013 }
3014
3015 data.animprogress = fields[12].Get<uint8>();
3016 data.artKit = 0;
3017
3018 uint32 go_state = fields[13].Get<uint8>();
3019 if (go_state >= MAX_GO_STATE)
3020 {
3021 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid `state` ({}) value, skip", guid, data.id, go_state);
3022 continue;
3023 }
3024 data.go_state = GOState(go_state);
3025
3026 data.spawnMask = fields[14].Get<uint8>();
3027
3028 if (!_transportMaps.count(data.mapid))
3029 {
3030 if (data.spawnMask & ~spawnMasks[data.mapid])
3031 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);
3032 }
3033 else
3034 data.spawnGroupId = 1; // force compatibility group for transport spawns
3035
3036 data.phaseMask = fields[15].Get<uint32>();
3037 int16 gameEvent = fields[16].Get<int16>();
3038 uint32 PoolId = fields[17].Get<uint32>();
3039
3040 if (data.rotation.x < -1.0f || data.rotation.x > 1.0f)
3041 {
3042 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationX ({}) value, skip", guid, data.id, data.rotation.x);
3043 continue;
3044 }
3045
3046 if (data.rotation.y < -1.0f || data.rotation.y > 1.0f)
3047 {
3048 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationY ({}) value, skip", guid, data.id, data.rotation.y);
3049 continue;
3050 }
3051
3052 if (data.rotation.z < -1.0f || data.rotation.z > 1.0f)
3053 {
3054 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationZ ({}) value, skip", guid, data.id, data.rotation.z);
3055 continue;
3056 }
3057
3058 if (data.rotation.w < -1.0f || data.rotation.w > 1.0f)
3059 {
3060 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationW ({}) value, skip", guid, data.id, data.rotation.w);
3061 continue;
3062 }
3063
3064 if (fabs(data.rotation.x * data.rotation.x + data.rotation.y * data.rotation.y +
3065 data.rotation.z * data.rotation.z + data.rotation.w * data.rotation.w - 1.0f) >= 1e-5f)
3066 {
3067 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);
3068 data.rotation = G3D::Quat(G3D::Matrix3::fromEulerAnglesZYX(data.orientation, 0.0f, 0.0f));
3069 }
3070
3071 if (!MapMgr::IsValidMapCoord(data.mapid, data.posX, data.posY, data.posZ, data.orientation))
3072 {
3073 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid coordinates, skip", guid, data.id);
3074 continue;
3075 }
3076
3077 if (data.phaseMask == 0)
3078 {
3079 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with `phaseMask`=0 (not visible for anyone), set to 1.", guid, data.id);
3080 data.phaseMask = 1;
3081 }
3082
3084 {
3085 uint32 zoneId = sMapMgr->GetZoneId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
3086 uint32 areaId = sMapMgr->GetAreaId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
3087
3089
3090 stmt->SetData(0, zoneId);
3091 stmt->SetData(1, areaId);
3092 stmt->SetData(2, guid);
3093
3094 WorldDatabase.Execute(stmt);
3095 }
3096
3097 if (gameEvent == 0 && PoolId == 0) // if not this is to be managed by GameEvent System or Pool system
3098 AddGameobjectToGrid(guid, &data);
3099 } while (result->NextRow());
3100
3101 LOG_INFO("server.loading", ">> Loaded {} Gameobjects in {} ms", (unsigned long)_gameObjectDataStore.size(), GetMSTimeDiffToNow(oldMSTime));
3102 LOG_INFO("server.loading", " ");
3103}
@ GAMEOBJECT_TYPE_TRAP
Definition SharedDefines.h:1570
@ CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA
Definition WorldConfig.h:113
@ 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, SpawnData::mapid, MAX_DIFFICULTY, MAX_GO_STATE, SpawnData::orientation, SpawnData::phaseMask, SpawnData::posX, SpawnData::posY, SpawnData::posZ, GameObjectData::rotation, SpawnData::ScriptId, PreparedStatementBase::SetData(), sGameObjectDisplayInfoStore, sMapMgr, sMapStore, SpawnData::spawnGroupId, SpawnData::spawnId, SpawnData::spawnMask, GameObjectData::spawntimesecs, sWorld, WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA, and WorldDatabase.

◆ LoadGameObjectSummons()

void ObjectMgr::LoadGameObjectSummons ( )
2240{
2241 uint32 oldMSTime = getMSTime();
2242
2243 _goSummonDataStore.clear();
2244
2245 // 0 1 2 3 4 5 6 7 8 9 10 11 12
2246 QueryResult result = WorldDatabase.Query("SELECT summonerId, summonerType, groupId, entry, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, respawnTime FROM gameobject_summon_groups");
2247
2248 if (!result)
2249 {
2250 LOG_WARN("server.loading", ">> Loaded 0 gameobject summons. DB table `gameobject_summon_groups` is empty.");
2251 return;
2252 }
2253
2254 uint32 count = 0;
2255 do
2256 {
2257 Field* fields = result->Fetch();
2258
2259 uint32 summonerId = fields[0].Get<uint32>();
2260 SummonerType summonerType = SummonerType(fields[1].Get<uint8>());
2261 uint8 group = fields[2].Get<uint8>();
2262
2263 switch (summonerType)
2264 {
2266 if (!GetCreatureTemplate(summonerId))
2267 {
2268 LOG_ERROR("sql.sql", "Table `gameobject_summon_groups` has summoner with non existing entry {} for creature summoner type, skipped.", summonerId);
2269 continue;
2270 }
2271 break;
2273 if (!GetGameObjectTemplate(summonerId))
2274 {
2275 LOG_ERROR("sql.sql", "Table `gameobject_summon_groups` has summoner with non existing entry {} for gameobject summoner type, skipped.", summonerId);
2276 continue;
2277 }
2278 break;
2279 case SUMMONER_TYPE_MAP:
2280 if (!sMapStore.LookupEntry(summonerId))
2281 {
2282 LOG_ERROR("sql.sql", "Table `gameobject_summon_groups` has summoner with non existing entry {} for map summoner type, skipped.", summonerId);
2283 continue;
2284 }
2285 break;
2286 default:
2287 LOG_ERROR("sql.sql", "Table `gameobject_summon_groups` has unhandled summoner type {} for summoner {}, skipped.", summonerType, summonerId);
2288 continue;
2289 }
2290
2292 data.entry = fields[3].Get<uint32>();
2293
2294 if (!GetGameObjectTemplate(data.entry))
2295 {
2296 LOG_ERROR("sql.sql", "Table `gameobject_summon_groups` has gameobject in group [Summoner ID: {}, Summoner Type: {}, Group ID: {}] with non existing gameobject entry {}, skipped.", summonerId, summonerType, group, data.entry);
2297 continue;
2298 }
2299
2300 float posX = fields[4].Get<float>();
2301 float posY = fields[5].Get<float>();
2302 float posZ = fields[6].Get<float>();
2303 float orientation = fields[7].Get<float>();
2304
2305 data.pos.Relocate(posX, posY, posZ, orientation);
2306
2307 data.rot = G3D::Quat(fields[8].Get<float>(), fields[9].Get<float>(), fields[10].Get<float>(), fields[11].Get<float>());
2308 data.respawnTime = fields[12].Get<uint32>();
2309
2310 TempSummonGroupKey key(summonerId, summonerType, group);
2311 _goSummonDataStore[key].push_back(data);
2312
2313 ++count;
2314 } while (result->NextRow());
2315
2316 LOG_INFO("server.loading", ">> Loaded {} Gameobject Summons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2317 LOG_INFO("server.loading", " ");
2318}
SummonerType
Definition TemporarySummon.h:25
@ SUMMONER_TYPE_MAP
Definition TemporarySummon.h:28
@ SUMMONER_TYPE_CREATURE
Definition TemporarySummon.h:26
@ SUMMONER_TYPE_GAMEOBJECT
Definition TemporarySummon.h:27
Stores data for temp gameobject summons.
Definition TemporarySummon.h:42
G3D::Quat rot
Definition TemporarySummon.h:45
uint32 respawnTime
Duration in seconds; passed to SummonGameObject's respawnTime parameter.
Definition TemporarySummon.h:46
uint32 entry
Definition TemporarySummon.h:43
Position pos
Definition TemporarySummon.h:44
void Relocate(float x, float y)
Definition Position.h:77

References _goSummonDataStore, GameObjectSummonData::entry, Field::Get(), GetCreatureTemplate(), GetGameObjectTemplate(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, GameObjectSummonData::pos, Position::Relocate(), GameObjectSummonData::respawnTime, GameObjectSummonData::rot, sMapStore, SUMMONER_TYPE_CREATURE, SUMMONER_TYPE_GAMEOBJECT, SUMMONER_TYPE_MAP, and WorldDatabase.

◆ LoadGameObjectTemplate()

void ObjectMgr::LoadGameObjectTemplate ( )
7887{
7888 uint32 oldMSTime = getMSTime();
7889
7890 // 0 1 2 3 4 5 6 7
7891 QueryResult result = WorldDatabase.Query("SELECT entry, type, displayId, name, IconName, castBarCaption, unk1, size, "
7892 // 8 9 10 11 12 13 14 15 16 17 18 19 20
7893 "Data0, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11, Data12, "
7894 // 21 22 23 24 25 26 27 28 29 30 31 32 33
7895 "Data13, Data14, Data15, Data16, Data17, Data18, Data19, Data20, Data21, Data22, Data23, AIName, ScriptName "
7896 "FROM gameobject_template");
7897
7898 if (!result)
7899 {
7900 LOG_WARN("server.loading", ">> Loaded 0 gameobject definitions. DB table `gameobject_template` is empty.");
7901 LOG_INFO("server.loading", " ");
7902 return;
7903 }
7904
7905 _gameObjectTemplateStore.rehash(result->GetRowCount());
7906 uint32 count = 0;
7907 do
7908 {
7909 Field* fields = result->Fetch();
7910
7911 uint32 entry = fields[0].Get<uint32>();
7912
7914
7915 got.entry = entry;
7916 got.type = uint32(fields[1].Get<uint8>());
7917 got.displayId = fields[2].Get<uint32>();
7918 got.name = fields[3].Get<std::string>();
7919 got.IconName = fields[4].Get<std::string>();
7920 got.castBarCaption = fields[5].Get<std::string>();
7921 got.unk1 = fields[6].Get<std::string>();
7922 got.size = fields[7].Get<float>();
7923
7924 for (uint8 i = 0; i < MAX_GAMEOBJECT_DATA; ++i)
7925 got.raw.data[i] = fields[8 + i].Get<int32>(); // data1 and data6 can be -1
7926
7927 got.AIName = fields[32].Get<std::string>();
7928 got.ScriptId = GetScriptId(fields[33].Get<std::string>());
7929 got.IsForQuests = false;
7930
7931 // Checks
7932 if (!got.AIName.empty() && !sGameObjectAIRegistry->HasItem(got.AIName))
7933 {
7934 LOG_ERROR("sql.sql", "GameObject (Entry: {}) has non-registered `AIName` '{}' set, removing", got.entry, got.AIName);
7935 }
7936
7937 switch (got.type)
7938 {
7939 case GAMEOBJECT_TYPE_DOOR: //0
7940 {
7941 if (got.door.lockId)
7942 CheckGOLockId(&got, got.door.lockId, 1);
7943 CheckGONoDamageImmuneId(&got, got.door.noDamageImmune, 3);
7944 break;
7945 }
7946 case GAMEOBJECT_TYPE_BUTTON: //1
7947 {
7948 if (got.button.lockId)
7949 CheckGOLockId(&got, got.button.lockId, 1);
7950 CheckGONoDamageImmuneId(&got, got.button.noDamageImmune, 4);
7951 break;
7952 }
7954 {
7955 if (got.questgiver.lockId)
7956 CheckGOLockId(&got, got.questgiver.lockId, 0);
7957 CheckGONoDamageImmuneId(&got, got.questgiver.noDamageImmune, 5);
7958 break;
7959 }
7960 case GAMEOBJECT_TYPE_CHEST: //3
7961 {
7962 if (got.chest.lockId)
7963 CheckGOLockId(&got, got.chest.lockId, 0);
7964
7965 CheckGOConsumable(&got, got.chest.consumable, 3);
7966
7967 if (got.chest.linkedTrapId) // linked trap
7968 CheckGOLinkedTrapId(&got, got.chest.linkedTrapId, 7);
7969 break;
7970 }
7971 case GAMEOBJECT_TYPE_TRAP: //6
7972 {
7973 if (got.trap.lockId)
7974 CheckGOLockId(&got, got.trap.lockId, 0);
7975 break;
7976 }
7977 case GAMEOBJECT_TYPE_CHAIR: //7
7978 CheckAndFixGOChairHeightId(&got, got.chair.height, 1);
7979 break;
7981 {
7982 if (got.spellFocus.focusId)
7983 {
7984 if (!sSpellFocusObjectStore.LookupEntry(got.spellFocus.focusId))
7985 LOG_ERROR("sql.sql", "GameObject (Entry: {} GoType: {}) have data0={} but SpellFocus (Id: {}) not exist.",
7986 entry, got.type, got.spellFocus.focusId, got.spellFocus.focusId);
7987 }
7988
7989 if (got.spellFocus.linkedTrapId) // linked trap
7990 CheckGOLinkedTrapId(&got, got.spellFocus.linkedTrapId, 2);
7991 break;
7992 }
7993 case GAMEOBJECT_TYPE_GOOBER: //10
7994 {
7995 if (got.goober.lockId)
7996 CheckGOLockId(&got, got.goober.lockId, 0);
7997
7998 CheckGOConsumable(&got, got.goober.consumable, 3);
7999
8000 if (got.goober.pageId) // pageId
8001 {
8002 if (!GetPageText(got.goober.pageId))
8003 LOG_ERROR("sql.sql", "GameObject (Entry: {} GoType: {}) have data7={} but PageText (Entry {}) not exist.",
8004 entry, got.type, got.goober.pageId, got.goober.pageId);
8005 }
8006 CheckGONoDamageImmuneId(&got, got.goober.noDamageImmune, 11);
8007 if (got.goober.linkedTrapId) // linked trap
8008 CheckGOLinkedTrapId(&got, got.goober.linkedTrapId, 12);
8009 break;
8010 }
8012 {
8013 if (got.areadamage.lockId)
8014 CheckGOLockId(&got, got.areadamage.lockId, 0);
8015 break;
8016 }
8017 case GAMEOBJECT_TYPE_CAMERA: //13
8018 {
8019 if (got.camera.lockId)
8020 CheckGOLockId(&got, got.camera.lockId, 0);
8021 break;
8022 }
8024 {
8025 if (got.moTransport.taxiPathId)
8026 {
8027 if (got.moTransport.taxiPathId >= sTaxiPathNodesByPath.size() || sTaxiPathNodesByPath[got.moTransport.taxiPathId].empty())
8028 LOG_ERROR("sql.sql", "GameObject (Entry: {} GoType: {}) have data0={} but TaxiPath (Id: {}) not exist.",
8029 entry, got.type, got.moTransport.taxiPathId, got.moTransport.taxiPathId);
8030 }
8031 if (uint32 transportMap = got.moTransport.mapID)
8032 _transportMaps.insert(transportMap);
8033 break;
8034 }
8036 break;
8038 {
8039 // always must have spell
8040 CheckGOSpellId(&got, got.spellcaster.spellId, 0);
8041 break;
8042 }
8043 case GAMEOBJECT_TYPE_FLAGSTAND: //24
8044 {
8045 if (got.flagstand.lockId)
8046 CheckGOLockId(&got, got.flagstand.lockId, 0);
8047 CheckGONoDamageImmuneId(&got, got.flagstand.noDamageImmune, 5);
8048 break;
8049 }
8051 {
8052 if (got.fishinghole.lockId)
8053 CheckGOLockId(&got, got.fishinghole.lockId, 4);
8054 break;
8055 }
8056 case GAMEOBJECT_TYPE_FLAGDROP: //26
8057 {
8058 if (got.flagdrop.lockId)
8059 CheckGOLockId(&got, got.flagdrop.lockId, 0);
8060 CheckGONoDamageImmuneId(&got, got.flagdrop.noDamageImmune, 3);
8061 break;
8062 }
8064 CheckAndFixGOChairHeightId(&got, got.barberChair.chairheight, 0);
8065 break;
8066 }
8067
8068 ++count;
8069 } while (result->NextRow());
8070
8071 LOG_INFO("server.loading", ">> Loaded {} Game Object Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8072 LOG_INFO("server.loading", " ");
8073}
DBCStorage< SpellFocusObjectEntry > sSpellFocusObjectStore(SpellFocusObjectfmt)
#define sGameObjectAIRegistry
Definition GameObjectAIFactory.h:49
void CheckGONoDamageImmuneId(GameObjectTemplate *goTemplate, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7867
void CheckGOSpellId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7846
void CheckAndFixGOChairHeightId(GameObjectTemplate const *goInfo, uint32 const &dataN, uint32 N)
Definition ObjectMgr.cpp:7855
void CheckGOConsumable(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7876
void CheckGOLinkedTrapId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7836
void CheckGOLockId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7827
@ GAMEOBJECT_TYPE_CAMERA
Definition SharedDefines.h:1577
@ GAMEOBJECT_TYPE_BUTTON
Definition SharedDefines.h:1565
@ GAMEOBJECT_TYPE_MO_TRANSPORT
Definition SharedDefines.h:1579
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition SharedDefines.h:1582
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition SharedDefines.h:1589
@ GAMEOBJECT_TYPE_FLAGDROP
Definition SharedDefines.h:1590
@ GAMEOBJECT_TYPE_SPELLCASTER
Definition SharedDefines.h:1586
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition SharedDefines.h:1588
@ GAMEOBJECT_TYPE_CHAIR
Definition SharedDefines.h:1571
@ GAMEOBJECT_TYPE_AREADAMAGE
Definition SharedDefines.h:1576
@ GAMEOBJECT_TYPE_BARBER_CHAIR
Definition SharedDefines.h:1596
@ GAMEOBJECT_TYPE_DOOR
Definition SharedDefines.h:1564
#define MAX_GAMEOBJECT_DATA
Definition SharedDefines.h:1603
PageText const * GetPageText(uint32 pageEntry)
Definition ObjectMgr.cpp:6510
uint32 entry
Definition GameObjectData.h:33

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 ( )
8076{
8077 uint32 oldMSTime = getMSTime();
8078
8079 // 0 1 2 3 4 5 6 7 8
8080 QueryResult result = WorldDatabase.Query("SELECT entry, faction, flags, mingold, maxgold, artkit0, artkit1, artkit2, artkit3 FROM gameobject_template_addon");
8081
8082 if (!result)
8083 {
8084 LOG_WARN("server.loading", ">> Loaded 0 gameobject template addon definitions. DB table `gameobject_template_addon` is empty.");
8085 LOG_INFO("server.loading", " ");
8086 return;
8087 }
8088
8089 uint32 count = 0;
8090 do
8091 {
8092 Field* fields = result->Fetch();
8093
8094 uint32 entry = fields[0].Get<uint32>();
8095
8096 GameObjectTemplate const* got = GetGameObjectTemplate(entry);
8097 if (!got)
8098 {
8099 LOG_ERROR("sql.sql",
8100 "GameObject template (Entry: {}) does not exist but has a record in `gameobject_template_addon`",
8101 entry);
8102 continue;
8103 }
8104
8106 gameObjectAddon.faction = uint32(fields[1].Get<uint16>());
8107 gameObjectAddon.flags = fields[2].Get<uint32>();
8108 gameObjectAddon.mingold = fields[3].Get<uint32>();
8109 gameObjectAddon.maxgold = fields[4].Get<uint32>();
8110
8111 for (uint32 i = 0; i < gameObjectAddon.artKits.size(); i++)
8112 {
8113 uint32 artKitID = fields[5 + i].Get<uint32>();
8114 if (!artKitID)
8115 continue;
8116
8117 if (!sGameObjectArtKitStore.LookupEntry(artKitID))
8118 {
8119 LOG_ERROR("sql.sql", "GameObject (Entry: {}) has invalid `artkit{}` {} defined, set to zero instead.", entry, i, artKitID);
8120 continue;
8121 }
8122
8123 gameObjectAddon.artKits[i] = artKitID;
8124 }
8125
8126 // checks
8127 if (gameObjectAddon.faction && !sFactionTemplateStore.LookupEntry(gameObjectAddon.faction))
8128 LOG_ERROR("sql.sql",
8129 "GameObject (Entry: {}) has invalid faction ({}) defined in `gameobject_template_addon`.",
8130 entry, gameObjectAddon.faction);
8131
8132 if (gameObjectAddon.maxgold > 0)
8133 {
8134 switch (got->type)
8135 {
8138 break;
8139 default:
8140 LOG_ERROR("sql.sql",
8141 "GameObject (Entry {} GoType: {}) cannot be looted but has maxgold set in `gameobject_template_addon`.",
8142 entry, got->type);
8143 break;
8144 }
8145 }
8146
8147 ++count;
8148 } while (result->NextRow());
8149
8150 LOG_INFO("server.loading", ">> Loaded {} Game Object Template Addons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8151 LOG_INFO("server.loading", " ");
8152}
DBCStorage< GameObjectArtKitEntry > sGameObjectArtKitStore(GameObjectArtKitfmt)
Definition GameObjectData.h:667
uint32 mingold
Definition GameObjectData.h:671
uint32 flags
Definition GameObjectData.h:670
uint32 faction
Definition GameObjectData.h:669
std::array< uint32, 4 > artKits
Definition GameObjectData.h:673
uint32 maxgold
Definition GameObjectData.h:672

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 ( )
9864{
9865 uint32 oldMSTime = getMSTime();
9866
9867 _gameTeleStore.clear(); // for reload case
9868
9869 // 0 1 2 3 4 5 6
9870 QueryResult result = WorldDatabase.Query("SELECT id, position_x, position_y, position_z, orientation, map, name FROM game_tele");
9871
9872 if (!result)
9873 {
9874 LOG_WARN("server.loading", ">> Loaded 0 GameTeleports. DB table `game_tele` is empty!");
9875 LOG_INFO("server.loading", " ");
9876 return;
9877 }
9878
9879 uint32 count = 0;
9880
9881 do
9882 {
9883 Field* fields = result->Fetch();
9884
9885 uint32 id = fields[0].Get<uint32>();
9886
9887 GameTele gt;
9888
9889 gt.position_x = fields[1].Get<float>();
9890 gt.position_y = fields[2].Get<float>();
9891 gt.position_z = fields[3].Get<float>();
9892 gt.orientation = fields[4].Get<float>();
9893 gt.mapId = fields[5].Get<uint16>();
9894 gt.name = fields[6].Get<std::string>();
9895
9896 if (!MapMgr::IsValidMapCoord(gt.mapId, gt.position_x, gt.position_y, gt.position_z, gt.orientation))
9897 {
9898 LOG_ERROR("sql.sql", "Wrong position for id {} (name: {}) in `game_tele` table, ignoring.", id, gt.name);
9899 continue;
9900 }
9901
9902 if (!Utf8toWStr(gt.name, gt.wnameLow))
9903 {
9904 LOG_ERROR("sql.sql", "Wrong UTF8 name for id {} in `game_tele` table, ignoring.", id);
9905 continue;
9906 }
9907
9908 wstrToLower(gt.wnameLow);
9909
9910 _gameTeleStore[id] = gt;
9911
9912 ++count;
9913 } while (result->NextRow());
9914
9915 LOG_INFO("server.loading", ">> Loaded {} GameTeleports in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9916 LOG_INFO("server.loading", " ");
9917}
float position_x
Definition ObjectMgr.h:136

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 ( )
10320{
10321 uint32 oldMSTime = getMSTime();
10322
10323 _gossipMenusStore.clear();
10324
10325 QueryResult result = WorldDatabase.Query("SELECT MenuID, TextID FROM gossip_menu");
10326
10327 if (!result)
10328 {
10329 LOG_WARN("server.loading", ">> Loaded 0 gossip_menu entries. DB table `gossip_menu` is empty!");
10330 LOG_INFO("server.loading", " ");
10331 return;
10332 }
10333
10334 do
10335 {
10336 Field* fields = result->Fetch();
10337
10338 GossipMenus gMenu;
10339
10340 gMenu.MenuID = fields[0].Get<uint32>();
10341 gMenu.TextID = fields[1].Get<uint32>();
10342
10343 if (!GetGossipText(gMenu.TextID))
10344 {
10345 LOG_ERROR("sql.sql", "Table gossip_menu entry {} are using non-existing TextID {}", gMenu.MenuID, gMenu.TextID);
10346 continue;
10347 }
10348
10349 _gossipMenusStore.insert(GossipMenusContainer::value_type(gMenu.MenuID, gMenu));
10350 } while (result->NextRow());
10351
10352 LOG_INFO("server.loading", ">> Loaded {} gossip_menu entries in {} ms", (uint32)_gossipMenusStore.size(), GetMSTimeDiffToNow(oldMSTime));
10353 LOG_INFO("server.loading", " ");
10354}
GossipText const * GetGossipText(uint32 Text_ID) const
Definition ObjectMgr.cpp:6688
Definition ObjectMgr.h:630
uint32 TextID
Definition ObjectMgr.h:632
uint32 MenuID
Definition ObjectMgr.h:631

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

◆ LoadGossipMenuItems()

void ObjectMgr::LoadGossipMenuItems ( )
10357{
10358 uint32 oldMSTime = getMSTime();
10359
10360 _gossipMenuItemsStore.clear();
10361
10362 QueryResult result = WorldDatabase.Query(
10363 // 0 1 2 3 4 5 6 7 8 9 10 11 12
10364 "SELECT MenuID, OptionID, OptionIcon, OptionText, OptionBroadcastTextID, OptionType, OptionNpcFlag, ActionMenuID, ActionPoiID, BoxCoded, BoxMoney, BoxText, BoxBroadcastTextID "
10365 "FROM gossip_menu_option ORDER BY MenuID, OptionID");
10366
10367 if (!result)
10368 {
10369 LOG_WARN("server.loading", ">> Loaded 0 gossip_menu_option IDs. DB table `gossip_menu_option` is empty!");
10370 LOG_INFO("server.loading", " ");
10371 return;
10372 }
10373
10374 do
10375 {
10376 Field* fields = result->Fetch();
10377
10378 GossipMenuItems gMenuItem;
10379
10380 gMenuItem.MenuID = fields[0].Get<uint32>();
10381 gMenuItem.OptionID = fields[1].Get<uint16>();
10382 gMenuItem.OptionIcon = fields[2].Get<uint32>();
10383 gMenuItem.OptionText = fields[3].Get<std::string>();
10384 gMenuItem.OptionBroadcastTextID = fields[4].Get<uint32>();
10385 gMenuItem.OptionType = fields[5].Get<uint8>();
10386 gMenuItem.OptionNpcFlag = fields[6].Get<uint32>();
10387 gMenuItem.ActionMenuID = fields[7].Get<uint32>();
10388 gMenuItem.ActionPoiID = fields[8].Get<uint32>();
10389 gMenuItem.BoxCoded = fields[9].Get<bool>();
10390 gMenuItem.BoxMoney = fields[10].Get<uint32>();
10391 gMenuItem.BoxText = fields[11].Get<std::string>();
10392 gMenuItem.BoxBroadcastTextID = fields[12].Get<uint32>();
10393
10394 if (gMenuItem.OptionIcon >= GOSSIP_ICON_MAX)
10395 {
10396 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);
10397 gMenuItem.OptionIcon = GOSSIP_ICON_CHAT;
10398 }
10399
10401 {
10402 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} has non-existing or incompatible OptionBroadcastTextID {}, ignoring.", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.OptionBroadcastTextID);
10403 gMenuItem.OptionBroadcastTextID = 0;
10404 }
10405
10406 if (gMenuItem.OptionType >= GOSSIP_OPTION_MAX)
10407 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);
10408
10409 if (gMenuItem.ActionPoiID && !GetPointOfInterest(gMenuItem.ActionPoiID))
10410 {
10411 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} use non-existing ActionPoiID {}, ignoring", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.ActionPoiID);
10412 gMenuItem.ActionPoiID = 0;
10413 }
10414
10415 if (gMenuItem.BoxBroadcastTextID && !GetBroadcastText(gMenuItem.BoxBroadcastTextID))
10416 {
10417 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} has non-existing or incompatible BoxBroadcastTextID {}, ignoring.", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.BoxBroadcastTextID);
10418 gMenuItem.BoxBroadcastTextID = 0;
10419 }
10420
10421 _gossipMenuItemsStore.insert(GossipMenuItemsContainer::value_type(gMenuItem.MenuID, gMenuItem));
10422 } while (result->NextRow());
10423
10424 // Warn if any trainer creature templates reference a GossipMenuId that has no gossip_menu_option entries
10425 // This will cause the gossip menu to fallback to MenuID 0 at runtime which will display: "I wish to unlearn my talents."
10426 std::set<uint32> checkedMenuIds;
10427 for (auto const& [entry, tmpl] : _creatureTemplateStore)
10428 {
10429 uint32 menuId = tmpl.GossipMenuId;
10430 if (!menuId)
10431 continue;
10432
10433 if (!(tmpl.npcflag & UNIT_NPC_FLAG_TRAINER))
10434 continue;
10435
10436 if (checkedMenuIds.contains(menuId))
10437 continue;
10438
10439 checkedMenuIds.insert(menuId);
10440
10441 auto [first, second] = _gossipMenuItemsStore.equal_range(menuId);
10442 if (first == second)
10443 LOG_WARN("server.loading", "Trainer creature template references GossipMenuId {} has no `gossip_menu_option` entries. This will fallback to MenuID 0.", menuId);
10444 }
10445
10446 LOG_INFO("server.loading", ">> Loaded {} gossip_menu_option entries in {} ms", uint32(_gossipMenuItemsStore.size()), GetMSTimeDiffToNow(oldMSTime));
10447 LOG_INFO("server.loading", " ");
10448}
@ 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:326
PointOfInterest const * GetPointOfInterest(uint32 id) const
Definition ObjectMgr.h:934
BroadcastText const * GetBroadcastText(uint32 id) const
Definition ObjectMgr.h:1229
Definition ObjectMgr.h:612
uint8 OptionIcon
Definition ObjectMgr.h:615
uint32 BoxBroadcastTextID
Definition ObjectMgr.h:626
std::string OptionText
Definition ObjectMgr.h:616
uint32 ActionMenuID
Definition ObjectMgr.h:620
bool BoxCoded
Definition ObjectMgr.h:622
uint32 MenuID
Definition ObjectMgr.h:613
uint32 OptionNpcFlag
Definition ObjectMgr.h:619
uint32 ActionPoiID
Definition ObjectMgr.h:621
uint32 BoxMoney
Definition ObjectMgr.h:623
std::string BoxText
Definition ObjectMgr.h:624
uint32 OptionID
Definition ObjectMgr.h:614
uint32 OptionType
Definition ObjectMgr.h:618
uint32 OptionBroadcastTextID
Definition ObjectMgr.h:617

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

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

◆ LoadGossipText()

void ObjectMgr::LoadGossipText ( )
6697{
6698 uint32 oldMSTime = getMSTime();
6699
6700 QueryResult result = WorldDatabase.Query("SELECT ID, "
6701 "text0_0, text0_1, BroadcastTextID0, lang0, Probability0, em0_0, em0_1, em0_2, em0_3, em0_4, em0_5, "
6702 "text1_0, text1_1, BroadcastTextID1, lang1, Probability1, em1_0, em1_1, em1_2, em1_3, em1_4, em1_5, "
6703 "text2_0, text2_1, BroadcastTextID2, lang2, Probability2, em2_0, em2_1, em2_2, em2_3, em2_4, em2_5, "
6704 "text3_0, text3_1, BroadcastTextID3, lang3, Probability3, em3_0, em3_1, em3_2, em3_3, em3_4, em3_5, "
6705 "text4_0, text4_1, BroadcastTextID4, lang4, Probability4, em4_0, em4_1, em4_2, em4_3, em4_4, em4_5, "
6706 "text5_0, text5_1, BroadcastTextID5, lang5, Probability5, em5_0, em5_1, em5_2, em5_3, em5_4, em5_5, "
6707 "text6_0, text6_1, BroadcastTextID6, lang6, Probability6, em6_0, em6_1, em6_2, em6_3, em6_4, em6_5, "
6708 "text7_0, text7_1, BroadcastTextID7, lang7, Probability7, em7_0, em7_1, em7_2, em7_3, em7_4, em7_5 "
6709 "FROM npc_text");
6710
6711 if (!result)
6712 {
6713 LOG_WARN("server.loading", ">> Loaded 0 npc texts, table is empty!");
6714 LOG_INFO("server.loading", " ");
6715 return;
6716 }
6717
6718 _gossipTextStore.rehash(result->GetRowCount());
6719
6720 uint32 count = 0;
6721 uint8 cic;
6722
6723 do
6724 {
6725 cic = 0;
6726
6727 Field* fields = result->Fetch();
6728
6729 uint32 id = fields[cic++].Get<uint32>();
6730 if (!id)
6731 {
6732 LOG_ERROR("sql.sql", "Table `npc_text` has record wit reserved id 0, ignore.");
6733 continue;
6734 }
6735
6736 GossipText& gText = _gossipTextStore[id];
6737
6738 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
6739 {
6740 gText.Options[i].Text_0 = fields[cic++].Get<std::string>();
6741 gText.Options[i].Text_1 = fields[cic++].Get<std::string>();
6742 gText.Options[i].BroadcastTextID = fields[cic++].Get<uint32>();
6743 gText.Options[i].Language = fields[cic++].Get<uint8>();
6744 gText.Options[i].Probability = fields[cic++].Get<float>();
6745
6746 for (uint8 j = 0; j < MAX_GOSSIP_TEXT_EMOTES; ++j)
6747 {
6748 gText.Options[i].Emotes[j]._Delay = fields[cic++].Get<uint16>();
6749 gText.Options[i].Emotes[j]._Emote = fields[cic++].Get<uint16>();
6750 }
6751 }
6752
6753 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; i++)
6754 {
6755 if (gText.Options[i].BroadcastTextID)
6756 {
6758 {
6759 LOG_ERROR("sql.sql", "GossipText (Id: {}) in table `npc_text` has non-existing or incompatible BroadcastTextID{} {}.", id, i, gText.Options[i].BroadcastTextID);
6760 gText.Options[i].BroadcastTextID = 0;
6761 }
6762 }
6763 }
6764
6765 count++;
6766 } while (result->NextRow());
6767
6768 LOG_INFO("server.loading", ">> Loaded {} Npc Texts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6769 LOG_INFO("server.loading", " ");
6770}
#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 ( )
6604{
6605 uint32 oldMSTime = getMSTime();
6606
6607 // 0 1 2 3
6608 QueryResult result = WorldDatabase.Query("SELECT entry, creditType, creditEntry, lastEncounterDungeon FROM instance_encounters");
6609 if (!result)
6610 {
6611 LOG_WARN("server.loading", ">> Loaded 0 instance encounters, table is empty!");
6612 LOG_INFO("server.loading", " ");
6613 return;
6614 }
6615
6616 uint32 count = 0;
6617 std::map<uint32, DungeonEncounterEntry const*> dungeonLastBosses;
6618 do
6619 {
6620 Field* fields = result->Fetch();
6621 uint32 entry = fields[0].Get<uint32>();
6622 uint8 creditType = fields[1].Get<uint8>();
6623 uint32 creditEntry = fields[2].Get<uint32>();
6624 uint32 lastEncounterDungeon = fields[3].Get<uint16>();
6625 DungeonEncounterEntry const* dungeonEncounter = sDungeonEncounterStore.LookupEntry(entry);
6626 if (!dungeonEncounter)
6627 {
6628 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid encounter id {}, skipped!", entry);
6629 continue;
6630 }
6631
6632 if (lastEncounterDungeon && !sLFGMgr->GetLFGDungeonEntry(lastEncounterDungeon))
6633 {
6634 LOG_ERROR("sql.sql", "Table `instance_encounters` has an encounter {} ({}) marked as final for invalid dungeon id {}, skipped!", entry, dungeonEncounter->encounterName[0], lastEncounterDungeon);
6635 continue;
6636 }
6637
6638 std::map<uint32, DungeonEncounterEntry const*>::const_iterator itr = dungeonLastBosses.find(lastEncounterDungeon);
6639 if (lastEncounterDungeon)
6640 {
6641 if (itr != dungeonLastBosses.end())
6642 {
6643 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]);
6644 continue;
6645 }
6646
6647 dungeonLastBosses[lastEncounterDungeon] = dungeonEncounter;
6648 }
6649
6650 switch (creditType)
6651 {
6653 {
6654 CreatureTemplate const* creatureInfo = GetCreatureTemplate(creditEntry);
6655 if (!creatureInfo)
6656 {
6657 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid creature (entry {}) linked to the encounter {} ({}), skipped!", creditEntry, entry, dungeonEncounter->encounterName[0]);
6658 continue;
6659 }
6660 const_cast<CreatureTemplate*>(creatureInfo)->flags_extra |= CREATURE_FLAG_EXTRA_DUNGEON_BOSS;
6661 break;
6662 }
6664 {
6665 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(creditEntry);
6666 if (!spellInfo)
6667 {
6668 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid spell (entry {}) linked to the encounter {} ({}), skipped!", creditEntry, entry, dungeonEncounter->encounterName[0]);
6669 continue;
6670 }
6671 const_cast<SpellInfo*>(spellInfo)->AttributesCu |= SPELL_ATTR0_CU_ENCOUNTER_REWARD;
6672 break;
6673 }
6674 default:
6675 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid credit type ({}) for encounter {} ({}), skipped!", creditType, entry, dungeonEncounter->encounterName[0]);
6676 continue;
6677 }
6678
6679 DungeonEncounterList& encounters = _dungeonEncounterStore[MAKE_PAIR32(dungeonEncounter->mapId, dungeonEncounter->difficulty)];
6680 encounters.push_back(new DungeonEncounter(dungeonEncounter, EncounterCreditType(creditType), creditEntry, lastEncounterDungeon));
6681 ++count;
6682 } while (result->NextRow());
6683
6684 LOG_INFO("server.loading", ">> Loaded {} Instance Encounters in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6685 LOG_INFO("server.loading", " ");
6686}
@ CREATURE_FLAG_EXTRA_DUNGEON_BOSS
Definition CreatureData.h:74
DBCStorage< DungeonEncounterEntry > sDungeonEncounterStore(DungeonEncounterfmt)
#define sLFGMgr
Definition LFGMgr.h:658
EncounterCreditType
Definition Map.h:160
@ ENCOUNTER_CREDIT_KILL_CREATURE
Definition Map.h:161
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition Map.h:162
std::list< DungeonEncounter const * > DungeonEncounterList
Definition ObjectMgr.h:716
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition SpellInfo.h:208
Definition DBCStructure.h:866
Definition ObjectMgr.h:706

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 ( )
6553{
6554 uint32 oldMSTime = getMSTime();
6555
6556 // 0 1 2 4
6557 QueryResult result = WorldDatabase.Query("SELECT map, parent, script, allowMount FROM instance_template");
6558
6559 if (!result)
6560 {
6561 LOG_WARN("server.loading", ">> Loaded 0 instance templates. DB table `instance_template` is empty!");
6562 LOG_INFO("server.loading", " ");
6563 return;
6564 }
6565
6566 uint32 count = 0;
6567 do
6568 {
6569 Field* fields = result->Fetch();
6570
6571 uint16 mapID = fields[0].Get<uint16>();
6572
6573 if (!MapMgr::IsValidMAP(mapID, true))
6574 {
6575 LOG_ERROR("sql.sql", "ObjectMgr::LoadInstanceTemplate: bad mapid {} for template!", mapID);
6576 continue;
6577 }
6578
6579 InstanceTemplate instanceTemplate;
6580
6581 instanceTemplate.AllowMount = fields[3].Get<bool>();
6582 instanceTemplate.Parent = uint32(fields[1].Get<uint16>());
6583 instanceTemplate.ScriptId = GetScriptId(fields[2].Get<std::string>());
6584
6585 _instanceTemplateStore[mapID] = instanceTemplate;
6586
6587 ++count;
6588 } while (result->NextRow());
6589
6590 LOG_INFO("server.loading", ">> Loaded {} Instance Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6591 LOG_INFO("server.loading", " ");
6592}
static bool IsValidMAP(uint32 mapid, bool startUp)
Definition MapMgr.cpp:311
bool AllowMount
Definition Map.h:127
uint32 ScriptId
Definition Map.h:126

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 ( )
3263{
3264 uint32 oldMSTime = getMSTime();
3265
3266 _itemLocaleStore.clear(); // need for reload case
3267
3268 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Name, Description FROM item_template_locale");
3269 if (!result)
3270 return;
3271
3272 do
3273 {
3274 Field* fields = result->Fetch();
3275
3276 uint32 ID = fields[0].Get<uint32>();
3277
3278 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
3279 if (locale == LOCALE_enUS)
3280 continue;
3281
3282 ItemLocale& data = _itemLocaleStore[ID];
3283 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
3284 AddLocaleString(fields[3].Get<std::string>(), locale, data.Description);
3285 } while (result->NextRow());
3286
3287 LOG_INFO("server.loading", ">> Loaded {} Item Locale Strings in {} ms", (uint32)_itemLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
3288}
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 ( )
3939{
3940 uint32 oldMSTime = getMSTime();
3941
3942 _itemSetNameLocaleStore.clear(); // need for reload case
3943
3944 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Name FROM item_set_names_locale");
3945
3946 if (!result)
3947 return;
3948
3949 do
3950 {
3951 Field* fields = result->Fetch();
3952
3953 uint32 ID = fields[0].Get<uint32>();
3954
3955 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
3956 if (locale == LOCALE_enUS)
3957 continue;
3958
3960 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
3961 } while (result->NextRow());
3962
3963 LOG_INFO("server.loading", ">> Loaded {} Item Set Name Locale Strings in {} ms", uint32(_itemSetNameLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime));
3964}
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 ( )
3967{
3968 uint32 oldMSTime = getMSTime();
3969
3970 _itemSetNameStore.clear(); // needed for reload case
3971
3972 std::set<uint32> itemSetItems;
3973
3974 // fill item set member ids
3975 for (uint32 entryId = 0; entryId < sItemSetStore.GetNumRows(); ++entryId)
3976 {
3977 ItemSetEntry const* setEntry = sItemSetStore.LookupEntry(entryId);
3978 if (!setEntry)
3979 continue;
3980
3981 for (uint32 i = 0; i < MAX_ITEM_SET_ITEMS; ++i)
3982 if (setEntry->itemId[i])
3983 itemSetItems.insert(setEntry->itemId[i]);
3984 }
3985
3986 // 0 1 2
3987 QueryResult result = WorldDatabase.Query("SELECT `entry`, `name`, `InventoryType` FROM `item_set_names`");
3988
3989 if (!result)
3990 {
3991 LOG_WARN("server.loading", ">> Loaded 0 item set names. DB table `item_set_names` is empty.");
3992 LOG_INFO("server.loading", " ");
3993 return;
3994 }
3995
3996 _itemSetNameStore.rehash(result->GetRowCount());
3997 uint32 count = 0;
3998
3999 do
4000 {
4001 Field* fields = result->Fetch();
4002
4003 uint32 entry = fields[0].Get<uint32>();
4004 if (itemSetItems.find(entry) == itemSetItems.end())
4005 {
4006 LOG_ERROR("sql.sql", "Item set name (Entry: {}) not found in ItemSet.dbc, data useless.", entry);
4007 continue;
4008 }
4009
4010 ItemSetNameEntry& data = _itemSetNameStore[entry];
4011 data.name = fields[1].Get<std::string>();
4012
4013 uint32 invType = fields[2].Get<uint8>();
4014 if (invType >= MAX_INVTYPE)
4015 {
4016 LOG_ERROR("sql.sql", "Item set name (Entry: {}) has wrong InventoryType value ({})", entry, invType);
4017 invType = INVTYPE_NON_EQUIP;
4018 }
4019
4020 data.InventoryType = invType;
4021 itemSetItems.erase(entry);
4022 ++count;
4023 } while (result->NextRow());
4024
4025 if (!itemSetItems.empty())
4026 {
4027 ItemTemplate const* pProto;
4028 for (std::set<uint32>::iterator itr = itemSetItems.begin(); itr != itemSetItems.end(); ++itr)
4029 {
4030 uint32 entry = *itr;
4031 // add data from item_template if available
4032 pProto = GetItemTemplate(entry);
4033 if (pProto)
4034 {
4035 LOG_ERROR("sql.sql", "Item set part (Entry: {}) does not have entry in `item_set_names`, adding data from `item_template`.", entry);
4036 ItemSetNameEntry& data = _itemSetNameStore[entry];
4037 data.name = pProto->Name1;
4038 data.InventoryType = pProto->InventoryType;
4039 ++count;
4040 }
4041 else
4042 LOG_ERROR("sql.sql", "Item set part (Entry: {}) does not have entry in `item_set_names`, set will not display properly.", entry);
4043 }
4044 }
4045
4046 LOG_INFO("server.loading", ">> Loaded {} Item Set Names in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4047 LOG_INFO("server.loading", " ");
4048}
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 ( )
3315{
3316 uint32 oldMSTime = getMSTime();
3317
3318 // 0 1 2 3 4 5 6 7 8 9 10 11 12
3319 QueryResult result = WorldDatabase.Query("SELECT entry, class, subclass, SoundOverrideSubclass, name, displayid, Quality, Flags, FlagsExtra, BuyCount, BuyPrice, SellPrice, InventoryType, "
3320 // 13 14 15 16 17 18 19 20
3321 "AllowableClass, AllowableRace, ItemLevel, RequiredLevel, RequiredSkill, RequiredSkillRank, requiredspell, requiredhonorrank, "
3322 // 21 22 23 24 25 26 27
3323 "RequiredCityRank, RequiredReputationFaction, RequiredReputationRank, maxcount, stackable, ContainerSlots, stat_type1, "
3324 // 28 29 30 31 32 33 34 35 36 37
3325 "stat_value1, stat_type2, stat_value2, stat_type3, stat_value3, stat_type4, stat_value4, stat_type5, stat_value5, stat_type6, "
3326 // 38 39 40 41 42 43 44 45 46
3327 "stat_value6, stat_type7, stat_value7, stat_type8, stat_value8, stat_type9, stat_value9, stat_type10, stat_value10, "
3328 // 47 48 49 50 51 52 53 54 55 56 57
3329 "ScalingStatDistribution, ScalingStatValue, dmg_min1, dmg_max1, dmg_type1, dmg_min2, dmg_max2, dmg_type2, armor, holy_res, fire_res, "
3330 // 58 59 60 61 62 63 64 65 66 67
3331 "nature_res, frost_res, shadow_res, arcane_res, delay, ammo_type, RangedModRange, spellid_1, spelltrigger_1, spellcharges_1, "
3332 // 68 69 70 71 72 73 74
3333 "spellppmRate_1, spellcooldown_1, spellcategory_1, spellcategorycooldown_1, spellid_2, spelltrigger_2, spellcharges_2, "
3334 // 75 76 77 78 79 80 81
3335 "spellppmRate_2, spellcooldown_2, spellcategory_2, spellcategorycooldown_2, spellid_3, spelltrigger_3, spellcharges_3, "
3336 // 82 83 84 85 86 87 88
3337 "spellppmRate_3, spellcooldown_3, spellcategory_3, spellcategorycooldown_3, spellid_4, spelltrigger_4, spellcharges_4, "
3338 // 89 90 91 92 93 94 95
3339 "spellppmRate_4, spellcooldown_4, spellcategory_4, spellcategorycooldown_4, spellid_5, spelltrigger_5, spellcharges_5, "
3340 // 96 97 98 99 100 101 102 103 104
3341 "spellppmRate_5, spellcooldown_5, spellcategory_5, spellcategorycooldown_5, bonding, description, PageText, LanguageID, PageMaterial, "
3342 // 105 106 107 108 109 110 111 112 113 114 115 116
3343 "startquest, lockid, Material, sheath, RandomProperty, RandomSuffix, block, itemset, MaxDurability, area, Map, BagFamily, "
3344 // 117 118 119 120 121 122 123 124
3345 "TotemCategory, socketColor_1, socketContent_1, socketColor_2, socketContent_2, socketColor_3, socketContent_3, socketBonus, "
3346 // 125 126 127 128 129 130 131 132
3347 "GemProperties, RequiredDisenchantSkill, ArmorDamageModifier, duration, ItemLimitCategory, HolidayId, ScriptName, DisenchantID, "
3348 // 133 134 135 136
3349 "FoodType, minMoneyLoot, maxMoneyLoot, flagsCustom FROM item_template");
3350
3351 if (!result)
3352 {
3353 LOG_WARN("server.loading", ">> Loaded 0 item templates. DB table `item_template` is empty.");
3354 LOG_INFO("server.loading", " ");
3355 return;
3356 }
3357
3358 _itemTemplateStore.reserve(result->GetRowCount());
3359 uint32 count = 0;
3360 // original inspiration https://github.com/TrinityCore/TrinityCore/commit/0c44bd33ee7b42c924859139a9f4b04cf2b91261
3361 bool enforceDBCAttributes = sWorld->getBoolConfig(CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES);
3362
3363 do
3364 {
3365 Field* fields = result->Fetch();
3366
3367 uint32 entry = fields[0].Get<uint32>();
3368
3369 ItemTemplate& itemTemplate = _itemTemplateStore[entry];
3370
3371 itemTemplate.ItemId = entry;
3372 itemTemplate.Class = uint32(fields[1].Get<uint8>());
3373 itemTemplate.SubClass = uint32(fields[2].Get<uint8>());
3374 itemTemplate.SoundOverrideSubclass = int32(fields[3].Get<int8>());
3375 itemTemplate.Name1 = fields[4].Get<std::string>();
3376 itemTemplate.DisplayInfoID = fields[5].Get<uint32>();
3377 itemTemplate.Quality = uint32(fields[6].Get<uint8>());
3378 itemTemplate.Flags = ItemFlags(fields[7].Get<uint32>());
3379 itemTemplate.Flags2 = ItemFlags2(fields[8].Get<uint32>());
3380 itemTemplate.BuyCount = uint32(fields[9].Get<uint8>());
3381 itemTemplate.BuyPrice = int32(fields[10].Get<int64>());
3382 itemTemplate.SellPrice = uint32(fields[11].Get<uint32>());
3383 itemTemplate.InventoryType = uint32(fields[12].Get<uint8>());
3384 itemTemplate.AllowableClass = fields[13].Get<int32>();
3385 itemTemplate.AllowableRace = fields[14].Get<int32>();
3386 itemTemplate.ItemLevel = uint32(fields[15].Get<uint16>());
3387 itemTemplate.RequiredLevel = uint32(fields[16].Get<uint8>());
3388 itemTemplate.RequiredSkill = uint32(fields[17].Get<uint16>());
3389 itemTemplate.RequiredSkillRank = uint32(fields[18].Get<uint16>());
3390 itemTemplate.RequiredSpell = fields[19].Get<uint32>();
3391 itemTemplate.RequiredHonorRank = fields[20].Get<uint32>();
3392 itemTemplate.RequiredCityRank = fields[21].Get<uint32>();
3393 itemTemplate.RequiredReputationFaction = uint32(fields[22].Get<uint16>());
3394 itemTemplate.RequiredReputationRank = uint32(fields[23].Get<uint16>());
3395 itemTemplate.MaxCount = fields[24].Get<int32>();
3396 itemTemplate.Stackable = fields[25].Get<int32>();
3397 itemTemplate.ContainerSlots = uint32(fields[26].Get<uint8>());
3398
3399 uint8 statsCount = 0;
3400 uint8 statsIterator = 0;
3401 while (statsIterator < MAX_ITEM_PROTO_STATS)
3402 {
3403 uint32 statType = uint32(fields[27 + statsIterator * 2].Get<uint8>());
3404 int32 statValue = fields[28 + statsIterator * 2].Get<int32>();
3405 statsIterator++;
3406 if (statValue == 0)
3407 continue;
3408
3409 itemTemplate.ItemStat[statsCount].ItemStatType = statType;
3410 itemTemplate.ItemStat[statsCount].ItemStatValue = statValue;
3411 statsCount++;
3412 }
3413 itemTemplate.StatsCount = statsCount;
3414
3415 itemTemplate.ScalingStatDistribution = uint32(fields[47].Get<uint16>());
3416 itemTemplate.ScalingStatValue = fields[48].Get<int32>();
3417
3418 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
3419 {
3420 itemTemplate.Damage[i].DamageMin = fields[49 + i * 3].Get<float>();
3421 itemTemplate.Damage[i].DamageMax = fields[50 + i * 3].Get<float>();
3422 itemTemplate.Damage[i].DamageType = uint32(fields[51 + i * 3].Get<uint8>());
3423 }
3424
3425 itemTemplate.Armor = fields[55].Get<uint32>();
3426 itemTemplate.HolyRes = fields[56].Get<int32>();
3427 itemTemplate.FireRes = fields[57].Get<int32>();
3428 itemTemplate.NatureRes = fields[58].Get<int32>();
3429 itemTemplate.FrostRes = fields[59].Get<int32>();
3430 itemTemplate.ShadowRes = fields[60].Get<int32>();
3431 itemTemplate.ArcaneRes = fields[61].Get<int32>();
3432 itemTemplate.Delay = uint32(fields[62].Get<uint16>());
3433 itemTemplate.AmmoType = uint32(fields[63].Get<uint8>());
3434 itemTemplate.RangedModRange = fields[64].Get<float>();
3435
3436 for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
3437 {
3438 itemTemplate.Spells[i].SpellId = fields[65 + i * 7 ].Get<int32>();
3439 itemTemplate.Spells[i].SpellTrigger = uint32(fields[66 + i * 7].Get<uint8>());
3440 itemTemplate.Spells[i].SpellCharges = int32(fields[67 + i * 7].Get<int16>());
3441 itemTemplate.Spells[i].SpellPPMRate = fields[68 + i * 7].Get<float>();
3442 itemTemplate.Spells[i].SpellCooldown = fields[69 + i * 7].Get<int32>();
3443 itemTemplate.Spells[i].SpellCategory = uint32(fields[70 + i * 7].Get<uint16>());
3444 itemTemplate.Spells[i].SpellCategoryCooldown = fields[71 + i * 7].Get<int32>();
3445 }
3446
3447 itemTemplate.Bonding = uint32(fields[100].Get<uint8>());
3448 itemTemplate.Description = fields[101].Get<std::string>();
3449 itemTemplate.PageText = fields[102].Get<uint32>();
3450 itemTemplate.LanguageID = uint32(fields[103].Get<uint8>());
3451 itemTemplate.PageMaterial = uint32(fields[104].Get<uint8>());
3452 itemTemplate.StartQuest = fields[105].Get<uint32>();
3453 itemTemplate.LockID = fields[106].Get<uint32>();
3454 itemTemplate.Material = int32(fields[107].Get<int8>());
3455 itemTemplate.Sheath = uint32(fields[108].Get<uint8>());
3456 itemTemplate.RandomProperty = fields[109].Get<int32>();
3457 itemTemplate.RandomSuffix = fields[110].Get<int32>();
3458 itemTemplate.Block = fields[111].Get<uint32>();
3459 itemTemplate.ItemSet = fields[112].Get<uint32>();
3460 itemTemplate.MaxDurability = uint32(fields[113].Get<uint16>());
3461 itemTemplate.Area = fields[114].Get<uint32>();
3462 itemTemplate.Map = uint32(fields[115].Get<uint16>());
3463 itemTemplate.BagFamily = fields[116].Get<uint32>();
3464 itemTemplate.TotemCategory = fields[117].Get<uint32>();
3465
3466 for (uint8 i = 0; i < MAX_ITEM_PROTO_SOCKETS; ++i)
3467 {
3468 itemTemplate.Socket[i].Color = uint32(fields[118 + i * 2].Get<uint8>());
3469 itemTemplate.Socket[i].Content = fields[119 + i * 2].Get<uint32>();
3470 }
3471
3472 itemTemplate.socketBonus = fields[124].Get<uint32>();
3473 itemTemplate.GemProperties = fields[125].Get<uint32>();
3474 itemTemplate.RequiredDisenchantSkill = uint32(fields[126].Get<int16>());
3475 itemTemplate.ArmorDamageModifier = fields[127].Get<float>();
3476 itemTemplate.Duration = fields[128].Get<uint32>();
3477 itemTemplate.ItemLimitCategory = uint32(fields[129].Get<int16>());
3478 itemTemplate.HolidayId = fields[130].Get<uint32>();
3479 itemTemplate.ScriptId = GetScriptId(fields[131].Get<std::string>());
3480 itemTemplate.DisenchantID = fields[132].Get<uint32>();
3481 itemTemplate.FoodType = uint32(fields[133].Get<uint8>());
3482 itemTemplate.MinMoneyLoot = fields[134].Get<uint32>();
3483 itemTemplate.MaxMoneyLoot = fields[135].Get<uint32>();
3484 itemTemplate.FlagsCu = ItemFlagsCustom(fields[136].Get<uint32>());
3485
3486 // Checks
3487 ItemEntry const* dbcitem = sItemStore.LookupEntry(entry);
3488
3489 if (!dbcitem)
3490 {
3491 LOG_DEBUG("sql.sql", "Item (Entry: {}) does not exist in item.dbc! (not correct id?).", entry);
3492 continue;
3493 }
3494
3495 if (enforceDBCAttributes)
3496 {
3497 if (itemTemplate.Class != dbcitem->ClassID)
3498 {
3499 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Class value ({}), must be ({}).", entry, itemTemplate.Class, dbcitem->ClassID);
3500 itemTemplate.Class = dbcitem->ClassID;
3501 }
3502 if (itemTemplate.SubClass != dbcitem->SubclassID)
3503 {
3504 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Subclass value ({}) for class {}, must be ({}).", entry, itemTemplate.SubClass, itemTemplate.Class, dbcitem->SubclassID);
3505 itemTemplate.SubClass = dbcitem->SubclassID;
3506 }
3507 if (itemTemplate.SoundOverrideSubclass != dbcitem->SoundOverrideSubclassID)
3508 {
3509 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct SoundOverrideSubclass ({}), must be {}.", entry, itemTemplate.SoundOverrideSubclass, dbcitem->SoundOverrideSubclassID);
3510 itemTemplate.SoundOverrideSubclass = dbcitem->SoundOverrideSubclassID;
3511 }
3512 if (itemTemplate.Material != dbcitem->Material)
3513 {
3514 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct material ({}), must be {}.", entry, itemTemplate.Material, dbcitem->Material);
3515 itemTemplate.Material = dbcitem->Material;
3516 }
3517 if (itemTemplate.InventoryType != dbcitem->InventoryType)
3518 {
3519 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong InventoryType value ({}), must be {}.", entry, itemTemplate.InventoryType, dbcitem->InventoryType);
3520 itemTemplate.InventoryType = dbcitem->InventoryType;
3521 }
3522 if (itemTemplate.DisplayInfoID != dbcitem->DisplayInfoID)
3523 {
3524 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct display id ({}), must be {}.", entry, itemTemplate.DisplayInfoID, dbcitem->DisplayInfoID);
3525 itemTemplate.DisplayInfoID = dbcitem->DisplayInfoID;
3526 }
3527 if (itemTemplate.Sheath != dbcitem->SheatheType)
3528 {
3529 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Sheath ({}), must be {}.", entry, itemTemplate.Sheath, dbcitem->SheatheType);
3530 itemTemplate.Sheath = dbcitem->SheatheType;
3531 }
3532 }
3533
3534 if (itemTemplate.Quality >= MAX_ITEM_QUALITY)
3535 {
3536 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Quality value ({})", entry, itemTemplate.Quality);
3537 itemTemplate.Quality = ITEM_QUALITY_NORMAL;
3538 }
3539
3540 if (itemTemplate.HasFlag2(ITEM_FLAG2_FACTION_HORDE))
3541 {
3542 if (FactionEntry const* faction = sFactionStore.LookupEntry(HORDE))
3543 if ((itemTemplate.AllowableRace & faction->BaseRepRaceMask[0]) == 0)
3544 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.",
3545 entry, itemTemplate.AllowableRace, ITEM_FLAG2_FACTION_HORDE);
3546
3547 if (itemTemplate.HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE))
3548 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.",
3550 }
3551 else if (itemTemplate.HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE))
3552 {
3553 if (FactionEntry const* faction = sFactionStore.LookupEntry(ALLIANCE))
3554 if ((itemTemplate.AllowableRace & faction->BaseRepRaceMask[0]) == 0)
3555 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.",
3556 entry, itemTemplate.AllowableRace, ITEM_FLAG2_FACTION_ALLIANCE);
3557 }
3558
3559 if (itemTemplate.BuyCount <= 0)
3560 {
3561 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong BuyCount value ({}), set to default(1).", entry, itemTemplate.BuyCount);
3562 itemTemplate.BuyCount = 1;
3563 }
3564
3565 if (itemTemplate.RequiredSkill >= MAX_SKILL_TYPE)
3566 {
3567 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong RequiredSkill value ({})", entry, itemTemplate.RequiredSkill);
3568 itemTemplate.RequiredSkill = 0;
3569 }
3570
3571 {
3572 // can be used in equip slot, as page read use in inventory, or spell casting at use
3573 bool req = itemTemplate.InventoryType != INVTYPE_NON_EQUIP || itemTemplate.PageText;
3574 if (!req)
3575 for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
3576 {
3577 if (itemTemplate.Spells[j].SpellId)
3578 {
3579 req = true;
3580 break;
3581 }
3582 }
3583
3584 if (req)
3585 {
3586 if (!(itemTemplate.AllowableClass & CLASSMASK_ALL_PLAYABLE))
3587 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have any playable classes ({}) in `AllowableClass` and can't be equipped or used.", entry, itemTemplate.AllowableClass);
3588
3589 if (!(itemTemplate.AllowableRace & sRaceMgr->GetPlayableRaceMask()))
3590 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have any playable races ({}) in `AllowableRace` and can't be equipped or used.", entry, itemTemplate.AllowableRace);
3591 }
3592 }
3593
3594 if (itemTemplate.RequiredSpell && !sSpellMgr->GetSpellInfo(itemTemplate.RequiredSpell))
3595 {
3596 LOG_ERROR("sql.sql", "Item (Entry: {}) has a wrong (non-existing) spell in RequiredSpell ({})", entry, itemTemplate.RequiredSpell);
3597 itemTemplate.RequiredSpell = 0;
3598 }
3599
3600 if (itemTemplate.RequiredReputationRank >= MAX_REPUTATION_RANK)
3601 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong reputation rank in RequiredReputationRank ({}), item can't be used.", entry, itemTemplate.RequiredReputationRank);
3602
3603 if (itemTemplate.RequiredReputationFaction)
3604 {
3605 if (!sFactionStore.LookupEntry(itemTemplate.RequiredReputationFaction))
3606 {
3607 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (not existing) faction in RequiredReputationFaction ({})", entry, itemTemplate.RequiredReputationFaction);
3608 itemTemplate.RequiredReputationFaction = 0;
3609 }
3610
3611 if (itemTemplate.RequiredReputationRank == MIN_REPUTATION_RANK)
3612 LOG_ERROR("sql.sql", "Item (Entry: {}) has min. reputation rank in RequiredReputationRank (0) but RequiredReputationFaction > 0, faction setting is useless.", entry);
3613 }
3614
3615 if (itemTemplate.MaxCount < -1)
3616 {
3617 LOG_ERROR("sql.sql", "Item (Entry: {}) has too large negative in maxcount ({}), replace by value (-1) no storing limits.", entry, itemTemplate.MaxCount);
3618 itemTemplate.MaxCount = -1;
3619 }
3620
3621 if (itemTemplate.Stackable == 0)
3622 {
3623 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong value in stackable ({}), replace by default 1.", entry, itemTemplate.Stackable);
3624 itemTemplate.Stackable = 1;
3625 }
3626 else if (itemTemplate.Stackable < -1)
3627 {
3628 LOG_ERROR("sql.sql", "Item (Entry: {}) has too large negative in stackable ({}), replace by value (-1) no stacking limits.", entry, itemTemplate.Stackable);
3629 itemTemplate.Stackable = -1;
3630 }
3631
3632 if (itemTemplate.ContainerSlots > MAX_BAG_SIZE)
3633 {
3634 LOG_ERROR("sql.sql", "Item (Entry: {}) has too large value in ContainerSlots ({}), replace by hardcoded limit ({}).", entry, itemTemplate.ContainerSlots, MAX_BAG_SIZE);
3635 itemTemplate.ContainerSlots = MAX_BAG_SIZE;
3636 }
3637
3638 for (uint8 j = 0; j < itemTemplate.StatsCount; ++j)
3639 {
3640 // for ItemStatValue != 0
3641 if (itemTemplate.ItemStat[j].ItemStatValue && itemTemplate.ItemStat[j].ItemStatType >= MAX_ITEM_MOD)
3642 {
3643 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (non-existing?) stat_type{} ({})", entry, j + 1, itemTemplate.ItemStat[j].ItemStatType);
3644 itemTemplate.ItemStat[j].ItemStatType = 0;
3645 }
3646
3647 switch (itemTemplate.ItemStat[j].ItemStatType)
3648 {
3651 // Skip warning for specific items: 13113 (Feathermoon Headdress - Blizzard oversight), 34967 (test item)
3652 if (entry != 13113 && entry != 34967)
3653 LOG_WARN("sql.sql", "Item (Entry: {}) has deprecated stat_type{} ({})", entry, j + 1, itemTemplate.ItemStat[j].ItemStatType);
3654
3655 break;
3656 default:
3657 break;
3658 }
3659 }
3660
3661 for (uint8 j = 0; j < MAX_ITEM_PROTO_DAMAGES; ++j)
3662 {
3663 if (itemTemplate.Damage[j].DamageType >= MAX_SPELL_SCHOOL)
3664 {
3665 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong dmg_type{} ({})", entry, j + 1, itemTemplate.Damage[j].DamageType);
3666 itemTemplate.Damage[j].DamageType = 0;
3667 }
3668 }
3669
3670 // special format
3671 if ((itemTemplate.Spells[0].SpellId == 483) || (itemTemplate.Spells[0].SpellId == 55884))
3672 {
3673 // spell_1
3674 if (itemTemplate.Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
3675 {
3676 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);
3677 itemTemplate.Spells[0].SpellId = 0;
3678 itemTemplate.Spells[0].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3679 itemTemplate.Spells[1].SpellId = 0;
3680 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3681 }
3682
3683 // spell_2 have learning spell
3684 if (itemTemplate.Spells[1].SpellTrigger != ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
3685 {
3686 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);
3687 itemTemplate.Spells[0].SpellId = 0;
3688 itemTemplate.Spells[1].SpellId = 0;
3689 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3690 }
3691 else if (!itemTemplate.Spells[1].SpellId)
3692 {
3693 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have an expected spell in spellid_{} in special learning format.", entry, 1 + 1);
3694 itemTemplate.Spells[0].SpellId = 0;
3695 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3696 }
3697 else if (itemTemplate.Spells[1].SpellId != -1)
3698 {
3699 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemTemplate.Spells[1].SpellId);
3700 if (!spellInfo && !sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, itemTemplate.Spells[1].SpellId, nullptr))
3701 {
3702 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (not existing) spell in spellid_{} ({})", entry, 1 + 1, itemTemplate.Spells[1].SpellId);
3703 itemTemplate.Spells[0].SpellId = 0;
3704 itemTemplate.Spells[1].SpellId = 0;
3705 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3706 }
3707 // allowed only in special format
3708 else if ((itemTemplate.Spells[1].SpellId == 483) || (itemTemplate.Spells[1].SpellId == 55884))
3709 {
3710 LOG_ERROR("sql.sql", "Item (Entry: {}) has broken spell in spellid_{} ({})", entry, 1 + 1, itemTemplate.Spells[1].SpellId);
3711 itemTemplate.Spells[0].SpellId = 0;
3712 itemTemplate.Spells[1].SpellId = 0;
3713 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3714 }
3715 }
3716
3717 // spell_3*, spell_4*, spell_5* is empty
3718 for (uint8 j = 2; j < MAX_ITEM_PROTO_SPELLS; ++j)
3719 {
3720 if (itemTemplate.Spells[j].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
3721 {
3722 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong item spell trigger value in spelltrigger_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellTrigger);
3723 itemTemplate.Spells[j].SpellId = 0;
3724 itemTemplate.Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3725 }
3726 else if (itemTemplate.Spells[j].SpellId != 0)
3727 {
3728 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong spell in spellid_{} ({}) for learning special format", entry, j + 1, itemTemplate.Spells[j].SpellId);
3729 itemTemplate.Spells[j].SpellId = 0;
3730 }
3731 }
3732 }
3733 // normal spell list
3734 else
3735 {
3736 for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
3737 {
3738 if (itemTemplate.Spells[j].SpellTrigger >= MAX_ITEM_SPELLTRIGGER || itemTemplate.Spells[j].SpellTrigger == ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
3739 {
3740 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong item spell trigger value in spelltrigger_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellTrigger);
3741 itemTemplate.Spells[j].SpellId = 0;
3742 itemTemplate.Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3743 }
3744
3745 if (itemTemplate.Spells[j].SpellId && itemTemplate.Spells[j].SpellId != -1)
3746 {
3747 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemTemplate.Spells[j].SpellId);
3748 if (!spellInfo && !sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, itemTemplate.Spells[j].SpellId, nullptr))
3749 {
3750 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (not existing) spell in spellid_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellId);
3751 itemTemplate.Spells[j].SpellId = 0;
3752 }
3753 // allowed only in special format
3754 else if ((itemTemplate.Spells[j].SpellId == 483) || (itemTemplate.Spells[j].SpellId == 55884))
3755 {
3756 LOG_ERROR("sql.sql", "Item (Entry: {}) has broken spell in spellid_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellId);
3757 itemTemplate.Spells[j].SpellId = 0;
3758 }
3759 }
3760 }
3761 }
3762
3763 if (itemTemplate.Bonding >= MAX_BIND_TYPE)
3764 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Bonding value ({})", entry, itemTemplate.Bonding);
3765
3766 if (itemTemplate.PageText && !GetPageText(itemTemplate.PageText))
3767 LOG_ERROR("sql.sql", "Item (Entry: {}) has non existing first page (Id:{})", entry, itemTemplate.PageText);
3768
3769 if (itemTemplate.LockID && !sLockStore.LookupEntry(itemTemplate.LockID))
3770 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong LockID ({})", entry, itemTemplate.LockID);
3771
3772 if (itemTemplate.RandomProperty)
3773 {
3774 // To be implemented later
3775 if (itemTemplate.RandomProperty == -1)
3776 itemTemplate.RandomProperty = 0;
3777
3778 else if (!sItemRandomPropertiesStore.LookupEntry(GetItemEnchantMod(itemTemplate.RandomProperty)))
3779 {
3780 LOG_ERROR("sql.sql", "Item (Entry: {}) has unknown (wrong or not listed in `item_enchantment_template`) RandomProperty ({})", entry, itemTemplate.RandomProperty);
3781 itemTemplate.RandomProperty = 0;
3782 }
3783 }
3784
3785 if (itemTemplate.RandomSuffix && !sItemRandomSuffixStore.LookupEntry(GetItemEnchantMod(itemTemplate.RandomSuffix)))
3786 {
3787 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong RandomSuffix ({})", entry, itemTemplate.RandomSuffix);
3788 itemTemplate.RandomSuffix = 0;
3789 }
3790
3791 if (itemTemplate.ItemSet && !sItemSetStore.LookupEntry(itemTemplate.ItemSet))
3792 {
3793 LOG_ERROR("sql.sql", "Item (Entry: {}) have wrong ItemSet ({})", entry, itemTemplate.ItemSet);
3794 itemTemplate.ItemSet = 0;
3795 }
3796
3797 if (itemTemplate.Area && !sAreaTableStore.LookupEntry(itemTemplate.Area))
3798 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Area ({})", entry, itemTemplate.Area);
3799
3800 if (itemTemplate.Map && !sMapStore.LookupEntry(itemTemplate.Map))
3801 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Map ({})", entry, itemTemplate.Map);
3802
3803 if (itemTemplate.BagFamily)
3804 {
3805 // check bits
3806 for (uint32 j = 0; j < sizeof(itemTemplate.BagFamily) * 8; ++j)
3807 {
3808 uint32 mask = 1 << j;
3809 if ((itemTemplate.BagFamily & mask) == 0)
3810 continue;
3811
3812 ItemBagFamilyEntry const* bf = sItemBagFamilyStore.LookupEntry(j + 1);
3813 if (!bf)
3814 {
3815 LOG_ERROR("sql.sql", "Item (Entry: {}) has bag family bit set not listed in ItemBagFamily.dbc, remove bit", entry);
3816 itemTemplate.BagFamily &= ~mask;
3817 continue;
3818 }
3819
3821 {
3822 CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemTemplate.ItemId);
3823 if (!ctEntry)
3824 {
3825 LOG_ERROR("sql.sql", "Item (Entry: {}) has currency bag family bit set in BagFamily but not listed in CurrencyTypes.dbc, remove bit", entry);
3826 itemTemplate.BagFamily &= ~mask;
3827 }
3828 }
3829 }
3830 }
3831
3832 if (itemTemplate.TotemCategory && !sTotemCategoryStore.LookupEntry(itemTemplate.TotemCategory))
3833 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong TotemCategory ({})", entry, itemTemplate.TotemCategory);
3834
3835 for (uint8 j = 0; j < MAX_ITEM_PROTO_SOCKETS; ++j)
3836 {
3837 if (itemTemplate.Socket[j].Color && (itemTemplate.Socket[j].Color & SOCKET_COLOR_ALL) != itemTemplate.Socket[j].Color)
3838 {
3839 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong socketColor_{} ({})", entry, j + 1, itemTemplate.Socket[j].Color);
3840 itemTemplate.Socket[j].Color = 0;
3841 }
3842 }
3843
3844 if (itemTemplate.GemProperties && !sGemPropertiesStore.LookupEntry(itemTemplate.GemProperties))
3845 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong GemProperties ({})", entry, itemTemplate.GemProperties);
3846
3847 if (itemTemplate.FoodType >= MAX_PET_DIET)
3848 {
3849 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong FoodType value ({})", entry, itemTemplate.FoodType);
3850 itemTemplate.FoodType = 0;
3851 }
3852
3853 if (itemTemplate.ItemLimitCategory && !sItemLimitCategoryStore.LookupEntry(itemTemplate.ItemLimitCategory))
3854 {
3855 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong LimitCategory value ({})", entry, itemTemplate.ItemLimitCategory);
3856 itemTemplate.ItemLimitCategory = 0;
3857 }
3858
3859 if (itemTemplate.HolidayId && !sHolidaysStore.LookupEntry(itemTemplate.HolidayId))
3860 {
3861 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong HolidayId value ({})", entry, itemTemplate.HolidayId);
3862 itemTemplate.HolidayId = 0;
3863 }
3864
3865 if (itemTemplate.HasFlagCu(ITEM_FLAGS_CU_DURATION_REAL_TIME) && !itemTemplate.Duration)
3866 {
3867 LOG_ERROR("sql.sql", "Item (Entry {}) has flag ITEM_FLAGS_CU_DURATION_REAL_TIME but it does not have duration limit", entry);
3868 itemTemplate.FlagsCu = static_cast<ItemFlagsCustom>(static_cast<uint32>(itemTemplate.FlagsCu) & ~ITEM_FLAGS_CU_DURATION_REAL_TIME);
3869 }
3870
3871 // Set after checks to ensure valid item quality
3872 itemTemplate.BuyPrice *= sWorld->getRate(qualityToBuyValueConfig[itemTemplate.Quality]);
3873 itemTemplate.SellPrice *= sWorld->getRate(qualityToSellValueConfig[itemTemplate.Quality]);
3874
3875 // Fill categories map
3876 for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
3877 if (itemTemplate.Spells[i].SpellId && itemTemplate.Spells[i].SpellCategory && itemTemplate.Spells[i].SpellCategoryCooldown)
3878 {
3879 SpellCategoryStore::iterator ct = sSpellsByCategoryStore.find(itemTemplate.Spells[i].SpellCategory);
3880 if (ct != sSpellsByCategoryStore.end())
3881 {
3882 ct->second.emplace(true, itemTemplate.Spells[i].SpellId);
3883 }
3884 else
3885 sSpellsByCategoryStore[itemTemplate.Spells[i].SpellCategory].emplace(true, itemTemplate.Spells[i].SpellId);
3886 }
3887
3888 ++count;
3889 } while (result->NextRow());
3890
3891 // pussywizard:
3892 {
3893 uint32 max = 0;
3894 for (ItemTemplateContainer::const_iterator itr = _itemTemplateStore.begin(); itr != _itemTemplateStore.end(); ++itr)
3895 if (itr->first > max)
3896 max = itr->first;
3897 if (max)
3898 {
3899 _itemTemplateStoreFast.clear();
3900 _itemTemplateStoreFast.resize(max + 1, nullptr);
3901 for (ItemTemplateContainer::iterator itr = _itemTemplateStore.begin(); itr != _itemTemplateStore.end(); ++itr)
3902 _itemTemplateStoreFast[itr->first] = &(itr->second);
3903 }
3904 }
3905
3906 // Check if item templates for DBC referenced character start outfit are present
3907 std::set<uint32> notFoundOutfit;
3908 for (uint32 i = 1; i < sCharStartOutfitStore.GetNumRows(); ++i)
3909 {
3910 CharStartOutfitEntry const* entry = sCharStartOutfitStore.LookupEntry(i);
3911 if (!entry)
3912 continue;
3913
3914 for (int j = 0; j < MAX_OUTFIT_ITEMS; ++j)
3915 {
3916 if (entry->ItemId[j] <= 0)
3917 continue;
3918
3919 uint32 item_id = entry->ItemId[j];
3920
3921 if (!GetItemTemplate(item_id))
3922 notFoundOutfit.insert(item_id);
3923 }
3924 }
3925
3926 for (std::set<uint32>::const_iterator itr = notFoundOutfit.begin(); itr != notFoundOutfit.end(); ++itr)
3927 LOG_ERROR("sql.sql", "Item (Entry: {}) does not exist in `item_template` but is referenced in `CharStartOutfit.dbc`", *itr);
3928
3929 LOG_INFO("server.loading", ">> Loaded {} Item Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3930 LOG_INFO("server.loading", " ");
3931}
#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:3302
ServerConfigs const qualityToBuyValueConfig[MAX_ITEM_QUALITY]
Definition ObjectMgr.cpp:3290
#define MAX_REPUTATION_RANK
Definition SharedDefines.h:233
#define MIN_REPUTATION_RANK
Definition SharedDefines.h:232
#define MAX_PET_DIET
Definition SharedDefines.h:3464
@ ITEM_QUALITY_NORMAL
Definition SharedDefines.h:318
#define MAX_ITEM_QUALITY
Definition SharedDefines.h:327
#define MAX_SKILL_TYPE
Definition SharedDefines.h:3251
@ ALLIANCE
Definition SharedDefines.h:756
@ HORDE
Definition SharedDefines.h:755
#define CLASSMASK_ALL_PLAYABLE
Definition SharedDefines.h:142
@ CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES
Definition WorldConfig.h:96
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, sAreaTableStore, sCharStartOutfitStore, sCurrencyTypesStore, sDisableMgr, sFactionStore, sGemPropertiesStore, ItemEntry::SheatheType, sHolidaysStore, sItemBagFamilyStore, sItemLimitCategoryStore, sItemRandomPropertiesStore, sItemRandomSuffixStore, sItemSetStore, sItemStore, sLockStore, sMapStore, SOCKET_COLOR_ALL, ItemEntry::SoundOverrideSubclassID, sRaceMgr, sSpellMgr, sSpellsByCategoryStore, sTotemCategoryStore, ItemEntry::SubclassID, sWorld, and WorldDatabase.

◆ LoadLinkedRespawn()

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

◆ LoadMailLevelRewards()

void ObjectMgr::LoadMailLevelRewards ( )
10004{
10005 uint32 oldMSTime = getMSTime();
10006
10007 _mailLevelRewardStore.clear(); // for reload case
10008
10009 // 0 1 2 3
10010 QueryResult result = WorldDatabase.Query("SELECT level, raceMask, mailTemplateId, senderEntry FROM mail_level_reward");
10011
10012 if (!result)
10013 {
10014 LOG_WARN("server.loading", ">> Loaded 0 level dependent mail rewards. DB table `mail_level_reward` is empty.");
10015 LOG_INFO("server.loading", " ");
10016 return;
10017 }
10018
10019 uint32 count = 0;
10020
10021 do
10022 {
10023 Field* fields = result->Fetch();
10024
10025 uint8 level = fields[0].Get<uint8>();
10026 uint32 raceMask = fields[1].Get<uint32>();
10027 uint32 mailTemplateId = fields[2].Get<uint32>();
10028 uint32 senderEntry = fields[3].Get<uint32>();
10029
10030 if (level > MAX_LEVEL)
10031 {
10032 LOG_ERROR("sql.sql", "Table `mail_level_reward` have data for level {} that more supported by client ({}), ignoring.", level, MAX_LEVEL);
10033 continue;
10034 }
10035
10036 if (!(raceMask & sRaceMgr->GetPlayableRaceMask()))
10037 {
10038 LOG_ERROR("sql.sql", "Table `mail_level_reward` have raceMask ({}) for level {} that not include any player races, ignoring.", raceMask, level);
10039 continue;
10040 }
10041
10042 if (!sMailTemplateStore.LookupEntry(mailTemplateId))
10043 {
10044 LOG_ERROR("sql.sql", "Table `mail_level_reward` have invalid mailTemplateId ({}) for level {} that invalid not include any player races, ignoring.", mailTemplateId, level);
10045 continue;
10046 }
10047
10048 if (!GetCreatureTemplate(senderEntry))
10049 {
10050 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);
10051 continue;
10052 }
10053
10054 _mailLevelRewardStore[level].push_back(MailLevelReward(raceMask, mailTemplateId, senderEntry));
10055
10056 ++count;
10057 } while (result->NextRow());
10058
10059 LOG_INFO("server.loading", ">> Loaded {} Level Dependent Mail Rewards in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10060 LOG_INFO("server.loading", " ");
10061}
#define MAX_LEVEL
Definition DBCEnums.h:39
DBCStorage< MailTemplateEntry > sMailTemplateStore(MailTemplateEntryfmt)
Definition ObjectMgr.h:549

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

◆ LoadModuleStrings()

bool ObjectMgr::LoadModuleStrings ( )
9583{
9584 uint32 oldMSTime = getMSTime();
9585
9586 _moduleStringStore.clear(); // for reload case
9587 QueryResult result = WorldDatabase.Query("SELECT module, id, string FROM module_string");
9588 if (!result)
9589 {
9590 LOG_WARN("server.loading", ">> Loaded 0 module strings. DB table `module_string` is empty.");
9591 LOG_INFO("server.loading", " ");
9592 return false;
9593 }
9594
9595 do
9596 {
9597 Field* fields = result->Fetch();
9598
9599 std::string module = fields[0].Get<std::string>();
9600 uint32 id = fields[1].Get<uint32>();
9601
9602 std::pair<std::string, uint32> pairKey = std::make_pair(module, id);
9603 ModuleString& data = _moduleStringStore[pairKey];
9604
9605 AddLocaleString(fields[2].Get<std::string>(), LOCALE_enUS, data.Content);
9606 } while (result->NextRow());
9607
9608 LOG_INFO("server.loading", ">> Loaded {} Module Strings in {} ms", _moduleStringStore.size(), GetMSTimeDiffToNow(oldMSTime));
9609 LOG_INFO("server.loading", " ");
9610
9611 return true;
9612}

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

◆ LoadModuleStringsLocale()

bool ObjectMgr::LoadModuleStringsLocale ( )
9615{
9616 uint32 oldMSTime = getMSTime();
9617
9618 QueryResult result = WorldDatabase.Query("SELECT module, id, locale, string FROM module_string_locale");
9619 if (!result)
9620 {
9621 LOG_WARN("server.loading", ">> Loaded 0 module strings locale. DB table `module_string_locale` is empty.");
9622 LOG_INFO("server.loading", " ");
9623 return false;
9624 }
9625
9626 uint32 localeCount = 0;
9627 do
9628 {
9629 Field* fields = result->Fetch();
9630
9631 std::string module = fields[0].Get<std::string>();
9632 uint32 id = fields[1].Get<uint32>();
9633
9634 std::pair<std::string, uint32> pairKey = std::make_pair(module, id);
9635 ModuleString& data = _moduleStringStore[pairKey];
9636
9637 ModuleStringContainer::iterator ms = _moduleStringStore.find(pairKey);
9638 if (ms == _moduleStringStore.end())
9639 {
9640 LOG_ERROR("sql.sql", "ModuleString (Module: {} Id: {}) found in table `module_string_locale` but does not exist in `module_string`. Skipped!", module, id);
9641 continue;
9642 }
9643
9644 LocaleConstant locale = GetLocaleByName(fields[2].Get<std::string>());
9645 if (locale == LOCALE_enUS)
9646 continue;
9647
9648 AddLocaleString(fields[3].Get<std::string>(), locale, data.Content);
9649 localeCount++;
9650 } while (result->NextRow());
9651
9652 LOG_INFO("server.loading", ">> Loaded {} Module Strings Locales in {} ms", localeCount, GetMSTimeDiffToNow(oldMSTime));
9653 LOG_INFO("server.loading", " ");
9654
9655 return true;
9656}

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

◆ LoadNPCSpellClickSpells()

void ObjectMgr::LoadNPCSpellClickSpells ( )
8689{
8690 uint32 oldMSTime = getMSTime();
8691
8692 _spellClickInfoStore.clear();
8693 // 0 1 2 3
8694 QueryResult result = WorldDatabase.Query("SELECT npc_entry, spell_id, cast_flags, user_type FROM npc_spellclick_spells");
8695
8696 if (!result)
8697 {
8698 LOG_WARN("server.loading", ">> Loaded 0 spellclick spells. DB table `npc_spellclick_spells` is empty.");
8699 LOG_INFO("server.loading", " ");
8700 return;
8701 }
8702
8703 uint32 count = 0;
8704
8705 do
8706 {
8707 Field* fields = result->Fetch();
8708
8709 uint32 npc_entry = fields[0].Get<uint32>();
8710 CreatureTemplate const* cInfo = GetCreatureTemplate(npc_entry);
8711 if (!cInfo)
8712 {
8713 LOG_ERROR("sql.sql", "Table npc_spellclick_spells references unknown creature_template {}. Skipping entry.", npc_entry);
8714 continue;
8715 }
8716
8717 uint32 spellid = fields[1].Get<uint32>();
8718 SpellInfo const* spellinfo = sSpellMgr->GetSpellInfo(spellid);
8719 if (!spellinfo)
8720 {
8721 LOG_ERROR("sql.sql", "Table npc_spellclick_spells references unknown spellid {}. Skipping entry.", spellid);
8722 continue;
8723 }
8724
8725 uint8 userType = fields[3].Get<uint16>();
8726 if (userType >= SPELL_CLICK_USER_MAX)
8727 LOG_ERROR("sql.sql", "Table npc_spellclick_spells references unknown user type {}. Skipping entry.", uint32(userType));
8728
8729 uint8 castFlags = fields[2].Get<uint8>();
8730 SpellClickInfo info;
8731 info.spellId = spellid;
8732 info.castFlags = castFlags;
8733 info.userType = SpellClickUserTypes(userType);
8734 _spellClickInfoStore.insert(SpellClickInfoContainer::value_type(npc_entry, info));
8735
8736 ++count;
8737 } while (result->NextRow());
8738
8739 // all spellclick data loaded, now we check if there are creatures with NPC_FLAG_SPELLCLICK but with no data
8740 // NOTE: It *CAN* be the other way around: no spellclick flag but with spellclick data, in case of creature-only vehicle accessories
8742 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
8743 {
8744 if ((itr->second.npcflag & UNIT_NPC_FLAG_SPELLCLICK) && _spellClickInfoStore.find(itr->second.Entry) == _spellClickInfoStore.end())
8745 {
8746 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);
8747 const_cast<CreatureTemplate*>(&itr->second)->npcflag &= ~UNIT_NPC_FLAG_SPELLCLICK;
8748 }
8749 }
8750
8751 LOG_INFO("server.loading", ">> Loaded {} Spellclick Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8752 LOG_INFO("server.loading", " ");
8753}
SpellClickUserTypes
Definition SharedDefines.h:668
@ SPELL_CLICK_USER_MAX
Definition SharedDefines.h:673
@ UNIT_NPC_FLAG_SPELLCLICK
Definition UnitDefines.h:346
Definition ObjectMgr.h:401
uint32 spellId
Definition ObjectMgr.h:402

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 ( )
6773{
6774 uint32 oldMSTime = getMSTime();
6775
6776 _npcTextLocaleStore.clear(); // need for reload case
6777
6778 QueryResult result = WorldDatabase.Query("SELECT ID, Locale, "
6779 // 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
6780 "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 "
6781 "FROM npc_text_locale");
6782
6783 if (!result)
6784 return;
6785
6786 do
6787 {
6788 Field* fields = result->Fetch();
6789
6790 uint32 ID = fields[0].Get<uint32>();
6791
6792 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
6793 if (locale == LOCALE_enUS)
6794 continue;
6795
6797 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
6798 {
6799 AddLocaleString(fields[2 + i * 2].Get<std::string>(), locale, data.Text_0[i]);
6800 AddLocaleString(fields[3 + i * 2].Get<std::string>(), locale, data.Text_1[i]);
6801 }
6802 } while (result->NextRow());
6803
6804 LOG_INFO("server.loading", ">> Loaded {} Npc Text Locale Strings in {} ms", (uint32)_npcTextLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
6805}
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 ( )
6520{
6521 uint32 oldMSTime = getMSTime();
6522
6523 _pageTextLocaleStore.clear(); // need for reload case
6524
6525 // 0 1 2
6526 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Text FROM page_text_locale");
6527
6528 if (!result)
6529 {
6530 LOG_WARN("server.loading", ">> Loaded 0 page texts. DB table `page_text_locale` is empty!");
6531 LOG_INFO("server.loading", " ");
6532 return;
6533 }
6534
6535 do
6536 {
6537 Field* fields = result->Fetch();
6538
6539 uint32 ID = fields[0].Get<uint32>();
6540
6541 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
6542 if (locale == LOCALE_enUS)
6543 continue;
6544
6546 AddLocaleString(fields[2].Get<std::string>(), locale, data.Text);
6547 } while (result->NextRow());
6548
6549 LOG_INFO("server.loading", ">> Loaded {} Page Text Locale Strings in {} ms", (uint32)_pageTextLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
6550}
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 ( )
6470{
6471 uint32 oldMSTime = getMSTime();
6472
6473 // 0 1 2
6474 QueryResult result = WorldDatabase.Query("SELECT ID, Text, NextPageID FROM page_text");
6475
6476 if (!result)
6477 {
6478 LOG_WARN("server.loading", ">> Loaded 0 page texts. DB table `page_text` is empty!");
6479 LOG_INFO("server.loading", " ");
6480 return;
6481 }
6482
6483 uint32 count = 0;
6484 do
6485 {
6486 Field* fields = result->Fetch();
6487
6488 PageText& pageText = _pageTextStore[fields[0].Get<uint32>()];
6489
6490 pageText.Text = fields[1].Get<std::string>();
6491 pageText.NextPage = fields[2].Get<uint32>();
6492
6493 ++count;
6494 } while (result->NextRow());
6495
6496 for (PageTextContainer::const_iterator itr = _pageTextStore.begin(); itr != _pageTextStore.end(); ++itr)
6497 {
6498 if (itr->second.NextPage)
6499 {
6500 PageTextContainer::const_iterator itr2 = _pageTextStore.find(itr->second.NextPage);
6501 if (itr2 == _pageTextStore.end())
6502 LOG_ERROR("sql.sql", "Page text (Id: {}) has not existing next page (Id: {})", itr->first, itr->second.NextPage);
6503 }
6504 }
6505
6506 LOG_INFO("server.loading", ">> Loaded {} Page Texts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6507 LOG_INFO("server.loading", " ");
6508}
Definition ObjectMgr.h:60
std::string Text
Definition ObjectMgr.h:61
uint32 NextPage
Definition ObjectMgr.h:62

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

◆ LoadPetLevelInfo()

void ObjectMgr::LoadPetLevelInfo ( )
4207{
4208 uint32 oldMSTime = getMSTime();
4209
4210 // 0 1 2 3 4 5 6 7 8 9 10 11
4211 QueryResult result = WorldDatabase.Query("SELECT creature_entry, level, hp, mana, str, agi, sta, inte, spi, armor, min_dmg, max_dmg FROM pet_levelstats");
4212
4213 if (!result)
4214 {
4215 LOG_WARN("server.loading", ">> Loaded 0 level pet stats definitions. DB table `pet_levelstats` is empty.");
4216 LOG_INFO("server.loading", " ");
4217 return;
4218 }
4219
4220 uint32 count = 0;
4221
4222 do
4223 {
4224 Field* fields = result->Fetch();
4225
4226 uint32 creature_id = fields[0].Get<uint32>();
4227 if (!GetCreatureTemplate(creature_id))
4228 {
4229 LOG_ERROR("sql.sql", "Wrong creature id {} in `pet_levelstats` table, ignoring.", creature_id);
4230 continue;
4231 }
4232
4233 uint32 current_level = fields[1].Get<uint8>();
4234 if (current_level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4235 {
4236 if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
4237 LOG_ERROR("sql.sql", "Wrong (> {}) level {} in `pet_levelstats` table, ignoring.", STRONG_MAX_LEVEL, current_level);
4238 else
4239 {
4240 LOG_DEBUG("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `pet_levelstats` table, ignoring.", current_level);
4241 ++count; // make result loading percent "expected" correct in case disabled detail mode for example.
4242 }
4243 continue;
4244 }
4245 else if (current_level < 1)
4246 {
4247 LOG_ERROR("sql.sql", "Wrong (<1) level {} in `pet_levelstats` table, ignoring.", current_level);
4248 continue;
4249 }
4250
4251 PetLevelInfo*& pInfoMapEntry = _petInfoStore[creature_id];
4252
4253 if (!pInfoMapEntry)
4254 pInfoMapEntry = new PetLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)];
4255
4256 // data for level 1 stored in [0] array element, ...
4257 PetLevelInfo* pLevelInfo = &pInfoMapEntry[current_level - 1];
4258
4259 pLevelInfo->health = fields[2].Get<uint32>();
4260 pLevelInfo->mana = fields[3].Get<uint32>();
4261 pLevelInfo->armor = fields[9].Get<uint32>();
4262 pLevelInfo->min_dmg = fields[10].Get<uint32>();
4263 pLevelInfo->max_dmg = fields[11].Get<uint32>();
4264 for (uint8 i = 0; i < MAX_STATS; i++)
4265 {
4266 pLevelInfo->stats[i] = fields[i + 4].Get<uint32>();
4267 }
4268
4269 ++count;
4270 } while (result->NextRow());
4271
4272 // Fill gaps and check integrity
4273 for (PetLevelInfoContainer::iterator itr = _petInfoStore.begin(); itr != _petInfoStore.end(); ++itr)
4274 {
4275 PetLevelInfo* pInfo = itr->second;
4276
4277 // fatal error if no level 1 data
4278 if (!pInfo || pInfo[0].health == 0)
4279 {
4280 LOG_ERROR("sql.sql", "Creature {} does not have pet stats data for Level 1!", itr->first);
4281 exit(1);
4282 }
4283
4284 // fill level gaps
4285 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4286 {
4287 if (pInfo[level].health == 0)
4288 {
4289 LOG_ERROR("sql.sql", "Creature {} has no data for Level {} pet stats data, using data of Level {}.", itr->first, level + 1, level);
4290 pInfo[level] = pInfo[level - 1];
4291 }
4292 }
4293 }
4294
4295 LOG_INFO("server.loading", ">> Loaded {} Level Pet Stats Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4296 LOG_INFO("server.loading", " ");
4297}
#define STRONG_MAX_LEVEL
Definition DBCEnums.h:43
#define MAX_STATS
Definition SharedDefines.h:253
Definition ObjectMgr.h:534
uint32 max_dmg
Definition ObjectMgr.h:545
uint32 mana
Definition ObjectMgr.h:542
uint32 min_dmg
Definition ObjectMgr.h:544
uint32 health
Definition ObjectMgr.h:541
std::array< uint32, MAX_STATS > stats
Definition ObjectMgr.h:540
uint32 armor
Definition ObjectMgr.h:543

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 ( )
8195{
8196 uint32 oldMSTime = getMSTime();
8197 // 0 1 2
8198 QueryResult result = WorldDatabase.Query("SELECT word, entry, half FROM pet_name_generation");
8199
8200 if (!result)
8201 {
8202 LOG_WARN("server.loading", ">> Loaded 0 pet name parts. DB table `pet_name_generation` is empty!");
8203 LOG_INFO("server.loading", " ");
8204 return;
8205 }
8206
8207 uint32 count = 0;
8208
8209 do
8210 {
8211 Field* fields = result->Fetch();
8212 std::string word = fields[0].Get<std::string>();
8213 uint32 entry = fields[1].Get<uint32>();
8214 bool half = fields[2].Get<bool>();
8215 if (half)
8216 _petHalfName1[entry].push_back(word);
8217 else
8218 _petHalfName0[entry].push_back(word);
8219 ++count;
8220 } while (result->NextRow());
8221
8222 LOG_INFO("server.loading", ">> Loaded {} Pet Name Parts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8223 LOG_INFO("server.loading", " ");
8224}

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

◆ LoadPetNamesLocales()

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

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

◆ LoadPetNumber()

void ObjectMgr::LoadPetNumber ( )
8227{
8228 uint32 oldMSTime = getMSTime();
8229
8230 QueryResult result = CharacterDatabase.Query("SELECT MAX(id) FROM character_pet");
8231 if (result)
8232 {
8233 Field* fields = result->Fetch();
8234 _hiPetNumber = fields[0].Get<uint32>() + 1;
8235 }
8236
8237 LOG_INFO("server.loading", ">> Loaded The Max Pet Number: {} in {} ms", _hiPetNumber - 1, GetMSTimeDiffToNow(oldMSTime));
8238 LOG_INFO("server.loading", " ");
8239}

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

◆ LoadPlayerInfo()

void ObjectMgr::LoadPlayerInfo ( )
4346{
4347 // Load playercreate
4348 {
4349 if (_playerInfo.empty() || _playerInfo.size() != sRaceMgr->GetMaxRaces())
4350 {
4351 _playerInfo.clear();
4352 _playerInfo.resize(sRaceMgr->GetMaxRaces());
4353 for (auto& classVec : _playerInfo)
4354 classVec.resize(MAX_CLASSES, nullptr);
4355 }
4356
4357 uint32 oldMSTime = getMSTime();
4358 // 0 1 2 3 4 5 6
4359 QueryResult result = WorldDatabase.Query("SELECT race, class, map, zone, position_x, position_y, position_z, orientation FROM playercreateinfo");
4360
4361 if (!result)
4362 {
4363 LOG_INFO("server.loading", " ");
4364 LOG_WARN("server.loading", ">> Loaded 0 player create definitions. DB table `playercreateinfo` is empty.");
4365 exit(1);
4366 }
4367 else
4368 {
4369 uint32 count = 0;
4370
4371 do
4372 {
4373 Field* fields = result->Fetch();
4374
4375 uint32 current_race = fields[0].Get<uint8>();
4376 uint32 current_class = fields[1].Get<uint8>();
4377 uint32 mapId = fields[2].Get<uint16>();
4378 uint32 areaId = fields[3].Get<uint32>(); // zone
4379 float positionX = fields[4].Get<float>();
4380 float positionY = fields[5].Get<float>();
4381 float positionZ = fields[6].Get<float>();
4382 float orientation = fields[7].Get<float>();
4383
4384 if (current_race >= sRaceMgr->GetMaxRaces())
4385 {
4386 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo` table, ignoring.", current_race);
4387 continue;
4388 }
4389
4390 ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(current_race);
4391 if (!rEntry)
4392 {
4393 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo` table, ignoring.", current_race);
4394 continue;
4395 }
4396
4397 if (current_class >= MAX_CLASSES)
4398 {
4399 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo` table, ignoring.", current_class);
4400 continue;
4401 }
4402
4403 if (!sChrClassesStore.LookupEntry(current_class))
4404 {
4405 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo` table, ignoring.", current_class);
4406 continue;
4407 }
4408
4409 // accept DB data only for valid position (and non instanceable)
4410 if (!MapMgr::IsValidMapCoord(mapId, positionX, positionY, positionZ, orientation))
4411 {
4412 LOG_ERROR("sql.sql", "Wrong home position for class {} race {} pair in `playercreateinfo` table, ignoring.", current_class, current_race);
4413 continue;
4414 }
4415
4416 if (sMapStore.LookupEntry(mapId)->Instanceable())
4417 {
4418 LOG_ERROR("sql.sql", "Home position in instanceable map for class {} race {} pair in `playercreateinfo` table, ignoring.", current_class, current_race);
4419 continue;
4420 }
4421
4422 PlayerInfo* info = new PlayerInfo();
4423 info->mapId = mapId;
4424 info->areaId = areaId;
4425 info->positionX = positionX;
4426 info->positionY = positionY;
4427 info->positionZ = positionZ;
4428 info->orientation = orientation;
4429 info->displayId_m = rEntry->model_m;
4430 info->displayId_f = rEntry->model_f;
4431 _playerInfo[current_race][current_class] = info;
4432
4433 ++count;
4434 } while (result->NextRow());
4435
4436 LOG_INFO("server.loading", ">> Loaded {} Player Create Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4437 LOG_INFO("server.loading", " ");
4438 }
4439 }
4440
4441 // Load playercreate items
4442 LOG_INFO("server.loading", "Loading Player Create Items Data...");
4443 {
4444 uint32 oldMSTime = getMSTime();
4445 // 0 1 2 3
4446 QueryResult result = WorldDatabase.Query("SELECT race, class, itemid, amount FROM playercreateinfo_item");
4447
4448 if (!result)
4449 {
4450 LOG_WARN("server.loading", ">> Loaded 0 Custom Player Create Items. DB Table `playercreateinfo_item` Is Empty.");
4451 LOG_INFO("server.loading", " ");
4452 }
4453 else
4454 {
4455 uint32 count = 0;
4456
4457 do
4458 {
4459 Field* fields = result->Fetch();
4460
4461 uint32 current_race = fields[0].Get<uint8>();
4462 if (current_race >= sRaceMgr->GetMaxRaces())
4463 {
4464 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo_item` table, ignoring.", current_race);
4465 continue;
4466 }
4467
4468 uint32 current_class = fields[1].Get<uint8>();
4469 if (current_class >= MAX_CLASSES)
4470 {
4471 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo_item` table, ignoring.", current_class);
4472 continue;
4473 }
4474
4475 uint32 item_id = fields[2].Get<uint32>();
4476
4477 if (!GetItemTemplate(item_id))
4478 {
4479 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);
4480 continue;
4481 }
4482
4483 int32 amount = fields[3].Get<int32>();
4484
4485 if (!amount)
4486 {
4487 LOG_ERROR("sql.sql", "Item id {} (class {} race {}) have amount == 0 in `playercreateinfo_item` table, ignoring.", item_id, current_race, current_class);
4488 continue;
4489 }
4490
4491 if (!current_race || !current_class)
4492 {
4493 uint32 min_race = current_race ? current_race : 1;
4494 uint32 max_race = current_race ? current_race + 1 : sRaceMgr->GetMaxRaces();
4495 uint32 min_class = current_class ? current_class : 1;
4496 uint32 max_class = current_class ? current_class + 1 : MAX_CLASSES;
4497 for (uint32 r = min_race; r < max_race; ++r)
4498 for (uint32 c = min_class; c < max_class; ++c)
4499 PlayerCreateInfoAddItemHelper(r, c, item_id, amount);
4500 }
4501 else
4502 PlayerCreateInfoAddItemHelper(current_race, current_class, item_id, amount);
4503
4504 ++count;
4505 } while (result->NextRow());
4506
4507 LOG_INFO("server.loading", ">> Loaded {} Custom Player Create Items in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4508 LOG_INFO("server.loading", " ");
4509 }
4510 }
4511
4512 // Load playercreate skills
4513 LOG_INFO("server.loading", "Loading Player Create Skill Data...");
4514 {
4515 uint32 oldMSTime = getMSTime();
4516
4517 QueryResult result = WorldDatabase.Query("SELECT raceMask, classMask, skill, `rank` FROM playercreateinfo_skills");
4518
4519 if (!result)
4520 {
4521 LOG_WARN("server.loading", ">> Loaded 0 Player Create Skills. DB Table `playercreateinfo_skills` Is Empty.");
4522 }
4523 else
4524 {
4525 uint32 count = 0;
4526
4527 do
4528 {
4529 Field* fields = result->Fetch();
4530 uint32 raceMask = fields[0].Get<uint32>();
4531 uint32 classMask = fields[1].Get<uint32>();
4533 skill.SkillId = fields[2].Get<uint16>();
4534 skill.Rank = fields[3].Get<uint16>();
4535
4536 if (skill.Rank >= MAX_SKILL_STEP)
4537 {
4538 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);
4539 continue;
4540 }
4541
4542 if (raceMask != 0 && !(raceMask & sRaceMgr->GetPlayableRaceMask()))
4543 {
4544 LOG_ERROR("sql.sql", "Wrong race mask {} in `playercreateinfo_skills` table, ignoring.", raceMask);
4545 continue;
4546 }
4547
4548 if (classMask != 0 && !(classMask & CLASSMASK_ALL_PLAYABLE))
4549 {
4550 LOG_ERROR("sql.sql", "Wrong class mask {} in `playercreateinfo_skills` table, ignoring.", classMask);
4551 continue;
4552 }
4553
4554 if (!sSkillLineStore.LookupEntry(skill.SkillId))
4555 {
4556 LOG_ERROR("sql.sql", "Wrong skill id {} in `playercreateinfo_skills` table, ignoring.", skill.SkillId);
4557 continue;
4558 }
4559
4560 for (uint32 raceIndex = RACE_HUMAN; raceIndex < sRaceMgr->GetMaxRaces(); ++raceIndex)
4561 {
4562 if (raceMask == 0 || ((1 << (raceIndex - 1)) & raceMask))
4563 {
4564 for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex)
4565 {
4566 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
4567 {
4568 if (!GetSkillRaceClassInfo(skill.SkillId, raceIndex, classIndex))
4569 continue;
4570
4571 if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
4572 {
4573 info->skills.push_back(skill);
4574 ++count;
4575 }
4576 }
4577 }
4578 }
4579 }
4580 } while (result->NextRow());
4581
4582 LOG_INFO("server.loading", ">> Loaded {} Player Create Skills in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4583 LOG_INFO("server.loading", " ");
4584 }
4585 }
4586
4587 // Load playercreate spells
4588 LOG_INFO("server.loading", "Loading Player Create Spell Data...");
4589 {
4590 uint32 oldMSTime = getMSTime();
4591
4592 QueryResult result = WorldDatabase.Query("SELECT racemask, classmask, Spell FROM playercreateinfo_spell_custom");
4593
4594 if (!result)
4595 {
4596 LOG_WARN("server.loading", ">> Loaded 0 player create spells. DB table `playercreateinfo_spell_custom` is empty.");
4597 }
4598 else
4599 {
4600 uint32 count = 0;
4601
4602 do
4603 {
4604 Field* fields = result->Fetch();
4605 uint32 raceMask = fields[0].Get<uint32>();
4606 uint32 classMask = fields[1].Get<uint32>();
4607 uint32 spellId = fields[2].Get<uint32>();
4608
4609 if (raceMask != 0 && !(raceMask & sRaceMgr->GetPlayableRaceMask()))
4610 {
4611 LOG_ERROR("sql.sql", "Wrong race mask {} in `playercreateinfo_spell_custom` table, ignoring.", raceMask);
4612 continue;
4613 }
4614
4615 if (classMask != 0 && !(classMask & CLASSMASK_ALL_PLAYABLE))
4616 {
4617 LOG_ERROR("sql.sql", "Wrong class mask {} in `playercreateinfo_spell_custom` table, ignoring.", classMask);
4618 continue;
4619 }
4620
4621 for (uint32 raceIndex = RACE_HUMAN; raceIndex < sRaceMgr->GetMaxRaces(); ++raceIndex)
4622 {
4623 if (raceMask == 0 || ((1 << (raceIndex - 1)) & raceMask))
4624 {
4625 for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex)
4626 {
4627 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
4628 {
4629 if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
4630 {
4631 info->customSpells.push_back(spellId);
4632 ++count;
4633 }
4634 }
4635 }
4636 }
4637 }
4638 } while (result->NextRow());
4639
4640 LOG_INFO("server.loading", ">> Loaded {} Custom Player Create Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4641 LOG_INFO("server.loading", " ");
4642 }
4643 }
4644
4645 // Load playercreate cast spell
4646 LOG_INFO("server.loading", "Loading Player Create Cast Spell Data...");
4647 {
4648 uint32 oldMSTime = getMSTime();
4649
4650 QueryResult result = WorldDatabase.Query("SELECT raceMask, classMask, spell FROM playercreateinfo_cast_spell");
4651
4652 if (!result)
4653 {
4654 LOG_WARN("server.loading", ">> Loaded 0 Player Create Cast Spells. DB Table `playercreateinfo_cast_spell` Is Empty.");
4655 }
4656 else
4657 {
4658 uint32 count = 0;
4659
4660 do
4661 {
4662 Field* fields = result->Fetch();
4663 uint32 raceMask = fields[0].Get<uint32>();
4664 uint32 classMask = fields[1].Get<uint32>();
4665 uint32 spellId = fields[2].Get<uint32>();
4666
4667 if (raceMask != 0 && !(raceMask & sRaceMgr->GetPlayableRaceMask()))
4668 {
4669 LOG_ERROR("sql.sql", "Wrong race mask {} in `playercreateinfo_cast_spell` table, ignoring.", raceMask);
4670 continue;
4671 }
4672
4673 if (classMask != 0 && !(classMask & CLASSMASK_ALL_PLAYABLE))
4674 {
4675 LOG_ERROR("sql.sql", "Wrong class mask {} in `playercreateinfo_cast_spell` table, ignoring.", classMask);
4676 continue;
4677 }
4678
4679 for (uint32 raceIndex = RACE_HUMAN; raceIndex < sRaceMgr->GetMaxRaces(); ++raceIndex)
4680 {
4681 if (raceMask == 0 || ((1 << (raceIndex - 1)) & raceMask))
4682 {
4683 for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex)
4684 {
4685 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
4686 {
4687 if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
4688 {
4689 info->castSpells.push_back(spellId);
4690 ++count;
4691 }
4692 }
4693 }
4694 }
4695 }
4696 } while (result->NextRow());
4697
4698 LOG_INFO("server.loading", ">> Loaded {} Player Create Cast Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4699 LOG_INFO("server.loading", " ");
4700 }
4701 }
4702
4703 // Load playercreate actions
4704 LOG_INFO("server.loading", "Loading Player Create Action Data...");
4705 {
4706 uint32 oldMSTime = getMSTime();
4707
4708 // 0 1 2 3 4
4709 QueryResult result = WorldDatabase.Query("SELECT race, class, button, action, type FROM playercreateinfo_action");
4710
4711 if (!result)
4712 {
4713 LOG_WARN("server.loading", ">> Loaded 0 Player Create Actions. DB Table `playercreateinfo_action` Is Empty.");
4714 LOG_INFO("server.loading", " ");
4715 }
4716 else
4717 {
4718 uint32 count = 0;
4719
4720 do
4721 {
4722 Field* fields = result->Fetch();
4723
4724 uint32 current_race = fields[0].Get<uint8>();
4725 if (current_race >= sRaceMgr->GetMaxRaces())
4726 {
4727 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo_action` table, ignoring.", current_race);
4728 continue;
4729 }
4730
4731 uint32 current_class = fields[1].Get<uint8>();
4732 if (current_class >= MAX_CLASSES)
4733 {
4734 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo_action` table, ignoring.", current_class);
4735 continue;
4736 }
4737
4738 if (PlayerInfo* info = _playerInfo[current_race][current_class])
4739 info->action.push_back(PlayerCreateInfoAction(fields[2].Get<uint16>(), fields[3].Get<uint32>(), fields[4].Get<uint16>()));
4740
4741 ++count;
4742 } while (result->NextRow());
4743
4744 LOG_INFO("server.loading", ">> Loaded {} Player Create Actions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4745 LOG_INFO("server.loading", " ");
4746 }
4747 }
4748
4749 // Loading levels data (class/race dependent)
4750 LOG_INFO("server.loading", "Loading Player Create Level Stats Data...");
4751 {
4752 struct RaceStats
4753 {
4754 int16 StatModifier[MAX_STATS];
4755 };
4756
4757 std::vector<RaceStats> raceStatModifiers;
4758
4759 raceStatModifiers.resize(sRaceMgr->GetMaxRaces());
4760
4761 uint32 oldMSTime = getMSTime();
4762
4763 // 0 1 2 3 4 5
4764 QueryResult raceStatsResult = WorldDatabase.Query("SELECT Race, Strength, Agility, Stamina, Intellect, Spirit FROM player_race_stats");
4765
4766 if (!raceStatsResult)
4767 {
4768 LOG_WARN("server.loading", ">> Loaded 0 race stats definitions. DB table `player_race_stats` is empty.");
4769 LOG_INFO("server.loading", " ");
4770 exit(1);
4771 }
4772
4773 do
4774 {
4775 Field* fields = raceStatsResult->Fetch();
4776
4777 uint32 current_race = fields[0].Get<uint8>();
4778 if (current_race >= sRaceMgr->GetMaxRaces())
4779 {
4780 LOG_ERROR("sql.sql", "Wrong race {} in `player_race_stats` table, ignoring.", current_race);
4781 continue;
4782 }
4783
4784 for (uint32 i = 0; i < MAX_STATS; ++i)
4785 raceStatModifiers[current_race].StatModifier[i] = fields[i + 1].Get<int16>();
4786
4787 } while (raceStatsResult->NextRow());
4788
4789 // 0 1 2 3 4 5 6 7 8
4790 QueryResult result = WorldDatabase.Query("SELECT Class, Level, Strength, Agility, Stamina, Intellect, Spirit, BaseHP, BaseMana FROM player_class_stats");
4791
4792 if (!result)
4793 {
4794 LOG_ERROR("server.loading", ">> Loaded 0 level stats definitions. DB table `player_class_stats` is empty.");
4795 exit(1);
4796 }
4797
4798 uint32 count = 0;
4799
4800 do
4801 {
4802 Field* fields = result->Fetch();
4803
4804 uint32 current_class = fields[0].Get<uint8>();
4805 if (current_class >= MAX_CLASSES)
4806 {
4807 LOG_ERROR("sql.sql", "Wrong class {} in `player_class_stats` table, ignoring.", current_class);
4808 continue;
4809 }
4810
4811 uint32 current_level = fields[1].Get<uint8>();
4812 if (current_level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4813 {
4814 if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
4815 LOG_ERROR("sql.sql", "Wrong (> {}) level {} in `player_class_stats` table, ignoring.", STRONG_MAX_LEVEL, current_level);
4816 else
4817 LOG_DEBUG("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_class_stats` table, ignoring.", current_level);
4818
4819 continue;
4820 }
4821
4822 for (std::size_t race = 0; race < raceStatModifiers.size(); ++race)
4823 {
4824 if (PlayerInfo* info = _playerInfo[race][current_class])
4825 {
4826 if (!info->levelInfo)
4827 info->levelInfo = new PlayerLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)];
4828
4829 PlayerLevelInfo& levelInfo = info->levelInfo[current_level - 1];
4830 for (int i = 0; i < MAX_STATS; ++i)
4831 levelInfo.stats[i] = fields[i + 2].Get<uint16>() + raceStatModifiers[race].StatModifier[i];
4832 }
4833 }
4834
4835 PlayerClassInfo* info = _playerClassInfo[current_class];
4836 if (!info)
4837 {
4838 info = new PlayerClassInfo();
4840 _playerClassInfo[current_class] = info;
4841 }
4842
4843 PlayerClassLevelInfo& levelInfo = info->levelInfo[current_level - 1];
4844
4845 levelInfo.basehealth = fields[7].Get<uint32>();
4846 levelInfo.basemana = fields[8].Get<uint32>();
4847
4848 ++count;
4849 } while (result->NextRow());
4850
4851 // Fill gaps and check integrity
4852 for (int race = RACE_HUMAN; race < sRaceMgr->GetMaxRaces(); ++race)
4853 {
4854 // skip non existed races
4855 if (!sChrRacesStore.LookupEntry(race))
4856 continue;
4857
4858 for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
4859 {
4860 // skip non existed classes
4861 if (!sChrClassesStore.LookupEntry(class_))
4862 continue;
4863
4864 PlayerClassInfo* pClassInfo = _playerClassInfo[class_];
4865 PlayerInfo* info = _playerInfo[race][class_];
4866 if (!info)
4867 continue;
4868
4869 // skip expansion races if not playing with expansion
4870 if (sWorld->getIntConfig(CONFIG_EXPANSION) < EXPANSION_THE_BURNING_CRUSADE && (race == RACE_BLOODELF || race == RACE_DRAENEI))
4871 continue;
4872
4873 // skip expansion classes if not playing with expansion
4875 continue;
4876
4877 // fatal error if no initial stats data
4878 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))
4879 {
4880 LOG_ERROR("sql.sql", "Race {} class {} initial level does not have stats data!", race, class_);
4881 exit(1);
4882 }
4883
4884 // fatal error if no initial health/mana data
4885 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))
4886 {
4887 LOG_ERROR("sql.sql", "Class {} initial level does not have health/mana data!", class_);
4888 exit(1);
4889 }
4890
4891 // fill level gaps for stats
4892 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4893 {
4894 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))
4895 {
4896 LOG_ERROR("sql.sql", "Race {} class {} level {} does not have stats data. Using stats data of level {}.", race, class_, level + 1, level);
4897 info->levelInfo[level] = info->levelInfo[level - 1];
4898 }
4899 }
4900
4901 // fill level gaps for health/mana
4902 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4903 {
4904 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))
4905 {
4906 LOG_ERROR("sql.sql", "Class {} level {} does not have health/mana data. Using stats data of level {}.", class_, level + 1, level);
4907 pClassInfo->levelInfo[level] = pClassInfo->levelInfo[level - 1];
4908 }
4909 }
4910 }
4911 }
4912
4913 LOG_INFO("server.loading", ">> Loaded {} Level Stats Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4914 LOG_INFO("server.loading", " ");
4915 }
4916
4917 // Loading xp per level data
4918 LOG_INFO("server.loading", "Loading Player Create XP Data...");
4919 {
4920 uint32 oldMSTime = getMSTime();
4921
4922 _playerXPperLevel.resize(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
4923 for (uint8 level = 0; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4924 _playerXPperLevel[level] = 0;
4925
4926 // 0 1
4927 QueryResult result = WorldDatabase.Query("SELECT Level, Experience FROM player_xp_for_level");
4928
4929 if (!result)
4930 {
4931 LOG_WARN("server.loading", ">> Loaded 0 xp for level definitions. DB table `player_xp_for_level` is empty.");
4932 LOG_INFO("server.loading", " ");
4933 exit(1);
4934 }
4935
4936 uint32 count = 0;
4937
4938 do
4939 {
4940 Field* fields = result->Fetch();
4941
4942 uint32 current_level = fields[0].Get<uint8>();
4943 uint32 current_xp = fields[1].Get<uint32>();
4944
4945 if (current_level >= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4946 {
4947 if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
4948 LOG_ERROR("sql.sql", "Wrong (> {}) level {} in `player_xp_for_level` table, ignoring.", STRONG_MAX_LEVEL, current_level);
4949 else
4950 {
4951 LOG_DEBUG("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_xp_for_levels` table, ignoring.", current_level);
4952 ++count; // make result loading percent "expected" correct in case disabled detail mode for example.
4953 }
4954 continue;
4955 }
4956 //PlayerXPperLevel
4957 _playerXPperLevel[current_level] = current_xp;
4958 ++count;
4959 } while (result->NextRow());
4960
4961 // fill level gaps
4962 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4963 {
4964 if (_playerXPperLevel[level] == 0)
4965 {
4966 LOG_ERROR("sql.sql", "Level {} does not have XP for level data. Using data of level [{}] + 100.", level + 1, level);
4967 _playerXPperLevel[level] = _playerXPperLevel[level - 1] + 100;
4968 }
4969 }
4970
4971 LOG_INFO("server.loading", ">> Loaded {} XP For Level Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4972 LOG_INFO("server.loading", " ");
4973 }
4974}
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:131
@ 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:196
@ CONFIG_START_PLAYER_LEVEL
Definition WorldConfig.h:195
@ CONFIG_EXPANSION
Definition WorldConfig.h:232
void PlayerCreateInfoAddItemHelper(uint32 race_, uint32 class_, uint32 itemId, int32 count)
Definition ObjectMgr.cpp:4311
Definition DBCStructure.h:679
uint32 model_f
Definition DBCStructure.h:685
uint32 model_m
Definition DBCStructure.h:684
Definition Player.h:276
uint32 basehealth
Definition Player.h:278
uint32 basemana
Definition Player.h:279
Definition Player.h:302
Definition Player.h:314
uint16 SkillId
Definition Player.h:315
float orientation
Definition Player.h:331
uint16 displayId_m
Definition Player.h:332
float positionX
Definition Player.h:328
uint32 areaId
Definition Player.h:327
float positionY
Definition Player.h:329
float positionZ
Definition Player.h:330
uint32 mapId
Definition Player.h:326
uint16 displayId_f
Definition Player.h:333
Definition Player.h:290
std::array< uint32, MAX_STATS > stats
Definition Player.h:296

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_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, sChrClassesStore, sChrRacesStore, PlayerCreateInfoSkill::SkillId, sMapStore, sRaceMgr, sSkillLineStore, PlayerLevelInfo::stats, STRONG_MAX_LEVEL, sWorld, and WorldDatabase.

◆ LoadPlayerShapeshiftModels()

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

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

◆ LoadPlayerTotemModels()

void ObjectMgr::LoadPlayerTotemModels ( )
1786{
1787 uint32 oldMSTime = getMSTime();
1788
1789 QueryResult result = WorldDatabase.Query("SELECT TotemID, RaceID, ModelID from player_totem_model");
1790
1791 if (!result)
1792 {
1793 LOG_INFO("server.loading", ">> Loaded 0 player totem model records. DB table `player_totem_model` is empty.");
1794 return;
1795 }
1796
1797 uint32 count = 0;
1798 do
1799 {
1800 Field* fields = result->Fetch();
1801
1802 SummonSlot totemSlot = SummonSlot(fields[0].Get<uint8>());
1803 uint8 race = fields[1].Get<uint8>();
1804 uint32 displayId = fields[2].Get<uint32>();
1805
1806 if (totemSlot < SUMMON_SLOT_TOTEM_FIRE || totemSlot >= MAX_TOTEM_SLOT)
1807 {
1808 LOG_ERROR("sql.sql", "Wrong TotemSlot {} in `player_totem_model` table, skipped.", totemSlot);
1809 continue;
1810 }
1811
1812 ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race);
1813 if (!raceEntry)
1814 {
1815 LOG_ERROR("sql.sql", "Race {} defined in `player_totem_model` does not exists, skipped.", uint32(race));
1816 continue;
1817 }
1818
1819 CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(displayId);
1820 if (!displayEntry)
1821 {
1822 LOG_ERROR("sql.sql", "TotemSlot: {} defined in `player_totem_model` has non-existing model ({}), skipped.", totemSlot, displayId);
1823 continue;
1824 }
1825
1826 _playerTotemModel[std::make_pair(totemSlot, Races(race))] = displayId;
1827 ++count;
1828 } while (result->NextRow());
1829
1830 LOG_INFO("server.loading", ">> Loaded {} player totem model records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1831 LOG_INFO("server.loading", " ");
1832}
#define MAX_TOTEM_SLOT
Definition SharedDefines.h:3555
SummonSlot
Definition SharedDefines.h:3543
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 ( )
495{
496 uint32 oldMSTime = getMSTime();
497
498 _pointOfInterestLocaleStore.clear(); // need for reload case
499
500 // 0 1 2
501 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Name FROM points_of_interest_locale");
502
503 if (!result)
504 return;
505
506 do
507 {
508 Field* fields = result->Fetch();
509
510 uint32 ID = fields[0].Get<uint32>();
511
512 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
513 if (locale == LOCALE_enUS)
514 continue;
515
517 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
518 } while (result->NextRow());
519
520 LOG_INFO("server.loading", ">> Loaded {} Points Of Interest Locale Strings in {} ms", (uint32)_pointOfInterestLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
521}
Definition CreatureData.h:355
std::vector< std::string > Name
Definition CreatureData.h:356

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

◆ LoadPointsOfInterest()

void ObjectMgr::LoadPointsOfInterest ( )
8558{
8559 uint32 oldMSTime = getMSTime();
8560
8561 _pointsOfInterestStore.clear(); // need for reload case
8562
8563 uint32 count = 0;
8564
8565 // 0 1 2 3 4 5 6
8566 QueryResult result = WorldDatabase.Query("SELECT ID, PositionX, PositionY, Icon, Flags, Importance, Name FROM points_of_interest");
8567
8568 if (!result)
8569 {
8570 LOG_WARN("server.loading", ">> Loaded 0 Points of Interest definitions. DB table `points_of_interest` is empty.");
8571 LOG_INFO("server.loading", " ");
8572 return;
8573 }
8574
8575 do
8576 {
8577 Field* fields = result->Fetch();
8578
8579 uint32 point_id = fields[0].Get<uint32>();
8580
8581 PointOfInterest POI;
8582 POI.ID = point_id;
8583 POI.PositionX = fields[1].Get<float>();
8584 POI.PositionY = fields[2].Get<float>();
8585 POI.Icon = fields[3].Get<uint32>();
8586 POI.Flags = fields[4].Get<uint32>();
8587 POI.Importance = fields[5].Get<uint32>();
8588 POI.Name = fields[6].Get<std::string>();
8589
8590 if (!Acore::IsValidMapCoord(POI.PositionX, POI.PositionY))
8591 {
8592 LOG_ERROR("sql.sql", "Table `points_of_interest` (ID: {}) have invalid coordinates (X: {} Y: {}), ignored.", point_id, POI.PositionX, POI.PositionY);
8593 continue;
8594 }
8595
8596 _pointsOfInterestStore[point_id] = POI;
8597
8598 ++count;
8599 } while (result->NextRow());
8600
8601 LOG_INFO("server.loading", ">> Loaded {} Points of Interest Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8602 LOG_INFO("server.loading", " ");
8603}
bool IsValidMapCoord(float c)
Definition GridDefines.h:210
Definition ObjectMgr.h:594
uint32 ID
Definition ObjectMgr.h:595

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

◆ LoadProfanityNamesFromDB()

void ObjectMgr::LoadProfanityNamesFromDB ( )
9160{
9161 uint32 oldMSTime = getMSTime();
9162
9163 _profanityNamesStore.clear(); // need for reload case
9164
9165 QueryResult result = CharacterDatabase.Query("SELECT name FROM profanity_name");
9166
9167 if (!result)
9168 {
9169 LOG_WARN("server.loading", ">> Loaded 0 profanity names. DB table `profanity_name` is empty!");
9170 return;
9171 }
9172
9173 uint32 count = 0;
9174
9175 Field* fields;
9176 do
9177 {
9178 fields = result->Fetch();
9179 std::string name = fields[0].Get<std::string>();
9180
9181 std::wstring wstr;
9182 if (!Utf8toWStr (name, wstr))
9183 {
9184 LOG_ERROR("sql.sql", "Table `profanity_name` have invalid name: {}", name);
9185 continue;
9186 }
9187
9188 wstrToLower(wstr);
9189
9190 _profanityNamesStore.insert(wstr);
9191 ++count;
9192 } while (result->NextRow());
9193
9194 LOG_INFO("server.loading", ">> Loaded {} profanity names from DB in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9195}

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

◆ LoadProfanityNamesFromDBC()

void ObjectMgr::LoadProfanityNamesFromDBC ( )
9198{
9199 if (!sWorld->getBoolConfig(CONFIG_STRICT_NAMES_PROFANITY))
9200 {
9201 LOG_WARN("server.loading", ">> Loaded 0 profanity names from DBC. Config option disabled.");
9202 return;
9203 }
9204
9205 uint32 oldMSTime = getMSTime();
9206
9207 uint32 count = 0;
9208
9209 for (NamesProfanityEntry const* profanityStore : sNamesProfanityStore)
9210 {
9211 std::wstring wstr;
9212
9213 Utf8toWStr(profanityStore->Pattern, wstr);
9214
9215 // DBC does not have clean entries, remove the junk.
9216 boost::algorithm::replace_all(wstr, "\\<", "");
9217 boost::algorithm::replace_all(wstr, "\\>", "");
9218
9219 _profanityNamesStore.insert(wstr);
9220 count++;
9221 }
9222
9223 LOG_INFO("server.loading", ">> Loaded {} profanity names from DBC in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9224 LOG_INFO("server.loading", " ");
9225}
DBCStorage< NamesProfanityEntry > sNamesProfanityStore(NamesProfanityfmt)
@ CONFIG_STRICT_NAMES_PROFANITY
Definition WorldConfig.h:141
Definition DBCStructure.h:1405

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

◆ LoadQuestAreaTriggers()

void ObjectMgr::LoadQuestAreaTriggers ( )
6931{
6932 uint32 oldMSTime = getMSTime();
6933
6934 _questAreaTriggerStore.clear(); // need for reload case
6935
6936 QueryResult result = WorldDatabase.Query("SELECT id, quest FROM areatrigger_involvedrelation");
6937
6938 if (!result)
6939 {
6940 LOG_WARN("server.loading", ">> Loaded 0 quest trigger points. DB table `areatrigger_involvedrelation` is empty.");
6941 LOG_INFO("server.loading", " ");
6942 return;
6943 }
6944
6945 uint32 count = 0;
6946
6947 do
6948 {
6949 ++count;
6950
6951 Field* fields = result->Fetch();
6952
6953 uint32 trigger_ID = fields[0].Get<uint32>();
6954 uint32 quest_ID = fields[1].Get<uint32>();
6955
6956 AreaTrigger const* atEntry = GetAreaTrigger(trigger_ID);
6957 if (!atEntry)
6958 {
6959 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", trigger_ID);
6960 continue;
6961 }
6962
6963 Quest const* quest = GetQuestTemplate(quest_ID);
6964
6965 if (!quest)
6966 {
6967 LOG_ERROR("sql.sql", "Table `areatrigger_involvedrelation` has record (id: {}) for not existing quest {}", trigger_ID, quest_ID);
6968 continue;
6969 }
6970
6972 {
6973 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);
6974
6975 // this will prevent quest completing without objective
6976 const_cast<Quest*>(quest)->SetSpecialFlag(QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT);
6977
6978 // continue; - quest modified to required objective and trigger can be allowed.
6979 }
6980
6981 _questAreaTriggerStore[trigger_ID] = quest_ID;
6982 } while (result->NextRow());
6983
6984 LOG_INFO("server.loading", ">> Loaded {} Quest Trigger Points in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6985 LOG_INFO("server.loading", " ");
6986}
@ 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 ( )
7007{
7008 uint32 oldMSTime = getMSTime();
7009
7010 _questGreetingStore.clear(); // For reload case
7011
7012 // 0 1 2 3 4
7013 QueryResult result = WorldDatabase.Query("SELECT ID, Type, GreetEmoteType, GreetEmoteDelay, Greeting FROM quest_greeting");
7014 if (!result)
7015 {
7016 LOG_WARN("server.loading", ">> Loaded 0 quest greetings. DB table `quest_greeting` is empty.");
7017 return;
7018 }
7019
7020 do
7021 {
7022 Field* fields = result->Fetch();
7023
7024 uint32 id = fields[0].Get<uint32>();
7025 uint8 type = fields[1].Get<uint8>();
7026 switch (type)
7027 {
7028 case 0: // Creature
7029 if (!GetCreatureTemplate(id))
7030 {
7031 LOG_ERROR("sql.sql", "Table `quest_greeting`: creature template entry {} does not exist.", id);
7032 continue;
7033 }
7034 break;
7035 case 1: // GameObject
7036 if (!GetGameObjectTemplate(id))
7037 {
7038 LOG_ERROR("sql.sql", "Table `quest_greeting`: gameobject template entry {} does not exist.", id);
7039 continue;
7040 }
7041 break;
7042 default:
7043 LOG_ERROR("sql.sql", "Table `quest_greeting` has unknown type {} for id {}, skipped.", type, id);
7044 continue;
7045 }
7046
7047 std::pair<uint32, uint8> pairKey = std::make_pair(id, type);
7048 QuestGreeting& data = _questGreetingStore[pairKey];
7049
7050 data.EmoteType = fields[2].Get<uint16>();
7051 data.EmoteDelay = fields[3].Get<uint32>();
7052 AddLocaleString(fields[4].Get<std::string>(), LOCALE_enUS, data.Greeting);
7053 }
7054 while (result->NextRow());
7055
7056 LOG_INFO("server.loading", ">> Loaded {} quest_greeting in {} ms", _questGreetingStore.size(), GetMSTimeDiffToNow(oldMSTime));
7057 LOG_INFO("server.loading", " ");
7058}
Definition ObjectMgr.h:605
uint32 EmoteDelay
Definition ObjectMgr.h:607
std::vector< std::string > Greeting
Definition ObjectMgr.h:608
uint16 EmoteType
Definition ObjectMgr.h:606

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 ( )
7061{
7062 uint32 oldMSTime = getMSTime();
7063
7064 // 0 1 2 3
7065 QueryResult result = WorldDatabase.Query("SELECT ID, Type, Locale, Greeting FROM quest_greeting_locale");
7066 if (!result)
7067 {
7068 LOG_WARN("server.loading", ">> Loaded 0 quest_greeting locales. DB table `quest_greeting_locale` is empty.");
7069 return;
7070 }
7071
7072 uint32 localeCount = 0;
7073 do
7074 {
7075 Field* fields = result->Fetch();
7076
7077 uint32 id = fields[0].Get<uint32>();
7078 uint8 type = fields[1].Get<uint8>();
7079 switch (type)
7080 {
7081 case 0: // Creature
7082 if (!GetCreatureTemplate(id))
7083 {
7084 LOG_ERROR("sql.sql", "Table `quest_greeting_locale`: creature template entry {} does not exist.", id);
7085 continue;
7086 }
7087 break;
7088 case 1: // GameObject
7089 if (!GetGameObjectTemplate(id))
7090 {
7091 LOG_ERROR("sql.sql", "Table `quest_greeting_locale`: gameobject template entry {} does not exist.", id);
7092 continue;
7093 }
7094 break;
7095 default:
7096 continue;
7097 }
7098
7099 std::pair<uint32, uint8> pairKey = std::make_pair(id, type);
7100 QuestGreeting& data = _questGreetingStore[pairKey];
7101
7102 QuestGreetingContainer::iterator qgc = _questGreetingStore.find(pairKey);
7103 if (qgc == _questGreetingStore.end())
7104 {
7105 LOG_ERROR("sql.sql", "QuestGreeting (Id: {} Type: {}) found in table `quest_greeting_locale` but does not exist in `quest_greeting`. Skipped!", id, type);
7106 continue;
7107 }
7108
7109 LocaleConstant locale = GetLocaleByName(fields[2].Get<std::string>());
7110 if (locale == LOCALE_enUS)
7111 continue;
7112
7113 AddLocaleString(fields[3].Get<std::string>(), locale, data.Greeting);
7114 localeCount++;
7115 } while (result->NextRow());
7116
7117 LOG_INFO("server.loading", ">> Loaded {} quest greeting Locale Strings in {} ms", localeCount, GetMSTimeDiffToNow(oldMSTime));
7118 LOG_INFO("server.loading", " ");
7119}

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 ( )
5891{
5892 uint32 oldMSTime = getMSTime();
5893
5894 _questLocaleStore.clear(); // need for reload case
5895
5896 // 0 1 2 3 4 5 6 7 8 9 10
5897 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Title, Details, Objectives, EndText, CompletedText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4 FROM quest_template_locale");
5898
5899 if (!result)
5900 return;
5901
5902 do
5903 {
5904 Field* fields = result->Fetch();
5905
5906 uint32 ID = fields[0].Get<uint32>();
5907
5908 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
5909 if (locale == LOCALE_enUS)
5910 continue;
5911
5912 QuestLocale& data = _questLocaleStore[ID];
5913 AddLocaleString(fields[2].Get<std::string>(), locale, data.Title);
5914 AddLocaleString(fields[3].Get<std::string>(), locale, data.Details);
5915 AddLocaleString(fields[4].Get<std::string>(), locale, data.Objectives);
5916 AddLocaleString(fields[5].Get<std::string>(), locale, data.AreaDescription);
5917 AddLocaleString(fields[6].Get<std::string>(), locale, data.CompletedText);
5918
5919 for (uint8 i = 0; i < 4; ++i)
5920 AddLocaleString(fields[i + 7].Get<std::string>(), locale, data.ObjectiveText[i]);
5921 } while (result->NextRow());
5922
5923 LOG_INFO("server.loading", ">> Loaded {} Quest Locale Strings in {} ms", (uint32)_questLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
5924}
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 ( )
11263{
11264 uint32 oldMSTime = getMSTime();
11265
11266 _questMoneyRewards.clear();
11267
11268 // 0 1 2 3 4 5 6 7 8 9 10
11269 QueryResult result = WorldDatabase.Query("SELECT `Level`, Money0, Money1, Money2, Money3, Money4, Money5, Money6, Money7, Money8, Money9 FROM `quest_money_reward` ORDER BY `Level`");
11270 if (!result)
11271 {
11272 LOG_WARN("server.loading", ">> Loaded 0 quest money rewards. DB table `quest_money_reward` is empty.");
11273 return;
11274 }
11275
11276 uint32 count = 0;
11277 do
11278 {
11279 Field* fields = result->Fetch();
11280 uint32 Level = fields[0].Get<uint32>();
11281
11282 QuestMoneyRewardArray& questMoneyReward = _questMoneyRewards[Level];
11283 questMoneyReward.fill(0);
11284
11285 for (uint8 i = 0; i < MAX_QUEST_MONEY_REWARDS; ++i)
11286 {
11287 questMoneyReward[i] = fields[1 + i].Get<uint32>();
11288 ++count;
11289 }
11290 } while (result->NextRow());
11291
11292 LOG_INFO("server.loading", ">> Loaded {} Quest Money Rewards in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
11293 LOG_INFO("server.loading", " ");
11294}
std::array< uint32, MAX_QUEST_MONEY_REWARDS > QuestMoneyRewardArray
Definition ObjectMgr.h:724

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

◆ LoadQuestOfferRewardLocale()

void ObjectMgr::LoadQuestOfferRewardLocale ( )
7122{
7123 uint32 oldMSTime = getMSTime();
7124
7125 _questOfferRewardLocaleStore.clear(); // need for reload case
7126
7127 // 0 1 2
7128 QueryResult result = WorldDatabase.Query("SELECT Id, locale, RewardText FROM quest_offer_reward_locale");
7129 if (!result)
7130 return;
7131
7132 do
7133 {
7134 Field* fields = result->Fetch();
7135
7136 uint32 id = fields[0].Get<uint32>();
7137 std::string localeName = fields[1].Get<std::string>();
7138
7139 LocaleConstant locale = GetLocaleByName(localeName);
7140 if (locale == LOCALE_enUS)
7141 continue;
7142
7144 AddLocaleString(fields[2].Get<std::string>(), locale, data.RewardText);
7145 } while (result->NextRow());
7146
7147 LOG_INFO("server.loading", ">> Loaded {} Quest Offer Reward Locale Strings in {} ms", _questOfferRewardLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
7148}
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 ( )
8606{
8607 if (!sWorld->getBoolConfig(CONFIG_QUEST_POI_ENABLED))
8608 {
8609 LOG_INFO("server.loading", ">> Loaded 0 quest POI definitions. Disabled by config.");
8610 LOG_INFO("server.loading", " ");
8611 return;
8612 }
8613
8614 uint32 oldMSTime = getMSTime();
8615
8616 _questPOIStore.clear(); // need for reload case
8617
8618 uint32 count = 0;
8619
8620 // 0 1 2 3 4 5 6 7
8621 QueryResult result = WorldDatabase.Query("SELECT QuestID, id, ObjectiveIndex, MapID, WorldMapAreaId, Floor, Priority, Flags FROM quest_poi order by QuestID");
8622
8623 if (!result)
8624 {
8625 LOG_WARN("server.loading", ">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty.");
8626 LOG_INFO("server.loading", " ");
8627 return;
8628 }
8629
8630 // 0 1 2 3
8631 QueryResult points = WorldDatabase.Query("SELECT QuestID, Idx1, X, Y FROM quest_poi_points ORDER BY QuestID DESC, Idx2");
8632
8633 std::vector<std::vector<std::vector<QuestPOIPoint> > > POIs;
8634
8635 if (points)
8636 {
8637 // The first result should have the highest questId
8638 Field* fields = points->Fetch();
8639 uint32 questIdMax = fields[0].Get<uint32>();
8640 POIs.resize(questIdMax + 1);
8641
8642 do
8643 {
8644 fields = points->Fetch();
8645
8646 uint32 questId = fields[0].Get<uint32>();
8647 uint32 id = fields[1].Get<uint32>();
8648 int32 x = fields[2].Get<int32>();
8649 int32 y = fields[3].Get<int32>();
8650
8651 if (POIs[questId].size() <= id + 1)
8652 POIs[questId].resize(id + 10);
8653
8654 QuestPOIPoint point(x, y);
8655 POIs[questId][id].push_back(point);
8656 } while (points->NextRow());
8657 }
8658
8659 do
8660 {
8661 Field* fields = result->Fetch();
8662
8663 uint32 questId = fields[0].Get<uint32>();
8664 uint32 id = fields[1].Get<uint32>();
8665 int32 objIndex = fields[2].Get<int32>();
8666 uint32 mapId = fields[3].Get<uint32>();
8667 uint32 WorldMapAreaId = fields[4].Get<uint32>();
8668 uint32 FloorId = fields[5].Get<uint32>();
8669 uint32 unk3 = fields[6].Get<uint32>();
8670 uint32 unk4 = fields[7].Get<uint32>();
8671
8672 QuestPOI POI(id, objIndex, mapId, WorldMapAreaId, FloorId, unk3, unk4);
8673 if (questId < POIs.size() && id < POIs[questId].size())
8674 {
8675 POI.points = POIs[questId][id];
8676 _questPOIStore[questId].push_back(POI);
8677 }
8678 else
8679 LOG_ERROR("sql.sql", "Table quest_poi references unknown quest points for quest {} POI id {}", questId, id);
8680
8681 ++count;
8682 } while (result->NextRow());
8683
8684 LOG_INFO("server.loading", ">> Loaded {} Quest POI definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8685 LOG_INFO("server.loading", " ");
8686}
@ CONFIG_QUEST_POI_ENABLED
Definition WorldConfig.h:134
Definition ObjectMgr.h:644
Definition ObjectMgr.h:653

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
8956{
8957 uint32 oldMSTime = getMSTime();
8958
8959 map.clear(); // need for reload case
8960
8961 uint32 count = 0;
8962
8963 QueryResult result = WorldDatabase.Query("SELECT id, quest, pool_entry FROM {} qr LEFT JOIN pool_quest pq ON qr.quest = pq.entry", table);
8964
8965 if (!result)
8966 {
8967 LOG_WARN("server.loading", ">> Loaded 0 quest relations from `{}`, table is empty.", table);
8968 LOG_INFO("server.loading", " ");
8969 return;
8970 }
8971
8972 PooledQuestRelation* poolRelationMap = go ? &sPoolMgr->mQuestGORelation : &sPoolMgr->mQuestCreatureRelation;
8973 if (starter)
8974 poolRelationMap->clear();
8975
8976 do
8977 {
8978 uint32 id = result->Fetch()[0].Get<uint32>();
8979 uint32 quest = result->Fetch()[1].Get<uint32>();
8980 uint32 poolId = result->Fetch()[2].Get<uint32>();
8981
8982 if (_questTemplates.find(quest) == _questTemplates.end())
8983 {
8984 LOG_ERROR("sql.sql", "Table `{}`: Quest {} listed for entry {} does not exist.", table, quest, id);
8985 continue;
8986 }
8987
8988 if (!poolId || !starter)
8989 map.insert(QuestRelations::value_type(id, quest));
8990 else if (starter)
8991 poolRelationMap->insert(PooledQuestRelation::value_type(quest, id));
8992
8993 ++count;
8994 } while (result->NextRow());
8995
8996 LOG_INFO("server.loading", ">> Loaded {} Quest Relations From {} in {} ms", count, table, GetMSTimeDiffToNow(oldMSTime));
8997 LOG_INFO("server.loading", " ");
8998}
#define sPoolMgr
Definition PoolMgr.h:177
std::multimap< uint32, uint32 > PooledQuestRelation
Definition PoolMgr.h:101

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

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

◆ LoadQuestRequestItemsLocale()

void ObjectMgr::LoadQuestRequestItemsLocale ( )
7151{
7152 uint32 oldMSTime = getMSTime();
7153
7154 _questRequestItemsLocaleStore.clear(); // need for reload case
7155
7156 // 0 1 2
7157 QueryResult result = WorldDatabase.Query("SELECT Id, locale, CompletionText FROM quest_request_items_locale");
7158 if (!result)
7159 return;
7160
7161 do
7162 {
7163 Field* fields = result->Fetch();
7164
7165 uint32 id = fields[0].Get<uint32>();
7166 std::string localeName = fields[1].Get<std::string>();
7167
7168 LocaleConstant locale = GetLocaleByName(localeName);
7169 if (locale == LOCALE_enUS)
7170 continue;
7171
7173 AddLocaleString(fields[2].Get<std::string>(), locale, data.CompletionText);
7174 } while (result->NextRow());
7175
7176 LOG_INFO("server.loading", ">> Loaded {} Quest Request Items Locale Strings in {} ms", _questRequestItemsLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
7177}
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 ( )
5081{
5082 uint32 oldMSTime = getMSTime();
5083
5084 // For reload case
5085 for (QuestMap::const_iterator itr = _questTemplates.begin(); itr != _questTemplates.end(); ++itr)
5086 delete itr->second;
5087 _questTemplates.clear();
5088
5089 mExclusiveQuestGroups.clear();
5090
5091 QueryResult result = WorldDatabase.Query("SELECT "
5092 //0 1 2 3 4 5 6 7 8
5093 "ID, QuestType, QuestLevel, MinLevel, QuestSortID, QuestInfoID, SuggestedGroupNum, TimeAllowed, AllowableRaces,"
5094 // 9 10 11 12
5095 "RequiredFactionId1, RequiredFactionId2, RequiredFactionValue1, RequiredFactionValue2, "
5096 // 13 14 15 16 17 18 19 20
5097 "RewardNextQuest, RewardXPDifficulty, RewardMoney, RewardMoneyDifficulty, RewardDisplaySpell, RewardSpell, RewardHonor, RewardKillHonor, "
5098 // 21 22 23 24 25 26
5099 "StartItem, Flags, RewardTitle, RequiredPlayerKills, RewardTalents, RewardArenaPoints, "
5100 // 27 28 29 30 31 32 33 34
5101 "RewardItem1, RewardAmount1, RewardItem2, RewardAmount2, RewardItem3, RewardAmount3, RewardItem4, RewardAmount4, "
5102 // 35 36 37 38 39 40 41 42 43 44 45 46
5103 "RewardChoiceItemID1, RewardChoiceItemQuantity1, RewardChoiceItemID2, RewardChoiceItemQuantity2, RewardChoiceItemID3, RewardChoiceItemQuantity3, RewardChoiceItemID4, RewardChoiceItemQuantity4, RewardChoiceItemID5, RewardChoiceItemQuantity5, RewardChoiceItemID6, RewardChoiceItemQuantity6, "
5104 // 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
5105 "RewardFactionID1, RewardFactionValue1, RewardFactionOverride1, RewardFactionID2, RewardFactionValue2, RewardFactionOverride2, RewardFactionID3, RewardFactionValue3, RewardFactionOverride3, RewardFactionID4, RewardFactionValue4, RewardFactionOverride4, RewardFactionID5, RewardFactionValue5, RewardFactionOverride5,"
5106 // 61 63 64 65
5107 "POIContinent, POIx, POIy, POIPriority, "
5108 // 66 67 68 69 70
5109 "LogTitle, LogDescription, QuestDescription, AreaDescription, QuestCompletionLog, "
5110 // 71 72 73 74 75 76 77 78
5111 "RequiredNpcOrGo1, RequiredNpcOrGo2, RequiredNpcOrGo3, RequiredNpcOrGo4, RequiredNpcOrGoCount1, RequiredNpcOrGoCount2, RequiredNpcOrGoCount3, RequiredNpcOrGoCount4, "
5112 // 79 80 81 82 83 84 85 86
5113 "ItemDrop1, ItemDrop2, ItemDrop3, ItemDrop4, ItemDropQuantity1, ItemDropQuantity2, ItemDropQuantity3, ItemDropQuantity4, "
5114 // 87 88 89 90 91 92 93 94 95 96 97 98
5115 "RequiredItemId1, RequiredItemId2, RequiredItemId3, RequiredItemId4, RequiredItemId5, RequiredItemId6, RequiredItemCount1, RequiredItemCount2, RequiredItemCount3, RequiredItemCount4, RequiredItemCount5, RequiredItemCount6, "
5116 // 99 100 101 102 103
5117 "Unknown0, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4"
5118 " FROM quest_template");
5119 if (!result)
5120 {
5121 LOG_WARN("server.loading", ">> Loaded 0 quests definitions. DB table `quest_template` is empty.");
5122 LOG_INFO("server.loading", " ");
5123 return;
5124 }
5125
5126 // create multimap previous quest for each existed quest
5127 // some quests can have many previous maps set by NextQuestId in previous quest
5128 // for example set of race quests can lead to single not race specific quest
5129 do
5130 {
5131 Field* fields = result->Fetch();
5132
5133 Quest* newQuest = new Quest(fields);
5134 _questTemplates[newQuest->GetQuestId()] = newQuest;
5135 } while (result->NextRow());
5136
5137 // pussywizard:
5138 {
5139 uint32 max = 0;
5140 for (QuestMap::const_iterator itr = _questTemplates.begin(); itr != _questTemplates.end(); ++itr)
5141 if (itr->first > max)
5142 max = itr->first;
5143 if (max)
5144 {
5145 _questTemplatesFast.clear();
5146 _questTemplatesFast.resize(max + 1, nullptr);
5147 for (QuestMap::iterator itr = _questTemplates.begin(); itr != _questTemplates.end(); ++itr)
5148 _questTemplatesFast[itr->first] = itr->second;
5149 }
5150 }
5151
5152 for (QuestMap::iterator itr = _questTemplates.begin(); itr != _questTemplates.end(); ++itr)
5153 itr->second->InitializeQueryData();
5154
5155 std::map<uint32, uint32> usedMailTemplates;
5156
5157 // Load `quest_details`
5158 // 0 1 2 3 4 5 6 7 8
5159 result = WorldDatabase.Query("SELECT ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4 FROM quest_details");
5160
5161 if (!result)
5162 {
5163 LOG_WARN("server.loading", ">> Loaded 0 quest details. DB table `quest_details` is empty.");
5164 }
5165 else
5166 {
5167 do
5168 {
5169 Field* fields = result->Fetch();
5170 uint32 questId = fields[0].Get<uint32>();
5171
5172 auto itr = _questTemplates.find(questId);
5173 if (itr != _questTemplates.end())
5174 itr->second->LoadQuestDetails(fields);
5175 else
5176 LOG_ERROR("sql.sql", "Table `quest_details` has data for quest {} but such quest does not exist", questId);
5177 } while (result->NextRow());
5178 }
5179
5180 // Load `quest_request_items`
5181 // 0 1 2 3
5182 result = WorldDatabase.Query("SELECT ID, EmoteOnComplete, EmoteOnIncomplete, CompletionText FROM quest_request_items");
5183
5184 if (!result)
5185 {
5186 LOG_WARN("server.loading", ">> Loaded 0 quest request items. DB table `quest_request_items` is empty.");
5187 }
5188 else
5189 {
5190 do
5191 {
5192 Field* fields = result->Fetch();
5193 uint32 questId = fields[0].Get<uint32>();
5194
5195 auto itr = _questTemplates.find(questId);
5196 if (itr != _questTemplates.end())
5197 itr->second->LoadQuestRequestItems(fields);
5198 else
5199 LOG_ERROR("sql.sql", "Table `quest_request_items` has data for quest {} but such quest does not exist", questId);
5200 } while (result->NextRow());
5201 }
5202
5203 // Load `quest_offer_reward`
5204 // 0 1 2 3 4 5 6 7 8 9
5205 result = WorldDatabase.Query("SELECT ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4, RewardText FROM quest_offer_reward");
5206
5207 if (!result)
5208 {
5209 LOG_WARN("server.loading", ">> Loaded 0 quest reward emotes. DB table `quest_offer_reward` is empty.");
5210 }
5211 else
5212 {
5213 do
5214 {
5215 Field* fields = result->Fetch();
5216 uint32 questId = fields[0].Get<uint32>();
5217
5218 auto itr = _questTemplates.find(questId);
5219 if (itr != _questTemplates.end())
5220 itr->second->LoadQuestOfferReward(fields);
5221 else
5222 LOG_ERROR("sql.sql", "Table `quest_offer_reward` has data for quest {} but such quest does not exist", questId);
5223 } while (result->NextRow());
5224 }
5225
5226 // Load `quest_template_addon`
5227 // 0 1 2 3 4 5 6 7 8
5228 result = WorldDatabase.Query("SELECT ID, MaxLevel, AllowableClasses, SourceSpellID, PrevQuestID, NextQuestID, ExclusiveGroup, BreadcrumbForQuestId, RewardMailTemplateID, "
5229 //9 10 11 12 13 14 15 16 17 18
5230 "RewardMailDelay, RequiredSkillID, RequiredSkillPoints, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, ProvidedItemCount, RewardMailSenderEntry, SpecialFlags FROM quest_template_addon LEFT JOIN quest_mail_sender ON Id=QuestId");
5231
5232 if (!result)
5233 {
5234 LOG_WARN("server.loading", ">> Loaded 0 quest template addons. DB table `quest_template_addon` is empty.");
5235 }
5236 else
5237 {
5238 do
5239 {
5240 Field* fields = result->Fetch();
5241 uint32 questId = fields[0].Get<uint32>();
5242
5243 auto itr = _questTemplates.find(questId);
5244 if (itr != _questTemplates.end())
5245 itr->second->LoadQuestTemplateAddon(fields);
5246 else
5247 LOG_ERROR("sql.sql", "Table `quest_template_addon` has data for quest {} but such quest does not exist", questId);
5248 } while (result->NextRow());
5249 }
5250
5251 // Post processing
5252 for (QuestMap::iterator iter = _questTemplates.begin(); iter != _questTemplates.end(); ++iter)
5253 {
5254 // skip post-loading checks for disabled quests
5255 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_QUEST, iter->first, nullptr))
5256 continue;
5257
5258 Quest* qinfo = iter->second;
5259
5260 // additional quest integrity checks (GO, creature_template and item_template must be loaded already)
5261
5262 if (qinfo->GetQuestMethod() >= 3)
5263 LOG_ERROR("sql.sql", "Quest {} has `Method` = {}, expected values are 0, 1 or 2.", qinfo->GetQuestId(), qinfo->GetQuestMethod());
5264
5266 {
5267 LOG_ERROR("sql.sql", "Quest {} has `SpecialFlags` = {} > max allowed value. Correct `SpecialFlags` to value <= {}",
5270 }
5271
5272 if (qinfo->Flags & QUEST_FLAGS_DAILY && qinfo->Flags & QUEST_FLAGS_WEEKLY)
5273 {
5274 LOG_ERROR("sql.sql", "Weekly Quest {} is marked as daily quest in `Flags`, removed daily flag.", qinfo->GetQuestId());
5275 qinfo->Flags &= ~QUEST_FLAGS_DAILY;
5276 }
5277
5278 if (qinfo->Flags & QUEST_FLAGS_DAILY)
5279 {
5281 {
5282 LOG_ERROR("sql.sql", "Daily Quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->GetQuestId());
5284 }
5285 }
5286
5287 if (qinfo->Flags & QUEST_FLAGS_WEEKLY)
5288 {
5290 {
5291 LOG_ERROR("sql.sql", "Weekly Quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->GetQuestId());
5293 }
5294 }
5295
5297 {
5299 {
5300 LOG_ERROR("sql.sql", "Monthly quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->GetQuestId());
5302 }
5303 }
5304
5305 if (qinfo->Flags & QUEST_FLAGS_TRACKING)
5306 {
5307 // at auto-reward can be rewarded only RewardChoiceItemId[0]
5308 for (int j = 1; j < QUEST_REWARD_CHOICES_COUNT; ++j )
5309 {
5310 if (uint32 id = qinfo->RewardChoiceItemId[j])
5311 {
5312 LOG_ERROR("sql.sql", "Quest {} has `RewardChoiceItemId{}` = {} but item from `RewardChoiceItemId{}` can't be rewarded with quest flag QUEST_FLAGS_TRACKING.",
5313 qinfo->GetQuestId(), j + 1, id, j + 1);
5314 // no changes, quest ignore this data
5315 }
5316 }
5317 }
5318
5319 // client quest log visual (area case)
5320 if (qinfo->ZoneOrSort > 0)
5321 {
5322 if (!sAreaTableStore.LookupEntry(qinfo->ZoneOrSort))
5323 {
5324 LOG_ERROR("sql.sql", "Quest {} has `ZoneOrSort` = {} (zone case) but zone with this id does not exist.",
5325 qinfo->GetQuestId(), qinfo->ZoneOrSort);
5326 // no changes, quest not dependent from this value but can have problems at client
5327 }
5328 }
5329 // client quest log visual (sort case)
5330 if (qinfo->ZoneOrSort < 0)
5331 {
5332 QuestSortEntry const* qSort = sQuestSortStore.LookupEntry(-int32(qinfo->ZoneOrSort));
5333 if (!qSort)
5334 {
5335 LOG_ERROR("sql.sql", "Quest {} has `ZoneOrSort` = {} (sort case) but quest sort with this id does not exist.",
5336 qinfo->GetQuestId(), qinfo->ZoneOrSort);
5337 // 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)
5338 }
5339 //check for proper RequiredSkillId value (skill case)
5340 if (uint32 skill_id = SkillByQuestSort(-int32(qinfo->ZoneOrSort)))
5341 {
5342 if (qinfo->RequiredSkillId != skill_id)
5343 {
5344 LOG_ERROR("sql.sql", "Quest {} has `ZoneOrSort` = {} but `RequiredSkillId` does not have a corresponding value ({}).",
5345 qinfo->GetQuestId(), qinfo->ZoneOrSort, skill_id);
5346 //override, and force proper value here?
5347 }
5348 }
5349 }
5350
5351 // RequiredClasses, can be 0/CLASSMASK_ALL_PLAYABLE to allow any class
5352 if (qinfo->RequiredClasses)
5353 {
5355 {
5356 LOG_ERROR("sql.sql", "Quest {} does not contain any playable classes in `RequiredClasses` ({}), value set to 0 (all classes).", qinfo->GetQuestId(), qinfo->RequiredClasses);
5357 qinfo->RequiredClasses = 0;
5358 }
5359 }
5360 // AllowableRaces, can be 0/PlayableRaceMask to allow any race
5361 if (qinfo->AllowableRaces)
5362 {
5363 if (!(qinfo->AllowableRaces & sRaceMgr->GetPlayableRaceMask()))
5364 {
5365 LOG_ERROR("sql.sql", "Quest {} does not contain any playable races in `AllowableRaces` ({}), value set to 0 (all races).", qinfo->GetQuestId(), qinfo->AllowableRaces);
5366 qinfo->AllowableRaces = 0;
5367 }
5368 }
5369 // RequiredSkillId, can be 0
5370 if (qinfo->RequiredSkillId)
5371 {
5372 if (!sSkillLineStore.LookupEntry(qinfo->RequiredSkillId))
5373 {
5374 LOG_ERROR("sql.sql", "Quest {} has `RequiredSkillId` = {} but this skill does not exist",
5375 qinfo->GetQuestId(), qinfo->RequiredSkillId);
5376 }
5377 }
5378
5379 if (qinfo->RequiredSkillPoints)
5380 {
5381 if (qinfo->RequiredSkillPoints > sWorld->GetConfigMaxSkillValue())
5382 {
5383 LOG_ERROR("sql.sql", "Quest {} has `RequiredSkillPoints` = {} but max possible skill is {}, quest can't be done.",
5384 qinfo->GetQuestId(), qinfo->RequiredSkillPoints, sWorld->GetConfigMaxSkillValue());
5385 // no changes, quest can't be done for this requirement
5386 }
5387 }
5388 // else Skill quests can have 0 skill level, this is ok
5389
5390 if (qinfo->RequiredFactionId2 && !sFactionStore.LookupEntry(qinfo->RequiredFactionId2))
5391 {
5392 LOG_ERROR("sql.sql", "Quest {} has `RequiredFactionId2` = {} but faction template {} does not exist, quest can't be done.",
5393 qinfo->GetQuestId(), qinfo->RequiredFactionId2, qinfo->RequiredFactionId2);
5394 // no changes, quest can't be done for this requirement
5395 }
5396
5397 if (qinfo->RequiredFactionId1 && !sFactionStore.LookupEntry(qinfo->RequiredFactionId1))
5398 {
5399 LOG_ERROR("sql.sql", "Quest {} has `RequiredFactionId1` = {} but faction template {} does not exist, quest can't be done.",
5400 qinfo->GetQuestId(), qinfo->RequiredFactionId1, qinfo->RequiredFactionId1);
5401 // no changes, quest can't be done for this requirement
5402 }
5403
5404 if (qinfo->RequiredMinRepFaction && !sFactionStore.LookupEntry(qinfo->RequiredMinRepFaction))
5405 {
5406 LOG_ERROR("sql.sql", "Quest {} has `RequiredMinRepFaction` = {} but faction template {} does not exist, quest can't be done.",
5407 qinfo->GetQuestId(), qinfo->RequiredMinRepFaction, qinfo->RequiredMinRepFaction);
5408 // no changes, quest can't be done for this requirement
5409 }
5410
5411 if (qinfo->RequiredMaxRepFaction && !sFactionStore.LookupEntry(qinfo->RequiredMaxRepFaction))
5412 {
5413 LOG_ERROR("sql.sql", "Quest {} has `RequiredMaxRepFaction` = {} but faction template {} does not exist, quest can't be done.",
5414 qinfo->GetQuestId(), qinfo->RequiredMaxRepFaction, qinfo->RequiredMaxRepFaction);
5415 // no changes, quest can't be done for this requirement
5416 }
5417
5419 {
5420 LOG_ERROR("sql.sql", "Quest {} has `RequiredMinRepValue` = {} but max reputation is {}, quest can't be done.",
5422 // no changes, quest can't be done for this requirement
5423 }
5424
5425 if (qinfo->RequiredMinRepValue && qinfo->RequiredMaxRepValue && qinfo->RequiredMaxRepValue <= qinfo->RequiredMinRepValue)
5426 {
5427 LOG_ERROR("sql.sql", "Quest {} has `RequiredMaxRepValue` = {} and `RequiredMinRepValue` = {}, quest can't be done.",
5428 qinfo->GetQuestId(), qinfo->RequiredMaxRepValue, qinfo->RequiredMinRepValue);
5429 // no changes, quest can't be done for this requirement
5430 }
5431
5432 if (!qinfo->RequiredFactionId1 && qinfo->RequiredFactionValue1 != 0)
5433 {
5434 LOG_ERROR("sql.sql", "Quest {} has `RequiredFactionValue1` = {} but `RequiredFactionId1` is 0, value has no effect",
5435 qinfo->GetQuestId(), qinfo->RequiredFactionValue1);
5436 // warning
5437 }
5438
5439 if (!qinfo->RequiredFactionId2 && qinfo->RequiredFactionValue2 != 0)
5440 {
5441 LOG_ERROR("sql.sql", "Quest {} has `RequiredFactionValue2` = {} but `RequiredFactionId2` is 0, value has no effect",
5442 qinfo->GetQuestId(), qinfo->RequiredFactionValue2);
5443 // warning
5444 }
5445
5446 if (!qinfo->RequiredMinRepFaction && qinfo->RequiredMinRepValue != 0)
5447 {
5448 LOG_ERROR("sql.sql", "Quest {} has `RequiredMinRepValue` = {} but `RequiredMinRepFaction` is 0, value has no effect",
5449 qinfo->GetQuestId(), qinfo->RequiredMinRepValue);
5450 // warning
5451 }
5452
5453 if (!qinfo->RequiredMaxRepFaction && qinfo->RequiredMaxRepValue != 0)
5454 {
5455 LOG_ERROR("sql.sql", "Quest {} has `RequiredMaxRepValue` = {} but `RequiredMaxRepFaction` is 0, value has no effect",
5456 qinfo->GetQuestId(), qinfo->RequiredMaxRepValue);
5457 // warning
5458 }
5459
5460 if (qinfo->RewardTitleId && !sCharTitlesStore.LookupEntry(qinfo->RewardTitleId))
5461 {
5462 LOG_ERROR("sql.sql", "Quest {} has `RewardTitleId` = {} but CharTitle Id {} does not exist, quest can't be rewarded with title.",
5463 qinfo->GetQuestId(), qinfo->GetCharTitleId(), qinfo->GetCharTitleId());
5464 qinfo->RewardTitleId = 0;
5465 // quest can't reward this title
5466 }
5467
5468 if (qinfo->StartItem)
5469 {
5470 if (!GetItemTemplate(qinfo->StartItem))
5471 {
5472 LOG_ERROR("sql.sql", "Quest {} has `StartItem` = {} but item with entry {} does not exist, quest can't be done.",
5473 qinfo->GetQuestId(), qinfo->StartItem, qinfo->StartItem);
5474 qinfo->StartItem = 0; // quest can't be done for this requirement
5475 }
5476 else if (qinfo->StartItemCount == 0)
5477 {
5478 LOG_ERROR("sql.sql", "Quest {} has `StartItem` = {} but `StartItemCount` = 0, set to 1 but need fix in DB.",
5479 qinfo->GetQuestId(), qinfo->StartItem);
5480 qinfo->StartItemCount = 1; // update to 1 for allow quest work for backward compatibility with DB
5481 }
5482 }
5483 else if (qinfo->StartItemCount > 0)
5484 {
5485 LOG_ERROR("sql.sql", "Quest {} has `StartItem` = 0 but `StartItemCount` = {}, useless value.",
5486 qinfo->GetQuestId(), qinfo->StartItemCount);
5487 qinfo->StartItemCount = 0; // no quest work changes in fact
5488 }
5489
5490 if (qinfo->SourceSpellid)
5491 {
5492 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->SourceSpellid);
5493 if (!spellInfo)
5494 {
5495 LOG_ERROR("sql.sql", "Quest {} has `SourceSpellid` = {} but spell {} doesn't exist, quest can't be done.",
5496 qinfo->GetQuestId(), qinfo->SourceSpellid, qinfo->SourceSpellid);
5497 qinfo->SourceSpellid = 0; // quest can't be done for this requirement
5498 }
5499 else if (!SpellMgr::ComputeIsSpellValid(spellInfo))
5500 {
5501 LOG_ERROR("sql.sql", "Quest {} has `SourceSpellid` = {} but spell {} is broken, quest can't be done.",
5502 qinfo->GetQuestId(), qinfo->SourceSpellid, qinfo->SourceSpellid);
5503 qinfo->SourceSpellid = 0; // quest can't be done for this requirement
5504 }
5505 }
5506
5507 for (uint8 j = 0; j < QUEST_ITEM_OBJECTIVES_COUNT; ++j)
5508 {
5509 uint32 id = qinfo->RequiredItemId[j];
5510 if (id)
5511 {
5512 if (qinfo->RequiredItemCount[j] == 0)
5513 {
5514 LOG_ERROR("sql.sql", "Quest {} has `RequiredItemId{}` = {} but `RequiredItemCount{}` = 0, quest can't be done.",
5515 qinfo->GetQuestId(), j + 1, id, j + 1);
5516 // no changes, quest can't be done for this requirement
5517 }
5518
5520
5521 if (!GetItemTemplate(id))
5522 {
5523 LOG_ERROR("sql.sql", "Quest {} has `RequiredItemId{}` = {} but item with entry {} does not exist, quest can't be done.",
5524 qinfo->GetQuestId(), j + 1, id, id);
5525 qinfo->RequiredItemCount[j] = 0; // prevent incorrect work of quest
5526 }
5527 }
5528 else if (qinfo->RequiredItemCount[j] > 0)
5529 {
5530 LOG_ERROR("sql.sql", "Quest {} has `RequiredItemId{}` = 0 but `RequiredItemCount{}` = {}, quest can't be done.",
5531 qinfo->GetQuestId(), j + 1, j + 1, qinfo->RequiredItemCount[j]);
5532 qinfo->RequiredItemCount[j] = 0; // prevent incorrect work of quest
5533 }
5534 }
5535
5536 for (uint8 j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j)
5537 {
5538 uint32 id = qinfo->ItemDrop[j];
5539 if (id)
5540 {
5541 if (!GetItemTemplate(id))
5542 {
5543 LOG_ERROR("sql.sql", "Quest {} has `ItemDrop{}` = {} but item with entry {} does not exist, quest can't be done.",
5544 qinfo->GetQuestId(), j + 1, id, id);
5545 // no changes, quest can't be done for this requirement
5546 }
5547 }
5548 else
5549 {
5550 if (qinfo->ItemDropQuantity[j] > 0)
5551 {
5552 LOG_ERROR("sql.sql", "Quest {} has `ItemDrop{}` = 0 but `ItemDropQuantity{}` = {}.",
5553 qinfo->GetQuestId(), j + 1, j + 1, qinfo->ItemDropQuantity[j]);
5554 // no changes, quest ignore this data
5555 }
5556 }
5557 }
5558
5559 for (uint8 j = 0; j < QUEST_OBJECTIVES_COUNT; ++j)
5560 {
5561 int32 id = qinfo->RequiredNpcOrGo[j];
5562 if (id < 0 && !GetGameObjectTemplate(-id))
5563 {
5564 LOG_ERROR("sql.sql", "Quest {} has `RequiredNpcOrGo{}` = {} but gameobject {} does not exist, quest can't be done.",
5565 qinfo->GetQuestId(), j + 1, id, uint32(-id));
5566 qinfo->RequiredNpcOrGo[j] = 0; // quest can't be done for this requirement
5567 }
5568
5569 if (id > 0 && !GetCreatureTemplate(id))
5570 {
5571 LOG_ERROR("sql.sql", "Quest {} has `RequiredNpcOrGo{}` = {} but creature with entry {} does not exist, quest can't be done.",
5572 qinfo->GetQuestId(), j + 1, id, uint32(id));
5573 qinfo->RequiredNpcOrGo[j] = 0; // quest can't be done for this requirement
5574 }
5575
5576 if (id)
5577 {
5578 // In fact SpeakTo and Kill are quite same: either you can speak to mob:SpeakTo or you can't:Kill/Cast
5579
5581
5582 if (!qinfo->RequiredNpcOrGoCount[j])
5583 {
5584 LOG_ERROR("sql.sql", "Quest {} has `RequiredNpcOrGo{}` = {} but `RequiredNpcOrGoCount{}` = 0, quest can't be done.",
5585 qinfo->GetQuestId(), j + 1, id, j + 1);
5586 // no changes, quest can be incorrectly done, but we already report this
5587 }
5588 }
5589 else if (qinfo->RequiredNpcOrGoCount[j] > 0)
5590 {
5591 LOG_ERROR("sql.sql", "Quest {} has `RequiredNpcOrGo{}` = 0 but `RequiredNpcOrGoCount{}` = {}.",
5592 qinfo->GetQuestId(), j + 1, j + 1, qinfo->RequiredNpcOrGoCount[j]);
5593 // no changes, quest ignore this data
5594 }
5595 }
5596
5597 for (uint8 j = 0; j < QUEST_REWARD_CHOICES_COUNT; ++j)
5598 {
5599 uint32 id = qinfo->RewardChoiceItemId[j];
5600 if (id)
5601 {
5602 if (!GetItemTemplate(id))
5603 {
5604 LOG_ERROR("sql.sql", "Quest {} has `RewardChoiceItemId{}` = {} but item with entry {} does not exist, quest will not reward this item.",
5605 qinfo->GetQuestId(), j + 1, id, id);
5606 qinfo->RewardChoiceItemId[j] = 0; // no changes, quest will not reward this
5607 }
5608
5609 if (!qinfo->RewardChoiceItemCount[j])
5610 {
5611 LOG_ERROR("sql.sql", "Quest {} has `RewardChoiceItemId{}` = {} but `RewardChoiceItemCount{}` = 0, quest can't be done.",
5612 qinfo->GetQuestId(), j + 1, id, j + 1);
5613 // no changes, quest can't be done
5614 }
5615 }
5616 else if (qinfo->RewardChoiceItemCount[j] > 0)
5617 {
5618 LOG_ERROR("sql.sql", "Quest {} has `RewardChoiceItemId{}` = 0 but `RewardChoiceItemCount{}` = {}.",
5619 qinfo->GetQuestId(), j + 1, j + 1, qinfo->RewardChoiceItemCount[j]);
5620 // no changes, quest ignore this data
5621 }
5622 }
5623
5624 for (uint8 j = 0; j < QUEST_REWARDS_COUNT; ++j)
5625 {
5626 if (!qinfo->RewardItemId[0] && qinfo->RewardItemId[j])
5627 {
5628 LOG_ERROR("sql.sql", "Quest {} has no `RewardItemId1` but has `RewardItem{}`. Reward item will not be loaded.",
5629 qinfo->GetQuestId(), j + 1);
5630 }
5631 if (!qinfo->RewardItemId[1] && j > 1 && qinfo->RewardItemId[j])
5632 {
5633 LOG_ERROR("sql.sql", "Quest {} has no `RewardItemId2` but has `RewardItem{}`. Reward item will not be loaded.",
5634 qinfo->GetQuestId(), j + 1);
5635 }
5636 if (!qinfo->RewardItemId[2] && j > 2 && qinfo->RewardItemId[j])
5637 {
5638 LOG_ERROR("sql.sql", "Quest {} has no `RewardItemId3` but has `RewardItem{}`. Reward item will not be loaded.",
5639 qinfo->GetQuestId(), j + 1);
5640 }
5641 }
5642
5643 for (uint8 j = 0; j < QUEST_REWARDS_COUNT; ++j)
5644 {
5645 uint32 id = qinfo->RewardItemId[j];
5646 if (id)
5647 {
5648 if (!GetItemTemplate(id))
5649 {
5650 LOG_ERROR("sql.sql", "Quest {} has `RewardItemId{}` = {} but item with entry {} does not exist, quest will not reward this item.",
5651 qinfo->GetQuestId(), j + 1, id, id);
5652 qinfo->RewardItemId[j] = 0; // no changes, quest will not reward this item
5653 }
5654
5655 if (!qinfo->RewardItemIdCount[j])
5656 {
5657 LOG_ERROR("sql.sql", "Quest {} has `RewardItemId{}` = {} but `RewardItemIdCount{}` = 0, quest will not reward this item.",
5658 qinfo->GetQuestId(), j + 1, id, j + 1);
5659 // no changes
5660 }
5661 }
5662 else if (qinfo->RewardItemIdCount[j] > 0)
5663 {
5664 LOG_ERROR("sql.sql", "Quest {} has `RewardItemId{}` = 0 but `RewardItemIdCount{}` = {}.",
5665 qinfo->GetQuestId(), j + 1, j + 1, qinfo->RewardItemIdCount[j]);
5666 // no changes, quest ignore this data
5667 }
5668 }
5669
5670 for (uint8 j = 0; j < QUEST_REPUTATIONS_COUNT; ++j)
5671 {
5672 if (qinfo->RewardFactionId[j])
5673 {
5674 if (std::abs(qinfo->RewardFactionValueId[j]) > 9)
5675 {
5676 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]);
5677 }
5678 if (!sFactionStore.LookupEntry(qinfo->RewardFactionId[j]))
5679 {
5680 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]);
5681 qinfo->RewardFactionId[j] = 0; // quest will not reward this
5682 }
5683 }
5684
5685 else if (qinfo->RewardFactionValueIdOverride[j] != 0)
5686 {
5687 LOG_ERROR("sql.sql", "Quest {} has `RewardFactionId{}` = 0 but `RewardFactionValueIdOverride{}` = {}.",
5688 qinfo->GetQuestId(), j + 1, j + 1, qinfo->RewardFactionValueIdOverride[j]);
5689 // no changes, quest ignore this data
5690 }
5691 }
5692
5693 if (qinfo->RewardDisplaySpell)
5694 {
5695 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardDisplaySpell);
5696
5697 if (!spellInfo)
5698 {
5699 LOG_ERROR("sql.sql", "Quest {} has `RewardDisplaySpell` = {} but spell {} does not exist, spell removed as display reward.",
5700 qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell);
5701 qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest
5702 }
5703
5704 else if (!SpellMgr::ComputeIsSpellValid(spellInfo))
5705 {
5706 LOG_ERROR("sql.sql", "Quest {} has `RewardDisplaySpell` = {} but spell {} is broken, quest will not have a spell reward.",
5707 qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell);
5708 qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest
5709 }
5710
5711 else if (GetTalentSpellCost(qinfo->RewardDisplaySpell))
5712 {
5713 LOG_ERROR("sql.sql", "Quest {} has `RewardDisplaySpell` = {} but spell {} is talent, quest will not have a spell reward.",
5714 qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell);
5715 qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest
5716 }
5717 }
5718
5719 if (qinfo->RewardSpell > 0)
5720 {
5721 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardSpell);
5722
5723 if (!spellInfo)
5724 {
5725 LOG_ERROR("sql.sql", "Quest {} has `RewardSpell` = {} but spell {} does not exist, quest will not have a spell reward.",
5726 qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
5727 qinfo->RewardSpell = 0; // no spell will be casted on player
5728 }
5729
5730 else if (!SpellMgr::ComputeIsSpellValid(spellInfo))
5731 {
5732 LOG_ERROR("sql.sql", "Quest {} has `RewardSpell` = {} but spell {} is broken, quest will not have a spell reward.",
5733 qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
5734 qinfo->RewardSpell = 0; // no spell will be casted on player
5735 }
5736
5737 else if (GetTalentSpellCost(qinfo->RewardSpell))
5738 {
5739 LOG_ERROR("sql.sql", "Quest {} has `RewardDisplaySpell` = {} but spell {} is talent, quest will not have a spell reward.",
5740 qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
5741 qinfo->RewardSpell = 0; // no spell will be casted on player
5742 }
5743 }
5744
5745 if (qinfo->RewardMailTemplateId)
5746 {
5747 if (!sMailTemplateStore.LookupEntry(qinfo->RewardMailTemplateId))
5748 {
5749 LOG_ERROR("sql.sql", "Quest {} has `RewardMailTemplateId` = {} but mail template {} does not exist, quest will not have a mail reward.",
5750 qinfo->GetQuestId(), qinfo->RewardMailTemplateId, qinfo->RewardMailTemplateId);
5751 qinfo->RewardMailTemplateId = 0; // no mail will send to player
5752 qinfo->RewardMailDelay = 0; // no mail will send to player
5753 qinfo->RewardMailSenderEntry = 0;
5754 }
5755 else if (usedMailTemplates.find(qinfo->RewardMailTemplateId) != usedMailTemplates.end())
5756 {
5757 std::map<uint32, uint32>::const_iterator used_mt_itr = usedMailTemplates.find(qinfo->RewardMailTemplateId);
5758 LOG_ERROR("sql.sql", "Quest {} has `RewardMailTemplateId` = {} but mail template {} already used for quest {}, quest will not have a mail reward.",
5759 qinfo->GetQuestId(), qinfo->RewardMailTemplateId, qinfo->RewardMailTemplateId, used_mt_itr->second);
5760 qinfo->RewardMailTemplateId = 0; // no mail will send to player
5761 qinfo->RewardMailDelay = 0; // no mail will send to player
5762 qinfo->RewardMailSenderEntry = 0;
5763 }
5764 else
5765 usedMailTemplates[qinfo->RewardMailTemplateId] = qinfo->GetQuestId();
5766 }
5767
5768 if (qinfo->RewardNextQuest)
5769 {
5770 QuestMap::iterator qNextItr = _questTemplates.find(qinfo->RewardNextQuest);
5771 if (qNextItr == _questTemplates.end())
5772 {
5773 LOG_ERROR("sql.sql", "Quest {} has `RewardNextQuest` = {} but quest {} does not exist, quest chain will not work.",
5774 qinfo->GetQuestId(), qinfo->RewardNextQuest, qinfo->RewardNextQuest);
5775 qinfo->RewardNextQuest = 0;
5776 }
5777 else
5778 qNextItr->second->prevChainQuests.push_back(qinfo->GetQuestId());
5779 }
5780
5781 // fill additional data stores
5782 if (qinfo->PrevQuestId)
5783 {
5784 if (_questTemplates.find(std::abs(qinfo->GetPrevQuestId())) == _questTemplates.end())
5785 {
5786 LOG_ERROR("sql.sql", "Quest {} has PrevQuestId {}, but no such quest", qinfo->GetQuestId(), qinfo->GetPrevQuestId());
5787 }
5788 else
5789 {
5790 qinfo->prevQuests.push_back(qinfo->PrevQuestId);
5791 }
5792 }
5793
5794 if (qinfo->NextQuestId)
5795 {
5796 QuestMap::iterator qNextItr = _questTemplates.find(qinfo->GetNextQuestId());
5797 if (qNextItr == _questTemplates.end())
5798 {
5799 LOG_ERROR("sql.sql", "Quest {} has NextQuestId {}, but no such quest", qinfo->GetQuestId(), qinfo->GetNextQuestId());
5800 }
5801 else
5802 qNextItr->second->prevQuests.push_back(static_cast<int32>(qinfo->GetQuestId()));
5803 }
5804
5805 if (qinfo->ExclusiveGroup)
5806 mExclusiveQuestGroups.insert(std::pair<int32, uint32>(qinfo->ExclusiveGroup, qinfo->GetQuestId()));
5807
5808 if (uint32 breadcrumbForQuestId = qinfo->GetBreadcrumbForQuestId())
5809 {
5810 if (_questTemplates.find(breadcrumbForQuestId) == _questTemplates.end())
5811 LOG_ERROR("sql.sql", "Quest {} has BreadcrumbForQuestId {}, but no such quest exists", qinfo->GetQuestId(), breadcrumbForQuestId);
5812 else
5813 _breadcrumbsForQuest[breadcrumbForQuestId].push_back(qinfo->GetQuestId());
5814
5815 if (qinfo->GetNextQuestId())
5816 LOG_ERROR("sql.sql", "Quest {} is a breadcrumb quest but also has NextQuestID {} set", qinfo->GetQuestId(), qinfo->GetNextQuestId());
5817 if (qinfo->GetExclusiveGroup())
5818 LOG_ERROR("sql.sql", "Quest {} is a breadcrumb quest but also has ExclusiveGroup {} set", qinfo->GetQuestId(), qinfo->GetExclusiveGroup());
5819 }
5820
5821 if (qinfo->TimeAllowed)
5823 if (qinfo->RequiredPlayerKills)
5825 }
5826
5827 for (auto const& [questId, quest] : _questTemplates)
5828 {
5829 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_QUEST, questId, nullptr))
5830 continue;
5831
5832 uint32 breadcrumbForQuestId = quest->GetBreadcrumbForQuestId();
5833 if (!breadcrumbForQuestId)
5834 continue;
5835
5836 std::set<uint32> visitedQuests;
5837 visitedQuests.insert(questId);
5838
5839 while (breadcrumbForQuestId)
5840 {
5841 if (!visitedQuests.insert(breadcrumbForQuestId).second)
5842 {
5843 LOG_ERROR("sql.sql", "Breadcrumb quests {} and {} form a loop", questId, breadcrumbForQuestId);
5844 break;
5845 }
5846
5847 Quest const* targetQuest = GetQuestTemplate(breadcrumbForQuestId);
5848 if (!targetQuest)
5849 break;
5850
5851 breadcrumbForQuestId = targetQuest->GetBreadcrumbForQuestId();
5852 }
5853 }
5854
5855 // check QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT for spell with SPELL_EFFECT_QUEST_COMPLETE
5856 for (uint32 i = 0; i < sSpellMgr->GetSpellInfoStoreSize(); ++i)
5857 {
5858 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(i);
5859 if (!spellInfo)
5860 continue;
5861
5862 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
5863 {
5864 if (spellInfo->Effects[j].Effect != SPELL_EFFECT_QUEST_COMPLETE)
5865 continue;
5866
5867 uint32 quest_id = spellInfo->Effects[j].MiscValue;
5868
5869 Quest const* quest = GetQuestTemplate(quest_id);
5870
5871 // some quest referenced in spells not exist (outdated spells)
5872 if (!quest)
5873 continue;
5874
5876 {
5877 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);
5878
5879 // this will prevent quest completing without objective
5880 // xinef: remove this, leave error but do not break the quest
5881 // const_cast<Quest*>(quest)->SetSpecialFlag(QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT);
5882 }
5883 }
5884 }
5885
5886 LOG_INFO("server.loading", ">> Loaded {} Quests Definitions in {} ms", (unsigned long)_questTemplates.size(), GetMSTimeDiffToNow(oldMSTime));
5887 LOG_INFO("server.loading", " ");
5888}
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:782
uint32 SkillByQuestSort(int32 QuestSort)
Definition SharedDefines.h:3273
ExclusiveQuestGroups mExclusiveQuestGroups
Definition ObjectMgr.h:1155
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:417
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, 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, sRaceMgr, sSkillLineStore, sSpellMgr, Quest::StartItem, Quest::StartItemCount, sWorld, Quest::TimeAllowed, WorldDatabase, and Quest::ZoneOrSort.

◆ LoadQuestStartersAndEnders()

void ObjectMgr::LoadQuestStartersAndEnders ( )
inline
963 {
964 LOG_INFO("server.loading", "Loading GO Start Quest Data...");
966 LOG_INFO("server.loading", "Loading GO End Quest Data...");
968 LOG_INFO("server.loading", "Loading Creature Start Quest Data...");
970 LOG_INFO("server.loading", "Loading Creature End Quest Data...");
972 }
void LoadCreatureQuestEnders()
Definition ObjectMgr.cpp:9042
void LoadGameobjectQuestEnders()
Definition ObjectMgr.cpp:9014
void LoadGameobjectQuestStarters()
Definition ObjectMgr.cpp:9000
void LoadCreatureQuestStarters()
Definition ObjectMgr.cpp:9028

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

◆ LoadReferenceVendor()

int ObjectMgr::LoadReferenceVendor ( int32  vendor,
int32  item_id,
std::set< uint32 > *  skip_vendors 
)
10230{
10231 // find all items from the reference vendor
10233 stmt->SetData(0, uint32(item));
10234 PreparedQueryResult result = WorldDatabase.Query(stmt);
10235
10236 if (!result)
10237 return 0;
10238
10239 uint32 count = 0;
10240 do
10241 {
10242 Field* fields = result->Fetch();
10243
10244 int32 item_id = fields[0].Get<int32>();
10245
10246 // if item is a negative, its a reference
10247 if (item_id < 0)
10248 count += LoadReferenceVendor(vendor, -item_id, skip_vendors);
10249 else
10250 {
10251 uint32 maxcount = fields[1].Get<uint32>();
10252 uint32 incrtime = fields[2].Get<uint32>();
10253 uint32 ExtendedCost = fields[3].Get<uint32>();
10254
10255 if (!IsVendorItemValid(vendor, item_id, maxcount, incrtime, ExtendedCost, nullptr, skip_vendors))
10256 continue;
10257
10258 VendorItemData& vList = _cacheVendorItemStore[vendor];
10259
10260 vList.AddItem(item_id, maxcount, incrtime, ExtendedCost);
10261 ++count;
10262 }
10263 } while (result->NextRow());
10264
10265 return count;
10266}
@ WORLD_SEL_NPC_VENDOR_REF
Definition WorldDatabase.h:45
bool IsVendorItemValid(uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player *player=nullptr, std::set< uint32 > *skip_vendors=nullptr, uint32 ORnpcflag=0) const
Definition ObjectMgr.cpp:10491
int LoadReferenceVendor(int32 vendor, int32 item_id, std::set< uint32 > *skip_vendors)
Definition ObjectMgr.cpp:10229

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 ( )
8367{
8368 uint32 oldMSTime = getMSTime();
8369
8370 // For reload case
8371 _repOnKillStore.clear();
8372
8373 uint32 count = 0;
8374
8375 // 0 1 2
8376 QueryResult result = WorldDatabase.Query("SELECT creature_id, RewOnKillRepFaction1, RewOnKillRepFaction2, "
8377 // 3 4 5 6 7 8 9
8378 "IsTeamAward1, MaxStanding1, RewOnKillRepValue1, IsTeamAward2, MaxStanding2, RewOnKillRepValue2, TeamDependent "
8379 "FROM creature_onkill_reputation");
8380
8381 if (!result)
8382 {
8383 LOG_WARN("server.loading", ">> Loaded 0 creature award reputation definitions. DB table `creature_onkill_reputation` is empty.");
8384 LOG_INFO("server.loading", " ");
8385 return;
8386 }
8387
8388 do
8389 {
8390 Field* fields = result->Fetch();
8391
8392 uint32 creature_id = fields[0].Get<uint32>();
8393
8394 ReputationOnKillEntry repOnKill;
8395 repOnKill.RepFaction1 = fields[1].Get<int16>();
8396 repOnKill.RepFaction2 = fields[2].Get<int16>();
8397 repOnKill.IsTeamAward1 = fields[3].Get<bool>();
8398 repOnKill.ReputationMaxCap1 = fields[4].Get<uint8>();
8399 repOnKill.RepValue1 = fields[5].Get<float>();
8400 repOnKill.IsTeamAward2 = fields[6].Get<bool>();
8401 repOnKill.ReputationMaxCap2 = fields[7].Get<uint8>();
8402 repOnKill.RepValue2 = fields[8].Get<float>();
8403 repOnKill.TeamDependent = fields[9].Get<uint8>();
8404
8405 if (!GetCreatureTemplate(creature_id))
8406 {
8407 LOG_ERROR("sql.sql", "Table `creature_onkill_reputation` have data for not existed creature entry ({}), skipped", creature_id);
8408 continue;
8409 }
8410
8411 if (repOnKill.RepFaction1)
8412 {
8413 FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(repOnKill.RepFaction1);
8414 if (!factionEntry1)
8415 {
8416 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.RepFaction1);
8417 continue;
8418 }
8419 }
8420
8421 if (repOnKill.RepFaction2)
8422 {
8423 FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(repOnKill.RepFaction2);
8424 if (!factionEntry2)
8425 {
8426 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.RepFaction2);
8427 continue;
8428 }
8429 }
8430
8431 _repOnKillStore[creature_id] = repOnKill;
8432
8433 ++count;
8434 } while (result->NextRow());
8435
8436 LOG_INFO("server.loading", ">> Loaded {} Creature Award Reputation Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8437 LOG_INFO("server.loading", " ");
8438}
Definition ObjectMgr.h:574
uint32 RepFaction1
Definition ObjectMgr.h:575

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

◆ LoadReputationRewardRate()

void ObjectMgr::LoadReputationRewardRate ( )
8279{
8280 uint32 oldMSTime = getMSTime();
8281
8282 _repRewardRateStore.clear(); // for reload case
8283
8284 uint32 count = 0; // 0 1 2 3 4 5 6 7
8285 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");
8286 if (!result)
8287 {
8288 LOG_INFO("server.loading", ">> Loaded `reputation_reward_rate`, table is empty!");
8289 return;
8290 }
8291
8292 do
8293 {
8294 Field* fields = result->Fetch();
8295
8296 uint32 factionId = fields[0].Get<uint32>();
8297
8298 RepRewardRate repRate;
8299
8300 repRate.questRate = fields[1].Get<float>();
8301 repRate.questDailyRate = fields[2].Get<float>();
8302 repRate.questWeeklyRate = fields[3].Get<float>();
8303 repRate.questMonthlyRate = fields[4].Get<float>();
8304 repRate.questRepeatableRate = fields[5].Get<float>();
8305 repRate.creatureRate = fields[6].Get<float>();
8306 repRate.spellRate = fields[7].Get<float>();
8307
8308 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
8309 if (!factionEntry)
8310 {
8311 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_reward_rate`", factionId);
8312 continue;
8313 }
8314
8315 if (repRate.questRate < 0.0f)
8316 {
8317 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_rate with invalid rate {}, skipping data for faction {}", repRate.questRate, factionId);
8318 continue;
8319 }
8320
8321 if (repRate.questDailyRate < 0.0f)
8322 {
8323 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_daily_rate with invalid rate {}, skipping data for faction {}", repRate.questDailyRate, factionId);
8324 continue;
8325 }
8326
8327 if (repRate.questWeeklyRate < 0.0f)
8328 {
8329 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_weekly_rate with invalid rate {}, skipping data for faction {}", repRate.questWeeklyRate, factionId);
8330 continue;
8331 }
8332
8333 if (repRate.questMonthlyRate < 0.0f)
8334 {
8335 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_monthly_rate with invalid rate {}, skipping data for faction {}", repRate.questMonthlyRate, factionId);
8336 continue;
8337 }
8338
8339 if (repRate.questRepeatableRate < 0.0f)
8340 {
8341 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_repeatable_rate with invalid rate {}, skipping data for faction {}", repRate.questRepeatableRate, factionId);
8342 continue;
8343 }
8344
8345 if (repRate.creatureRate < 0.0f)
8346 {
8347 LOG_ERROR("sql.sql", "Table reputation_reward_rate has creature_rate with invalid rate {}, skipping data for faction {}", repRate.creatureRate, factionId);
8348 continue;
8349 }
8350
8351 if (repRate.spellRate < 0.0f)
8352 {
8353 LOG_ERROR("sql.sql", "Table reputation_reward_rate has spell_rate with invalid rate {}, skipping data for faction {}", repRate.spellRate, factionId);
8354 continue;
8355 }
8356
8357 _repRewardRateStore[factionId] = repRate;
8358
8359 ++count;
8360 } while (result->NextRow());
8361
8362 LOG_INFO("server.loading", ">> Loaded {} Reputation Reward Rate in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8363 LOG_INFO("server.loading", " ");
8364}
Definition ObjectMgr.h:563
float questRate
Definition ObjectMgr.h:564

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

◆ LoadReputationSpilloverTemplate()

void ObjectMgr::LoadReputationSpilloverTemplate ( )
8441{
8442 uint32 oldMSTime = getMSTime();
8443
8444 _repSpilloverTemplateStore.clear(); // for reload case
8445
8446 uint32 count = 0; // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
8447 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");
8448
8449 if (!result)
8450 {
8451 LOG_INFO("server.loading", ">> Loaded `reputation_spillover_template`, table is empty.");
8452 LOG_INFO("server.loading", " ");
8453 return;
8454 }
8455
8456 do
8457 {
8458 Field* fields = result->Fetch();
8459
8460 uint32 factionId = fields[0].Get<uint16>();
8461
8462 RepSpilloverTemplate repTemplate;
8463
8464 repTemplate.faction[0] = fields[1].Get<uint16>();
8465 repTemplate.faction_rate[0] = fields[2].Get<float>();
8466 repTemplate.faction_rank[0] = fields[3].Get<uint8>();
8467 repTemplate.faction[1] = fields[4].Get<uint16>();
8468 repTemplate.faction_rate[1] = fields[5].Get<float>();
8469 repTemplate.faction_rank[1] = fields[6].Get<uint8>();
8470 repTemplate.faction[2] = fields[7].Get<uint16>();
8471 repTemplate.faction_rate[2] = fields[8].Get<float>();
8472 repTemplate.faction_rank[2] = fields[9].Get<uint8>();
8473 repTemplate.faction[3] = fields[10].Get<uint16>();
8474 repTemplate.faction_rate[3] = fields[11].Get<float>();
8475 repTemplate.faction_rank[3] = fields[12].Get<uint8>();
8476 repTemplate.faction[4] = fields[13].Get<uint16>();
8477 repTemplate.faction_rate[4] = fields[14].Get<float>();
8478 repTemplate.faction_rank[4] = fields[15].Get<uint8>();
8479 repTemplate.faction[5] = fields[16].Get<uint16>();
8480 repTemplate.faction_rate[5] = fields[17].Get<float>();
8481 repTemplate.faction_rank[5] = fields[18].Get<uint8>();
8482
8483 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
8484
8485 if (!factionEntry)
8486 {
8487 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", factionId);
8488 continue;
8489 }
8490
8491 if (factionEntry->team == 0)
8492 {
8493 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} in `reputation_spillover_template` does not belong to any team, skipping", factionId);
8494 continue;
8495 }
8496
8497 for (uint32 i = 0; i < MAX_SPILLOVER_FACTIONS; ++i)
8498 {
8499 if (repTemplate.faction[i])
8500 {
8501 FactionEntry const* factionSpillover = sFactionStore.LookupEntry(repTemplate.faction[i]);
8502
8503 if (!factionSpillover)
8504 {
8505 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);
8506 continue;
8507 }
8508
8509 if (factionSpillover->reputationListID < 0)
8510 {
8511 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);
8512 continue;
8513 }
8514
8515 if (repTemplate.faction_rank[i] >= MAX_REPUTATION_RANK)
8516 {
8517 LOG_ERROR("sql.sql", "Rank {} used in `reputation_spillover_template` for spillover faction {} is not valid, skipping", repTemplate.faction_rank[i], repTemplate.faction[i]);
8518 continue;
8519 }
8520 }
8521 }
8522
8523 FactionEntry const* factionEntry0 = sFactionStore.LookupEntry(repTemplate.faction[0]);
8524 if (repTemplate.faction[0] && !factionEntry0)
8525 {
8526 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[0]);
8527 continue;
8528 }
8529 FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(repTemplate.faction[1]);
8530 if (repTemplate.faction[1] && !factionEntry1)
8531 {
8532 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[1]);
8533 continue;
8534 }
8535 FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(repTemplate.faction[2]);
8536 if (repTemplate.faction[2] && !factionEntry2)
8537 {
8538 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[2]);
8539 continue;
8540 }
8541 FactionEntry const* factionEntry3 = sFactionStore.LookupEntry(repTemplate.faction[3]);
8542 if (repTemplate.faction[3] && !factionEntry3)
8543 {
8544 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[3]);
8545 continue;
8546 }
8547
8548 _repSpilloverTemplateStore[factionId] = repTemplate;
8549
8550 ++count;
8551 } while (result->NextRow());
8552
8553 LOG_INFO("server.loading", ">> Loaded {} Reputation Spillover Template in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8554 LOG_INFO("server.loading", " ");
8555}
#define MAX_SPILLOVER_FACTIONS
Definition SharedDefines.h:235
int32 reputationListID
Definition DBCStructure.h:909
Definition ObjectMgr.h:587
uint32 faction[MAX_SPILLOVER_FACTIONS]
Definition ObjectMgr.h:588

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 ( )
9057{
9058 uint32 oldMSTime = getMSTime();
9059
9060 _reservedNamesStore.clear(); // need for reload case
9061
9062 QueryResult result = CharacterDatabase.Query("SELECT name FROM reserved_name");
9063
9064 if (!result)
9065 {
9066 LOG_WARN("server.loading", ">> Loaded 0 reserved names. DB table `reserved_name` is empty!");
9067 return;
9068 }
9069
9070 uint32 count = 0;
9071
9072 Field* fields;
9073 do
9074 {
9075 fields = result->Fetch();
9076 std::string name = fields[0].Get<std::string>();
9077
9078 std::wstring wstr;
9079 if (!Utf8toWStr (name, wstr))
9080 {
9081 LOG_ERROR("sql.sql", "Table `reserved_name` have invalid name: {}", name);
9082 continue;
9083 }
9084
9085 wstrToLower(wstr);
9086
9087 _reservedNamesStore.insert(wstr);
9088 ++count;
9089 } while (result->NextRow());
9090
9091 LOG_INFO("server.loading", ">> Loaded {} reserved names from DB in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9092}

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

◆ LoadReservedPlayerNamesDBC()

void ObjectMgr::LoadReservedPlayerNamesDBC ( )
9095{
9096 if (!sWorld->getBoolConfig(CONFIG_STRICT_NAMES_RESERVED))
9097 {
9098 LOG_WARN("server.loading", ">> Loaded 0 reserved names from DBC. Config option disabled.");
9099 return;
9100 }
9101
9102 uint32 oldMSTime = getMSTime();
9103
9104 uint32 count = 0;
9105
9106 for (NamesReservedEntry const* reservedStore : sNamesReservedStore)
9107 {
9108 std::wstring wstr;
9109
9110 Utf8toWStr(reservedStore->Pattern, wstr);
9111
9112 // DBC does not have clean entries, remove the junk.
9113 boost::algorithm::replace_all(wstr, "\\<", "");
9114 boost::algorithm::replace_all(wstr, "\\>", "");
9115
9116 _reservedNamesStore.insert(wstr);
9117 count++;
9118 }
9119
9120 LOG_INFO("server.loading", ">> Loaded {} reserved names from DBC in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9121 LOG_INFO("server.loading", " ");
9122}
DBCStorage< NamesReservedEntry > sNamesReservedStore(NamesReservedfmt)
@ CONFIG_STRICT_NAMES_RESERVED
Definition WorldConfig.h:140
Definition DBCStructure.h:1398

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

◆ LoadScriptNames()

void ObjectMgr::LoadScriptNames ( )
10572{
10573 uint32 oldMSTime = getMSTime();
10574
10575 // We insert an empty placeholder here so we can use the
10576 // script id 0 as dummy for "no script found".
10577 _scriptNamesStore.emplace_back("");
10578
10579 QueryResult result = WorldDatabase.Query(
10580 "SELECT DISTINCT(ScriptName) FROM achievement_criteria_data WHERE ScriptName <> '' AND type = 11 "
10581 "UNION "
10582 "SELECT DISTINCT(ScriptName) FROM battleground_template WHERE ScriptName <> '' "
10583 "UNION "
10584 "SELECT DISTINCT(ScriptName) FROM creature WHERE ScriptName <> '' "
10585 "UNION "
10586 "SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' "
10587 "UNION "
10588 "SELECT DISTINCT(ScriptName) FROM gameobject WHERE ScriptName <> '' "
10589 "UNION "
10590 "SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' "
10591 "UNION "
10592 "SELECT DISTINCT(ScriptName) FROM item_template WHERE ScriptName <> '' "
10593 "UNION "
10594 "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
10595 "UNION "
10596 "SELECT DISTINCT(ScriptName) FROM spell_script_names WHERE ScriptName <> '' "
10597 "UNION "
10598 "SELECT DISTINCT(ScriptName) FROM transports WHERE ScriptName <> '' "
10599 "UNION "
10600 "SELECT DISTINCT(ScriptName) FROM game_weather WHERE ScriptName <> '' "
10601 "UNION "
10602 "SELECT DISTINCT(ScriptName) FROM conditions WHERE ScriptName <> '' "
10603 "UNION "
10604 "SELECT DISTINCT(ScriptName) FROM outdoorpvp_template WHERE ScriptName <> '' "
10605 "UNION "
10606 "SELECT DISTINCT(script) FROM instance_template WHERE script <> ''");
10607
10608 if (!result)
10609 {
10610 LOG_INFO("server.loading", " ");
10611 LOG_ERROR("sql.sql", ">> Loaded empty set of Script Names!");
10612 return;
10613 }
10614
10615 _scriptNamesStore.reserve(result->GetRowCount() + 1);
10616
10617 do
10618 {
10619 _scriptNamesStore.push_back((*result)[0].Get<std::string>());
10620 } while (result->NextRow());
10621
10622 std::sort(_scriptNamesStore.begin(), _scriptNamesStore.end());
10623 LOG_INFO("server.loading", ">> Loaded {} ScriptNames in {} ms", _scriptNamesStore.size(), GetMSTimeDiffToNow(oldMSTime));
10624 LOG_INFO("server.loading", " ");
10625}

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

◆ LoadScripts()

void ObjectMgr::LoadScripts ( ScriptsType  type)
private
5927{
5928 uint32 oldMSTime = getMSTime();
5929
5930 ScriptMapMap* scripts = GetScriptsMapByType(type);
5931 if (!scripts)
5932 return;
5933
5934 std::string tableName = GetScriptsTableNameByType(type);
5935 if (tableName.empty())
5936 return;
5937
5938 if (sScriptMgr->IsScriptScheduled()) // function cannot be called when scripts are in use.
5939 return;
5940
5941 LOG_INFO("server.loading", "Loading {}...", tableName);
5942
5943 scripts->clear(); // need for reload support
5944
5945 bool isSpellScriptTable = (type == SCRIPTS_SPELL);
5946 // 0 1 2 3 4 5 6 7 8 9
5947 QueryResult result = WorldDatabase.Query("SELECT id, delay, command, datalong, datalong2, dataint, x, y, z, o{} FROM {}", isSpellScriptTable ? ", effIndex" : "", tableName);
5948
5949 if (!result)
5950 {
5951 LOG_WARN("server.loading", ">> Loaded 0 script definitions. DB table `{}` is empty!", tableName);
5952 LOG_INFO("server.loading", " ");
5953 return;
5954 }
5955
5956 uint32 count = 0;
5957
5958 do
5959 {
5960 Field* fields = result->Fetch();
5961 ScriptInfo tmp;
5962 tmp.type = type;
5963 tmp.id = fields[0].Get<uint32>();
5964 if (isSpellScriptTable)
5965 tmp.id |= fields[10].Get<uint8>() << 24;
5966 tmp.delay = fields[1].Get<uint32>();
5967 tmp.command = ScriptCommands(fields[2].Get<uint32>());
5968 tmp.Raw.nData[0] = fields[3].Get<uint32>();
5969 tmp.Raw.nData[1] = fields[4].Get<uint32>();
5970 tmp.Raw.nData[2] = fields[5].Get<int32>();
5971 tmp.Raw.fData[0] = fields[6].Get<float>();
5972 tmp.Raw.fData[1] = fields[7].Get<float>();
5973 tmp.Raw.fData[2] = fields[8].Get<float>();
5974 tmp.Raw.fData[3] = fields[9].Get<float>();
5975
5976 // generic command args check
5977 switch (tmp.command)
5978 {
5980 {
5982 {
5983 LOG_ERROR("sql.sql", "Table `{}` has invalid talk type (datalong = {}) in SCRIPT_COMMAND_TALK for script id {}",
5984 tableName, tmp.Talk.ChatType, tmp.id);
5985 continue;
5986 }
5988 {
5989 LOG_ERROR("sql.sql", "Table `{}` has invalid talk text id (dataint = {}) in SCRIPT_COMMAND_TALK for script id {}",
5990 tableName, tmp.Talk.TextID, tmp.id);
5991 continue;
5992 }
5993 break;
5994 }
5995
5997 {
5998 if (!sEmotesStore.LookupEntry(tmp.Emote.EmoteID))
5999 {
6000 LOG_ERROR("sql.sql", "Table `{}` has invalid emote id (datalong = {}) in SCRIPT_COMMAND_EMOTE for script id {}",
6001 tableName, tmp.Emote.EmoteID, tmp.id);
6002 continue;
6003 }
6004 break;
6005 }
6006
6008 {
6009 if (!sMapStore.LookupEntry(tmp.TeleportTo.MapID))
6010 {
6011 LOG_ERROR("sql.sql", "Table `{}` has invalid map (Id: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
6012 tableName, tmp.TeleportTo.MapID, tmp.id);
6013 continue;
6014 }
6015
6017 {
6018 LOG_ERROR("sql.sql", "Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
6019 tableName, tmp.TeleportTo.DestX, tmp.TeleportTo.DestY, tmp.TeleportTo.DestZ, tmp.TeleportTo.Orientation, tmp.id);
6020 continue;
6021 }
6022 break;
6023 }
6024
6026 {
6027 Quest const* quest = GetQuestTemplate(tmp.QuestExplored.QuestID);
6028 if (!quest)
6029 {
6030 LOG_ERROR("sql.sql", "Table `{}` has invalid quest (ID: {}) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id {}",
6031 tableName, tmp.QuestExplored.QuestID, tmp.id);
6032 continue;
6033 }
6034
6036 {
6037 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.",
6038 tableName, tmp.QuestExplored.QuestID, tmp.id);
6039
6040 // this will prevent quest completing without objective
6041 const_cast<Quest*>(quest)->SetSpecialFlag(QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT);
6042
6043 // continue; - quest objective requirement set and command can be allowed
6044 }
6045
6047 {
6048 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 {}",
6049 tableName, tmp.QuestExplored.Distance, tmp.id);
6050 continue;
6051 }
6052
6054 {
6055 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",
6057 continue;
6058 }
6059
6061 {
6062 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",
6063 tableName, tmp.QuestExplored.Distance, tmp.id, INTERACTION_DISTANCE);
6064 continue;
6065 }
6066
6067 break;
6068 }
6069
6071 {
6073 {
6074 LOG_ERROR("sql.sql", "Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_KILL_CREDIT for script id {}",
6075 tableName, tmp.KillCredit.CreatureEntry, tmp.id);
6076 continue;
6077 }
6078 break;
6079 }
6080
6082 {
6084 if (!data)
6085 {
6086 LOG_ERROR("sql.sql", "Table `{}` has invalid gameobject (GUID: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
6087 tableName, tmp.RespawnGameobject.GOGuid, tmp.id);
6088 continue;
6089 }
6090
6091 GameObjectTemplate const* info = GetGameObjectTemplate(data->id);
6092 if (!info)
6093 {
6094 LOG_ERROR("sql.sql", "Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
6095 tableName, tmp.RespawnGameobject.GOGuid, data->id, tmp.id);
6096 continue;
6097 }
6098
6099 if (info->type == GAMEOBJECT_TYPE_FISHINGNODE ||
6101 info->type == GAMEOBJECT_TYPE_DOOR ||
6102 info->type == GAMEOBJECT_TYPE_BUTTON ||
6103 info->type == GAMEOBJECT_TYPE_TRAP)
6104 {
6105 LOG_ERROR("sql.sql", "Table `{}` have gameobject type ({}) unsupported by command SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
6106 tableName, info->entry, tmp.id);
6107 continue;
6108 }
6109 break;
6110 }
6111
6113 {
6115 {
6116 LOG_ERROR("sql.sql", "Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
6118 continue;
6119 }
6120
6122 if (!GetCreatureTemplate(entry))
6123 {
6124 LOG_ERROR("sql.sql", "Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
6125 tableName, tmp.TempSummonCreature.CreatureEntry, tmp.id);
6126 continue;
6127 }
6128 break;
6129 }
6130
6133 {
6135 if (!data)
6136 {
6137 LOG_ERROR("sql.sql", "Table `{}` has invalid gameobject (GUID: {}) in {} for script id {}",
6138 tableName, tmp.ToggleDoor.GOGuid, GetScriptCommandName(tmp.command), tmp.id);
6139 continue;
6140 }
6141
6142 GameObjectTemplate const* info = GetGameObjectTemplate(data->id);
6143 if (!info)
6144 {
6145 LOG_ERROR("sql.sql", "Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in {} for script id {}",
6146 tableName, tmp.ToggleDoor.GOGuid, data->id, GetScriptCommandName(tmp.command), tmp.id);
6147 continue;
6148 }
6149
6150 if (info->type != GAMEOBJECT_TYPE_DOOR)
6151 {
6152 LOG_ERROR("sql.sql", "Table `{}` has gameobject type ({}) non supported by command {} for script id {}",
6153 tableName, info->entry, GetScriptCommandName(tmp.command), tmp.id);
6154 continue;
6155 }
6156
6157 break;
6158 }
6159
6161 {
6162 if (!sSpellMgr->GetSpellInfo(tmp.RemoveAura.SpellID))
6163 {
6164 LOG_ERROR("sql.sql", "Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
6165 tableName, tmp.RemoveAura.SpellID, tmp.id);
6166 continue;
6167 }
6168 if (tmp.RemoveAura.Flags & ~0x1) // 1 bits (0, 1)
6169 {
6170 LOG_ERROR("sql.sql", "Table `{}` using unknown flags in datalong2 ({}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
6171 tableName, tmp.RemoveAura.Flags, tmp.id);
6172 continue;
6173 }
6174 break;
6175 }
6176
6178 {
6179 if (!sSpellMgr->GetSpellInfo(tmp.CastSpell.SpellID))
6180 {
6181 LOG_ERROR("sql.sql", "Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
6182 tableName, tmp.CastSpell.SpellID, tmp.id);
6183 continue;
6184 }
6185 if (tmp.CastSpell.Flags > 4) // targeting type
6186 {
6187 LOG_ERROR("sql.sql", "Table `{}` using unknown target in datalong2 ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
6188 tableName, tmp.CastSpell.Flags, tmp.id);
6189 continue;
6190 }
6191 if (tmp.CastSpell.Flags != 4 && tmp.CastSpell.CreatureEntry & ~0x1) // 1 bit (0, 1)
6192 {
6193 LOG_ERROR("sql.sql", "Table `{}` using unknown flags in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
6194 tableName, tmp.CastSpell.CreatureEntry, tmp.id);
6195 continue;
6196 }
6197 else if (tmp.CastSpell.Flags == 4 && !GetCreatureTemplate(tmp.CastSpell.CreatureEntry))
6198 {
6199 LOG_ERROR("sql.sql", "Table `{}` using invalid creature entry in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
6200 tableName, tmp.CastSpell.CreatureEntry, tmp.id);
6201 continue;
6202 }
6203 break;
6204 }
6205
6207 {
6209 {
6210 LOG_ERROR("sql.sql", "Table `{}` has nonexistent item (entry: {}) in SCRIPT_COMMAND_CREATE_ITEM for script id {}",
6211 tableName, tmp.CreateItem.ItemEntry, tmp.id);
6212 continue;
6213 }
6214 if (!tmp.CreateItem.Amount)
6215 {
6216 LOG_ERROR("sql.sql", "Table `{}` SCRIPT_COMMAND_CREATE_ITEM but amount is {} for script id {}",
6217 tableName, tmp.CreateItem.Amount, tmp.id);
6218 continue;
6219 }
6220 break;
6221 }
6222 default:
6223 break;
6224 }
6225
6226 if (scripts->find(tmp.id) == scripts->end())
6227 {
6228 ScriptMap emptyMap;
6229 (*scripts)[tmp.id] = emptyMap;
6230 }
6231 (*scripts)[tmp.id].insert(std::pair<uint32, ScriptInfo>(tmp.delay, tmp));
6232
6233 ++count;
6234 } while (result->NextRow());
6235
6236 LOG_INFO("server.loading", ">> Loaded {} script definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6237 LOG_INFO("server.loading", " ");
6238}
@ CHAT_TYPE_WHISPER
Definition CreatureData.h:416
#define DEFAULT_VISIBILITY_DISTANCE
Definition ObjectDefines.h:39
#define INTERACTION_DISTANCE
Definition ObjectDefines.h:24
std::multimap< uint32, ScriptInfo > ScriptMap
Definition ObjectMgr.h:388
ScriptMapMap * GetScriptsMapByType(ScriptsType type)
Definition ObjectMgr.cpp:84
ScriptCommands
Definition ObjectMgr.h:94
@ SCRIPT_COMMAND_EMOTE
Definition ObjectMgr.h:96
@ SCRIPT_COMMAND_CREATE_ITEM
Definition ObjectMgr.h:112
@ SCRIPT_COMMAND_CLOSE_DOOR
Definition ObjectMgr.h:107
@ SCRIPT_COMMAND_CAST_SPELL
Definition ObjectMgr.h:110
@ SCRIPT_COMMAND_RESPAWN_GAMEOBJECT
Definition ObjectMgr.h:104
@ SCRIPT_COMMAND_QUEST_EXPLORED
Definition ObjectMgr.h:102
@ SCRIPT_COMMAND_TALK
Definition ObjectMgr.h:95
@ SCRIPT_COMMAND_OPEN_DOOR
Definition ObjectMgr.h:106
@ SCRIPT_COMMAND_TELEPORT_TO
Definition ObjectMgr.h:101
@ SCRIPT_COMMAND_TEMP_SUMMON_CREATURE
Definition ObjectMgr.h:105
@ SCRIPT_COMMAND_KILL_CREDIT
Definition ObjectMgr.h:103
@ SCRIPT_COMMAND_REMOVE_AURA
Definition ObjectMgr.h:109
std::string GetScriptCommandName(ScriptCommands command)
Definition ObjectMgr.cpp:104
std::map< uint32, ScriptMap > ScriptMapMap
Definition ObjectMgr.h:389
std::string GetScriptsTableNameByType(ScriptsType type)
Definition ObjectMgr.cpp:64
@ SCRIPTS_SPELL
Definition ObjectMgr.h:151
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition SharedDefines.h:1581
@ CHAT_MSG_RAID_BOSS_WHISPER
Definition SharedDefines.h:3427
Definition ObjectMgr.h:193
float Orientation
Definition ObjectMgr.h:253
uint32 Flags
Definition ObjectMgr.h:210
struct ScriptInfo::@270::@273 Talk
ScriptsType type
Definition ObjectMgr.h:194
uint32 QuestID
Definition ObjectMgr.h:258
struct ScriptInfo::@270::@280 KillCredit
struct ScriptInfo::@270::@287 CreateItem
int32 TextID
Definition ObjectMgr.h:211
struct ScriptInfo::@270::@278 TeleportTo
float DestX
Definition ObjectMgr.h:232
uint32 ItemEntry
Definition ObjectMgr.h:319
struct ScriptInfo::@270::@285 CastSpell
uint32 ChatType
Definition ObjectMgr.h:209
uint32 id
Definition ObjectMgr.h:195
struct ScriptInfo::@270::@272 Raw
uint32 delay
Definition ObjectMgr.h:196
float fData[4]
Definition ObjectMgr.h:204
float PosY
Definition ObjectMgr.h:281
ScriptCommands command
Definition ObjectMgr.h:197
float DestY
Definition ObjectMgr.h:233
uint32 MapID
Definition ObjectMgr.h:246
uint32 nData[3]
Definition ObjectMgr.h:203
float PosZ
Definition ObjectMgr.h:282
struct ScriptInfo::@270::@284 RemoveAura
struct ScriptInfo::@270::@282 TempSummonCreature
float PosX
Definition ObjectMgr.h:280
uint32 Distance
Definition ObjectMgr.h:259
uint32 SpellID
Definition ObjectMgr.h:297
float DestZ
Definition ObjectMgr.h:234
struct ScriptInfo::@270::@279 QuestExplored
struct ScriptInfo::@270::@283 ToggleDoor
struct ScriptInfo::@270::@281 RespawnGameobject
uint32 GOGuid
Definition ObjectMgr.h:270
uint32 CreatureEntry
Definition ObjectMgr.h:264
uint32 Amount
Definition ObjectMgr.h:320
struct ScriptInfo::@270::@274 Emote
uint32 EmoteID
Definition ObjectMgr.h:216

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().

◆ LoadSpawnGroups()

void ObjectMgr::LoadSpawnGroups ( )
8847{
8848 uint32 oldMSTime = getMSTime();
8849
8850 // Reset prior state for hot-reload support
8851 // Preserve the forced legacy group for spawns on transport maps (set in LoadCreatures/LoadGameobjects).
8852 _spawnGroupMapStore.clear();
8853 for (auto& [id, data] : _creatureDataStore)
8854 data.spawnGroupId = _transportMaps.count(data.mapid) ? 1 : 0;
8855 for (auto& [id, data] : _gameObjectDataStore)
8856 data.spawnGroupId = _transportMaps.count(data.mapid) ? 1 : 0;
8857
8858 // 0 1 2
8859 QueryResult result = WorldDatabase.Query("SELECT groupId, spawnType, spawnId FROM spawn_group");
8860
8861 if (!result)
8862 {
8863 LOG_INFO("server.loading", ">> Loaded 0 spawn group members. DB table `spawn_group` is empty.");
8864 LOG_INFO("server.loading", " ");
8865 return;
8866 }
8867
8868 uint32 numMembers = 0;
8869 do
8870 {
8871 Field* fields = result->Fetch();
8872 uint32 groupId = fields[0].Get<uint32>();
8873 uint32 type = fields[1].Get<uint8>();
8874 if (type >= SPAWN_TYPE_MAX)
8875 {
8876 LOG_ERROR("sql.sql", "Spawn data with invalid type {} listed for spawn group {}. Skipped.", type, groupId);
8877 continue;
8878 }
8879 SpawnObjectType spawnType = SpawnObjectType(type);
8880 ObjectGuid::LowType spawnId = fields[2].Get<uint32>();
8881
8882 SpawnData const* data = GetSpawnData(spawnType, spawnId);
8883 if (!data)
8884 {
8885 LOG_ERROR("sql.sql", "Spawn data with ID ({},{}) not found, but is listed as a member of spawn group {}!",
8886 uint32(spawnType), spawnId, groupId);
8887 continue;
8888 }
8889 if (data->spawnGroupId)
8890 {
8891 LOG_ERROR("sql.sql", "Spawn with ID ({},{}) is listed as a member of spawn group {}, but is already a member of spawn group {}. Skipping.",
8892 uint32(spawnType), spawnId, groupId, data->spawnGroupId);
8893 continue;
8894 }
8895
8896 auto it = _spawnGroupDataStore.find(groupId);
8897 if (it == _spawnGroupDataStore.end())
8898 {
8899 LOG_ERROR("sql.sql", "Spawn group {} assigned to spawn ID ({},{}), but group is not found!", groupId, uint32(spawnType), spawnId);
8900 continue;
8901 }
8902
8903 SpawnGroupTemplateData& groupTemplate = it->second;
8904 if (groupTemplate.mapId == SPAWNGROUP_MAP_UNSET)
8905 groupTemplate.mapId = data->mapid;
8906 else if (groupTemplate.mapId != data->mapid && !(groupTemplate.flags & SPAWNGROUP_FLAG_SYSTEM))
8907 {
8908 LOG_ERROR("sql.sql", "Spawn group {} has map ID {}, but spawn ({},{}) has map id {} - spawn NOT added to group!",
8909 groupId, groupTemplate.mapId, uint32(spawnType), spawnId, data->mapid);
8910 continue;
8911 }
8912
8913 // Warn if spawn is also in a pool (non-system groups and pools are mutually exclusive)
8914 if (!(groupTemplate.flags & SPAWNGROUP_FLAG_SYSTEM))
8915 {
8916 uint32 poolId = 0;
8917 if (spawnType == SPAWN_TYPE_CREATURE)
8918 poolId = sPoolMgr->IsPartOfAPool<Creature>(spawnId);
8919 else if (spawnType == SPAWN_TYPE_GAMEOBJECT)
8920 poolId = sPoolMgr->IsPartOfAPool<GameObject>(spawnId);
8921
8922 if (poolId)
8923 LOG_WARN("sql.sql", "Spawn ({},{}) is a member of spawn group {} and also part of pool {}. This may cause issues!",
8924 uint32(spawnType), spawnId, groupId, poolId);
8925 }
8926
8927 const_cast<SpawnData*>(data)->spawnGroupId = groupId;
8928 if (!(groupTemplate.flags & SPAWNGROUP_FLAG_SYSTEM))
8929 _spawnGroupMapStore.emplace(groupId, data);
8930 ++numMembers;
8931 } while (result->NextRow());
8932
8933 LOG_INFO("server.loading", ">> Loaded {} spawn group members in {} ms", numMembers, GetMSTimeDiffToNow(oldMSTime));
8934 LOG_INFO("server.loading", " ");
8935}
SpawnObjectType
Definition SpawnData.h:26
@ SPAWN_TYPE_MAX
Definition SpawnData.h:30
SpawnData const * GetSpawnData(SpawnObjectType type, ObjectGuid::LowType spawnId) const
Definition ObjectMgr.cpp:8775
Definition SpawnData.h:66
Definition SpawnData.h:58
SpawnGroupFlags flags
Definition SpawnData.h:62
uint32 mapId
Definition SpawnData.h:61

References _creatureDataStore, _gameObjectDataStore, _spawnGroupDataStore, _spawnGroupMapStore, _transportMaps, SpawnGroupTemplateData::flags, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), GetSpawnData(), LOG_ERROR, LOG_INFO, LOG_WARN, SpawnGroupTemplateData::mapId, SPAWN_TYPE_CREATURE, SPAWN_TYPE_GAMEOBJECT, SPAWN_TYPE_MAX, SPAWNGROUP_FLAG_SYSTEM, SPAWNGROUP_MAP_UNSET, sPoolMgr, and WorldDatabase.

◆ LoadSpawnGroupTemplates()

void ObjectMgr::LoadSpawnGroupTemplates ( )
8789{
8790 uint32 oldMSTime = getMSTime();
8791
8792 _spawnGroupDataStore.clear();
8793
8794 // 0 1 2
8795 QueryResult result = WorldDatabase.Query("SELECT groupId, groupName, groupFlags FROM spawn_group_template");
8796
8797 if (result)
8798 {
8799 do
8800 {
8801 Field* fields = result->Fetch();
8802 uint32 groupId = fields[0].Get<uint32>();
8804 group.groupId = groupId;
8805 group.name = fields[1].Get<std::string>();
8806 group.mapId = SPAWNGROUP_MAP_UNSET;
8807 uint32 flags = fields[2].Get<uint32>();
8808 if (flags & ~uint32(SPAWNGROUP_FLAG_ALL))
8809 {
8810 flags &= uint32(SPAWNGROUP_FLAG_ALL);
8811 LOG_ERROR("sql.sql", "Invalid spawn group flag {} on group ID {} ({}), reduced to valid flags {}.",
8812 fields[2].Get<uint32>(), groupId, group.name, flags);
8813 }
8814 if ((flags & SPAWNGROUP_FLAG_SYSTEM) && (flags & SPAWNGROUP_FLAG_MANUAL_SPAWN))
8815 {
8816 flags &= ~SPAWNGROUP_FLAG_MANUAL_SPAWN;
8817 LOG_ERROR("sql.sql", "System spawn group {} ({}) has invalid manual spawn flag. Ignored.", groupId, group.name);
8818 }
8819 group.flags = SpawnGroupFlags(flags);
8820 } while (result->NextRow());
8821 }
8822
8823 if (_spawnGroupDataStore.find(0) == _spawnGroupDataStore.end())
8824 {
8825 LOG_ERROR("sql.sql", "Default spawn group (index 0) is missing from DB! Manually inserted.");
8827 data.groupId = 0;
8828 data.name = "Default Group";
8831 }
8832 if (_spawnGroupDataStore.find(1) == _spawnGroupDataStore.end())
8833 {
8834 LOG_ERROR("sql.sql", "Default legacy spawn group (index 1) is missing from DB! Manually inserted.");
8836 data.groupId = 1;
8837 data.name = "Legacy Group";
8840 }
8841
8842 LOG_INFO("server.loading", ">> Loaded {} spawn group templates in {} ms", _spawnGroupDataStore.size(), GetMSTimeDiffToNow(oldMSTime));
8843 LOG_INFO("server.loading", " ");
8844}
@ SPAWNGROUP_FLAG_ALL
Definition SpawnData.h:50
@ SPAWNGROUP_FLAG_MANUAL_SPAWN
Definition SpawnData.h:46
std::string name
Definition SpawnData.h:60
uint32 groupId
Definition SpawnData.h:59

References _spawnGroupDataStore, SpawnGroupTemplateData::flags, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), SpawnGroupTemplateData::groupId, LOG_ERROR, LOG_INFO, SpawnGroupTemplateData::mapId, SpawnGroupTemplateData::name, SPAWNGROUP_FLAG_ALL, SPAWNGROUP_FLAG_COMPATIBILITY_MODE, SPAWNGROUP_FLAG_MANUAL_SPAWN, SPAWNGROUP_FLAG_SYSTEM, SPAWNGROUP_MAP_UNSET, and WorldDatabase.

◆ LoadSpellScriptNames()

void ObjectMgr::LoadSpellScriptNames ( )
6340{
6341 uint32 oldMSTime = getMSTime();
6342
6343 _spellScriptsStore.clear(); // need for reload case
6344
6345 QueryResult result = WorldDatabase.Query("SELECT spell_id, ScriptName FROM spell_script_names");
6346
6347 if (!result)
6348 {
6349 LOG_WARN("server.loading", ">> Loaded 0 spell script names. DB table `spell_script_names` is empty!");
6350 LOG_INFO("server.loading", " ");
6351 return;
6352 }
6353
6354 uint32 count = 0;
6355
6356 do
6357 {
6358 Field* fields = result->Fetch();
6359
6360 int32 spellId = fields[0].Get<int32>();
6361 std::string scriptName = fields[1].Get<std::string>();
6362
6363 bool allRanks = false;
6364 if (spellId <= 0)
6365 {
6366 allRanks = true;
6367 spellId = -spellId;
6368 }
6369
6370 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
6371 if (!spellInfo)
6372 {
6373 LOG_ERROR("sql.sql", "Scriptname: `{}` spell (spell_id:{}) does not exist in `Spell.dbc`.", scriptName, fields[0].Get<int32>());
6374 continue;
6375 }
6376
6377 if (allRanks)
6378 {
6379 if (sSpellMgr->GetFirstSpellInChain(spellId) != uint32(spellId))
6380 {
6381 LOG_ERROR("sql.sql", "Scriptname: `{}` spell (spell_id:{}) is not first rank of spell.", scriptName, fields[0].Get<int32>());
6382 continue;
6383 }
6384 while (spellInfo)
6385 {
6386 _spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, GetScriptId(scriptName)));
6387 spellInfo = spellInfo->GetNextRankSpell();
6388 }
6389 }
6390 else
6391 _spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, GetScriptId(scriptName)));
6392 ++count;
6393 } while (result->NextRow());
6394
6395 LOG_INFO("server.loading", ">> Loaded {} spell script names in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6396 LOG_INFO("server.loading", " ");
6397}
SpellInfo const * GetNextRankSpell() const
Definition SpellInfo.cpp:2915

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

◆ LoadSpellScripts()

void ObjectMgr::LoadSpellScripts ( )
6241{
6243
6244 // check ids
6245 for (ScriptMapMap::const_iterator itr = sSpellScripts.begin(); itr != sSpellScripts.end(); ++itr)
6246 {
6247 uint32 spellId = uint32(itr->first) & 0x00FFFFFF;
6248 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
6249
6250 if (!spellInfo)
6251 {
6252 LOG_ERROR("sql.sql", "Table `spell_scripts` has not existing spell (Id: {}) as script id", spellId);
6253 continue;
6254 }
6255
6256 SpellEffIndex i = SpellEffIndex((uint32(itr->first) >> 24) & 0x000000FF);
6257 if (uint32(i) >= MAX_SPELL_EFFECTS)
6258 {
6259 LOG_ERROR("sql.sql", "Table `spell_scripts` has too high effect index {} for spell (Id: {}) as script id", uint32(i), spellId);
6260 }
6261
6262 //check for correct spellEffect
6263 if (!spellInfo->Effects[i].Effect || (spellInfo->Effects[i].Effect != SPELL_EFFECT_SCRIPT_EFFECT && spellInfo->Effects[i].Effect != SPELL_EFFECT_DUMMY))
6264 LOG_ERROR("sql.sql", "Table `spell_scripts` - spell {} effect {} is not SPELL_EFFECT_SCRIPT_EFFECT or SPELL_EFFECT_DUMMY", spellId, uint32(i));
6265 }
6266}
ScriptMapMap sSpellScripts
Definition ObjectMgr.cpp:60
SpellEffIndex
Definition SharedDefines.h:30
@ SPELL_EFFECT_DUMMY
Definition SharedDefines.h:769
@ SPELL_EFFECT_SCRIPT_EFFECT
Definition SharedDefines.h:843

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 ( )
7180{
7181 uint32 oldMSTime = getMSTime();
7182
7183 _tavernAreaTriggerStore.clear(); // need for reload case
7184
7185 QueryResult result = WorldDatabase.Query("SELECT id, faction FROM areatrigger_tavern");
7186
7187 if (!result)
7188 {
7189 LOG_WARN("server.loading", ">> Loaded 0 tavern triggers. DB table `areatrigger_tavern` is empty.");
7190 LOG_INFO("server.loading", " ");
7191 return;
7192 }
7193
7194 uint32 count = 0;
7195
7196 do
7197 {
7198 ++count;
7199
7200 Field* fields = result->Fetch();
7201
7202 uint32 Trigger_ID = fields[0].Get<uint32>();
7203
7204 AreaTrigger const* atEntry = GetAreaTrigger(Trigger_ID);
7205 if (!atEntry)
7206 {
7207 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
7208 continue;
7209 }
7210
7211 uint32 faction = fields[1].Get<uint32>();
7212
7213 _tavernAreaTriggerStore.emplace(Trigger_ID, faction);
7214 } while (result->NextRow());
7215
7216 LOG_INFO("server.loading", ">> Loaded {} Tavern Triggers in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7217 LOG_INFO("server.loading", " ");
7218}

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

◆ LoadTempSummons()

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

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 ( )
10064{
10065 uint32 oldMSTime = getMSTime();
10066
10067 // For reload case
10068 _trainers.clear();
10069 _classTrainers.clear();
10070
10071 std::unordered_map<int32, std::vector<Trainer::Spell>> spellsByTrainer;
10072 if (QueryResult trainerSpellsResult = WorldDatabase.Query("SELECT TrainerId, SpellId, MoneyCost, ReqSkillLine, ReqSkillRank, ReqAbility1, ReqAbility2, ReqAbility3, ReqLevel FROM trainer_spell"))
10073 {
10074 do
10075 {
10076 Field* fields = trainerSpellsResult->Fetch();
10077
10078 Trainer::Spell spell;
10079 uint32 trainerId = fields[0].Get<uint32>();
10080 spell.SpellId = fields[1].Get<uint32>();
10081 spell.MoneyCost = fields[2].Get<uint32>();
10082 spell.ReqSkillLine = fields[3].Get<uint32>();
10083 spell.ReqSkillRank = fields[4].Get<uint32>();
10084 spell.ReqAbility[0] = fields[5].Get<uint32>();
10085 spell.ReqAbility[1] = fields[6].Get<uint32>();
10086 spell.ReqAbility[2] = fields[7].Get<uint32>();
10087 spell.ReqLevel = fields[8].Get<uint8>();
10088
10089 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell.SpellId);
10090 if (!spellInfo)
10091 {
10092 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing spell (SpellId: {}) for TrainerId {}, ignoring", spell.SpellId, trainerId);
10093 continue;
10094 }
10095
10096 if (GetTalentSpellCost(spell.SpellId))
10097 {
10098 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing spell (SpellId: {}) which is a talent, for TrainerId {}, ignoring", spell.SpellId, trainerId);
10099 continue;
10100 }
10101
10102 if (spell.ReqSkillLine && !sSkillLineStore.LookupEntry(spell.ReqSkillLine))
10103 {
10104 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing skill (ReqSkillLine: {}) for TrainerId {} and SpellId {}, ignoring",
10105 spell.ReqSkillLine, spell.SpellId, trainerId);
10106 continue;
10107 }
10108
10109 bool allReqValid = true;
10110 for (std::size_t i = 0; i < spell.ReqAbility.size(); ++i)
10111 {
10112 uint32 requiredSpell = spell.ReqAbility[i];
10113 if (requiredSpell && !sSpellMgr->GetSpellInfo(requiredSpell))
10114 {
10115 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing spell (ReqAbility {} : {}) for TrainerId {} and SpellId {}, ignoring",
10116 i + 1, requiredSpell, trainerId, spell.SpellId);
10117 allReqValid = false;
10118 }
10119 }
10120
10121 if (!allReqValid)
10122 continue;
10123
10124 spellsByTrainer[trainerId].push_back(spell);
10125 } while (trainerSpellsResult->NextRow());
10126 }
10127
10128 if (QueryResult trainersResult = WorldDatabase.Query("SELECT Id, Type, Requirement, Greeting FROM trainer"))
10129 {
10130 do
10131 {
10132 Field* fields = trainersResult->Fetch();
10133
10134 uint32 trainerId = fields[0].Get<uint32>();
10135 Trainer::Type trainerType = Trainer::Type(fields[1].Get<uint8>());
10136 uint32 requirement = fields[2].Get<uint32>();
10137 std::string greeting = fields[3].Get<std::string>();
10138 std::vector<Trainer::Spell> spells;
10139 auto spellsItr = spellsByTrainer.find(trainerId);
10140 if (spellsItr != spellsByTrainer.end())
10141 {
10142 spells = std::move(spellsItr->second);
10143 spellsByTrainer.erase(spellsItr);
10144 }
10145
10146 auto [it, isNew] = _trainers.emplace(std::piecewise_construct, std::forward_as_tuple(trainerId), std::forward_as_tuple(trainerId, trainerType, requirement, std::move(greeting), std::move(spells)));
10147 ASSERT(isNew);
10148 if (trainerType == Trainer::Type::Class)
10149 {
10150 if (!requirement || requirement >= MAX_CLASSES)
10151 LOG_ERROR("sql.sql", "Table `trainer` has invalid class requirement for trainer {}, ignoring");
10152 else
10153 {
10154 uint8 classId = static_cast<uint8>(requirement);
10155 _classTrainers[classId].push_back(&it->second);
10156 }
10157 }
10158 } while (trainersResult->NextRow());
10159 }
10160
10161 for (auto const& unusedSpells : spellsByTrainer)
10162 {
10163 for (Trainer::Spell const& unusedSpell : unusedSpells.second)
10164 {
10165 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing trainer (TrainerId: {}) for SpellId {}, ignoring", unusedSpells.first, unusedSpell.SpellId);
10166 }
10167 }
10168
10169 if (QueryResult trainerLocalesResult = WorldDatabase.Query("SELECT Id, locale, Greeting_lang FROM trainer_locale"))
10170 {
10171 do
10172 {
10173 Field* fields = trainerLocalesResult->Fetch();
10174 uint32 trainerId = fields[0].Get<uint32>();
10175 std::string localeName = fields[1].Get<std::string>();
10176
10177 LocaleConstant locale = GetLocaleByName(localeName);
10178 if (locale == LOCALE_enUS)
10179 continue;
10180
10182 trainer->AddGreetingLocale(locale, fields[2].Get<std::string>());
10183 else
10184 LOG_ERROR("sql.sql", "Table `trainer_locale` references non-existing trainer (TrainerId: {}) for locale %s, ignoring",
10185 trainerId, localeName.c_str());
10186 } while (trainerLocalesResult->NextRow());
10187 }
10188
10189 LOG_INFO("server.loading", ">> Loaded {} Trainers in {} ms", _trainers.size(), GetMSTimeDiffToNow(oldMSTime));
10190}
#define ASSERT
Definition Errors.h:68
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 _classTrainers, _trainers, ASSERT, Trainer::Class, Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), GetTalentSpellCost(), LOCALE_enUS, LOG_ERROR, LOG_INFO, Acore::Containers::MapGetValuePtr(), MAX_CLASSES, 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 ( )
4107{
4108 uint32 oldMSTime = getMSTime();
4109
4110 _vehicleAccessoryStore.clear(); // needed for reload case
4111
4112 uint32 count = 0;
4113
4114 // 0 1 2 3 4 5
4115 QueryResult result = WorldDatabase.Query("SELECT `guid`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer` FROM `vehicle_accessory`");
4116
4117 if (!result)
4118 {
4119 LOG_WARN("server.loading", ">> Loaded 0 Vehicle Accessories in {} ms", GetMSTimeDiffToNow(oldMSTime));
4120 LOG_INFO("server.loading", " ");
4121 return;
4122 }
4123
4124 do
4125 {
4126 Field* fields = result->Fetch();
4127
4128 uint32 uiGUID = fields[0].Get<uint32>();
4129 uint32 uiAccessory = fields[1].Get<uint32>();
4130 int8 uiSeat = int8(fields[2].Get<int16>());
4131 bool bMinion = fields[3].Get<bool>();
4132 uint8 uiSummonType = fields[4].Get<uint8>();
4133 uint32 uiSummonTimer = fields[5].Get<uint32>();
4134
4135 if (!GetCreatureTemplate(uiAccessory))
4136 {
4137 LOG_ERROR("sql.sql", "Table `vehicle_accessory`: Accessory {} does not exist.", uiAccessory);
4138 continue;
4139 }
4140
4141 _vehicleAccessoryStore[uiGUID].push_back(VehicleAccessory(uiAccessory, uiSeat, bMinion, uiSummonType, uiSummonTimer));
4142
4143 ++count;
4144 } while (result->NextRow());
4145
4146 LOG_INFO("server.loading", ">> Loaded {} Vehicle Accessories in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4147 LOG_INFO("server.loading", " ");
4148}
Definition VehicleDefines.h:115

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

◆ LoadVehicleSeatAddon()

void ObjectMgr::LoadVehicleSeatAddon ( )
4151{
4152 uint32 oldMSTime = getMSTime();
4153
4154 _vehicleSeatAddonStore.clear(); // needed for reload case
4155
4156 uint32 count = 0;
4157
4158 // 0 1 2 3 4 5 6
4159 QueryResult result = WorldDatabase.Query("SELECT `SeatEntry`, `SeatOrientation`, `ExitParamX`, `ExitParamY`, `ExitParamZ`, `ExitParamO`, `ExitParamValue` FROM `vehicle_seat_addon`");
4160
4161 if (!result)
4162 {
4163 LOG_ERROR("server.loading", ">> Loaded 0 vehicle seat addons. DB table `vehicle_seat_addon` is empty.");
4164 return;
4165 }
4166
4167 do
4168 {
4169 Field* fields = result->Fetch();
4170
4171 uint32 seatID = fields[0].Get<uint32>();
4172 float orientation = fields[1].Get<float>();
4173 float exitX = fields[2].Get<float>();
4174 float exitY = fields[3].Get<float>();
4175 float exitZ = fields[4].Get<float>();
4176 float exitO = fields[5].Get<float>();
4177 uint8 exitParam = fields[6].Get<uint8>();
4178
4179 if (!sVehicleSeatStore.LookupEntry(seatID))
4180 {
4181 LOG_ERROR("sql.sql", "Table `vehicle_seat_addon`: SeatID: {} does not exist in VehicleSeat.dbc. Skipping entry.", seatID);
4182 continue;
4183 }
4184
4185 // Sanitizing values
4186 if (orientation > float(M_PI * 2))
4187 {
4188 LOG_ERROR("sql.sql", "Table `vehicle_seat_addon`: SeatID: {} is using invalid angle offset value ({}). Set Value to 0.", seatID, orientation);
4189 orientation = 0.0f;
4190 }
4191
4193 {
4194 LOG_ERROR("sql.sql", "Table `vehicle_seat_addon`: SeatID: {} is using invalid exit parameter value ({}). Setting to 0 (none).", seatID, exitParam);
4195 continue;
4196 }
4197
4198 _vehicleSeatAddonStore[seatID] = VehicleSeatAddon(orientation, exitX, exitY, exitZ, exitO, exitParam);
4199
4200 ++count;
4201 } while (result->NextRow());
4202
4203 LOG_INFO("server.loading", ">> Loaded {} Vehicle Seat Addon entries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4204}
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 ( )
4051{
4052 uint32 oldMSTime = getMSTime();
4053
4054 _vehicleTemplateAccessoryStore.clear(); // needed for reload case
4055
4056 uint32 count = 0;
4057
4058 // 0 1 2 3 4 5
4059 QueryResult result = WorldDatabase.Query("SELECT `entry`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer` FROM `vehicle_template_accessory`");
4060
4061 if (!result)
4062 {
4063 LOG_WARN("server.loading", ">> Loaded 0 vehicle template accessories. DB table `vehicle_template_accessory` is empty.");
4064 LOG_INFO("server.loading", " ");
4065 return;
4066 }
4067
4068 do
4069 {
4070 Field* fields = result->Fetch();
4071
4072 uint32 uiEntry = fields[0].Get<uint32>();
4073 uint32 uiAccessory = fields[1].Get<uint32>();
4074 int8 uiSeat = int8(fields[2].Get<int8>());
4075 bool bMinion = fields[3].Get<bool>();
4076 uint8 uiSummonType = fields[4].Get<uint8>();
4077 uint32 uiSummonTimer = fields[5].Get<uint32>();
4078
4079 if (!GetCreatureTemplate(uiEntry))
4080 {
4081 LOG_ERROR("sql.sql", "Table `vehicle_template_accessory`: creature template entry {} does not exist.", uiEntry);
4082 continue;
4083 }
4084
4085 if (!GetCreatureTemplate(uiAccessory))
4086 {
4087 LOG_ERROR("sql.sql", "Table `vehicle_template_accessory`: Accessory {} does not exist.", uiAccessory);
4088 continue;
4089 }
4090
4091 if (_spellClickInfoStore.find(uiEntry) == _spellClickInfoStore.end())
4092 {
4093 LOG_ERROR("sql.sql", "Table `vehicle_template_accessory`: creature template entry {} has no data in npc_spellclick_spells", uiEntry);
4094 continue;
4095 }
4096
4097 _vehicleTemplateAccessoryStore[uiEntry].push_back(VehicleAccessory(uiAccessory, uiSeat, bMinion, uiSummonType, uiSummonTimer));
4098
4099 ++count;
4100 } while (result->NextRow());
4101
4102 LOG_INFO("server.loading", ">> Loaded {} Vehicle Template Accessories in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4103 LOG_INFO("server.loading", " ");
4104}

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

◆ LoadVendors()

void ObjectMgr::LoadVendors ( )
10269{
10270 uint32 oldMSTime = getMSTime();
10271
10272 // For reload case
10273 for (CacheVendorItemContainer::iterator itr = _cacheVendorItemStore.begin(); itr != _cacheVendorItemStore.end(); ++itr)
10274 itr->second.Clear();
10275 _cacheVendorItemStore.clear();
10276
10277 std::set<uint32> skip_vendors;
10278
10279 QueryResult result = WorldDatabase.Query("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor ORDER BY entry, slot ASC, item, ExtendedCost");
10280 if (!result)
10281 {
10282 LOG_INFO("server.loading", " ");
10283 LOG_WARN("server.loading", ">> Loaded 0 Vendors. DB table `npc_vendor` is empty!");
10284 return;
10285 }
10286
10287 uint32 count = 0;
10288
10289 do
10290 {
10291 Field* fields = result->Fetch();
10292
10293 uint32 entry = fields[0].Get<uint32>();
10294 int32 item_id = fields[1].Get<int32>();
10295
10296 // if item is a negative, its a reference
10297 if (item_id < 0)
10298 count += LoadReferenceVendor(entry, -item_id, &skip_vendors);
10299 else
10300 {
10301 uint32 maxcount = fields[2].Get<uint32>();
10302 uint32 incrtime = fields[3].Get<uint32>();
10303 uint32 ExtendedCost = fields[4].Get<uint32>();
10304
10305 if (!IsVendorItemValid(entry, item_id, maxcount, incrtime, ExtendedCost, nullptr, &skip_vendors))
10306 continue;
10307
10308 VendorItemData& vList = _cacheVendorItemStore[entry];
10309
10310 vList.AddItem(item_id, maxcount, incrtime, ExtendedCost);
10311 ++count;
10312 }
10313 } while (result->NextRow());
10314
10315 LOG_INFO("server.loading", ">> Loaded {} Vendors in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10316 LOG_INFO("server.loading", " ");
10317}

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

◆ LoadWaypointScripts()

void ObjectMgr::LoadWaypointScripts ( )
6313{
6315
6316 std::set<uint32> actionSet;
6317
6318 for (ScriptMapMap::const_iterator itr = sWaypointScripts.begin(); itr != sWaypointScripts.end(); ++itr)
6319 actionSet.insert(itr->first);
6320
6322 PreparedQueryResult result = WorldDatabase.Query(stmt);
6323
6324 if (result)
6325 {
6326 do
6327 {
6328 Field* fields = result->Fetch();
6329 uint32 action = fields[0].Get<uint32>();
6330
6331 actionSet.erase(action);
6332 } while (result->NextRow());
6333 }
6334
6335 for (std::set<uint32>::iterator itr = actionSet.begin(); itr != actionSet.end(); ++itr)
6336 LOG_ERROR("sql.sql", "There is no waypoint which links to the waypoint script {}", *itr);
6337}
ScriptMapMap sWaypointScripts
Definition ObjectMgr.cpp:62
@ SCRIPTS_WAYPOINT
Definition ObjectMgr.h:153
@ 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
1361{ return _gameObjectDataStore[guid]; }

References _gameObjectDataStore.

Referenced by AddGOData().

◆ NewOrExistCreatureData()

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

References _creatureDataStore.

Referenced by AddCreData().

◆ OnDeleteSpawnData()

void ObjectMgr::OnDeleteSpawnData ( SpawnData const *  data)
8938{
8939 auto templateIt = _spawnGroupDataStore.find(data->spawnGroupId);
8940 ASSERT(templateIt != _spawnGroupDataStore.end(), "Spawn data is being deleted and has invalid spawn group index {}!", data->spawnGroupId);
8941 if (templateIt->second.flags & SPAWNGROUP_FLAG_SYSTEM)
8942 return;
8943
8944 auto pair = _spawnGroupMapStore.equal_range(data->spawnGroupId);
8945 for (auto it = pair.first; it != pair.second; ++it)
8946 {
8947 if (it->second != data)
8948 continue;
8949 _spawnGroupMapStore.erase(it);
8950 return;
8951 }
8952 ASSERT(false, "Spawn data being removed is member of spawn group {}, but not found in lookup table!", data->spawnGroupId);
8953}

References _spawnGroupDataStore, _spawnGroupMapStore, ASSERT, SPAWNGROUP_FLAG_SYSTEM, and SpawnData::spawnGroupId.

◆ PlayerCreateInfoAddItemHelper()

void ObjectMgr::PlayerCreateInfoAddItemHelper ( uint32  race_,
uint32  class_,
uint32  itemId,
int32  count 
)
private
4312{
4313 if (!_playerInfo[race_][class_])
4314 return;
4315
4316 if (count > 0)
4317 _playerInfo[race_][class_]->item.push_back(PlayerCreateInfoItem(itemId, count));
4318 else
4319 {
4320 if (count < -1)
4321 LOG_ERROR("sql.sql", "Invalid count {} specified on item {} be removed from original player create info (use -1)!", count, itemId);
4322
4323 for (uint32 gender = 0; gender < GENDER_NONE; ++gender)
4324 {
4325 if (CharStartOutfitEntry const* entry = GetCharStartOutfitEntry(race_, class_, gender))
4326 {
4327 bool found = false;
4328 for (uint8 x = 0; x < MAX_OUTFIT_ITEMS; ++x)
4329 {
4330 if (entry->ItemId[x] > 0 && uint32(entry->ItemId[x]) == itemId)
4331 {
4332 found = true;
4333 const_cast<CharStartOutfitEntry*>(entry)->ItemId[x] = 0;
4334 break;
4335 }
4336 }
4337
4338 if (!found)
4339 LOG_ERROR("sql.sql", "Item {} specified to be removed from original create info not found in dbc!", itemId);
4340 }
4341 }
4342 }
4343}
CharStartOutfitEntry const * GetCharStartOutfitEntry(uint8 race, uint8 class_, uint8 gender)
Definition DBCStores.cpp:842
Definition Player.h:266

References _playerInfo, GENDER_NONE, GetCharStartOutfitEntry(), LOG_ERROR, and MAX_OUTFIT_ITEMS.

Referenced by LoadPlayerInfo().

◆ RemoveCreatureFromGrid()

void ObjectMgr::RemoveCreatureFromGrid ( ObjectGuid::LowType  guid,
CreatureData const *  data 
)
2797{
2798 uint8 mask = data->spawnMask;
2799 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
2800 {
2801 if (mask & 1)
2802 {
2803 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
2804 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
2805 cell_guids.creatures.erase(guid);
2806 }
2807 }
2808}

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

Referenced by DeleteCreatureData().

◆ RemoveGameobjectFromGrid()

void ObjectMgr::RemoveGameobjectFromGrid ( ObjectGuid::LowType  guid,
GameObjectData const *  data 
)
3249{
3250 uint8 mask = data->spawnMask;
3251 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
3252 {
3253 if (mask & 1)
3254 {
3255 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
3256 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
3257 cell_guids.gameobjects.erase(guid);
3258 }
3259 }
3260}

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

Referenced by DeleteGOData().

◆ RemoveVendorItem()

bool ObjectMgr::RemoveVendorItem ( uint32  entry,
uint32  item,
bool  persist = true 
)
10470{
10471 CacheVendorItemContainer::iterator iter = _cacheVendorItemStore.find(entry);
10472 if (iter == _cacheVendorItemStore.end())
10473 return false;
10474
10475 if (!iter->second.RemoveItem(item))
10476 return false;
10477
10478 if (persist)
10479 {
10481
10482 stmt->SetData(0, entry);
10483 stmt->SetData(1, item);
10484
10485 WorldDatabase.Execute(stmt);
10486 }
10487
10488 return true;
10489}
@ WORLD_DEL_NPC_VENDOR
Definition WorldDatabase.h:44

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

◆ ReturnOrDeleteOldMails()

void ObjectMgr::ReturnOrDeleteOldMails ( bool  serverUp)
6808{
6809 uint32 oldMSTime = getMSTime();
6810
6811 time_t curTime = GameTime::GetGameTime().count();
6812
6814 stmt->SetData(0, uint32(curTime));
6815 PreparedQueryResult result = CharacterDatabase.Query(stmt);
6816 if (!result)
6817 return;
6818
6819 std::map<uint32 /*messageId*/, MailItemInfoVec> itemsCache;
6820 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_EXPIRED_MAIL_ITEMS);
6821 stmt->SetData(0, uint32(curTime));
6822 if (PreparedQueryResult items = CharacterDatabase.Query(stmt))
6823 {
6824 MailItemInfo item;
6825 do
6826 {
6827 Field* fields = items->Fetch();
6828 item.item_guid = fields[0].Get<uint32>();
6829 item.item_template = fields[1].Get<uint32>();
6830 uint32 mailId = fields[2].Get<uint32>();
6831 itemsCache[mailId].push_back(item);
6832 } while (items->NextRow());
6833 }
6834
6835 uint32 deletedCount = 0;
6836 uint32 returnedCount = 0;
6837 do
6838 {
6839 Field* fields = result->Fetch();
6840 Mail* m = new Mail;
6841 m->messageID = fields[0].Get<uint32>();
6842 m->messageType = fields[1].Get<uint8>();
6843 m->sender = fields[2].Get<uint32>();
6844 m->receiver = fields[3].Get<uint32>();
6845 bool has_items = fields[4].Get<bool>();
6846 m->expire_time = time_t(fields[5].Get<uint32>());
6847 m->deliver_time = time_t(0);
6848 m->stationery = fields[6].Get<uint8>();
6849 m->checked = fields[7].Get<uint8>();
6850 m->mailTemplateId = fields[8].Get<int16>();
6851
6852 Player* player = nullptr;
6853 if (serverUp)
6855
6856 if (player) // don't modify mails of a logged in player
6857 {
6858 delete m;
6859 continue;
6860 }
6861
6862 // Delete or return mail
6863 if (has_items)
6864 {
6865 // read items from cache
6866 m->items.swap(itemsCache[m->messageID]);
6867
6868 // If it is mail from non-player, or if it's already return mail, it shouldn't be returned, but deleted
6869 if (!m->IsSentByPlayer() || m->IsSentByGM() || (m->IsCODPayment() || m->IsReturnedMail()))
6870 {
6871 for (auto const& mailedItem : m->items)
6872 {
6873 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE);
6874 stmt->SetData(0, mailedItem.item_guid);
6875 CharacterDatabase.Execute(stmt);
6876 }
6877
6878 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID);
6879 stmt->SetData(0, m->messageID);
6880 CharacterDatabase.Execute(stmt);
6881 }
6882 else
6883 {
6884 // Mail will be returned
6885 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_MAIL_RETURNED);
6886 stmt->SetData(0, m->receiver);
6887 stmt->SetData(1, m->sender);
6888 stmt->SetData(2, uint32(curTime + 30 * DAY));
6889 stmt->SetData(3, uint32(curTime));
6891 stmt->SetData(5, m->messageID);
6892 CharacterDatabase.Execute(stmt);
6893 for (auto const& mailedItem : m->items)
6894 {
6895 // Update receiver in mail items for its proper delivery, and in instance_item for avoid lost item at sender delete
6896 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_MAIL_ITEM_RECEIVER);
6897 stmt->SetData(0, m->sender);
6898 stmt->SetData(1, mailedItem.item_guid);
6899 CharacterDatabase.Execute(stmt);
6900
6901 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_OWNER);
6902 stmt->SetData(0, m->sender);
6903 stmt->SetData(1, mailedItem.item_guid);
6904 CharacterDatabase.Execute(stmt);
6905 }
6906
6907 // xinef: update global data
6908 sCharacterCache->IncreaseCharacterMailCount(ObjectGuid(HighGuid::Player, m->sender));
6909 sCharacterCache->DecreaseCharacterMailCount(ObjectGuid(HighGuid::Player, m->receiver));
6910
6911 delete m;
6912 ++returnedCount;
6913 continue;
6914 }
6915 }
6916
6917 sCharacterCache->DecreaseCharacterMailCount(ObjectGuid(HighGuid::Player, m->receiver));
6918
6919 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_BY_ID);
6920 stmt->SetData(0, m->messageID);
6921 CharacterDatabase.Execute(stmt);
6922 delete m;
6923 ++deletedCount;
6924 } while (result->NextRow());
6925
6926 LOG_INFO("server.loading", ">> Processed {} expired mails: {} deleted and {} returned in {} ms", deletedCount + returnedCount, deletedCount, returnedCount, GetMSTimeDiffToNow(oldMSTime));
6927 LOG_INFO("server.loading", " ");
6928}
#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:384
@ 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:1084
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 
)
2107{
2108 if (!guidLow)
2109 return false;
2110
2111 CreatureData const* master = GetCreatureData(guidLow);
2112 ObjectGuid guid = ObjectGuid::Create<HighGuid::Unit>(master->id, guidLow);
2113
2114 if (!linkedGuidLow) // we're removing the linking
2115 {
2116 _linkedRespawnStore.erase(guid);
2118 stmt->SetData(0, guidLow);
2119 WorldDatabase.Execute(stmt);
2120 return true;
2121 }
2122
2123 CreatureData const* slave = GetCreatureData(linkedGuidLow);
2124 if (!slave)
2125 {
2126 LOG_ERROR("sql.sql", "Creature '{}' linking to non-existent creature '{}'.", guidLow, linkedGuidLow);
2127 return false;
2128 }
2129
2130 MapEntry const* map = sMapStore.LookupEntry(master->mapid);
2131 if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
2132 {
2133 LOG_ERROR("sql.sql", "Creature '{}' linking to '{}' on an unpermitted map.", guidLow, linkedGuidLow);
2134 return false;
2135 }
2136
2137 if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
2138 {
2139 LOG_ERROR("sql.sql", "LinkedRespawn: Creature '{}' linking to '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
2140 return false;
2141 }
2142
2143 ObjectGuid linkedGuid = ObjectGuid::Create<HighGuid::Unit>(slave->id, linkedGuidLow);
2144
2145 _linkedRespawnStore[guid] = linkedGuid;
2147 stmt->SetData(0, guidLow);
2148 stmt->SetData(1, linkedGuidLow);
2149 WorldDatabase.Execute(stmt);
2150 return true;
2151}
@ WORLD_REP_CREATURE_LINKED_RESPAWN
Definition WorldDatabase.h:33
@ WORLD_DEL_CRELINKED_RESPAWN
Definition WorldDatabase.h:32

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

◆ SetDBCLocaleIndex()

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

References DBCLocaleIndex.

◆ SetHighestGuids()

void ObjectMgr::SetHighestGuids ( )
7695{
7696 QueryResult result = CharacterDatabase.Query("SELECT MAX(guid) FROM characters");
7697 if (result)
7698 GetGuidSequenceGenerator<HighGuid::Player>().Set((*result)[0].Get<uint32>() + 1);
7699
7700 result = CharacterDatabase.Query("SELECT MAX(guid) FROM item_instance");
7701 if (result)
7702 GetGuidSequenceGenerator<HighGuid::Item>().Set((*result)[0].Get<uint32>() + 1);
7703
7704 // Cleanup other tables from not existed guids ( >= _hiItemGuid)
7705 CharacterDatabase.Execute("DELETE FROM character_inventory WHERE item >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7706 CharacterDatabase.Execute("DELETE FROM mail_items WHERE item_guid >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7707 CharacterDatabase.Execute("DELETE FROM auctionhouse WHERE itemguid >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7708 CharacterDatabase.Execute("DELETE FROM guild_bank_item WHERE item_guid >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7709
7710 result = WorldDatabase.Query("SELECT MAX(guid) FROM transports");
7711 if (result)
7712 GetGuidSequenceGenerator<HighGuid::Mo_Transport>().Set((*result)[0].Get<uint32>() + 1);
7713
7714 result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse");
7715 if (result)
7716 _auctionId = (*result)[0].Get<uint32>() + 1;
7717
7718 result = CharacterDatabase.Query("SELECT MAX(id) FROM mail");
7719 if (result)
7720 _mailId = (*result)[0].Get<uint32>() + 1;
7721
7722 result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team");
7723 if (result)
7724 sArenaTeamMgr->SetNextArenaTeamId((*result)[0].Get<uint32>() + 1);
7725
7726 result = CharacterDatabase.Query("SELECT MAX(fight_id) FROM log_arena_fights");
7727 if (result)
7728 sArenaTeamMgr->SetLastArenaLogId((*result)[0].Get<uint32>());
7729
7730 result = CharacterDatabase.Query("SELECT MAX(setguid) FROM character_equipmentsets");
7731 if (result)
7732 _equipmentSetGuid = (*result)[0].Get<uint64>() + 1;
7733
7734 result = CharacterDatabase.Query("SELECT MAX(guildId) FROM guild");
7735 if (result)
7736 sGuildMgr->SetNextGuildId((*result)[0].Get<uint32>() + 1);
7737
7738 result = WorldDatabase.Query("SELECT MAX(guid) FROM creature");
7739 if (result)
7740 _creatureSpawnId = (*result)[0].Get<uint32>() + 1;
7741
7742 result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject");
7743 if (result)
7744 _gameObjectSpawnId = (*result)[0].Get<uint32>() + 1;
7745}
#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 ( )
6400{
6401 uint32 oldMSTime = getMSTime();
6402
6403 if (_spellScriptsStore.empty())
6404 {
6405 LOG_INFO("server.loading", ">> Validated 0 scripts.");
6406 LOG_INFO("server.loading", " ");
6407 return;
6408 }
6409
6410 uint32 count = 0;
6411
6412 for (SpellScriptsContainer::iterator itr = _spellScriptsStore.begin(); itr != _spellScriptsStore.end();)
6413 {
6414 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
6415 std::vector<std::pair<SpellScriptLoader*, SpellScriptsContainer::iterator> > SpellScriptLoaders;
6416 sScriptMgr->CreateSpellScriptLoaders(itr->first, SpellScriptLoaders);
6417 itr = _spellScriptsStore.upper_bound(itr->first);
6418
6419 for (std::vector<std::pair<SpellScriptLoader*, SpellScriptsContainer::iterator> >::iterator sitr = SpellScriptLoaders.begin(); sitr != SpellScriptLoaders.end(); ++sitr)
6420 {
6421 SpellScript* spellScript = sitr->first->GetSpellScript();
6422 AuraScript* auraScript = sitr->first->GetAuraScript();
6423 bool valid = true;
6424 if (!spellScript && !auraScript)
6425 {
6426 LOG_ERROR("sql.sql", "Functions GetSpellScript() and GetAuraScript() of script `{}` do not return objects - script skipped", GetScriptName(sitr->second->second));
6427 valid = false;
6428 }
6429 if (spellScript)
6430 {
6431 spellScript->_Init(&sitr->first->GetName(), spellInfo->Id);
6432 spellScript->_Register();
6433 if (!spellScript->_Validate(spellInfo))
6434 valid = false;
6435 delete spellScript;
6436 }
6437 if (auraScript)
6438 {
6439 auraScript->_Init(&sitr->first->GetName(), spellInfo->Id);
6440 auraScript->_Register();
6441 if (!auraScript->_Validate(spellInfo))
6442 valid = false;
6443 delete auraScript;
6444 }
6445 if (!valid)
6446 {
6447 _spellScriptsStore.erase(sitr->second);
6448 }
6449 }
6450 ++count;
6451 }
6452
6453 LOG_INFO("server.loading", ">> Validated {} scripts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6454 LOG_INFO("server.loading", " ");
6455}
Definition SpellScript.h:518
bool _Validate(SpellInfo const *entry) override
Definition SpellScript.cpp:662
std::string const & GetScriptName(uint32 id) const
Definition ObjectMgr.cpp:10627
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

◆ _chatFilterAutomaton

std::unique_ptr<Acore::AhoCorasick<wchar_t> > ObjectMgr::_chatFilterAutomaton
private

Referenced by IsChatFiltered(), and LoadChatFilter().

◆ _classTrainers

std::unordered_map<uint8, std::vector<Trainer::Trainer const*> > ObjectMgr::_classTrainers
private

Referenced by GetClassTrainers(), and LoadTrainers().

◆ _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().

◆ _goSummonDataStore

GameObjectSummonDataContainer ObjectMgr::_goSummonDataStore
private

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

Referenced by GetGameObjectSummonGroup(), and LoadGameObjectSummons().

◆ _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

std::vector<std::vector<PlayerInfo*> > ObjectMgr::_playerInfo
private

◆ _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

◆ _spawnGroupDataStore

◆ _spawnGroupMapStore

SpawnGroupLinkContainer ObjectMgr::_spawnGroupMapStore
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: