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
 
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 (std::vector< std::string > const &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 
1706 {
1708 CREATURE_TO_GO, // Creature is dependant on GO
1709 GO_TO_GO,
1710 GO_TO_CREATURE, // GO is dependant on creature
1711 };
@ CREATURE_TO_GO
Definition ObjectMgr.h:1708
@ CREATURE_TO_CREATURE
Definition ObjectMgr.h:1707
@ GO_TO_GO
Definition ObjectMgr.h:1709
@ GO_TO_CREATURE
Definition ObjectMgr.h:1710

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:126
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:1672
ObjectGuid::LowType _gameObjectSpawnId
Definition ObjectMgr.h:1539
uint32 _mailId
Definition ObjectMgr.h:1533
ObjectGuid::LowType _creatureSpawnId
Definition ObjectMgr.h:1538
LocaleConstant DBCLocaleIndex
Definition ObjectMgr.h:1609
PlayerClassInfo * _playerClassInfo[MAX_CLASSES]
Definition ObjectMgr.h:1629
uint64 _equipmentSetGuid
Definition ObjectMgr.h:1532
uint32 _auctionId
Definition ObjectMgr.h:1531
uint32 _hiPetNumber
Definition ObjectMgr.h:1535

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:1633
PetLevelInfoContainer _petInfoStore
Definition ObjectMgr.h:1627
QuestMap _questTemplates
Definition ObjectMgr.h:1554
DungeonProgressionRequirementsContainer _accessRequirementStore
Definition ObjectMgr.h:1568
DungeonEncounterContainer _dungeonEncounterStore
Definition ObjectMgr.h:1569
CacheVendorItemContainer _cacheVendorItemStore
Definition ObjectMgr.h:1697
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 
)
2784{
2785 uint8 mask = data->spawnMask;
2786 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
2787 {
2788 if (mask & 1)
2789 {
2790 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
2791 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
2792 cell_guids.creatures.insert(guid);
2793 }
2794 }
2795}
uint32 MAKE_PAIR32(uint16 l, uint16 h)
Definition ObjectDefines.h:88
MapObjectGuids _mapObjectGuidsStore
Definition ObjectMgr.h:1654
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 
)
2865{
2866 CreatureTemplate const* cInfo = GetCreatureTemplate(entry);
2867 if (!cInfo)
2868 return 0;
2869
2870 uint32 level = cInfo->minlevel == cInfo->maxlevel ? cInfo->minlevel : urand(cInfo->minlevel, cInfo->maxlevel); // Only used for extracting creature base stats
2871 CreatureBaseStats const* stats = GetCreatureBaseStats(level, cInfo->unit_class);
2872 Map* map = sMapMgr->CreateBaseMap(mapId);
2873 if (!map)
2874 return 0;
2875
2877 CreatureData& data = NewOrExistCreatureData(spawnId);
2878 data.spawnId = spawnId;
2879 data.spawnMask = spawnId;
2880 data.id = entry;
2881 data.id2 = 0;
2882 data.id3 = 0;
2883 data.mapid = mapId;
2884 data.displayid = 0;
2885 data.equipmentId = 0;
2886 data.posX = x;
2887 data.posY = y;
2888 data.posZ = z;
2889 data.orientation = o;
2890 data.spawntimesecs = spawntimedelay;
2891 data.wander_distance = 0;
2892 data.currentwaypoint = 0;
2893 data.curhealth = stats->GenerateHealth(cInfo);
2894 data.curmana = stats->GenerateMana(cInfo);
2895 data.movementType = cInfo->MovementType;
2896 data.spawnMask = 1;
2898 data.dbData = false;
2899 data.npcflag = cInfo->npcflag;
2900 data.unit_flags = cInfo->unit_flags;
2901 data.dynamicflags = cInfo->dynamicflags;
2902
2903 AddCreatureToGrid(spawnId, &data);
2904
2905 // Spawn if necessary (loaded grids only)
2906 if (!map->Instanceable() && map->IsGridLoaded(x, y))
2907 {
2908 Creature* creature = new Creature();
2909 if (!creature->LoadCreatureFromDB(spawnId, map, true, true))
2910 {
2911 LOG_ERROR("sql.sql", "AddCreature: Cannot add creature entry {} to map", entry);
2912 delete creature;
2913 return 0;
2914 }
2915 }
2916
2917 return spawnId;
2918}
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:168
bool IsGridLoaded(GridCoord const &gridCoord) const
Definition Map.cpp:206
bool Instanceable() const
Definition Map.h:298
uint32 LowType
Definition ObjectGuid.h:125
CreatureBaseStats const * GetCreatureBaseStats(uint8 level, uint8 unitClass)
Definition ObjectMgr.cpp:10651
void AddCreatureToGrid(ObjectGuid::LowType guid, CreatureData const *data)
Definition ObjectMgr.cpp:2783
ObjectGuid::LowType GenerateCreatureSpawnId()
Definition ObjectMgr.cpp:7656
CreatureData & NewOrExistCreatureData(ObjectGuid::LowType spawnId)
Definition ObjectMgr.h:1244
CreatureTemplate const * GetCreatureTemplate(uint32 entry)
Definition ObjectMgr.cpp:11016
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 
)
3236{
3237 uint8 mask = data->spawnMask;
3238 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
3239 {
3240 if (mask & 1)
3241 {
3242 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
3243 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
3244 cell_guids.gameobjects.insert(guid);
3245 }
3246 }
3247}
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)
9821{
9822 // find max id
9823 uint32 new_id = 0;
9824 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9825 if (itr->first > new_id)
9826 new_id = itr->first;
9827
9828 // use next
9829 ++new_id;
9830
9831 if (!Utf8toWStr(tele.name, tele.wnameLow))
9832 return false;
9833
9834 wstrToLower(tele.wnameLow);
9835
9836 _gameTeleStore[new_id] = tele;
9837
9839
9840 stmt->SetData(0, new_id);
9841 stmt->SetData(1, tele.position_x);
9842 stmt->SetData(2, tele.position_y);
9843 stmt->SetData(3, tele.position_z);
9844 stmt->SetData(4, tele.orientation);
9845 stmt->SetData(5, uint16(tele.mapId));
9846 stmt->SetData(6, tele.name);
9847
9848 WorldDatabase.Execute(stmt);
9849
9850 return true;
9851}
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:42
GameTeleContainer _gameTeleStore
Definition ObjectMgr.h:1597
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 
)
2812{
2813 GameObjectTemplate const* goinfo = GetGameObjectTemplate(entry);
2814 if (!goinfo)
2815 return 0;
2816
2817 Map* map = sMapMgr->CreateBaseMap(mapId);
2818 if (!map)
2819 return 0;
2820
2822
2823 GameObjectData& data = NewGOData(spawnId);
2824 data.spawnId = spawnId;
2825 data.id = entry;
2826 data.mapid = mapId;
2827 data.posX = x;
2828 data.posY = y;
2829 data.posZ = z;
2830 data.orientation = o;
2831 data.rotation.x = rotation0;
2832 data.rotation.y = rotation1;
2833 data.rotation.z = rotation2;
2834 data.rotation.w = rotation3;
2835 data.spawntimesecs = spawntimedelay;
2836 data.animprogress = 100;
2837 data.spawnMask = 1;
2838 data.go_state = GO_STATE_READY;
2840 data.artKit = goinfo->type == GAMEOBJECT_TYPE_CAPTURE_POINT ? 21 : 0;
2841 data.dbData = false;
2842 data.spawnGroupId = 0;
2843
2844 AddGameobjectToGrid(spawnId, &data);
2845
2846 // Spawn if necessary (loaded grids only)
2847 // We use spawn coords to spawn
2848 if (!map->Instanceable() && map->IsGridLoaded(x, y))
2849 {
2851 if (!go->LoadGameObjectFromDB(spawnId, map))
2852 {
2853 LOG_ERROR("sql.sql", "AddGOData: cannot add gameobject entry {} to map", entry);
2854 delete go;
2855 return 0;
2856 }
2857 }
2858
2859 LOG_DEBUG("maps", "AddGOData: spawnId {} entry {} map {} x {} y {} z {} o {}", spawnId, entry, mapId, x, y, z, o);
2860
2861 return spawnId;
2862}
@ 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:1102
void AddGameobjectToGrid(ObjectGuid::LowType guid, GameObjectData const *data)
Definition ObjectMgr.cpp:3235
GameObjectTemplate const * GetGameObjectTemplate(uint32 entry)
Definition ObjectMgr.cpp:10992
ObjectGuid::LowType GenerateGameObjectSpawnId()
Definition ObjectMgr.cpp:7666
GameObjectData & NewGOData(ObjectGuid::LowType guid)
Definition ObjectMgr.h:1359
bool IsGameObjectStaticTransport(uint32 entry)
Definition ObjectMgr.cpp:11001
Definition Transport.h:120
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)
9121{
9122 if (!IsProfanityName(name))
9123 {
9124 std::wstring wstr;
9125 if (!Utf8toWStr(name, wstr))
9126 {
9127 LOG_ERROR("server", "Could not add invalid name to profanity player names: {}", name);
9128 return;
9129 }
9130 wstrToLower(wstr);
9131
9132 _profanityNamesStore.insert(wstr);
9133
9135 stmt->SetData(0, name);
9136 CharacterDatabase.Execute(stmt);
9137 }
9138}
@ CHAR_INS_PROFANITY_PLAYER_NAME
Definition CharacterDatabase.h:529
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition DatabaseEnv.cpp:21
ProfanityNamesContainer _profanityNamesStore
Definition ObjectMgr.h:1592
bool IsProfanityName(std::string_view name) const
Definition ObjectMgr.cpp:9105

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

◆ AddReservedPlayerName()

void ObjectMgr::AddReservedPlayerName ( std::string const &  name)
9018{
9019 if (!IsReservedName(name))
9020 {
9021 std::wstring wstr;
9022 if (!Utf8toWStr(name, wstr))
9023 {
9024 LOG_ERROR("server", "Could not add invalid name to reserved player names: {}", name);
9025 return;
9026 }
9027 wstrToLower(wstr);
9028
9029 _reservedNamesStore.insert(wstr);
9030
9032 stmt->SetData(0, name);
9033 CharacterDatabase.Execute(stmt);
9034 }
9035}
@ CHAR_INS_RESERVED_PLAYER_NAME
Definition CharacterDatabase.h:528
bool IsReservedName(std::string_view name) const
Definition ObjectMgr.cpp:9002
ReservedNamesContainer _reservedNamesStore
Definition ObjectMgr.h:1588

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 
)
10329{
10330 VendorItemData& vList = _cacheVendorItemStore[entry];
10331 vList.AddItem(item, maxcount, incrtime, extendedCost);
10332
10333 if (persist)
10334 {
10336
10337 stmt->SetData(0, entry);
10338 stmt->SetData(1, item);
10339 stmt->SetData(2, maxcount);
10340 stmt->SetData(3, incrtime);
10341 stmt->SetData(4, extendedCost);
10342
10343 WorldDatabase.Execute(stmt);
10344 }
10345}
@ WORLD_INS_NPC_VENDOR
Definition WorldDatabase.h:44
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
5006{
5007 // base data (last known level)
5008 *info = _playerInfo[race][_class]->levelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) - 1];
5009
5010 // if conversion from uint32 to uint8 causes unexpected behaviour, change lvl to uint32
5011 for (uint8 lvl = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) - 1; lvl < level; ++lvl)
5012 {
5013 switch (_class)
5014 {
5015 case CLASS_WARRIOR:
5016 info->stats[STAT_STRENGTH] += (lvl > 23 ? 2 : (lvl > 1 ? 1 : 0));
5017 info->stats[STAT_STAMINA] += (lvl > 23 ? 2 : (lvl > 1 ? 1 : 0));
5018 info->stats[STAT_AGILITY] += (lvl > 36 ? 1 : (lvl > 6 && (lvl % 2) ? 1 : 0));
5019 info->stats[STAT_INTELLECT] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
5020 info->stats[STAT_SPIRIT] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
5021 break;
5022 case CLASS_PALADIN:
5023 info->stats[STAT_STRENGTH] += (lvl > 3 ? 1 : 0);
5024 info->stats[STAT_STAMINA] += (lvl > 33 ? 2 : (lvl > 1 ? 1 : 0));
5025 info->stats[STAT_AGILITY] += (lvl > 38 ? 1 : (lvl > 7 && !(lvl % 2) ? 1 : 0));
5026 info->stats[STAT_INTELLECT] += (lvl > 6 && (lvl % 2) ? 1 : 0);
5027 info->stats[STAT_SPIRIT] += (lvl > 7 ? 1 : 0);
5028 break;
5029 case CLASS_HUNTER:
5030 info->stats[STAT_STRENGTH] += (lvl > 4 ? 1 : 0);
5031 info->stats[STAT_STAMINA] += (lvl > 4 ? 1 : 0);
5032 info->stats[STAT_AGILITY] += (lvl > 33 ? 2 : (lvl > 1 ? 1 : 0));
5033 info->stats[STAT_INTELLECT] += (lvl > 8 && (lvl % 2) ? 1 : 0);
5034 info->stats[STAT_SPIRIT] += (lvl > 38 ? 1 : (lvl > 9 && !(lvl % 2) ? 1 : 0));
5035 break;
5036 case CLASS_ROGUE:
5037 info->stats[STAT_STRENGTH] += (lvl > 5 ? 1 : 0);
5038 info->stats[STAT_STAMINA] += (lvl > 4 ? 1 : 0);
5039 info->stats[STAT_AGILITY] += (lvl > 16 ? 2 : (lvl > 1 ? 1 : 0));
5040 info->stats[STAT_INTELLECT] += (lvl > 8 && !(lvl % 2) ? 1 : 0);
5041 info->stats[STAT_SPIRIT] += (lvl > 38 ? 1 : (lvl > 9 && !(lvl % 2) ? 1 : 0));
5042 break;
5043 case CLASS_PRIEST:
5044 info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
5045 info->stats[STAT_STAMINA] += (lvl > 5 ? 1 : 0);
5046 info->stats[STAT_AGILITY] += (lvl > 38 ? 1 : (lvl > 8 && (lvl % 2) ? 1 : 0));
5047 info->stats[STAT_INTELLECT] += (lvl > 22 ? 2 : (lvl > 1 ? 1 : 0));
5048 info->stats[STAT_SPIRIT] += (lvl > 3 ? 1 : 0);
5049 break;
5050 case CLASS_SHAMAN:
5051 info->stats[STAT_STRENGTH] += (lvl > 34 ? 1 : (lvl > 6 && (lvl % 2) ? 1 : 0));
5052 info->stats[STAT_STAMINA] += (lvl > 4 ? 1 : 0);
5053 info->stats[STAT_AGILITY] += (lvl > 7 && !(lvl % 2) ? 1 : 0);
5054 info->stats[STAT_INTELLECT] += (lvl > 5 ? 1 : 0);
5055 info->stats[STAT_SPIRIT] += (lvl > 4 ? 1 : 0);
5056 break;
5057 case CLASS_MAGE:
5058 info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
5059 info->stats[STAT_STAMINA] += (lvl > 5 ? 1 : 0);
5060 info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
5061 info->stats[STAT_INTELLECT] += (lvl > 24 ? 2 : (lvl > 1 ? 1 : 0));
5062 info->stats[STAT_SPIRIT] += (lvl > 33 ? 2 : (lvl > 2 ? 1 : 0));
5063 break;
5064 case CLASS_WARLOCK:
5065 info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
5066 info->stats[STAT_STAMINA] += (lvl > 38 ? 2 : (lvl > 3 ? 1 : 0));
5067 info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
5068 info->stats[STAT_INTELLECT] += (lvl > 33 ? 2 : (lvl > 2 ? 1 : 0));
5069 info->stats[STAT_SPIRIT] += (lvl > 38 ? 2 : (lvl > 3 ? 1 : 0));
5070 break;
5071 case CLASS_DRUID:
5072 info->stats[STAT_STRENGTH] += (lvl > 38 ? 2 : (lvl > 6 && (lvl % 2) ? 1 : 0));
5073 info->stats[STAT_STAMINA] += (lvl > 32 ? 2 : (lvl > 4 ? 1 : 0));
5074 info->stats[STAT_AGILITY] += (lvl > 38 ? 2 : (lvl > 8 && (lvl % 2) ? 1 : 0));
5075 info->stats[STAT_INTELLECT] += (lvl > 38 ? 3 : (lvl > 4 ? 1 : 0));
5076 info->stats[STAT_SPIRIT] += (lvl > 38 ? 3 : (lvl > 5 ? 1 : 0));
5077 }
5078 }
5079}
@ 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:195
#define sWorld
Definition World.h:318

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 
)
9640{
9641 AreaTableEntry const* fArea = sAreaTableStore.LookupEntry(entry);
9642 if (!fArea)
9643 {
9644 LOG_ERROR("sql.sql", "AreaId {} defined in `skill_fishing_base_level` does not exist", entry);
9645 return;
9646 }
9647
9648 _fishingBaseForAreaStore[entry] = skill;
9649
9650 LOG_INFO("server.loading", ">> Fishing base skill level of area {} changed to {}", entry, skill);
9651 LOG_INFO("server.loading", " ");
9652}
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
#define LOG_INFO(filterType__,...)
Definition Log.h:153
FishingBaseSkillContainer _fishingBaseForAreaStore
Definition ObjectMgr.h:1642
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:42
static constexpr uint32 MAX_CREATURE_SPELLS
Definition Unit.h:46
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:1702
CreatureCustomIDsContainer _creatureCustomIDsStore
Definition ObjectMgr.h:1659
std::set< uint32 > _hasDifficultyEntries[MAX_DIFFICULTY - 1]
Definition ObjectMgr.h:1703
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
9655{
9656 // get main part of the name
9657 std::wstring mainpart = GetMainPartOfName(w_ownname, 0);
9658 // prepare flags
9659 bool x = true;
9660 bool y = true;
9661
9662 // check declined names
9663 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
9664 {
9665 std::wstring wname;
9666 if (!Utf8toWStr(names.name[i], wname))
9667 return false;
9668
9669 if (mainpart != GetMainPartOfName(wname, i + 1))
9670 x = false;
9671
9672 if (w_ownname != wname)
9673 y = false;
9674 }
9675 return (x || y);
9676}
#define MAX_DECLINED_NAME_CASES
Definition Unit.h:547
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
9360{
9361 std::wstring wname;
9362 if (!Utf8toWStr(name, wname))
9363 return PET_NAME_INVALID;
9364
9365 if (wname.size() > MAX_PET_NAME)
9366 return PET_NAME_TOO_LONG;
9367
9368 uint32 minName = sWorld->getIntConfig(CONFIG_MIN_PET_NAME);
9369 if (wname.size() < minName)
9370 return PET_NAME_TOO_SHORT;
9371
9372 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_PET_NAMES);
9373 if (!isValidString(wname, strictMask, false))
9375
9376 // Check Reserved Name
9377 if (sObjectMgr->IsReservedName(name))
9378 return PET_NAME_RESERVED;
9379
9380 // Check Profanity Name
9381 if (sObjectMgr->IsProfanityName(name))
9382 return PET_NAME_PROFANE;
9383
9384 return PET_NAME_SUCCESS;
9385}
bool isValidString(std::wstring wstr, uint32 strictMask, bool numericOrSpace, bool create=false)
Definition ObjectMgr.cpp:9244
#define sObjectMgr
Definition ObjectMgr.h:1730
#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:182
@ CONFIG_MIN_PET_NAME
Definition WorldConfig.h:185

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
9281{
9282 std::wstring wname;
9283
9284 // Check for invalid characters
9285 if (!Utf8toWStr(name, wname))
9287
9288 // Check for too long name
9289 if (wname.size() > MAX_PLAYER_NAME)
9290 return CHAR_NAME_TOO_LONG;
9291
9292 // Check for too short name
9293 uint32 minName = sWorld->getIntConfig(CONFIG_MIN_PLAYER_NAME);
9294 if (wname.size() < minName)
9295 return CHAR_NAME_TOO_SHORT;
9296
9297 // Check for mixed languages
9298 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_PLAYER_NAMES);
9299 if (!isValidString(wname, strictMask, false, create))
9301
9302 // Check for three consecutive letters
9303 wstrToLower(wname);
9304 for (std::size_t i = 2; i < wname.size(); ++i)
9305 if (wname[i] == wname[i - 1] && wname[i] == wname[i - 2])
9307
9308 // Check Reserved Name
9309 if (sObjectMgr->IsReservedName(name))
9310 return CHAR_NAME_RESERVED;
9311
9312 // Check Profanity Name
9313 if (sObjectMgr->IsProfanityName(name))
9314 return CHAR_NAME_PROFANE;
9315
9316 return CHAR_NAME_SUCCESS;
9317}
#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:179
@ CONFIG_MIN_PLAYER_NAME
Definition WorldConfig.h:183

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)
8634{
8635 // remove mapid*cellid -> guid_set map
8636 CreatureData const* data = GetCreatureData(guid);
8637 if (data)
8638 RemoveCreatureFromGrid(guid, data);
8639
8640 _creatureDataStore.erase(guid);
8641}
CreatureDataContainer _creatureDataStore
Definition ObjectMgr.h:1657
void RemoveCreatureFromGrid(ObjectGuid::LowType guid, CreatureData const *data)
Definition ObjectMgr.cpp:2797
CreatureData const * GetCreatureData(ObjectGuid::LowType spawnId) const
Definition ObjectMgr.h:1235

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

◆ DeleteGameTele()

bool ObjectMgr::DeleteGameTele ( std::string_view  name)
9854{
9855 // explicit name case
9856 std::wstring wname;
9857 if (!Utf8toWStr(name, wname))
9858 return false;
9859
9860 // converting string that we try to find to lower case
9861 wstrToLower(wname);
9862
9863 for (GameTeleContainer::iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9864 {
9865 if (itr->second.wnameLow == wname)
9866 {
9868
9869 stmt->SetData(0, itr->second.name);
9870
9871 WorldDatabase.Execute(stmt);
9872
9873 _gameTeleStore.erase(itr);
9874 return true;
9875 }
9876 }
9877
9878 return false;
9879}
@ WORLD_DEL_GAME_TELE
Definition WorldDatabase.h:43

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

◆ DeleteGOData()

void ObjectMgr::DeleteGOData ( ObjectGuid::LowType  guid)
8644{
8645 // remove mapid*cellid -> guid_set map
8646 GameObjectData const* data = GetGameObjectData(guid);
8647 if (data)
8648 RemoveGameobjectFromGrid(guid, data);
8649
8650 _gameObjectDataStore.erase(guid);
8651}
GameObjectData const * GetGameObjectData(ObjectGuid::LowType spawnId) const
Definition ObjectMgr.h:1270
GameObjectDataContainer _gameObjectDataStore
Definition ObjectMgr.h:1671
void RemoveGameobjectFromGrid(ObjectGuid::LowType guid, GameObjectData const *data)
Definition ObjectMgr.cpp:3249

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

◆ GenerateAuctionID()

uint32 ObjectMgr::GenerateAuctionID ( )
7626{
7627 if (_auctionId >= 0xFFFFFFFE)
7628 {
7629 LOG_ERROR("server.worldserver", "Auctions ids overflow!! Can't continue, shutting down server. ");
7631 }
7632 return _auctionId++;
7633}
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 ( )
7657{
7658 if (_creatureSpawnId >= uint32(0xFFFFFF))
7659 {
7660 LOG_ERROR("server.worldserver", "Creature spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info.");
7662 }
7663 return _creatureSpawnId++;
7664}

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

Referenced by AddCreData().

◆ GenerateEquipmentSetGuid()

uint64 ObjectMgr::GenerateEquipmentSetGuid ( )
7636{
7637 if (_equipmentSetGuid >= uint64(0xFFFFFFFFFFFFFFFELL))
7638 {
7639 LOG_ERROR("server.worldserver", "EquipmentSet guid overflow!! Can't continue, shutting down server. ");
7641 }
7642 return _equipmentSetGuid++;
7643}
std::uint64_t uint64
Definition Define.h:106

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

◆ GenerateGameObjectSpawnId()

uint32 ObjectMgr::GenerateGameObjectSpawnId ( )
7667{
7668 if (_gameObjectSpawnId >= uint32(0xFFFFFF))
7669 {
7670 LOG_ERROR("server.worldserver", "GameObject spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7672 }
7673 return _gameObjectSpawnId++;
7674}

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

Referenced by AddGOData().

◆ GenerateMailID()

uint32 ObjectMgr::GenerateMailID ( )
7646{
7647 if (_mailId >= 0xFFFFFFFE)
7648 {
7649 LOG_ERROR("server.worldserver", "Mail ids overflow!! Can't continue, shutting down server. ");
7651 }
7652 std::lock_guard<std::mutex> guard(_mailIdMutex);
7653 return _mailId++;
7654}
std::mutex _mailIdMutex
Definition ObjectMgr.h:1534

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

◆ GeneratePetName()

std::string ObjectMgr::GeneratePetName ( uint32  entry)
8133{
8134 std::vector<std::string>& list0 = _petHalfName0[entry];
8135 std::vector<std::string>& list1 = _petHalfName1[entry];
8136
8137 if (list0.empty() || list1.empty())
8138 {
8139 CreatureTemplate const* cinfo = GetCreatureTemplate(entry);
8140 char const* petname = GetPetName(cinfo->family, sWorld->GetDefaultDbcLocale());
8141 if (!petname)
8142 return cinfo->Name;
8143
8144 return std::string(petname);
8145 }
8146
8147 return *(list0.begin() + urand(0, list0.size() - 1)) + *(list1.begin() + urand(0, list1.size() - 1));
8148}
char const * GetPetName(uint32 petfamily, uint32 dbclang)
Definition DBCStores.cpp:665
HalfNameContainer _petHalfName1
Definition ObjectMgr.h:1646
HalfNameContainer _petHalfName0
Definition ObjectMgr.h:1645
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 
)
8120{
8121 std::vector<std::string>& list0 = _petHalfLocaleName0[std::make_pair(entry, locale)];
8122 std::vector<std::string>& list1 = _petHalfLocaleName1[std::make_pair(entry, locale)];
8123
8124 if (list0.empty() || list1.empty())
8125 {
8126 return GeneratePetName(entry);
8127 }
8128
8129 return *(list0.begin() + urand(0, list0.size() - 1)) + *(list1.begin() + urand(0, list1.size() - 1));
8130}
HalfNameContainerLocale _petHalfLocaleName0
Definition ObjectMgr.h:1648
HalfNameContainerLocale _petHalfLocaleName1
Definition ObjectMgr.h:1649
std::string GeneratePetName(uint32 entry)
Definition ObjectMgr.cpp:8132

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

◆ GeneratePetNumber()

uint32 ObjectMgr::GeneratePetNumber ( )
8151{
8152 std::lock_guard<std::mutex> guard(_hiPetNumberMutex);
8153 return ++_hiPetNumber;
8154}
std::mutex _hiPetNumberMutex
Definition ObjectMgr.h:1536

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
1389 {
1390 AcoreStringContainer::const_iterator itr = _acoreStringStore.find(entry);
1391 if (itr == _acoreStringStore.end())
1392 return nullptr;
1393
1394 return &itr->second;
1395 }
AcoreStringContainer _acoreStringStore
Definition ObjectMgr.h:1693

References _acoreStringStore.

Referenced by GetAcoreString(), and GetAcoreStringForDBCLocale().

◆ GetAcoreString() [2/2]

std::string ObjectMgr::GetAcoreString ( uint32  entry,
LocaleConstant  locale 
) const
9586{
9587 AcoreString const* as = GetAcoreString(entry);
9588 if (as && !as->Content.empty())
9589 {
9590 if (as->Content.size() > std::size_t(locale) && !as->Content[locale].empty())
9591 return as->Content[locale];
9592
9593 return as->Content[DEFAULT_LOCALE];
9594 }
9595
9596 std::string msg = Acore::StringFormat("No entry for acore_string ({}) in DB.", entry);
9597 LOG_ERROR("sql.sql", msg);
9598 return msg;
9599}
#define DEFAULT_LOCALE
Definition Common.h:139
AcoreString const * GetAcoreString(uint32 entry) const
Definition ObjectMgr.h:1388
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
1397{ return GetAcoreString(entry, DBCLocaleIndex); }

References DBCLocaleIndex, and GetAcoreString().

◆ GetAllAreaTriggerScriptData()

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

References _areaTriggerScriptStore.

◆ GetAllCreatureData()

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

References _creatureDataStore.

◆ GetAllGOData()

GameObjectDataContainer const & ObjectMgr::GetAllGOData ( ) const
inline
1269{ 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:1565

References _areaTriggerStore.

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

◆ GetAreaTriggerScriptId()

uint32 ObjectMgr::GetAreaTriggerScriptId ( uint32  trigger_id)
9679{
9680 AreaTriggerScriptContainer::const_iterator i = _areaTriggerScriptStore.find(trigger_id);
9681 if (i != _areaTriggerScriptStore.end())
9682 return i->second;
9683 return 0;
9684}

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:1566

References _areaTriggerTeleportStore.

◆ GetBaseReputationOf()

int32 ObjectMgr::GetBaseReputationOf ( FactionEntry const *  factionEntry,
uint8  race,
uint8  playerClass 
)
9693{
9694 if (!factionEntry)
9695 return 0;
9696
9697 uint32 raceMask = (1 << (race - 1));
9698 uint32 classMask = (1 << (playerClass - 1));
9699
9700 for (int i = 0; i < 4; i++)
9701 {
9702 if ((!factionEntry->BaseRepClassMask[i] ||
9703 factionEntry->BaseRepClassMask[i] & classMask) &&
9704 (!factionEntry->BaseRepRaceMask[i] ||
9705 factionEntry->BaseRepRaceMask[i] & raceMask))
9706 return factionEntry->BaseRepValue[i];
9707 }
9708
9709 return 0;
9710}

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

◆ GetBaseXP()

uint32 ObjectMgr::GetBaseXP ( uint8  level)
8061{
8062 return _baseXPTable[level] ? _baseXPTable[level] : 0;
8063}
BaseXPContainer _baseXPTable
Definition ObjectMgr.h:1639

References _baseXPTable.

◆ GetBreadcrumbsForQuest()

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

References _breadcrumbsForQuest.

◆ GetBroadcastText()

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

References _broadcastTextStore.

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

◆ GetClassTrainers()

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

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:1662

References _creatureAddonStore.

◆ GetCreatureBaseStats()

CreatureBaseStats const * ObjectMgr::GetCreatureBaseStats ( uint8  level,
uint8  unitClass 
)
10652{
10653 CreatureBaseStatsContainer::const_iterator it = _creatureBaseStatsStore.find(MAKE_PAIR16(level, unitClass));
10654
10655 if (it != _creatureBaseStatsStore.end())
10656 return &(it->second);
10657
10658 struct DefaultCreatureBaseStats : public CreatureBaseStats
10659 {
10660 DefaultCreatureBaseStats()
10661 {
10662 BaseArmor = 1;
10663 for (uint8 j = 0; j < MAX_EXPANSIONS; ++j)
10664 {
10665 BaseHealth[j] = 1;
10666 BaseDamage[j] = 0.0f;
10667 }
10668 BaseMana = 0;
10669 AttackPower = 0;
10670 RangedAttackPower = 0;
10671 Strength = 0;
10672 Agility = 0;
10673 Stamina = 0;
10674 Intellect = 0;
10675 Spirit = 0;
10676 }
10677 };
10678 static const DefaultCreatureBaseStats defStats;
10679 return &defStats;
10680}
uint16 MAKE_PAIR16(uint8 l, uint8 h)
Definition ObjectDefines.h:83
CreatureBaseStatsContainer _creatureBaseStatsStore
Definition ObjectMgr.h:1623

References _creatureBaseStatsStore, MAKE_PAIR16(), and MAX_EXPANSIONS.

Referenced by AddCreData().

◆ GetCreatureData()

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

References _creatureDataStore.

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

◆ GetCreatureLocale()

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

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:1661

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:1664
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:1584

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:1667

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:1583

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:1663

References _creatureTemplateAddonStore.

◆ GetCreatureTemplates()

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

References _creatureTemplateStore.

Referenced by LoadCreatureClassLevelStats(), and LoadNPCSpellClickSpells().

◆ GetDBCLocaleIndex()

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

References DBCLocaleIndex.

◆ GetDefaultSpawnGroup()

SpawnGroupTemplateData const * ObjectMgr::GetDefaultSpawnGroup ( ) const
inline
1283{ 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:1668

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:1665

References _gameObjectAddonStore.

◆ GetGameObjectData()

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

References _gameObjectDataStore.

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

◆ GetGameObjectLocale()

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

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:1666

References _gameObjectQuestItemStore.

◆ GetGameObjectQuestItemMap()

GameObjectQuestItemMap const * ObjectMgr::GetGameObjectQuestItemMap ( ) const
inline

◆ GetGameObjectSummonGroup()

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

References _goSummonDataStore.

◆ GetGameObjectTemplate()

GameObjectTemplate const * ObjectMgr::GetGameObjectTemplate ( uint32  entry)
10993{
10994 GameObjectTemplateContainer::const_iterator itr = _gameObjectTemplateStore.find(entry);
10995 if (itr != _gameObjectTemplateStore.end())
10996 return &(itr->second);
10997
10998 return nullptr;
10999}
GameObjectTemplateContainer _gameObjectTemplateStore
Definition ObjectMgr.h:1675

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
11008{
11009 auto itr = _gameObjectTemplateAddonStore.find(entry);
11010 if (itr != _gameObjectTemplateAddonStore.end())
11011 return &itr->second;
11012
11013 return nullptr;
11014}
GameObjectTemplateAddonContainer _gameObjectTemplateAddonStore
Definition ObjectMgr.h:1676

References _gameObjectTemplateAddonStore.

◆ GetGameObjectTemplates()

GameObjectTemplateContainer const * ObjectMgr::GetGameObjectTemplates ( ) const
inline

◆ GetGameTele() [1/2]

GameTele const * ObjectMgr::GetGameTele ( std::string_view  name,
bool  exactSearch = false 
) const
9798{
9799 // explicit name case
9800 std::wstring wname;
9801 if (!Utf8toWStr(name, wname))
9802 return nullptr;
9803
9804 // converting string that we try to find to lower case
9805 wstrToLower(wname);
9806
9807 // Alternative first GameTele what contains wnameLow as substring in case no GameTele location found
9808 GameTele const* alt = nullptr;
9809 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9810 {
9811 if (itr->second.wnameLow == wname)
9812 return &itr->second;
9813 else if (!exactSearch && !alt && itr->second.wnameLow.find(wname) != std::wstring::npos)
9814 alt = &itr->second;
9815 }
9816
9817 return alt;
9818}
Definition ObjectMgr.h:135

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

◆ GetGameTele() [2/2]

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

References _gameTeleStore.

◆ GetGameTeleMap()

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

References _gameTeleStore.

◆ GetGenerator()

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

◆ GetGoBackTrigger()

AreaTriggerTeleport const * ObjectMgr::GetGoBackTrigger ( uint32  Map) const
7525{
7526 bool useParentDbValue = false;
7527 uint32 parentId = 0;
7528 MapEntry const* mapEntry = sMapStore.LookupEntry(Map);
7529 if (!mapEntry || mapEntry->entrance_map < 0)
7530 return nullptr;
7531
7532 if (mapEntry->IsDungeon())
7533 {
7534 InstanceTemplate const* iTemplate = sObjectMgr->GetInstanceTemplate(Map);
7535
7536 if (!iTemplate)
7537 return nullptr;
7538
7539 parentId = iTemplate->Parent;
7540 useParentDbValue = true;
7541 }
7542
7543 uint32 entrance_map = uint32(mapEntry->entrance_map);
7544 for (AreaTriggerTeleportContainer::const_iterator itr = _areaTriggerTeleportStore.begin(); itr != _areaTriggerTeleportStore.end(); ++itr)
7545 if ((!useParentDbValue && itr->second.target_mapId == entrance_map) || (useParentDbValue && itr->second.target_mapId == parentId))
7546 {
7547 AreaTrigger const* atEntry = GetAreaTrigger(itr->first);
7548 if (atEntry && atEntry->map == Map)
7549 return &itr->second;
7550 }
7551 return nullptr;
7552}
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:126
uint32 Parent
Definition Map.h:127
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:1582

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:1581

References _goQuestRelations.

◆ GetGOQuestRelationMap()

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

References _goQuestRelations.

◆ GetGossipMenuItemsLocale()

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

References _gossipMenuItemsLocaleStore.

◆ GetGossipMenuItemsMapBounds()

GossipMenuItemsMapBounds ObjectMgr::GetGossipMenuItemsMapBounds ( uint32  uiMenuId) const
inline
1481 {
1482 return _gossipMenuItemsStore.equal_range(uiMenuId);
1483 }
GossipMenuItemsContainer _gossipMenuItemsStore
Definition ObjectMgr.h:1576

References _gossipMenuItemsStore.

◆ GetGossipMenuItemsMapBoundsNonConst()

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

References _gossipMenuItemsStore.

◆ GetGossipMenusMapBounds()

GossipMenusMapBounds ObjectMgr::GetGossipMenusMapBounds ( uint32  uiMenuId) const
inline
1471 {
1472 return _gossipMenusStore.equal_range(uiMenuId);
1473 }
GossipMenusContainer _gossipMenusStore
Definition ObjectMgr.h:1575

References _gossipMenusStore.

◆ GetGossipMenusMapBoundsNonConst()

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

References _gossipMenusStore.

◆ GetGossipText()

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

References _gossipTextStore.

Referenced by LoadGossipMenu().

◆ GetGridObjectGuids()

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

References _emptyCellObjectGuids, _mapObjectGuidsStore, and MAKE_PAIR32().

◆ GetGuidSequenceGenerator()

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

References _guidGenerators.

◆ GetInstanceTemplate()

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

References _instanceTemplateStore.

◆ GetItemLocale()

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

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:1652

References _itemSetNameStore.

◆ GetItemSetNameLocale()

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

References _itemSetNameLocaleStore.

◆ GetItemTemplate()

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

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:1683

References _itemTemplateStore.

◆ GetItemTemplateStoreFast()

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

References _itemTemplateStoreFast.

◆ GetLegacySpawnGroup()

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

References _spawnGroupDataStore.

◆ GetLinkedRespawnGuid()

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

References _linkedRespawnStore, and ObjectGuid::Empty.

◆ GetLocaleString() [1/2]

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

◆ GetLocaleString() [2/2]

◆ GetMailLevelReward()

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

References _mailLevelRewardStore.

◆ GetMapEntranceTrigger()

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

Searches for the areatrigger which teleports players to the given map

7558{
7559 for (AreaTriggerTeleportContainer::const_iterator itr = _areaTriggerTeleportStore.begin(); itr != _areaTriggerTeleportStore.end(); ++itr)
7560 {
7561 if (itr->second.target_mapId == Map) // Id is used to determine correct Scarlet Monastery instance
7562 {
7563 // xinef: no need to check, already done at loading
7564 //AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(itr->first);
7565 //if (atEntry)
7566 return &itr->second;
7567 }
7568 }
7569 return nullptr;
7570}

References _areaTriggerTeleportStore.

◆ GetMapObjectGuids()

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

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:1717
uint8 GetByteValue(uint16 index, uint8 offset) const
Definition Object.cpp:316
TeamId GetTeamId(bool original=false) const
Definition Player.h:2138
uint8 getRace(bool original=false) const
Definition Unit.cpp:17057

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:1715

References _playerTotemModel, and LOG_ERROR.

◆ GetModuleString() [1/2]

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

References _moduleStringStore.

Referenced by GetModuleString().

◆ GetModuleString() [2/2]

std::string const * ObjectMgr::GetModuleString ( std::string  module,
uint32  id,
LocaleConstant  locale 
) const
9537{
9538 ModuleString const* ms = GetModuleString(module, id);
9539 if (ms && !ms->Content.empty())
9540 {
9541 if (ms->Content.size() > size_t(locale) && !ms->Content[locale].empty())
9542 return &ms->Content[locale];
9543
9544 return &ms->Content[DEFAULT_LOCALE];
9545 }
9546
9547 LOG_ERROR("sql.sql", "Module string module {} id {} not found in DB.", module, id);
9548
9549 return (std::string*)"error";
9550}
ModuleString const * GetModuleString(std::string module, uint32 id) const
Definition ObjectMgr.h:1377
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 
)
7142{
7143 bool found = false;
7144 float dist = 10000;
7145 uint32 id = 0;
7146
7147 for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
7148 {
7149 TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i);
7150
7151 if (!node || node->map_id != mapid || (!node->MountCreatureID[teamId == TEAM_ALLIANCE ? 1 : 0] && node->MountCreatureID[0] != 32981)) // dk flight
7152 continue;
7153
7154 uint8 field = (uint8)((i - 1) / 32);
7155 uint32 submask = 1 << ((i - 1) % 32);
7156
7157 // skip not taxi network nodes
7158 if (field >= TaxiMaskSize || (sTaxiNodesMask[field] & submask) == 0)
7159 {
7160 continue;
7161 }
7162
7163 float dist2 = (node->x - x) * (node->x - x) + (node->y - y) * (node->y - y) + (node->z - z) * (node->z - z);
7164 if (found)
7165 {
7166 if (dist2 < dist)
7167 {
7168 dist = dist2;
7169 id = i;
7170 }
7171 }
7172 else
7173 {
7174 found = true;
7175 dist = dist2;
7176 id = i;
7177 }
7178 }
7179
7180 return id;
7181}
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 
)
7137{
7138 return GetNearestTaxiNode(loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetMapId(), teamId);
7139}
uint32 GetNearestTaxiNode(float x, float y, float z, uint32 mapid, uint32 teamId)
Definition ObjectMgr.cpp:7141

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

◆ GetNpcTextLocale()

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

References _npcTextLocaleStore.

◆ GetNpcVendorItemList()

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

References _cacheVendorItemStore.

Referenced by IsVendorItemValid().

◆ GetPageText()

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

References _pageTextStore.

Referenced by LoadGameObjectTemplate(), and LoadItemTemplates().

◆ GetPageTextLocale()

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

References _pageTextLocaleStore.

◆ GetPetLevelInfo()

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

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
4978{
4979 if (level < 1 || class_ >= MAX_CLASSES)
4980 return;
4981
4982 PlayerClassInfo const* pInfo = _playerClassInfo[class_];
4983
4984 if (level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4985 level = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
4986
4987 *info = pInfo->levelInfo[level - 1];
4988}
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
11039{
11040 if (race >= sRaceMgr->GetMaxRaces())
11041 return nullptr;
11042 if (class_ >= MAX_CLASSES)
11043 return nullptr;
11044 PlayerInfo const* info = _playerInfo[race][class_];
11045 if (!info)
11046 return nullptr;
11047 return info;
11048}
Definition Player.h:322

References _playerInfo, MAX_CLASSES, and sRaceMgr.

◆ GetPlayerLevelInfo()

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

References _pointsOfInterestStore.

Referenced by LoadGossipMenuItems().

◆ GetPointOfInterestLocale()

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

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:1561

References _questAreaTriggerStore.

◆ GetQuestGreeting()

QuestGreeting const * ObjectMgr::GetQuestGreeting ( TypeID  type,
uint32  id 
) const
6867{
6868 uint8 typeIndex;
6869 if (type == TYPEID_UNIT)
6870 typeIndex = 0;
6871 else if (type == TYPEID_GAMEOBJECT)
6872 typeIndex = 1;
6873 else
6874 return nullptr;
6875
6876 std::pair<uint32, uint8> pairKey = std::make_pair(id, typeIndex);
6877 QuestGreetingContainer::const_iterator itr = _questGreetingStore.find(pairKey);
6878 if (itr == _questGreetingStore.end())
6879 return nullptr;
6880
6881 return &itr->second;
6882}
@ TYPEID_GAMEOBJECT
Definition ObjectGuid.h:40
@ TYPEID_UNIT
Definition ObjectGuid.h:38
QuestGreetingContainer _questGreetingStore
Definition ObjectMgr.h:1564

References _questGreetingStore, TYPEID_GAMEOBJECT, and TYPEID_UNIT.

◆ GetQuestLocale()

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

References _questLocaleStore.

◆ GetQuestMoneyReward()

uint32 ObjectMgr::GetQuestMoneyReward ( uint8  level,
uint32  questMoneyDifficulty 
) const
11175{
11176 if (questMoneyDifficulty < MAX_QUEST_MONEY_REWARDS)
11177 {
11178 auto const& itr = _questMoneyRewards.find(level);
11179 if (itr != _questMoneyRewards.end())
11180 {
11181 return itr->second.at(questMoneyDifficulty);
11182 }
11183 }
11184
11185 return 0;
11186}
static constexpr uint32 MAX_QUEST_MONEY_REWARDS
Definition ObjectMgr.h:723
QuestMoneyRewardStore _questMoneyRewards
Definition ObjectMgr.h:1719

References _questMoneyRewards, and MAX_QUEST_MONEY_REWARDS.

◆ GetQuestOfferRewardLocale()

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

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:1579

References _questPOIStore.

◆ GetQuestRequestItemsLocale()

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

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:1555

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:1571

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:1573

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:1572

References _repOnKillStore.

◆ GetScriptId()

uint32 ObjectMgr::GetScriptId ( std::string const &  name)
10512{
10513 // use binary search to find the script name in the sorted vector
10514 // assume "" is the first element
10515 if (name.empty())
10516 return 0;
10517
10518 ScriptNameContainer::const_iterator itr = std::lower_bound(_scriptNamesStore.begin(), _scriptNamesStore.end(), name);
10519 if (itr == _scriptNamesStore.end() || (*itr != name))
10520 return 0;
10521
10522 return uint32(itr - _scriptNamesStore.begin());
10523}
ScriptNameContainer _scriptNamesStore
Definition ObjectMgr.h:1599

References _scriptNamesStore.

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

◆ GetScriptName()

std::string const & ObjectMgr::GetScriptName ( uint32  id) const
10506{
10507 static std::string const empty = "";
10508 return (id < _scriptNamesStore.size()) ? _scriptNamesStore[id] : empty;
10509}

References _scriptNamesStore.

Referenced by ValidateSpellScripts().

◆ GetScriptNames()

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

References _scriptNamesStore.

◆ GetSparringData()

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

References _creatureSparringStore.

◆ GetSpawnData()

SpawnData const * ObjectMgr::GetSpawnData ( SpawnObjectType  type,
ObjectGuid::LowType  spawnId 
) const
8654{
8655 switch (type)
8656 {
8658 return GetCreatureData(spawnId);
8660 return GetGameObjectData(spawnId);
8661 default:
8662 return nullptr;
8663 }
8664}
@ 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
1286 {
1287 return _spawnGroupMapStore.equal_range(groupId);
1288 }
SpawnGroupLinkContainer _spawnGroupMapStore
Definition ObjectMgr.h:1673

References _spawnGroupMapStore.

◆ GetSpawnGroupData()

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

References _spawnGroupDataStore.

◆ GetSpellClickInfoMapBounds()

SpellClickInfoMapBounds ObjectMgr::GetSpellClickInfoMapBounds ( uint32  creature_id) const
inline
1466 {
1467 return _spellClickInfoStore.equal_range(creature_id);
1468 }
SpellClickInfoContainer _spellClickInfoStore
Definition ObjectMgr.h:1601

References _spellClickInfoStore.

◆ GetSpellScriptsBounds()

SpellScriptsBounds ObjectMgr::GetSpellScriptsBounds ( uint32  spell_id)
9687{
9688 return SpellScriptsBounds(_spellScriptsStore.lower_bound(spell_id), _spellScriptsStore.upper_bound(spell_id));
9689}
std::pair< SpellScriptsContainer::iterator, SpellScriptsContainer::iterator > SpellScriptsBounds
Definition ObjectMgr.h:391
SpellScriptsContainer _spellScriptsStore
Definition ObjectMgr.h:1603

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

References _tempSummonDataStore.

◆ GetTaxiMountDisplayId()

uint32 ObjectMgr::GetTaxiMountDisplayId ( uint32  id,
TeamId  teamId,
bool  allowed_alt_team = false 
)
7208{
7209 CreatureModel mountModel;
7210 CreatureTemplate const* mount_info = nullptr;
7211
7212 // select mount creature id
7213 TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id);
7214 if (node)
7215 {
7216 uint32 mount_entry = node->MountCreatureID[teamId == TEAM_ALLIANCE ? 1 : 0];
7217
7218 // Fix for Alliance not being able to use Acherus taxi
7219 // only one mount type for both sides
7220 if (mount_entry == 0 && allowed_alt_team)
7221 {
7222 // Simply reverse the selection. At least one team in theory should have a valid mount ID to choose.
7223 mount_entry = node->MountCreatureID[teamId];
7224 }
7225
7226 mount_info = GetCreatureTemplate(mount_entry);
7227 if (mount_info)
7228 {
7229 CreatureModel const* model = mount_info->GetRandomValidModel();
7230 if (!model)
7231 {
7232 LOG_ERROR("sql.sql", "No displayid found for the taxi mount with the entry {}! Can't load it!", mount_entry);
7233 return 0;
7234 }
7235 mountModel = *model;
7236 }
7237 }
7238
7239 // minfo is not actually used but the mount_id was updated
7240 GetCreatureModelRandomGender(&mountModel, mount_info);
7241
7242 return mountModel.CreatureDisplayID;
7243}
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 
)
7184{
7185 TaxiPathSetBySource::iterator src_i = sTaxiPathSetBySource.find(source);
7186 if (src_i == sTaxiPathSetBySource.end())
7187 {
7188 path = 0;
7189 cost = 0;
7190 return;
7191 }
7192
7193 TaxiPathSetForSource& pathSet = src_i->second;
7194
7195 TaxiPathSetForSource::iterator dest_i = pathSet.find(destination);
7196 if (dest_i == pathSet.end())
7197 {
7198 path = 0;
7199 cost = 0;
7200 return;
7201 }
7202
7203 cost = dest_i->second->price;
7204 path = dest_i->second->ID;
7205}
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)
10099{
10100 auto itr = _creatureDefaultTrainers.find(creatureId);
10101 if (itr != _creatureDefaultTrainers.end())
10102 return Acore::Containers::MapGetValuePtr(_trainers, itr->second);
10103
10104 return nullptr;
10105}
std::unordered_map< uint32, uint32 > _creatureDefaultTrainers
Definition ObjectMgr.h:1700
std::unordered_map< uint32, Trainer::Trainer > _trainers
Definition ObjectMgr.h:1698

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

◆ GetVehicleAccessoryList()

VehicleAccessoryList const * ObjectMgr::GetVehicleAccessoryList ( Vehicle veh) const
11022{
11023 if (Creature* cre = veh->GetBase()->ToCreature())
11024 {
11025 // Give preference to GUID-based accessories
11026 VehicleAccessoryContainer::const_iterator itr = _vehicleAccessoryStore.find(cre->GetSpawnId());
11027 if (itr != _vehicleAccessoryStore.end())
11028 return &itr->second;
11029 }
11030
11031 // Otherwise return entry-based
11032 VehicleAccessoryContainer::const_iterator itr = _vehicleTemplateAccessoryStore.find(veh->GetCreatureEntry());
11033 if (itr != _vehicleTemplateAccessoryStore.end())
11034 return &itr->second;
11035 return nullptr;
11036}
VehicleAccessoryContainer _vehicleAccessoryStore
Definition ObjectMgr.h:1606
VehicleAccessoryContainer _vehicleTemplateAccessoryStore
Definition ObjectMgr.h:1605
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
1520 {
1521 VehicleSeatAddonContainer::const_iterator itr = _vehicleSeatAddonStore.find(seatId);
1522 if (itr == _vehicleSeatAddonStore.end())
1523 return nullptr;
1524
1525 return &itr->second;
1526 }
VehicleSeatAddonContainer _vehicleSeatAddonStore
Definition ObjectMgr.h:1607

References _vehicleSeatAddonStore.

◆ GetXPForLevel()

uint32 ObjectMgr::GetXPForLevel ( uint8  level) const
8066{
8067 if (level < _playerXPperLevel.size())
8068 return _playerXPperLevel[level];
8069 return 0;
8070}
PlayerXPperLevel _playerXPperLevel
Definition ObjectMgr.h:1636

References _playerXPperLevel.

◆ InitializeSpellInfoPrecomputedData()

void ObjectMgr::InitializeSpellInfoPrecomputedData ( )
6459{
6460 uint32 limit = sSpellStore.GetNumRows();
6461 for(uint32 i = 0; i <= limit; ++i)
6462 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(i))
6463 {
6464 const_cast<SpellInfo*>(spellInfo)->SetStackableWithRanks(spellInfo->ComputeIsStackableWithRanks());
6465 const_cast<SpellInfo*>(spellInfo)->SetCritCapable(spellInfo->ComputeIsCritCapable());
6466 const_cast<SpellInfo*>(spellInfo)->SetSpellValid(SpellMgr::ComputeIsSpellValid(spellInfo, false));
6467 }
6468}
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
9194{
9195 if (!_chatFilterAutomaton || text.empty())
9196 return false;
9197
9198 std::wstring wtext;
9199 if (!Utf8toWStr(text, wtext))
9200 return false;
9201
9202 wstrToLower(wtext);
9203
9204 return _chatFilterAutomaton->ContainsAny(wtext);
9205}
std::unique_ptr< Acore::AhoCorasick< wchar_t > > _chatFilterAutomaton
Definition ObjectMgr.h:1595

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

◆ IsGameObjectStaticTransport()

bool ObjectMgr::IsGameObjectStaticTransport ( uint32  entry)
11002{
11003 GameObjectTemplate const* goinfo = GetGameObjectTemplate(entry);
11004 return goinfo && goinfo->type == GAMEOBJECT_TYPE_TRANSPORT;
11005}
@ 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
9106{
9107 // pussywizard
9108 if (name.size() >= 2 && (name[name.size() - 2] == 'G' || name[name.size() - 2] == 'g') && (name[name.size() - 1] == 'M' || name[name.size() - 1] == 'm'))
9109 return true;
9110
9111 std::wstring wstr;
9112 if (!Utf8toWStr (name, wstr))
9113 return false;
9114
9115 wstrToLower(wstr);
9116
9117 return _profanityNamesStore.find(wstr) != _profanityNamesStore.end();
9118}

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

Referenced by AddProfanityPlayerName().

◆ IsReservedName()

bool ObjectMgr::IsReservedName ( std::string_view  name) const
9003{
9004 // pussywizard
9005 if (name.size() >= 2 && (name[name.size() - 2] == 'G' || name[name.size() - 2] == 'g') && (name[name.size() - 1] == 'M' || name[name.size() - 1] == 'm'))
9006 return true;
9007
9008 std::wstring wstr;
9009 if (!Utf8toWStr (name, wstr))
9010 return false;
9011
9012 wstrToLower(wstr);
9013
9014 return _reservedNamesStore.find(wstr) != _reservedNamesStore.end();
9015}

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:1562

References _tavernAreaTriggerStore.

◆ IsTransportMap()

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

References _transportMaps.

◆ IsValidChannelName()

bool ObjectMgr::IsValidChannelName ( std::string const &  name)
static
9346{
9347 std::wstring wname;
9348 if (!Utf8toWStr(name, wname))
9349 return false;
9350
9351 if (wname.size() > MAX_CHANNEL_NAME)
9352 return false;
9353
9354 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_CHANNEL_NAMES);
9355
9356 return isValidString(wname, strictMask, true);
9357}
#define MAX_CHANNEL_NAME
Definition ObjectMgr.h:691
@ CONFIG_STRICT_CHANNEL_NAMES
Definition WorldConfig.h:181

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

◆ IsValidCharterName()

bool ObjectMgr::IsValidCharterName ( std::string_view  name)
static
9320{
9321 std::wstring wname;
9322 if (!Utf8toWStr(name, wname))
9323 return false;
9324
9325 if (wname.size() > MAX_CHARTER_NAME)
9326 return false;
9327
9328 uint32 minName = sWorld->getIntConfig(CONFIG_MIN_CHARTER_NAME);
9329 if (wname.size() < minName)
9330 return false;
9331
9332 // Check Reserved Name
9333 if (sObjectMgr->IsReservedName(name))
9334 return false;
9335
9336 // Check Profanity Name
9337 if (sObjectMgr->IsProfanityName(name))
9338 return false;
9339
9340 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_CHARTER_NAMES);
9341
9342 return isValidString(wname, strictMask, true);
9343}
#define MAX_CHARTER_NAME
Definition ObjectMgr.h:690
@ CONFIG_MIN_CHARTER_NAME
Definition WorldConfig.h:184
@ CONFIG_STRICT_CHARTER_NAMES
Definition WorldConfig.h:180

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
10370{
10371 /*
10372 CreatureTemplate const* cInfo = GetCreatureTemplate(vendor_entry);
10373 if (!cInfo)
10374 {
10375 if (player)
10376 ChatHandler(player->GetSession()).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
10377 else
10378 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have data for not existed creature template (Entry: {}), ignore", vendor_entry);
10379 return false;
10380 }
10381
10382 if (!((cInfo->npcflag | ORnpcflag) & UNIT_NPC_FLAG_VENDOR))
10383 {
10384 if (!skip_vendors || skip_vendors->count(vendor_entry) == 0)
10385 {
10386 if (player)
10387 ChatHandler(player->GetSession()).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
10388 else
10389 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have data for not creature template (Entry: {}) without vendor flag, ignore", vendor_entry);
10390
10391 if (skip_vendors)
10392 skip_vendors->insert(vendor_entry);
10393 }
10394 return false;
10395 }
10396 */
10397
10398 if (!sObjectMgr->GetItemTemplate(item_id))
10399 {
10400 if (player)
10402 else
10403 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` for Vendor (Entry: {}) have in item list non-existed item ({}), ignore", vendor_entry, item_id);
10404 return false;
10405 }
10406
10407 if (ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost))
10408 {
10409 if (player)
10411 else
10412 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have Item (Entry: {}) with wrong ExtendedCost ({}) for vendor ({}), ignore", item_id, ExtendedCost, vendor_entry);
10413 return false;
10414 }
10415
10416 if (maxcount > 0 && incrtime == 0)
10417 {
10418 if (player)
10419 ChatHandler(player->GetSession()).PSendSysMessage("MaxCount != 0 ({}) but IncrTime == 0", maxcount);
10420 else
10421 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);
10422 return false;
10423 }
10424 else if (maxcount == 0 && incrtime > 0)
10425 {
10426 if (player)
10427 ChatHandler(player->GetSession()).PSendSysMessage("MaxCount == 0 but IncrTime<>= 0");
10428 else
10429 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);
10430 return false;
10431 }
10432
10433 VendorItemData const* vItems = GetNpcVendorItemList(vendor_entry);
10434 if (!vItems)
10435 return true; // later checks for non-empty lists
10436
10437 if (vItems->FindItemCostPair(item_id, ExtendedCost))
10438 {
10439 if (player)
10440 ChatHandler(player->GetSession()).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, item_id, ExtendedCost);
10441 else
10442 LOG_ERROR("sql.sql", "Table `npc_vendor` has duplicate items {} (with extended cost {}) for vendor (Entry: {}), ignoring", item_id, ExtendedCost, vendor_entry);
10443 return false;
10444 }
10445
10446 return true;
10447}
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:1447
WorldSession * GetSession() const
Definition Player.h:2030
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 ( )
7357{
7358 uint32 oldMSTime = getMSTime();
7359
7360 if (!_accessRequirementStore.empty())
7361 {
7362 for (DungeonProgressionRequirementsContainer::iterator itr = _accessRequirementStore.begin(); itr != _accessRequirementStore.end(); ++itr)
7363 {
7364 std::unordered_map<uint8, DungeonProgressionRequirements*> difficulties = itr->second;
7365 for (auto difficultiesItr = difficulties.begin(); difficultiesItr != difficulties.end(); ++difficultiesItr)
7366 {
7367 for (auto questItr = difficultiesItr->second->quests.begin(); questItr != difficultiesItr->second->quests.end(); ++questItr)
7368 {
7369 delete* questItr;
7370 }
7371
7372 for (auto achievementItr = difficultiesItr->second->achievements.begin(); achievementItr != difficultiesItr->second->achievements.end(); ++achievementItr)
7373 {
7374 delete* achievementItr;
7375 }
7376
7377 for (auto itemsItr = difficultiesItr->second->items.begin(); itemsItr != difficultiesItr->second->items.end(); ++itemsItr)
7378 {
7379 delete* itemsItr;
7380 }
7381
7382 delete difficultiesItr->second;
7383 }
7384 }
7385
7386 _accessRequirementStore.clear(); // need for reload case
7387 }
7388 // 0 1 2 3 4 5
7389 QueryResult access_template_result = WorldDatabase.Query("SELECT id, map_id, difficulty, min_level, max_level, min_avg_item_level FROM dungeon_access_template");
7390 if (!access_template_result)
7391 {
7392 LOG_WARN("server.loading", ">> Loaded 0 access requirement definitions. DB table `dungeon_access_template` is empty.");
7393 LOG_INFO("server.loading", " ");
7394 return;
7395 }
7396
7397 uint32 count = 0;
7398 uint32 countProgressionRequirements = 0;
7399
7400 do
7401 {
7402 Field* fields = access_template_result->Fetch();
7403
7404 //Get the common variables for the access requirements
7405 uint8 dungeon_access_id = fields[0].Get<uint8>();
7406 uint32 mapid = fields[1].Get<uint32>();
7407 uint8 difficulty = fields[2].Get<uint8>();
7408
7409 //Set up the access requirements
7411 ar->levelMin = fields[3].Get<uint8>();
7412 ar->levelMax = fields[4].Get<uint8>();
7413 ar->reqItemLevel = fields[5].Get<uint16>();
7414
7415 // 0 1 2 3 4 6
7416 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);
7417 if (progression_requirements_results)
7418 {
7419 do
7420 {
7421 Field* progression_requirement_row = progression_requirements_results->Fetch();
7422
7423 const uint8 requirement_type = progression_requirement_row[0].Get<uint8>();
7424 const uint32 requirement_id = progression_requirement_row[1].Get<uint32>();
7425 const std::string requirement_note = progression_requirement_row[2].Get<std::string>();
7426 const uint8 requirement_faction = progression_requirement_row[3].Get<uint8>();
7427 const uint8 requirement_priority = progression_requirement_row[4].IsNull() ? UINT8_MAX : progression_requirement_row[4].Get<uint8>();
7428 const bool requirement_checkLeaderOnly = progression_requirement_row[5].Get<bool>();
7429
7430 ProgressionRequirement* progression_requirement = new ProgressionRequirement();
7431 progression_requirement->id = requirement_id;
7432 progression_requirement->note = requirement_note;
7433 progression_requirement->faction = (TeamId)requirement_faction;
7434 progression_requirement->priority = requirement_priority;
7435 progression_requirement->checkLeaderOnly = requirement_checkLeaderOnly;
7436
7437 std::vector<ProgressionRequirement*>* currentRequirementsList = nullptr;
7438
7439 switch (requirement_type)
7440 {
7441 case 0:
7442 {
7443 //Achievement
7444 if (!sAchievementStore.LookupEntry(progression_requirement->id))
7445 {
7446 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);
7447 break;
7448 }
7449
7450 currentRequirementsList = &ar->achievements;
7451 break;
7452 }
7453 case 1:
7454 {
7455 //Quest
7456 if (!GetQuestTemplate(progression_requirement->id))
7457 {
7458 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);
7459 break;
7460 }
7461
7462 currentRequirementsList = &ar->quests;
7463 break;
7464 }
7465 case 2:
7466 {
7467 //Item
7468 ItemTemplate const* pProto = GetItemTemplate(progression_requirement->id);
7469 if (!pProto)
7470 {
7471 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);
7472 break;
7473 }
7474
7475 currentRequirementsList = &ar->items;
7476 break;
7477 }
7478 default:
7479 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);
7480 break;
7481 }
7482
7483 //Check if array is valid and delete the progression requirement
7484 if (!currentRequirementsList)
7485 {
7486 delete progression_requirement;
7487 continue;
7488 }
7489
7490 //Insert into the array
7491 if (currentRequirementsList->size() > requirement_priority)
7492 {
7493 currentRequirementsList->insert(currentRequirementsList->begin() + requirement_priority, progression_requirement);
7494 }
7495 else
7496 {
7497 currentRequirementsList->push_back(progression_requirement);
7498 }
7499
7500 } while (progression_requirements_results->NextRow());
7501 }
7502
7503 //Sort all arrays for priority
7504 auto sortFunction = [](ProgressionRequirement const* const a, ProgressionRequirement const* const b) {return a->priority > b->priority; };
7505 std::sort(ar->achievements.begin(), ar->achievements.end(), sortFunction);
7506 std::sort(ar->quests.begin(), ar->quests.end(), sortFunction);
7507 std::sort(ar->items.begin(), ar->items.end(), sortFunction);
7508
7509 countProgressionRequirements += ar->achievements.size();
7510 countProgressionRequirements += ar->quests.size();
7511 countProgressionRequirements += ar->items.size();
7512 count++;
7513
7514 _accessRequirementStore[mapid][difficulty] = ar;
7515 } while (access_template_result->NextRow());
7516
7517 LOG_INFO("server.loading", ">> Loaded {} Rows From dungeon_access_template And {} Rows From dungeon_access_requirements in {} ms", count, countProgressionRequirements, GetMSTimeDiffToNow(oldMSTime));
7518 LOG_INFO("server.loading", " ");
7519}
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:3934
Quest const * GetQuestTemplate(uint32 quest_id) const
Definition ObjectMgr.h:840
Definition Player.h:936
Definition ItemTemplate.h:619
Definition Player.h:927
uint32 priority
Definition Player.h:931

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 ( )
9553{
9554 uint32 oldMSTime = getMSTime();
9555
9556 _acoreStringStore.clear(); // for reload case
9557 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");
9558 if (!result)
9559 {
9560 LOG_WARN("server.loading", ">> Loaded 0 acore strings. DB table `acore_strings` is empty.");
9561 LOG_INFO("server.loading", " ");
9562 return false;
9563 }
9564
9565 do
9566 {
9567 Field* fields = result->Fetch();
9568
9569 uint32 entry = fields[0].Get<uint32>();
9570
9571 AcoreString& data = _acoreStringStore[entry];
9572
9573 data.Content.resize(DEFAULT_LOCALE + 1);
9574
9575 for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
9576 AddLocaleString(fields[i + 1].Get<std::string>(), LocaleConstant(i), data.Content);
9577 } while (result->NextRow());
9578
9579 LOG_INFO("server.loading", ">> Loaded {} Acore Strings in {} ms", (uint32)_acoreStringStore.size(), GetMSTimeDiffToNow(oldMSTime));
9580 LOG_INFO("server.loading", " ");
9581
9582 return true;
9583}
LocaleConstant
Definition Common.h:125
@ TOTAL_LOCALES
Definition Common.h:136
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 ( )
7246{
7247 uint32 oldMSTime = getMSTime();
7248
7249 _areaTriggerStore.clear();
7250
7251 QueryResult result = WorldDatabase.Query("SELECT entry, map, x, y, z, radius, length, width, height, orientation FROM areatrigger");
7252
7253 if (!result)
7254 {
7255 LOG_WARN("server.loading", ">> Loaded 0 area trigger definitions. DB table `areatrigger` is empty.");
7256 LOG_INFO("server.loading", " ");
7257 return;
7258 }
7259
7260 uint32 count = 0;
7261
7262 do
7263 {
7264 Field* fields = result->Fetch();
7265
7266 ++count;
7267
7268 AreaTrigger at;
7269
7270 at.entry = fields[0].Get<uint32>();
7271 at.map = fields[1].Get<uint32>();
7272 at.x = fields[2].Get<float>();
7273 at.y = fields[3].Get<float>();
7274 at.z = fields[4].Get<float>();
7275 at.radius = fields[5].Get<float>();
7276 at.length = fields[6].Get<float>();
7277 at.width = fields[7].Get<float>();
7278 at.height = fields[8].Get<float>();
7279 at.orientation = fields[9].Get<float>();
7280
7281 MapEntry const* mapEntry = sMapStore.LookupEntry(at.map);
7282 if (!mapEntry)
7283 {
7284 LOG_ERROR("sql.sql", "Area trigger (ID:{}) map (ID: {}) does not exist in `Map.dbc`.", at.entry, at.map);
7285 continue;
7286 }
7287
7288 _areaTriggerStore[at.entry] = at;
7289 } while (result->NextRow());
7290
7291 LOG_INFO("server.loading", ">> Loaded {} Area Trigger Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7292 LOG_INFO("server.loading", " ");
7293}
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 ( )
7099{
7100 uint32 oldMSTime = getMSTime();
7101
7102 _areaTriggerScriptStore.clear(); // need for reload case
7103 QueryResult result = WorldDatabase.Query("SELECT entry, ScriptName FROM areatrigger_scripts");
7104
7105 if (!result)
7106 {
7107 LOG_WARN("server.loading", ">> Loaded 0 Areatrigger Scripts. DB Table `areatrigger_scripts` Is Empty.");
7108 LOG_INFO("server.loading", " ");
7109 return;
7110 }
7111
7112 uint32 count = 0;
7113
7114 do
7115 {
7116 ++count;
7117
7118 Field* fields = result->Fetch();
7119
7120 uint32 Trigger_ID = fields[0].Get<uint32>();
7121 std::string scriptName = fields[1].Get<std::string>();
7122
7123 AreaTrigger const* atEntry = GetAreaTrigger(Trigger_ID);
7124 if (!atEntry)
7125 {
7126 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
7127 continue;
7128 }
7129 _areaTriggerScriptStore[Trigger_ID] = GetScriptId(scriptName);
7130 } while (result->NextRow());
7131
7132 LOG_INFO("server.loading", ">> Loaded {} Areatrigger Scripts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7133 LOG_INFO("server.loading", " ");
7134}
uint32 GetScriptId(std::string const &name)
Definition ObjectMgr.cpp:10511

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

◆ LoadAreaTriggerTeleports()

void ObjectMgr::LoadAreaTriggerTeleports ( )
7296{
7297 uint32 oldMSTime = getMSTime();
7298
7299 _areaTriggerTeleportStore.clear(); // need for reload case
7300
7301 // 0 1 2 3 4 5
7302 QueryResult result = WorldDatabase.Query("SELECT ID, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM areatrigger_teleport");
7303
7304 if (!result)
7305 {
7306 LOG_WARN("server.loading", ">> Loaded 0 area trigger teleport definitions. DB table `areatrigger_teleport` is empty.");
7307 LOG_INFO("server.loading", " ");
7308 return;
7309 }
7310
7311 uint32 count = 0;
7312
7313 do
7314 {
7315 Field* fields = result->Fetch();
7316
7317 ++count;
7318
7319 uint32 Trigger_ID = fields[0].Get<uint32>();
7320
7322
7323 at.target_mapId = fields[1].Get<uint16>();
7324 at.target_X = fields[2].Get<float>();
7325 at.target_Y = fields[3].Get<float>();
7326 at.target_Z = fields[4].Get<float>();
7327 at.target_Orientation = fields[5].Get<float>();
7328
7329 AreaTrigger const* atEntry = GetAreaTrigger(Trigger_ID);
7330 if (!atEntry)
7331 {
7332 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
7333 continue;
7334 }
7335
7336 MapEntry const* mapEntry = sMapStore.LookupEntry(at.target_mapId);
7337 if (!mapEntry)
7338 {
7339 LOG_ERROR("sql.sql", "Area trigger (ID:{}) target map (ID: {}) does not exist in `Map.dbc`.", Trigger_ID, at.target_mapId);
7340 continue;
7341 }
7342
7343 if (at.target_X == 0 && at.target_Y == 0 && at.target_Z == 0)
7344 {
7345 LOG_ERROR("sql.sql", "Area trigger (ID:{}) target coordinates not provided.", Trigger_ID);
7346 continue;
7347 }
7348
7349 _areaTriggerTeleportStore[Trigger_ID] = at;
7350 } while (result->NextRow());
7351
7352 LOG_INFO("server.loading", ">> Loaded {} Area Trigger Teleport Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7353 LOG_INFO("server.loading", " ");
7354}
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 ( )
10611{
10612 uint32 oldMSTime = getMSTime();
10613
10614 // 0 1 2 3
10615 QueryResult result = WorldDatabase.Query("SELECT ID, locale, MaleText, FemaleText FROM broadcast_text_locale");
10616
10617 if (!result)
10618 {
10619 LOG_WARN("server.loading", ">> Loaded 0 broadcast text locales. DB table `broadcast_text_locale` is empty.");
10620 LOG_INFO("server.loading", " ");
10621 return;
10622 }
10623
10624 uint32 locales_count = 0;
10625 do
10626 {
10627 Field* fields = result->Fetch();
10628
10629 uint32 id = fields[0].Get<uint32>();
10630
10631 BroadcastTextContainer::iterator bct = _broadcastTextStore.find(id);
10632 if (bct == _broadcastTextStore.end())
10633 {
10634 LOG_ERROR("sql.sql", "BroadcastText (Id: {}) found in table `broadcast_text_locale` but does not exist in `broadcast_text`. Skipped!", id);
10635 continue;
10636 }
10637
10638 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
10639 if (locale == LOCALE_enUS)
10640 continue;
10641
10642 AddLocaleString(fields[2].Get<std::string>(), locale, bct->second.MaleText);
10643 AddLocaleString(fields[3].Get<std::string>(), locale, bct->second.FemaleText);
10644 locales_count++;
10645 } while (result->NextRow());
10646
10647 LOG_INFO("server.loading", ">> Loaded {} Broadcast Text Locales in {} ms", locales_count, GetMSTimeDiffToNow(oldMSTime));
10648 LOG_INFO("server.loading", " ");
10649}
LocaleConstant GetLocaleByName(std::string const &name)
Definition Common.cpp:78

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

◆ LoadBroadcastTexts()

void ObjectMgr::LoadBroadcastTexts ( )
10526{
10527 uint32 oldMSTime = getMSTime();
10528
10529 _broadcastTextStore.clear(); // for reload case
10530
10531 // 0 1 2 3 4 5 6 7 8 9 10 11 12
10532 QueryResult result = WorldDatabase.Query("SELECT ID, LanguageID, MaleText, FemaleText, EmoteID1, EmoteID2, EmoteID3, EmoteDelay1, EmoteDelay2, EmoteDelay3, SoundEntriesID, EmotesID, Flags FROM broadcast_text");
10533 if (!result)
10534 {
10535 LOG_WARN("server.loading", ">> Loaded 0 broadcast texts. DB table `broadcast_text` is empty.");
10536 LOG_INFO("server.loading", " ");
10537 return;
10538 }
10539
10540 _broadcastTextStore.rehash(result->GetRowCount());
10541
10542 do
10543 {
10544 Field* fields = result->Fetch();
10545
10546 BroadcastText bct;
10547
10548 bct.Id = fields[0].Get<uint32>();
10549 bct.LanguageID = fields[1].Get<uint32>();
10550 bct.MaleText[DEFAULT_LOCALE] = fields[2].Get<std::string>();
10551 bct.FemaleText[DEFAULT_LOCALE] = fields[3].Get<std::string>();
10552 bct.EmoteId1 = fields[4].Get<uint32>();
10553 bct.EmoteId2 = fields[5].Get<uint32>();
10554 bct.EmoteId3 = fields[6].Get<uint32>();
10555 bct.EmoteDelay1 = fields[7].Get<uint32>();
10556 bct.EmoteDelay2 = fields[8].Get<uint32>();
10557 bct.EmoteDelay3 = fields[9].Get<uint32>();
10558 bct.SoundEntriesId = fields[10].Get<uint32>();
10559 bct.EmotesID = fields[11].Get<uint32>();
10560 bct.Flags = fields[12].Get<uint32>();
10561
10562 if (bct.SoundEntriesId)
10563 {
10564 if (!sSoundEntriesStore.LookupEntry(bct.SoundEntriesId))
10565 {
10566 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has SoundEntriesId {} but sound does not exist.", bct.Id, bct.SoundEntriesId);
10567 bct.SoundEntriesId = 0;
10568 }
10569 }
10570
10572 {
10573 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` using Language {} but Language does not exist.", bct.Id, bct.LanguageID);
10575 }
10576
10577 if (bct.EmoteId1)
10578 {
10579 if (!sEmotesStore.LookupEntry(bct.EmoteId1))
10580 {
10581 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has EmoteId1 {} but emote does not exist.", bct.Id, bct.EmoteId1);
10582 bct.EmoteId1 = 0;
10583 }
10584 }
10585
10586 if (bct.EmoteId2)
10587 {
10588 if (!sEmotesStore.LookupEntry(bct.EmoteId2))
10589 {
10590 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has EmoteId2 {} but emote does not exist.", bct.Id, bct.EmoteId2);
10591 bct.EmoteId2 = 0;
10592 }
10593 }
10594
10595 if (bct.EmoteId3)
10596 {
10597 if (!sEmotesStore.LookupEntry(bct.EmoteId3))
10598 {
10599 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has EmoteId3 {} but emote does not exist.", bct.Id, bct.EmoteId3);
10600 bct.EmoteId3 = 0;
10601 }
10602 }
10603
10604 _broadcastTextStore[bct.Id] = bct;
10605 } while (result->NextRow());
10606
10607 LOG_INFO("server.loading", ">> Loaded {} Broadcast Texts in {} ms", _broadcastTextStore.size(), GetMSTimeDiffToNow(oldMSTime));
10608}
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 ( )
9141{
9142 uint32 oldMSTime = getMSTime();
9143
9144 _chatFilterAutomaton.reset(); // need for reload case
9145
9147 PreparedQueryResult result = CharacterDatabase.Query(stmt);
9148
9149 if (!result)
9150 {
9151 LOG_WARN("server.loading", ">> Loaded 0 chat filter words. DB table `chat_filter` is empty!");
9152 LOG_INFO("server.loading", " ");
9153 return;
9154 }
9155
9156 auto automaton = std::make_unique<Acore::AhoCorasick<wchar_t>>();
9157 uint32 count = 0;
9158
9159 do
9160 {
9161 Field* fields = result->Fetch();
9162 std::string word = fields[1].Get<std::string>();
9163
9164 if (word.empty())
9165 continue;
9166
9167 std::wstring wstr;
9168 if (!Utf8toWStr(word, wstr))
9169 {
9170 LOG_ERROR("sql.sql", "Table `chat_filter` has invalid word: {}", word);
9171 continue;
9172 }
9173
9174 wstrToLower(wstr);
9175
9176 if (wstr.empty())
9177 continue;
9178
9179 automaton->Insert(wstr);
9180 ++count;
9181 } while (result->NextRow());
9182
9183 if (count > 0)
9184 {
9185 automaton->Build();
9186 _chatFilterAutomaton = std::move(automaton);
9187 }
9188
9189 LOG_INFO("server.loading", ">> Loaded {} chat filter words in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9190 LOG_INFO("server.loading", " ");
9191}
@ CHAR_SEL_CHAT_FILTER
Definition CharacterDatabase.h:531
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 ( )
10683{
10684 uint32 oldMSTime = getMSTime();
10685
10686 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");
10687
10688 if (!result)
10689 {
10690 LOG_WARN("server.loading", ">> Loaded 0 creature base stats. DB table `creature_classlevelstats` is empty.");
10691 LOG_INFO("server.loading", " ");
10692 return;
10693 }
10694
10695 uint32 count = 0;
10696 do
10697 {
10698 Field* fields = result->Fetch();
10699
10700 uint8 Level = fields[0].Get<uint8>();
10701 uint8 Class = fields[1].Get<uint8>();
10702
10703 if (!Class || ((1 << (Class - 1)) & CLASSMASK_ALL_CREATURES) == 0)
10704 LOG_ERROR("sql.sql", "Creature base stats for level {} has invalid class {}", Level, Class);
10705
10706 CreatureBaseStats stats;
10707
10708 for (uint8 i = 0; i < MAX_EXPANSIONS; ++i)
10709 {
10710 stats.BaseHealth[i] = fields[2 + i].Get<uint32>();
10711
10712 if (stats.BaseHealth[i] == 0)
10713 {
10714 LOG_ERROR("sql.sql", "Creature base stats for class {}, level {} has invalid zero base HP[{}] - set to 1", Class, Level, i);
10715 stats.BaseHealth[i] = 1;
10716 }
10717
10718 // xinef: if no data is available, get them from lower expansions
10719 if (stats.BaseHealth[i] <= 1)
10720 {
10721 for (uint8 j = i; j > 0;)
10722 {
10723 --j;
10724 if (stats.BaseHealth[j] > 1)
10725 {
10726 stats.BaseHealth[i] = stats.BaseHealth[j];
10727 break;
10728 }
10729 }
10730 }
10731
10732 stats.BaseDamage[i] = fields[9 + i].Get<float>();
10733 if (stats.BaseDamage[i] < 0.0f)
10734 {
10735 LOG_ERROR("sql.sql", "Creature base stats for class {}, level {} has invalid negative base damage[{}] - set to 0.0", Class, Level, i);
10736 stats.BaseDamage[i] = 0.0f;
10737 }
10738 }
10739
10740 stats.BaseMana = fields[5].Get<uint32>();
10741 stats.BaseArmor = fields[6].Get<uint32>();
10742
10743 stats.AttackPower = fields[7].Get<uint32>();
10744 stats.RangedAttackPower = fields[8].Get<uint32>();
10745
10746 stats.Strength = fields[12].Get<uint32>();
10747 stats.Agility = fields[13].Get<uint32>();
10748 stats.Stamina = fields[14].Get<uint32>();
10749 stats.Intellect = fields[15].Get<uint32>();
10750 stats.Spirit = fields[16].Get<uint32>();
10751
10752 if (!stats.Strength || !stats.Agility || !stats.Stamina || !stats.Intellect || !stats.Spirit)
10753 {
10754 // Once these attributes are implemented, this should probably be uncommented.
10755 // LOG_WARN("server.loading", "Creature base attributes for class {}, level {} are missing!", Class, Level);
10756 }
10757
10759
10760 ++count;
10761 } while (result->NextRow());
10762
10764 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
10765 {
10766 for (uint16 lvl = itr->second.minlevel; lvl <= itr->second.maxlevel; ++lvl)
10767 {
10768 if (_creatureBaseStatsStore.find(MAKE_PAIR16(lvl, itr->second.unit_class)) == _creatureBaseStatsStore.end())
10769 LOG_ERROR("sql.sql", "Missing base stats for creature class {} level {}", itr->second.unit_class, lvl);
10770 }
10771 }
10772
10773 LOG_INFO("server.loading", ">> Loaded {} Creature Base Stats in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10774 LOG_INFO("server.loading", " ");
10775}
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.
2575{
2576 CreatureData const* data = GetCreatureData(spawnId);
2577 if (data)
2578 return data;
2579
2580 QueryResult result = WorldDatabase.Query("SELECT creature.guid, id, map, equipment_id, "
2581 "position_x, position_y, position_z, orientation, spawntimesecs, wander_distance, "
2582 "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, "
2583 "creature.npcflag, creature.unit_flags, creature.dynamicflags, creature.ScriptName "
2584 "FROM creature WHERE creature.guid = {}", spawnId);
2585
2586 if (!result)
2587 return nullptr;
2588
2589 Field* fields = result->Fetch();
2590 uint32 creatureId = fields[1].Get<uint32>();
2591
2592 CreatureTemplate const* cInfo = GetCreatureTemplate(creatureId);
2593 if (!cInfo)
2594 {
2595 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non-existing creature entry {} in `id` field, skipped.", spawnId, creatureId);
2596 return nullptr;
2597 }
2598
2600 creatureData.id = creatureId;
2601 creatureData.mapid = fields[2].Get<uint16>();
2602 creatureData.equipmentId = fields[3].Get<int8>();
2603 creatureData.posX = fields[4].Get<float>();
2604 creatureData.posY = fields[5].Get<float>();
2605 creatureData.posZ = fields[6].Get<float>();
2606 creatureData.orientation = fields[7].Get<float>();
2607 creatureData.spawntimesecs = fields[8].Get<uint32>();
2608 creatureData.wander_distance = fields[9].Get<float>();
2609 creatureData.currentwaypoint = fields[10].Get<uint32>();
2610 creatureData.curhealth = fields[11].Get<uint32>();
2611 creatureData.curmana = fields[12].Get<uint32>();
2612 creatureData.movementType = fields[13].Get<uint8>();
2613 creatureData.spawnMask = fields[14].Get<uint8>();
2614 creatureData.phaseMask = fields[15].Get<uint32>();
2615 creatureData.npcflag = fields[16].Get<uint32>();
2616 creatureData.unit_flags = fields[17].Get<uint32>();
2617 creatureData.dynamicflags = fields[18].Get<uint32>();
2618 creatureData.ScriptId = GetScriptId(fields[19].Get<std::string>());
2619 creatureData.spawnGroupId = 0;
2620
2621 if (!creatureData.ScriptId)
2622 creatureData.ScriptId = cInfo->ScriptID;
2623
2624 // Load alternate entries from creature_multispawn
2625 QueryResult variantResult = WorldDatabase.Query("SELECT entry FROM creature_multispawn WHERE spawnId = {} ORDER BY entry", spawnId);
2626 if (variantResult)
2627 {
2628 do
2629 {
2630 uint32 variantEntry = variantResult->Fetch()[0].Get<uint32>();
2631 if (!GetCreatureTemplate(variantEntry))
2632 {
2633 LOG_ERROR("sql.sql", "Table `creature_multispawn` has creature (SpawnId: {}) with non-existing entry {}, skipped.", spawnId, variantEntry);
2634 continue;
2635 }
2636
2637 // Check difficulty entries for variant
2638 bool diffOk = true;
2639 for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && diffOk; ++diff)
2640 {
2641 if (_difficultyEntries[diff].find(variantEntry) != _difficultyEntries[diff].end())
2642 {
2643 LOG_ERROR("sql.sql", "Table `creature_multispawn` has creature (SpawnId: {}) with entry {} listed as difficulty template in `creature_template`, skipped.",
2644 spawnId, variantEntry);
2645 diffOk = false;
2646 }
2647 }
2648 if (!diffOk)
2649 continue;
2650
2651 // Validate equipment for variant entry
2652 if (creatureData.equipmentId != 0 && !GetEquipmentInfo(variantEntry, creatureData.equipmentId))
2653 {
2654 LOG_ERROR("sql.sql", "Table `creature_multispawn` has creature (SpawnId: {}) with entry {} where equipment_id {} not found in `creature_equip_template`.",
2655 spawnId, variantEntry, creatureData.equipmentId);
2656 }
2657
2658 if (!creatureData.id2)
2659 creatureData.id2 = variantEntry;
2660 else if (!creatureData.id3)
2661 creatureData.id3 = variantEntry;
2662 else
2663 LOG_ERROR("sql.sql", "Table `creature_multispawn` has more than 2 variant entries for creature (SpawnId: {}), extra entry {} skipped.", spawnId, variantEntry);
2664 } while (variantResult->NextRow());
2665 }
2666
2667 MapEntry const* mapEntry = sMapStore.LookupEntry(creatureData.mapid);
2668 if (!mapEntry)
2669 {
2670 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) that spawned at non-existing map (Id: {}), skipped.", spawnId, creatureData.mapid);
2671 _creatureDataStore.erase(spawnId);
2672 return nullptr;
2673 }
2674
2675 if (mapEntry->IsRaid() && creatureData.spawntimesecs >= 7 * DAY && creatureData.spawntimesecs < 14 * DAY)
2676 creatureData.spawntimesecs = 14 * DAY;
2677
2678 bool ok = true;
2679 for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff)
2680 {
2681 if (_difficultyEntries[diff].find(creatureId) != _difficultyEntries[diff].end())
2682 {
2683 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) that is listed as difficulty {} template (Entry: {}) in `creature_template`, skipped.",
2684 spawnId, diff + 1, creatureId);
2685 ok = false;
2686 }
2687 }
2688
2689 if (!ok)
2690 {
2691 _creatureDataStore.erase(spawnId);
2692 return nullptr;
2693 }
2694
2695 if (creatureData.equipmentId != 0)
2696 {
2697 if (!GetEquipmentInfo(creatureId, creatureData.equipmentId))
2698 {
2699 LOG_ERROR("sql.sql", "Table `creature` has creature (Entry: {}) with equipment_id {} not found in table `creature_equip_template`, set to no equipment.",
2700 creatureId, creatureData.equipmentId);
2701 creatureData.equipmentId = 0;
2702 }
2703 }
2704
2705 if (creatureData.movementType >= MAX_DB_MOTION_TYPE)
2706 {
2707 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entry: {}) with wrong movement generator type ({}), set to IDLE.",
2708 spawnId, creatureId, creatureData.movementType);
2709 creatureData.movementType = IDLE_MOTION_TYPE;
2710 }
2711
2712 if (creatureData.wander_distance < 0.0f)
2713 {
2714 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entry: {}) with `wander_distance`< 0, set to 0.",
2715 spawnId, creatureId);
2716 creatureData.wander_distance = 0.0f;
2717 }
2718 else if (creatureData.movementType == RANDOM_MOTION_TYPE)
2719 {
2720 if (creatureData.wander_distance == 0.0f)
2721 {
2722 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).",
2723 spawnId, creatureId);
2724 creatureData.movementType = IDLE_MOTION_TYPE;
2725 }
2726 }
2727 else if (creatureData.movementType == IDLE_MOTION_TYPE)
2728 {
2729 if (creatureData.wander_distance != 0.0f)
2730 {
2731 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entry: {}) with `MovementType`=0 (idle) have `wander_distance`<>0, set to 0.",
2732 spawnId, creatureId);
2733 creatureData.wander_distance = 0.0f;
2734 }
2735 }
2736
2737 if (creatureData.phaseMask == 0)
2738 {
2739 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entry: {}) with `phaseMask`=0 (not visible for anyone), set to 1.",
2740 spawnId, creatureId);
2741 creatureData.phaseMask = 1;
2742 }
2743
2744 return &creatureData;
2745}
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 ( )
10071{
10072 uint32 oldMSTime = getMSTime();
10073
10075
10076 if (QueryResult result = WorldDatabase.Query("SELECT CreatureId, TrainerId FROM creature_default_trainer"))
10077 {
10078 do
10079 {
10080 Field* fields = result->Fetch();
10081 uint32 creatureId = fields[0].Get<uint32>();
10082 uint32 trainerId = fields[1].Get<uint32>();
10083
10084 if (!GetCreatureTemplate(creatureId))
10085 {
10086 LOG_ERROR("sql.sql", "Table `creature_default_trainer` references non-existing creature template (CreatureId: %u), ignoring", creatureId);
10087 continue;
10088 }
10089
10090 _creatureDefaultTrainers[creatureId] = trainerId;
10091
10092 } while (result->NextRow());
10093 }
10094
10095 LOG_INFO("server.loading", ">> Loaded {} default trainers in {} ms", _creatureDefaultTrainers.size(), GetMSTimeDiffToNow(oldMSTime));
10096}

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 ( )
8921{
8922 LoadQuestRelationsHelper(_creatureQuestInvolvedRelations, "creature_questender", false, false);
8923
8924 for (QuestRelations::iterator itr = _creatureQuestInvolvedRelations.begin(); itr != _creatureQuestInvolvedRelations.end(); ++itr)
8925 {
8926 CreatureTemplate const* cInfo = GetCreatureTemplate(itr->first);
8927 if (!cInfo)
8928 LOG_ERROR("sql.sql", "Table `creature_questender` have data for not existed creature entry ({}) and existed quest {}", itr->first, itr->second);
8929 else if (!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER))
8930 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);
8931 }
8932}
@ UNIT_NPC_FLAG_QUESTGIVER
Definition UnitDefines.h:323
void LoadQuestRelationsHelper(QuestRelations &map, std::string const &table, bool starter, bool go)
Definition ObjectMgr.cpp:8833

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

Referenced by LoadQuestStartersAndEnders().

◆ LoadCreatureQuestItems()

void ObjectMgr::LoadCreatureQuestItems ( )
11096{
11097 uint32 oldMSTime = getMSTime();
11098
11099 // 0 1 2
11100 QueryResult result = WorldDatabase.Query("SELECT CreatureEntry, ItemId, Idx FROM creature_questitem ORDER BY Idx ASC");
11101
11102 if (!result)
11103 {
11104 LOG_WARN("server.loading", ">> Loaded 0 creature quest items. DB table `creature_questitem` is empty.");
11105 return;
11106 }
11107
11108 uint32 count = 0;
11109 do
11110 {
11111 Field* fields = result->Fetch();
11112
11113 uint32 entry = fields[0].Get<uint32>();
11114 uint32 item = fields[1].Get<uint32>();
11115 uint32 idx = fields[2].Get<uint32>();
11116
11117 CreatureTemplate const* creatureInfo = GetCreatureTemplate(entry);
11118 if (!creatureInfo)
11119 {
11120 LOG_ERROR("sql.sql", "Table `creature_questitem` has data for nonexistent creature (entry: {}, idx: {}), skipped", entry, idx);
11121 continue;
11122 };
11123
11124 ItemEntry const* dbcData = sItemStore.LookupEntry(item);
11125 if (!dbcData)
11126 {
11127 LOG_ERROR("sql.sql", "Table `creature_questitem` has nonexistent item (ID: {}) in creature (entry: {}, idx: {}), skipped", item, entry, idx);
11128 continue;
11129 };
11130
11131 _creatureQuestItemStore[entry].push_back(item);
11132
11133 ++count;
11134 } while (result->NextRow());
11135
11136 LOG_INFO("server.loading", ">> Loaded {} Creature Quest Items in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
11137 LOG_INFO("server.loading", " ");
11138}
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 ( )
8907{
8908 LoadQuestRelationsHelper(_creatureQuestRelations, "creature_queststarter", true, false);
8909
8910 for (QuestRelations::iterator itr = _creatureQuestRelations.begin(); itr != _creatureQuestRelations.end(); ++itr)
8911 {
8912 CreatureTemplate const* cInfo = GetCreatureTemplate(itr->first);
8913 if (!cInfo)
8914 LOG_ERROR("sql.sql", "Table `creature_queststarter` have data for not existed creature entry ({}) and existed quest {}", itr->first, itr->second);
8915 else if (!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER))
8916 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);
8917 }
8918}

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 data.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. Pooled spawns are in
2494 // the grid data too; the grid loader filters them by pool state.
2495 if (gameEvent == 0)
2496 AddCreatureToGrid(spawnId, &data);
2497
2498 ++count;
2499 } while (result->NextRow());
2500
2501 // Load alternate entries from creature_multispawn
2502 QueryResult variantResult = WorldDatabase.Query("SELECT spawnId, entry FROM creature_multispawn ORDER BY spawnId");
2503 if (variantResult)
2504 {
2505 uint32 variantCount = 0;
2506 do
2507 {
2508 Field* fields = variantResult->Fetch();
2509 ObjectGuid::LowType spawnId = fields[0].Get<uint32>();
2510 uint32 entry = fields[1].Get<uint32>();
2511
2512 auto creatureDataIt = _creatureDataStore.find(spawnId);
2513 if (creatureDataIt == _creatureDataStore.end())
2514 {
2515 LOG_ERROR("sql.sql", "Table `creature_multispawn` has entry for non-existing creature spawn (SpawnId: {}), skipped.", spawnId);
2516 continue;
2517 }
2518
2519 CreatureData* data = &creatureDataIt->second;
2520
2521 CreatureTemplate const* variantInfo = GetCreatureTemplate(entry);
2522 if (!variantInfo)
2523 {
2524 LOG_ERROR("sql.sql", "Table `creature_multispawn` has creature (SpawnId: {}) with non-existing creature entry {}, skipped.", spawnId, entry);
2525 continue;
2526 }
2527
2528 // Check difficulty entries for variant
2529 bool diffOk = true;
2530 for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && diffOk; ++diff)
2531 {
2532 if (_difficultyEntries[diff].find(entry) != _difficultyEntries[diff].end())
2533 {
2534 LOG_ERROR("sql.sql", "Table `creature_multispawn` has creature (SpawnId: {}) with entry {} listed as difficulty template in `creature_template`, skipped.",
2535 spawnId, entry);
2536 diffOk = false;
2537 }
2538 }
2539 if (!diffOk)
2540 continue;
2541
2542 // Validate equipment for variant entry
2543 if (data->equipmentId != 0 && !GetEquipmentInfo(entry, data->equipmentId))
2544 {
2545 LOG_ERROR("sql.sql", "Table `creature_multispawn` has creature (SpawnId: {}) with entry {} where equipment_id {} not found in `creature_equip_template`.",
2546 spawnId, entry, data->equipmentId);
2547 }
2548
2549 // Populate id2/id3 fields
2550 if (!data->id2)
2551 {
2552 data->id2 = entry;
2553 ++variantCount;
2554 }
2555 else if (!data->id3)
2556 {
2557 data->id3 = entry;
2558 ++variantCount;
2559 }
2560 else
2561 LOG_ERROR("sql.sql", "Table `creature_multispawn` has more than 2 variant entries for creature (SpawnId: {}), extra entry {} skipped.", spawnId, entry);
2562 } while (variantResult->NextRow());
2563
2564 LOG_INFO("server.loading", ">> Loaded {} creature spawn variants", variantCount);
2565 }
2566
2567 LOG_INFO("server.loading", ">> Loaded {} Creatures in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2568 LOG_INFO("server.loading", " ");
2569}
@ 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:114
@ WORLD_UPD_CREATURE_ZONE_AREA_DATA
Definition WorldDatabase.h:116
uint32 ScriptId
Definition SpawnData.h:76
uint32 poolId
Definition SpawnData.h:79

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

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:743
@ 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 ( )
6270{
6272
6273 std::set<uint32> evt_scripts;
6274 // Load all possible script entries from gameobjects
6276 for (GameObjectTemplateContainer::const_iterator itr = gotc->begin(); itr != gotc->end(); ++itr)
6277 if (uint32 eventId = itr->second.GetEventScriptId())
6278 evt_scripts.insert(eventId);
6279
6280 // Load all possible script entries from spells
6281 for (uint32 i = 1; i < sSpellMgr->GetSpellInfoStoreSize(); ++i)
6282 if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(i))
6283 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
6284 if (spell->Effects[j].Effect == SPELL_EFFECT_SEND_EVENT)
6285 if (spell->Effects[j].MiscValue)
6286 evt_scripts.insert(spell->Effects[j].MiscValue);
6287
6288 for (std::size_t path_idx = 0; path_idx < sTaxiPathNodesByPath.size(); ++path_idx)
6289 {
6290 for (std::size_t node_idx = 0; node_idx < sTaxiPathNodesByPath[path_idx].size(); ++node_idx)
6291 {
6292 TaxiPathNodeEntry const* node = sTaxiPathNodesByPath[path_idx][node_idx];
6293
6294 if (node->arrivalEventID)
6295 evt_scripts.insert(node->arrivalEventID);
6296
6297 if (node->departureEventID)
6298 evt_scripts.insert(node->departureEventID);
6299 }
6300 }
6301
6302 // Then check if all scripts are in above list of possible script entries
6303 for (ScriptMapMap::const_iterator itr = sEventScripts.begin(); itr != sEventScripts.end(); ++itr)
6304 {
6305 std::set<uint32>::const_iterator itr2 = evt_scripts.find(itr->first);
6306 if (itr2 == evt_scripts.end())
6307 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 {}",
6308 itr->first, SPELL_EFFECT_SEND_EVENT);
6309 }
6310}
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:5927
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 ( )
8033{
8034 uint32 oldMSTime = getMSTime();
8035
8036 QueryResult result = WorldDatabase.Query("SELECT level, basexp FROM exploration_basexp");
8037
8038 if (!result)
8039 {
8040 LOG_WARN("server.loading", ">> Loaded 0 BaseXP definitions. DB table `exploration_basexp` is empty.");
8041 LOG_INFO("server.loading", " ");
8042 return;
8043 }
8044
8045 uint32 count = 0;
8046
8047 do
8048 {
8049 Field* fields = result->Fetch();
8050 uint8 level = fields[0].Get<uint8>();
8051 uint32 basexp = fields[1].Get<int32>();
8052 _baseXPTable[level] = basexp;
8053 ++count;
8054 } while (result->NextRow());
8055
8056 LOG_INFO("server.loading", ">> Loaded {} BaseXP Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8057 LOG_INFO("server.loading", " ");
8058}

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

◆ LoadFactionChangeAchievements()

void ObjectMgr::LoadFactionChangeAchievements ( )
10778{
10779 uint32 oldMSTime = getMSTime();
10780
10781 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_achievement");
10782
10783 if (!result)
10784 {
10785 LOG_WARN("server.loading", ">> Loaded 0 faction change achievement pairs. DB table `player_factionchange_achievement` is empty.");
10786 LOG_INFO("server.loading", " ");
10787 return;
10788 }
10789
10790 uint32 count = 0;
10791
10792 do
10793 {
10794 Field* fields = result->Fetch();
10795
10796 uint32 alliance = fields[0].Get<uint32>();
10797 uint32 horde = fields[1].Get<uint32>();
10798
10799 if (!sAchievementStore.LookupEntry(alliance))
10800 LOG_ERROR("sql.sql", "Achievement {} (alliance_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", alliance);
10801 else if (!sAchievementStore.LookupEntry(horde))
10802 LOG_ERROR("sql.sql", "Achievement {} (horde_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", horde);
10803 else
10804 FactionChangeAchievements[alliance] = horde;
10805
10806 ++count;
10807 } while (result->NextRow());
10808
10809 LOG_INFO("server.loading", ">> Loaded {} faction change achievement pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10810 LOG_INFO("server.loading", " ");
10811}
CharacterConversionMap FactionChangeAchievements
Definition ObjectMgr.h:1503

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

◆ LoadFactionChangeItems()

void ObjectMgr::LoadFactionChangeItems ( )
10814{
10815 uint32 oldMSTime = getMSTime();
10816
10817 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_items");
10818
10819 if (!result)
10820 {
10821 LOG_WARN("server.loading", ">> Loaded 0 faction change item pairs. DB table `player_factionchange_items` is empty.");
10822 LOG_INFO("server.loading", " ");
10823 return;
10824 }
10825
10826 uint32 count = 0;
10827
10828 do
10829 {
10830 Field* fields = result->Fetch();
10831
10832 uint32 alliance = fields[0].Get<uint32>();
10833 uint32 horde = fields[1].Get<uint32>();
10834
10835 if (!GetItemTemplate(alliance))
10836 LOG_ERROR("sql.sql", "Item {} (alliance_id) referenced in `player_factionchange_items` does not exist, pair skipped!", alliance);
10837 else if (!GetItemTemplate(horde))
10838 LOG_ERROR("sql.sql", "Item {} (horde_id) referenced in `player_factionchange_items` does not exist, pair skipped!", horde);
10839 else
10840 FactionChangeItems[alliance] = horde;
10841
10842 ++count;
10843 } while (result->NextRow());
10844
10845 LOG_INFO("server.loading", ">> Loaded {} faction change item pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10846 LOG_INFO("server.loading", " ");
10847}
CharacterConversionMap FactionChangeItems
Definition ObjectMgr.h:1504

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

◆ LoadFactionChangeQuests()

void ObjectMgr::LoadFactionChangeQuests ( )
10850{
10851 uint32 oldMSTime = getMSTime();
10852
10853 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_quests");
10854
10855 if (!result)
10856 {
10857 LOG_WARN("server.loading", ">> Loaded 0 faction change quest pairs. DB table `player_factionchange_quests` is empty.");
10858 LOG_INFO("server.loading", " ");
10859 return;
10860 }
10861
10862 uint32 count = 0;
10863
10864 do
10865 {
10866 Field* fields = result->Fetch();
10867
10868 uint32 alliance = fields[0].Get<uint32>();
10869 uint32 horde = fields[1].Get<uint32>();
10870
10871 if (!GetQuestTemplate(alliance))
10872 LOG_ERROR("sql.sql", "Quest {} (alliance_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", alliance);
10873 else if (!GetQuestTemplate(horde))
10874 LOG_ERROR("sql.sql", "Quest {} (horde_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", horde);
10875 else
10876 FactionChangeQuests[alliance] = horde;
10877
10878 ++count;
10879 } while (result->NextRow());
10880
10881 LOG_INFO("server.loading", ">> Loaded {} faction change quest pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10882 LOG_INFO("server.loading", " ");
10883}
CharacterConversionMap FactionChangeQuests
Definition ObjectMgr.h:1505

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

◆ LoadFactionChangeReputations()

void ObjectMgr::LoadFactionChangeReputations ( )
10886{
10887 uint32 oldMSTime = getMSTime();
10888
10889 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_reputations");
10890
10891 if (!result)
10892 {
10893 LOG_WARN("server.loading", ">> Loaded 0 faction change reputation pairs. DB table `player_factionchange_reputations` is empty.");
10894 LOG_INFO("server.loading", " ");
10895 return;
10896 }
10897
10898 uint32 count = 0;
10899
10900 do
10901 {
10902 Field* fields = result->Fetch();
10903
10904 uint32 alliance = fields[0].Get<uint32>();
10905 uint32 horde = fields[1].Get<uint32>();
10906
10907 if (!sFactionStore.LookupEntry(alliance))
10908 LOG_ERROR("sql.sql", "Reputation {} (alliance_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", alliance);
10909 else if (!sFactionStore.LookupEntry(horde))
10910 LOG_ERROR("sql.sql", "Reputation {} (horde_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", horde);
10911 else
10912 FactionChangeReputation[alliance] = horde;
10913
10914 ++count;
10915 } while (result->NextRow());
10916
10917 LOG_INFO("server.loading", ">> Loaded {} faction change reputation pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10918 LOG_INFO("server.loading", " ");
10919}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
CharacterConversionMap FactionChangeReputation
Definition ObjectMgr.h:1506

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

◆ LoadFactionChangeSpells()

void ObjectMgr::LoadFactionChangeSpells ( )
10922{
10923 uint32 oldMSTime = getMSTime();
10924
10925 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_spells");
10926
10927 if (!result)
10928 {
10929 LOG_WARN("server.loading", ">> Loaded 0 faction change spell pairs. DB table `player_factionchange_spells` is empty.");
10930 LOG_INFO("server.loading", " ");
10931 return;
10932 }
10933
10934 uint32 count = 0;
10935
10936 do
10937 {
10938 Field* fields = result->Fetch();
10939
10940 uint32 alliance = fields[0].Get<uint32>();
10941 uint32 horde = fields[1].Get<uint32>();
10942
10943 if (!sSpellMgr->GetSpellInfo(alliance))
10944 LOG_ERROR("sql.sql", "Spell {} (alliance_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", alliance);
10945 else if (!sSpellMgr->GetSpellInfo(horde))
10946 LOG_ERROR("sql.sql", "Spell {} (horde_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", horde);
10947 else
10948 FactionChangeSpells[alliance] = horde;
10949
10950 ++count;
10951 } while (result->NextRow());
10952
10953 LOG_INFO("server.loading", ">> Loaded {} faction change spell pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10954 LOG_INFO("server.loading", " ");
10955}
CharacterConversionMap FactionChangeSpells
Definition ObjectMgr.h:1507

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

◆ LoadFactionChangeTitles()

void ObjectMgr::LoadFactionChangeTitles ( )
10958{
10959 uint32 oldMSTime = getMSTime();
10960
10961 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_titles");
10962
10963 if (!result)
10964 {
10965 LOG_WARN("server.loading", ">> Loaded 0 faction change title pairs. DB table `player_factionchange_title` is empty.");
10966 return;
10967 }
10968
10969 uint32 count = 0;
10970
10971 do
10972 {
10973 Field* fields = result->Fetch();
10974
10975 uint32 alliance = fields[0].Get<uint32>();
10976 uint32 horde = fields[1].Get<uint32>();
10977
10978 if (!sCharTitlesStore.LookupEntry(alliance))
10979 LOG_ERROR("sql.sql", "Title {} (alliance_id) referenced in `player_factionchange_title` does not exist, pair skipped!", alliance);
10980 else if (!sCharTitlesStore.LookupEntry(horde))
10981 LOG_ERROR("sql.sql", "Title {} (horde_id) referenced in `player_factionchange_title` does not exist, pair skipped!", horde);
10982 else
10983 FactionChangeTitles[alliance] = horde;
10984
10985 ++count;
10986 } while (result->NextRow());
10987
10988 LOG_INFO("server.loading", ">> Loaded {} faction change title pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10989 LOG_INFO("server.loading", " ");
10990}
DBCStorage< CharTitlesEntry > sCharTitlesStore(CharTitlesEntryfmt)
CharacterConversionMap FactionChangeTitles
Definition ObjectMgr.h:1508

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

◆ LoadFishingBaseSkillLevel()

void ObjectMgr::LoadFishingBaseSkillLevel ( )
9602{
9603 uint32 oldMSTime = getMSTime();
9604
9605 _fishingBaseForAreaStore.clear(); // for reload case
9606
9607 QueryResult result = WorldDatabase.Query("SELECT entry, skill FROM skill_fishing_base_level");
9608
9609 if (!result)
9610 {
9611 LOG_WARN("server.loading", ">> Loaded 0 areas for fishing base skill level. DB table `skill_fishing_base_level` is empty.");
9612 LOG_INFO("server.loading", " ");
9613 return;
9614 }
9615
9616 uint32 count = 0;
9617
9618 do
9619 {
9620 Field* fields = result->Fetch();
9621 uint32 entry = fields[0].Get<uint32>();
9622 int32 skill = fields[1].Get<int16>();
9623
9624 AreaTableEntry const* fArea = sAreaTableStore.LookupEntry(entry);
9625 if (!fArea)
9626 {
9627 LOG_ERROR("sql.sql", "AreaId {} defined in `skill_fishing_base_level` does not exist", entry);
9628 continue;
9629 }
9630
9631 _fishingBaseForAreaStore[entry] = skill;
9632 ++count;
9633 } while (result->NextRow());
9634
9635 LOG_INFO("server.loading", ">> Loaded {} areas for fishing base skill level in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9636 LOG_INFO("server.loading", " ");
9637}

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.
3110{
3111 GameObjectData const* data = GetGameObjectData(spawnId);
3112 if (data)
3113 return data;
3114
3115 QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
3116 "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, "
3117 "ScriptName "
3118 "FROM gameobject WHERE gameobject.guid = {}", spawnId);
3119
3120 if (!result)
3121 return nullptr;
3122
3123 Field* fields = result->Fetch();
3124 uint32 entry = fields[1].Get<uint32>();
3125
3126 GameObjectTemplate const* gInfo = GetGameObjectTemplate(entry);
3127 if (!gInfo)
3128 {
3129 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {}) with non-existing gameobject entry {}, skipped.", spawnId, entry);
3130 return nullptr;
3131 }
3132
3133 if (gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId))
3134 {
3135 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry {} GoType: {}) with an invalid displayId ({}), not loaded.",
3136 spawnId, entry, gInfo->type, gInfo->displayId);
3137 return nullptr;
3138 }
3139
3141 goData.id = entry;
3142 goData.mapid = fields[2].Get<uint16>();
3143 goData.posX = fields[3].Get<float>();
3144 goData.posY = fields[4].Get<float>();
3145 goData.posZ = fields[5].Get<float>();
3146 goData.orientation = fields[6].Get<float>();
3147 goData.rotation.x = fields[7].Get<float>();
3148 goData.rotation.y = fields[8].Get<float>();
3149 goData.rotation.z = fields[9].Get<float>();
3150 goData.rotation.w = fields[10].Get<float>();
3151 goData.spawntimesecs = fields[11].Get<int32>();
3152 goData.animprogress = fields[12].Get<uint8>();
3153 goData.artKit = 0;
3154 goData.ScriptId = GetScriptId(fields[16].Get<std::string>());
3155
3156 if (!goData.ScriptId)
3157 goData.ScriptId = gInfo->ScriptId;
3158
3159 MapEntry const* mapEntry = sMapStore.LookupEntry(goData.mapid);
3160 if (!mapEntry)
3161 {
3162 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) spawned on a non-existing map (Id: {}), skipped.", spawnId, entry, goData.mapid);
3163 _gameObjectDataStore.erase(spawnId);
3164 return nullptr;
3165 }
3166
3167 if (goData.spawntimesecs == 0 && gInfo->IsDespawnAtAction())
3168 {
3169 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);
3170 }
3171
3172 uint32 go_state = fields[13].Get<uint8>();
3173 if (go_state >= MAX_GO_STATE)
3174 {
3175 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid `state` ({}) value, skipped.", spawnId, entry, go_state);
3176 _gameObjectDataStore.erase(spawnId);
3177 return nullptr;
3178 }
3179 goData.go_state = GOState(go_state);
3180
3181 goData.spawnMask = fields[14].Get<uint8>();
3182 goData.phaseMask = fields[15].Get<uint32>();
3183
3184 if (goData.rotation.x < -1.0f || goData.rotation.x > 1.0f)
3185 {
3186 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationX ({}) value, skipped.", spawnId, entry, goData.rotation.x);
3187 _gameObjectDataStore.erase(spawnId);
3188 return nullptr;
3189 }
3190
3191 if (goData.rotation.y < -1.0f || goData.rotation.y > 1.0f)
3192 {
3193 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationY ({}) value, skipped.", spawnId, entry, goData.rotation.y);
3194 _gameObjectDataStore.erase(spawnId);
3195 return nullptr;
3196 }
3197
3198 if (goData.rotation.z < -1.0f || goData.rotation.z > 1.0f)
3199 {
3200 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationZ ({}) value, skipped.", spawnId, entry, goData.rotation.z);
3201 _gameObjectDataStore.erase(spawnId);
3202 return nullptr;
3203 }
3204
3205 if (goData.rotation.w < -1.0f || goData.rotation.w > 1.0f)
3206 {
3207 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationW ({}) value, skipped.", spawnId, entry, goData.rotation.w);
3208 _gameObjectDataStore.erase(spawnId);
3209 return nullptr;
3210 }
3211
3212 if (fabs(goData.rotation.x * goData.rotation.x + goData.rotation.y * goData.rotation.y +
3213 goData.rotation.z * goData.rotation.z + goData.rotation.w * goData.rotation.w - 1.0f) >= 1e-5f)
3214 {
3215 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);
3216 goData.rotation = G3D::Quat(G3D::Matrix3::fromEulerAnglesZYX(goData.orientation, 0.0f, 0.0f));
3217 }
3218
3219 if (!MapMgr::IsValidMapCoord(goData.mapid, goData.posX, goData.posY, goData.posZ, goData.orientation))
3220 {
3221 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid coordinates, skipped.", spawnId, entry);
3222 _gameObjectDataStore.erase(spawnId);
3223 return nullptr;
3224 }
3225
3226 if (goData.phaseMask == 0)
3227 {
3228 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with `phaseMask`=0 (not visible for anyone), set to 1.", spawnId, entry);
3229 goData.phaseMask = 1;
3230 }
3231
3232 return &goData;
3233}
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 ( )
9388{
9389 uint32 oldMSTime = getMSTime();
9390
9391 if (GetGameObjectTemplates()->empty())
9392 {
9393 LOG_WARN("server.loading", ">> Loaded 0 GameObjects for quests");
9394 LOG_INFO("server.loading", " ");
9395 return;
9396 }
9397
9398 uint32 count = 0;
9399
9400 // collect GO entries for GO that must activated
9402 for (GameObjectTemplateContainer::iterator itr = gotc->begin(); itr != gotc->end(); ++itr)
9403 {
9404 itr->second.IsForQuests = false;
9405 switch (itr->second.type)
9406 {
9408 itr->second.IsForQuests = true;
9409 ++count;
9410 break;
9412 {
9413 // scan GO chest with loot including quest items
9414 uint32 loot_id = (itr->second.GetLootId());
9415
9416 // find quest loot for GO
9417 if (itr->second.chest.questId || LootTemplates_Gameobject.HaveQuestLootFor(loot_id))
9418 {
9419 itr->second.IsForQuests = true;
9420 ++count;
9421 }
9422 break;
9423 }
9425 {
9426 if (itr->second._generic.questID > 0) //quests objects
9427 {
9428 itr->second.IsForQuests = true;
9429 ++count;
9430 }
9431 break;
9432 }
9434 {
9435 if (itr->second.spellFocus.questID > 0) //quests objects
9436 {
9437 itr->second.IsForQuests = true;
9438 ++count;
9439 }
9440 break;
9441 }
9443 {
9444 if (itr->second.goober.questId > 0) //quests objects
9445 {
9446 itr->second.IsForQuests = true;
9447 ++count;
9448 }
9449 break;
9450 }
9451 default:
9452 break;
9453 }
9454 }
9455
9456 LOG_INFO("server.loading", ">> Loaded {} GameObjects for quests in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9457 LOG_INFO("server.loading", " ");
9458}
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 ( )
7677{
7678 uint32 oldMSTime = getMSTime();
7679
7680 _gameObjectLocaleStore.clear(); // need for reload case
7681
7682 // 0 1 2 3
7683 QueryResult result = WorldDatabase.Query("SELECT entry, locale, name, castBarCaption FROM gameobject_template_locale");
7684 if (!result)
7685 return;
7686
7687 do
7688 {
7689 Field* fields = result->Fetch();
7690
7691 uint32 ID = fields[0].Get<uint32>();
7692
7693 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
7694 if (locale == LOCALE_enUS)
7695 continue;
7696
7698 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
7699 AddLocaleString(fields[3].Get<std::string>(), locale, data.CastBarCaption);
7700 } while (result->NextRow());
7701
7702 LOG_INFO("server.loading", ">> Loaded {} Gameobject Locale Strings in {} ms", (uint32)_gameObjectLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
7703}
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 ( )
8893{
8894 LoadQuestRelationsHelper(_goQuestInvolvedRelations, "gameobject_questender", false, true);
8895
8896 for (QuestRelations::iterator itr = _goQuestInvolvedRelations.begin(); itr != _goQuestInvolvedRelations.end(); ++itr)
8897 {
8898 GameObjectTemplate const* goInfo = GetGameObjectTemplate(itr->first);
8899 if (!goInfo)
8900 LOG_ERROR("sql.sql", "Table `gameobject_questender` have data for not existed gameobject entry ({}) and existed quest {}", itr->first, itr->second);
8901 else if (goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER)
8902 LOG_ERROR("sql.sql", "Table `gameobject_questender` have data gameobject entry ({}) for quest {}, but GO is not GAMEOBJECT_TYPE_QUESTGIVER", itr->first, itr->second);
8903 }
8904}

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

Referenced by LoadQuestStartersAndEnders().

◆ LoadGameObjectQuestItems()

void ObjectMgr::LoadGameObjectQuestItems ( )
11051{
11052 uint32 oldMSTime = getMSTime();
11053
11054 // 0 1 2
11055 QueryResult result = WorldDatabase.Query("SELECT GameObjectEntry, ItemId, Idx FROM gameobject_questitem ORDER BY Idx ASC");
11056
11057 if (!result)
11058 {
11059 LOG_WARN("server.loading", ">> Loaded 0 gameobject quest items. DB table `gameobject_questitem` is empty.");
11060 return;
11061 }
11062
11063 uint32 count = 0;
11064 do
11065 {
11066 Field* fields = result->Fetch();
11067
11068 uint32 entry = fields[0].Get<uint32>();
11069 uint32 item = fields[1].Get<uint32>();
11070 uint32 idx = fields[2].Get<uint32>();
11071
11072 GameObjectTemplate const* goInfo = GetGameObjectTemplate(entry);
11073 if (!goInfo)
11074 {
11075 LOG_ERROR("sql.sql", "Table `gameobject_questitem` has data for nonexistent gameobject (entry: {}, idx: {}), skipped", entry, idx);
11076 continue;
11077 };
11078
11079 ItemEntry const* dbcData = sItemStore.LookupEntry(item);
11080 if (!dbcData)
11081 {
11082 LOG_ERROR("sql.sql", "Table `gameobject_questitem` has nonexistent item (ID: {}) in gameobject (entry: {}, idx: {}), skipped", item, entry, idx);
11083 continue;
11084 };
11085
11086 _gameObjectQuestItemStore[entry].push_back(item);
11087
11088 ++count;
11089 } while (result->NextRow());
11090
11091 LOG_INFO("server.loading", ">> Loaded {} Gameobject Quest Items in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
11092 LOG_INFO("server.loading", " ");
11093}

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

◆ LoadGameobjectQuestStarters()

void ObjectMgr::LoadGameobjectQuestStarters ( )
8879{
8880 LoadQuestRelationsHelper(_goQuestRelations, "gameobject_queststarter", true, true);
8881
8882 for (QuestRelations::iterator itr = _goQuestRelations.begin(); itr != _goQuestRelations.end(); ++itr)
8883 {
8884 GameObjectTemplate const* goInfo = GetGameObjectTemplate(itr->first);
8885 if (!goInfo)
8886 LOG_ERROR("sql.sql", "Table `gameobject_queststarter` have data for not existed gameobject entry ({}) and existed quest {}", itr->first, itr->second);
8887 else if (goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER)
8888 LOG_ERROR("sql.sql", "Table `gameobject_queststarter` have data gameobject entry ({}) for quest {}, but GO is not GAMEOBJECT_TYPE_QUESTGIVER", itr->first, itr->second);
8889 }
8890}

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

Referenced by LoadQuestStartersAndEnders().

◆ LoadGameobjects()

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

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::poolId, 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 ( )
7765{
7766 uint32 oldMSTime = getMSTime();
7767
7768 // 0 1 2 3 4 5 6 7
7769 QueryResult result = WorldDatabase.Query("SELECT entry, type, displayId, name, IconName, castBarCaption, unk1, size, "
7770 // 8 9 10 11 12 13 14 15 16 17 18 19 20
7771 "Data0, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11, Data12, "
7772 // 21 22 23 24 25 26 27 28 29 30 31 32 33
7773 "Data13, Data14, Data15, Data16, Data17, Data18, Data19, Data20, Data21, Data22, Data23, AIName, ScriptName "
7774 "FROM gameobject_template");
7775
7776 if (!result)
7777 {
7778 LOG_WARN("server.loading", ">> Loaded 0 gameobject definitions. DB table `gameobject_template` is empty.");
7779 LOG_INFO("server.loading", " ");
7780 return;
7781 }
7782
7783 _gameObjectTemplateStore.rehash(result->GetRowCount());
7784 uint32 count = 0;
7785 do
7786 {
7787 Field* fields = result->Fetch();
7788
7789 uint32 entry = fields[0].Get<uint32>();
7790
7792
7793 got.entry = entry;
7794 got.type = uint32(fields[1].Get<uint8>());
7795 got.displayId = fields[2].Get<uint32>();
7796 got.name = fields[3].Get<std::string>();
7797 got.IconName = fields[4].Get<std::string>();
7798 got.castBarCaption = fields[5].Get<std::string>();
7799 got.unk1 = fields[6].Get<std::string>();
7800 got.size = fields[7].Get<float>();
7801
7802 for (uint8 i = 0; i < MAX_GAMEOBJECT_DATA; ++i)
7803 got.raw.data[i] = fields[8 + i].Get<int32>(); // data1 and data6 can be -1
7804
7805 got.AIName = fields[32].Get<std::string>();
7806 got.ScriptId = GetScriptId(fields[33].Get<std::string>());
7807 got.IsForQuests = false;
7808
7809 // Checks
7810 if (!got.AIName.empty() && !sGameObjectAIRegistry->HasItem(got.AIName))
7811 {
7812 LOG_ERROR("sql.sql", "GameObject (Entry: {}) has non-registered `AIName` '{}' set, removing", got.entry, got.AIName);
7813 }
7814
7815 switch (got.type)
7816 {
7817 case GAMEOBJECT_TYPE_DOOR: //0
7818 {
7819 if (got.door.lockId)
7820 CheckGOLockId(&got, got.door.lockId, 1);
7821 CheckGONoDamageImmuneId(&got, got.door.noDamageImmune, 3);
7822 break;
7823 }
7824 case GAMEOBJECT_TYPE_BUTTON: //1
7825 {
7826 if (got.button.lockId)
7827 CheckGOLockId(&got, got.button.lockId, 1);
7828 CheckGONoDamageImmuneId(&got, got.button.noDamageImmune, 4);
7829 break;
7830 }
7832 {
7833 if (got.questgiver.lockId)
7834 CheckGOLockId(&got, got.questgiver.lockId, 0);
7835 CheckGONoDamageImmuneId(&got, got.questgiver.noDamageImmune, 5);
7836 break;
7837 }
7838 case GAMEOBJECT_TYPE_CHEST: //3
7839 {
7840 if (got.chest.lockId)
7841 CheckGOLockId(&got, got.chest.lockId, 0);
7842
7843 CheckGOConsumable(&got, got.chest.consumable, 3);
7844
7845 if (got.chest.linkedTrapId) // linked trap
7846 CheckGOLinkedTrapId(&got, got.chest.linkedTrapId, 7);
7847 break;
7848 }
7849 case GAMEOBJECT_TYPE_TRAP: //6
7850 {
7851 if (got.trap.lockId)
7852 CheckGOLockId(&got, got.trap.lockId, 0);
7853 break;
7854 }
7855 case GAMEOBJECT_TYPE_CHAIR: //7
7856 CheckAndFixGOChairHeightId(&got, got.chair.height, 1);
7857 break;
7859 {
7860 if (got.spellFocus.focusId)
7861 {
7862 if (!sSpellFocusObjectStore.LookupEntry(got.spellFocus.focusId))
7863 LOG_ERROR("sql.sql", "GameObject (Entry: {} GoType: {}) have data0={} but SpellFocus (Id: {}) not exist.",
7864 entry, got.type, got.spellFocus.focusId, got.spellFocus.focusId);
7865 }
7866
7867 if (got.spellFocus.linkedTrapId) // linked trap
7868 CheckGOLinkedTrapId(&got, got.spellFocus.linkedTrapId, 2);
7869 break;
7870 }
7871 case GAMEOBJECT_TYPE_GOOBER: //10
7872 {
7873 if (got.goober.lockId)
7874 CheckGOLockId(&got, got.goober.lockId, 0);
7875
7876 CheckGOConsumable(&got, got.goober.consumable, 3);
7877
7878 if (got.goober.pageId) // pageId
7879 {
7880 if (!GetPageText(got.goober.pageId))
7881 LOG_ERROR("sql.sql", "GameObject (Entry: {} GoType: {}) have data7={} but PageText (Entry {}) not exist.",
7882 entry, got.type, got.goober.pageId, got.goober.pageId);
7883 }
7884 CheckGONoDamageImmuneId(&got, got.goober.noDamageImmune, 11);
7885 if (got.goober.linkedTrapId) // linked trap
7886 CheckGOLinkedTrapId(&got, got.goober.linkedTrapId, 12);
7887 break;
7888 }
7890 {
7891 if (got.areadamage.lockId)
7892 CheckGOLockId(&got, got.areadamage.lockId, 0);
7893 break;
7894 }
7895 case GAMEOBJECT_TYPE_CAMERA: //13
7896 {
7897 if (got.camera.lockId)
7898 CheckGOLockId(&got, got.camera.lockId, 0);
7899 break;
7900 }
7902 {
7903 if (got.moTransport.taxiPathId)
7904 {
7905 if (got.moTransport.taxiPathId >= sTaxiPathNodesByPath.size() || sTaxiPathNodesByPath[got.moTransport.taxiPathId].empty())
7906 LOG_ERROR("sql.sql", "GameObject (Entry: {} GoType: {}) have data0={} but TaxiPath (Id: {}) not exist.",
7907 entry, got.type, got.moTransport.taxiPathId, got.moTransport.taxiPathId);
7908 }
7909 if (uint32 transportMap = got.moTransport.mapID)
7910 _transportMaps.insert(transportMap);
7911 break;
7912 }
7914 break;
7916 {
7917 // always must have spell
7918 CheckGOSpellId(&got, got.spellcaster.spellId, 0);
7919 break;
7920 }
7921 case GAMEOBJECT_TYPE_FLAGSTAND: //24
7922 {
7923 if (got.flagstand.lockId)
7924 CheckGOLockId(&got, got.flagstand.lockId, 0);
7925 CheckGONoDamageImmuneId(&got, got.flagstand.noDamageImmune, 5);
7926 break;
7927 }
7929 {
7930 if (got.fishinghole.lockId)
7931 CheckGOLockId(&got, got.fishinghole.lockId, 4);
7932 break;
7933 }
7934 case GAMEOBJECT_TYPE_FLAGDROP: //26
7935 {
7936 if (got.flagdrop.lockId)
7937 CheckGOLockId(&got, got.flagdrop.lockId, 0);
7938 CheckGONoDamageImmuneId(&got, got.flagdrop.noDamageImmune, 3);
7939 break;
7940 }
7942 CheckAndFixGOChairHeightId(&got, got.barberChair.chairheight, 0);
7943 break;
7944 }
7945
7946 ++count;
7947 } while (result->NextRow());
7948
7949 LOG_INFO("server.loading", ">> Loaded {} Game Object Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7950 LOG_INFO("server.loading", " ");
7951}
DBCStorage< SpellFocusObjectEntry > sSpellFocusObjectStore(SpellFocusObjectfmt)
#define sGameObjectAIRegistry
Definition GameObjectAIFactory.h:49
void CheckGONoDamageImmuneId(GameObjectTemplate *goTemplate, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7745
void CheckGOSpellId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7724
void CheckAndFixGOChairHeightId(GameObjectTemplate const *goInfo, uint32 const &dataN, uint32 N)
Definition ObjectMgr.cpp:7733
void CheckGOConsumable(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7754
void CheckGOLinkedTrapId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7714
void CheckGOLockId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7705
@ 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:6511
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 ( )
7954{
7955 uint32 oldMSTime = getMSTime();
7956
7957 // 0 1 2 3 4 5 6 7 8
7958 QueryResult result = WorldDatabase.Query("SELECT entry, faction, flags, mingold, maxgold, artkit0, artkit1, artkit2, artkit3 FROM gameobject_template_addon");
7959
7960 if (!result)
7961 {
7962 LOG_WARN("server.loading", ">> Loaded 0 gameobject template addon definitions. DB table `gameobject_template_addon` is empty.");
7963 LOG_INFO("server.loading", " ");
7964 return;
7965 }
7966
7967 uint32 count = 0;
7968 do
7969 {
7970 Field* fields = result->Fetch();
7971
7972 uint32 entry = fields[0].Get<uint32>();
7973
7974 GameObjectTemplate const* got = GetGameObjectTemplate(entry);
7975 if (!got)
7976 {
7977 LOG_ERROR("sql.sql",
7978 "GameObject template (Entry: {}) does not exist but has a record in `gameobject_template_addon`",
7979 entry);
7980 continue;
7981 }
7982
7984 gameObjectAddon.faction = uint32(fields[1].Get<uint16>());
7985 gameObjectAddon.flags = fields[2].Get<uint32>();
7986 gameObjectAddon.mingold = fields[3].Get<uint32>();
7987 gameObjectAddon.maxgold = fields[4].Get<uint32>();
7988
7989 for (uint32 i = 0; i < gameObjectAddon.artKits.size(); i++)
7990 {
7991 uint32 artKitID = fields[5 + i].Get<uint32>();
7992 if (!artKitID)
7993 continue;
7994
7995 if (!sGameObjectArtKitStore.LookupEntry(artKitID))
7996 {
7997 LOG_ERROR("sql.sql", "GameObject (Entry: {}) has invalid `artkit{}` {} defined, set to zero instead.", entry, i, artKitID);
7998 continue;
7999 }
8000
8001 gameObjectAddon.artKits[i] = artKitID;
8002 }
8003
8004 // checks
8005 if (gameObjectAddon.faction && !sFactionTemplateStore.LookupEntry(gameObjectAddon.faction))
8006 LOG_ERROR("sql.sql",
8007 "GameObject (Entry: {}) has invalid faction ({}) defined in `gameobject_template_addon`.",
8008 entry, gameObjectAddon.faction);
8009
8010 if (gameObjectAddon.maxgold > 0)
8011 {
8012 switch (got->type)
8013 {
8016 break;
8017 default:
8018 LOG_ERROR("sql.sql",
8019 "GameObject (Entry {} GoType: {}) cannot be looted but has maxgold set in `gameobject_template_addon`.",
8020 entry, got->type);
8021 break;
8022 }
8023 }
8024
8025 ++count;
8026 } while (result->NextRow());
8027
8028 LOG_INFO("server.loading", ">> Loaded {} Game Object Template Addons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8029 LOG_INFO("server.loading", " ");
8030}
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 ( )
9742{
9743 uint32 oldMSTime = getMSTime();
9744
9745 _gameTeleStore.clear(); // for reload case
9746
9747 // 0 1 2 3 4 5 6
9748 QueryResult result = WorldDatabase.Query("SELECT id, position_x, position_y, position_z, orientation, map, name FROM game_tele");
9749
9750 if (!result)
9751 {
9752 LOG_WARN("server.loading", ">> Loaded 0 GameTeleports. DB table `game_tele` is empty!");
9753 LOG_INFO("server.loading", " ");
9754 return;
9755 }
9756
9757 uint32 count = 0;
9758
9759 do
9760 {
9761 Field* fields = result->Fetch();
9762
9763 uint32 id = fields[0].Get<uint32>();
9764
9765 GameTele gt;
9766
9767 gt.position_x = fields[1].Get<float>();
9768 gt.position_y = fields[2].Get<float>();
9769 gt.position_z = fields[3].Get<float>();
9770 gt.orientation = fields[4].Get<float>();
9771 gt.mapId = fields[5].Get<uint16>();
9772 gt.name = fields[6].Get<std::string>();
9773
9774 if (!MapMgr::IsValidMapCoord(gt.mapId, gt.position_x, gt.position_y, gt.position_z, gt.orientation))
9775 {
9776 LOG_ERROR("sql.sql", "Wrong position for id {} (name: {}) in `game_tele` table, ignoring.", id, gt.name);
9777 continue;
9778 }
9779
9780 if (!Utf8toWStr(gt.name, gt.wnameLow))
9781 {
9782 LOG_ERROR("sql.sql", "Wrong UTF8 name for id {} in `game_tele` table, ignoring.", id);
9783 continue;
9784 }
9785
9786 wstrToLower(gt.wnameLow);
9787
9788 _gameTeleStore[id] = gt;
9789
9790 ++count;
9791 } while (result->NextRow());
9792
9793 LOG_INFO("server.loading", ">> Loaded {} GameTeleports in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9794 LOG_INFO("server.loading", " ");
9795}
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 ( )
10198{
10199 uint32 oldMSTime = getMSTime();
10200
10201 _gossipMenusStore.clear();
10202
10203 QueryResult result = WorldDatabase.Query("SELECT MenuID, TextID FROM gossip_menu");
10204
10205 if (!result)
10206 {
10207 LOG_WARN("server.loading", ">> Loaded 0 gossip_menu entries. DB table `gossip_menu` is empty!");
10208 LOG_INFO("server.loading", " ");
10209 return;
10210 }
10211
10212 do
10213 {
10214 Field* fields = result->Fetch();
10215
10216 GossipMenus gMenu;
10217
10218 gMenu.MenuID = fields[0].Get<uint32>();
10219 gMenu.TextID = fields[1].Get<uint32>();
10220
10221 if (!GetGossipText(gMenu.TextID))
10222 {
10223 LOG_ERROR("sql.sql", "Table gossip_menu entry {} are using non-existing TextID {}", gMenu.MenuID, gMenu.TextID);
10224 continue;
10225 }
10226
10227 _gossipMenusStore.insert(GossipMenusContainer::value_type(gMenu.MenuID, gMenu));
10228 } while (result->NextRow());
10229
10230 LOG_INFO("server.loading", ">> Loaded {} gossip_menu entries in {} ms", (uint32)_gossipMenusStore.size(), GetMSTimeDiffToNow(oldMSTime));
10231 LOG_INFO("server.loading", " ");
10232}
GossipText const * GetGossipText(uint32 Text_ID) const
Definition ObjectMgr.cpp:6689
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 ( )
10235{
10236 uint32 oldMSTime = getMSTime();
10237
10238 _gossipMenuItemsStore.clear();
10239
10240 QueryResult result = WorldDatabase.Query(
10241 // 0 1 2 3 4 5 6 7 8 9 10 11 12
10242 "SELECT MenuID, OptionID, OptionIcon, OptionText, OptionBroadcastTextID, OptionType, OptionNpcFlag, ActionMenuID, ActionPoiID, BoxCoded, BoxMoney, BoxText, BoxBroadcastTextID "
10243 "FROM gossip_menu_option ORDER BY MenuID, OptionID");
10244
10245 if (!result)
10246 {
10247 LOG_WARN("server.loading", ">> Loaded 0 gossip_menu_option IDs. DB table `gossip_menu_option` is empty!");
10248 LOG_INFO("server.loading", " ");
10249 return;
10250 }
10251
10252 do
10253 {
10254 Field* fields = result->Fetch();
10255
10256 GossipMenuItems gMenuItem;
10257
10258 gMenuItem.MenuID = fields[0].Get<uint32>();
10259 gMenuItem.OptionID = fields[1].Get<uint16>();
10260 gMenuItem.OptionIcon = fields[2].Get<uint32>();
10261 gMenuItem.OptionText = fields[3].Get<std::string>();
10262 gMenuItem.OptionBroadcastTextID = fields[4].Get<uint32>();
10263 gMenuItem.OptionType = fields[5].Get<uint8>();
10264 gMenuItem.OptionNpcFlag = fields[6].Get<uint32>();
10265 gMenuItem.ActionMenuID = fields[7].Get<uint32>();
10266 gMenuItem.ActionPoiID = fields[8].Get<uint32>();
10267 gMenuItem.BoxCoded = fields[9].Get<bool>();
10268 gMenuItem.BoxMoney = fields[10].Get<uint32>();
10269 gMenuItem.BoxText = fields[11].Get<std::string>();
10270 gMenuItem.BoxBroadcastTextID = fields[12].Get<uint32>();
10271
10272 if (gMenuItem.OptionIcon >= GOSSIP_ICON_MAX)
10273 {
10274 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);
10275 gMenuItem.OptionIcon = GOSSIP_ICON_CHAT;
10276 }
10277
10279 {
10280 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} has non-existing or incompatible OptionBroadcastTextID {}, ignoring.", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.OptionBroadcastTextID);
10281 gMenuItem.OptionBroadcastTextID = 0;
10282 }
10283
10284 if (gMenuItem.OptionType >= GOSSIP_OPTION_MAX)
10285 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);
10286
10287 if (gMenuItem.ActionPoiID && !GetPointOfInterest(gMenuItem.ActionPoiID))
10288 {
10289 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} use non-existing ActionPoiID {}, ignoring", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.ActionPoiID);
10290 gMenuItem.ActionPoiID = 0;
10291 }
10292
10293 if (gMenuItem.BoxBroadcastTextID && !GetBroadcastText(gMenuItem.BoxBroadcastTextID))
10294 {
10295 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} has non-existing or incompatible BoxBroadcastTextID {}, ignoring.", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.BoxBroadcastTextID);
10296 gMenuItem.BoxBroadcastTextID = 0;
10297 }
10298
10299 _gossipMenuItemsStore.insert(GossipMenuItemsContainer::value_type(gMenuItem.MenuID, gMenuItem));
10300 } while (result->NextRow());
10301
10302 // Warn if any trainer creature templates reference a GossipMenuId that has no gossip_menu_option entries
10303 // This will cause the gossip menu to fallback to MenuID 0 at runtime which will display: "I wish to unlearn my talents."
10304 std::set<uint32> checkedMenuIds;
10305 for (auto const& [entry, tmpl] : _creatureTemplateStore)
10306 {
10307 uint32 menuId = tmpl.GossipMenuId;
10308 if (!menuId)
10309 continue;
10310
10311 if (!(tmpl.npcflag & UNIT_NPC_FLAG_TRAINER))
10312 continue;
10313
10314 if (checkedMenuIds.contains(menuId))
10315 continue;
10316
10317 checkedMenuIds.insert(menuId);
10318
10319 auto [first, second] = _gossipMenuItemsStore.equal_range(menuId);
10320 if (first == second)
10321 LOG_WARN("server.loading", "Trainer creature template references GossipMenuId {} has no `gossip_menu_option` entries. This will fallback to MenuID 0.", menuId);
10322 }
10323
10324 LOG_INFO("server.loading", ">> Loaded {} gossip_menu_option entries in {} ms", uint32(_gossipMenuItemsStore.size()), GetMSTimeDiffToNow(oldMSTime));
10325 LOG_INFO("server.loading", " ");
10326}
@ 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:1227
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 ( )
6698{
6699 uint32 oldMSTime = getMSTime();
6700
6701 QueryResult result = WorldDatabase.Query("SELECT ID, "
6702 "text0_0, text0_1, BroadcastTextID0, lang0, Probability0, em0_0, em0_1, em0_2, em0_3, em0_4, em0_5, "
6703 "text1_0, text1_1, BroadcastTextID1, lang1, Probability1, em1_0, em1_1, em1_2, em1_3, em1_4, em1_5, "
6704 "text2_0, text2_1, BroadcastTextID2, lang2, Probability2, em2_0, em2_1, em2_2, em2_3, em2_4, em2_5, "
6705 "text3_0, text3_1, BroadcastTextID3, lang3, Probability3, em3_0, em3_1, em3_2, em3_3, em3_4, em3_5, "
6706 "text4_0, text4_1, BroadcastTextID4, lang4, Probability4, em4_0, em4_1, em4_2, em4_3, em4_4, em4_5, "
6707 "text5_0, text5_1, BroadcastTextID5, lang5, Probability5, em5_0, em5_1, em5_2, em5_3, em5_4, em5_5, "
6708 "text6_0, text6_1, BroadcastTextID6, lang6, Probability6, em6_0, em6_1, em6_2, em6_3, em6_4, em6_5, "
6709 "text7_0, text7_1, BroadcastTextID7, lang7, Probability7, em7_0, em7_1, em7_2, em7_3, em7_4, em7_5 "
6710 "FROM npc_text");
6711
6712 if (!result)
6713 {
6714 LOG_WARN("server.loading", ">> Loaded 0 npc texts, table is empty!");
6715 LOG_INFO("server.loading", " ");
6716 return;
6717 }
6718
6719 _gossipTextStore.rehash(result->GetRowCount());
6720
6721 uint32 count = 0;
6722 uint8 cic;
6723
6724 do
6725 {
6726 cic = 0;
6727
6728 Field* fields = result->Fetch();
6729
6730 uint32 id = fields[cic++].Get<uint32>();
6731 if (!id)
6732 {
6733 LOG_ERROR("sql.sql", "Table `npc_text` has record wit reserved id 0, ignore.");
6734 continue;
6735 }
6736
6737 GossipText& gText = _gossipTextStore[id];
6738
6739 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
6740 {
6741 gText.Options[i].Text_0 = fields[cic++].Get<std::string>();
6742 gText.Options[i].Text_1 = fields[cic++].Get<std::string>();
6743 gText.Options[i].BroadcastTextID = fields[cic++].Get<uint32>();
6744 gText.Options[i].Language = fields[cic++].Get<uint8>();
6745 gText.Options[i].Probability = fields[cic++].Get<float>();
6746
6747 for (uint8 j = 0; j < MAX_GOSSIP_TEXT_EMOTES; ++j)
6748 {
6749 gText.Options[i].Emotes[j]._Delay = fields[cic++].Get<uint16>();
6750 gText.Options[i].Emotes[j]._Emote = fields[cic++].Get<uint16>();
6751 }
6752 }
6753
6754 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; i++)
6755 {
6756 if (gText.Options[i].BroadcastTextID)
6757 {
6759 {
6760 LOG_ERROR("sql.sql", "GossipText (Id: {}) in table `npc_text` has non-existing or incompatible BroadcastTextID{} {}.", id, i, gText.Options[i].BroadcastTextID);
6761 gText.Options[i].BroadcastTextID = 0;
6762 }
6763 }
6764 }
6765
6766 count++;
6767 } while (result->NextRow());
6768
6769 LOG_INFO("server.loading", ">> Loaded {} Npc Texts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6770 LOG_INFO("server.loading", " ");
6771}
#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 ( )
6605{
6606 uint32 oldMSTime = getMSTime();
6607
6608 // 0 1 2 3
6609 QueryResult result = WorldDatabase.Query("SELECT entry, creditType, creditEntry, lastEncounterDungeon FROM instance_encounters");
6610 if (!result)
6611 {
6612 LOG_WARN("server.loading", ">> Loaded 0 instance encounters, table is empty!");
6613 LOG_INFO("server.loading", " ");
6614 return;
6615 }
6616
6617 uint32 count = 0;
6618 std::map<uint32, DungeonEncounterEntry const*> dungeonLastBosses;
6619 do
6620 {
6621 Field* fields = result->Fetch();
6622 uint32 entry = fields[0].Get<uint32>();
6623 uint8 creditType = fields[1].Get<uint8>();
6624 uint32 creditEntry = fields[2].Get<uint32>();
6625 uint32 lastEncounterDungeon = fields[3].Get<uint16>();
6626 DungeonEncounterEntry const* dungeonEncounter = sDungeonEncounterStore.LookupEntry(entry);
6627 if (!dungeonEncounter)
6628 {
6629 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid encounter id {}, skipped!", entry);
6630 continue;
6631 }
6632
6633 if (lastEncounterDungeon && !sLFGMgr->GetLFGDungeonEntry(lastEncounterDungeon))
6634 {
6635 LOG_ERROR("sql.sql", "Table `instance_encounters` has an encounter {} ({}) marked as final for invalid dungeon id {}, skipped!", entry, dungeonEncounter->encounterName[0], lastEncounterDungeon);
6636 continue;
6637 }
6638
6639 std::map<uint32, DungeonEncounterEntry const*>::const_iterator itr = dungeonLastBosses.find(lastEncounterDungeon);
6640 if (lastEncounterDungeon)
6641 {
6642 if (itr != dungeonLastBosses.end())
6643 {
6644 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]);
6645 continue;
6646 }
6647
6648 dungeonLastBosses[lastEncounterDungeon] = dungeonEncounter;
6649 }
6650
6651 switch (creditType)
6652 {
6654 {
6655 CreatureTemplate const* creatureInfo = GetCreatureTemplate(creditEntry);
6656 if (!creatureInfo)
6657 {
6658 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid creature (entry {}) linked to the encounter {} ({}), skipped!", creditEntry, entry, dungeonEncounter->encounterName[0]);
6659 continue;
6660 }
6661 const_cast<CreatureTemplate*>(creatureInfo)->flags_extra |= CREATURE_FLAG_EXTRA_DUNGEON_BOSS;
6662 break;
6663 }
6665 {
6666 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(creditEntry);
6667 if (!spellInfo)
6668 {
6669 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid spell (entry {}) linked to the encounter {} ({}), skipped!", creditEntry, entry, dungeonEncounter->encounterName[0]);
6670 continue;
6671 }
6672 const_cast<SpellInfo*>(spellInfo)->AttributesCu |= SPELL_ATTR0_CU_ENCOUNTER_REWARD;
6673 break;
6674 }
6675 default:
6676 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid credit type ({}) for encounter {} ({}), skipped!", creditType, entry, dungeonEncounter->encounterName[0]);
6677 continue;
6678 }
6679
6680 DungeonEncounterList& encounters = _dungeonEncounterStore[MAKE_PAIR32(dungeonEncounter->mapId, dungeonEncounter->difficulty)];
6681 encounters.push_back(new DungeonEncounter(dungeonEncounter, EncounterCreditType(creditType), creditEntry, lastEncounterDungeon));
6682 ++count;
6683 } while (result->NextRow());
6684
6685 LOG_INFO("server.loading", ">> Loaded {} Instance Encounters in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6686 LOG_INFO("server.loading", " ");
6687}
@ CREATURE_FLAG_EXTRA_DUNGEON_BOSS
Definition CreatureData.h:74
DBCStorage< DungeonEncounterEntry > sDungeonEncounterStore(DungeonEncounterfmt)
#define sLFGMgr
Definition LFGMgr.h:665
EncounterCreditType
Definition Map.h:162
@ ENCOUNTER_CREDIT_KILL_CREATURE
Definition Map.h:163
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition Map.h:164
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 ( )
6554{
6555 uint32 oldMSTime = getMSTime();
6556
6557 // 0 1 2 4
6558 QueryResult result = WorldDatabase.Query("SELECT map, parent, script, allowMount FROM instance_template");
6559
6560 if (!result)
6561 {
6562 LOG_WARN("server.loading", ">> Loaded 0 instance templates. DB table `instance_template` is empty!");
6563 LOG_INFO("server.loading", " ");
6564 return;
6565 }
6566
6567 uint32 count = 0;
6568 do
6569 {
6570 Field* fields = result->Fetch();
6571
6572 uint16 mapID = fields[0].Get<uint16>();
6573
6574 if (!MapMgr::IsValidMAP(mapID, true))
6575 {
6576 LOG_ERROR("sql.sql", "ObjectMgr::LoadInstanceTemplate: bad mapid {} for template!", mapID);
6577 continue;
6578 }
6579
6580 InstanceTemplate instanceTemplate;
6581
6582 instanceTemplate.AllowMount = fields[3].Get<bool>();
6583 instanceTemplate.Parent = uint32(fields[1].Get<uint16>());
6584 instanceTemplate.ScriptId = GetScriptId(fields[2].Get<std::string>());
6585
6586 _instanceTemplateStore[mapID] = instanceTemplate;
6587
6588 ++count;
6589 } while (result->NextRow());
6590
6591 LOG_INFO("server.loading", ">> Loaded {} Instance Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6592 LOG_INFO("server.loading", " ");
6593}
static bool IsValidMAP(uint32 mapid, bool startUp)
Definition MapMgr.cpp:312
bool AllowMount
Definition Map.h:129
uint32 ScriptId
Definition Map.h:128

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

References _itemTemplateStore, _itemTemplateStoreFast, ALLIANCE, BAG_FAMILY_MASK_CURRENCY_TOKENS, ItemEntry::ClassID, CLASSMASK_ALL_PLAYABLE, CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES, DISABLE_TYPE_SPELL, ItemEntry::DisplayInfoID, Field::Get(), GetItemEnchantMod(), GetItemTemplate(), getMSTime(), GetMSTimeDiffToNow(), GetPageText(), GetScriptId(), HORDE, ItemEntry::InventoryType, INVTYPE_NON_EQUIP, ITEM_FLAG2_FACTION_ALLIANCE, ITEM_FLAG2_FACTION_HORDE, ITEM_FLAGS_CU_DURATION_REAL_TIME, ITEM_MOD_SPELL_DAMAGE_DONE, ITEM_MOD_SPELL_HEALING_DONE, ITEM_QUALITY_NORMAL, ITEM_SPELLTRIGGER_LEARN_SPELL_ID, ITEM_SPELLTRIGGER_ON_USE, ItemTemplate::ItemId, CharStartOutfitEntry::ItemId, LOG_DEBUG, LOG_ERROR, LOG_INFO, LOG_WARN, ItemEntry::Material, MAX_BAG_SIZE, MAX_BIND_TYPE, MAX_ITEM_MOD, MAX_ITEM_PROTO_DAMAGES, MAX_ITEM_PROTO_SOCKETS, MAX_ITEM_PROTO_SPELLS, MAX_ITEM_PROTO_STATS, MAX_ITEM_QUALITY, MAX_ITEM_SPELLTRIGGER, MAX_OUTFIT_ITEMS, MAX_PET_DIET, MAX_REPUTATION_RANK, MAX_SKILL_TYPE, MAX_SPELL_SCHOOL, MIN_REPUTATION_RANK, qualityToBuyValueConfig, qualityToSellValueConfig, 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 CreatureData const* 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 CreatureData const* 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 CreatureData const* 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 GameObjectData const* 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 GameObjectData const* 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 GameObjectData const* 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 GameObjectData const* 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 CreatureData const* 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:121
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 ( )
9882{
9883 uint32 oldMSTime = getMSTime();
9884
9885 _mailLevelRewardStore.clear(); // for reload case
9886
9887 // 0 1 2 3
9888 QueryResult result = WorldDatabase.Query("SELECT level, raceMask, mailTemplateId, senderEntry FROM mail_level_reward");
9889
9890 if (!result)
9891 {
9892 LOG_WARN("server.loading", ">> Loaded 0 level dependent mail rewards. DB table `mail_level_reward` is empty.");
9893 LOG_INFO("server.loading", " ");
9894 return;
9895 }
9896
9897 uint32 count = 0;
9898
9899 do
9900 {
9901 Field* fields = result->Fetch();
9902
9903 uint8 level = fields[0].Get<uint8>();
9904 uint32 raceMask = fields[1].Get<uint32>();
9905 uint32 mailTemplateId = fields[2].Get<uint32>();
9906 uint32 senderEntry = fields[3].Get<uint32>();
9907
9908 if (level > MAX_LEVEL)
9909 {
9910 LOG_ERROR("sql.sql", "Table `mail_level_reward` have data for level {} that more supported by client ({}), ignoring.", level, MAX_LEVEL);
9911 continue;
9912 }
9913
9914 if (!(raceMask & sRaceMgr->GetPlayableRaceMask()))
9915 {
9916 LOG_ERROR("sql.sql", "Table `mail_level_reward` have raceMask ({}) for level {} that not include any player races, ignoring.", raceMask, level);
9917 continue;
9918 }
9919
9920 if (!sMailTemplateStore.LookupEntry(mailTemplateId))
9921 {
9922 LOG_ERROR("sql.sql", "Table `mail_level_reward` have invalid mailTemplateId ({}) for level {} that invalid not include any player races, ignoring.", mailTemplateId, level);
9923 continue;
9924 }
9925
9926 if (!GetCreatureTemplate(senderEntry))
9927 {
9928 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);
9929 continue;
9930 }
9931
9932 _mailLevelRewardStore[level].push_back(MailLevelReward(raceMask, mailTemplateId, senderEntry));
9933
9934 ++count;
9935 } while (result->NextRow());
9936
9937 LOG_INFO("server.loading", ">> Loaded {} Level Dependent Mail Rewards in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9938 LOG_INFO("server.loading", " ");
9939}
#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 ( )
9461{
9462 uint32 oldMSTime = getMSTime();
9463
9464 _moduleStringStore.clear(); // for reload case
9465 QueryResult result = WorldDatabase.Query("SELECT module, id, string FROM module_string");
9466 if (!result)
9467 {
9468 LOG_WARN("server.loading", ">> Loaded 0 module strings. DB table `module_string` is empty.");
9469 LOG_INFO("server.loading", " ");
9470 return false;
9471 }
9472
9473 do
9474 {
9475 Field* fields = result->Fetch();
9476
9477 std::string module = fields[0].Get<std::string>();
9478 uint32 id = fields[1].Get<uint32>();
9479
9480 std::pair<std::string, uint32> pairKey = std::make_pair(module, id);
9481 ModuleString& data = _moduleStringStore[pairKey];
9482
9483 AddLocaleString(fields[2].Get<std::string>(), LOCALE_enUS, data.Content);
9484 } while (result->NextRow());
9485
9486 LOG_INFO("server.loading", ">> Loaded {} Module Strings in {} ms", _moduleStringStore.size(), GetMSTimeDiffToNow(oldMSTime));
9487 LOG_INFO("server.loading", " ");
9488
9489 return true;
9490}

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

◆ LoadModuleStringsLocale()

bool ObjectMgr::LoadModuleStringsLocale ( )
9493{
9494 uint32 oldMSTime = getMSTime();
9495
9496 QueryResult result = WorldDatabase.Query("SELECT module, id, locale, string FROM module_string_locale");
9497 if (!result)
9498 {
9499 LOG_WARN("server.loading", ">> Loaded 0 module strings locale. DB table `module_string_locale` is empty.");
9500 LOG_INFO("server.loading", " ");
9501 return false;
9502 }
9503
9504 uint32 localeCount = 0;
9505 do
9506 {
9507 Field* fields = result->Fetch();
9508
9509 std::string module = fields[0].Get<std::string>();
9510 uint32 id = fields[1].Get<uint32>();
9511
9512 std::pair<std::string, uint32> pairKey = std::make_pair(module, id);
9513 ModuleString& data = _moduleStringStore[pairKey];
9514
9515 ModuleStringContainer::iterator ms = _moduleStringStore.find(pairKey);
9516 if (ms == _moduleStringStore.end())
9517 {
9518 LOG_ERROR("sql.sql", "ModuleString (Module: {} Id: {}) found in table `module_string_locale` but does not exist in `module_string`. Skipped!", module, id);
9519 continue;
9520 }
9521
9522 LocaleConstant locale = GetLocaleByName(fields[2].Get<std::string>());
9523 if (locale == LOCALE_enUS)
9524 continue;
9525
9526 AddLocaleString(fields[3].Get<std::string>(), locale, data.Content);
9527 localeCount++;
9528 } while (result->NextRow());
9529
9530 LOG_INFO("server.loading", ">> Loaded {} Module Strings Locales in {} ms", localeCount, GetMSTimeDiffToNow(oldMSTime));
9531 LOG_INFO("server.loading", " ");
9532
9533 return true;
9534}

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

◆ LoadNPCSpellClickSpells()

void ObjectMgr::LoadNPCSpellClickSpells ( )
8567{
8568 uint32 oldMSTime = getMSTime();
8569
8570 _spellClickInfoStore.clear();
8571 // 0 1 2 3
8572 QueryResult result = WorldDatabase.Query("SELECT npc_entry, spell_id, cast_flags, user_type FROM npc_spellclick_spells");
8573
8574 if (!result)
8575 {
8576 LOG_WARN("server.loading", ">> Loaded 0 spellclick spells. DB table `npc_spellclick_spells` is empty.");
8577 LOG_INFO("server.loading", " ");
8578 return;
8579 }
8580
8581 uint32 count = 0;
8582
8583 do
8584 {
8585 Field* fields = result->Fetch();
8586
8587 uint32 npc_entry = fields[0].Get<uint32>();
8588 CreatureTemplate const* cInfo = GetCreatureTemplate(npc_entry);
8589 if (!cInfo)
8590 {
8591 LOG_ERROR("sql.sql", "Table npc_spellclick_spells references unknown creature_template {}. Skipping entry.", npc_entry);
8592 continue;
8593 }
8594
8595 uint32 spellid = fields[1].Get<uint32>();
8596 SpellInfo const* spellinfo = sSpellMgr->GetSpellInfo(spellid);
8597 if (!spellinfo)
8598 {
8599 LOG_ERROR("sql.sql", "Table npc_spellclick_spells references unknown spellid {}. Skipping entry.", spellid);
8600 continue;
8601 }
8602
8603 uint8 userType = fields[3].Get<uint16>();
8604 if (userType >= SPELL_CLICK_USER_MAX)
8605 LOG_ERROR("sql.sql", "Table npc_spellclick_spells references unknown user type {}. Skipping entry.", uint32(userType));
8606
8607 uint8 castFlags = fields[2].Get<uint8>();
8608 SpellClickInfo info;
8609 info.spellId = spellid;
8610 info.castFlags = castFlags;
8611 info.userType = SpellClickUserTypes(userType);
8612 _spellClickInfoStore.insert(SpellClickInfoContainer::value_type(npc_entry, info));
8613
8614 ++count;
8615 } while (result->NextRow());
8616
8617 // all spellclick data loaded, now we check if there are creatures with NPC_FLAG_SPELLCLICK but with no data
8618 // NOTE: It *CAN* be the other way around: no spellclick flag but with spellclick data, in case of creature-only vehicle accessories
8620 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
8621 {
8622 if ((itr->second.npcflag & UNIT_NPC_FLAG_SPELLCLICK) && _spellClickInfoStore.find(itr->second.Entry) == _spellClickInfoStore.end())
8623 {
8624 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);
8625 const_cast<CreatureTemplate*>(&itr->second)->npcflag &= ~UNIT_NPC_FLAG_SPELLCLICK;
8626 }
8627 }
8628
8629 LOG_INFO("server.loading", ">> Loaded {} Spellclick Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8630 LOG_INFO("server.loading", " ");
8631}
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 ( )
6774{
6775 uint32 oldMSTime = getMSTime();
6776
6777 _npcTextLocaleStore.clear(); // need for reload case
6778
6779 QueryResult result = WorldDatabase.Query("SELECT ID, Locale, "
6780 // 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
6781 "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 "
6782 "FROM npc_text_locale");
6783
6784 if (!result)
6785 return;
6786
6787 do
6788 {
6789 Field* fields = result->Fetch();
6790
6791 uint32 ID = fields[0].Get<uint32>();
6792
6793 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
6794 if (locale == LOCALE_enUS)
6795 continue;
6796
6798 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
6799 {
6800 AddLocaleString(fields[2 + i * 2].Get<std::string>(), locale, data.Text_0[i]);
6801 AddLocaleString(fields[3 + i * 2].Get<std::string>(), locale, data.Text_1[i]);
6802 }
6803 } while (result->NextRow());
6804
6805 LOG_INFO("server.loading", ">> Loaded {} Npc Text Locale Strings in {} ms", (uint32)_npcTextLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
6806}
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 ( )
6521{
6522 uint32 oldMSTime = getMSTime();
6523
6524 _pageTextLocaleStore.clear(); // need for reload case
6525
6526 // 0 1 2
6527 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Text FROM page_text_locale");
6528
6529 if (!result)
6530 {
6531 LOG_WARN("server.loading", ">> Loaded 0 page texts. DB table `page_text_locale` is empty!");
6532 LOG_INFO("server.loading", " ");
6533 return;
6534 }
6535
6536 do
6537 {
6538 Field* fields = result->Fetch();
6539
6540 uint32 ID = fields[0].Get<uint32>();
6541
6542 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
6543 if (locale == LOCALE_enUS)
6544 continue;
6545
6547 AddLocaleString(fields[2].Get<std::string>(), locale, data.Text);
6548 } while (result->NextRow());
6549
6550 LOG_INFO("server.loading", ">> Loaded {} Page Text Locale Strings in {} ms", (uint32)_pageTextLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
6551}
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 ( )
6471{
6472 uint32 oldMSTime = getMSTime();
6473
6474 // 0 1 2
6475 QueryResult result = WorldDatabase.Query("SELECT ID, Text, NextPageID FROM page_text");
6476
6477 if (!result)
6478 {
6479 LOG_WARN("server.loading", ">> Loaded 0 page texts. DB table `page_text` is empty!");
6480 LOG_INFO("server.loading", " ");
6481 return;
6482 }
6483
6484 uint32 count = 0;
6485 do
6486 {
6487 Field* fields = result->Fetch();
6488
6489 PageText& pageText = _pageTextStore[fields[0].Get<uint32>()];
6490
6491 pageText.Text = fields[1].Get<std::string>();
6492 pageText.NextPage = fields[2].Get<uint32>();
6493
6494 ++count;
6495 } while (result->NextRow());
6496
6497 for (PageTextContainer::const_iterator itr = _pageTextStore.begin(); itr != _pageTextStore.end(); ++itr)
6498 {
6499 if (itr->second.NextPage)
6500 {
6501 PageTextContainer::const_iterator itr2 = _pageTextStore.find(itr->second.NextPage);
6502 if (itr2 == _pageTextStore.end())
6503 LOG_ERROR("sql.sql", "Page text (Id: {}) has not existing next page (Id: {})", itr->first, itr->second.NextPage);
6504 }
6505 }
6506
6507 LOG_INFO("server.loading", ">> Loaded {} Page Texts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6508 LOG_INFO("server.loading", " ");
6509}
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 ( )
4208{
4209 uint32 oldMSTime = getMSTime();
4210
4211 // 0 1 2 3 4 5 6 7 8 9 10 11
4212 QueryResult result = WorldDatabase.Query("SELECT creature_entry, level, hp, mana, str, agi, sta, inte, spi, armor, min_dmg, max_dmg FROM pet_levelstats");
4213
4214 if (!result)
4215 {
4216 LOG_WARN("server.loading", ">> Loaded 0 level pet stats definitions. DB table `pet_levelstats` is empty.");
4217 LOG_INFO("server.loading", " ");
4218 return;
4219 }
4220
4221 uint32 count = 0;
4222
4223 do
4224 {
4225 Field* fields = result->Fetch();
4226
4227 uint32 creature_id = fields[0].Get<uint32>();
4228 if (!GetCreatureTemplate(creature_id))
4229 {
4230 LOG_ERROR("sql.sql", "Wrong creature id {} in `pet_levelstats` table, ignoring.", creature_id);
4231 continue;
4232 }
4233
4234 uint32 current_level = fields[1].Get<uint8>();
4235 if (current_level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4236 {
4237 if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
4238 LOG_ERROR("sql.sql", "Wrong (> {}) level {} in `pet_levelstats` table, ignoring.", STRONG_MAX_LEVEL, current_level);
4239 else
4240 {
4241 LOG_DEBUG("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `pet_levelstats` table, ignoring.", current_level);
4242 ++count; // make result loading percent "expected" correct in case disabled detail mode for example.
4243 }
4244 continue;
4245 }
4246 else if (current_level < 1)
4247 {
4248 LOG_ERROR("sql.sql", "Wrong (<1) level {} in `pet_levelstats` table, ignoring.", current_level);
4249 continue;
4250 }
4251
4252 PetLevelInfo*& pInfoMapEntry = _petInfoStore[creature_id];
4253
4254 if (!pInfoMapEntry)
4255 pInfoMapEntry = new PetLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)];
4256
4257 // data for level 1 stored in [0] array element, ...
4258 PetLevelInfo* pLevelInfo = &pInfoMapEntry[current_level - 1];
4259
4260 pLevelInfo->health = fields[2].Get<uint32>();
4261 pLevelInfo->mana = fields[3].Get<uint32>();
4262 pLevelInfo->armor = fields[9].Get<uint32>();
4263 pLevelInfo->min_dmg = fields[10].Get<uint32>();
4264 pLevelInfo->max_dmg = fields[11].Get<uint32>();
4265 for (uint8 i = 0; i < MAX_STATS; i++)
4266 {
4267 pLevelInfo->stats[i] = fields[i + 4].Get<uint32>();
4268 }
4269
4270 ++count;
4271 } while (result->NextRow());
4272
4273 // Fill gaps and check integrity
4274 for (PetLevelInfoContainer::iterator itr = _petInfoStore.begin(); itr != _petInfoStore.end(); ++itr)
4275 {
4276 PetLevelInfo* pInfo = itr->second;
4277
4278 // fatal error if no level 1 data
4279 if (!pInfo || pInfo[0].health == 0)
4280 {
4281 LOG_ERROR("sql.sql", "Creature {} does not have pet stats data for Level 1!", itr->first);
4282 exit(1);
4283 }
4284
4285 // fill level gaps
4286 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4287 {
4288 if (pInfo[level].health == 0)
4289 {
4290 LOG_ERROR("sql.sql", "Creature {} has no data for Level {} pet stats data, using data of Level {}.", itr->first, level + 1, level);
4291 pInfo[level] = pInfo[level - 1];
4292 }
4293 }
4294 }
4295
4296 LOG_INFO("server.loading", ">> Loaded {} Level Pet Stats Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4297 LOG_INFO("server.loading", " ");
4298}
#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 ( )
8073{
8074 uint32 oldMSTime = getMSTime();
8075 // 0 1 2
8076 QueryResult result = WorldDatabase.Query("SELECT word, entry, half FROM pet_name_generation");
8077
8078 if (!result)
8079 {
8080 LOG_WARN("server.loading", ">> Loaded 0 pet name parts. DB table `pet_name_generation` is empty!");
8081 LOG_INFO("server.loading", " ");
8082 return;
8083 }
8084
8085 uint32 count = 0;
8086
8087 do
8088 {
8089 Field* fields = result->Fetch();
8090 std::string word = fields[0].Get<std::string>();
8091 uint32 entry = fields[1].Get<uint32>();
8092 bool half = fields[2].Get<bool>();
8093 if (half)
8094 _petHalfName1[entry].push_back(word);
8095 else
8096 _petHalfName0[entry].push_back(word);
8097 ++count;
8098 } while (result->NextRow());
8099
8100 LOG_INFO("server.loading", ">> Loaded {} Pet Name Parts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8101 LOG_INFO("server.loading", " ");
8102}

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 ( )
8105{
8106 uint32 oldMSTime = getMSTime();
8107
8108 QueryResult result = CharacterDatabase.Query("SELECT MAX(id) FROM character_pet");
8109 if (result)
8110 {
8111 Field* fields = result->Fetch();
8112 _hiPetNumber = fields[0].Get<uint32>() + 1;
8113 }
8114
8115 LOG_INFO("server.loading", ">> Loaded The Max Pet Number: {} in {} ms", _hiPetNumber - 1, GetMSTimeDiffToNow(oldMSTime));
8116 LOG_INFO("server.loading", " ");
8117}

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

◆ LoadPlayerInfo()

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

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

◆ LoadProfanityNamesFromDBC()

void ObjectMgr::LoadProfanityNamesFromDBC ( )
9076{
9077 if (!sWorld->getBoolConfig(CONFIG_STRICT_NAMES_PROFANITY))
9078 {
9079 LOG_WARN("server.loading", ">> Loaded 0 profanity names from DBC. Config option disabled.");
9080 return;
9081 }
9082
9083 uint32 oldMSTime = getMSTime();
9084
9085 uint32 count = 0;
9086
9087 for (NamesProfanityEntry const* profanityStore : sNamesProfanityStore)
9088 {
9089 std::wstring wstr;
9090
9091 Utf8toWStr(profanityStore->Pattern, wstr);
9092
9093 // DBC does not have clean entries, remove the junk.
9094 boost::algorithm::replace_all(wstr, "\\<", "");
9095 boost::algorithm::replace_all(wstr, "\\>", "");
9096
9097 _profanityNamesStore.insert(wstr);
9098 count++;
9099 }
9100
9101 LOG_INFO("server.loading", ">> Loaded {} profanity names from DBC in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9102 LOG_INFO("server.loading", " ");
9103}
DBCStorage< NamesProfanityEntry > sNamesProfanityStore(NamesProfanityfmt)
@ CONFIG_STRICT_NAMES_PROFANITY
Definition WorldConfig.h:143
Definition DBCStructure.h:1405

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

◆ LoadQuestAreaTriggers()

void ObjectMgr::LoadQuestAreaTriggers ( )
6809{
6810 uint32 oldMSTime = getMSTime();
6811
6812 _questAreaTriggerStore.clear(); // need for reload case
6813
6814 QueryResult result = WorldDatabase.Query("SELECT id, quest FROM areatrigger_involvedrelation");
6815
6816 if (!result)
6817 {
6818 LOG_WARN("server.loading", ">> Loaded 0 quest trigger points. DB table `areatrigger_involvedrelation` is empty.");
6819 LOG_INFO("server.loading", " ");
6820 return;
6821 }
6822
6823 uint32 count = 0;
6824
6825 do
6826 {
6827 ++count;
6828
6829 Field* fields = result->Fetch();
6830
6831 uint32 trigger_ID = fields[0].Get<uint32>();
6832 uint32 quest_ID = fields[1].Get<uint32>();
6833
6834 AreaTrigger const* atEntry = GetAreaTrigger(trigger_ID);
6835 if (!atEntry)
6836 {
6837 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", trigger_ID);
6838 continue;
6839 }
6840
6841 Quest const* quest = GetQuestTemplate(quest_ID);
6842
6843 if (!quest)
6844 {
6845 LOG_ERROR("sql.sql", "Table `areatrigger_involvedrelation` has record (id: {}) for not existing quest {}", trigger_ID, quest_ID);
6846 continue;
6847 }
6848
6850 {
6851 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);
6852
6853 // this will prevent quest completing without objective
6854 const_cast<Quest*>(quest)->SetSpecialFlag(QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT);
6855
6856 // continue; - quest modified to required objective and trigger can be allowed.
6857 }
6858
6859 _questAreaTriggerStore[trigger_ID] = quest_ID;
6860 } while (result->NextRow());
6861
6862 LOG_INFO("server.loading", ">> Loaded {} Quest Trigger Points in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6863 LOG_INFO("server.loading", " ");
6864}
@ 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 ( )
6885{
6886 uint32 oldMSTime = getMSTime();
6887
6888 _questGreetingStore.clear(); // For reload case
6889
6890 // 0 1 2 3 4
6891 QueryResult result = WorldDatabase.Query("SELECT ID, Type, GreetEmoteType, GreetEmoteDelay, Greeting FROM quest_greeting");
6892 if (!result)
6893 {
6894 LOG_WARN("server.loading", ">> Loaded 0 quest greetings. DB table `quest_greeting` is empty.");
6895 return;
6896 }
6897
6898 do
6899 {
6900 Field* fields = result->Fetch();
6901
6902 uint32 id = fields[0].Get<uint32>();
6903 uint8 type = fields[1].Get<uint8>();
6904 switch (type)
6905 {
6906 case 0: // Creature
6907 if (!GetCreatureTemplate(id))
6908 {
6909 LOG_ERROR("sql.sql", "Table `quest_greeting`: creature template entry {} does not exist.", id);
6910 continue;
6911 }
6912 break;
6913 case 1: // GameObject
6914 if (!GetGameObjectTemplate(id))
6915 {
6916 LOG_ERROR("sql.sql", "Table `quest_greeting`: gameobject template entry {} does not exist.", id);
6917 continue;
6918 }
6919 break;
6920 default:
6921 LOG_ERROR("sql.sql", "Table `quest_greeting` has unknown type {} for id {}, skipped.", type, id);
6922 continue;
6923 }
6924
6925 std::pair<uint32, uint8> pairKey = std::make_pair(id, type);
6926 QuestGreeting& data = _questGreetingStore[pairKey];
6927
6928 data.EmoteType = fields[2].Get<uint16>();
6929 data.EmoteDelay = fields[3].Get<uint32>();
6930 AddLocaleString(fields[4].Get<std::string>(), LOCALE_enUS, data.Greeting);
6931 }
6932 while (result->NextRow());
6933
6934 LOG_INFO("server.loading", ">> Loaded {} quest_greeting in {} ms", _questGreetingStore.size(), GetMSTimeDiffToNow(oldMSTime));
6935 LOG_INFO("server.loading", " ");
6936}
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 ( )
6939{
6940 uint32 oldMSTime = getMSTime();
6941
6942 // 0 1 2 3
6943 QueryResult result = WorldDatabase.Query("SELECT ID, Type, Locale, Greeting FROM quest_greeting_locale");
6944 if (!result)
6945 {
6946 LOG_WARN("server.loading", ">> Loaded 0 quest_greeting locales. DB table `quest_greeting_locale` is empty.");
6947 return;
6948 }
6949
6950 uint32 localeCount = 0;
6951 do
6952 {
6953 Field* fields = result->Fetch();
6954
6955 uint32 id = fields[0].Get<uint32>();
6956 uint8 type = fields[1].Get<uint8>();
6957 switch (type)
6958 {
6959 case 0: // Creature
6960 if (!GetCreatureTemplate(id))
6961 {
6962 LOG_ERROR("sql.sql", "Table `quest_greeting_locale`: creature template entry {} does not exist.", id);
6963 continue;
6964 }
6965 break;
6966 case 1: // GameObject
6967 if (!GetGameObjectTemplate(id))
6968 {
6969 LOG_ERROR("sql.sql", "Table `quest_greeting_locale`: gameobject template entry {} does not exist.", id);
6970 continue;
6971 }
6972 break;
6973 default:
6974 continue;
6975 }
6976
6977 std::pair<uint32, uint8> pairKey = std::make_pair(id, type);
6978 QuestGreeting& data = _questGreetingStore[pairKey];
6979
6980 QuestGreetingContainer::iterator qgc = _questGreetingStore.find(pairKey);
6981 if (qgc == _questGreetingStore.end())
6982 {
6983 LOG_ERROR("sql.sql", "QuestGreeting (Id: {} Type: {}) found in table `quest_greeting_locale` but does not exist in `quest_greeting`. Skipped!", id, type);
6984 continue;
6985 }
6986
6987 LocaleConstant locale = GetLocaleByName(fields[2].Get<std::string>());
6988 if (locale == LOCALE_enUS)
6989 continue;
6990
6991 AddLocaleString(fields[3].Get<std::string>(), locale, data.Greeting);
6992 localeCount++;
6993 } while (result->NextRow());
6994
6995 LOG_INFO("server.loading", ">> Loaded {} quest greeting Locale Strings in {} ms", localeCount, GetMSTimeDiffToNow(oldMSTime));
6996 LOG_INFO("server.loading", " ");
6997}

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 ( )
5892{
5893 uint32 oldMSTime = getMSTime();
5894
5895 _questLocaleStore.clear(); // need for reload case
5896
5897 // 0 1 2 3 4 5 6 7 8 9 10
5898 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Title, Details, Objectives, EndText, CompletedText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4 FROM quest_template_locale");
5899
5900 if (!result)
5901 return;
5902
5903 do
5904 {
5905 Field* fields = result->Fetch();
5906
5907 uint32 ID = fields[0].Get<uint32>();
5908
5909 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
5910 if (locale == LOCALE_enUS)
5911 continue;
5912
5913 QuestLocale& data = _questLocaleStore[ID];
5914 AddLocaleString(fields[2].Get<std::string>(), locale, data.Title);
5915 AddLocaleString(fields[3].Get<std::string>(), locale, data.Details);
5916 AddLocaleString(fields[4].Get<std::string>(), locale, data.Objectives);
5917 AddLocaleString(fields[5].Get<std::string>(), locale, data.AreaDescription);
5918 AddLocaleString(fields[6].Get<std::string>(), locale, data.CompletedText);
5919
5920 for (uint8 i = 0; i < 4; ++i)
5921 AddLocaleString(fields[i + 7].Get<std::string>(), locale, data.ObjectiveText[i]);
5922 } while (result->NextRow());
5923
5924 LOG_INFO("server.loading", ">> Loaded {} Quest Locale Strings in {} ms", (uint32)_questLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
5925}
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 ( )
11141{
11142 uint32 oldMSTime = getMSTime();
11143
11144 _questMoneyRewards.clear();
11145
11146 // 0 1 2 3 4 5 6 7 8 9 10
11147 QueryResult result = WorldDatabase.Query("SELECT `Level`, Money0, Money1, Money2, Money3, Money4, Money5, Money6, Money7, Money8, Money9 FROM `quest_money_reward` ORDER BY `Level`");
11148 if (!result)
11149 {
11150 LOG_WARN("server.loading", ">> Loaded 0 quest money rewards. DB table `quest_money_reward` is empty.");
11151 return;
11152 }
11153
11154 uint32 count = 0;
11155 do
11156 {
11157 Field* fields = result->Fetch();
11158 uint32 Level = fields[0].Get<uint32>();
11159
11160 QuestMoneyRewardArray& questMoneyReward = _questMoneyRewards[Level];
11161 questMoneyReward.fill(0);
11162
11163 for (uint8 i = 0; i < MAX_QUEST_MONEY_REWARDS; ++i)
11164 {
11165 questMoneyReward[i] = fields[1 + i].Get<uint32>();
11166 ++count;
11167 }
11168 } while (result->NextRow());
11169
11170 LOG_INFO("server.loading", ">> Loaded {} Quest Money Rewards in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
11171 LOG_INFO("server.loading", " ");
11172}
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 ( )
7000{
7001 uint32 oldMSTime = getMSTime();
7002
7003 _questOfferRewardLocaleStore.clear(); // need for reload case
7004
7005 // 0 1 2
7006 QueryResult result = WorldDatabase.Query("SELECT Id, locale, RewardText FROM quest_offer_reward_locale");
7007 if (!result)
7008 return;
7009
7010 do
7011 {
7012 Field* fields = result->Fetch();
7013
7014 uint32 id = fields[0].Get<uint32>();
7015 std::string localeName = fields[1].Get<std::string>();
7016
7017 LocaleConstant locale = GetLocaleByName(localeName);
7018 if (locale == LOCALE_enUS)
7019 continue;
7020
7022 AddLocaleString(fields[2].Get<std::string>(), locale, data.RewardText);
7023 } while (result->NextRow());
7024
7025 LOG_INFO("server.loading", ">> Loaded {} Quest Offer Reward Locale Strings in {} ms", _questOfferRewardLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
7026}
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 ( )
8484{
8485 if (!sWorld->getBoolConfig(CONFIG_QUEST_POI_ENABLED))
8486 {
8487 LOG_INFO("server.loading", ">> Loaded 0 quest POI definitions. Disabled by config.");
8488 LOG_INFO("server.loading", " ");
8489 return;
8490 }
8491
8492 uint32 oldMSTime = getMSTime();
8493
8494 _questPOIStore.clear(); // need for reload case
8495
8496 uint32 count = 0;
8497
8498 // 0 1 2 3 4 5 6 7
8499 QueryResult result = WorldDatabase.Query("SELECT QuestID, id, ObjectiveIndex, MapID, WorldMapAreaId, Floor, Priority, Flags FROM quest_poi order by QuestID");
8500
8501 if (!result)
8502 {
8503 LOG_WARN("server.loading", ">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty.");
8504 LOG_INFO("server.loading", " ");
8505 return;
8506 }
8507
8508 // 0 1 2 3
8509 QueryResult points = WorldDatabase.Query("SELECT QuestID, Idx1, X, Y FROM quest_poi_points ORDER BY QuestID DESC, Idx2");
8510
8511 std::vector<std::vector<std::vector<QuestPOIPoint> > > POIs;
8512
8513 if (points)
8514 {
8515 // The first result should have the highest questId
8516 Field* fields = points->Fetch();
8517 uint32 questIdMax = fields[0].Get<uint32>();
8518 POIs.resize(questIdMax + 1);
8519
8520 do
8521 {
8522 fields = points->Fetch();
8523
8524 uint32 questId = fields[0].Get<uint32>();
8525 uint32 id = fields[1].Get<uint32>();
8526 int32 x = fields[2].Get<int32>();
8527 int32 y = fields[3].Get<int32>();
8528
8529 if (POIs[questId].size() <= id + 1)
8530 POIs[questId].resize(id + 10);
8531
8532 QuestPOIPoint point(x, y);
8533 POIs[questId][id].push_back(point);
8534 } while (points->NextRow());
8535 }
8536
8537 do
8538 {
8539 Field* fields = result->Fetch();
8540
8541 uint32 questId = fields[0].Get<uint32>();
8542 uint32 id = fields[1].Get<uint32>();
8543 int32 objIndex = fields[2].Get<int32>();
8544 uint32 mapId = fields[3].Get<uint32>();
8545 uint32 WorldMapAreaId = fields[4].Get<uint32>();
8546 uint32 FloorId = fields[5].Get<uint32>();
8547 uint32 unk3 = fields[6].Get<uint32>();
8548 uint32 unk4 = fields[7].Get<uint32>();
8549
8550 QuestPOI POI(id, objIndex, mapId, WorldMapAreaId, FloorId, unk3, unk4);
8551 if (questId < POIs.size() && id < POIs[questId].size())
8552 {
8553 POI.points = POIs[questId][id];
8554 _questPOIStore[questId].push_back(POI);
8555 }
8556 else
8557 LOG_ERROR("sql.sql", "Table quest_poi references unknown quest points for quest {} POI id {}", questId, id);
8558
8559 ++count;
8560 } while (result->NextRow());
8561
8562 LOG_INFO("server.loading", ">> Loaded {} Quest POI definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8563 LOG_INFO("server.loading", " ");
8564}
@ CONFIG_QUEST_POI_ENABLED
Definition WorldConfig.h:136
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
8834{
8835 uint32 oldMSTime = getMSTime();
8836
8837 map.clear(); // need for reload case
8838
8839 uint32 count = 0;
8840
8841 QueryResult result = WorldDatabase.Query("SELECT id, quest, pool_entry FROM {} qr LEFT JOIN pool_quest pq ON qr.quest = pq.entry", table);
8842
8843 if (!result)
8844 {
8845 LOG_WARN("server.loading", ">> Loaded 0 quest relations from `{}`, table is empty.", table);
8846 LOG_INFO("server.loading", " ");
8847 return;
8848 }
8849
8850 PooledQuestRelation* poolRelationMap = go ? &sPoolMgr->mQuestGORelation : &sPoolMgr->mQuestCreatureRelation;
8851 if (starter)
8852 poolRelationMap->clear();
8853
8854 do
8855 {
8856 uint32 id = result->Fetch()[0].Get<uint32>();
8857 uint32 quest = result->Fetch()[1].Get<uint32>();
8858 uint32 poolId = result->Fetch()[2].Get<uint32>();
8859
8860 if (_questTemplates.find(quest) == _questTemplates.end())
8861 {
8862 LOG_ERROR("sql.sql", "Table `{}`: Quest {} listed for entry {} does not exist.", table, quest, id);
8863 continue;
8864 }
8865
8866 if (!poolId || !starter)
8867 map.insert(QuestRelations::value_type(id, quest));
8868 else if (starter)
8869 poolRelationMap->insert(PooledQuestRelation::value_type(quest, id));
8870
8871 ++count;
8872 } while (result->NextRow());
8873
8874 LOG_INFO("server.loading", ">> Loaded {} Quest Relations From {} in {} ms", count, table, GetMSTimeDiffToNow(oldMSTime));
8875 LOG_INFO("server.loading", " ");
8876}
#define sPoolMgr
Definition PoolMgr.h:216
std::multimap< uint32, uint32 > PooledQuestRelation
Definition PoolMgr.h:120

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

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

◆ LoadQuestRequestItemsLocale()

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

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

◆ LoadReferenceVendor()

int ObjectMgr::LoadReferenceVendor ( int32  vendor,
int32  item_id,
std::set< uint32 > *  skip_vendors 
)
10108{
10109 // find all items from the reference vendor
10111 stmt->SetData(0, uint32(item));
10112 PreparedQueryResult result = WorldDatabase.Query(stmt);
10113
10114 if (!result)
10115 return 0;
10116
10117 uint32 count = 0;
10118 do
10119 {
10120 Field* fields = result->Fetch();
10121
10122 int32 item_id = fields[0].Get<int32>();
10123
10124 // if item is a negative, its a reference
10125 if (item_id < 0)
10126 count += LoadReferenceVendor(vendor, -item_id, skip_vendors);
10127 else
10128 {
10129 uint32 maxcount = fields[1].Get<uint32>();
10130 uint32 incrtime = fields[2].Get<uint32>();
10131 uint32 ExtendedCost = fields[3].Get<uint32>();
10132
10133 if (!IsVendorItemValid(vendor, item_id, maxcount, incrtime, ExtendedCost, nullptr, skip_vendors))
10134 continue;
10135
10136 VendorItemData& vList = _cacheVendorItemStore[vendor];
10137
10138 vList.AddItem(item_id, maxcount, incrtime, ExtendedCost);
10139 ++count;
10140 }
10141 } while (result->NextRow());
10142
10143 return count;
10144}
@ WORLD_SEL_NPC_VENDOR_REF
Definition WorldDatabase.h:46
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:10369
int LoadReferenceVendor(int32 vendor, int32 item_id, std::set< uint32 > *skip_vendors)
Definition ObjectMgr.cpp:10107

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 ( )
8245{
8246 uint32 oldMSTime = getMSTime();
8247
8248 // For reload case
8249 _repOnKillStore.clear();
8250
8251 uint32 count = 0;
8252
8253 // 0 1 2
8254 QueryResult result = WorldDatabase.Query("SELECT creature_id, RewOnKillRepFaction1, RewOnKillRepFaction2, "
8255 // 3 4 5 6 7 8 9
8256 "IsTeamAward1, MaxStanding1, RewOnKillRepValue1, IsTeamAward2, MaxStanding2, RewOnKillRepValue2, TeamDependent "
8257 "FROM creature_onkill_reputation");
8258
8259 if (!result)
8260 {
8261 LOG_WARN("server.loading", ">> Loaded 0 creature award reputation definitions. DB table `creature_onkill_reputation` is empty.");
8262 LOG_INFO("server.loading", " ");
8263 return;
8264 }
8265
8266 do
8267 {
8268 Field* fields = result->Fetch();
8269
8270 uint32 creature_id = fields[0].Get<uint32>();
8271
8272 ReputationOnKillEntry repOnKill;
8273 repOnKill.RepFaction1 = fields[1].Get<int16>();
8274 repOnKill.RepFaction2 = fields[2].Get<int16>();
8275 repOnKill.IsTeamAward1 = fields[3].Get<bool>();
8276 repOnKill.ReputationMaxCap1 = fields[4].Get<uint8>();
8277 repOnKill.RepValue1 = fields[5].Get<float>();
8278 repOnKill.IsTeamAward2 = fields[6].Get<bool>();
8279 repOnKill.ReputationMaxCap2 = fields[7].Get<uint8>();
8280 repOnKill.RepValue2 = fields[8].Get<float>();
8281 repOnKill.TeamDependent = fields[9].Get<uint8>();
8282
8283 if (!GetCreatureTemplate(creature_id))
8284 {
8285 LOG_ERROR("sql.sql", "Table `creature_onkill_reputation` have data for not existed creature entry ({}), skipped", creature_id);
8286 continue;
8287 }
8288
8289 if (repOnKill.RepFaction1)
8290 {
8291 FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(repOnKill.RepFaction1);
8292 if (!factionEntry1)
8293 {
8294 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.RepFaction1);
8295 continue;
8296 }
8297 }
8298
8299 if (repOnKill.RepFaction2)
8300 {
8301 FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(repOnKill.RepFaction2);
8302 if (!factionEntry2)
8303 {
8304 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.RepFaction2);
8305 continue;
8306 }
8307 }
8308
8309 _repOnKillStore[creature_id] = repOnKill;
8310
8311 ++count;
8312 } while (result->NextRow());
8313
8314 LOG_INFO("server.loading", ">> Loaded {} Creature Award Reputation Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8315 LOG_INFO("server.loading", " ");
8316}
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 ( )
8157{
8158 uint32 oldMSTime = getMSTime();
8159
8160 _repRewardRateStore.clear(); // for reload case
8161
8162 uint32 count = 0; // 0 1 2 3 4 5 6 7
8163 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");
8164 if (!result)
8165 {
8166 LOG_INFO("server.loading", ">> Loaded `reputation_reward_rate`, table is empty!");
8167 return;
8168 }
8169
8170 do
8171 {
8172 Field* fields = result->Fetch();
8173
8174 uint32 factionId = fields[0].Get<uint32>();
8175
8176 RepRewardRate repRate;
8177
8178 repRate.questRate = fields[1].Get<float>();
8179 repRate.questDailyRate = fields[2].Get<float>();
8180 repRate.questWeeklyRate = fields[3].Get<float>();
8181 repRate.questMonthlyRate = fields[4].Get<float>();
8182 repRate.questRepeatableRate = fields[5].Get<float>();
8183 repRate.creatureRate = fields[6].Get<float>();
8184 repRate.spellRate = fields[7].Get<float>();
8185
8186 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
8187 if (!factionEntry)
8188 {
8189 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_reward_rate`", factionId);
8190 continue;
8191 }
8192
8193 if (repRate.questRate < 0.0f)
8194 {
8195 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_rate with invalid rate {}, skipping data for faction {}", repRate.questRate, factionId);
8196 continue;
8197 }
8198
8199 if (repRate.questDailyRate < 0.0f)
8200 {
8201 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_daily_rate with invalid rate {}, skipping data for faction {}", repRate.questDailyRate, factionId);
8202 continue;
8203 }
8204
8205 if (repRate.questWeeklyRate < 0.0f)
8206 {
8207 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_weekly_rate with invalid rate {}, skipping data for faction {}", repRate.questWeeklyRate, factionId);
8208 continue;
8209 }
8210
8211 if (repRate.questMonthlyRate < 0.0f)
8212 {
8213 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_monthly_rate with invalid rate {}, skipping data for faction {}", repRate.questMonthlyRate, factionId);
8214 continue;
8215 }
8216
8217 if (repRate.questRepeatableRate < 0.0f)
8218 {
8219 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_repeatable_rate with invalid rate {}, skipping data for faction {}", repRate.questRepeatableRate, factionId);
8220 continue;
8221 }
8222
8223 if (repRate.creatureRate < 0.0f)
8224 {
8225 LOG_ERROR("sql.sql", "Table reputation_reward_rate has creature_rate with invalid rate {}, skipping data for faction {}", repRate.creatureRate, factionId);
8226 continue;
8227 }
8228
8229 if (repRate.spellRate < 0.0f)
8230 {
8231 LOG_ERROR("sql.sql", "Table reputation_reward_rate has spell_rate with invalid rate {}, skipping data for faction {}", repRate.spellRate, factionId);
8232 continue;
8233 }
8234
8235 _repRewardRateStore[factionId] = repRate;
8236
8237 ++count;
8238 } while (result->NextRow());
8239
8240 LOG_INFO("server.loading", ">> Loaded {} Reputation Reward Rate in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8241 LOG_INFO("server.loading", " ");
8242}
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 ( )
8319{
8320 uint32 oldMSTime = getMSTime();
8321
8322 _repSpilloverTemplateStore.clear(); // for reload case
8323
8324 uint32 count = 0; // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
8325 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");
8326
8327 if (!result)
8328 {
8329 LOG_INFO("server.loading", ">> Loaded `reputation_spillover_template`, table is empty.");
8330 LOG_INFO("server.loading", " ");
8331 return;
8332 }
8333
8334 do
8335 {
8336 Field* fields = result->Fetch();
8337
8338 uint32 factionId = fields[0].Get<uint16>();
8339
8340 RepSpilloverTemplate repTemplate;
8341
8342 repTemplate.faction[0] = fields[1].Get<uint16>();
8343 repTemplate.faction_rate[0] = fields[2].Get<float>();
8344 repTemplate.faction_rank[0] = fields[3].Get<uint8>();
8345 repTemplate.faction[1] = fields[4].Get<uint16>();
8346 repTemplate.faction_rate[1] = fields[5].Get<float>();
8347 repTemplate.faction_rank[1] = fields[6].Get<uint8>();
8348 repTemplate.faction[2] = fields[7].Get<uint16>();
8349 repTemplate.faction_rate[2] = fields[8].Get<float>();
8350 repTemplate.faction_rank[2] = fields[9].Get<uint8>();
8351 repTemplate.faction[3] = fields[10].Get<uint16>();
8352 repTemplate.faction_rate[3] = fields[11].Get<float>();
8353 repTemplate.faction_rank[3] = fields[12].Get<uint8>();
8354 repTemplate.faction[4] = fields[13].Get<uint16>();
8355 repTemplate.faction_rate[4] = fields[14].Get<float>();
8356 repTemplate.faction_rank[4] = fields[15].Get<uint8>();
8357 repTemplate.faction[5] = fields[16].Get<uint16>();
8358 repTemplate.faction_rate[5] = fields[17].Get<float>();
8359 repTemplate.faction_rank[5] = fields[18].Get<uint8>();
8360
8361 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
8362
8363 if (!factionEntry)
8364 {
8365 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", factionId);
8366 continue;
8367 }
8368
8369 if (factionEntry->team == 0)
8370 {
8371 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} in `reputation_spillover_template` does not belong to any team, skipping", factionId);
8372 continue;
8373 }
8374
8375 for (uint32 i = 0; i < MAX_SPILLOVER_FACTIONS; ++i)
8376 {
8377 if (repTemplate.faction[i])
8378 {
8379 FactionEntry const* factionSpillover = sFactionStore.LookupEntry(repTemplate.faction[i]);
8380
8381 if (!factionSpillover)
8382 {
8383 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);
8384 continue;
8385 }
8386
8387 if (factionSpillover->reputationListID < 0)
8388 {
8389 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);
8390 continue;
8391 }
8392
8393 if (repTemplate.faction_rank[i] >= MAX_REPUTATION_RANK)
8394 {
8395 LOG_ERROR("sql.sql", "Rank {} used in `reputation_spillover_template` for spillover faction {} is not valid, skipping", repTemplate.faction_rank[i], repTemplate.faction[i]);
8396 continue;
8397 }
8398 }
8399 }
8400
8401 FactionEntry const* factionEntry0 = sFactionStore.LookupEntry(repTemplate.faction[0]);
8402 if (repTemplate.faction[0] && !factionEntry0)
8403 {
8404 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[0]);
8405 continue;
8406 }
8407 FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(repTemplate.faction[1]);
8408 if (repTemplate.faction[1] && !factionEntry1)
8409 {
8410 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[1]);
8411 continue;
8412 }
8413 FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(repTemplate.faction[2]);
8414 if (repTemplate.faction[2] && !factionEntry2)
8415 {
8416 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[2]);
8417 continue;
8418 }
8419 FactionEntry const* factionEntry3 = sFactionStore.LookupEntry(repTemplate.faction[3]);
8420 if (repTemplate.faction[3] && !factionEntry3)
8421 {
8422 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[3]);
8423 continue;
8424 }
8425
8426 _repSpilloverTemplateStore[factionId] = repTemplate;
8427
8428 ++count;
8429 } while (result->NextRow());
8430
8431 LOG_INFO("server.loading", ">> Loaded {} Reputation Spillover Template in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8432 LOG_INFO("server.loading", " ");
8433}
#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 ( )
8935{
8936 uint32 oldMSTime = getMSTime();
8937
8938 _reservedNamesStore.clear(); // need for reload case
8939
8940 QueryResult result = CharacterDatabase.Query("SELECT name FROM reserved_name");
8941
8942 if (!result)
8943 {
8944 LOG_WARN("server.loading", ">> Loaded 0 reserved names. DB table `reserved_name` is empty!");
8945 return;
8946 }
8947
8948 uint32 count = 0;
8949
8950 Field* fields;
8951 do
8952 {
8953 fields = result->Fetch();
8954 std::string name = fields[0].Get<std::string>();
8955
8956 std::wstring wstr;
8957 if (!Utf8toWStr (name, wstr))
8958 {
8959 LOG_ERROR("sql.sql", "Table `reserved_name` have invalid name: {}", name);
8960 continue;
8961 }
8962
8963 wstrToLower(wstr);
8964
8965 _reservedNamesStore.insert(wstr);
8966 ++count;
8967 } while (result->NextRow());
8968
8969 LOG_INFO("server.loading", ">> Loaded {} reserved names from DB in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8970}

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

◆ LoadReservedPlayerNamesDBC()

void ObjectMgr::LoadReservedPlayerNamesDBC ( )
8973{
8974 if (!sWorld->getBoolConfig(CONFIG_STRICT_NAMES_RESERVED))
8975 {
8976 LOG_WARN("server.loading", ">> Loaded 0 reserved names from DBC. Config option disabled.");
8977 return;
8978 }
8979
8980 uint32 oldMSTime = getMSTime();
8981
8982 uint32 count = 0;
8983
8984 for (NamesReservedEntry const* reservedStore : sNamesReservedStore)
8985 {
8986 std::wstring wstr;
8987
8988 Utf8toWStr(reservedStore->Pattern, wstr);
8989
8990 // DBC does not have clean entries, remove the junk.
8991 boost::algorithm::replace_all(wstr, "\\<", "");
8992 boost::algorithm::replace_all(wstr, "\\>", "");
8993
8994 _reservedNamesStore.insert(wstr);
8995 count++;
8996 }
8997
8998 LOG_INFO("server.loading", ">> Loaded {} reserved names from DBC in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8999 LOG_INFO("server.loading", " ");
9000}
DBCStorage< NamesReservedEntry > sNamesReservedStore(NamesReservedfmt)
@ CONFIG_STRICT_NAMES_RESERVED
Definition WorldConfig.h:142
Definition DBCStructure.h:1398

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

◆ LoadScriptNames()

void ObjectMgr::LoadScriptNames ( )
10450{
10451 uint32 oldMSTime = getMSTime();
10452
10453 // We insert an empty placeholder here so we can use the
10454 // script id 0 as dummy for "no script found".
10455 _scriptNamesStore.emplace_back("");
10456
10457 QueryResult result = WorldDatabase.Query(
10458 "SELECT DISTINCT(ScriptName) FROM achievement_criteria_data WHERE ScriptName <> '' AND type = 11 "
10459 "UNION "
10460 "SELECT DISTINCT(ScriptName) FROM battleground_template WHERE ScriptName <> '' "
10461 "UNION "
10462 "SELECT DISTINCT(ScriptName) FROM creature WHERE ScriptName <> '' "
10463 "UNION "
10464 "SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' "
10465 "UNION "
10466 "SELECT DISTINCT(ScriptName) FROM gameobject WHERE ScriptName <> '' "
10467 "UNION "
10468 "SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' "
10469 "UNION "
10470 "SELECT DISTINCT(ScriptName) FROM item_template WHERE ScriptName <> '' "
10471 "UNION "
10472 "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
10473 "UNION "
10474 "SELECT DISTINCT(ScriptName) FROM spell_script_names WHERE ScriptName <> '' "
10475 "UNION "
10476 "SELECT DISTINCT(ScriptName) FROM transports WHERE ScriptName <> '' "
10477 "UNION "
10478 "SELECT DISTINCT(ScriptName) FROM game_weather WHERE ScriptName <> '' "
10479 "UNION "
10480 "SELECT DISTINCT(ScriptName) FROM conditions WHERE ScriptName <> '' "
10481 "UNION "
10482 "SELECT DISTINCT(ScriptName) FROM outdoorpvp_template WHERE ScriptName <> '' "
10483 "UNION "
10484 "SELECT DISTINCT(script) FROM instance_template WHERE script <> ''");
10485
10486 if (!result)
10487 {
10488 LOG_INFO("server.loading", " ");
10489 LOG_ERROR("sql.sql", ">> Loaded empty set of Script Names!");
10490 return;
10491 }
10492
10493 _scriptNamesStore.reserve(result->GetRowCount() + 1);
10494
10495 do
10496 {
10497 _scriptNamesStore.push_back((*result)[0].Get<std::string>());
10498 } while (result->NextRow());
10499
10500 std::sort(_scriptNamesStore.begin(), _scriptNamesStore.end());
10501 LOG_INFO("server.loading", ">> Loaded {} ScriptNames in {} ms", _scriptNamesStore.size(), GetMSTimeDiffToNow(oldMSTime));
10502 LOG_INFO("server.loading", " ");
10503}

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

◆ LoadScripts()

void ObjectMgr::LoadScripts ( ScriptsType  type)
private
5928{
5929 uint32 oldMSTime = getMSTime();
5930
5931 ScriptMapMap* scripts = GetScriptsMapByType(type);
5932 if (!scripts)
5933 return;
5934
5935 std::string tableName = GetScriptsTableNameByType(type);
5936 if (tableName.empty())
5937 return;
5938
5939 if (sScriptMgr->IsScriptScheduled()) // function cannot be called when scripts are in use.
5940 return;
5941
5942 LOG_INFO("server.loading", "Loading {}...", tableName);
5943
5944 scripts->clear(); // need for reload support
5945
5946 bool isSpellScriptTable = (type == SCRIPTS_SPELL);
5947 // 0 1 2 3 4 5 6 7 8 9
5948 QueryResult result = WorldDatabase.Query("SELECT id, delay, command, datalong, datalong2, dataint, x, y, z, o{} FROM {}", isSpellScriptTable ? ", effIndex" : "", tableName);
5949
5950 if (!result)
5951 {
5952 LOG_WARN("server.loading", ">> Loaded 0 script definitions. DB table `{}` is empty!", tableName);
5953 LOG_INFO("server.loading", " ");
5954 return;
5955 }
5956
5957 uint32 count = 0;
5958
5959 do
5960 {
5961 Field* fields = result->Fetch();
5962 ScriptInfo tmp;
5963 tmp.type = type;
5964 tmp.id = fields[0].Get<uint32>();
5965 if (isSpellScriptTable)
5966 tmp.id |= fields[10].Get<uint8>() << 24;
5967 tmp.delay = fields[1].Get<uint32>();
5968 tmp.command = ScriptCommands(fields[2].Get<uint32>());
5969 tmp.Raw.nData[0] = fields[3].Get<uint32>();
5970 tmp.Raw.nData[1] = fields[4].Get<uint32>();
5971 tmp.Raw.nData[2] = fields[5].Get<int32>();
5972 tmp.Raw.fData[0] = fields[6].Get<float>();
5973 tmp.Raw.fData[1] = fields[7].Get<float>();
5974 tmp.Raw.fData[2] = fields[8].Get<float>();
5975 tmp.Raw.fData[3] = fields[9].Get<float>();
5976
5977 // generic command args check
5978 switch (tmp.command)
5979 {
5981 {
5983 {
5984 LOG_ERROR("sql.sql", "Table `{}` has invalid talk type (datalong = {}) in SCRIPT_COMMAND_TALK for script id {}",
5985 tableName, tmp.Talk.ChatType, tmp.id);
5986 continue;
5987 }
5989 {
5990 LOG_ERROR("sql.sql", "Table `{}` has invalid talk text id (dataint = {}) in SCRIPT_COMMAND_TALK for script id {}",
5991 tableName, tmp.Talk.TextID, tmp.id);
5992 continue;
5993 }
5994 break;
5995 }
5996
5998 {
5999 if (!sEmotesStore.LookupEntry(tmp.Emote.EmoteID))
6000 {
6001 LOG_ERROR("sql.sql", "Table `{}` has invalid emote id (datalong = {}) in SCRIPT_COMMAND_EMOTE for script id {}",
6002 tableName, tmp.Emote.EmoteID, tmp.id);
6003 continue;
6004 }
6005 break;
6006 }
6007
6009 {
6010 if (!sMapStore.LookupEntry(tmp.TeleportTo.MapID))
6011 {
6012 LOG_ERROR("sql.sql", "Table `{}` has invalid map (Id: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
6013 tableName, tmp.TeleportTo.MapID, tmp.id);
6014 continue;
6015 }
6016
6018 {
6019 LOG_ERROR("sql.sql", "Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
6020 tableName, tmp.TeleportTo.DestX, tmp.TeleportTo.DestY, tmp.TeleportTo.DestZ, tmp.TeleportTo.Orientation, tmp.id);
6021 continue;
6022 }
6023 break;
6024 }
6025
6027 {
6028 Quest const* quest = GetQuestTemplate(tmp.QuestExplored.QuestID);
6029 if (!quest)
6030 {
6031 LOG_ERROR("sql.sql", "Table `{}` has invalid quest (ID: {}) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id {}",
6032 tableName, tmp.QuestExplored.QuestID, tmp.id);
6033 continue;
6034 }
6035
6037 {
6038 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.",
6039 tableName, tmp.QuestExplored.QuestID, tmp.id);
6040
6041 // this will prevent quest completing without objective
6042 const_cast<Quest*>(quest)->SetSpecialFlag(QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT);
6043
6044 // continue; - quest objective requirement set and command can be allowed
6045 }
6046
6048 {
6049 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 {}",
6050 tableName, tmp.QuestExplored.Distance, tmp.id);
6051 continue;
6052 }
6053
6055 {
6056 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",
6058 continue;
6059 }
6060
6062 {
6063 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",
6064 tableName, tmp.QuestExplored.Distance, tmp.id, INTERACTION_DISTANCE);
6065 continue;
6066 }
6067
6068 break;
6069 }
6070
6072 {
6074 {
6075 LOG_ERROR("sql.sql", "Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_KILL_CREDIT for script id {}",
6076 tableName, tmp.KillCredit.CreatureEntry, tmp.id);
6077 continue;
6078 }
6079 break;
6080 }
6081
6083 {
6085 if (!data)
6086 {
6087 LOG_ERROR("sql.sql", "Table `{}` has invalid gameobject (GUID: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
6088 tableName, tmp.RespawnGameobject.GOGuid, tmp.id);
6089 continue;
6090 }
6091
6092 GameObjectTemplate const* info = GetGameObjectTemplate(data->id);
6093 if (!info)
6094 {
6095 LOG_ERROR("sql.sql", "Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
6096 tableName, tmp.RespawnGameobject.GOGuid, data->id, tmp.id);
6097 continue;
6098 }
6099
6100 if (info->type == GAMEOBJECT_TYPE_FISHINGNODE ||
6102 info->type == GAMEOBJECT_TYPE_DOOR ||
6103 info->type == GAMEOBJECT_TYPE_BUTTON ||
6104 info->type == GAMEOBJECT_TYPE_TRAP)
6105 {
6106 LOG_ERROR("sql.sql", "Table `{}` have gameobject type ({}) unsupported by command SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
6107 tableName, info->entry, tmp.id);
6108 continue;
6109 }
6110 break;
6111 }
6112
6114 {
6116 {
6117 LOG_ERROR("sql.sql", "Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
6119 continue;
6120 }
6121
6123 if (!GetCreatureTemplate(entry))
6124 {
6125 LOG_ERROR("sql.sql", "Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
6126 tableName, tmp.TempSummonCreature.CreatureEntry, tmp.id);
6127 continue;
6128 }
6129 break;
6130 }
6131
6134 {
6136 if (!data)
6137 {
6138 LOG_ERROR("sql.sql", "Table `{}` has invalid gameobject (GUID: {}) in {} for script id {}",
6139 tableName, tmp.ToggleDoor.GOGuid, GetScriptCommandName(tmp.command), tmp.id);
6140 continue;
6141 }
6142
6143 GameObjectTemplate const* info = GetGameObjectTemplate(data->id);
6144 if (!info)
6145 {
6146 LOG_ERROR("sql.sql", "Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in {} for script id {}",
6147 tableName, tmp.ToggleDoor.GOGuid, data->id, GetScriptCommandName(tmp.command), tmp.id);
6148 continue;
6149 }
6150
6151 if (info->type != GAMEOBJECT_TYPE_DOOR)
6152 {
6153 LOG_ERROR("sql.sql", "Table `{}` has gameobject type ({}) non supported by command {} for script id {}",
6154 tableName, info->entry, GetScriptCommandName(tmp.command), tmp.id);
6155 continue;
6156 }
6157
6158 break;
6159 }
6160
6162 {
6163 if (!sSpellMgr->GetSpellInfo(tmp.RemoveAura.SpellID))
6164 {
6165 LOG_ERROR("sql.sql", "Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
6166 tableName, tmp.RemoveAura.SpellID, tmp.id);
6167 continue;
6168 }
6169 if (tmp.RemoveAura.Flags & ~0x1) // 1 bits (0, 1)
6170 {
6171 LOG_ERROR("sql.sql", "Table `{}` using unknown flags in datalong2 ({}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
6172 tableName, tmp.RemoveAura.Flags, tmp.id);
6173 continue;
6174 }
6175 break;
6176 }
6177
6179 {
6180 if (!sSpellMgr->GetSpellInfo(tmp.CastSpell.SpellID))
6181 {
6182 LOG_ERROR("sql.sql", "Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
6183 tableName, tmp.CastSpell.SpellID, tmp.id);
6184 continue;
6185 }
6186 if (tmp.CastSpell.Flags > 4) // targeting type
6187 {
6188 LOG_ERROR("sql.sql", "Table `{}` using unknown target in datalong2 ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
6189 tableName, tmp.CastSpell.Flags, tmp.id);
6190 continue;
6191 }
6192 if (tmp.CastSpell.Flags != 4 && tmp.CastSpell.CreatureEntry & ~0x1) // 1 bit (0, 1)
6193 {
6194 LOG_ERROR("sql.sql", "Table `{}` using unknown flags in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
6195 tableName, tmp.CastSpell.CreatureEntry, tmp.id);
6196 continue;
6197 }
6198 else if (tmp.CastSpell.Flags == 4 && !GetCreatureTemplate(tmp.CastSpell.CreatureEntry))
6199 {
6200 LOG_ERROR("sql.sql", "Table `{}` using invalid creature entry in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
6201 tableName, tmp.CastSpell.CreatureEntry, tmp.id);
6202 continue;
6203 }
6204 break;
6205 }
6206
6208 {
6210 {
6211 LOG_ERROR("sql.sql", "Table `{}` has nonexistent item (entry: {}) in SCRIPT_COMMAND_CREATE_ITEM for script id {}",
6212 tableName, tmp.CreateItem.ItemEntry, tmp.id);
6213 continue;
6214 }
6215 if (!tmp.CreateItem.Amount)
6216 {
6217 LOG_ERROR("sql.sql", "Table `{}` SCRIPT_COMMAND_CREATE_ITEM but amount is {} for script id {}",
6218 tableName, tmp.CreateItem.Amount, tmp.id);
6219 continue;
6220 }
6221 break;
6222 }
6223 default:
6224 break;
6225 }
6226
6227 if (scripts->find(tmp.id) == scripts->end())
6228 {
6229 ScriptMap emptyMap;
6230 (*scripts)[tmp.id] = emptyMap;
6231 }
6232 (*scripts)[tmp.id].insert(std::pair<uint32, ScriptInfo>(tmp.delay, tmp));
6233
6234 ++count;
6235 } while (result->NextRow());
6236
6237 LOG_INFO("server.loading", ">> Loaded {} script definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6238 LOG_INFO("server.loading", " ");
6239}
@ 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
ScriptsType type
Definition ObjectMgr.h:194
uint32 QuestID
Definition ObjectMgr.h:258
int32 TextID
Definition ObjectMgr.h:211
struct ScriptInfo::@271::@285 RemoveAura
float DestX
Definition ObjectMgr.h:232
uint32 ItemEntry
Definition ObjectMgr.h:319
uint32 ChatType
Definition ObjectMgr.h:209
uint32 id
Definition ObjectMgr.h:195
struct ScriptInfo::@271::@279 TeleportTo
uint32 delay
Definition ObjectMgr.h:196
float fData[4]
Definition ObjectMgr.h:204
struct ScriptInfo::@271::@284 ToggleDoor
struct ScriptInfo::@271::@280 QuestExplored
float PosY
Definition ObjectMgr.h:281
ScriptCommands command
Definition ObjectMgr.h:197
float DestY
Definition ObjectMgr.h:233
struct ScriptInfo::@271::@274 Talk
uint32 MapID
Definition ObjectMgr.h:246
uint32 nData[3]
Definition ObjectMgr.h:203
struct ScriptInfo::@271::@281 KillCredit
struct ScriptInfo::@271::@282 RespawnGameobject
float PosZ
Definition ObjectMgr.h:282
struct ScriptInfo::@271::@286 CastSpell
struct ScriptInfo::@271::@273 Raw
struct ScriptInfo::@271::@288 CreateItem
float PosX
Definition ObjectMgr.h:280
uint32 Distance
Definition ObjectMgr.h:259
uint32 SpellID
Definition ObjectMgr.h:297
struct ScriptInfo::@271::@283 TempSummonCreature
float DestZ
Definition ObjectMgr.h:234
uint32 GOGuid
Definition ObjectMgr.h:270
struct ScriptInfo::@271::@275 Emote
uint32 CreatureEntry
Definition ObjectMgr.h:264
uint32 Amount
Definition ObjectMgr.h:320
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 ( )
8725{
8726 uint32 oldMSTime = getMSTime();
8727
8728 // Reset prior state for hot-reload support
8729 // Preserve the forced legacy group for spawns on transport maps (set in LoadCreatures/LoadGameobjects).
8730 _spawnGroupMapStore.clear();
8731 for (auto& [id, data] : _creatureDataStore)
8732 data.spawnGroupId = _transportMaps.count(data.mapid) ? 1 : 0;
8733 for (auto& [id, data] : _gameObjectDataStore)
8734 data.spawnGroupId = _transportMaps.count(data.mapid) ? 1 : 0;
8735
8736 // 0 1 2
8737 QueryResult result = WorldDatabase.Query("SELECT groupId, spawnType, spawnId FROM spawn_group");
8738
8739 if (!result)
8740 {
8741 LOG_INFO("server.loading", ">> Loaded 0 spawn group members. DB table `spawn_group` is empty.");
8742 LOG_INFO("server.loading", " ");
8743 return;
8744 }
8745
8746 uint32 numMembers = 0;
8747 do
8748 {
8749 Field* fields = result->Fetch();
8750 uint32 groupId = fields[0].Get<uint32>();
8751 uint32 type = fields[1].Get<uint8>();
8752 if (type >= SPAWN_TYPE_MAX)
8753 {
8754 LOG_ERROR("sql.sql", "Spawn data with invalid type {} listed for spawn group {}. Skipped.", type, groupId);
8755 continue;
8756 }
8757 SpawnObjectType spawnType = SpawnObjectType(type);
8758 ObjectGuid::LowType spawnId = fields[2].Get<uint32>();
8759
8760 SpawnData const* data = GetSpawnData(spawnType, spawnId);
8761 if (!data)
8762 {
8763 LOG_ERROR("sql.sql", "Spawn data with ID ({},{}) not found, but is listed as a member of spawn group {}!",
8764 uint32(spawnType), spawnId, groupId);
8765 continue;
8766 }
8767 if (data->spawnGroupId)
8768 {
8769 LOG_ERROR("sql.sql", "Spawn with ID ({},{}) is listed as a member of spawn group {}, but is already a member of spawn group {}. Skipping.",
8770 uint32(spawnType), spawnId, groupId, data->spawnGroupId);
8771 continue;
8772 }
8773
8774 auto it = _spawnGroupDataStore.find(groupId);
8775 if (it == _spawnGroupDataStore.end())
8776 {
8777 LOG_ERROR("sql.sql", "Spawn group {} assigned to spawn ID ({},{}), but group is not found!", groupId, uint32(spawnType), spawnId);
8778 continue;
8779 }
8780
8781 SpawnGroupTemplateData& groupTemplate = it->second;
8782 if (groupTemplate.mapId == SPAWNGROUP_MAP_UNSET)
8783 groupTemplate.mapId = data->mapid;
8784 else if (groupTemplate.mapId != data->mapid && !(groupTemplate.flags & SPAWNGROUP_FLAG_SYSTEM))
8785 {
8786 LOG_ERROR("sql.sql", "Spawn group {} has map ID {}, but spawn ({},{}) has map id {} - spawn NOT added to group!",
8787 groupId, groupTemplate.mapId, uint32(spawnType), spawnId, data->mapid);
8788 continue;
8789 }
8790
8791 // Warn if spawn is also in a pool (non-system groups and pools are mutually exclusive)
8792 if (!(groupTemplate.flags & SPAWNGROUP_FLAG_SYSTEM))
8793 {
8794 uint32 poolId = 0;
8795 if (spawnType == SPAWN_TYPE_CREATURE)
8796 poolId = sPoolMgr->IsPartOfAPool<Creature>(spawnId);
8797 else if (spawnType == SPAWN_TYPE_GAMEOBJECT)
8798 poolId = sPoolMgr->IsPartOfAPool<GameObject>(spawnId);
8799
8800 if (poolId)
8801 LOG_WARN("sql.sql", "Spawn ({},{}) is a member of spawn group {} and also part of pool {}. This may cause issues!",
8802 uint32(spawnType), spawnId, groupId, poolId);
8803 }
8804
8805 const_cast<SpawnData*>(data)->spawnGroupId = groupId;
8806 if (!(groupTemplate.flags & SPAWNGROUP_FLAG_SYSTEM))
8807 _spawnGroupMapStore.emplace(groupId, data);
8808 ++numMembers;
8809 } while (result->NextRow());
8810
8811 LOG_INFO("server.loading", ">> Loaded {} spawn group members in {} ms", numMembers, GetMSTimeDiffToNow(oldMSTime));
8812 LOG_INFO("server.loading", " ");
8813}
SpawnObjectType
Definition SpawnData.h:26
@ SPAWN_TYPE_MAX
Definition SpawnData.h:30
SpawnData const * GetSpawnData(SpawnObjectType type, ObjectGuid::LowType spawnId) const
Definition ObjectMgr.cpp:8653
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 ( )
8667{
8668 uint32 oldMSTime = getMSTime();
8669
8670 _spawnGroupDataStore.clear();
8671
8672 // 0 1 2
8673 QueryResult result = WorldDatabase.Query("SELECT groupId, groupName, groupFlags FROM spawn_group_template");
8674
8675 if (result)
8676 {
8677 do
8678 {
8679 Field* fields = result->Fetch();
8680 uint32 groupId = fields[0].Get<uint32>();
8682 group.groupId = groupId;
8683 group.name = fields[1].Get<std::string>();
8684 group.mapId = SPAWNGROUP_MAP_UNSET;
8685 uint32 flags = fields[2].Get<uint32>();
8686 if (flags & ~uint32(SPAWNGROUP_FLAG_ALL))
8687 {
8688 flags &= uint32(SPAWNGROUP_FLAG_ALL);
8689 LOG_ERROR("sql.sql", "Invalid spawn group flag {} on group ID {} ({}), reduced to valid flags {}.",
8690 fields[2].Get<uint32>(), groupId, group.name, flags);
8691 }
8692 if ((flags & SPAWNGROUP_FLAG_SYSTEM) && (flags & SPAWNGROUP_FLAG_MANUAL_SPAWN))
8693 {
8694 flags &= ~SPAWNGROUP_FLAG_MANUAL_SPAWN;
8695 LOG_ERROR("sql.sql", "System spawn group {} ({}) has invalid manual spawn flag. Ignored.", groupId, group.name);
8696 }
8697 group.flags = SpawnGroupFlags(flags);
8698 } while (result->NextRow());
8699 }
8700
8701 if (_spawnGroupDataStore.find(0) == _spawnGroupDataStore.end())
8702 {
8703 LOG_ERROR("sql.sql", "Default spawn group (index 0) is missing from DB! Manually inserted.");
8705 data.groupId = 0;
8706 data.name = "Default Group";
8709 }
8710 if (_spawnGroupDataStore.find(1) == _spawnGroupDataStore.end())
8711 {
8712 LOG_ERROR("sql.sql", "Default legacy spawn group (index 1) is missing from DB! Manually inserted.");
8714 data.groupId = 1;
8715 data.name = "Legacy Group";
8718 }
8719
8720 LOG_INFO("server.loading", ">> Loaded {} spawn group templates in {} ms", _spawnGroupDataStore.size(), GetMSTimeDiffToNow(oldMSTime));
8721 LOG_INFO("server.loading", " ");
8722}
@ 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 ( )
6341{
6342 uint32 oldMSTime = getMSTime();
6343
6344 _spellScriptsStore.clear(); // need for reload case
6345
6346 QueryResult result = WorldDatabase.Query("SELECT spell_id, ScriptName FROM spell_script_names");
6347
6348 if (!result)
6349 {
6350 LOG_WARN("server.loading", ">> Loaded 0 spell script names. DB table `spell_script_names` is empty!");
6351 LOG_INFO("server.loading", " ");
6352 return;
6353 }
6354
6355 uint32 count = 0;
6356
6357 do
6358 {
6359 Field* fields = result->Fetch();
6360
6361 int32 spellId = fields[0].Get<int32>();
6362 std::string scriptName = fields[1].Get<std::string>();
6363
6364 bool allRanks = false;
6365 if (spellId <= 0)
6366 {
6367 allRanks = true;
6368 spellId = -spellId;
6369 }
6370
6371 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
6372 if (!spellInfo)
6373 {
6374 LOG_ERROR("sql.sql", "Scriptname: `{}` spell (spell_id:{}) does not exist in `Spell.dbc`.", scriptName, fields[0].Get<int32>());
6375 continue;
6376 }
6377
6378 if (allRanks)
6379 {
6380 if (sSpellMgr->GetFirstSpellInChain(spellId) != uint32(spellId))
6381 {
6382 LOG_ERROR("sql.sql", "Scriptname: `{}` spell (spell_id:{}) is not first rank of spell.", scriptName, fields[0].Get<int32>());
6383 continue;
6384 }
6385 while (spellInfo)
6386 {
6387 _spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, GetScriptId(scriptName)));
6388 spellInfo = spellInfo->GetNextRankSpell();
6389 }
6390 }
6391 else
6392 _spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, GetScriptId(scriptName)));
6393 ++count;
6394 } while (result->NextRow());
6395
6396 LOG_INFO("server.loading", ">> Loaded {} spell script names in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6397 LOG_INFO("server.loading", " ");
6398}
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 ( )
6242{
6244
6245 // check ids
6246 for (ScriptMapMap::const_iterator itr = sSpellScripts.begin(); itr != sSpellScripts.end(); ++itr)
6247 {
6248 uint32 spellId = uint32(itr->first) & 0x00FFFFFF;
6249 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
6250
6251 if (!spellInfo)
6252 {
6253 LOG_ERROR("sql.sql", "Table `spell_scripts` has not existing spell (Id: {}) as script id", spellId);
6254 continue;
6255 }
6256
6257 SpellEffIndex i = SpellEffIndex((uint32(itr->first) >> 24) & 0x000000FF);
6258 if (uint32(i) >= MAX_SPELL_EFFECTS)
6259 {
6260 LOG_ERROR("sql.sql", "Table `spell_scripts` has too high effect index {} for spell (Id: {}) as script id", uint32(i), spellId);
6261 }
6262
6263 //check for correct spellEffect
6264 if (!spellInfo->Effects[i].Effect || (spellInfo->Effects[i].Effect != SPELL_EFFECT_SCRIPT_EFFECT && spellInfo->Effects[i].Effect != SPELL_EFFECT_DUMMY))
6265 LOG_ERROR("sql.sql", "Table `spell_scripts` - spell {} effect {} is not SPELL_EFFECT_SCRIPT_EFFECT or SPELL_EFFECT_DUMMY", spellId, uint32(i));
6266 }
6267}
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 ( )
7058{
7059 uint32 oldMSTime = getMSTime();
7060
7061 _tavernAreaTriggerStore.clear(); // need for reload case
7062
7063 QueryResult result = WorldDatabase.Query("SELECT id, faction FROM areatrigger_tavern");
7064
7065 if (!result)
7066 {
7067 LOG_WARN("server.loading", ">> Loaded 0 tavern triggers. DB table `areatrigger_tavern` is empty.");
7068 LOG_INFO("server.loading", " ");
7069 return;
7070 }
7071
7072 uint32 count = 0;
7073
7074 do
7075 {
7076 ++count;
7077
7078 Field* fields = result->Fetch();
7079
7080 uint32 Trigger_ID = fields[0].Get<uint32>();
7081
7082 AreaTrigger const* atEntry = GetAreaTrigger(Trigger_ID);
7083 if (!atEntry)
7084 {
7085 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
7086 continue;
7087 }
7088
7089 uint32 faction = fields[1].Get<uint32>();
7090
7091 _tavernAreaTriggerStore.emplace(Trigger_ID, faction);
7092 } while (result->NextRow());
7093
7094 LOG_INFO("server.loading", ">> Loaded {} Tavern Triggers in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7095 LOG_INFO("server.loading", " ");
7096}

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 ( )
9942{
9943 uint32 oldMSTime = getMSTime();
9944
9945 // For reload case
9946 _trainers.clear();
9947 _classTrainers.clear();
9948
9949 std::unordered_map<int32, std::vector<Trainer::Spell>> spellsByTrainer;
9950 if (QueryResult trainerSpellsResult = WorldDatabase.Query("SELECT TrainerId, SpellId, MoneyCost, ReqSkillLine, ReqSkillRank, ReqAbility1, ReqAbility2, ReqAbility3, ReqLevel FROM trainer_spell"))
9951 {
9952 do
9953 {
9954 Field* fields = trainerSpellsResult->Fetch();
9955
9956 Trainer::Spell spell;
9957 uint32 trainerId = fields[0].Get<uint32>();
9958 spell.SpellId = fields[1].Get<uint32>();
9959 spell.MoneyCost = fields[2].Get<uint32>();
9960 spell.ReqSkillLine = fields[3].Get<uint32>();
9961 spell.ReqSkillRank = fields[4].Get<uint32>();
9962 spell.ReqAbility[0] = fields[5].Get<uint32>();
9963 spell.ReqAbility[1] = fields[6].Get<uint32>();
9964 spell.ReqAbility[2] = fields[7].Get<uint32>();
9965 spell.ReqLevel = fields[8].Get<uint8>();
9966
9967 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell.SpellId);
9968 if (!spellInfo)
9969 {
9970 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing spell (SpellId: {}) for TrainerId {}, ignoring", spell.SpellId, trainerId);
9971 continue;
9972 }
9973
9974 if (GetTalentSpellCost(spell.SpellId))
9975 {
9976 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing spell (SpellId: {}) which is a talent, for TrainerId {}, ignoring", spell.SpellId, trainerId);
9977 continue;
9978 }
9979
9980 if (spell.ReqSkillLine && !sSkillLineStore.LookupEntry(spell.ReqSkillLine))
9981 {
9982 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing skill (ReqSkillLine: {}) for TrainerId {} and SpellId {}, ignoring",
9983 spell.ReqSkillLine, spell.SpellId, trainerId);
9984 continue;
9985 }
9986
9987 bool allReqValid = true;
9988 for (std::size_t i = 0; i < spell.ReqAbility.size(); ++i)
9989 {
9990 uint32 requiredSpell = spell.ReqAbility[i];
9991 if (requiredSpell && !sSpellMgr->GetSpellInfo(requiredSpell))
9992 {
9993 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing spell (ReqAbility {} : {}) for TrainerId {} and SpellId {}, ignoring",
9994 i + 1, requiredSpell, trainerId, spell.SpellId);
9995 allReqValid = false;
9996 }
9997 }
9998
9999 if (!allReqValid)
10000 continue;
10001
10002 spellsByTrainer[trainerId].push_back(spell);
10003 } while (trainerSpellsResult->NextRow());
10004 }
10005
10006 if (QueryResult trainersResult = WorldDatabase.Query("SELECT Id, Type, Requirement, Greeting FROM trainer"))
10007 {
10008 do
10009 {
10010 Field* fields = trainersResult->Fetch();
10011
10012 uint32 trainerId = fields[0].Get<uint32>();
10013 Trainer::Type trainerType = Trainer::Type(fields[1].Get<uint8>());
10014 uint32 requirement = fields[2].Get<uint32>();
10015 std::string greeting = fields[3].Get<std::string>();
10016 std::vector<Trainer::Spell> spells;
10017 auto spellsItr = spellsByTrainer.find(trainerId);
10018 if (spellsItr != spellsByTrainer.end())
10019 {
10020 spells = std::move(spellsItr->second);
10021 spellsByTrainer.erase(spellsItr);
10022 }
10023
10024 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)));
10025 ASSERT(isNew);
10026 if (trainerType == Trainer::Type::Class)
10027 {
10028 if (!requirement || requirement >= MAX_CLASSES)
10029 LOG_ERROR("sql.sql", "Table `trainer` has invalid class requirement for trainer {}, ignoring");
10030 else
10031 {
10032 uint8 classId = static_cast<uint8>(requirement);
10033 _classTrainers[classId].push_back(&it->second);
10034 }
10035 }
10036 } while (trainersResult->NextRow());
10037 }
10038
10039 for (auto const& unusedSpells : spellsByTrainer)
10040 {
10041 for (Trainer::Spell const& unusedSpell : unusedSpells.second)
10042 {
10043 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing trainer (TrainerId: {}) for SpellId {}, ignoring", unusedSpells.first, unusedSpell.SpellId);
10044 }
10045 }
10046
10047 if (QueryResult trainerLocalesResult = WorldDatabase.Query("SELECT Id, locale, Greeting_lang FROM trainer_locale"))
10048 {
10049 do
10050 {
10051 Field* fields = trainerLocalesResult->Fetch();
10052 uint32 trainerId = fields[0].Get<uint32>();
10053 std::string localeName = fields[1].Get<std::string>();
10054
10055 LocaleConstant locale = GetLocaleByName(localeName);
10056 if (locale == LOCALE_enUS)
10057 continue;
10058
10060 trainer->AddGreetingLocale(locale, fields[2].Get<std::string>());
10061 else
10062 LOG_ERROR("sql.sql", "Table `trainer_locale` references non-existing trainer (TrainerId: {}) for locale %s, ignoring",
10063 trainerId, localeName.c_str());
10064 } while (trainerLocalesResult->NextRow());
10065 }
10066
10067 LOG_INFO("server.loading", ">> Loaded {} Trainers in {} ms", _trainers.size(), GetMSTimeDiffToNow(oldMSTime));
10068}
#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 ( )
4108{
4109 uint32 oldMSTime = getMSTime();
4110
4111 _vehicleAccessoryStore.clear(); // needed for reload case
4112
4113 uint32 count = 0;
4114
4115 // 0 1 2 3 4 5
4116 QueryResult result = WorldDatabase.Query("SELECT `guid`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer` FROM `vehicle_accessory`");
4117
4118 if (!result)
4119 {
4120 LOG_WARN("server.loading", ">> Loaded 0 Vehicle Accessories in {} ms", GetMSTimeDiffToNow(oldMSTime));
4121 LOG_INFO("server.loading", " ");
4122 return;
4123 }
4124
4125 do
4126 {
4127 Field* fields = result->Fetch();
4128
4129 uint32 uiGUID = fields[0].Get<uint32>();
4130 uint32 uiAccessory = fields[1].Get<uint32>();
4131 int8 uiSeat = int8(fields[2].Get<int16>());
4132 bool bMinion = fields[3].Get<bool>();
4133 uint8 uiSummonType = fields[4].Get<uint8>();
4134 uint32 uiSummonTimer = fields[5].Get<uint32>();
4135
4136 if (!GetCreatureTemplate(uiAccessory))
4137 {
4138 LOG_ERROR("sql.sql", "Table `vehicle_accessory`: Accessory {} does not exist.", uiAccessory);
4139 continue;
4140 }
4141
4142 _vehicleAccessoryStore[uiGUID].push_back(VehicleAccessory(uiAccessory, uiSeat, bMinion, uiSummonType, uiSummonTimer));
4143
4144 ++count;
4145 } while (result->NextRow());
4146
4147 LOG_INFO("server.loading", ">> Loaded {} Vehicle Accessories in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4148 LOG_INFO("server.loading", " ");
4149}
Definition VehicleDefines.h:115

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

◆ LoadVehicleSeatAddon()

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

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

◆ LoadVendors()

void ObjectMgr::LoadVendors ( )
10147{
10148 uint32 oldMSTime = getMSTime();
10149
10150 // For reload case
10151 for (CacheVendorItemContainer::iterator itr = _cacheVendorItemStore.begin(); itr != _cacheVendorItemStore.end(); ++itr)
10152 itr->second.Clear();
10153 _cacheVendorItemStore.clear();
10154
10155 std::set<uint32> skip_vendors;
10156
10157 QueryResult result = WorldDatabase.Query("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor ORDER BY entry, slot ASC, item, ExtendedCost");
10158 if (!result)
10159 {
10160 LOG_INFO("server.loading", " ");
10161 LOG_WARN("server.loading", ">> Loaded 0 Vendors. DB table `npc_vendor` is empty!");
10162 return;
10163 }
10164
10165 uint32 count = 0;
10166
10167 do
10168 {
10169 Field* fields = result->Fetch();
10170
10171 uint32 entry = fields[0].Get<uint32>();
10172 int32 item_id = fields[1].Get<int32>();
10173
10174 // if item is a negative, its a reference
10175 if (item_id < 0)
10176 count += LoadReferenceVendor(entry, -item_id, &skip_vendors);
10177 else
10178 {
10179 uint32 maxcount = fields[2].Get<uint32>();
10180 uint32 incrtime = fields[3].Get<uint32>();
10181 uint32 ExtendedCost = fields[4].Get<uint32>();
10182
10183 if (!IsVendorItemValid(entry, item_id, maxcount, incrtime, ExtendedCost, nullptr, &skip_vendors))
10184 continue;
10185
10186 VendorItemData& vList = _cacheVendorItemStore[entry];
10187
10188 vList.AddItem(item_id, maxcount, incrtime, ExtendedCost);
10189 ++count;
10190 }
10191 } while (result->NextRow());
10192
10193 LOG_INFO("server.loading", ">> Loaded {} Vendors in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10194 LOG_INFO("server.loading", " ");
10195}

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

◆ LoadWaypointScripts()

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

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

◆ NewGOData()

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

References _gameObjectDataStore.

Referenced by AddGOData().

◆ NewOrExistCreatureData()

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

References _creatureDataStore.

Referenced by AddCreData().

◆ OnDeleteSpawnData()

void ObjectMgr::OnDeleteSpawnData ( SpawnData const *  data)
8816{
8817 auto templateIt = _spawnGroupDataStore.find(data->spawnGroupId);
8818 ASSERT(templateIt != _spawnGroupDataStore.end(), "Spawn data is being deleted and has invalid spawn group index {}!", data->spawnGroupId);
8819 if (templateIt->second.flags & SPAWNGROUP_FLAG_SYSTEM)
8820 return;
8821
8822 auto pair = _spawnGroupMapStore.equal_range(data->spawnGroupId);
8823 for (auto it = pair.first; it != pair.second; ++it)
8824 {
8825 if (it->second != data)
8826 continue;
8827 _spawnGroupMapStore.erase(it);
8828 return;
8829 }
8830 ASSERT(false, "Spawn data being removed is member of spawn group {}, but not found in lookup table!", data->spawnGroupId);
8831}

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

◆ PlayerCreateInfoAddItemHelper()

void ObjectMgr::PlayerCreateInfoAddItemHelper ( uint32  race_,
uint32  class_,
uint32  itemId,
int32  count 
)
private
4313{
4314 if (!_playerInfo[race_][class_])
4315 return;
4316
4317 if (count > 0)
4318 _playerInfo[race_][class_]->item.push_back(PlayerCreateInfoItem(itemId, count));
4319 else
4320 {
4321 if (count < -1)
4322 LOG_ERROR("sql.sql", "Invalid count {} specified on item {} be removed from original player create info (use -1)!", count, itemId);
4323
4324 for (uint32 gender = 0; gender < GENDER_NONE; ++gender)
4325 {
4326 if (CharStartOutfitEntry const* entry = GetCharStartOutfitEntry(race_, class_, gender))
4327 {
4328 bool found = false;
4329 for (uint8 x = 0; x < MAX_OUTFIT_ITEMS; ++x)
4330 {
4331 if (entry->ItemId[x] > 0 && uint32(entry->ItemId[x]) == itemId)
4332 {
4333 found = true;
4334 const_cast<CharStartOutfitEntry*>(entry)->ItemId[x] = 0;
4335 break;
4336 }
4337 }
4338
4339 if (!found)
4340 LOG_ERROR("sql.sql", "Item {} specified to be removed from original create info not found in dbc!", itemId);
4341 }
4342 }
4343 }
4344}
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 
)
2798{
2799 uint8 mask = data->spawnMask;
2800 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
2801 {
2802 if (mask & 1)
2803 {
2804 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
2805 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
2806 cell_guids.creatures.erase(guid);
2807 }
2808 }
2809}

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 
)
3250{
3251 uint8 mask = data->spawnMask;
3252 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
3253 {
3254 if (mask & 1)
3255 {
3256 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
3257 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
3258 cell_guids.gameobjects.erase(guid);
3259 }
3260 }
3261}

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 
)
10348{
10349 CacheVendorItemContainer::iterator iter = _cacheVendorItemStore.find(entry);
10350 if (iter == _cacheVendorItemStore.end())
10351 return false;
10352
10353 if (!iter->second.RemoveItem(item))
10354 return false;
10355
10356 if (persist)
10357 {
10359
10360 stmt->SetData(0, entry);
10361 stmt->SetData(1, item);
10362
10363 WorldDatabase.Execute(stmt);
10364 }
10365
10366 return true;
10367}
@ WORLD_DEL_NPC_VENDOR
Definition WorldDatabase.h:45

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

◆ 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
1399{ DBCLocaleIndex = locale; }

References DBCLocaleIndex.

◆ SetHighestGuids()

void ObjectMgr::SetHighestGuids ( )
7573{
7574 QueryResult result = CharacterDatabase.Query("SELECT MAX(guid) FROM characters");
7575 if (result)
7576 GetGuidSequenceGenerator<HighGuid::Player>().Set((*result)[0].Get<uint32>() + 1);
7577
7578 result = CharacterDatabase.Query("SELECT MAX(guid) FROM item_instance");
7579 if (result)
7580 GetGuidSequenceGenerator<HighGuid::Item>().Set((*result)[0].Get<uint32>() + 1);
7581
7582 // Cleanup other tables from not existed guids ( >= _hiItemGuid)
7583 CharacterDatabase.Execute("DELETE FROM character_inventory WHERE item >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7584 CharacterDatabase.Execute("DELETE FROM mail_items WHERE item_guid >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7585 CharacterDatabase.Execute("DELETE FROM auctionhouse WHERE itemguid >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7586 CharacterDatabase.Execute("DELETE FROM guild_bank_item WHERE item_guid >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7587
7588 result = WorldDatabase.Query("SELECT MAX(guid) FROM transports");
7589 if (result)
7590 GetGuidSequenceGenerator<HighGuid::Mo_Transport>().Set((*result)[0].Get<uint32>() + 1);
7591
7592 result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse");
7593 if (result)
7594 _auctionId = (*result)[0].Get<uint32>() + 1;
7595
7596 result = CharacterDatabase.Query("SELECT MAX(id) FROM mail");
7597 if (result)
7598 _mailId = (*result)[0].Get<uint32>() + 1;
7599
7600 result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team");
7601 if (result)
7602 sArenaTeamMgr->SetNextArenaTeamId((*result)[0].Get<uint32>() + 1);
7603
7604 result = CharacterDatabase.Query("SELECT MAX(fight_id) FROM log_arena_fights");
7605 if (result)
7606 sArenaTeamMgr->SetLastArenaLogId((*result)[0].Get<uint32>());
7607
7608 result = CharacterDatabase.Query("SELECT MAX(setguid) FROM character_equipmentsets");
7609 if (result)
7610 _equipmentSetGuid = (*result)[0].Get<uint64>() + 1;
7611
7612 result = CharacterDatabase.Query("SELECT MAX(guildId) FROM guild");
7613 if (result)
7614 sGuildMgr->SetNextGuildId((*result)[0].Get<uint32>() + 1);
7615
7616 result = WorldDatabase.Query("SELECT MAX(guid) FROM creature");
7617 if (result)
7618 _creatureSpawnId = (*result)[0].Get<uint32>() + 1;
7619
7620 result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject");
7621 if (result)
7622 _gameObjectSpawnId = (*result)[0].Get<uint32>() + 1;
7623}
#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 ( )
6401{
6402 uint32 oldMSTime = getMSTime();
6403
6404 if (_spellScriptsStore.empty())
6405 {
6406 LOG_INFO("server.loading", ">> Validated 0 scripts.");
6407 LOG_INFO("server.loading", " ");
6408 return;
6409 }
6410
6411 uint32 count = 0;
6412
6413 for (SpellScriptsContainer::iterator itr = _spellScriptsStore.begin(); itr != _spellScriptsStore.end();)
6414 {
6415 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
6416 std::vector<std::pair<SpellScriptLoader*, SpellScriptsContainer::iterator> > SpellScriptLoaders;
6417 sScriptMgr->CreateSpellScriptLoaders(itr->first, SpellScriptLoaders);
6418 itr = _spellScriptsStore.upper_bound(itr->first);
6419
6420 for (std::vector<std::pair<SpellScriptLoader*, SpellScriptsContainer::iterator> >::iterator sitr = SpellScriptLoaders.begin(); sitr != SpellScriptLoaders.end(); ++sitr)
6421 {
6422 SpellScript* spellScript = sitr->first->GetSpellScript();
6423 AuraScript* auraScript = sitr->first->GetAuraScript();
6424 bool valid = true;
6425 if (!spellScript && !auraScript)
6426 {
6427 LOG_ERROR("sql.sql", "Functions GetSpellScript() and GetAuraScript() of script `{}` do not return objects - script skipped", GetScriptName(sitr->second->second));
6428 valid = false;
6429 }
6430 if (spellScript)
6431 {
6432 spellScript->_Init(&sitr->first->GetName(), spellInfo->Id);
6433 spellScript->_Register();
6434 if (!spellScript->_Validate(spellInfo))
6435 valid = false;
6436 delete spellScript;
6437 }
6438 if (auraScript)
6439 {
6440 auraScript->_Init(&sitr->first->GetName(), spellInfo->Id);
6441 auraScript->_Register();
6442 if (!auraScript->_Validate(spellInfo))
6443 valid = false;
6444 delete auraScript;
6445 }
6446 if (!valid)
6447 {
6448 _spellScriptsStore.erase(sitr->second);
6449 }
6450 }
6451 ++count;
6452 }
6453
6454 LOG_INFO("server.loading", ">> Validated {} scripts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6455 LOG_INFO("server.loading", " ");
6456}
Definition SpellScript.h:518
bool _Validate(SpellInfo const *entry) override
Definition SpellScript.cpp:662
std::string const & GetScriptName(uint32 id) const
Definition ObjectMgr.cpp:10505
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: