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

#include "ObjectMgr.h"

Classes

struct  GameobjectInstanceSavedState
 

Public Types

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

Public Member Functions

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

Static Public Member Functions

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

Public Attributes

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

Private Types

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

Private Member Functions

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

Private Attributes

uint32 _auctionId
 
uint64 _equipmentSetGuid
 
uint32 _mailId
 
std::mutex _mailIdMutex
 
uint32 _hiPetNumber
 
std::mutex _hiPetNumberMutex
 
ObjectGuid::LowType _creatureSpawnId
 
ObjectGuid::LowType _gameObjectSpawnId
 
std::map< HighGuid, std::unique_ptr< ObjectGuidGeneratorBase > > _guidGenerators
 
QuestMap _questTemplates
 
std::vector< Quest * > _questTemplatesFast
 
QuestAreaTriggerContainer _questAreaTriggerStore
 
TavernAreaTriggerContainer _tavernAreaTriggerStore
 
GossipTextContainer _gossipTextStore
 
QuestGreetingContainer _questGreetingStore
 
AreaTriggerContainer _areaTriggerStore
 
AreaTriggerTeleportContainer _areaTriggerTeleportStore
 
AreaTriggerScriptContainer _areaTriggerScriptStore
 
DungeonProgressionRequirementsContainer _accessRequirementStore
 
DungeonEncounterContainer _dungeonEncounterStore
 
RepRewardRateContainer _repRewardRateStore
 
RepOnKillContainer _repOnKillStore
 
RepSpilloverTemplateContainer _repSpilloverTemplateStore
 
GossipMenusContainer _gossipMenusStore
 
GossipMenuItemsContainer _gossipMenuItemsStore
 
PointOfInterestContainer _pointsOfInterestStore
 
QuestPOIContainer _questPOIStore
 
QuestRelations _goQuestRelations
 
QuestRelations _goQuestInvolvedRelations
 
QuestRelations _creatureQuestRelations
 
QuestRelations _creatureQuestInvolvedRelations
 
ReservedNamesContainer _reservedNamesStore
 
ProfanityNamesContainer _profanityNamesStore
 
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
 
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< 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 
1675 {
1677 CREATURE_TO_GO, // Creature is dependant on GO
1678 GO_TO_GO,
1679 GO_TO_CREATURE, // GO is dependant on creature
1680 };
@ CREATURE_TO_GO
Definition ObjectMgr.h:1677
@ CREATURE_TO_CREATURE
Definition ObjectMgr.h:1676
@ GO_TO_GO
Definition ObjectMgr.h:1678
@ GO_TO_CREATURE
Definition ObjectMgr.h:1679

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}
@ LOCALE_enUS
Definition Common.h:118
std::uint8_t uint8
Definition Define.h:109
#define MAX_CLASSES
Definition SharedDefines.h:140
ObjectGuid::LowType _gameObjectSpawnId
Definition ObjectMgr.h:1514
uint32 _mailId
Definition ObjectMgr.h:1508
ObjectGuid::LowType _creatureSpawnId
Definition ObjectMgr.h:1513
LocaleConstant DBCLocaleIndex
Definition ObjectMgr.h:1581
PlayerClassInfo * _playerClassInfo[MAX_CLASSES]
Definition ObjectMgr.h:1601
uint64 _equipmentSetGuid
Definition ObjectMgr.h:1507
uint32 _auctionId
Definition ObjectMgr.h:1506
uint32 _hiPetNumber
Definition ObjectMgr.h:1510

References _playerClassInfo, and MAX_CLASSES.

◆ ~ObjectMgr()

ObjectMgr::~ObjectMgr ( )
private
316{
317 for (QuestMap::iterator i = _questTemplates.begin(); i != _questTemplates.end(); ++i)
318 delete i->second;
319
320 for (PetLevelInfoContainer::iterator i = _petInfoStore.begin(); i != _petInfoStore.end(); ++i)
321 delete[] i->second;
322
323 // free only if loaded
324 for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
325 {
326 if (_playerClassInfo[class_])
327 delete[] _playerClassInfo[class_]->levelInfo;
328 delete _playerClassInfo[class_];
329 }
330
331 for (int race = 0; race < sRaceMgr->GetMaxRaces(); ++race)
332 {
333 for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
334 {
335 if (_playerInfo[race][class_])
336 delete[] _playerInfo[race][class_]->levelInfo;
337 delete _playerInfo[race][class_];
338 }
339 }
340
341 for (CacheVendorItemContainer::iterator itr = _cacheVendorItemStore.begin(); itr != _cacheVendorItemStore.end(); ++itr)
342 itr->second.Clear();
343
344 for (DungeonEncounterContainer::iterator itr = _dungeonEncounterStore.begin(); itr != _dungeonEncounterStore.end(); ++itr)
345 for (DungeonEncounterList::iterator encounterItr = itr->second.begin(); encounterItr != itr->second.end(); ++encounterItr)
346 delete *encounterItr;
347
348 for (DungeonProgressionRequirementsContainer::iterator itr = _accessRequirementStore.begin(); itr != _accessRequirementStore.end(); ++itr)
349 {
350 std::unordered_map<uint8, DungeonProgressionRequirements*> difficulties = itr->second;
351 for (auto difficultiesItr = difficulties.begin(); difficultiesItr != difficulties.end(); ++difficultiesItr)
352 {
353 for (auto questItr = difficultiesItr->second->quests.begin(); questItr != difficultiesItr->second->quests.end(); ++questItr)
354 {
355 delete* questItr;
356 }
357
358 for (auto achievementItr = difficultiesItr->second->achievements.begin(); achievementItr != difficultiesItr->second->achievements.end(); ++achievementItr)
359 {
360 delete* achievementItr;
361 }
362
363 for (auto itemsItr = difficultiesItr->second->items.begin(); itemsItr != difficultiesItr->second->items.end(); ++itemsItr)
364 {
365 delete* itemsItr;
366 }
367
368 delete difficultiesItr->second;
369 }
370 }
371}
#define sRaceMgr
Definition RaceMgr.h:52
std::vector< std::vector< PlayerInfo * > > _playerInfo
Definition ObjectMgr.h:1605
PetLevelInfoContainer _petInfoStore
Definition ObjectMgr.h:1599
QuestMap _questTemplates
Definition ObjectMgr.h:1529
DungeonProgressionRequirementsContainer _accessRequirementStore
Definition ObjectMgr.h:1543
DungeonEncounterContainer _dungeonEncounterStore
Definition ObjectMgr.h:1544
CacheVendorItemContainer _cacheVendorItemStore
Definition ObjectMgr.h:1667
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 
)
2700{
2701 uint8 mask = data->spawnMask;
2702 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
2703 {
2704 if (mask & 1)
2705 {
2706 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
2707 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
2708 cell_guids.creatures.insert(guid);
2709 }
2710 }
2711}
uint32 MAKE_PAIR32(uint16 l, uint16 h)
Definition ObjectDefines.h:88
MapObjectGuids _mapObjectGuidsStore
Definition ObjectMgr.h:1626
GridCoord ComputeGridCoord(float x, float y)
Definition GridDefines.h:185
Definition ObjectMgr.h:479
CellGuidSet creatures
Definition ObjectMgr.h:480
Definition GridDefines.h:88
uint32 GetId() const
Definition GridDefines.h:150

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

Referenced by AddCreData(), and LoadCreatures().

◆ AddCreData()

ObjectGuid::LowType ObjectMgr::AddCreData ( uint32  entry,
uint32  map,
float  x,
float  y,
float  z,
float  o,
uint32  spawntimedelay = 0 
)
2779{
2780 CreatureTemplate const* cInfo = GetCreatureTemplate(entry);
2781 if (!cInfo)
2782 return 0;
2783
2784 uint32 level = cInfo->minlevel == cInfo->maxlevel ? cInfo->minlevel : urand(cInfo->minlevel, cInfo->maxlevel); // Only used for extracting creature base stats
2785 CreatureBaseStats const* stats = GetCreatureBaseStats(level, cInfo->unit_class);
2786 Map* map = sMapMgr->CreateBaseMap(mapId);
2787 if (!map)
2788 return 0;
2789
2791 CreatureData& data = NewOrExistCreatureData(spawnId);
2792 data.spawnMask = spawnId;
2793 data.id1 = entry;
2794 data.id2 = 0;
2795 data.id3 = 0;
2796 data.mapid = mapId;
2797 data.displayid = 0;
2798 data.equipmentId = 0;
2799 data.posX = x;
2800 data.posY = y;
2801 data.posZ = z;
2802 data.orientation = o;
2803 data.spawntimesecs = spawntimedelay;
2804 data.wander_distance = 0;
2805 data.currentwaypoint = 0;
2806 data.curhealth = stats->GenerateHealth(cInfo);
2807 data.curmana = stats->GenerateMana(cInfo);
2808 data.movementType = cInfo->MovementType;
2809 data.spawnMask = 1;
2811 data.dbData = false;
2812 data.npcflag = cInfo->npcflag;
2813 data.unit_flags = cInfo->unit_flags;
2814 data.dynamicflags = cInfo->dynamicflags;
2815
2816 AddCreatureToGrid(spawnId, &data);
2817
2818 // Spawn if necessary (loaded grids only)
2819 if (!map->Instanceable() && map->IsGridLoaded(x, y))
2820 {
2821 Creature* creature = new Creature();
2822 if (!creature->LoadCreatureFromDB(spawnId, map, true, true))
2823 {
2824 LOG_ERROR("sql.sql", "AddCreature: Cannot add creature entry {} to map", entry);
2825 delete creature;
2826 return 0;
2827 }
2828 }
2829
2830 return spawnId;
2831}
std::uint32_t uint32
Definition Define.h:107
#define LOG_ERROR(filterType__,...)
Definition Log.h:158
#define sMapMgr
Definition MapMgr.h:220
@ PHASEMASK_NORMAL
Definition Object.h:62
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:44
Definition Creature.h:47
bool LoadCreatureFromDB(ObjectGuid::LowType guid, Map *map, bool addToMap=true, bool allowDuplicate=false)
Definition Creature.cpp:1665
Definition Map.h:163
bool IsGridLoaded(GridCoord const &gridCoord) const
Definition Map.cpp:204
bool Instanceable() const
Definition Map.h:295
uint32 LowType
Definition ObjectGuid.h:122
CreatureBaseStats const * GetCreatureBaseStats(uint8 level, uint8 unitClass)
Definition ObjectMgr.cpp:10414
void AddCreatureToGrid(ObjectGuid::LowType guid, CreatureData const *data)
Definition ObjectMgr.cpp:2699
ObjectGuid::LowType GenerateCreatureSpawnId()
Definition ObjectMgr.cpp:7678
CreatureData & NewOrExistCreatureData(ObjectGuid::LowType spawnId)
Definition ObjectMgr.h:1239
CreatureTemplate const * GetCreatureTemplate(uint32 entry)
Definition ObjectMgr.cpp:10779
Definition CreatureData.h:299
uint32 GenerateMana(CreatureTemplate const *info) const
Definition CreatureData.h:319
uint32 GenerateHealth(CreatureTemplate const *info) const
Definition CreatureData.h:314
Definition CreatureData.h:371
float wander_distance
Definition CreatureData.h:385
uint32 phaseMask
Definition CreatureData.h:377
uint32 spawntimesecs
Definition CreatureData.h:384
uint32 dynamicflags
Definition CreatureData.h:393
uint32 npcflag
Definition CreatureData.h:391
bool dbData
Definition CreatureData.h:395
uint32 displayid
Definition CreatureData.h:378
uint8 movementType
Definition CreatureData.h:389
uint8 spawnMask
Definition CreatureData.h:390
uint32 unit_flags
Definition CreatureData.h:392
uint32 id2
Definition CreatureData.h:374
uint32 curhealth
Definition CreatureData.h:387
float orientation
Definition CreatureData.h:383
uint32 curmana
Definition CreatureData.h:388
uint32 id3
Definition CreatureData.h:375
float posY
Definition CreatureData.h:381
float posX
Definition CreatureData.h:380
int8 equipmentId
Definition CreatureData.h:379
uint32 currentwaypoint
Definition CreatureData.h:386
uint16 mapid
Definition CreatureData.h:376
float posZ
Definition CreatureData.h:382
uint32 id1
Definition CreatureData.h:373
Definition CreatureData.h:186
uint32 unit_flags
Definition CreatureData.h:214
uint8 minlevel
Definition CreatureData.h:195
uint8 maxlevel
Definition CreatureData.h:196
uint32 MovementType
Definition CreatureData.h:230
uint32 npcflag
Definition CreatureData.h:199
uint32 unit_class
Definition CreatureData.h:213
uint32 dynamicflags
Definition CreatureData.h:216

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

◆ AddGameobjectInfo()

void ObjectMgr::AddGameobjectInfo ( GameObjectTemplate goinfo)

◆ AddGameobjectToGrid()

void ObjectMgr::AddGameobjectToGrid ( ObjectGuid::LowType  guid,
GameObjectData const *  data 
)
3142{
3143 uint8 mask = data->spawnMask;
3144 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
3145 {
3146 if (mask & 1)
3147 {
3148 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
3149 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
3150 cell_guids.gameobjects.insert(guid);
3151 }
3152 }
3153}
CellGuidSet gameobjects
Definition ObjectMgr.h:481

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

Referenced by AddGOData(), and LoadGameobjects().

◆ AddGameTele()

bool ObjectMgr::AddGameTele ( GameTele data)
9596{
9597 // find max id
9598 uint32 new_id = 0;
9599 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9600 if (itr->first > new_id)
9601 new_id = itr->first;
9602
9603 // use next
9604 ++new_id;
9605
9606 if (!Utf8toWStr(tele.name, tele.wnameLow))
9607 return false;
9608
9609 wstrToLower(tele.wnameLow);
9610
9611 _gameTeleStore[new_id] = tele;
9612
9614
9615 stmt->SetData(0, new_id);
9616 stmt->SetData(1, tele.position_x);
9617 stmt->SetData(2, tele.position_y);
9618 stmt->SetData(3, tele.position_z);
9619 stmt->SetData(4, tele.orientation);
9620 stmt->SetData(5, uint16(tele.mapId));
9621 stmt->SetData(6, tele.name);
9622
9623 WorldDatabase.Execute(stmt);
9624
9625 return true;
9626}
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition DatabaseEnv.cpp:20
std::uint16_t uint16
Definition Define.h:108
bool Utf8toWStr(char const *utf8str, std::size_t csize, wchar_t *wstr, std::size_t &wsize)
Definition Util.cpp:281
void wstrToLower(std::wstring &str)
Definition Util.cpp:382
@ WORLD_INS_GAME_TELE
Definition WorldDatabase.h:41
GameTeleContainer _gameTeleStore
Definition ObjectMgr.h:1569
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 
)
2728{
2729 GameObjectTemplate const* goinfo = GetGameObjectTemplate(entry);
2730 if (!goinfo)
2731 return 0;
2732
2733 Map* map = sMapMgr->CreateBaseMap(mapId);
2734 if (!map)
2735 return 0;
2736
2738
2739 GameObjectData& data = NewGOData(spawnId);
2740 data.id = entry;
2741 data.mapid = mapId;
2742 data.posX = x;
2743 data.posY = y;
2744 data.posZ = z;
2745 data.orientation = o;
2746 data.rotation.x = rotation0;
2747 data.rotation.y = rotation1;
2748 data.rotation.z = rotation2;
2749 data.rotation.w = rotation3;
2750 data.spawntimesecs = spawntimedelay;
2751 data.animprogress = 100;
2752 data.spawnMask = 1;
2753 data.go_state = GO_STATE_READY;
2755 data.artKit = goinfo->type == GAMEOBJECT_TYPE_CAPTURE_POINT ? 21 : 0;
2756 data.dbData = false;
2757
2758 AddGameobjectToGrid(spawnId, &data);
2759
2760 // Spawn if necessary (loaded grids only)
2761 // We use spawn coords to spawn
2762 if (!map->Instanceable() && map->IsGridLoaded(x, y))
2763 {
2765 if (!go->LoadGameObjectFromDB(spawnId, map))
2766 {
2767 LOG_ERROR("sql.sql", "AddGOData: cannot add gameobject entry {} to map", entry);
2768 delete go;
2769 return 0;
2770 }
2771 }
2772
2773 LOG_DEBUG("maps", "AddGOData: spawnId {} entry {} map {} x {} y {} z {} o {}", spawnId, entry, mapId, x, y, z, o);
2774
2775 return spawnId;
2776}
@ GO_STATE_READY
Definition GameObjectData.h:708
#define LOG_DEBUG(filterType__,...)
Definition Log.h:170
@ GAMEOBJECT_TYPE_CAPTURE_POINT
Definition SharedDefines.h:1577
Definition GameObject.h:120
virtual bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map *map, bool addToMap=true)
Definition GameObject.cpp:1099
void AddGameobjectToGrid(ObjectGuid::LowType guid, GameObjectData const *data)
Definition ObjectMgr.cpp:3141
GameObjectTemplate const * GetGameObjectTemplate(uint32 entry)
Definition ObjectMgr.cpp:10755
ObjectGuid::LowType GenerateGameObjectSpawnId()
Definition ObjectMgr.cpp:7688
GameObjectData & NewGOData(ObjectGuid::LowType guid)
Definition ObjectMgr.h:1339
bool IsGameObjectStaticTransport(uint32 entry)
Definition ObjectMgr.cpp:10764
Definition Transport.h:115
Definition GameObjectData.h:714
bool dbData
Definition GameObjectData.h:730
float orientation
Definition GameObjectData.h:722
float posZ
Definition GameObjectData.h:721
uint8 artKit
Definition GameObjectData.h:729
int32 spawntimesecs
Definition GameObjectData.h:724
uint8 spawnMask
Definition GameObjectData.h:728
G3D::Quat rotation
Definition GameObjectData.h:723
uint32 animprogress
Definition GameObjectData.h:726
uint16 mapid
Definition GameObjectData.h:717
float posX
Definition GameObjectData.h:719
uint32 phaseMask
Definition GameObjectData.h:718
float posY
Definition GameObjectData.h:720
uint32 id
Definition GameObjectData.h:716
GOState go_state
Definition GameObjectData.h:727
Definition GameObjectData.h:31
uint32 type
Definition GameObjectData.h:33

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

◆ AddLocaleString()

◆ AddProfanityPlayerName()

void ObjectMgr::AddProfanityPlayerName ( std::string const &  name)
8963{
8964 if (!IsProfanityName(name))
8965 {
8966 std::wstring wstr;
8967 if (!Utf8toWStr(name, wstr))
8968 {
8969 LOG_ERROR("server", "Could not add invalid name to profanity player names: {}", name);
8970 return;
8971 }
8972 wstrToLower(wstr);
8973
8974 _profanityNamesStore.insert(wstr);
8975
8977 stmt->SetData(0, name);
8978 CharacterDatabase.Execute(stmt);
8979 }
8980}
@ CHAR_INS_PROFANITY_PLAYER_NAME
Definition CharacterDatabase.h:522
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition DatabaseEnv.cpp:21
ProfanityNamesContainer _profanityNamesStore
Definition ObjectMgr.h:1567
bool IsProfanityName(std::string_view name) const
Definition ObjectMgr.cpp:8947

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

◆ AddReservedPlayerName()

void ObjectMgr::AddReservedPlayerName ( std::string const &  name)
8860{
8861 if (!IsReservedName(name))
8862 {
8863 std::wstring wstr;
8864 if (!Utf8toWStr(name, wstr))
8865 {
8866 LOG_ERROR("server", "Could not add invalid name to reserved player names: {}", name);
8867 return;
8868 }
8869 wstrToLower(wstr);
8870
8871 _reservedNamesStore.insert(wstr);
8872
8874 stmt->SetData(0, name);
8875 CharacterDatabase.Execute(stmt);
8876 }
8877}
@ CHAR_INS_RESERVED_PLAYER_NAME
Definition CharacterDatabase.h:521
bool IsReservedName(std::string_view name) const
Definition ObjectMgr.cpp:8844
ReservedNamesContainer _reservedNamesStore
Definition ObjectMgr.h:1563

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 
)
10092{
10093 VendorItemData& vList = _cacheVendorItemStore[entry];
10094 vList.AddItem(item, maxcount, incrtime, extendedCost);
10095
10096 if (persist)
10097 {
10099
10100 stmt->SetData(0, entry);
10101 stmt->SetData(1, item);
10102 stmt->SetData(2, maxcount);
10103 stmt->SetData(3, incrtime);
10104 stmt->SetData(4, extendedCost);
10105
10106 WorldDatabase.Execute(stmt);
10107 }
10108}
@ WORLD_INS_NPC_VENDOR
Definition WorldDatabase.h:43
Definition CreatureData.h:470
void AddItem(uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost)
Definition CreatureData.h:482

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
4910{
4911 // base data (last known level)
4912 *info = _playerInfo[race][_class]->levelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) - 1];
4913
4914 // if conversion from uint32 to uint8 causes unexpected behaviour, change lvl to uint32
4915 for (uint8 lvl = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) - 1; lvl < level; ++lvl)
4916 {
4917 switch (_class)
4918 {
4919 case CLASS_WARRIOR:
4920 info->stats[STAT_STRENGTH] += (lvl > 23 ? 2 : (lvl > 1 ? 1 : 0));
4921 info->stats[STAT_STAMINA] += (lvl > 23 ? 2 : (lvl > 1 ? 1 : 0));
4922 info->stats[STAT_AGILITY] += (lvl > 36 ? 1 : (lvl > 6 && (lvl % 2) ? 1 : 0));
4923 info->stats[STAT_INTELLECT] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4924 info->stats[STAT_SPIRIT] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4925 break;
4926 case CLASS_PALADIN:
4927 info->stats[STAT_STRENGTH] += (lvl > 3 ? 1 : 0);
4928 info->stats[STAT_STAMINA] += (lvl > 33 ? 2 : (lvl > 1 ? 1 : 0));
4929 info->stats[STAT_AGILITY] += (lvl > 38 ? 1 : (lvl > 7 && !(lvl % 2) ? 1 : 0));
4930 info->stats[STAT_INTELLECT] += (lvl > 6 && (lvl % 2) ? 1 : 0);
4931 info->stats[STAT_SPIRIT] += (lvl > 7 ? 1 : 0);
4932 break;
4933 case CLASS_HUNTER:
4934 info->stats[STAT_STRENGTH] += (lvl > 4 ? 1 : 0);
4935 info->stats[STAT_STAMINA] += (lvl > 4 ? 1 : 0);
4936 info->stats[STAT_AGILITY] += (lvl > 33 ? 2 : (lvl > 1 ? 1 : 0));
4937 info->stats[STAT_INTELLECT] += (lvl > 8 && (lvl % 2) ? 1 : 0);
4938 info->stats[STAT_SPIRIT] += (lvl > 38 ? 1 : (lvl > 9 && !(lvl % 2) ? 1 : 0));
4939 break;
4940 case CLASS_ROGUE:
4941 info->stats[STAT_STRENGTH] += (lvl > 5 ? 1 : 0);
4942 info->stats[STAT_STAMINA] += (lvl > 4 ? 1 : 0);
4943 info->stats[STAT_AGILITY] += (lvl > 16 ? 2 : (lvl > 1 ? 1 : 0));
4944 info->stats[STAT_INTELLECT] += (lvl > 8 && !(lvl % 2) ? 1 : 0);
4945 info->stats[STAT_SPIRIT] += (lvl > 38 ? 1 : (lvl > 9 && !(lvl % 2) ? 1 : 0));
4946 break;
4947 case CLASS_PRIEST:
4948 info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4949 info->stats[STAT_STAMINA] += (lvl > 5 ? 1 : 0);
4950 info->stats[STAT_AGILITY] += (lvl > 38 ? 1 : (lvl > 8 && (lvl % 2) ? 1 : 0));
4951 info->stats[STAT_INTELLECT] += (lvl > 22 ? 2 : (lvl > 1 ? 1 : 0));
4952 info->stats[STAT_SPIRIT] += (lvl > 3 ? 1 : 0);
4953 break;
4954 case CLASS_SHAMAN:
4955 info->stats[STAT_STRENGTH] += (lvl > 34 ? 1 : (lvl > 6 && (lvl % 2) ? 1 : 0));
4956 info->stats[STAT_STAMINA] += (lvl > 4 ? 1 : 0);
4957 info->stats[STAT_AGILITY] += (lvl > 7 && !(lvl % 2) ? 1 : 0);
4958 info->stats[STAT_INTELLECT] += (lvl > 5 ? 1 : 0);
4959 info->stats[STAT_SPIRIT] += (lvl > 4 ? 1 : 0);
4960 break;
4961 case CLASS_MAGE:
4962 info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4963 info->stats[STAT_STAMINA] += (lvl > 5 ? 1 : 0);
4964 info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4965 info->stats[STAT_INTELLECT] += (lvl > 24 ? 2 : (lvl > 1 ? 1 : 0));
4966 info->stats[STAT_SPIRIT] += (lvl > 33 ? 2 : (lvl > 2 ? 1 : 0));
4967 break;
4968 case CLASS_WARLOCK:
4969 info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4970 info->stats[STAT_STAMINA] += (lvl > 38 ? 2 : (lvl > 3 ? 1 : 0));
4971 info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4972 info->stats[STAT_INTELLECT] += (lvl > 33 ? 2 : (lvl > 2 ? 1 : 0));
4973 info->stats[STAT_SPIRIT] += (lvl > 38 ? 2 : (lvl > 3 ? 1 : 0));
4974 break;
4975 case CLASS_DRUID:
4976 info->stats[STAT_STRENGTH] += (lvl > 38 ? 2 : (lvl > 6 && (lvl % 2) ? 1 : 0));
4977 info->stats[STAT_STAMINA] += (lvl > 32 ? 2 : (lvl > 4 ? 1 : 0));
4978 info->stats[STAT_AGILITY] += (lvl > 38 ? 2 : (lvl > 8 && (lvl % 2) ? 1 : 0));
4979 info->stats[STAT_INTELLECT] += (lvl > 38 ? 3 : (lvl > 4 ? 1 : 0));
4980 info->stats[STAT_SPIRIT] += (lvl > 38 ? 3 : (lvl > 5 ? 1 : 0));
4981 }
4982 }
4983}
@ 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:191
#define sWorld
Definition World.h:316

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 
)
9415{
9416 AreaTableEntry const* fArea = sAreaTableStore.LookupEntry(entry);
9417 if (!fArea)
9418 {
9419 LOG_ERROR("sql.sql", "AreaId {} defined in `skill_fishing_base_level` does not exist", entry);
9420 return;
9421 }
9422
9423 _fishingBaseForAreaStore[entry] = skill;
9424
9425 LOG_INFO("server.loading", ">> Fishing base skill level of area {} changed to {}", entry, skill);
9426 LOG_INFO("server.loading", " ");
9427}
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
#define LOG_INFO(filterType__,...)
Definition Log.h:166
FishingBaseSkillContainer _fishingBaseForAreaStore
Definition ObjectMgr.h:1614
Definition DBCStructure.h:519

References _fishingBaseForAreaStore, LOG_ERROR, LOG_INFO, and sAreaTableStore.

◆ CheckCreatureMovement()

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

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

Referenced by CheckCreatureTemplate(), and LoadCreatureMovementOverrides().

◆ CheckCreatureTemplate()

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

References _creatureCustomIDsStore, _difficultyEntries, Creature::_GetDamageMod(), _hasDifficultyEntries, CreatureTemplate::AIName, BASE_ATTACK_TIME, CreatureTemplate::BaseAttackTime, CheckCreatureMovement(), 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
9430{
9431 // get main part of the name
9432 std::wstring mainpart = GetMainPartOfName(w_ownname, 0);
9433 // prepare flags
9434 bool x = true;
9435 bool y = true;
9436
9437 // check declined names
9438 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
9439 {
9440 std::wstring wname;
9441 if (!Utf8toWStr(names.name[i], wname))
9442 return false;
9443
9444 if (mainpart != GetMainPartOfName(wname, i + 1))
9445 x = false;
9446
9447 if (w_ownname != wname)
9448 y = false;
9449 }
9450 return (x || y);
9451}
#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
9135{
9136 std::wstring wname;
9137 if (!Utf8toWStr(name, wname))
9138 return PET_NAME_INVALID;
9139
9140 if (wname.size() > MAX_PET_NAME)
9141 return PET_NAME_TOO_LONG;
9142
9143 uint32 minName = sWorld->getIntConfig(CONFIG_MIN_PET_NAME);
9144 if (wname.size() < minName)
9145 return PET_NAME_TOO_SHORT;
9146
9147 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_PET_NAMES);
9148 if (!isValidString(wname, strictMask, false))
9150
9151 // Check Reserved Name
9152 if (sObjectMgr->IsReservedName(name))
9153 return PET_NAME_RESERVED;
9154
9155 // Check Profanity Name
9156 if (sObjectMgr->IsProfanityName(name))
9157 return PET_NAME_PROFANE;
9158
9159 return PET_NAME_SUCCESS;
9160}
bool isValidString(std::wstring wstr, uint32 strictMask, bool numericOrSpace, bool create=false)
Definition ObjectMgr.cpp:9019
#define sObjectMgr
Definition ObjectMgr.h:1699
#define MAX_PET_NAME
Definition ObjectMgr.h:685
@ PET_NAME_INVALID
Definition SharedDefines.h:3900
@ PET_NAME_RESERVED
Definition SharedDefines.h:3906
@ PET_NAME_SUCCESS
Definition SharedDefines.h:3898
@ PET_NAME_MIXED_LANGUAGES
Definition SharedDefines.h:3904
@ PET_NAME_TOO_SHORT
Definition SharedDefines.h:3902
@ PET_NAME_TOO_LONG
Definition SharedDefines.h:3903
@ PET_NAME_PROFANE
Definition SharedDefines.h:3905
@ CONFIG_STRICT_PET_NAMES
Definition WorldConfig.h:178
@ CONFIG_MIN_PET_NAME
Definition WorldConfig.h:181

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

Referenced by WorldSession::HandlePetRename().

◆ CheckPlayerName()

uint8 ObjectMgr::CheckPlayerName ( std::string_view  name,
bool  create = false 
)
static
9056{
9057 std::wstring wname;
9058
9059 // Check for invalid characters
9060 if (!Utf8toWStr(name, wname))
9062
9063 // Check for too long name
9064 if (wname.size() > MAX_PLAYER_NAME)
9065 return CHAR_NAME_TOO_LONG;
9066
9067 // Check for too short name
9068 uint32 minName = sWorld->getIntConfig(CONFIG_MIN_PLAYER_NAME);
9069 if (wname.size() < minName)
9070 return CHAR_NAME_TOO_SHORT;
9071
9072 // Check for mixed languages
9073 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_PLAYER_NAMES);
9074 if (!isValidString(wname, strictMask, false, create))
9076
9077 // Check for three consecutive letters
9078 wstrToLower(wname);
9079 for (std::size_t i = 2; i < wname.size(); ++i)
9080 if (wname[i] == wname[i - 1] && wname[i] == wname[i - 2])
9082
9083 // Check Reserved Name
9084 if (sObjectMgr->IsReservedName(name))
9085 return CHAR_NAME_RESERVED;
9086
9087 // Check Profanity Name
9088 if (sObjectMgr->IsProfanityName(name))
9089 return CHAR_NAME_PROFANE;
9090
9091 return CHAR_NAME_SUCCESS;
9092}
#define MAX_PLAYER_NAME
Definition ObjectMgr.h:683
@ CHAR_NAME_TOO_SHORT
Definition SharedDefines.h:3655
@ CHAR_NAME_THREE_CONSECUTIVE
Definition SharedDefines.h:3663
@ CHAR_NAME_INVALID_CHARACTER
Definition SharedDefines.h:3657
@ CHAR_NAME_TOO_LONG
Definition SharedDefines.h:3656
@ CHAR_NAME_RESERVED
Definition SharedDefines.h:3660
@ CHAR_NAME_MIXED_LANGUAGES
Definition SharedDefines.h:3658
@ CHAR_NAME_PROFANE
Definition SharedDefines.h:3659
@ CHAR_NAME_SUCCESS
Definition SharedDefines.h:3652
@ CONFIG_STRICT_PLAYER_NAMES
Definition WorldConfig.h:175
@ CONFIG_MIN_PLAYER_NAME
Definition WorldConfig.h:179

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
1650{
1651 npcflag = cinfo->npcflag;
1652 unit_flags = cinfo->unit_flags;
1653 dynamicflags = cinfo->dynamicflags;
1654
1655 if (data)
1656 {
1657 if (data->npcflag)
1658 npcflag = data->npcflag;
1659
1660 if (data->unit_flags)
1661 unit_flags = data->unit_flags;
1662
1663 if (data->dynamicflags)
1664 dynamicflags = data->dynamicflags;
1665 }
1666}

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
1635{
1636 // Load creature model (display id)
1637 if (data && data->displayid)
1638 if (CreatureModel const* model = cinfo->GetModelWithDisplayId(data->displayid))
1639 return model;
1640
1641 if (!cinfo->HasFlagsExtra(CREATURE_FLAG_EXTRA_TRIGGER))
1642 if (CreatureModel const* model = cinfo->GetRandomValidModel())
1643 return model;
1644
1645 // Triggers by default receive the invisible model
1646 return cinfo->GetFirstInvisibleModel();
1647}
@ CREATURE_FLAG_EXTRA_TRIGGER
Definition CreatureData.h:52

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

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

◆ DeleteCreatureData()

void ObjectMgr::DeleteCreatureData ( ObjectGuid::LowType  spawnId)
8656{
8657 // remove mapid*cellid -> guid_set map
8658 CreatureData const* data = GetCreatureData(guid);
8659 if (data)
8660 RemoveCreatureFromGrid(guid, data);
8661
8662 _creatureDataStore.erase(guid);
8663}
CreatureDataContainer _creatureDataStore
Definition ObjectMgr.h:1629
void RemoveCreatureFromGrid(ObjectGuid::LowType guid, CreatureData const *data)
Definition ObjectMgr.cpp:2713
CreatureData const * GetCreatureData(ObjectGuid::LowType spawnId) const
Definition ObjectMgr.h:1230

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

◆ DeleteGameTele()

bool ObjectMgr::DeleteGameTele ( std::string_view  name)
9629{
9630 // explicit name case
9631 std::wstring wname;
9632 if (!Utf8toWStr(name, wname))
9633 return false;
9634
9635 // converting string that we try to find to lower case
9636 wstrToLower(wname);
9637
9638 for (GameTeleContainer::iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9639 {
9640 if (itr->second.wnameLow == wname)
9641 {
9643
9644 stmt->SetData(0, itr->second.name);
9645
9646 WorldDatabase.Execute(stmt);
9647
9648 _gameTeleStore.erase(itr);
9649 return true;
9650 }
9651 }
9652
9653 return false;
9654}
@ WORLD_DEL_GAME_TELE
Definition WorldDatabase.h:42

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

◆ DeleteGOData()

void ObjectMgr::DeleteGOData ( ObjectGuid::LowType  guid)
8666{
8667 // remove mapid*cellid -> guid_set map
8668 GameObjectData const* data = GetGameObjectData(guid);
8669 if (data)
8670 RemoveGameobjectFromGrid(guid, data);
8671
8672 _gameObjectDataStore.erase(guid);
8673}
GameObjectData const * GetGameObjectData(ObjectGuid::LowType spawnId) const
Definition ObjectMgr.h:1265
GameObjectDataContainer _gameObjectDataStore
Definition ObjectMgr.h:1643
void RemoveGameobjectFromGrid(ObjectGuid::LowType guid, GameObjectData const *data)
Definition ObjectMgr.cpp:3155

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

◆ GenerateAuctionID()

uint32 ObjectMgr::GenerateAuctionID ( )
7648{
7649 if (_auctionId >= 0xFFFFFFFE)
7650 {
7651 LOG_ERROR("server.worldserver", "Auctions ids overflow!! Can't continue, shutting down server. ");
7653 }
7654 return _auctionId++;
7655}
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 ( )
7679{
7680 if (_creatureSpawnId >= uint32(0xFFFFFF))
7681 {
7682 LOG_ERROR("server.worldserver", "Creature spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info.");
7684 }
7685 return _creatureSpawnId++;
7686}

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

Referenced by AddCreData().

◆ GenerateEquipmentSetGuid()

uint64 ObjectMgr::GenerateEquipmentSetGuid ( )
7658{
7659 if (_equipmentSetGuid >= uint64(0xFFFFFFFFFFFFFFFELL))
7660 {
7661 LOG_ERROR("server.worldserver", "EquipmentSet guid overflow!! Can't continue, shutting down server. ");
7663 }
7664 return _equipmentSetGuid++;
7665}
std::uint64_t uint64
Definition Define.h:106

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

◆ GenerateGameObjectSpawnId()

uint32 ObjectMgr::GenerateGameObjectSpawnId ( )
7689{
7690 if (_gameObjectSpawnId >= uint32(0xFFFFFF))
7691 {
7692 LOG_ERROR("server.worldserver", "GameObject spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7694 }
7695 return _gameObjectSpawnId++;
7696}

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

Referenced by AddGOData().

◆ GenerateMailID()

uint32 ObjectMgr::GenerateMailID ( )
7668{
7669 if (_mailId >= 0xFFFFFFFE)
7670 {
7671 LOG_ERROR("server.worldserver", "Mail ids overflow!! Can't continue, shutting down server. ");
7673 }
7674 std::lock_guard<std::mutex> guard(_mailIdMutex);
7675 return _mailId++;
7676}
std::mutex _mailIdMutex
Definition ObjectMgr.h:1509

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

◆ GeneratePetName()

std::string ObjectMgr::GeneratePetName ( uint32  entry)
8155{
8156 std::vector<std::string>& list0 = _petHalfName0[entry];
8157 std::vector<std::string>& list1 = _petHalfName1[entry];
8158
8159 if (list0.empty() || list1.empty())
8160 {
8161 CreatureTemplate const* cinfo = GetCreatureTemplate(entry);
8162 char const* petname = GetPetName(cinfo->family, sWorld->GetDefaultDbcLocale());
8163 if (!petname)
8164 return cinfo->Name;
8165
8166 return std::string(petname);
8167 }
8168
8169 return *(list0.begin() + urand(0, list0.size() - 1)) + *(list1.begin() + urand(0, list1.size() - 1));
8170}
char const * GetPetName(uint32 petfamily, uint32 dbclang)
Definition DBCStores.cpp:665
HalfNameContainer _petHalfName1
Definition ObjectMgr.h:1618
HalfNameContainer _petHalfName0
Definition ObjectMgr.h:1617
std::string Name
Definition CreatureData.h:191

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

Referenced by GeneratePetNameLocale().

◆ GeneratePetNameLocale()

std::string ObjectMgr::GeneratePetNameLocale ( uint32  entry,
LocaleConstant  locale 
)
8142{
8143 std::vector<std::string>& list0 = _petHalfLocaleName0[std::make_pair(entry, locale)];
8144 std::vector<std::string>& list1 = _petHalfLocaleName1[std::make_pair(entry, locale)];
8145
8146 if (list0.empty() || list1.empty())
8147 {
8148 return GeneratePetName(entry);
8149 }
8150
8151 return *(list0.begin() + urand(0, list0.size() - 1)) + *(list1.begin() + urand(0, list1.size() - 1));
8152}
HalfNameContainerLocale _petHalfLocaleName0
Definition ObjectMgr.h:1620
HalfNameContainerLocale _petHalfLocaleName1
Definition ObjectMgr.h:1621
std::string GeneratePetName(uint32 entry)
Definition ObjectMgr.cpp:8154

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

◆ GeneratePetNumber()

uint32 ObjectMgr::GeneratePetNumber ( )
8173{
8174 std::lock_guard<std::mutex> guard(_hiPetNumberMutex);
8175 return ++_hiPetNumber;
8176}
std::mutex _hiPetNumberMutex
Definition ObjectMgr.h:1511

References _hiPetNumber, and _hiPetNumberMutex.

◆ GetAccessRequirement()

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

References _accessRequirementStore.

◆ GetAcoreString() [1/2]

AcoreString const * ObjectMgr::GetAcoreString ( uint32  entry) const
inline
1369 {
1370 AcoreStringContainer::const_iterator itr = _acoreStringStore.find(entry);
1371 if (itr == _acoreStringStore.end())
1372 return nullptr;
1373
1374 return &itr->second;
1375 }
AcoreStringContainer _acoreStringStore
Definition ObjectMgr.h:1663

References _acoreStringStore.

Referenced by GetAcoreString(), and GetAcoreStringForDBCLocale().

◆ GetAcoreString() [2/2]

std::string ObjectMgr::GetAcoreString ( uint32  entry,
LocaleConstant  locale 
) const
9361{
9362 AcoreString const* as = GetAcoreString(entry);
9363 if (as && !as->Content.empty())
9364 {
9365 if (as->Content.size() > std::size_t(locale) && !as->Content[locale].empty())
9366 return as->Content[locale];
9367
9368 return as->Content[DEFAULT_LOCALE];
9369 }
9370
9371 std::string msg = Acore::StringFormat("No entry for acore_string ({}) in DB.", entry);
9372 LOG_ERROR("sql.sql", msg);
9373 return msg;
9374}
#define DEFAULT_LOCALE
Definition Common.h:131
AcoreString const * GetAcoreString(uint32 entry) const
Definition ObjectMgr.h:1368
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default AC string format function.
Definition StringFormat.h:44
Definition ObjectMgr.h:502
std::vector< std::string > Content
Definition ObjectMgr.h:503

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

◆ GetAcoreStringForDBCLocale()

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

References DBCLocaleIndex, and GetAcoreString().

◆ GetAllAreaTriggerScriptData()

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

References _areaTriggerScriptStore.

◆ GetAllCreatureData()

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

References _creatureDataStore.

◆ GetAllGOData()

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

References _gameObjectDataStore.

◆ GetAreaTrigger()

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

References _areaTriggerStore.

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

◆ GetAreaTriggerScriptId()

uint32 ObjectMgr::GetAreaTriggerScriptId ( uint32  trigger_id)
9454{
9455 AreaTriggerScriptContainer::const_iterator i = _areaTriggerScriptStore.find(trigger_id);
9456 if (i != _areaTriggerScriptStore.end())
9457 return i->second;
9458 return 0;
9459}

References _areaTriggerScriptStore.

◆ GetAreaTriggerTeleport()

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

References _areaTriggerTeleportStore.

◆ GetBaseReputationOf()

int32 ObjectMgr::GetBaseReputationOf ( FactionEntry const *  factionEntry,
uint8  race,
uint8  playerClass 
)
9468{
9469 if (!factionEntry)
9470 return 0;
9471
9472 uint32 raceMask = (1 << (race - 1));
9473 uint32 classMask = (1 << (playerClass - 1));
9474
9475 for (int i = 0; i < 4; i++)
9476 {
9477 if ((!factionEntry->BaseRepClassMask[i] ||
9478 factionEntry->BaseRepClassMask[i] & classMask) &&
9479 (!factionEntry->BaseRepRaceMask[i] ||
9480 factionEntry->BaseRepRaceMask[i] & raceMask))
9481 return factionEntry->BaseRepValue[i];
9482 }
9483
9484 return 0;
9485}

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

◆ GetBaseXP()

uint32 ObjectMgr::GetBaseXP ( uint8  level)
8083{
8084 return _baseXPTable[level] ? _baseXPTable[level] : 0;
8085}
BaseXPContainer _baseXPTable
Definition ObjectMgr.h:1611

References _baseXPTable.

◆ GetBreadcrumbsForQuest()

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

References _breadcrumbsForQuest.

◆ GetBroadcastText()

BroadcastText const * ObjectMgr::GetBroadcastText ( uint32  id) const
inline
1223 {
1224 BroadcastTextContainer::const_iterator itr = _broadcastTextStore.find(id);
1225 if (itr != _broadcastTextStore.end())
1226 return &itr->second;
1227 return nullptr;
1228 }
BroadcastTextContainer _broadcastTextStore
Definition ObjectMgr.h:1652

References _broadcastTextStore.

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

◆ GetCreatureAddon()

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

References _creatureAddonStore.

◆ GetCreatureBaseStats()

CreatureBaseStats const * ObjectMgr::GetCreatureBaseStats ( uint8  level,
uint8  unitClass 
)
10415{
10416 CreatureBaseStatsContainer::const_iterator it = _creatureBaseStatsStore.find(MAKE_PAIR16(level, unitClass));
10417
10418 if (it != _creatureBaseStatsStore.end())
10419 return &(it->second);
10420
10421 struct DefaultCreatureBaseStats : public CreatureBaseStats
10422 {
10423 DefaultCreatureBaseStats()
10424 {
10425 BaseArmor = 1;
10426 for (uint8 j = 0; j < MAX_EXPANSIONS; ++j)
10427 {
10428 BaseHealth[j] = 1;
10429 BaseDamage[j] = 0.0f;
10430 }
10431 BaseMana = 0;
10432 AttackPower = 0;
10433 RangedAttackPower = 0;
10434 Strength = 0;
10435 Agility = 0;
10436 Stamina = 0;
10437 Intellect = 0;
10438 Spirit = 0;
10439 }
10440 };
10441 static const DefaultCreatureBaseStats defStats;
10442 return &defStats;
10443}
uint16 MAKE_PAIR16(uint8 l, uint8 h)
Definition ObjectDefines.h:83
CreatureBaseStatsContainer _creatureBaseStatsStore
Definition ObjectMgr.h:1595

References _creatureBaseStatsStore, MAKE_PAIR16(), and MAX_EXPANSIONS.

Referenced by AddCreData().

◆ GetCreatureData()

CreatureData const * ObjectMgr::GetCreatureData ( ObjectGuid::LowType  spawnId) const
inline
1231 {
1232 CreatureDataContainer::const_iterator itr = _creatureDataStore.find(spawnId);
1233 if (itr == _creatureDataStore.end()) return nullptr;
1234 return &itr->second;
1235 }

References _creatureDataStore.

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

◆ GetCreatureLocale()

CreatureLocale const * ObjectMgr::GetCreatureLocale ( uint32  entry) const
inline
1272 {
1273 CreatureLocaleContainer::const_iterator itr = _creatureLocaleStore.find(entry);
1274 if (itr == _creatureLocaleStore.end()) return nullptr;
1275 return &itr->second;
1276 }
CreatureLocaleContainer _creatureLocaleStore
Definition ObjectMgr.h:1642

References _creatureLocaleStore.

◆ GetCreatureModelInfo()

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

References _creatureModelStore.

Referenced by GetCreatureModelRandomGender(), and LoadCreatureTemplateModels().

◆ GetCreatureModelRandomGender()

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

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

Referenced by GetTaxiMountDisplayId().

◆ GetCreatureMovementOverride()

CreatureMovementData const * ObjectMgr::GetCreatureMovementOverride ( ObjectGuid::LowType  spawnId) const
1440{
1442}
std::unordered_map< ObjectGuid::LowType, CreatureMovementData > _creatureMovementOverrides
Definition ObjectMgr.h:1636
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
1009 {
1010 return _creatureQuestInvolvedRelations.equal_range(creature_entry);
1011 }
QuestRelations _creatureQuestInvolvedRelations
Definition ObjectMgr.h:1559

References _creatureQuestInvolvedRelations.

◆ GetCreatureQuestInvolvedRelationMap()

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

References _creatureQuestInvolvedRelations.

◆ GetCreatureQuestItemList()

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

References _creatureQuestItemStore.

◆ GetCreatureQuestItemMap()

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

References _creatureQuestItemStore.

◆ GetCreatureQuestRelationBounds()

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

References _creatureQuestRelations.

◆ GetCreatureQuestRelationMap()

QuestRelations * ObjectMgr::GetCreatureQuestRelationMap ( )
inline
994 {
996 }

References _creatureQuestRelations.

◆ GetCreatureTemplate()

◆ GetCreatureTemplateAddon()

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

References _creatureTemplateAddonStore.

◆ GetCreatureTemplates()

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

References _creatureTemplateStore.

Referenced by LoadCreatureClassLevelStats(), and LoadNPCSpellClickSpells().

◆ GetDBCLocaleIndex()

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

References DBCLocaleIndex.

◆ GetDungeonEncounterList()

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

References _dungeonEncounterStore, and MAKE_PAIR32().

◆ GetEquipmentInfo()

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

References _equipmentInfoStore, and urand().

Referenced by LoadCreatureDataFromDB(), and LoadCreatures().

◆ GetFishingBaseSkillLevel()

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

References _fishingBaseForAreaStore.

◆ GetGameObjectAddon()

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

References _gameObjectAddonStore.

◆ GetGameObjectData()

GameObjectData const * ObjectMgr::GetGameObjectData ( ObjectGuid::LowType  spawnId) const
inline
1266 {
1267 GameObjectDataContainer::const_iterator itr = _gameObjectDataStore.find(spawnId);
1268 if (itr == _gameObjectDataStore.end()) return nullptr;
1269 return &itr->second;
1270 }

References _gameObjectDataStore.

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

◆ GetGameObjectLocale()

GameObjectLocale const * ObjectMgr::GetGameObjectLocale ( uint32  entry) const
inline
1278 {
1279 GameObjectLocaleContainer::const_iterator itr = _gameObjectLocaleStore.find(entry);
1280 if (itr == _gameObjectLocaleStore.end()) return nullptr;
1281 return &itr->second;
1282 }
GameObjectLocaleContainer _gameObjectLocaleStore
Definition ObjectMgr.h:1644

References _gameObjectLocaleStore.

◆ GetGameObjectQuestItemList()

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

References _gameObjectQuestItemStore.

◆ GetGameObjectQuestItemMap()

GameObjectQuestItemMap const * ObjectMgr::GetGameObjectQuestItemMap ( ) const
inline

◆ GetGameObjectSummonGroup()

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

References _goSummonDataStore.

◆ GetGameObjectTemplate()

GameObjectTemplate const * ObjectMgr::GetGameObjectTemplate ( uint32  entry)
10756{
10757 GameObjectTemplateContainer::const_iterator itr = _gameObjectTemplateStore.find(entry);
10758 if (itr != _gameObjectTemplateStore.end())
10759 return &(itr->second);
10760
10761 return nullptr;
10762}
GameObjectTemplateContainer _gameObjectTemplateStore
Definition ObjectMgr.h:1645

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
10771{
10772 auto itr = _gameObjectTemplateAddonStore.find(entry);
10773 if (itr != _gameObjectTemplateAddonStore.end())
10774 return &itr->second;
10775
10776 return nullptr;
10777}
GameObjectTemplateAddonContainer _gameObjectTemplateAddonStore
Definition ObjectMgr.h:1646

References _gameObjectTemplateAddonStore.

◆ GetGameObjectTemplates()

GameObjectTemplateContainer const * ObjectMgr::GetGameObjectTemplates ( ) const
inline

◆ GetGameTele() [1/2]

GameTele const * ObjectMgr::GetGameTele ( std::string_view  name,
bool  exactSearch = false 
) const
9573{
9574 // explicit name case
9575 std::wstring wname;
9576 if (!Utf8toWStr(name, wname))
9577 return nullptr;
9578
9579 // converting string that we try to find to lower case
9580 wstrToLower(wname);
9581
9582 // Alternative first GameTele what contains wnameLow as substring in case no GameTele location found
9583 const GameTele* alt = nullptr;
9584 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9585 {
9586 if (itr->second.wnameLow == wname)
9587 return &itr->second;
9588 else if (!exactSearch && !alt && itr->second.wnameLow.find(wname) != std::wstring::npos)
9589 alt = &itr->second;
9590 }
9591
9592 return alt;
9593}
Definition ObjectMgr.h:133

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

◆ GetGameTele() [2/2]

GameTele const * ObjectMgr::GetGameTele ( uint32  id) const
inline
1410 {
1411 GameTeleContainer::const_iterator itr = _gameTeleStore.find(id);
1412 if (itr == _gameTeleStore.end()) return nullptr;
1413 return &itr->second;
1414 }

References _gameTeleStore.

◆ GetGameTeleMap()

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

References _gameTeleStore.

◆ GetGenerator()

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

◆ GetGoBackTrigger()

AreaTriggerTeleport const * ObjectMgr::GetGoBackTrigger ( uint32  Map) const
7547{
7548 bool useParentDbValue = false;
7549 uint32 parentId = 0;
7550 MapEntry const* mapEntry = sMapStore.LookupEntry(Map);
7551 if (!mapEntry || mapEntry->entrance_map < 0)
7552 return nullptr;
7553
7554 if (mapEntry->IsDungeon())
7555 {
7556 InstanceTemplate const* iTemplate = sObjectMgr->GetInstanceTemplate(Map);
7557
7558 if (!iTemplate)
7559 return nullptr;
7560
7561 parentId = iTemplate->Parent;
7562 useParentDbValue = true;
7563 }
7564
7565 uint32 entrance_map = uint32(mapEntry->entrance_map);
7566 for (AreaTriggerTeleportContainer::const_iterator itr = _areaTriggerTeleportStore.begin(); itr != _areaTriggerTeleportStore.end(); ++itr)
7567 if ((!useParentDbValue && itr->second.target_mapId == entrance_map) || (useParentDbValue && itr->second.target_mapId == parentId))
7568 {
7569 AreaTrigger const* atEntry = GetAreaTrigger(itr->first);
7570 if (atEntry && atEntry->map == Map)
7571 return &itr->second;
7572 }
7573 return nullptr;
7574}
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
AreaTrigger const * GetAreaTrigger(uint32 trigger) const
Definition ObjectMgr.h:863
Definition ObjectMgr.h:421
uint32 map
Definition ObjectMgr.h:423
Definition Map.h:121
uint32 Parent
Definition Map.h:122
Definition DBCStructure.h:1325
int32 entrance_map
Definition DBCStructure.h:1340
bool IsDungeon() const
Definition DBCStructure.h:1351

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

◆ GetGOQuestInvolvedRelationBounds()

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

References _goQuestInvolvedRelations.

◆ GetGOQuestInvolvedRelationMap()

QuestRelations * ObjectMgr::GetGOQuestInvolvedRelationMap ( )
inline
979 {
981 }

References _goQuestInvolvedRelations.

◆ GetGOQuestRelationBounds()

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

References _goQuestRelations.

◆ GetGOQuestRelationMap()

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

References _goQuestRelations.

◆ GetGossipMenuItemsLocale()

GossipMenuItemsLocale const * ObjectMgr::GetGossipMenuItemsLocale ( uint32  entry) const
inline
1308 {
1309 GossipMenuItemsLocaleContainer::const_iterator itr = _gossipMenuItemsLocaleStore.find(entry);
1310 if (itr == _gossipMenuItemsLocaleStore.end()) return nullptr;
1311 return &itr->second;
1312 }
GossipMenuItemsLocaleContainer _gossipMenuItemsLocaleStore
Definition ObjectMgr.h:1664

References _gossipMenuItemsLocaleStore.

◆ GetGossipMenuItemsMapBounds()

GossipMenuItemsMapBounds ObjectMgr::GetGossipMenuItemsMapBounds ( uint32  uiMenuId) const
inline
1456 {
1457 return _gossipMenuItemsStore.equal_range(uiMenuId);
1458 }
GossipMenuItemsContainer _gossipMenuItemsStore
Definition ObjectMgr.h:1551

References _gossipMenuItemsStore.

◆ GetGossipMenuItemsMapBoundsNonConst()

GossipMenuItemsMapBoundsNonConst ObjectMgr::GetGossipMenuItemsMapBoundsNonConst ( uint32  uiMenuId)
inline
1460 {
1461 return _gossipMenuItemsStore.equal_range(uiMenuId);
1462 }

References _gossipMenuItemsStore.

◆ GetGossipMenusMapBounds()

GossipMenusMapBounds ObjectMgr::GetGossipMenusMapBounds ( uint32  uiMenuId) const
inline
1446 {
1447 return _gossipMenusStore.equal_range(uiMenuId);
1448 }
GossipMenusContainer _gossipMenusStore
Definition ObjectMgr.h:1550

References _gossipMenusStore.

◆ GetGossipMenusMapBoundsNonConst()

GossipMenusMapBoundsNonConst ObjectMgr::GetGossipMenusMapBoundsNonConst ( uint32  uiMenuId)
inline
1451 {
1452 return _gossipMenusStore.equal_range(uiMenuId);
1453 }

References _gossipMenusStore.

◆ GetGossipText()

GossipText const * ObjectMgr::GetGossipText ( uint32  Text_ID) const
6594{
6595 GossipTextContainer::const_iterator itr = _gossipTextStore.find(Text_ID);
6596 if (itr != _gossipTextStore.end())
6597 return &itr->second;
6598 return nullptr;
6599}
GossipTextContainer _gossipTextStore
Definition ObjectMgr.h:1538

References _gossipTextStore.

Referenced by LoadGossipMenu().

◆ GetGridObjectGuids()

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

References _emptyCellObjectGuids, _mapObjectGuidsStore, and MAKE_PAIR32().

◆ GetGuidSequenceGenerator()

template<HighGuid high>
ObjectGuidGeneratorBase & ObjectMgr::GetGuidSequenceGenerator ( )
inlineprivate
1519 {
1520 auto itr = _guidGenerators.find(high);
1521 if (itr == _guidGenerators.end())
1522 itr = _guidGenerators.insert(std::make_pair(high, std::unique_ptr<ObjectGuidGenerator<high>>(new ObjectGuidGenerator<high>()))).first;
1523
1524 return *itr->second;
1525 }
Definition ObjectGuid.h:297
std::map< HighGuid, std::unique_ptr< ObjectGuidGeneratorBase > > _guidGenerators
Definition ObjectMgr.h:1527

References _guidGenerators.

◆ GetInstanceTemplate()

InstanceTemplate const * ObjectMgr::GetInstanceTemplate ( uint32  mapId)
6500{
6501 InstanceTemplateContainer::const_iterator itr = _instanceTemplateStore.find(uint16(mapID));
6502 if (itr != _instanceTemplateStore.end())
6503 return &(itr->second);
6504
6505 return nullptr;
6506}
InstanceTemplateContainer _instanceTemplateStore
Definition ObjectMgr.h:1584

References _instanceTemplateStore.

◆ GetItemLocale()

ItemLocale const * ObjectMgr::GetItemLocale ( uint32  entry) const
inline
1284 {
1285 ItemLocaleContainer::const_iterator itr = _itemLocaleStore.find(entry);
1286 if (itr == _itemLocaleStore.end()) return nullptr;
1287 return &itr->second;
1288 }
ItemLocaleContainer _itemLocaleStore
Definition ObjectMgr.h:1655

References _itemLocaleStore.

◆ GetItemSetNameEntry()

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

References _itemSetNameStore.

◆ GetItemSetNameLocale()

ItemSetNameLocale const * ObjectMgr::GetItemSetNameLocale ( uint32  entry) const
inline
1290 {
1291 ItemSetNameLocaleContainer::const_iterator itr = _itemSetNameLocaleStore.find(entry);
1292 if (itr == _itemSetNameLocaleStore.end())return nullptr;
1293 return &itr->second;
1294 }
ItemSetNameLocaleContainer _itemSetNameLocaleStore
Definition ObjectMgr.h:1656

References _itemSetNameLocaleStore.

◆ GetItemTemplate()

ItemTemplate const * ObjectMgr::GetItemTemplate ( uint32  entry)
3839{
3840 return entry < _itemTemplateStoreFast.size() ? _itemTemplateStoreFast[entry] : nullptr;
3841}
std::vector< ItemTemplate * > _itemTemplateStoreFast
Definition ObjectMgr.h:1654

References _itemTemplateStoreFast.

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

◆ GetItemTemplateStore()

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

References _itemTemplateStore.

◆ GetItemTemplateStoreFast()

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

References _itemTemplateStoreFast.

◆ GetLinkedRespawnGuid()

ObjectGuid ObjectMgr::GetLinkedRespawnGuid ( ObjectGuid  guid) const
inline
1257 {
1258 LinkedRespawnContainer::const_iterator itr = _linkedRespawnStore.find(guid);
1259 if (itr == _linkedRespawnStore.end())
1260 return ObjectGuid::Empty;
1261 return itr->second;
1262 }
static ObjectGuid const Empty
Definition ObjectGuid.h:120
LinkedRespawnContainer _linkedRespawnStore
Definition ObjectMgr.h:1641

References _linkedRespawnStore, and ObjectGuid::Empty.

◆ GetLocaleString() [1/2]

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

◆ GetLocaleString() [2/2]

◆ GetMailLevelReward()

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

References _mailLevelRewardStore.

◆ GetMapEntranceTrigger()

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

Searches for the areatrigger which teleports players to the given map

7580{
7581 for (AreaTriggerTeleportContainer::const_iterator itr = _areaTriggerTeleportStore.begin(); itr != _areaTriggerTeleportStore.end(); ++itr)
7582 {
7583 if (itr->second.target_mapId == Map) // Id is used to determine correct Scarlet Monastery instance
7584 {
7585 // xinef: no need to check, already done at loading
7586 //AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(itr->first);
7587 //if (atEntry)
7588 return &itr->second;
7589 }
7590 }
7591 return nullptr;
7592}

References _areaTriggerTeleportStore.

◆ GetMapObjectGuids()

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

References _emptyCellObjectGuidsMap, _mapObjectGuidsStore, and MAKE_PAIR32().

◆ GetModelForShapeshift()

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

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

◆ GetModelForTotem()

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

References _playerTotemModel, and LOG_ERROR.

◆ GetModuleString() [1/2]

ModuleString const * ObjectMgr::GetModuleString ( std::string  module,
uint32  id 
) const
inline
1358 {
1359 std::pair<std::string, uint32> pairKey = std::make_pair(module, id);
1360 ModuleStringContainer::const_iterator itr = _moduleStringStore.find(pairKey);
1361 if (itr == _moduleStringStore.end())
1362 return nullptr;
1363
1364 return &itr->second;
1365 }
ModuleStringContainer _moduleStringStore
Definition ObjectMgr.h:1662

References _moduleStringStore.

Referenced by GetModuleString().

◆ GetModuleString() [2/2]

std::string const * ObjectMgr::GetModuleString ( std::string  module,
uint32  id,
LocaleConstant  locale 
) const
9312{
9313 ModuleString const* ms = GetModuleString(module, id);
9314 if (ms && !ms->Content.empty())
9315 {
9316 if (ms->Content.size() > size_t(locale) && !ms->Content[locale].empty())
9317 return &ms->Content[locale];
9318
9319 return &ms->Content[DEFAULT_LOCALE];
9320 }
9321
9322 LOG_ERROR("sql.sql", "Module string module {} id {} not found in DB.", module, id);
9323
9324 return (std::string*)"error";
9325}
ModuleString const * GetModuleString(std::string module, uint32 id) const
Definition ObjectMgr.h:1357
Definition ObjectMgr.h:497
std::vector< std::string > Content
Definition ObjectMgr.h:498

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

◆ GetNearestTaxiNode()

uint32 ObjectMgr::GetNearestTaxiNode ( float  x,
float  y,
float  z,
uint32  mapid,
uint32  teamId 
)
7164{
7165 bool found = false;
7166 float dist = 10000;
7167 uint32 id = 0;
7168
7169 for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
7170 {
7171 TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i);
7172
7173 if (!node || node->map_id != mapid || (!node->MountCreatureID[teamId == TEAM_ALLIANCE ? 1 : 0] && node->MountCreatureID[0] != 32981)) // dk flight
7174 continue;
7175
7176 uint8 field = (uint8)((i - 1) / 32);
7177 uint32 submask = 1 << ((i - 1) % 32);
7178
7179 // skip not taxi network nodes
7180 if (field >= TaxiMaskSize || (sTaxiNodesMask[field] & submask) == 0)
7181 {
7182 continue;
7183 }
7184
7185 float dist2 = (node->x - x) * (node->x - x) + (node->y - y) * (node->y - y) + (node->z - z) * (node->z - z);
7186 if (found)
7187 {
7188 if (dist2 < dist)
7189 {
7190 dist = dist2;
7191 id = i;
7192 }
7193 }
7194 else
7195 {
7196 found = true;
7197 dist = dist2;
7198 id = i;
7199 }
7200 }
7201
7202 return id;
7203}
TaxiMask sTaxiNodesMask
Definition DBCStores.cpp:176
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
static constexpr std::size_t TaxiMaskSize
Definition DBCStructure.h:2248
Definition DBCStructure.h:1953
float z
Definition DBCStructure.h:1958
uint32 map_id
Definition DBCStructure.h:1955
float x
Definition DBCStructure.h:1956
float y
Definition DBCStructure.h:1957
uint32 MountCreatureID[2]
Definition DBCStructure.h:1961

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

◆ GetNpcTextLocale()

NpcTextLocale const * ObjectMgr::GetNpcTextLocale ( uint32  entry) const
inline
1332 {
1333 NpcTextLocaleContainer::const_iterator itr = _npcTextLocaleStore.find(entry);
1334 if (itr == _npcTextLocaleStore.end()) return nullptr;
1335 return &itr->second;
1336 }
NpcTextLocaleContainer _npcTextLocaleStore
Definition ObjectMgr.h:1660

References _npcTextLocaleStore.

◆ GetNpcVendorItemList()

VendorItemData const * ObjectMgr::GetNpcVendorItemList ( uint32  entry) const
inline
1423 {
1424 CacheVendorItemContainer::const_iterator iter = _cacheVendorItemStore.find(entry);
1425 if (iter == _cacheVendorItemStore.end())
1426 return nullptr;
1427
1428 return &iter->second;
1429 }

References _cacheVendorItemStore.

Referenced by IsVendorItemValid().

◆ GetPageText()

PageText const * ObjectMgr::GetPageText ( uint32  pageEntry)
6416{
6417 PageTextContainer::const_iterator itr = _pageTextStore.find(pageEntry);
6418 if (itr != _pageTextStore.end())
6419 return &(itr->second);
6420
6421 return nullptr;
6422}
PageTextContainer _pageTextStore
Definition ObjectMgr.h:1583

References _pageTextStore.

Referenced by LoadGameObjectTemplate(), and LoadItemTemplates().

◆ GetPageTextLocale()

PageTextLocale const * ObjectMgr::GetPageTextLocale ( uint32  entry) const
inline
1296 {
1297 PageTextLocaleContainer::const_iterator itr = _pageTextLocaleStore.find(entry);
1298 if (itr == _pageTextLocaleStore.end()) return nullptr;
1299 return &itr->second;
1300 }
PageTextLocaleContainer _pageTextLocaleStore
Definition ObjectMgr.h:1661

References _pageTextLocaleStore.

◆ GetPetLevelInfo()

PetLevelInfo const * ObjectMgr::GetPetLevelInfo ( uint32  creature_id,
uint8  level 
) const
4205{
4206 if (level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4207 level = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
4208
4209 PetLevelInfoContainer::const_iterator itr = _petInfoStore.find(creature_id);
4210 if (itr == _petInfoStore.end())
4211 return nullptr;
4212
4213 return &itr->second[level - 1]; // data for level 1 stored in [0] array element, ...
4214}

References _petInfoStore, CONFIG_MAX_PLAYER_LEVEL, and sWorld.

◆ GetPlayerClassInfo()

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

References _playerClassInfo, and MAX_CLASSES.

◆ GetPlayerClassLevelInfo()

void ObjectMgr::GetPlayerClassLevelInfo ( uint32  class_,
uint8  level,
PlayerClassLevelInfo info 
) const
4882{
4883 if (level < 1 || class_ >= MAX_CLASSES)
4884 return;
4885
4886 PlayerClassInfo const* pInfo = _playerClassInfo[class_];
4887
4888 if (level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4889 level = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
4890
4891 *info = pInfo->levelInfo[level - 1];
4892}
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
10802{
10803 if (race >= sRaceMgr->GetMaxRaces())
10804 return nullptr;
10805 if (class_ >= MAX_CLASSES)
10806 return nullptr;
10807 PlayerInfo const* info = _playerInfo[race][class_];
10808 if (!info)
10809 return nullptr;
10810 return info;
10811}
Definition Player.h:322

References _playerInfo, MAX_CLASSES, and sRaceMgr.

◆ GetPlayerLevelInfo()

void ObjectMgr::GetPlayerLevelInfo ( uint32  race,
uint32  class_,
uint8  level,
PlayerLevelInfo info 
) const
4895{
4896 if (level < 1 || race >= sRaceMgr->GetMaxRaces() || class_ >= MAX_CLASSES)
4897 return;
4898
4899 PlayerInfo const* pInfo = _playerInfo[race][class_];
4900 if (!pInfo)
4901 return;
4902
4903 if (level <= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4904 *info = pInfo->levelInfo[level - 1];
4905 else
4906 BuildPlayerLevelInfo(race, class_, level, info);
4907}
void BuildPlayerLevelInfo(uint8 race, uint8 class_, uint8 level, PlayerLevelInfo *plinfo) const
Definition ObjectMgr.cpp:4909
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
930 {
931 PointOfInterestContainer::const_iterator itr = _pointsOfInterestStore.find(id);
932 if (itr != _pointsOfInterestStore.end())
933 return &itr->second;
934 return nullptr;
935 }
PointOfInterestContainer _pointsOfInterestStore
Definition ObjectMgr.h:1552

References _pointsOfInterestStore.

Referenced by LoadGossipMenuItems().

◆ GetPointOfInterestLocale()

PointOfInterestLocale const * ObjectMgr::GetPointOfInterestLocale ( uint32  poi_id) const
inline
1314 {
1315 PointOfInterestLocaleContainer::const_iterator itr = _pointOfInterestLocaleStore.find(poi_id);
1316 if (itr == _pointOfInterestLocaleStore.end()) return nullptr;
1317 return &itr->second;
1318 }
PointOfInterestLocaleContainer _pointOfInterestLocaleStore
Definition ObjectMgr.h:1665

References _pointOfInterestLocaleStore.

◆ GetQuestForAreaTrigger()

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

References _questAreaTriggerStore.

◆ GetQuestGreeting()

QuestGreeting const * ObjectMgr::GetQuestGreeting ( TypeID  type,
uint32  id 
) const
6894{
6895 uint8 typeIndex;
6896 if (type == TYPEID_UNIT)
6897 typeIndex = 0;
6898 else if (type == TYPEID_GAMEOBJECT)
6899 typeIndex = 1;
6900 else
6901 return nullptr;
6902
6903 std::pair<uint32, uint8> pairKey = std::make_pair(id, typeIndex);
6904 QuestGreetingContainer::const_iterator itr = _questGreetingStore.find(pairKey);
6905 if (itr == _questGreetingStore.end())
6906 return nullptr;
6907
6908 return &itr->second;
6909}
@ TYPEID_GAMEOBJECT
Definition ObjectGuid.h:37
@ TYPEID_UNIT
Definition ObjectGuid.h:35
QuestGreetingContainer _questGreetingStore
Definition ObjectMgr.h:1539

References _questGreetingStore, TYPEID_GAMEOBJECT, and TYPEID_UNIT.

◆ GetQuestLocale()

QuestLocale const * ObjectMgr::GetQuestLocale ( uint32  entry) const
inline
1302 {
1303 QuestLocaleContainer::const_iterator itr = _questLocaleStore.find(entry);
1304 if (itr == _questLocaleStore.end()) return nullptr;
1305 return &itr->second;
1306 }
QuestLocaleContainer _questLocaleStore
Definition ObjectMgr.h:1657

References _questLocaleStore.

◆ GetQuestMoneyReward()

uint32 ObjectMgr::GetQuestMoneyReward ( uint8  level,
uint32  questMoneyDifficulty 
) const
10938{
10939 if (questMoneyDifficulty < MAX_QUEST_MONEY_REWARDS)
10940 {
10941 auto const& itr = _questMoneyRewards.find(level);
10942 if (itr != _questMoneyRewards.end())
10943 {
10944 return itr->second.at(questMoneyDifficulty);
10945 }
10946 }
10947
10948 return 0;
10949}
static constexpr uint32 MAX_QUEST_MONEY_REWARDS
Definition ObjectMgr.h:719
QuestMoneyRewardStore _questMoneyRewards
Definition ObjectMgr.h:1688

References _questMoneyRewards, and MAX_QUEST_MONEY_REWARDS.

◆ GetQuestOfferRewardLocale()

QuestOfferRewardLocale const * ObjectMgr::GetQuestOfferRewardLocale ( uint32  entry) const
inline
1320 {
1321 auto itr = _questOfferRewardLocaleStore.find(entry);
1322 if (itr == _questOfferRewardLocaleStore.end()) return nullptr;
1323 return &itr->second;
1324 }
QuestOfferRewardLocaleContainer _questOfferRewardLocaleStore
Definition ObjectMgr.h:1658

References _questOfferRewardLocaleStore.

◆ GetQuestPOIVector()

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

References _questPOIStore.

◆ GetQuestRequestItemsLocale()

QuestRequestItemsLocale const * ObjectMgr::GetQuestRequestItemsLocale ( uint32  entry) const
inline
1326 {
1327 auto itr = _questRequestItemsLocaleStore.find(entry);
1328 if (itr == _questRequestItemsLocaleStore.end()) return nullptr;
1329 return &itr->second;
1330 }
QuestRequestItemsLocaleContainer _questRequestItemsLocaleStore
Definition ObjectMgr.h:1659

References _questRequestItemsLocaleStore.

◆ GetQuestTemplate()

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

References _questTemplatesFast.

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

◆ GetQuestTemplates()

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

References _questTemplates.

◆ GetRepRewardRate()

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

References _repRewardRateStore.

◆ GetRepSpilloverTemplate()

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

References _repSpilloverTemplateStore.

◆ GetReputationOnKilEntry()

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

References _repOnKillStore.

◆ GetScriptId()

uint32 ObjectMgr::GetScriptId ( std::string const &  name)
10275{
10276 // use binary search to find the script name in the sorted vector
10277 // assume "" is the first element
10278 if (name.empty())
10279 return 0;
10280
10281 ScriptNameContainer::const_iterator itr = std::lower_bound(_scriptNamesStore.begin(), _scriptNamesStore.end(), name);
10282 if (itr == _scriptNamesStore.end() || (*itr != name))
10283 return 0;
10284
10285 return uint32(itr - _scriptNamesStore.begin());
10286}
ScriptNameContainer _scriptNamesStore
Definition ObjectMgr.h:1571

References _scriptNamesStore.

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

◆ GetScriptName()

std::string const & ObjectMgr::GetScriptName ( uint32  id) const
10269{
10270 static std::string const empty = "";
10271 return (id < _scriptNamesStore.size()) ? _scriptNamesStore[id] : empty;
10272}

References _scriptNamesStore.

Referenced by ValidateSpellScripts().

◆ GetScriptNames()

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

References _scriptNamesStore.

◆ GetSparringData()

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

References _creatureSparringStore.

◆ GetSpellClickInfoMapBounds()

SpellClickInfoMapBounds ObjectMgr::GetSpellClickInfoMapBounds ( uint32  creature_id) const
inline
1441 {
1442 return _spellClickInfoStore.equal_range(creature_id);
1443 }
SpellClickInfoContainer _spellClickInfoStore
Definition ObjectMgr.h:1573

References _spellClickInfoStore.

◆ GetSpellScriptsBounds()

SpellScriptsBounds ObjectMgr::GetSpellScriptsBounds ( uint32  spell_id)
9462{
9463 return SpellScriptsBounds(_spellScriptsStore.lower_bound(spell_id), _spellScriptsStore.upper_bound(spell_id));
9464}
std::pair< SpellScriptsContainer::iterator, SpellScriptsContainer::iterator > SpellScriptsBounds
Definition ObjectMgr.h:389
SpellScriptsContainer _spellScriptsStore
Definition ObjectMgr.h:1575

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

References _tempSummonDataStore.

◆ GetTaxiMountDisplayId()

uint32 ObjectMgr::GetTaxiMountDisplayId ( uint32  id,
TeamId  teamId,
bool  allowed_alt_team = false 
)
7230{
7231 CreatureModel mountModel;
7232 CreatureTemplate const* mount_info = nullptr;
7233
7234 // select mount creature id
7235 TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id);
7236 if (node)
7237 {
7238 uint32 mount_entry = node->MountCreatureID[teamId == TEAM_ALLIANCE ? 1 : 0];
7239
7240 // Fix for Alliance not being able to use Acherus taxi
7241 // only one mount type for both sides
7242 if (mount_entry == 0 && allowed_alt_team)
7243 {
7244 // Simply reverse the selection. At least one team in theory should have a valid mount ID to choose.
7245 mount_entry = node->MountCreatureID[teamId];
7246 }
7247
7248 mount_info = GetCreatureTemplate(mount_entry);
7249 if (mount_info)
7250 {
7251 CreatureModel const* model = mount_info->GetRandomValidModel();
7252 if (!model)
7253 {
7254 LOG_ERROR("sql.sql", "No displayid found for the taxi mount with the entry {}! Can't load it!", mount_entry);
7255 return 0;
7256 }
7257 mountModel = *model;
7258 }
7259 }
7260
7261 // minfo is not actually used but the mount_id was updated
7262 GetCreatureModelRandomGender(&mountModel, mount_info);
7263
7264 return mountModel.CreatureDisplayID;
7265}
CreatureModelInfo const * GetCreatureModelRandomGender(CreatureModel *model, CreatureTemplate const *creatureTemplate) const
Definition ObjectMgr.cpp:1668
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 
)
7206{
7207 TaxiPathSetBySource::iterator src_i = sTaxiPathSetBySource.find(source);
7208 if (src_i == sTaxiPathSetBySource.end())
7209 {
7210 path = 0;
7211 cost = 0;
7212 return;
7213 }
7214
7215 TaxiPathSetForSource& pathSet = src_i->second;
7216
7217 TaxiPathSetForSource::iterator dest_i = pathSet.find(destination);
7218 if (dest_i == pathSet.end())
7219 {
7220 path = 0;
7221 cost = 0;
7222 return;
7223 }
7224
7225 cost = dest_i->second->price;
7226 path = dest_i->second->ID;
7227}
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)
9862{
9863 auto itr = _creatureDefaultTrainers.find(creatureId);
9864 if (itr != _creatureDefaultTrainers.end())
9865 return Acore::Containers::MapGetValuePtr(_trainers, itr->second);
9866
9867 return nullptr;
9868}
std::unordered_map< uint32, uint32 > _creatureDefaultTrainers
Definition ObjectMgr.h:1669
std::unordered_map< uint32, Trainer::Trainer > _trainers
Definition ObjectMgr.h:1668

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

◆ GetVehicleAccessoryList()

VehicleAccessoryList const * ObjectMgr::GetVehicleAccessoryList ( Vehicle veh) const
10785{
10786 if (Creature* cre = veh->GetBase()->ToCreature())
10787 {
10788 // Give preference to GUID-based accessories
10789 VehicleAccessoryContainer::const_iterator itr = _vehicleAccessoryStore.find(cre->GetSpawnId());
10790 if (itr != _vehicleAccessoryStore.end())
10791 return &itr->second;
10792 }
10793
10794 // Otherwise return entry-based
10795 VehicleAccessoryContainer::const_iterator itr = _vehicleTemplateAccessoryStore.find(veh->GetCreatureEntry());
10796 if (itr != _vehicleTemplateAccessoryStore.end())
10797 return &itr->second;
10798 return nullptr;
10799}
VehicleAccessoryContainer _vehicleAccessoryStore
Definition ObjectMgr.h:1578
VehicleAccessoryContainer _vehicleTemplateAccessoryStore
Definition ObjectMgr.h:1577
Creature * ToCreature()
Definition Object.h:205
Unit * GetBase() const
May be called from scripts.
Definition Vehicle.h:37
uint32 GetCreatureEntry() const
Definition Vehicle.h:39

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

◆ GetVehicleSeatAddon()

VehicleSeatAddon const * ObjectMgr::GetVehicleSeatAddon ( uint32  seatId) const
inline
1495 {
1496 VehicleSeatAddonContainer::const_iterator itr = _vehicleSeatAddonStore.find(seatId);
1497 if (itr == _vehicleSeatAddonStore.end())
1498 return nullptr;
1499
1500 return &itr->second;
1501 }
VehicleSeatAddonContainer _vehicleSeatAddonStore
Definition ObjectMgr.h:1579

References _vehicleSeatAddonStore.

◆ GetXPForLevel()

uint32 ObjectMgr::GetXPForLevel ( uint8  level) const
8088{
8089 if (level < _playerXPperLevel.size())
8090 return _playerXPperLevel[level];
8091 return 0;
8092}
PlayerXPperLevel _playerXPperLevel
Definition ObjectMgr.h:1608

References _playerXPperLevel.

◆ InitializeSpellInfoPrecomputedData()

void ObjectMgr::InitializeSpellInfoPrecomputedData ( )
6363{
6364 uint32 limit = sSpellStore.GetNumRows();
6365 for(uint32 i = 0; i <= limit; ++i)
6366 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(i))
6367 {
6368 const_cast<SpellInfo*>(spellInfo)->SetStackableWithRanks(spellInfo->ComputeIsStackableWithRanks());
6369 const_cast<SpellInfo*>(spellInfo)->SetCritCapable(spellInfo->ComputeIsCritCapable());
6370 const_cast<SpellInfo*>(spellInfo)->SetSpellValid(SpellMgr::ComputeIsSpellValid(spellInfo, false));
6371 }
6372}
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
Definition SpellInfo.h:316
static bool ComputeIsSpellValid(SpellInfo const *spellInfo, bool msg=true)
Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book,...
Definition SpellMgr.cpp:368

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

◆ instance()

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

References instance().

Referenced by instance().

◆ IsGameObjectStaticTransport()

bool ObjectMgr::IsGameObjectStaticTransport ( uint32  entry)
10765{
10766 GameObjectTemplate const* goinfo = GetGameObjectTemplate(entry);
10767 return goinfo && goinfo->type == GAMEOBJECT_TYPE_TRANSPORT;
10768}
@ GAMEOBJECT_TYPE_TRANSPORT
Definition SharedDefines.h:1559

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

Referenced by AddGOData().

◆ IsProfanityName()

bool ObjectMgr::IsProfanityName ( std::string_view  name) const
8948{
8949 // pussywizard
8950 if (name.size() >= 2 && (name[name.size() - 2] == 'G' || name[name.size() - 2] == 'g') && (name[name.size() - 1] == 'M' || name[name.size() - 1] == 'm'))
8951 return true;
8952
8953 std::wstring wstr;
8954 if (!Utf8toWStr (name, wstr))
8955 return false;
8956
8957 wstrToLower(wstr);
8958
8959 return _profanityNamesStore.find(wstr) != _profanityNamesStore.end();
8960}

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

Referenced by AddProfanityPlayerName().

◆ IsReservedName()

bool ObjectMgr::IsReservedName ( std::string_view  name) const
8845{
8846 // pussywizard
8847 if (name.size() >= 2 && (name[name.size() - 2] == 'G' || name[name.size() - 2] == 'g') && (name[name.size() - 1] == 'M' || name[name.size() - 1] == 'm'))
8848 return true;
8849
8850 std::wstring wstr;
8851 if (!Utf8toWStr (name, wstr))
8852 return false;
8853
8854 wstrToLower(wstr);
8855
8856 return _reservedNamesStore.find(wstr) != _reservedNamesStore.end();
8857}

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

Referenced by AddReservedPlayerName().

◆ IsTavernAreaTrigger()

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

References _tavernAreaTriggerStore.

◆ IsTransportMap()

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

References _transportMaps.

◆ IsValidChannelName()

bool ObjectMgr::IsValidChannelName ( std::string const &  name)
static
9121{
9122 std::wstring wname;
9123 if (!Utf8toWStr(name, wname))
9124 return false;
9125
9126 if (wname.size() > MAX_CHANNEL_NAME)
9127 return false;
9128
9129 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_CHANNEL_NAMES);
9130
9131 return isValidString(wname, strictMask, true);
9132}
#define MAX_CHANNEL_NAME
Definition ObjectMgr.h:687
@ CONFIG_STRICT_CHANNEL_NAMES
Definition WorldConfig.h:177

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

◆ IsValidCharterName()

bool ObjectMgr::IsValidCharterName ( std::string_view  name)
static
9095{
9096 std::wstring wname;
9097 if (!Utf8toWStr(name, wname))
9098 return false;
9099
9100 if (wname.size() > MAX_CHARTER_NAME)
9101 return false;
9102
9103 uint32 minName = sWorld->getIntConfig(CONFIG_MIN_CHARTER_NAME);
9104 if (wname.size() < minName)
9105 return false;
9106
9107 // Check Reserved Name
9108 if (sObjectMgr->IsReservedName(name))
9109 return false;
9110
9111 // Check Profanity Name
9112 if (sObjectMgr->IsProfanityName(name))
9113 return false;
9114
9115 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_CHARTER_NAMES);
9116
9117 return isValidString(wname, strictMask, true);
9118}
#define MAX_CHARTER_NAME
Definition ObjectMgr.h:686
@ CONFIG_MIN_CHARTER_NAME
Definition WorldConfig.h:180
@ CONFIG_STRICT_CHARTER_NAMES
Definition WorldConfig.h:176

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
10133{
10134 /*
10135 CreatureTemplate const* cInfo = GetCreatureTemplate(vendor_entry);
10136 if (!cInfo)
10137 {
10138 if (player)
10139 ChatHandler(player->GetSession()).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
10140 else
10141 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have data for not existed creature template (Entry: {}), ignore", vendor_entry);
10142 return false;
10143 }
10144
10145 if (!((cInfo->npcflag | ORnpcflag) & UNIT_NPC_FLAG_VENDOR))
10146 {
10147 if (!skip_vendors || skip_vendors->count(vendor_entry) == 0)
10148 {
10149 if (player)
10150 ChatHandler(player->GetSession()).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
10151 else
10152 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have data for not creature template (Entry: {}) without vendor flag, ignore", vendor_entry);
10153
10154 if (skip_vendors)
10155 skip_vendors->insert(vendor_entry);
10156 }
10157 return false;
10158 }
10159 */
10160
10161 if (!sObjectMgr->GetItemTemplate(item_id))
10162 {
10163 if (player)
10165 else
10166 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` for Vendor (Entry: {}) have in item list non-existed item ({}), ignore", vendor_entry, item_id);
10167 return false;
10168 }
10169
10170 if (ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost))
10171 {
10172 if (player)
10174 else
10175 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have Item (Entry: {}) with wrong ExtendedCost ({}) for vendor ({}), ignore", item_id, ExtendedCost, vendor_entry);
10176 return false;
10177 }
10178
10179 if (maxcount > 0 && incrtime == 0)
10180 {
10181 if (player)
10182 ChatHandler(player->GetSession()).PSendSysMessage("MaxCount != 0 ({}) but IncrTime == 0", maxcount);
10183 else
10184 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);
10185 return false;
10186 }
10187 else if (maxcount == 0 && incrtime > 0)
10188 {
10189 if (player)
10190 ChatHandler(player->GetSession()).PSendSysMessage("MaxCount == 0 but IncrTime<>= 0");
10191 else
10192 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);
10193 return false;
10194 }
10195
10196 VendorItemData const* vItems = GetNpcVendorItemList(vendor_entry);
10197 if (!vItems)
10198 return true; // later checks for non-empty lists
10199
10200 if (vItems->FindItemCostPair(item_id, ExtendedCost))
10201 {
10202 if (player)
10203 ChatHandler(player->GetSession()).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, item_id, ExtendedCost);
10204 else
10205 LOG_ERROR("sql.sql", "Table `npc_vendor` has duplicate items {} (with extended cost {}) for vendor (Entry: {}), ignoring", item_id, ExtendedCost, vendor_entry);
10206 return false;
10207 }
10208
10209 return true;
10210}
DBCStorage< ItemExtendedCostEntry > sItemExtendedCostStore(ItemExtendedCostEntryfmt)
@ LANG_ITEM_ALREADY_IN_LIST
Definition Language.h:253
@ LANG_ITEM_NOT_FOUND
Definition Language.h:250
@ LANG_EXTENDED_COST_NOT_EXIST
Definition Language.h:378
Definition Chat.h:37
void PSendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:211
VendorItemData const * GetNpcVendorItemList(uint32 entry) const
Definition ObjectMgr.h:1422
WorldSession * GetSession() const
Definition Player.h:2017
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 ( )
7379{
7380 uint32 oldMSTime = getMSTime();
7381
7382 if (!_accessRequirementStore.empty())
7383 {
7384 for (DungeonProgressionRequirementsContainer::iterator itr = _accessRequirementStore.begin(); itr != _accessRequirementStore.end(); ++itr)
7385 {
7386 std::unordered_map<uint8, DungeonProgressionRequirements*> difficulties = itr->second;
7387 for (auto difficultiesItr = difficulties.begin(); difficultiesItr != difficulties.end(); ++difficultiesItr)
7388 {
7389 for (auto questItr = difficultiesItr->second->quests.begin(); questItr != difficultiesItr->second->quests.end(); ++questItr)
7390 {
7391 delete* questItr;
7392 }
7393
7394 for (auto achievementItr = difficultiesItr->second->achievements.begin(); achievementItr != difficultiesItr->second->achievements.end(); ++achievementItr)
7395 {
7396 delete* achievementItr;
7397 }
7398
7399 for (auto itemsItr = difficultiesItr->second->items.begin(); itemsItr != difficultiesItr->second->items.end(); ++itemsItr)
7400 {
7401 delete* itemsItr;
7402 }
7403
7404 delete difficultiesItr->second;
7405 }
7406 }
7407
7408 _accessRequirementStore.clear(); // need for reload case
7409 }
7410 // 0 1 2 3 4 5
7411 QueryResult access_template_result = WorldDatabase.Query("SELECT id, map_id, difficulty, min_level, max_level, min_avg_item_level FROM dungeon_access_template");
7412 if (!access_template_result)
7413 {
7414 LOG_WARN("server.loading", ">> Loaded 0 access requirement definitions. DB table `dungeon_access_template` is empty.");
7415 LOG_INFO("server.loading", " ");
7416 return;
7417 }
7418
7419 uint32 count = 0;
7420 uint32 countProgressionRequirements = 0;
7421
7422 do
7423 {
7424 Field* fields = access_template_result->Fetch();
7425
7426 //Get the common variables for the access requirements
7427 uint8 dungeon_access_id = fields[0].Get<uint8>();
7428 uint32 mapid = fields[1].Get<uint32>();
7429 uint8 difficulty = fields[2].Get<uint8>();
7430
7431 //Set up the access requirements
7433 ar->levelMin = fields[3].Get<uint8>();
7434 ar->levelMax = fields[4].Get<uint8>();
7435 ar->reqItemLevel = fields[5].Get<uint16>();
7436
7437 // 0 1 2 3 4 6
7438 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);
7439 if (progression_requirements_results)
7440 {
7441 do
7442 {
7443 Field* progression_requirement_row = progression_requirements_results->Fetch();
7444
7445 const uint8 requirement_type = progression_requirement_row[0].Get<uint8>();
7446 const uint32 requirement_id = progression_requirement_row[1].Get<uint32>();
7447 const std::string requirement_note = progression_requirement_row[2].Get<std::string>();
7448 const uint8 requirement_faction = progression_requirement_row[3].Get<uint8>();
7449 const uint8 requirement_priority = progression_requirement_row[4].IsNull() ? UINT8_MAX : progression_requirement_row[4].Get<uint8>();
7450 const bool requirement_checkLeaderOnly = progression_requirement_row[5].Get<bool>();
7451
7452 ProgressionRequirement* progression_requirement = new ProgressionRequirement();
7453 progression_requirement->id = requirement_id;
7454 progression_requirement->note = requirement_note;
7455 progression_requirement->faction = (TeamId)requirement_faction;
7456 progression_requirement->priority = requirement_priority;
7457 progression_requirement->checkLeaderOnly = requirement_checkLeaderOnly;
7458
7459 std::vector<ProgressionRequirement*>* currentRequirementsList = nullptr;
7460
7461 switch (requirement_type)
7462 {
7463 case 0:
7464 {
7465 //Achievement
7466 if (!sAchievementStore.LookupEntry(progression_requirement->id))
7467 {
7468 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);
7469 break;
7470 }
7471
7472 currentRequirementsList = &ar->achievements;
7473 break;
7474 }
7475 case 1:
7476 {
7477 //Quest
7478 if (!GetQuestTemplate(progression_requirement->id))
7479 {
7480 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);
7481 break;
7482 }
7483
7484 currentRequirementsList = &ar->quests;
7485 break;
7486 }
7487 case 2:
7488 {
7489 //Item
7490 ItemTemplate const* pProto = GetItemTemplate(progression_requirement->id);
7491 if (!pProto)
7492 {
7493 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);
7494 break;
7495 }
7496
7497 currentRequirementsList = &ar->items;
7498 break;
7499 }
7500 default:
7501 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);
7502 break;
7503 }
7504
7505 //Check if array is valid and delete the progression requirement
7506 if (!currentRequirementsList)
7507 {
7508 delete progression_requirement;
7509 continue;
7510 }
7511
7512 //Insert into the array
7513 if (currentRequirementsList->size() > requirement_priority)
7514 {
7515 currentRequirementsList->insert(currentRequirementsList->begin() + requirement_priority, progression_requirement);
7516 }
7517 else
7518 {
7519 currentRequirementsList->push_back(progression_requirement);
7520 }
7521
7522 } while (progression_requirements_results->NextRow());
7523 }
7524
7525 //Sort all arrays for priority
7526 auto sortFunction = [](const ProgressionRequirement* const a, const ProgressionRequirement* const b) {return a->priority > b->priority; };
7527 std::sort(ar->achievements.begin(), ar->achievements.end(), sortFunction);
7528 std::sort(ar->quests.begin(), ar->quests.end(), sortFunction);
7529 std::sort(ar->items.begin(), ar->items.end(), sortFunction);
7530
7531 countProgressionRequirements += ar->achievements.size();
7532 countProgressionRequirements += ar->quests.size();
7533 countProgressionRequirements += ar->items.size();
7534 count++;
7535
7536 _accessRequirementStore[mapid][difficulty] = ar;
7537 } while (access_template_result->NextRow());
7538
7539 LOG_INFO("server.loading", ">> Loaded {} Rows From dungeon_access_template And {} Rows From dungeon_access_requirements in {} ms", count, countProgressionRequirements, GetMSTimeDiffToNow(oldMSTime));
7540 LOG_INFO("server.loading", " ");
7541}
DBCStorage< AchievementEntry > sAchievementStore(Achievementfmt)
std::shared_ptr< ResultSet > QueryResult
Definition DatabaseEnvFwd.h:27
#define LOG_WARN(filterType__,...)
Definition Log.h:162
TeamId
Definition SharedDefines.h: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:3838
Quest const * GetQuestTemplate(uint32 quest_id) const
Definition ObjectMgr.h:835
Definition Player.h:935
Definition ItemTemplate.h:619
Definition Player.h:926
uint32 priority
Definition Player.h:930

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

◆ LoadAcoreStrings()

bool ObjectMgr::LoadAcoreStrings ( )
9328{
9329 uint32 oldMSTime = getMSTime();
9330
9331 _acoreStringStore.clear(); // for reload case
9332 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");
9333 if (!result)
9334 {
9335 LOG_WARN("server.loading", ">> Loaded 0 acore strings. DB table `acore_strings` is empty.");
9336 LOG_INFO("server.loading", " ");
9337 return false;
9338 }
9339
9340 do
9341 {
9342 Field* fields = result->Fetch();
9343
9344 uint32 entry = fields[0].Get<uint32>();
9345
9346 AcoreString& data = _acoreStringStore[entry];
9347
9348 data.Content.resize(DEFAULT_LOCALE + 1);
9349
9350 for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
9351 AddLocaleString(fields[i + 1].Get<std::string>(), LocaleConstant(i), data.Content);
9352 } while (result->NextRow());
9353
9354 LOG_INFO("server.loading", ">> Loaded {} Acore Strings in {} ms", (uint32)_acoreStringStore.size(), GetMSTimeDiffToNow(oldMSTime));
9355 LOG_INFO("server.loading", " ");
9356
9357 return true;
9358}
LocaleConstant
Definition Common.h:117
@ TOTAL_LOCALES
Definition Common.h:128
static void AddLocaleString(std::string &&s, LocaleConstant locale, std::vector< std::string > &data)
Definition ObjectMgr.cpp:379

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

◆ LoadAreaTriggers()

void ObjectMgr::LoadAreaTriggers ( )
7268{
7269 uint32 oldMSTime = getMSTime();
7270
7271 _areaTriggerStore.clear();
7272
7273 QueryResult result = WorldDatabase.Query("SELECT entry, map, x, y, z, radius, length, width, height, orientation FROM areatrigger");
7274
7275 if (!result)
7276 {
7277 LOG_WARN("server.loading", ">> Loaded 0 area trigger definitions. DB table `areatrigger` is empty.");
7278 LOG_INFO("server.loading", " ");
7279 return;
7280 }
7281
7282 uint32 count = 0;
7283
7284 do
7285 {
7286 Field* fields = result->Fetch();
7287
7288 ++count;
7289
7290 AreaTrigger at;
7291
7292 at.entry = fields[0].Get<uint32>();
7293 at.map = fields[1].Get<uint32>();
7294 at.x = fields[2].Get<float>();
7295 at.y = fields[3].Get<float>();
7296 at.z = fields[4].Get<float>();
7297 at.radius = fields[5].Get<float>();
7298 at.length = fields[6].Get<float>();
7299 at.width = fields[7].Get<float>();
7300 at.height = fields[8].Get<float>();
7301 at.orientation = fields[9].Get<float>();
7302
7303 MapEntry const* mapEntry = sMapStore.LookupEntry(at.map);
7304 if (!mapEntry)
7305 {
7306 LOG_ERROR("sql.sql", "Area trigger (ID:{}) map (ID: {}) does not exist in `Map.dbc`.", at.entry, at.map);
7307 continue;
7308 }
7309
7310 _areaTriggerStore[at.entry] = at;
7311 } while (result->NextRow());
7312
7313 LOG_INFO("server.loading", ">> Loaded {} Area Trigger Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7314 LOG_INFO("server.loading", " ");
7315}
float height
Definition ObjectMgr.h:430
float x
Definition ObjectMgr.h:424
float y
Definition ObjectMgr.h:425
float orientation
Definition ObjectMgr.h:431
float length
Definition ObjectMgr.h:428
uint32 entry
Definition ObjectMgr.h:422
float radius
Definition ObjectMgr.h:427
float z
Definition ObjectMgr.h:426
float width
Definition ObjectMgr.h:429

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

◆ LoadAreaTriggerScripts()

void ObjectMgr::LoadAreaTriggerScripts ( )
7126{
7127 uint32 oldMSTime = getMSTime();
7128
7129 _areaTriggerScriptStore.clear(); // need for reload case
7130 QueryResult result = WorldDatabase.Query("SELECT entry, ScriptName FROM areatrigger_scripts");
7131
7132 if (!result)
7133 {
7134 LOG_WARN("server.loading", ">> Loaded 0 Areatrigger Scripts. DB Table `areatrigger_scripts` Is Empty.");
7135 LOG_INFO("server.loading", " ");
7136 return;
7137 }
7138
7139 uint32 count = 0;
7140
7141 do
7142 {
7143 ++count;
7144
7145 Field* fields = result->Fetch();
7146
7147 uint32 Trigger_ID = fields[0].Get<uint32>();
7148 std::string scriptName = fields[1].Get<std::string>();
7149
7150 AreaTrigger const* atEntry = GetAreaTrigger(Trigger_ID);
7151 if (!atEntry)
7152 {
7153 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
7154 continue;
7155 }
7156 _areaTriggerScriptStore[Trigger_ID] = GetScriptId(scriptName);
7157 } while (result->NextRow());
7158
7159 LOG_INFO("server.loading", ">> Loaded {} Areatrigger Scripts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7160 LOG_INFO("server.loading", " ");
7161}
uint32 GetScriptId(std::string const &name)
Definition ObjectMgr.cpp:10274

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

◆ LoadAreaTriggerTeleports()

void ObjectMgr::LoadAreaTriggerTeleports ( )
7318{
7319 uint32 oldMSTime = getMSTime();
7320
7321 _areaTriggerTeleportStore.clear(); // need for reload case
7322
7323 // 0 1 2 3 4 5
7324 QueryResult result = WorldDatabase.Query("SELECT ID, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM areatrigger_teleport");
7325
7326 if (!result)
7327 {
7328 LOG_WARN("server.loading", ">> Loaded 0 area trigger teleport definitions. DB table `areatrigger_teleport` is empty.");
7329 LOG_INFO("server.loading", " ");
7330 return;
7331 }
7332
7333 uint32 count = 0;
7334
7335 do
7336 {
7337 Field* fields = result->Fetch();
7338
7339 ++count;
7340
7341 uint32 Trigger_ID = fields[0].Get<uint32>();
7342
7344
7345 at.target_mapId = fields[1].Get<uint16>();
7346 at.target_X = fields[2].Get<float>();
7347 at.target_Y = fields[3].Get<float>();
7348 at.target_Z = fields[4].Get<float>();
7349 at.target_Orientation = fields[5].Get<float>();
7350
7351 AreaTrigger const* atEntry = GetAreaTrigger(Trigger_ID);
7352 if (!atEntry)
7353 {
7354 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
7355 continue;
7356 }
7357
7358 MapEntry const* mapEntry = sMapStore.LookupEntry(at.target_mapId);
7359 if (!mapEntry)
7360 {
7361 LOG_ERROR("sql.sql", "Area trigger (ID:{}) target map (ID: {}) does not exist in `Map.dbc`.", Trigger_ID, at.target_mapId);
7362 continue;
7363 }
7364
7365 if (at.target_X == 0 && at.target_Y == 0 && at.target_Z == 0)
7366 {
7367 LOG_ERROR("sql.sql", "Area trigger (ID:{}) target coordinates not provided.", Trigger_ID);
7368 continue;
7369 }
7370
7371 _areaTriggerTeleportStore[Trigger_ID] = at;
7372 } while (result->NextRow());
7373
7374 LOG_INFO("server.loading", ">> Loaded {} Area Trigger Teleport Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7375 LOG_INFO("server.loading", " ");
7376}
Definition ObjectMgr.h:412
uint32 target_mapId
Definition ObjectMgr.h:413

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

◆ LoadBroadcastTextLocales()

void ObjectMgr::LoadBroadcastTextLocales ( )
10374{
10375 uint32 oldMSTime = getMSTime();
10376
10377 // 0 1 2 3
10378 QueryResult result = WorldDatabase.Query("SELECT ID, locale, MaleText, FemaleText FROM broadcast_text_locale");
10379
10380 if (!result)
10381 {
10382 LOG_WARN("server.loading", ">> Loaded 0 broadcast text locales. DB table `broadcast_text_locale` is empty.");
10383 LOG_INFO("server.loading", " ");
10384 return;
10385 }
10386
10387 uint32 locales_count = 0;
10388 do
10389 {
10390 Field* fields = result->Fetch();
10391
10392 uint32 id = fields[0].Get<uint32>();
10393
10394 BroadcastTextContainer::iterator bct = _broadcastTextStore.find(id);
10395 if (bct == _broadcastTextStore.end())
10396 {
10397 LOG_ERROR("sql.sql", "BroadcastText (Id: {}) found in table `broadcast_text_locale` but does not exist in `broadcast_text`. Skipped!", id);
10398 continue;
10399 }
10400
10401 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
10402 if (locale == LOCALE_enUS)
10403 continue;
10404
10405 AddLocaleString(fields[2].Get<std::string>(), locale, bct->second.MaleText);
10406 AddLocaleString(fields[3].Get<std::string>(), locale, bct->second.FemaleText);
10407 locales_count++;
10408 } while (result->NextRow());
10409
10410 LOG_INFO("server.loading", ">> Loaded {} Broadcast Text Locales in {} ms", locales_count, GetMSTimeDiffToNow(oldMSTime));
10411 LOG_INFO("server.loading", " ");
10412}
LocaleConstant GetLocaleByName(const std::string &name)
Definition Common.cpp:42

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

◆ LoadBroadcastTexts()

void ObjectMgr::LoadBroadcastTexts ( )
10289{
10290 uint32 oldMSTime = getMSTime();
10291
10292 _broadcastTextStore.clear(); // for reload case
10293
10294 // 0 1 2 3 4 5 6 7 8 9 10 11 12
10295 QueryResult result = WorldDatabase.Query("SELECT ID, LanguageID, MaleText, FemaleText, EmoteID1, EmoteID2, EmoteID3, EmoteDelay1, EmoteDelay2, EmoteDelay3, SoundEntriesID, EmotesID, Flags FROM broadcast_text");
10296 if (!result)
10297 {
10298 LOG_WARN("server.loading", ">> Loaded 0 broadcast texts. DB table `broadcast_text` is empty.");
10299 LOG_INFO("server.loading", " ");
10300 return;
10301 }
10302
10303 _broadcastTextStore.rehash(result->GetRowCount());
10304
10305 do
10306 {
10307 Field* fields = result->Fetch();
10308
10309 BroadcastText bct;
10310
10311 bct.Id = fields[0].Get<uint32>();
10312 bct.LanguageID = fields[1].Get<uint32>();
10313 bct.MaleText[DEFAULT_LOCALE] = fields[2].Get<std::string>();
10314 bct.FemaleText[DEFAULT_LOCALE] = fields[3].Get<std::string>();
10315 bct.EmoteId1 = fields[4].Get<uint32>();
10316 bct.EmoteId2 = fields[5].Get<uint32>();
10317 bct.EmoteId3 = fields[6].Get<uint32>();
10318 bct.EmoteDelay1 = fields[7].Get<uint32>();
10319 bct.EmoteDelay2 = fields[8].Get<uint32>();
10320 bct.EmoteDelay3 = fields[9].Get<uint32>();
10321 bct.SoundEntriesId = fields[10].Get<uint32>();
10322 bct.EmotesID = fields[11].Get<uint32>();
10323 bct.Flags = fields[12].Get<uint32>();
10324
10325 if (bct.SoundEntriesId)
10326 {
10327 if (!sSoundEntriesStore.LookupEntry(bct.SoundEntriesId))
10328 {
10329 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has SoundEntriesId {} but sound does not exist.", bct.Id, bct.SoundEntriesId);
10330 bct.SoundEntriesId = 0;
10331 }
10332 }
10333
10335 {
10336 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` using Language {} but Language does not exist.", bct.Id, bct.LanguageID);
10338 }
10339
10340 if (bct.EmoteId1)
10341 {
10342 if (!sEmotesStore.LookupEntry(bct.EmoteId1))
10343 {
10344 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has EmoteId1 {} but emote does not exist.", bct.Id, bct.EmoteId1);
10345 bct.EmoteId1 = 0;
10346 }
10347 }
10348
10349 if (bct.EmoteId2)
10350 {
10351 if (!sEmotesStore.LookupEntry(bct.EmoteId2))
10352 {
10353 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has EmoteId2 {} but emote does not exist.", bct.Id, bct.EmoteId2);
10354 bct.EmoteId2 = 0;
10355 }
10356 }
10357
10358 if (bct.EmoteId3)
10359 {
10360 if (!sEmotesStore.LookupEntry(bct.EmoteId3))
10361 {
10362 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has EmoteId3 {} but emote does not exist.", bct.Id, bct.EmoteId3);
10363 bct.EmoteId3 = 0;
10364 }
10365 }
10366
10367 _broadcastTextStore[bct.Id] = bct;
10368 } while (result->NextRow());
10369
10370 LOG_INFO("server.loading", ">> Loaded {} Broadcast Texts in {} ms", _broadcastTextStore.size(), GetMSTimeDiffToNow(oldMSTime));
10371}
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:435
uint32 EmoteDelay2
Definition ObjectMgr.h:450
uint32 Id
Definition ObjectMgr.h:442
std::vector< std::string > FemaleText
Definition ObjectMgr.h:445
uint32 EmotesID
Definition ObjectMgr.h:453
uint32 LanguageID
Definition ObjectMgr.h:443
uint32 EmoteId2
Definition ObjectMgr.h:447
uint32 EmoteDelay1
Definition ObjectMgr.h:449
uint32 SoundEntriesId
Definition ObjectMgr.h:452
std::vector< std::string > MaleText
Definition ObjectMgr.h:444
uint32 EmoteId3
Definition ObjectMgr.h:448
uint32 EmoteId1
Definition ObjectMgr.h:446
uint32 EmoteDelay3
Definition ObjectMgr.h:451
uint32 Flags
Definition ObjectMgr.h:454

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

◆ LoadCreatureAddons()

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

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 ( )
10446{
10447 uint32 oldMSTime = getMSTime();
10448
10449 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");
10450
10451 if (!result)
10452 {
10453 LOG_WARN("server.loading", ">> Loaded 0 creature base stats. DB table `creature_classlevelstats` is empty.");
10454 LOG_INFO("server.loading", " ");
10455 return;
10456 }
10457
10458 uint32 count = 0;
10459 do
10460 {
10461 Field* fields = result->Fetch();
10462
10463 uint8 Level = fields[0].Get<uint8>();
10464 uint8 Class = fields[1].Get<uint8>();
10465
10466 if (!Class || ((1 << (Class - 1)) & CLASSMASK_ALL_CREATURES) == 0)
10467 LOG_ERROR("sql.sql", "Creature base stats for level {} has invalid class {}", Level, Class);
10468
10469 CreatureBaseStats stats;
10470
10471 for (uint8 i = 0; i < MAX_EXPANSIONS; ++i)
10472 {
10473 stats.BaseHealth[i] = fields[2 + i].Get<uint32>();
10474
10475 if (stats.BaseHealth[i] == 0)
10476 {
10477 LOG_ERROR("sql.sql", "Creature base stats for class {}, level {} has invalid zero base HP[{}] - set to 1", Class, Level, i);
10478 stats.BaseHealth[i] = 1;
10479 }
10480
10481 // xinef: if no data is available, get them from lower expansions
10482 if (stats.BaseHealth[i] <= 1)
10483 {
10484 for (uint8 j = i; j > 0;)
10485 {
10486 --j;
10487 if (stats.BaseHealth[j] > 1)
10488 {
10489 stats.BaseHealth[i] = stats.BaseHealth[j];
10490 break;
10491 }
10492 }
10493 }
10494
10495 stats.BaseDamage[i] = fields[9 + i].Get<float>();
10496 if (stats.BaseDamage[i] < 0.0f)
10497 {
10498 LOG_ERROR("sql.sql", "Creature base stats for class {}, level {} has invalid negative base damage[{}] - set to 0.0", Class, Level, i);
10499 stats.BaseDamage[i] = 0.0f;
10500 }
10501 }
10502
10503 stats.BaseMana = fields[5].Get<uint32>();
10504 stats.BaseArmor = fields[6].Get<uint32>();
10505
10506 stats.AttackPower = fields[7].Get<uint32>();
10507 stats.RangedAttackPower = fields[8].Get<uint32>();
10508
10509 stats.Strength = fields[12].Get<uint32>();
10510 stats.Agility = fields[13].Get<uint32>();
10511 stats.Stamina = fields[14].Get<uint32>();
10512 stats.Intellect = fields[15].Get<uint32>();
10513 stats.Spirit = fields[16].Get<uint32>();
10514
10515 if (!stats.Strength || !stats.Agility || !stats.Stamina || !stats.Intellect || !stats.Spirit)
10516 {
10517 // Once these attributes are implemented, this should probably be uncommented.
10518 // LOG_WARN("server.loading", "Creature base attributes for class {}, level {} are missing!", Class, Level);
10519 }
10520
10522
10523 ++count;
10524 } while (result->NextRow());
10525
10527 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
10528 {
10529 for (uint16 lvl = itr->second.minlevel; lvl <= itr->second.maxlevel; ++lvl)
10530 {
10531 if (_creatureBaseStatsStore.find(MAKE_PAIR16(lvl, itr->second.unit_class)) == _creatureBaseStatsStore.end())
10532 LOG_ERROR("sql.sql", "Missing base stats for creature class {} level {}", itr->second.unit_class, lvl);
10533 }
10534 }
10535
10536 LOG_INFO("server.loading", ">> Loaded {} Creature Base Stats in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10537 LOG_INFO("server.loading", " ");
10538}
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
Definition CreatureData.h:288
@ Class
Requires the player to be a specific class.
@ Level
Requires the player to be at least a specific level.
CreatureTemplateContainer const * GetCreatureTemplates() const
Definition ObjectMgr.h:770
uint32 BaseMana
Definition CreatureData.h:301
uint32 Agility
Definition CreatureData.h:307
float BaseDamage[MAX_EXPANSIONS]
Definition CreatureData.h:305
uint32 RangedAttackPower
Definition CreatureData.h:304
uint32 AttackPower
Definition CreatureData.h:303
uint32 BaseHealth[MAX_EXPANSIONS]
Definition CreatureData.h:300
uint32 Strength
Definition CreatureData.h:306
float BaseArmor
Definition CreatureData.h:302
uint32 Spirit
Definition CreatureData.h:310
uint32 Stamina
Definition CreatureData.h:308
uint32 Intellect
Definition CreatureData.h:309

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.

943{
944 // Hack for modules
945 std::string stringCreatureIds = sConfigMgr->GetOption<std::string>("Creatures.CustomIDs", "190010,55005,999991,25462,98888,601014,34567,34568");
946 std::vector<std::string_view> CustomCreatures = Acore::Tokenize(stringCreatureIds, ',', false);
947
948 for (auto& itr : CustomCreatures)
949 {
950 _creatureCustomIDsStore.push_back(Acore::StringTo<uint32>(itr).value());
951 }
952}
#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.
2509{
2510 CreatureData const* data = GetCreatureData(spawnId);
2511 if (data)
2512 return data;
2513
2514 QueryResult result = WorldDatabase.Query("SELECT creature.guid, id1, id2, id3, map, equipment_id, "
2515 "position_x, position_y, position_z, orientation, spawntimesecs, wander_distance, "
2516 "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, "
2517 "creature.npcflag, creature.unit_flags, creature.dynamicflags, creature.ScriptName "
2518 "FROM creature WHERE creature.guid = {}", spawnId);
2519
2520 if (!result)
2521 return nullptr;
2522
2523 Field* fields = result->Fetch();
2524 uint32 id1 = fields[1].Get<uint32>();
2525 uint32 id2 = fields[2].Get<uint32>();
2526 uint32 id3 = fields[3].Get<uint32>();
2527
2528 CreatureTemplate const* cInfo = GetCreatureTemplate(id1);
2529 if (!cInfo)
2530 {
2531 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non-existing creature entry {} in id1 field, skipped.", spawnId, id1);
2532 return nullptr;
2533 }
2534
2535 if (id2 && !GetCreatureTemplate(id2))
2536 {
2537 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non-existing creature entry {} in id2 field, skipped.", spawnId, id2);
2538 return nullptr;
2539 }
2540
2541 if (id3 && !GetCreatureTemplate(id3))
2542 {
2543 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non-existing creature entry {} in id3 field, skipped.", spawnId, id3);
2544 return nullptr;
2545 }
2546
2547 if (!id2 && id3)
2548 {
2549 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with creature entry {} in id3 field but no entry in id2 field, skipped.", spawnId, id3);
2550 return nullptr;
2551 }
2552
2554 creatureData.id1 = id1;
2555 creatureData.id2 = id2;
2556 creatureData.id3 = id3;
2557 creatureData.mapid = fields[4].Get<uint16>();
2558 creatureData.equipmentId = fields[5].Get<int8>();
2559 creatureData.posX = fields[6].Get<float>();
2560 creatureData.posY = fields[7].Get<float>();
2561 creatureData.posZ = fields[8].Get<float>();
2562 creatureData.orientation = fields[9].Get<float>();
2563 creatureData.spawntimesecs = fields[10].Get<uint32>();
2564 creatureData.wander_distance = fields[11].Get<float>();
2565 creatureData.currentwaypoint = fields[12].Get<uint32>();
2566 creatureData.curhealth = fields[13].Get<uint32>();
2567 creatureData.curmana = fields[14].Get<uint32>();
2568 creatureData.movementType = fields[15].Get<uint8>();
2569 creatureData.spawnMask = fields[16].Get<uint8>();
2570 creatureData.phaseMask = fields[17].Get<uint32>();
2571 creatureData.npcflag = fields[18].Get<uint32>();
2572 creatureData.unit_flags = fields[19].Get<uint32>();
2573 creatureData.dynamicflags = fields[20].Get<uint32>();
2574 creatureData.ScriptId = GetScriptId(fields[21].Get<std::string>());
2575
2576 if (!creatureData.ScriptId)
2577 creatureData.ScriptId = cInfo->ScriptID;
2578
2579 MapEntry const* mapEntry = sMapStore.LookupEntry(creatureData.mapid);
2580 if (!mapEntry)
2581 {
2582 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) that spawned at non-existing map (Id: {}), skipped.", spawnId, creatureData.mapid);
2583 _creatureDataStore.erase(spawnId);
2584 return nullptr;
2585 }
2586
2587 if (mapEntry->IsRaid() && creatureData.spawntimesecs >= 7 * DAY && creatureData.spawntimesecs < 14 * DAY)
2588 creatureData.spawntimesecs = 14 * DAY;
2589
2590 bool ok = true;
2591 for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff)
2592 {
2593 if (_difficultyEntries[diff].find(id1) != _difficultyEntries[diff].end() ||
2594 _difficultyEntries[diff].find(id2) != _difficultyEntries[diff].end() ||
2595 _difficultyEntries[diff].find(id3) != _difficultyEntries[diff].end())
2596 {
2597 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) that is listed as difficulty {} template (Entries: {}, {}, {}) in `creature_template`, skipped.",
2598 spawnId, diff + 1, id1, id2, id3);
2599 ok = false;
2600 }
2601 }
2602
2603 if (!ok)
2604 {
2605 _creatureDataStore.erase(spawnId);
2606 return nullptr;
2607 }
2608
2609 if (creatureData.equipmentId != 0)
2610 {
2611 if (!GetEquipmentInfo(id1, creatureData.equipmentId) ||
2612 (id2 && !GetEquipmentInfo(id2, creatureData.equipmentId)) ||
2613 (id3 && !GetEquipmentInfo(id3, creatureData.equipmentId)))
2614 {
2615 LOG_ERROR("sql.sql", "Table `creature` has creature (Entries: {}, {}, {}) with equipment_id {} not found in table `creature_equip_template`, set to no equipment.",
2616 id1, id2, id3, creatureData.equipmentId);
2617 creatureData.equipmentId = 0;
2618 }
2619 }
2620
2621 if (creatureData.movementType >= MAX_DB_MOTION_TYPE)
2622 {
2623 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with wrong movement generator type ({}), set to IDLE.",
2624 spawnId, id1, id2, id3, creatureData.movementType);
2625 creatureData.movementType = IDLE_MOTION_TYPE;
2626 }
2627
2628 if (creatureData.wander_distance < 0.0f)
2629 {
2630 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with `wander_distance`< 0, set to 0.",
2631 spawnId, id1, id2, id3);
2632 creatureData.wander_distance = 0.0f;
2633 }
2634 else if (creatureData.movementType == RANDOM_MOTION_TYPE)
2635 {
2636 if (creatureData.wander_distance == 0.0f)
2637 {
2638 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with `MovementType`=1 (random movement) but with `wander_distance`=0, replace by idle movement type (0).",
2639 spawnId, id1, id2, id3);
2640 creatureData.movementType = IDLE_MOTION_TYPE;
2641 }
2642 }
2643 else if (creatureData.movementType == IDLE_MOTION_TYPE)
2644 {
2645 if (creatureData.wander_distance != 0.0f)
2646 {
2647 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with `MovementType`=0 (idle) have `wander_distance`<>0, set to 0.",
2648 spawnId, id1, id2, id3);
2649 creatureData.wander_distance = 0.0f;
2650 }
2651 }
2652
2653 if (creatureData.phaseMask == 0)
2654 {
2655 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with `phaseMask`=0 (not visible for anyone), set to 1.",
2656 spawnId, id1, id2, id3);
2657 creatureData.phaseMask = 1;
2658 }
2659
2660 return &creatureData;
2661}
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:1444
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 ( )
9834{
9835 uint32 oldMSTime = getMSTime();
9836
9838
9839 if (QueryResult result = WorldDatabase.Query("SELECT CreatureId, TrainerId FROM creature_default_trainer"))
9840 {
9841 do
9842 {
9843 Field* fields = result->Fetch();
9844 uint32 creatureId = fields[0].Get<uint32>();
9845 uint32 trainerId = fields[1].Get<uint32>();
9846
9847 if (!GetCreatureTemplate(creatureId))
9848 {
9849 LOG_ERROR("sql.sql", "Table `creature_default_trainer` references non-existing creature template (CreatureId: %u), ignoring", creatureId);
9850 continue;
9851 }
9852
9853 _creatureDefaultTrainers[creatureId] = trainerId;
9854
9855 } while (result->NextRow());
9856 }
9857
9858 LOG_INFO("server.loading", ">> Loaded {} default trainers in {} ms", _creatureDefaultTrainers.size(), GetMSTimeDiffToNow(oldMSTime));
9859}

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

◆ LoadCreatureLocales()

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

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

◆ LoadCreatureModelInfo()

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

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

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

◆ LoadCreatureQuestEnders()

void ObjectMgr::LoadCreatureQuestEnders ( )
8763{
8764 LoadQuestRelationsHelper(_creatureQuestInvolvedRelations, "creature_questender", false, false);
8765
8766 for (QuestRelations::iterator itr = _creatureQuestInvolvedRelations.begin(); itr != _creatureQuestInvolvedRelations.end(); ++itr)
8767 {
8768 CreatureTemplate const* cInfo = GetCreatureTemplate(itr->first);
8769 if (!cInfo)
8770 LOG_ERROR("sql.sql", "Table `creature_questender` have data for not existed creature entry ({}) and existed quest {}", itr->first, itr->second);
8771 else if (!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER))
8772 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);
8773 }
8774}
@ UNIT_NPC_FLAG_QUESTGIVER
Definition UnitDefines.h:320
void LoadQuestRelationsHelper(QuestRelations &map, std::string const &table, bool starter, bool go)
Definition ObjectMgr.cpp:8675

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

Referenced by LoadQuestStartersAndEnders().

◆ LoadCreatureQuestItems()

void ObjectMgr::LoadCreatureQuestItems ( )
10859{
10860 uint32 oldMSTime = getMSTime();
10861
10862 // 0 1 2
10863 QueryResult result = WorldDatabase.Query("SELECT CreatureEntry, ItemId, Idx FROM creature_questitem ORDER BY Idx ASC");
10864
10865 if (!result)
10866 {
10867 LOG_WARN("server.loading", ">> Loaded 0 creature quest items. DB table `creature_questitem` is empty.");
10868 return;
10869 }
10870
10871 uint32 count = 0;
10872 do
10873 {
10874 Field* fields = result->Fetch();
10875
10876 uint32 entry = fields[0].Get<uint32>();
10877 uint32 item = fields[1].Get<uint32>();
10878 uint32 idx = fields[2].Get<uint32>();
10879
10880 CreatureTemplate const* creatureInfo = GetCreatureTemplate(entry);
10881 if (!creatureInfo)
10882 {
10883 LOG_ERROR("sql.sql", "Table `creature_questitem` has data for nonexistent creature (entry: {}, idx: {}), skipped", entry, idx);
10884 continue;
10885 };
10886
10887 ItemEntry const* dbcData = sItemStore.LookupEntry(item);
10888 if (!dbcData)
10889 {
10890 LOG_ERROR("sql.sql", "Table `creature_questitem` has nonexistent item (ID: {}) in creature (entry: {}, idx: {}), skipped", item, entry, idx);
10891 continue;
10892 };
10893
10894 _creatureQuestItemStore[entry].push_back(item);
10895
10896 ++count;
10897 } while (result->NextRow());
10898
10899 LOG_INFO("server.loading", ">> Loaded {} Creature Quest Items in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10900 LOG_INFO("server.loading", " ");
10901}
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 ( )
8749{
8750 LoadQuestRelationsHelper(_creatureQuestRelations, "creature_queststarter", true, false);
8751
8752 for (QuestRelations::iterator itr = _creatureQuestRelations.begin(); itr != _creatureQuestRelations.end(); ++itr)
8753 {
8754 CreatureTemplate const* cInfo = GetCreatureTemplate(itr->first);
8755 if (!cInfo)
8756 LOG_ERROR("sql.sql", "Table `creature_queststarter` have data for not existed creature entry ({}) and existed quest {}", itr->first, itr->second);
8757 else if (!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER))
8758 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);
8759 }
8760}

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

Referenced by LoadQuestStartersAndEnders().

◆ LoadCreatures()

void ObjectMgr::LoadCreatures ( )
2308{
2309 uint32 oldMSTime = getMSTime();
2310
2311 // 0 1 2 3 4 5 6 7 8 9 10 11
2312 QueryResult result = WorldDatabase.Query("SELECT creature.guid, id1, id2, id3, map, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, wander_distance, "
2313 // 12 13 14 15 16 17 18 19 20 21 22
2314 "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags, "
2315 // 23
2316 "creature.ScriptName "
2317 "FROM creature "
2318 "LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid "
2319 "LEFT OUTER JOIN pool_creature ON creature.guid = pool_creature.guid");
2320
2321 if (!result)
2322 {
2323 LOG_WARN("server.loading", ">> Loaded 0 creatures. DB table `creature` is empty.");
2324 LOG_INFO("server.loading", " ");
2325 return;
2326 }
2327
2329 LOG_INFO("server.loading", "Calculating zone and area fields. This may take a moment...");
2330
2331 // Build single time for check spawnmask
2332 std::map<uint32, uint32> spawnMasks;
2333 for (uint32 i = 0; i < sMapStore.GetNumRows(); ++i)
2334 if (sMapStore.LookupEntry(i))
2335 for (int k = 0; k < MAX_DIFFICULTY; ++k)
2337 spawnMasks[i] |= (1 << k);
2338
2339 _creatureDataStore.rehash(result->GetRowCount());
2340 uint32 count = 0;
2341 do
2342 {
2343 Field* fields = result->Fetch();
2344
2345 ObjectGuid::LowType spawnId = fields[0].Get<uint32>();
2346 uint32 id1 = fields[1].Get<uint32>();
2347 uint32 id2 = fields[2].Get<uint32>();
2348 uint32 id3 = fields[3].Get<uint32>();
2349
2350 CreatureTemplate const* cInfo = GetCreatureTemplate(id1);
2351 if (!cInfo)
2352 {
2353 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non existing creature entry {} in id1 field, skipped.", spawnId, id1);
2354 continue;
2355 }
2356 CreatureTemplate const* cInfo2 = GetCreatureTemplate(id2);
2357 if (!cInfo2 && id2)
2358 {
2359 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non existing creature entry {} in id2 field, skipped.", spawnId, id2);
2360 continue;
2361 }
2362 CreatureTemplate const* cInfo3 = GetCreatureTemplate(id3);
2363 if (!cInfo3 && id3)
2364 {
2365 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non existing creature entry {} in id3 field, skipped.", spawnId, id3);
2366 continue;
2367 }
2368 if (!id2 && id3)
2369 {
2370 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with creature entry {} in id3 field but no entry in id2 field, skipped.", spawnId, id3);
2371 continue;
2372 }
2373 CreatureData& data = _creatureDataStore[spawnId];
2374 data.id1 = id1;
2375 data.id2 = id2;
2376 data.id3 = id3;
2377 data.mapid = fields[4].Get<uint16>();
2378 data.equipmentId = fields[5].Get<int8>();
2379 data.posX = fields[6].Get<float>();
2380 data.posY = fields[7].Get<float>();
2381 data.posZ = fields[8].Get<float>();
2382 data.orientation = fields[9].Get<float>();
2383 data.spawntimesecs = fields[10].Get<uint32>();
2384 data.wander_distance = fields[11].Get<float>();
2385 data.currentwaypoint = fields[12].Get<uint32>();
2386 data.curhealth = fields[13].Get<uint32>();
2387 data.curmana = fields[14].Get<uint32>();
2388 data.movementType = fields[15].Get<uint8>();
2389 data.spawnMask = fields[16].Get<uint8>();
2390 data.phaseMask = fields[17].Get<uint32>();
2391 int16 gameEvent = fields[18].Get<int16>();
2392 uint32 PoolId = fields[19].Get<uint32>();
2393 data.npcflag = fields[20].Get<uint32>();
2394 data.unit_flags = fields[21].Get<uint32>();
2395 data.dynamicflags = fields[22].Get<uint32>();
2396 data.ScriptId = GetScriptId(fields[23].Get<std::string>());
2397
2398 if (!data.ScriptId)
2399 data.ScriptId = cInfo->ScriptID;
2400
2401 MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid);
2402 if (!mapEntry)
2403 {
2404 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {}) that spawned at not existed map (Id: {}), skipped.", spawnId, data.mapid);
2405 continue;
2406 }
2407
2408 // pussywizard: 7 days means no reaspawn, so set it to 14 days, because manual id reset may be late
2409 if (mapEntry->IsRaid() && data.spawntimesecs >= 7 * DAY && data.spawntimesecs < 14 * DAY)
2410 data.spawntimesecs = 14 * DAY;
2411
2412 // Skip spawnMask check for transport maps
2413 if (!_transportMaps.count(data.mapid) && data.spawnMask & ~spawnMasks[data.mapid])
2414 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {}) that have wrong spawn mask {} including not supported difficulty modes for map (Id: {}).",
2415 spawnId, data.spawnMask, data.mapid);
2416
2417 bool ok = true;
2418 for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff)
2419 {
2420 if ((_difficultyEntries[diff].find(data.id1) != _difficultyEntries[diff].end()) || (_difficultyEntries[diff].find(data.id2) != _difficultyEntries[diff].end()) || (_difficultyEntries[diff].find(data.id3) != _difficultyEntries[diff].end()))
2421 {
2422 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {}) that listed as difficulty {} template (Entries: {}, {}, {}) in `creature_template`, skipped.",
2423 spawnId, diff + 1, data.id1, data.id2, data.id3);
2424 ok = false;
2425 }
2426 }
2427 if (!ok)
2428 continue;
2429
2430 // -1 random, 0 no equipment,
2431 if (data.equipmentId != 0)
2432 {
2433 if ((!GetEquipmentInfo(data.id1, data.equipmentId)) || (data.id2 && !GetEquipmentInfo(data.id2, data.equipmentId)) || (data.id3 && !GetEquipmentInfo(data.id3, data.equipmentId)))
2434 {
2435 LOG_ERROR("sql.sql", "Table `creature` have creature (Entries: {}, {}, {}) one or more with equipment_id {} not found in table `creature_equip_template`, set to no equipment.",
2436 data.id1, data.id2, data.id3, data.equipmentId);
2437 data.equipmentId = 0;
2438 }
2439 }
2441 {
2442 if (!mapEntry->IsDungeon())
2443 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entries: {}, {}, {}) with a `creature_template`.`flags_extra` in one or more entries including CREATURE_FLAG_EXTRA_INSTANCE_BIND but creature are not in instance.",
2444 spawnId, data.id1, data.id2, data.id3);
2445 }
2446 if (data.movementType >= MAX_DB_MOTION_TYPE)
2447 {
2448 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {} Entries: {}, {}, {}) with wrong movement generator type ({}), ignored and set to IDLE.", spawnId, data.id1, data.id2, data.id3, data.movementType);
2450 }
2451 if (data.wander_distance < 0.0f)
2452 {
2453 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entries: {}, {}, {}) with `wander_distance`< 0, set to 0.", spawnId, data.id1, data.id2, data.id3);
2454 data.wander_distance = 0.0f;
2455 }
2456 else if (data.movementType == RANDOM_MOTION_TYPE)
2457 {
2458 if (data.wander_distance == 0.0f)
2459 {
2460 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entries: {}, {}, {}) with `MovementType`=1 (random movement) but with `wander_distance`=0, replace by idle movement type (0).",
2461 spawnId, data.id1, data.id2, data.id3);
2463 }
2464 }
2465 else if (data.movementType == IDLE_MOTION_TYPE)
2466 {
2467 if (data.wander_distance != 0.0f)
2468 {
2469 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entries: {}, {}, {}) with `MovementType`=0 (idle) have `wander_distance`<>0, set to 0.", spawnId, data.id1, data.id2, data.id3);
2470 data.wander_distance = 0.0f;
2471 }
2472 }
2473
2474 if (data.phaseMask == 0)
2475 {
2476 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entries: {}, {}, {}) with `phaseMask`=0 (not visible for anyone), set to 1.", spawnId, data.id1, data.id2, data.id3);
2477 data.phaseMask = 1;
2478 }
2479
2481 {
2482 uint32 zoneId = sMapMgr->GetZoneId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
2483 uint32 areaId = sMapMgr->GetAreaId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
2484
2486
2487 stmt->SetData(0, zoneId);
2488 stmt->SetData(1, areaId);
2489 stmt->SetData(2, spawnId);
2490
2491 WorldDatabase.Execute(stmt);
2492 }
2493
2494 // Add to grid if not managed by the game event or pool system
2495 if (gameEvent == 0 && PoolId == 0)
2496 AddCreatureToGrid(spawnId, &data);
2497
2498 ++count;
2499 } while (result->NextRow());
2500
2501 LOG_INFO("server.loading", ">> Loaded {} Creatures in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2502 LOG_INFO("server.loading", " ");
2503}
@ CREATURE_FLAG_EXTRA_INSTANCE_BIND
Definition CreatureData.h:45
Difficulty
Definition DBCEnums.h:266
MapDifficulty const * GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
Definition DBCStores.cpp:761
std::int16_t int16
Definition Define.h:104
@ CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA
Definition WorldConfig.h:113
@ WORLD_UPD_CREATURE_ZONE_AREA_DATA
Definition WorldDatabase.h:114
uint32 ScriptId
Definition CreatureData.h:394
bool HasFlagsExtra(uint32 flag) const
Definition CreatureData.h:279

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

◆ LoadCreatureSparring()

void ObjectMgr::LoadCreatureSparring ( )
2664{
2665 uint32 oldMSTime = getMSTime();
2666
2667 QueryResult result = WorldDatabase.Query("SELECT GUID, SparringPCT FROM creature_sparring");
2668
2669 if (!result)
2670 {
2671 LOG_WARN("server.loading", ">> Loaded 0 sparring data. DB table `creature_sparring` is empty.");
2672 LOG_INFO("server.loading", " ");
2673 return;
2674 }
2675
2676 uint32 count = 0;
2677 do
2678 {
2679 Field* fields = result->Fetch();
2680
2681 ObjectGuid::LowType spawnId = fields[0].Get<uint32>();
2682 float sparringHealthPct = fields[1].Get<float>();
2683
2684 if (!GetCreatureData(spawnId))
2685 {
2686 LOG_ERROR("sql.sql", "Entry {} has a record in `creature_sparring` but doesn't exist in `creatures` table");
2687 continue;
2688 }
2689
2690 _creatureSparringStore[spawnId].push_back(sparringHealthPct);
2691
2692 ++count;
2693 } while (result->NextRow());
2694
2695 LOG_INFO("server.loading", ">> Loaded {} sparring data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2696 LOG_INFO("server.loading", " ");
2697}

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

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

Referenced by LoadCreatureTemplates().

◆ LoadCreatureTemplateAddons()

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

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

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

Referenced by LoadCreatureTemplates().

◆ LoadCreatureTemplateResistances()

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

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

◆ LoadCreatureTemplateSpells()

void ObjectMgr::LoadCreatureTemplateSpells ( )
801{
802 uint32 oldMSTime = getMSTime();
803
804 // 0 1 2
805 QueryResult result = WorldDatabase.Query("SELECT CreatureID, `Index`, Spell FROM creature_template_spell");
806
807 if (!result)
808 {
809 LOG_WARN("server.loading", ">> Loaded 0 creature template spell definitions. DB table `creature_template_spell` is empty.");
810 LOG_INFO("server.loading", " ");
811 return;
812 }
813
814 uint32 count = 0;
815
816 do
817 {
818 Field* fields = result->Fetch();
819
820 uint32 creatureID = fields[0].Get<uint32>();
821 uint8 index = fields[1].Get<uint8>();
822
823 if (index >= MAX_CREATURE_SPELLS)
824 {
825 LOG_ERROR("sql.sql", "creature_template_spell has spell definitions for creature {} with a incorrect index {}", creatureID, index);
826 continue;
827 }
828
829 CreatureTemplateContainer::iterator itr = _creatureTemplateStore.find(creatureID);
830 if (itr == _creatureTemplateStore.end())
831 {
832 LOG_ERROR("sql.sql", "creature_template_spell has spell definitions for creature {} but this creature doesn't exist", creatureID);
833 continue;
834 }
835
836 CreatureTemplate& creatureTemplate = itr->second;
837 creatureTemplate.spells[index] = fields[2].Get<uint32>();
838
839 ++count;
840 } while (result->NextRow());
841
842 LOG_INFO("server.loading", ">> Loaded {} Creature Template Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
843 LOG_INFO("server.loading", " ");
844}
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 ( )
1471{
1472 uint32 oldMSTime = getMSTime();
1473
1474 // 0 1 2 3 4
1475 QueryResult result = WorldDatabase.Query("SELECT CreatureID, ID, ItemID1, ItemID2, ItemID3 FROM creature_equip_template");
1476
1477 if (!result)
1478 {
1479 LOG_WARN("server.loading", ">> Loaded 0 creature equipment templates. DB table `creature_equip_template` is empty!");
1480 LOG_INFO("server.loading", " ");
1481 return;
1482 }
1483
1484 uint32 count = 0;
1485 do
1486 {
1487 Field* fields = result->Fetch();
1488
1489 uint32 entry = fields[0].Get<uint32>();
1490
1491 if (!GetCreatureTemplate(entry))
1492 {
1493 LOG_ERROR("sql.sql", "Creature template (CreatureID: {}) does not exist but has a record in `creature_equip_template`", entry);
1494 continue;
1495 }
1496
1497 uint8 id = fields[1].Get<uint8>();
1498 if (!id)
1499 {
1500 LOG_ERROR("sql.sql", "Creature equipment template with id 0 found for creature {}, skipped.", entry);
1501 continue;
1502 }
1503
1504 EquipmentInfo& equipmentInfo = _equipmentInfoStore[entry][id];
1505
1506 equipmentInfo.ItemEntry[0] = fields[2].Get<uint32>();
1507 equipmentInfo.ItemEntry[1] = fields[3].Get<uint32>();
1508 equipmentInfo.ItemEntry[2] = fields[4].Get<uint32>();
1509
1510 for (uint8 i = 0; i < MAX_EQUIPMENT_ITEMS; ++i)
1511 {
1512 if (!equipmentInfo.ItemEntry[i])
1513 continue;
1514
1515 ItemEntry const* dbcItem = sItemStore.LookupEntry(equipmentInfo.ItemEntry[i]);
1516
1517 if (!dbcItem)
1518 {
1519 LOG_ERROR("sql.sql", "Unknown item (ID={}) in creature_equip_template.ItemID{} for CreatureID = {} and ID = {}, forced to 0.",
1520 equipmentInfo.ItemEntry[i], i + 1, entry, id);
1521 equipmentInfo.ItemEntry[i] = 0;
1522 continue;
1523 }
1524
1525 if (dbcItem->InventoryType != INVTYPE_WEAPON &&
1526 dbcItem->InventoryType != INVTYPE_SHIELD &&
1527 dbcItem->InventoryType != INVTYPE_RANGED &&
1528 dbcItem->InventoryType != INVTYPE_2HWEAPON &&
1531 dbcItem->InventoryType != INVTYPE_HOLDABLE &&
1532 dbcItem->InventoryType != INVTYPE_THROWN &&
1534 {
1535 LOG_ERROR("sql.sql", "Item (ID={}) in creature_equip_template.ItemID{} for CreatureID = {} and ID = {} is not equipable in a hand, forced to 0.",
1536 equipmentInfo.ItemEntry[i], i + 1, entry, id);
1537 equipmentInfo.ItemEntry[i] = 0;
1538 }
1539 }
1540
1541 ++count;
1542 } while (result->NextRow());
1543
1544 LOG_INFO("server.loading", ">> Loaded {} Equipment Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1545 LOG_INFO("server.loading", " ");
1546}
#define MAX_EQUIPMENT_ITEMS
Definition CreatureData.h:35
@ INVTYPE_HOLDABLE
Definition ItemTemplate.h:279
@ INVTYPE_RANGED
Definition ItemTemplate.h:271
@ INVTYPE_THROWN
Definition ItemTemplate.h:281
@ INVTYPE_RANGEDRIGHT
Definition ItemTemplate.h:282
@ INVTYPE_WEAPON
Definition ItemTemplate.h:269
@ INVTYPE_WEAPONMAINHAND
Definition ItemTemplate.h:277
@ INVTYPE_WEAPONOFFHAND
Definition ItemTemplate.h:278
@ INVTYPE_2HWEAPON
Definition ItemTemplate.h:273
@ INVTYPE_SHIELD
Definition ItemTemplate.h:270
Definition CreatureData.h:361
uint32 ItemEntry[MAX_EQUIPMENT_ITEMS]
Definition CreatureData.h:362
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 ( )
6174{
6176
6177 std::set<uint32> evt_scripts;
6178 // Load all possible script entries from gameobjects
6180 for (GameObjectTemplateContainer::const_iterator itr = gotc->begin(); itr != gotc->end(); ++itr)
6181 if (uint32 eventId = itr->second.GetEventScriptId())
6182 evt_scripts.insert(eventId);
6183
6184 // Load all possible script entries from spells
6185 for (uint32 i = 1; i < sSpellMgr->GetSpellInfoStoreSize(); ++i)
6186 if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(i))
6187 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
6188 if (spell->Effects[j].Effect == SPELL_EFFECT_SEND_EVENT)
6189 if (spell->Effects[j].MiscValue)
6190 evt_scripts.insert(spell->Effects[j].MiscValue);
6191
6192 for (std::size_t path_idx = 0; path_idx < sTaxiPathNodesByPath.size(); ++path_idx)
6193 {
6194 for (std::size_t node_idx = 0; node_idx < sTaxiPathNodesByPath[path_idx].size(); ++node_idx)
6195 {
6196 TaxiPathNodeEntry const* node = sTaxiPathNodesByPath[path_idx][node_idx];
6197
6198 if (node->arrivalEventID)
6199 evt_scripts.insert(node->arrivalEventID);
6200
6201 if (node->departureEventID)
6202 evt_scripts.insert(node->departureEventID);
6203 }
6204 }
6205
6206 // Then check if all scripts are in above list of possible script entries
6207 for (ScriptMapMap::const_iterator itr = sEventScripts.begin(); itr != sEventScripts.end(); ++itr)
6208 {
6209 std::set<uint32>::const_iterator itr2 = evt_scripts.find(itr->first);
6210 if (itr2 == evt_scripts.end())
6211 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 {}",
6212 itr->first, SPELL_EFFECT_SEND_EVENT);
6213 }
6214}
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:150
@ SPELL_EFFECT_SEND_EVENT
Definition SharedDefines.h:827
GameObjectTemplateContainer const * GetGameObjectTemplates() const
Definition ObjectMgr.h:762
void LoadScripts(ScriptsType type)
Definition ObjectMgr.cpp:5831
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 ( )
8055{
8056 uint32 oldMSTime = getMSTime();
8057
8058 QueryResult result = WorldDatabase.Query("SELECT level, basexp FROM exploration_basexp");
8059
8060 if (!result)
8061 {
8062 LOG_WARN("server.loading", ">> Loaded 0 BaseXP definitions. DB table `exploration_basexp` is empty.");
8063 LOG_INFO("server.loading", " ");
8064 return;
8065 }
8066
8067 uint32 count = 0;
8068
8069 do
8070 {
8071 Field* fields = result->Fetch();
8072 uint8 level = fields[0].Get<uint8>();
8073 uint32 basexp = fields[1].Get<int32>();
8074 _baseXPTable[level] = basexp;
8075 ++count;
8076 } while (result->NextRow());
8077
8078 LOG_INFO("server.loading", ">> Loaded {} BaseXP Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8079 LOG_INFO("server.loading", " ");
8080}
std::int32_t int32
Definition Define.h:103

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

◆ LoadFactionChangeAchievements()

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

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

◆ LoadFactionChangeItems()

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

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

◆ LoadFactionChangeQuests()

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

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

◆ LoadFactionChangeReputations()

void ObjectMgr::LoadFactionChangeReputations ( )
10649{
10650 uint32 oldMSTime = getMSTime();
10651
10652 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_reputations");
10653
10654 if (!result)
10655 {
10656 LOG_WARN("server.loading", ">> Loaded 0 faction change reputation pairs. DB table `player_factionchange_reputations` is empty.");
10657 LOG_INFO("server.loading", " ");
10658 return;
10659 }
10660
10661 uint32 count = 0;
10662
10663 do
10664 {
10665 Field* fields = result->Fetch();
10666
10667 uint32 alliance = fields[0].Get<uint32>();
10668 uint32 horde = fields[1].Get<uint32>();
10669
10670 if (!sFactionStore.LookupEntry(alliance))
10671 LOG_ERROR("sql.sql", "Reputation {} (alliance_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", alliance);
10672 else if (!sFactionStore.LookupEntry(horde))
10673 LOG_ERROR("sql.sql", "Reputation {} (horde_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", horde);
10674 else
10675 FactionChangeReputation[alliance] = horde;
10676
10677 ++count;
10678 } while (result->NextRow());
10679
10680 LOG_INFO("server.loading", ">> Loaded {} faction change reputation pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10681 LOG_INFO("server.loading", " ");
10682}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
CharacterConversionMap FactionChangeReputation
Definition ObjectMgr.h:1481

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

◆ LoadFactionChangeSpells()

void ObjectMgr::LoadFactionChangeSpells ( )
10685{
10686 uint32 oldMSTime = getMSTime();
10687
10688 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_spells");
10689
10690 if (!result)
10691 {
10692 LOG_WARN("server.loading", ">> Loaded 0 faction change spell pairs. DB table `player_factionchange_spells` is empty.");
10693 LOG_INFO("server.loading", " ");
10694 return;
10695 }
10696
10697 uint32 count = 0;
10698
10699 do
10700 {
10701 Field* fields = result->Fetch();
10702
10703 uint32 alliance = fields[0].Get<uint32>();
10704 uint32 horde = fields[1].Get<uint32>();
10705
10706 if (!sSpellMgr->GetSpellInfo(alliance))
10707 LOG_ERROR("sql.sql", "Spell {} (alliance_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", alliance);
10708 else if (!sSpellMgr->GetSpellInfo(horde))
10709 LOG_ERROR("sql.sql", "Spell {} (horde_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", horde);
10710 else
10711 FactionChangeSpells[alliance] = horde;
10712
10713 ++count;
10714 } while (result->NextRow());
10715
10716 LOG_INFO("server.loading", ">> Loaded {} faction change spell pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10717 LOG_INFO("server.loading", " ");
10718}
CharacterConversionMap FactionChangeSpells
Definition ObjectMgr.h:1482

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

◆ LoadFactionChangeTitles()

void ObjectMgr::LoadFactionChangeTitles ( )
10721{
10722 uint32 oldMSTime = getMSTime();
10723
10724 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_titles");
10725
10726 if (!result)
10727 {
10728 LOG_WARN("server.loading", ">> Loaded 0 faction change title pairs. DB table `player_factionchange_title` is empty.");
10729 return;
10730 }
10731
10732 uint32 count = 0;
10733
10734 do
10735 {
10736 Field* fields = result->Fetch();
10737
10738 uint32 alliance = fields[0].Get<uint32>();
10739 uint32 horde = fields[1].Get<uint32>();
10740
10741 if (!sCharTitlesStore.LookupEntry(alliance))
10742 LOG_ERROR("sql.sql", "Title {} (alliance_id) referenced in `player_factionchange_title` does not exist, pair skipped!", alliance);
10743 else if (!sCharTitlesStore.LookupEntry(horde))
10744 LOG_ERROR("sql.sql", "Title {} (horde_id) referenced in `player_factionchange_title` does not exist, pair skipped!", horde);
10745 else
10746 FactionChangeTitles[alliance] = horde;
10747
10748 ++count;
10749 } while (result->NextRow());
10750
10751 LOG_INFO("server.loading", ">> Loaded {} faction change title pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10752 LOG_INFO("server.loading", " ");
10753}
DBCStorage< CharTitlesEntry > sCharTitlesStore(CharTitlesEntryfmt)
CharacterConversionMap FactionChangeTitles
Definition ObjectMgr.h:1483

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

◆ LoadFishingBaseSkillLevel()

void ObjectMgr::LoadFishingBaseSkillLevel ( )
9377{
9378 uint32 oldMSTime = getMSTime();
9379
9380 _fishingBaseForAreaStore.clear(); // for reload case
9381
9382 QueryResult result = WorldDatabase.Query("SELECT entry, skill FROM skill_fishing_base_level");
9383
9384 if (!result)
9385 {
9386 LOG_WARN("server.loading", ">> Loaded 0 areas for fishing base skill level. DB table `skill_fishing_base_level` is empty.");
9387 LOG_INFO("server.loading", " ");
9388 return;
9389 }
9390
9391 uint32 count = 0;
9392
9393 do
9394 {
9395 Field* fields = result->Fetch();
9396 uint32 entry = fields[0].Get<uint32>();
9397 int32 skill = fields[1].Get<int16>();
9398
9399 AreaTableEntry const* fArea = sAreaTableStore.LookupEntry(entry);
9400 if (!fArea)
9401 {
9402 LOG_ERROR("sql.sql", "AreaId {} defined in `skill_fishing_base_level` does not exist", entry);
9403 continue;
9404 }
9405
9406 _fishingBaseForAreaStore[entry] = skill;
9407 ++count;
9408 } while (result->NextRow());
9409
9410 LOG_INFO("server.loading", ">> Loaded {} areas for fishing base skill level in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9411 LOG_INFO("server.loading", " ");
9412}

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

◆ LoadGameObjectAddons()

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

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

◆ LoadGameObjectDataFromDB()

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

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

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

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

Parameters
spawnIdThe gameobject spawn GUID to load.
Returns
Pointer to the cached GameObjectData, or nullptr on failure.
3016{
3017 GameObjectData const* data = GetGameObjectData(spawnId);
3018 if (data)
3019 return data;
3020
3021 QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
3022 "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, "
3023 "ScriptName "
3024 "FROM gameobject WHERE gameobject.guid = {}", spawnId);
3025
3026 if (!result)
3027 return nullptr;
3028
3029 Field* fields = result->Fetch();
3030 uint32 entry = fields[1].Get<uint32>();
3031
3032 GameObjectTemplate const* gInfo = GetGameObjectTemplate(entry);
3033 if (!gInfo)
3034 {
3035 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {}) with non-existing gameobject entry {}, skipped.", spawnId, entry);
3036 return nullptr;
3037 }
3038
3039 if (gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId))
3040 {
3041 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry {} GoType: {}) with an invalid displayId ({}), not loaded.",
3042 spawnId, entry, gInfo->type, gInfo->displayId);
3043 return nullptr;
3044 }
3045
3046 GameObjectData& goData = _gameObjectDataStore[spawnId];
3047 goData.id = entry;
3048 goData.mapid = fields[2].Get<uint16>();
3049 goData.posX = fields[3].Get<float>();
3050 goData.posY = fields[4].Get<float>();
3051 goData.posZ = fields[5].Get<float>();
3052 goData.orientation = fields[6].Get<float>();
3053 goData.rotation.x = fields[7].Get<float>();
3054 goData.rotation.y = fields[8].Get<float>();
3055 goData.rotation.z = fields[9].Get<float>();
3056 goData.rotation.w = fields[10].Get<float>();
3057 goData.spawntimesecs = fields[11].Get<int32>();
3058 goData.animprogress = fields[12].Get<uint8>();
3059 goData.artKit = 0;
3060 goData.ScriptId = GetScriptId(fields[16].Get<std::string>());
3061
3062 if (!goData.ScriptId)
3063 goData.ScriptId = gInfo->ScriptId;
3064
3065 MapEntry const* mapEntry = sMapStore.LookupEntry(goData.mapid);
3066 if (!mapEntry)
3067 {
3068 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) spawned on a non-existing map (Id: {}), skipped.", spawnId, entry, goData.mapid);
3069 _gameObjectDataStore.erase(spawnId);
3070 return nullptr;
3071 }
3072
3073 if (goData.spawntimesecs == 0 && gInfo->IsDespawnAtAction())
3074 {
3075 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);
3076 }
3077
3078 uint32 go_state = fields[13].Get<uint8>();
3079 if (go_state >= MAX_GO_STATE)
3080 {
3081 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid `state` ({}) value, skipped.", spawnId, entry, go_state);
3082 _gameObjectDataStore.erase(spawnId);
3083 return nullptr;
3084 }
3085 goData.go_state = GOState(go_state);
3086
3087 goData.spawnMask = fields[14].Get<uint8>();
3088 goData.phaseMask = fields[15].Get<uint32>();
3089
3090 if (goData.rotation.x < -1.0f || goData.rotation.x > 1.0f)
3091 {
3092 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationX ({}) value, skipped.", spawnId, entry, goData.rotation.x);
3093 _gameObjectDataStore.erase(spawnId);
3094 return nullptr;
3095 }
3096
3097 if (goData.rotation.y < -1.0f || goData.rotation.y > 1.0f)
3098 {
3099 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationY ({}) value, skipped.", spawnId, entry, goData.rotation.y);
3100 _gameObjectDataStore.erase(spawnId);
3101 return nullptr;
3102 }
3103
3104 if (goData.rotation.z < -1.0f || goData.rotation.z > 1.0f)
3105 {
3106 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationZ ({}) value, skipped.", spawnId, entry, goData.rotation.z);
3107 _gameObjectDataStore.erase(spawnId);
3108 return nullptr;
3109 }
3110
3111 if (goData.rotation.w < -1.0f || goData.rotation.w > 1.0f)
3112 {
3113 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationW ({}) value, skipped.", spawnId, entry, goData.rotation.w);
3114 _gameObjectDataStore.erase(spawnId);
3115 return nullptr;
3116 }
3117
3118 if (fabs(goData.rotation.x * goData.rotation.x + goData.rotation.y * goData.rotation.y +
3119 goData.rotation.z * goData.rotation.z + goData.rotation.w * goData.rotation.w - 1.0f) >= 1e-5f)
3120 {
3121 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);
3122 goData.rotation = G3D::Quat(G3D::Matrix3::fromEulerAnglesZYX(goData.orientation, 0.0f, 0.0f));
3123 }
3124
3125 if (!MapMgr::IsValidMapCoord(goData.mapid, goData.posX, goData.posY, goData.posZ, goData.orientation))
3126 {
3127 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid coordinates, skipped.", spawnId, entry);
3128 _gameObjectDataStore.erase(spawnId);
3129 return nullptr;
3130 }
3131
3132 if (goData.phaseMask == 0)
3133 {
3134 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with `phaseMask`=0 (not visible for anyone), set to 1.", spawnId, entry);
3135 goData.phaseMask = 1;
3136 }
3137
3138 return &goData;
3139}
DBCStorage< GameObjectDisplayInfoEntry > sGameObjectDisplayInfoStore(GameObjectDisplayInfofmt)
#define MAX_GO_STATE
Definition GameObjectData.h:27
GOState
Definition GameObjectData.h:706
static bool IsValidMapCoord(uint32 mapid, Position const &pos)
Definition MapMgr.h:90
uint32 ScriptId
Definition GameObjectData.h:725

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

◆ LoadGameObjectForQuests()

void ObjectMgr::LoadGameObjectForQuests ( )
9163{
9164 uint32 oldMSTime = getMSTime();
9165
9166 if (GetGameObjectTemplates()->empty())
9167 {
9168 LOG_WARN("server.loading", ">> Loaded 0 GameObjects for quests");
9169 LOG_INFO("server.loading", " ");
9170 return;
9171 }
9172
9173 uint32 count = 0;
9174
9175 // collect GO entries for GO that must activated
9177 for (GameObjectTemplateContainer::iterator itr = gotc->begin(); itr != gotc->end(); ++itr)
9178 {
9179 itr->second.IsForQuests = false;
9180 switch (itr->second.type)
9181 {
9183 itr->second.IsForQuests = true;
9184 ++count;
9185 break;
9187 {
9188 // scan GO chest with loot including quest items
9189 uint32 loot_id = (itr->second.GetLootId());
9190
9191 // find quest loot for GO
9192 if (itr->second.chest.questId || LootTemplates_Gameobject.HaveQuestLootFor(loot_id))
9193 {
9194 itr->second.IsForQuests = true;
9195 ++count;
9196 }
9197 break;
9198 }
9200 {
9201 if (itr->second._generic.questID > 0) //quests objects
9202 {
9203 itr->second.IsForQuests = true;
9204 ++count;
9205 }
9206 break;
9207 }
9209 {
9210 if (itr->second.spellFocus.questID > 0) //quests objects
9211 {
9212 itr->second.IsForQuests = true;
9213 ++count;
9214 }
9215 break;
9216 }
9218 {
9219 if (itr->second.goober.questId > 0) //quests objects
9220 {
9221 itr->second.IsForQuests = true;
9222 ++count;
9223 }
9224 break;
9225 }
9226 default:
9227 break;
9228 }
9229 }
9230
9231 LOG_INFO("server.loading", ">> Loaded {} GameObjects for quests in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9232 LOG_INFO("server.loading", " ");
9233}
LootStore LootTemplates_Gameobject("gameobject_loot_template", "gameobject entry", true)
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition SharedDefines.h:1556
@ GAMEOBJECT_TYPE_GENERIC
Definition SharedDefines.h:1553
@ GAMEOBJECT_TYPE_CHEST
Definition SharedDefines.h:1551
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition SharedDefines.h:1550
@ GAMEOBJECT_TYPE_GOOBER
Definition SharedDefines.h:1558
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 ( )
7699{
7700 uint32 oldMSTime = getMSTime();
7701
7702 _gameObjectLocaleStore.clear(); // need for reload case
7703
7704 // 0 1 2 3
7705 QueryResult result = WorldDatabase.Query("SELECT entry, locale, name, castBarCaption FROM gameobject_template_locale");
7706 if (!result)
7707 return;
7708
7709 do
7710 {
7711 Field* fields = result->Fetch();
7712
7713 uint32 ID = fields[0].Get<uint32>();
7714
7715 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
7716 if (locale == LOCALE_enUS)
7717 continue;
7718
7720 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
7721 AddLocaleString(fields[3].Get<std::string>(), locale, data.CastBarCaption);
7722 } while (result->NextRow());
7723
7724 LOG_INFO("server.loading", ">> Loaded {} Gameobject Locale Strings in {} ms", (uint32)_gameObjectLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
7725}
Definition GameObjectData.h:676
std::vector< std::string > Name
Definition GameObjectData.h:677
std::vector< std::string > CastBarCaption
Definition GameObjectData.h:678

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

◆ LoadGameobjectQuestEnders()

void ObjectMgr::LoadGameobjectQuestEnders ( )
8735{
8736 LoadQuestRelationsHelper(_goQuestInvolvedRelations, "gameobject_questender", false, true);
8737
8738 for (QuestRelations::iterator itr = _goQuestInvolvedRelations.begin(); itr != _goQuestInvolvedRelations.end(); ++itr)
8739 {
8740 GameObjectTemplate const* goInfo = GetGameObjectTemplate(itr->first);
8741 if (!goInfo)
8742 LOG_ERROR("sql.sql", "Table `gameobject_questender` have data for not existed gameobject entry ({}) and existed quest {}", itr->first, itr->second);
8743 else if (goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER)
8744 LOG_ERROR("sql.sql", "Table `gameobject_questender` have data gameobject entry ({}) for quest {}, but GO is not GAMEOBJECT_TYPE_QUESTGIVER", itr->first, itr->second);
8745 }
8746}

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

Referenced by LoadQuestStartersAndEnders().

◆ LoadGameObjectQuestItems()

void ObjectMgr::LoadGameObjectQuestItems ( )
10814{
10815 uint32 oldMSTime = getMSTime();
10816
10817 // 0 1 2
10818 QueryResult result = WorldDatabase.Query("SELECT GameObjectEntry, ItemId, Idx FROM gameobject_questitem ORDER BY Idx ASC");
10819
10820 if (!result)
10821 {
10822 LOG_WARN("server.loading", ">> Loaded 0 gameobject quest items. DB table `gameobject_questitem` is empty.");
10823 return;
10824 }
10825
10826 uint32 count = 0;
10827 do
10828 {
10829 Field* fields = result->Fetch();
10830
10831 uint32 entry = fields[0].Get<uint32>();
10832 uint32 item = fields[1].Get<uint32>();
10833 uint32 idx = fields[2].Get<uint32>();
10834
10835 GameObjectTemplate const* goInfo = GetGameObjectTemplate(entry);
10836 if (!goInfo)
10837 {
10838 LOG_ERROR("sql.sql", "Table `gameobject_questitem` has data for nonexistent gameobject (entry: {}, idx: {}), skipped", entry, idx);
10839 continue;
10840 };
10841
10842 ItemEntry const* dbcData = sItemStore.LookupEntry(item);
10843 if (!dbcData)
10844 {
10845 LOG_ERROR("sql.sql", "Table `gameobject_questitem` has nonexistent item (ID: {}) in gameobject (entry: {}, idx: {}), skipped", item, entry, idx);
10846 continue;
10847 };
10848
10849 _gameObjectQuestItemStore[entry].push_back(item);
10850
10851 ++count;
10852 } while (result->NextRow());
10853
10854 LOG_INFO("server.loading", ">> Loaded {} Gameobject Quest Items in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10855 LOG_INFO("server.loading", " ");
10856}

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

◆ LoadGameobjectQuestStarters()

void ObjectMgr::LoadGameobjectQuestStarters ( )
8721{
8722 LoadQuestRelationsHelper(_goQuestRelations, "gameobject_queststarter", true, true);
8723
8724 for (QuestRelations::iterator itr = _goQuestRelations.begin(); itr != _goQuestRelations.end(); ++itr)
8725 {
8726 GameObjectTemplate const* goInfo = GetGameObjectTemplate(itr->first);
8727 if (!goInfo)
8728 LOG_ERROR("sql.sql", "Table `gameobject_queststarter` have data for not existed gameobject entry ({}) and existed quest {}", itr->first, itr->second);
8729 else if (goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER)
8730 LOG_ERROR("sql.sql", "Table `gameobject_queststarter` have data gameobject entry ({}) for quest {}, but GO is not GAMEOBJECT_TYPE_QUESTGIVER", itr->first, itr->second);
8731 }
8732}

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

Referenced by LoadQuestStartersAndEnders().

◆ LoadGameobjects()

void ObjectMgr::LoadGameobjects ( )
2834{
2835 uint32 oldMSTime = getMSTime();
2836
2837 // 0 1 2 3 4 5 6
2838 QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
2839 // 7 8 9 10 11 12 13 14 15 16 17
2840 "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, eventEntry, pool_entry, "
2841 // 18
2842 "ScriptName "
2843 "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid "
2844 "LEFT OUTER JOIN pool_gameobject ON gameobject.guid = pool_gameobject.guid");
2845
2846 if (!result)
2847 {
2848 LOG_WARN("server.loading", ">> Loaded 0 gameobjects. DB table `gameobject` is empty.");
2849 LOG_INFO("server.loading", " ");
2850 return;
2851 }
2852
2854 LOG_INFO("server.loading", "Calculating zone and area fields. This may take a moment...");
2855
2856 // build single time for check spawnmask
2857 std::map<uint32, uint32> spawnMasks;
2858 for (uint32 i = 0; i < sMapStore.GetNumRows(); ++i)
2859 if (sMapStore.LookupEntry(i))
2860 for (int k = 0; k < MAX_DIFFICULTY; ++k)
2862 spawnMasks[i] |= (1 << k);
2863
2864 _gameObjectDataStore.rehash(result->GetRowCount());
2865 do
2866 {
2867 Field* fields = result->Fetch();
2868
2869 ObjectGuid::LowType guid = fields[0].Get<uint32>();
2870 uint32 entry = fields[1].Get<uint32>();
2871
2872 GameObjectTemplate const* gInfo = GetGameObjectTemplate(entry);
2873 if (!gInfo)
2874 {
2875 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {}) with non existing gameobject entry {}, skipped.", guid, entry);
2876 continue;
2877 }
2878
2879 if (!gInfo->displayId)
2880 {
2881 switch (gInfo->type)
2882 {
2885 break;
2886 default:
2887 LOG_ERROR("sql.sql", "Gameobject (GUID: {} Entry {} GoType: {}) doesn't have a displayId ({}), not loaded.", guid, entry, gInfo->type, gInfo->displayId);
2888 break;
2889 }
2890 }
2891
2892 if (gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId))
2893 {
2894 LOG_ERROR("sql.sql", "Gameobject (GUID: {} Entry {} GoType: {}) has an invalid displayId ({}), not loaded.", guid, entry, gInfo->type, gInfo->displayId);
2895 continue;
2896 }
2897
2899
2900 data.id = entry;
2901 data.mapid = fields[2].Get<uint16>();
2902 data.posX = fields[3].Get<float>();
2903 data.posY = fields[4].Get<float>();
2904 data.posZ = fields[5].Get<float>();
2905 data.orientation = fields[6].Get<float>();
2906 data.rotation.x = fields[7].Get<float>();
2907 data.rotation.y = fields[8].Get<float>();
2908 data.rotation.z = fields[9].Get<float>();
2909 data.rotation.w = fields[10].Get<float>();
2910 data.spawntimesecs = fields[11].Get<int32>();
2911 data.ScriptId = GetScriptId(fields[18].Get<std::string>());
2912 if (!data.ScriptId)
2913 data.ScriptId = gInfo->ScriptId;
2914
2915 MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid);
2916 if (!mapEntry)
2917 {
2918 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) spawned on a non-existed map (Id: {}), skip", guid, data.id, data.mapid);
2919 continue;
2920 }
2921
2922 if (data.spawntimesecs == 0 && gInfo->IsDespawnAtAction())
2923 {
2924 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);
2925 }
2926
2927 data.animprogress = fields[12].Get<uint8>();
2928 data.artKit = 0;
2929
2930 uint32 go_state = fields[13].Get<uint8>();
2931 if (go_state >= MAX_GO_STATE)
2932 {
2933 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid `state` ({}) value, skip", guid, data.id, go_state);
2934 continue;
2935 }
2936 data.go_state = GOState(go_state);
2937
2938 data.spawnMask = fields[14].Get<uint8>();
2939
2940 if (!_transportMaps.count(data.mapid) && data.spawnMask & ~spawnMasks[data.mapid])
2941 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);
2942
2943 data.phaseMask = fields[15].Get<uint32>();
2944 int16 gameEvent = fields[16].Get<int16>();
2945 uint32 PoolId = fields[17].Get<uint32>();
2946
2947 if (data.rotation.x < -1.0f || data.rotation.x > 1.0f)
2948 {
2949 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationX ({}) value, skip", guid, data.id, data.rotation.x);
2950 continue;
2951 }
2952
2953 if (data.rotation.y < -1.0f || data.rotation.y > 1.0f)
2954 {
2955 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationY ({}) value, skip", guid, data.id, data.rotation.y);
2956 continue;
2957 }
2958
2959 if (data.rotation.z < -1.0f || data.rotation.z > 1.0f)
2960 {
2961 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationZ ({}) value, skip", guid, data.id, data.rotation.z);
2962 continue;
2963 }
2964
2965 if (data.rotation.w < -1.0f || data.rotation.w > 1.0f)
2966 {
2967 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationW ({}) value, skip", guid, data.id, data.rotation.w);
2968 continue;
2969 }
2970
2971 if (fabs(data.rotation.x * data.rotation.x + data.rotation.y * data.rotation.y +
2972 data.rotation.z * data.rotation.z + data.rotation.w * data.rotation.w - 1.0f) >= 1e-5f)
2973 {
2974 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);
2975 data.rotation = G3D::Quat(G3D::Matrix3::fromEulerAnglesZYX(data.orientation, 0.0f, 0.0f));
2976 }
2977
2978 if (!MapMgr::IsValidMapCoord(data.mapid, data.posX, data.posY, data.posZ, data.orientation))
2979 {
2980 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid coordinates, skip", guid, data.id);
2981 continue;
2982 }
2983
2984 if (data.phaseMask == 0)
2985 {
2986 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with `phaseMask`=0 (not visible for anyone), set to 1.", guid, data.id);
2987 data.phaseMask = 1;
2988 }
2989
2991 {
2992 uint32 zoneId = sMapMgr->GetZoneId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
2993 uint32 areaId = sMapMgr->GetAreaId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
2994
2996
2997 stmt->SetData(0, zoneId);
2998 stmt->SetData(1, areaId);
2999 stmt->SetData(2, guid);
3000
3001 WorldDatabase.Execute(stmt);
3002 }
3003
3004 if (gameEvent == 0 && PoolId == 0) // if not this is to be managed by GameEvent System or Pool system
3005 AddGameobjectToGrid(guid, &data);
3006 } while (result->NextRow());
3007
3008 LOG_INFO("server.loading", ">> Loaded {} Gameobjects in {} ms", (unsigned long)_gameObjectDataStore.size(), GetMSTimeDiffToNow(oldMSTime));
3009 LOG_INFO("server.loading", " ");
3010}
@ GAMEOBJECT_TYPE_TRAP
Definition SharedDefines.h:1554
@ CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA
Definition WorldConfig.h:114
@ WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA
Definition WorldDatabase.h:115

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

◆ LoadGameObjectSummons()

void ObjectMgr::LoadGameObjectSummons ( )
2227{
2228 uint32 oldMSTime = getMSTime();
2229
2230 _goSummonDataStore.clear();
2231
2232 // 0 1 2 3 4 5 6 7 8 9 10 11 12
2233 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");
2234
2235 if (!result)
2236 {
2237 LOG_WARN("server.loading", ">> Loaded 0 gameobject summons. DB table `gameobject_summon_groups` is empty.");
2238 return;
2239 }
2240
2241 uint32 count = 0;
2242 do
2243 {
2244 Field* fields = result->Fetch();
2245
2246 uint32 summonerId = fields[0].Get<uint32>();
2247 SummonerType summonerType = SummonerType(fields[1].Get<uint8>());
2248 uint8 group = fields[2].Get<uint8>();
2249
2250 switch (summonerType)
2251 {
2253 if (!GetCreatureTemplate(summonerId))
2254 {
2255 LOG_ERROR("sql.sql", "Table `gameobject_summon_groups` has summoner with non existing entry {} for creature summoner type, skipped.", summonerId);
2256 continue;
2257 }
2258 break;
2260 if (!GetGameObjectTemplate(summonerId))
2261 {
2262 LOG_ERROR("sql.sql", "Table `gameobject_summon_groups` has summoner with non existing entry {} for gameobject summoner type, skipped.", summonerId);
2263 continue;
2264 }
2265 break;
2266 case SUMMONER_TYPE_MAP:
2267 if (!sMapStore.LookupEntry(summonerId))
2268 {
2269 LOG_ERROR("sql.sql", "Table `gameobject_summon_groups` has summoner with non existing entry {} for map summoner type, skipped.", summonerId);
2270 continue;
2271 }
2272 break;
2273 default:
2274 LOG_ERROR("sql.sql", "Table `gameobject_summon_groups` has unhandled summoner type {} for summoner {}, skipped.", summonerType, summonerId);
2275 continue;
2276 }
2277
2279 data.entry = fields[3].Get<uint32>();
2280
2281 if (!GetGameObjectTemplate(data.entry))
2282 {
2283 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);
2284 continue;
2285 }
2286
2287 float posX = fields[4].Get<float>();
2288 float posY = fields[5].Get<float>();
2289 float posZ = fields[6].Get<float>();
2290 float orientation = fields[7].Get<float>();
2291
2292 data.pos.Relocate(posX, posY, posZ, orientation);
2293
2294 data.rot = G3D::Quat(fields[8].Get<float>(), fields[9].Get<float>(), fields[10].Get<float>(), fields[11].Get<float>());
2295 data.respawnTime = fields[12].Get<uint32>();
2296
2297 TempSummonGroupKey key(summonerId, summonerType, group);
2298 _goSummonDataStore[key].push_back(data);
2299
2300 ++count;
2301 } while (result->NextRow());
2302
2303 LOG_INFO("server.loading", ">> Loaded {} Gameobject Summons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2304 LOG_INFO("server.loading", " ");
2305}
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 ( )
7787{
7788 uint32 oldMSTime = getMSTime();
7789
7790 // 0 1 2 3 4 5 6 7
7791 QueryResult result = WorldDatabase.Query("SELECT entry, type, displayId, name, IconName, castBarCaption, unk1, size, "
7792 // 8 9 10 11 12 13 14 15 16 17 18 19 20
7793 "Data0, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11, Data12, "
7794 // 21 22 23 24 25 26 27 28 29 30 31 32 33
7795 "Data13, Data14, Data15, Data16, Data17, Data18, Data19, Data20, Data21, Data22, Data23, AIName, ScriptName "
7796 "FROM gameobject_template");
7797
7798 if (!result)
7799 {
7800 LOG_WARN("server.loading", ">> Loaded 0 gameobject definitions. DB table `gameobject_template` is empty.");
7801 LOG_INFO("server.loading", " ");
7802 return;
7803 }
7804
7805 _gameObjectTemplateStore.rehash(result->GetRowCount());
7806 uint32 count = 0;
7807 do
7808 {
7809 Field* fields = result->Fetch();
7810
7811 uint32 entry = fields[0].Get<uint32>();
7812
7814
7815 got.entry = entry;
7816 got.type = uint32(fields[1].Get<uint8>());
7817 got.displayId = fields[2].Get<uint32>();
7818 got.name = fields[3].Get<std::string>();
7819 got.IconName = fields[4].Get<std::string>();
7820 got.castBarCaption = fields[5].Get<std::string>();
7821 got.unk1 = fields[6].Get<std::string>();
7822 got.size = fields[7].Get<float>();
7823
7824 for (uint8 i = 0; i < MAX_GAMEOBJECT_DATA; ++i)
7825 got.raw.data[i] = fields[8 + i].Get<int32>(); // data1 and data6 can be -1
7826
7827 got.AIName = fields[32].Get<std::string>();
7828 got.ScriptId = GetScriptId(fields[33].Get<std::string>());
7829 got.IsForQuests = false;
7830
7831 // Checks
7832 if (!got.AIName.empty() && !sGameObjectAIRegistry->HasItem(got.AIName))
7833 {
7834 LOG_ERROR("sql.sql", "GameObject (Entry: {}) has non-registered `AIName` '{}' set, removing", got.entry, got.AIName);
7835 }
7836
7837 switch (got.type)
7838 {
7839 case GAMEOBJECT_TYPE_DOOR: //0
7840 {
7841 if (got.door.lockId)
7842 CheckGOLockId(&got, got.door.lockId, 1);
7843 CheckGONoDamageImmuneId(&got, got.door.noDamageImmune, 3);
7844 break;
7845 }
7846 case GAMEOBJECT_TYPE_BUTTON: //1
7847 {
7848 if (got.button.lockId)
7849 CheckGOLockId(&got, got.button.lockId, 1);
7850 CheckGONoDamageImmuneId(&got, got.button.noDamageImmune, 4);
7851 break;
7852 }
7854 {
7855 if (got.questgiver.lockId)
7856 CheckGOLockId(&got, got.questgiver.lockId, 0);
7857 CheckGONoDamageImmuneId(&got, got.questgiver.noDamageImmune, 5);
7858 break;
7859 }
7860 case GAMEOBJECT_TYPE_CHEST: //3
7861 {
7862 if (got.chest.lockId)
7863 CheckGOLockId(&got, got.chest.lockId, 0);
7864
7865 CheckGOConsumable(&got, got.chest.consumable, 3);
7866
7867 if (got.chest.linkedTrapId) // linked trap
7868 CheckGOLinkedTrapId(&got, got.chest.linkedTrapId, 7);
7869 break;
7870 }
7871 case GAMEOBJECT_TYPE_TRAP: //6
7872 {
7873 if (got.trap.lockId)
7874 CheckGOLockId(&got, got.trap.lockId, 0);
7875 break;
7876 }
7877 case GAMEOBJECT_TYPE_CHAIR: //7
7878 CheckAndFixGOChairHeightId(&got, got.chair.height, 1);
7879 break;
7881 {
7882 if (got.spellFocus.focusId)
7883 {
7884 if (!sSpellFocusObjectStore.LookupEntry(got.spellFocus.focusId))
7885 LOG_ERROR("sql.sql", "GameObject (Entry: {} GoType: {}) have data0={} but SpellFocus (Id: {}) not exist.",
7886 entry, got.type, got.spellFocus.focusId, got.spellFocus.focusId);
7887 }
7888
7889 if (got.spellFocus.linkedTrapId) // linked trap
7890 CheckGOLinkedTrapId(&got, got.spellFocus.linkedTrapId, 2);
7891 break;
7892 }
7893 case GAMEOBJECT_TYPE_GOOBER: //10
7894 {
7895 if (got.goober.lockId)
7896 CheckGOLockId(&got, got.goober.lockId, 0);
7897
7898 CheckGOConsumable(&got, got.goober.consumable, 3);
7899
7900 if (got.goober.pageId) // pageId
7901 {
7902 if (!GetPageText(got.goober.pageId))
7903 LOG_ERROR("sql.sql", "GameObject (Entry: {} GoType: {}) have data7={} but PageText (Entry {}) not exist.",
7904 entry, got.type, got.goober.pageId, got.goober.pageId);
7905 }
7906 CheckGONoDamageImmuneId(&got, got.goober.noDamageImmune, 11);
7907 if (got.goober.linkedTrapId) // linked trap
7908 CheckGOLinkedTrapId(&got, got.goober.linkedTrapId, 12);
7909 break;
7910 }
7912 {
7913 if (got.areadamage.lockId)
7914 CheckGOLockId(&got, got.areadamage.lockId, 0);
7915 break;
7916 }
7917 case GAMEOBJECT_TYPE_CAMERA: //13
7918 {
7919 if (got.camera.lockId)
7920 CheckGOLockId(&got, got.camera.lockId, 0);
7921 break;
7922 }
7924 {
7925 if (got.moTransport.taxiPathId)
7926 {
7927 if (got.moTransport.taxiPathId >= sTaxiPathNodesByPath.size() || sTaxiPathNodesByPath[got.moTransport.taxiPathId].empty())
7928 LOG_ERROR("sql.sql", "GameObject (Entry: {} GoType: {}) have data0={} but TaxiPath (Id: {}) not exist.",
7929 entry, got.type, got.moTransport.taxiPathId, got.moTransport.taxiPathId);
7930 }
7931 if (uint32 transportMap = got.moTransport.mapID)
7932 _transportMaps.insert(transportMap);
7933 break;
7934 }
7936 break;
7938 {
7939 // always must have spell
7940 CheckGOSpellId(&got, got.spellcaster.spellId, 0);
7941 break;
7942 }
7943 case GAMEOBJECT_TYPE_FLAGSTAND: //24
7944 {
7945 if (got.flagstand.lockId)
7946 CheckGOLockId(&got, got.flagstand.lockId, 0);
7947 CheckGONoDamageImmuneId(&got, got.flagstand.noDamageImmune, 5);
7948 break;
7949 }
7951 {
7952 if (got.fishinghole.lockId)
7953 CheckGOLockId(&got, got.fishinghole.lockId, 4);
7954 break;
7955 }
7956 case GAMEOBJECT_TYPE_FLAGDROP: //26
7957 {
7958 if (got.flagdrop.lockId)
7959 CheckGOLockId(&got, got.flagdrop.lockId, 0);
7960 CheckGONoDamageImmuneId(&got, got.flagdrop.noDamageImmune, 3);
7961 break;
7962 }
7964 CheckAndFixGOChairHeightId(&got, got.barberChair.chairheight, 0);
7965 break;
7966 }
7967
7968 ++count;
7969 } while (result->NextRow());
7970
7971 LOG_INFO("server.loading", ">> Loaded {} Game Object Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7972 LOG_INFO("server.loading", " ");
7973}
DBCStorage< SpellFocusObjectEntry > sSpellFocusObjectStore(SpellFocusObjectfmt)
#define sGameObjectAIRegistry
Definition GameObjectAIFactory.h:49
void CheckGONoDamageImmuneId(GameObjectTemplate *goTemplate, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7767
void CheckGOSpellId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7746
void CheckAndFixGOChairHeightId(GameObjectTemplate const *goInfo, uint32 const &dataN, uint32 N)
Definition ObjectMgr.cpp:7755
void CheckGOConsumable(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7776
void CheckGOLinkedTrapId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7736
void CheckGOLockId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition ObjectMgr.cpp:7727
@ GAMEOBJECT_TYPE_CAMERA
Definition SharedDefines.h:1561
@ GAMEOBJECT_TYPE_BUTTON
Definition SharedDefines.h:1549
@ GAMEOBJECT_TYPE_MO_TRANSPORT
Definition SharedDefines.h:1563
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition SharedDefines.h:1566
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition SharedDefines.h:1573
@ GAMEOBJECT_TYPE_FLAGDROP
Definition SharedDefines.h:1574
@ GAMEOBJECT_TYPE_SPELLCASTER
Definition SharedDefines.h:1570
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition SharedDefines.h:1572
@ GAMEOBJECT_TYPE_CHAIR
Definition SharedDefines.h:1555
@ GAMEOBJECT_TYPE_AREADAMAGE
Definition SharedDefines.h:1560
@ GAMEOBJECT_TYPE_BARBER_CHAIR
Definition SharedDefines.h:1580
@ GAMEOBJECT_TYPE_DOOR
Definition SharedDefines.h:1548
#define MAX_GAMEOBJECT_DATA
Definition SharedDefines.h:1587
PageText const * GetPageText(uint32 pageEntry)
Definition ObjectMgr.cpp:6415
uint32 entry
Definition GameObjectData.h:32

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

◆ LoadGameObjectTemplateAddons()

void ObjectMgr::LoadGameObjectTemplateAddons ( )
7976{
7977 uint32 oldMSTime = getMSTime();
7978
7979 // 0 1 2 3 4 5 6 7 8
7980 QueryResult result = WorldDatabase.Query("SELECT entry, faction, flags, mingold, maxgold, artkit0, artkit1, artkit2, artkit3 FROM gameobject_template_addon");
7981
7982 if (!result)
7983 {
7984 LOG_WARN("server.loading", ">> Loaded 0 gameobject template addon definitions. DB table `gameobject_template_addon` is empty.");
7985 LOG_INFO("server.loading", " ");
7986 return;
7987 }
7988
7989 uint32 count = 0;
7990 do
7991 {
7992 Field* fields = result->Fetch();
7993
7994 uint32 entry = fields[0].Get<uint32>();
7995
7996 GameObjectTemplate const* got = GetGameObjectTemplate(entry);
7997 if (!got)
7998 {
7999 LOG_ERROR("sql.sql",
8000 "GameObject template (Entry: {}) does not exist but has a record in `gameobject_template_addon`",
8001 entry);
8002 continue;
8003 }
8004
8006 gameObjectAddon.faction = uint32(fields[1].Get<uint16>());
8007 gameObjectAddon.flags = fields[2].Get<uint32>();
8008 gameObjectAddon.mingold = fields[3].Get<uint32>();
8009 gameObjectAddon.maxgold = fields[4].Get<uint32>();
8010
8011 for (uint32 i = 0; i < gameObjectAddon.artKits.size(); i++)
8012 {
8013 uint32 artKitID = fields[5 + i].Get<uint32>();
8014 if (!artKitID)
8015 continue;
8016
8017 if (!sGameObjectArtKitStore.LookupEntry(artKitID))
8018 {
8019 LOG_ERROR("sql.sql", "GameObject (Entry: {}) has invalid `artkit{}` {} defined, set to zero instead.", entry, i, artKitID);
8020 continue;
8021 }
8022
8023 gameObjectAddon.artKits[i] = artKitID;
8024 }
8025
8026 // checks
8027 if (gameObjectAddon.faction && !sFactionTemplateStore.LookupEntry(gameObjectAddon.faction))
8028 LOG_ERROR("sql.sql",
8029 "GameObject (Entry: {}) has invalid faction ({}) defined in `gameobject_template_addon`.",
8030 entry, gameObjectAddon.faction);
8031
8032 if (gameObjectAddon.maxgold > 0)
8033 {
8034 switch (got->type)
8035 {
8038 break;
8039 default:
8040 LOG_ERROR("sql.sql",
8041 "GameObject (Entry {} GoType: {}) cannot be looted but has maxgold set in `gameobject_template_addon`.",
8042 entry, got->type);
8043 break;
8044 }
8045 }
8046
8047 ++count;
8048 } while (result->NextRow());
8049
8050 LOG_INFO("server.loading", ">> Loaded {} Game Object Template Addons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8051 LOG_INFO("server.loading", " ");
8052}
DBCStorage< GameObjectArtKitEntry > sGameObjectArtKitStore(GameObjectArtKitfmt)
Definition GameObjectData.h:666
uint32 mingold
Definition GameObjectData.h:670
uint32 flags
Definition GameObjectData.h:669
uint32 faction
Definition GameObjectData.h:668
std::array< uint32, 4 > artKits
Definition GameObjectData.h:672
uint32 maxgold
Definition GameObjectData.h:671

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

◆ LoadGameTele()

void ObjectMgr::LoadGameTele ( )
9517{
9518 uint32 oldMSTime = getMSTime();
9519
9520 _gameTeleStore.clear(); // for reload case
9521
9522 // 0 1 2 3 4 5 6
9523 QueryResult result = WorldDatabase.Query("SELECT id, position_x, position_y, position_z, orientation, map, name FROM game_tele");
9524
9525 if (!result)
9526 {
9527 LOG_WARN("server.loading", ">> Loaded 0 GameTeleports. DB table `game_tele` is empty!");
9528 LOG_INFO("server.loading", " ");
9529 return;
9530 }
9531
9532 uint32 count = 0;
9533
9534 do
9535 {
9536 Field* fields = result->Fetch();
9537
9538 uint32 id = fields[0].Get<uint32>();
9539
9540 GameTele gt;
9541
9542 gt.position_x = fields[1].Get<float>();
9543 gt.position_y = fields[2].Get<float>();
9544 gt.position_z = fields[3].Get<float>();
9545 gt.orientation = fields[4].Get<float>();
9546 gt.mapId = fields[5].Get<uint16>();
9547 gt.name = fields[6].Get<std::string>();
9548
9549 if (!MapMgr::IsValidMapCoord(gt.mapId, gt.position_x, gt.position_y, gt.position_z, gt.orientation))
9550 {
9551 LOG_ERROR("sql.sql", "Wrong position for id {} (name: {}) in `game_tele` table, ignoring.", id, gt.name);
9552 continue;
9553 }
9554
9555 if (!Utf8toWStr(gt.name, gt.wnameLow))
9556 {
9557 LOG_ERROR("sql.sql", "Wrong UTF8 name for id {} in `game_tele` table, ignoring.", id);
9558 continue;
9559 }
9560
9561 wstrToLower(gt.wnameLow);
9562
9563 _gameTeleStore[id] = gt;
9564
9565 ++count;
9566 } while (result->NextRow());
9567
9568 LOG_INFO("server.loading", ">> Loaded {} GameTeleports in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9569 LOG_INFO("server.loading", " ");
9570}
float position_x
Definition ObjectMgr.h:134

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

◆ LoadGossipMenu()

void ObjectMgr::LoadGossipMenu ( )
9961{
9962 uint32 oldMSTime = getMSTime();
9963
9964 _gossipMenusStore.clear();
9965
9966 QueryResult result = WorldDatabase.Query("SELECT MenuID, TextID FROM gossip_menu");
9967
9968 if (!result)
9969 {
9970 LOG_WARN("server.loading", ">> Loaded 0 gossip_menu entries. DB table `gossip_menu` is empty!");
9971 LOG_INFO("server.loading", " ");
9972 return;
9973 }
9974
9975 do
9976 {
9977 Field* fields = result->Fetch();
9978
9979 GossipMenus gMenu;
9980
9981 gMenu.MenuID = fields[0].Get<uint32>();
9982 gMenu.TextID = fields[1].Get<uint32>();
9983
9984 if (!GetGossipText(gMenu.TextID))
9985 {
9986 LOG_ERROR("sql.sql", "Table gossip_menu entry {} are using non-existing TextID {}", gMenu.MenuID, gMenu.TextID);
9987 continue;
9988 }
9989
9990 _gossipMenusStore.insert(GossipMenusContainer::value_type(gMenu.MenuID, gMenu));
9991 } while (result->NextRow());
9992
9993 LOG_INFO("server.loading", ">> Loaded {} gossip_menu entries in {} ms", (uint32)_gossipMenusStore.size(), GetMSTimeDiffToNow(oldMSTime));
9994 LOG_INFO("server.loading", " ");
9995}
GossipText const * GetGossipText(uint32 Text_ID) const
Definition ObjectMgr.cpp:6593
Definition ObjectMgr.h:626
uint32 TextID
Definition ObjectMgr.h:628
uint32 MenuID
Definition ObjectMgr.h:627

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

◆ LoadGossipMenuItems()

void ObjectMgr::LoadGossipMenuItems ( )
9998{
9999 uint32 oldMSTime = getMSTime();
10000
10001 _gossipMenuItemsStore.clear();
10002
10003 QueryResult result = WorldDatabase.Query(
10004 // 0 1 2 3 4 5 6 7 8 9 10 11 12
10005 "SELECT MenuID, OptionID, OptionIcon, OptionText, OptionBroadcastTextID, OptionType, OptionNpcFlag, ActionMenuID, ActionPoiID, BoxCoded, BoxMoney, BoxText, BoxBroadcastTextID "
10006 "FROM gossip_menu_option ORDER BY MenuID, OptionID");
10007
10008 if (!result)
10009 {
10010 LOG_WARN("server.loading", ">> Loaded 0 gossip_menu_option IDs. DB table `gossip_menu_option` is empty!");
10011 LOG_INFO("server.loading", " ");
10012 return;
10013 }
10014
10015 do
10016 {
10017 Field* fields = result->Fetch();
10018
10019 GossipMenuItems gMenuItem;
10020
10021 gMenuItem.MenuID = fields[0].Get<uint32>();
10022 gMenuItem.OptionID = fields[1].Get<uint16>();
10023 gMenuItem.OptionIcon = fields[2].Get<uint32>();
10024 gMenuItem.OptionText = fields[3].Get<std::string>();
10025 gMenuItem.OptionBroadcastTextID = fields[4].Get<uint32>();
10026 gMenuItem.OptionType = fields[5].Get<uint8>();
10027 gMenuItem.OptionNpcFlag = fields[6].Get<uint32>();
10028 gMenuItem.ActionMenuID = fields[7].Get<uint32>();
10029 gMenuItem.ActionPoiID = fields[8].Get<uint32>();
10030 gMenuItem.BoxCoded = fields[9].Get<bool>();
10031 gMenuItem.BoxMoney = fields[10].Get<uint32>();
10032 gMenuItem.BoxText = fields[11].Get<std::string>();
10033 gMenuItem.BoxBroadcastTextID = fields[12].Get<uint32>();
10034
10035 if (gMenuItem.OptionIcon >= GOSSIP_ICON_MAX)
10036 {
10037 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);
10038 gMenuItem.OptionIcon = GOSSIP_ICON_CHAT;
10039 }
10040
10042 {
10043 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} has non-existing or incompatible OptionBroadcastTextID {}, ignoring.", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.OptionBroadcastTextID);
10044 gMenuItem.OptionBroadcastTextID = 0;
10045 }
10046
10047 if (gMenuItem.OptionType >= GOSSIP_OPTION_MAX)
10048 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);
10049
10050 if (gMenuItem.ActionPoiID && !GetPointOfInterest(gMenuItem.ActionPoiID))
10051 {
10052 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} use non-existing ActionPoiID {}, ignoring", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.ActionPoiID);
10053 gMenuItem.ActionPoiID = 0;
10054 }
10055
10056 if (gMenuItem.BoxBroadcastTextID && !GetBroadcastText(gMenuItem.BoxBroadcastTextID))
10057 {
10058 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} has non-existing or incompatible BoxBroadcastTextID {}, ignoring.", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.BoxBroadcastTextID);
10059 gMenuItem.BoxBroadcastTextID = 0;
10060 }
10061
10062 _gossipMenuItemsStore.insert(GossipMenuItemsContainer::value_type(gMenuItem.MenuID, gMenuItem));
10063 } while (result->NextRow());
10064
10065 // Warn if any trainer creature templates reference a GossipMenuId that has no gossip_menu_option entries
10066 // This will cause the gossip menu to fallback to MenuID 0 at runtime which will display: "I wish to unlearn my talents."
10067 std::set<uint32> checkedMenuIds;
10068 for (auto const& [entry, tmpl] : _creatureTemplateStore)
10069 {
10070 uint32 menuId = tmpl.GossipMenuId;
10071 if (!menuId)
10072 continue;
10073
10074 if (!(tmpl.npcflag & UNIT_NPC_FLAG_TRAINER))
10075 continue;
10076
10077 if (checkedMenuIds.contains(menuId))
10078 continue;
10079
10080 checkedMenuIds.insert(menuId);
10081
10082 auto [first, second] = _gossipMenuItemsStore.equal_range(menuId);
10083 if (first == second)
10084 LOG_WARN("server.loading", "Trainer creature template references GossipMenuId {} has no `gossip_menu_option` entries. This will fallback to MenuID 0.", menuId);
10085 }
10086
10087 LOG_INFO("server.loading", ">> Loaded {} gossip_menu_option entries in {} ms", uint32(_gossipMenuItemsStore.size()), GetMSTimeDiffToNow(oldMSTime));
10088 LOG_INFO("server.loading", " ");
10089}
@ GOSSIP_ICON_CHAT
Definition GossipDef.h:61
@ GOSSIP_ICON_MAX
Definition GossipDef.h:82
@ GOSSIP_OPTION_MAX
Definition GossipDef.h:56
@ UNIT_NPC_FLAG_TRAINER
Definition UnitDefines.h:323
PointOfInterest const * GetPointOfInterest(uint32 id) const
Definition ObjectMgr.h:929
BroadcastText const * GetBroadcastText(uint32 id) const
Definition ObjectMgr.h:1222
Definition ObjectMgr.h:608
uint8 OptionIcon
Definition ObjectMgr.h:611
uint32 BoxBroadcastTextID
Definition ObjectMgr.h:622
std::string OptionText
Definition ObjectMgr.h:612
uint32 ActionMenuID
Definition ObjectMgr.h:616
bool BoxCoded
Definition ObjectMgr.h:618
uint32 MenuID
Definition ObjectMgr.h:609
uint32 OptionNpcFlag
Definition ObjectMgr.h:615
uint32 ActionPoiID
Definition ObjectMgr.h:617
uint32 BoxMoney
Definition ObjectMgr.h:619
std::string BoxText
Definition ObjectMgr.h:620
uint32 OptionID
Definition ObjectMgr.h:610
uint32 OptionType
Definition ObjectMgr.h:614
uint32 OptionBroadcastTextID
Definition ObjectMgr.h:613

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

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

◆ LoadGossipText()

void ObjectMgr::LoadGossipText ( )
6602{
6603 uint32 oldMSTime = getMSTime();
6604
6605 QueryResult result = WorldDatabase.Query("SELECT ID, "
6606 "text0_0, text0_1, BroadcastTextID0, lang0, Probability0, em0_0, em0_1, em0_2, em0_3, em0_4, em0_5, "
6607 "text1_0, text1_1, BroadcastTextID1, lang1, Probability1, em1_0, em1_1, em1_2, em1_3, em1_4, em1_5, "
6608 "text2_0, text2_1, BroadcastTextID2, lang2, Probability2, em2_0, em2_1, em2_2, em2_3, em2_4, em2_5, "
6609 "text3_0, text3_1, BroadcastTextID3, lang3, Probability3, em3_0, em3_1, em3_2, em3_3, em3_4, em3_5, "
6610 "text4_0, text4_1, BroadcastTextID4, lang4, Probability4, em4_0, em4_1, em4_2, em4_3, em4_4, em4_5, "
6611 "text5_0, text5_1, BroadcastTextID5, lang5, Probability5, em5_0, em5_1, em5_2, em5_3, em5_4, em5_5, "
6612 "text6_0, text6_1, BroadcastTextID6, lang6, Probability6, em6_0, em6_1, em6_2, em6_3, em6_4, em6_5, "
6613 "text7_0, text7_1, BroadcastTextID7, lang7, Probability7, em7_0, em7_1, em7_2, em7_3, em7_4, em7_5 "
6614 "FROM npc_text");
6615
6616 if (!result)
6617 {
6618 LOG_WARN("server.loading", ">> Loaded 0 npc texts, table is empty!");
6619 LOG_INFO("server.loading", " ");
6620 return;
6621 }
6622
6623 _gossipTextStore.rehash(result->GetRowCount());
6624
6625 uint32 count = 0;
6626 uint8 cic;
6627
6628 do
6629 {
6630 cic = 0;
6631
6632 Field* fields = result->Fetch();
6633
6634 uint32 id = fields[cic++].Get<uint32>();
6635 if (!id)
6636 {
6637 LOG_ERROR("sql.sql", "Table `npc_text` has record wit reserved id 0, ignore.");
6638 continue;
6639 }
6640
6641 GossipText& gText = _gossipTextStore[id];
6642
6643 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
6644 {
6645 gText.Options[i].Text_0 = fields[cic++].Get<std::string>();
6646 gText.Options[i].Text_1 = fields[cic++].Get<std::string>();
6647 gText.Options[i].BroadcastTextID = fields[cic++].Get<uint32>();
6648 gText.Options[i].Language = fields[cic++].Get<uint8>();
6649 gText.Options[i].Probability = fields[cic++].Get<float>();
6650
6651 for (uint8 j = 0; j < MAX_GOSSIP_TEXT_EMOTES; ++j)
6652 {
6653 gText.Options[i].Emotes[j]._Delay = fields[cic++].Get<uint16>();
6654 gText.Options[i].Emotes[j]._Emote = fields[cic++].Get<uint16>();
6655 }
6656 }
6657
6658 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; i++)
6659 {
6660 if (gText.Options[i].BroadcastTextID)
6661 {
6663 {
6664 LOG_ERROR("sql.sql", "GossipText (Id: {}) in table `npc_text` has non-existing or incompatible BroadcastTextID{} {}.", id, i, gText.Options[i].BroadcastTextID);
6665 gText.Options[i].BroadcastTextID = 0;
6666 }
6667 }
6668 }
6669
6670 count++;
6671 } while (result->NextRow());
6672
6673 LOG_INFO("server.loading", ">> Loaded {} Npc Texts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6674 LOG_INFO("server.loading", " ");
6675}
#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 ( )
6509{
6510 uint32 oldMSTime = getMSTime();
6511
6512 // 0 1 2 3
6513 QueryResult result = WorldDatabase.Query("SELECT entry, creditType, creditEntry, lastEncounterDungeon FROM instance_encounters");
6514 if (!result)
6515 {
6516 LOG_WARN("server.loading", ">> Loaded 0 instance encounters, table is empty!");
6517 LOG_INFO("server.loading", " ");
6518 return;
6519 }
6520
6521 uint32 count = 0;
6522 std::map<uint32, DungeonEncounterEntry const*> dungeonLastBosses;
6523 do
6524 {
6525 Field* fields = result->Fetch();
6526 uint32 entry = fields[0].Get<uint32>();
6527 uint8 creditType = fields[1].Get<uint8>();
6528 uint32 creditEntry = fields[2].Get<uint32>();
6529 uint32 lastEncounterDungeon = fields[3].Get<uint16>();
6530 DungeonEncounterEntry const* dungeonEncounter = sDungeonEncounterStore.LookupEntry(entry);
6531 if (!dungeonEncounter)
6532 {
6533 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid encounter id {}, skipped!", entry);
6534 continue;
6535 }
6536
6537 if (lastEncounterDungeon && !sLFGMgr->GetLFGDungeonEntry(lastEncounterDungeon))
6538 {
6539 LOG_ERROR("sql.sql", "Table `instance_encounters` has an encounter {} ({}) marked as final for invalid dungeon id {}, skipped!", entry, dungeonEncounter->encounterName[0], lastEncounterDungeon);
6540 continue;
6541 }
6542
6543 std::map<uint32, DungeonEncounterEntry const*>::const_iterator itr = dungeonLastBosses.find(lastEncounterDungeon);
6544 if (lastEncounterDungeon)
6545 {
6546 if (itr != dungeonLastBosses.end())
6547 {
6548 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]);
6549 continue;
6550 }
6551
6552 dungeonLastBosses[lastEncounterDungeon] = dungeonEncounter;
6553 }
6554
6555 switch (creditType)
6556 {
6558 {
6559 CreatureTemplate const* creatureInfo = GetCreatureTemplate(creditEntry);
6560 if (!creatureInfo)
6561 {
6562 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid creature (entry {}) linked to the encounter {} ({}), skipped!", creditEntry, entry, dungeonEncounter->encounterName[0]);
6563 continue;
6564 }
6565 const_cast<CreatureTemplate*>(creatureInfo)->flags_extra |= CREATURE_FLAG_EXTRA_DUNGEON_BOSS;
6566 break;
6567 }
6569 {
6570 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(creditEntry);
6571 if (!spellInfo)
6572 {
6573 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid spell (entry {}) linked to the encounter {} ({}), skipped!", creditEntry, entry, dungeonEncounter->encounterName[0]);
6574 continue;
6575 }
6576 const_cast<SpellInfo*>(spellInfo)->AttributesCu |= SPELL_ATTR0_CU_ENCOUNTER_REWARD;
6577 break;
6578 }
6579 default:
6580 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid credit type ({}) for encounter {} ({}), skipped!", creditType, entry, dungeonEncounter->encounterName[0]);
6581 continue;
6582 }
6583
6584 DungeonEncounterList& encounters = _dungeonEncounterStore[MAKE_PAIR32(dungeonEncounter->mapId, dungeonEncounter->difficulty)];
6585 encounters.push_back(new DungeonEncounter(dungeonEncounter, EncounterCreditType(creditType), creditEntry, lastEncounterDungeon));
6586 ++count;
6587 } while (result->NextRow());
6588
6589 LOG_INFO("server.loading", ">> Loaded {} Instance Encounters in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6590 LOG_INFO("server.loading", " ");
6591}
@ CREATURE_FLAG_EXTRA_DUNGEON_BOSS
Definition CreatureData.h:73
DBCStorage< DungeonEncounterEntry > sDungeonEncounterStore(DungeonEncounterfmt)
#define sLFGMgr
Definition LFGMgr.h:658
EncounterCreditType
Definition Map.h:157
@ ENCOUNTER_CREDIT_KILL_CREATURE
Definition Map.h:158
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition Map.h:159
std::list< DungeonEncounter const * > DungeonEncounterList
Definition ObjectMgr.h:712
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition SpellInfo.h:207
Definition DBCStructure.h:866
Definition ObjectMgr.h:702

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 ( )
6458{
6459 uint32 oldMSTime = getMSTime();
6460
6461 // 0 1 2 4
6462 QueryResult result = WorldDatabase.Query("SELECT map, parent, script, allowMount FROM instance_template");
6463
6464 if (!result)
6465 {
6466 LOG_WARN("server.loading", ">> Loaded 0 instance templates. DB table `instance_template` is empty!");
6467 LOG_INFO("server.loading", " ");
6468 return;
6469 }
6470
6471 uint32 count = 0;
6472 do
6473 {
6474 Field* fields = result->Fetch();
6475
6476 uint16 mapID = fields[0].Get<uint16>();
6477
6478 if (!MapMgr::IsValidMAP(mapID, true))
6479 {
6480 LOG_ERROR("sql.sql", "ObjectMgr::LoadInstanceTemplate: bad mapid {} for template!", mapID);
6481 continue;
6482 }
6483
6484 InstanceTemplate instanceTemplate;
6485
6486 instanceTemplate.AllowMount = fields[3].Get<bool>();
6487 instanceTemplate.Parent = uint32(fields[1].Get<uint16>());
6488 instanceTemplate.ScriptId = GetScriptId(fields[2].Get<std::string>());
6489
6490 _instanceTemplateStore[mapID] = instanceTemplate;
6491
6492 ++count;
6493 } while (result->NextRow());
6494
6495 LOG_INFO("server.loading", ">> Loaded {} Instance Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6496 LOG_INFO("server.loading", " ");
6497}
static bool IsValidMAP(uint32 mapid, bool startUp)
Definition MapMgr.cpp:311
bool AllowMount
Definition Map.h:124
uint32 ScriptId
Definition Map.h:123

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

◆ LoadItemLocales()

void ObjectMgr::LoadItemLocales ( )
3170{
3171 uint32 oldMSTime = getMSTime();
3172
3173 _itemLocaleStore.clear(); // need for reload case
3174
3175 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Name, Description FROM item_template_locale");
3176 if (!result)
3177 return;
3178
3179 do
3180 {
3181 Field* fields = result->Fetch();
3182
3183 uint32 ID = fields[0].Get<uint32>();
3184
3185 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
3186 if (locale == LOCALE_enUS)
3187 continue;
3188
3189 ItemLocale& data = _itemLocaleStore[ID];
3190 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
3191 AddLocaleString(fields[3].Get<std::string>(), locale, data.Description);
3192 } while (result->NextRow());
3193
3194 LOG_INFO("server.loading", ">> Loaded {} Item Locale Strings in {} ms", (uint32)_itemLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
3195}
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 ( )
3844{
3845 uint32 oldMSTime = getMSTime();
3846
3847 _itemSetNameLocaleStore.clear(); // need for reload case
3848
3849 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Name FROM item_set_names_locale");
3850
3851 if (!result)
3852 return;
3853
3854 do
3855 {
3856 Field* fields = result->Fetch();
3857
3858 uint32 ID = fields[0].Get<uint32>();
3859
3860 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
3861 if (locale == LOCALE_enUS)
3862 continue;
3863
3865 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
3866 } while (result->NextRow());
3867
3868 LOG_INFO("server.loading", ">> Loaded {} Item Set Name Locale Strings in {} ms", uint32(_itemSetNameLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime));
3869}
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 ( )
3872{
3873 uint32 oldMSTime = getMSTime();
3874
3875 _itemSetNameStore.clear(); // needed for reload case
3876
3877 std::set<uint32> itemSetItems;
3878
3879 // fill item set member ids
3880 for (uint32 entryId = 0; entryId < sItemSetStore.GetNumRows(); ++entryId)
3881 {
3882 ItemSetEntry const* setEntry = sItemSetStore.LookupEntry(entryId);
3883 if (!setEntry)
3884 continue;
3885
3886 for (uint32 i = 0; i < MAX_ITEM_SET_ITEMS; ++i)
3887 if (setEntry->itemId[i])
3888 itemSetItems.insert(setEntry->itemId[i]);
3889 }
3890
3891 // 0 1 2
3892 QueryResult result = WorldDatabase.Query("SELECT `entry`, `name`, `InventoryType` FROM `item_set_names`");
3893
3894 if (!result)
3895 {
3896 LOG_WARN("server.loading", ">> Loaded 0 item set names. DB table `item_set_names` is empty.");
3897 LOG_INFO("server.loading", " ");
3898 return;
3899 }
3900
3901 _itemSetNameStore.rehash(result->GetRowCount());
3902 uint32 count = 0;
3903
3904 do
3905 {
3906 Field* fields = result->Fetch();
3907
3908 uint32 entry = fields[0].Get<uint32>();
3909 if (itemSetItems.find(entry) == itemSetItems.end())
3910 {
3911 LOG_ERROR("sql.sql", "Item set name (Entry: {}) not found in ItemSet.dbc, data useless.", entry);
3912 continue;
3913 }
3914
3915 ItemSetNameEntry& data = _itemSetNameStore[entry];
3916 data.name = fields[1].Get<std::string>();
3917
3918 uint32 invType = fields[2].Get<uint8>();
3919 if (invType >= MAX_INVTYPE)
3920 {
3921 LOG_ERROR("sql.sql", "Item set name (Entry: {}) has wrong InventoryType value ({})", entry, invType);
3922 invType = INVTYPE_NON_EQUIP;
3923 }
3924
3925 data.InventoryType = invType;
3926 itemSetItems.erase(entry);
3927 ++count;
3928 } while (result->NextRow());
3929
3930 if (!itemSetItems.empty())
3931 {
3932 ItemTemplate const* pProto;
3933 for (std::set<uint32>::iterator itr = itemSetItems.begin(); itr != itemSetItems.end(); ++itr)
3934 {
3935 uint32 entry = *itr;
3936 // add data from item_template if available
3937 pProto = GetItemTemplate(entry);
3938 if (pProto)
3939 {
3940 LOG_ERROR("sql.sql", "Item set part (Entry: {}) does not have entry in `item_set_names`, adding data from `item_template`.", entry);
3941 ItemSetNameEntry& data = _itemSetNameStore[entry];
3942 data.name = pProto->Name1;
3943 data.InventoryType = pProto->InventoryType;
3944 ++count;
3945 }
3946 else
3947 LOG_ERROR("sql.sql", "Item set part (Entry: {}) does not have entry in `item_set_names`, set will not display properly.", entry);
3948 }
3949 }
3950
3951 LOG_INFO("server.loading", ">> Loaded {} Item Set Names in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3952 LOG_INFO("server.loading", " ");
3953}
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 ( )
3222{
3223 uint32 oldMSTime = getMSTime();
3224
3225 // 0 1 2 3 4 5 6 7 8 9 10 11 12
3226 QueryResult result = WorldDatabase.Query("SELECT entry, class, subclass, SoundOverrideSubclass, name, displayid, Quality, Flags, FlagsExtra, BuyCount, BuyPrice, SellPrice, InventoryType, "
3227 // 13 14 15 16 17 18 19 20
3228 "AllowableClass, AllowableRace, ItemLevel, RequiredLevel, RequiredSkill, RequiredSkillRank, requiredspell, requiredhonorrank, "
3229 // 21 22 23 24 25 26 27
3230 "RequiredCityRank, RequiredReputationFaction, RequiredReputationRank, maxcount, stackable, ContainerSlots, stat_type1, "
3231 // 28 29 30 31 32 33 34 35 36 37
3232 "stat_value1, stat_type2, stat_value2, stat_type3, stat_value3, stat_type4, stat_value4, stat_type5, stat_value5, stat_type6, "
3233 // 38 39 40 41 42 43 44 45 46
3234 "stat_value6, stat_type7, stat_value7, stat_type8, stat_value8, stat_type9, stat_value9, stat_type10, stat_value10, "
3235 // 47 48 49 50 51 52 53 54 55 56 57
3236 "ScalingStatDistribution, ScalingStatValue, dmg_min1, dmg_max1, dmg_type1, dmg_min2, dmg_max2, dmg_type2, armor, holy_res, fire_res, "
3237 // 58 59 60 61 62 63 64 65 66 67
3238 "nature_res, frost_res, shadow_res, arcane_res, delay, ammo_type, RangedModRange, spellid_1, spelltrigger_1, spellcharges_1, "
3239 // 68 69 70 71 72 73 74
3240 "spellppmRate_1, spellcooldown_1, spellcategory_1, spellcategorycooldown_1, spellid_2, spelltrigger_2, spellcharges_2, "
3241 // 75 76 77 78 79 80 81
3242 "spellppmRate_2, spellcooldown_2, spellcategory_2, spellcategorycooldown_2, spellid_3, spelltrigger_3, spellcharges_3, "
3243 // 82 83 84 85 86 87 88
3244 "spellppmRate_3, spellcooldown_3, spellcategory_3, spellcategorycooldown_3, spellid_4, spelltrigger_4, spellcharges_4, "
3245 // 89 90 91 92 93 94 95
3246 "spellppmRate_4, spellcooldown_4, spellcategory_4, spellcategorycooldown_4, spellid_5, spelltrigger_5, spellcharges_5, "
3247 // 96 97 98 99 100 101 102 103 104
3248 "spellppmRate_5, spellcooldown_5, spellcategory_5, spellcategorycooldown_5, bonding, description, PageText, LanguageID, PageMaterial, "
3249 // 105 106 107 108 109 110 111 112 113 114 115 116
3250 "startquest, lockid, Material, sheath, RandomProperty, RandomSuffix, block, itemset, MaxDurability, area, Map, BagFamily, "
3251 // 117 118 119 120 121 122 123 124
3252 "TotemCategory, socketColor_1, socketContent_1, socketColor_2, socketContent_2, socketColor_3, socketContent_3, socketBonus, "
3253 // 125 126 127 128 129 130 131 132
3254 "GemProperties, RequiredDisenchantSkill, ArmorDamageModifier, duration, ItemLimitCategory, HolidayId, ScriptName, DisenchantID, "
3255 // 133 134 135 136
3256 "FoodType, minMoneyLoot, maxMoneyLoot, flagsCustom FROM item_template");
3257
3258 if (!result)
3259 {
3260 LOG_WARN("server.loading", ">> Loaded 0 item templates. DB table `item_template` is empty.");
3261 LOG_INFO("server.loading", " ");
3262 return;
3263 }
3264
3265 _itemTemplateStore.reserve(result->GetRowCount());
3266 uint32 count = 0;
3267 // original inspiration https://github.com/TrinityCore/TrinityCore/commit/0c44bd33ee7b42c924859139a9f4b04cf2b91261
3268 bool enforceDBCAttributes = sWorld->getBoolConfig(CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES);
3269
3270 do
3271 {
3272 Field* fields = result->Fetch();
3273
3274 uint32 entry = fields[0].Get<uint32>();
3275
3276 ItemTemplate& itemTemplate = _itemTemplateStore[entry];
3277
3278 itemTemplate.ItemId = entry;
3279 itemTemplate.Class = uint32(fields[1].Get<uint8>());
3280 itemTemplate.SubClass = uint32(fields[2].Get<uint8>());
3281 itemTemplate.SoundOverrideSubclass = int32(fields[3].Get<int8>());
3282 itemTemplate.Name1 = fields[4].Get<std::string>();
3283 itemTemplate.DisplayInfoID = fields[5].Get<uint32>();
3284 itemTemplate.Quality = uint32(fields[6].Get<uint8>());
3285 itemTemplate.Flags = ItemFlags(fields[7].Get<uint32>());
3286 itemTemplate.Flags2 = ItemFlags2(fields[8].Get<uint32>());
3287 itemTemplate.BuyCount = uint32(fields[9].Get<uint8>());
3288 itemTemplate.BuyPrice = int32(fields[10].Get<int64>());
3289 itemTemplate.SellPrice = uint32(fields[11].Get<uint32>());
3290 itemTemplate.InventoryType = uint32(fields[12].Get<uint8>());
3291 itemTemplate.AllowableClass = fields[13].Get<int32>();
3292 itemTemplate.AllowableRace = fields[14].Get<int32>();
3293 itemTemplate.ItemLevel = uint32(fields[15].Get<uint16>());
3294 itemTemplate.RequiredLevel = uint32(fields[16].Get<uint8>());
3295 itemTemplate.RequiredSkill = uint32(fields[17].Get<uint16>());
3296 itemTemplate.RequiredSkillRank = uint32(fields[18].Get<uint16>());
3297 itemTemplate.RequiredSpell = fields[19].Get<uint32>();
3298 itemTemplate.RequiredHonorRank = fields[20].Get<uint32>();
3299 itemTemplate.RequiredCityRank = fields[21].Get<uint32>();
3300 itemTemplate.RequiredReputationFaction = uint32(fields[22].Get<uint16>());
3301 itemTemplate.RequiredReputationRank = uint32(fields[23].Get<uint16>());
3302 itemTemplate.MaxCount = fields[24].Get<int32>();
3303 itemTemplate.Stackable = fields[25].Get<int32>();
3304 itemTemplate.ContainerSlots = uint32(fields[26].Get<uint8>());
3305
3306 uint8 statsCount = 0;
3307 while (statsCount < MAX_ITEM_PROTO_STATS)
3308 {
3309 uint32 statType = uint32(fields[27 + statsCount * 2].Get<uint8>());
3310 int32 statValue = fields[28 + statsCount * 2].Get<int32>();
3311 if (statType == 0)
3312 break;
3313
3314 itemTemplate.ItemStat[statsCount].ItemStatType = statType;
3315 itemTemplate.ItemStat[statsCount].ItemStatValue = statValue;
3316 statsCount++;
3317 }
3318 itemTemplate.StatsCount = statsCount;
3319
3320 itemTemplate.ScalingStatDistribution = uint32(fields[47].Get<uint16>());
3321 itemTemplate.ScalingStatValue = fields[48].Get<int32>();
3322
3323 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
3324 {
3325 itemTemplate.Damage[i].DamageMin = fields[49 + i * 3].Get<float>();
3326 itemTemplate.Damage[i].DamageMax = fields[50 + i * 3].Get<float>();
3327 itemTemplate.Damage[i].DamageType = uint32(fields[51 + i * 3].Get<uint8>());
3328 }
3329
3330 itemTemplate.Armor = fields[55].Get<uint32>();
3331 itemTemplate.HolyRes = fields[56].Get<int32>();
3332 itemTemplate.FireRes = fields[57].Get<int32>();
3333 itemTemplate.NatureRes = fields[58].Get<int32>();
3334 itemTemplate.FrostRes = fields[59].Get<int32>();
3335 itemTemplate.ShadowRes = fields[60].Get<int32>();
3336 itemTemplate.ArcaneRes = fields[61].Get<int32>();
3337 itemTemplate.Delay = uint32(fields[62].Get<uint16>());
3338 itemTemplate.AmmoType = uint32(fields[63].Get<uint8>());
3339 itemTemplate.RangedModRange = fields[64].Get<float>();
3340
3341 for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
3342 {
3343 itemTemplate.Spells[i].SpellId = fields[65 + i * 7 ].Get<int32>();
3344 itemTemplate.Spells[i].SpellTrigger = uint32(fields[66 + i * 7].Get<uint8>());
3345 itemTemplate.Spells[i].SpellCharges = int32(fields[67 + i * 7].Get<int16>());
3346 itemTemplate.Spells[i].SpellPPMRate = fields[68 + i * 7].Get<float>();
3347 itemTemplate.Spells[i].SpellCooldown = fields[69 + i * 7].Get<int32>();
3348 itemTemplate.Spells[i].SpellCategory = uint32(fields[70 + i * 7].Get<uint16>());
3349 itemTemplate.Spells[i].SpellCategoryCooldown = fields[71 + i * 7].Get<int32>();
3350 }
3351
3352 itemTemplate.Bonding = uint32(fields[100].Get<uint8>());
3353 itemTemplate.Description = fields[101].Get<std::string>();
3354 itemTemplate.PageText = fields[102].Get<uint32>();
3355 itemTemplate.LanguageID = uint32(fields[103].Get<uint8>());
3356 itemTemplate.PageMaterial = uint32(fields[104].Get<uint8>());
3357 itemTemplate.StartQuest = fields[105].Get<uint32>();
3358 itemTemplate.LockID = fields[106].Get<uint32>();
3359 itemTemplate.Material = int32(fields[107].Get<int8>());
3360 itemTemplate.Sheath = uint32(fields[108].Get<uint8>());
3361 itemTemplate.RandomProperty = fields[109].Get<int32>();
3362 itemTemplate.RandomSuffix = fields[110].Get<int32>();
3363 itemTemplate.Block = fields[111].Get<uint32>();
3364 itemTemplate.ItemSet = fields[112].Get<uint32>();
3365 itemTemplate.MaxDurability = uint32(fields[113].Get<uint16>());
3366 itemTemplate.Area = fields[114].Get<uint32>();
3367 itemTemplate.Map = uint32(fields[115].Get<uint16>());
3368 itemTemplate.BagFamily = fields[116].Get<uint32>();
3369 itemTemplate.TotemCategory = fields[117].Get<uint32>();
3370
3371 for (uint8 i = 0; i < MAX_ITEM_PROTO_SOCKETS; ++i)
3372 {
3373 itemTemplate.Socket[i].Color = uint32(fields[118 + i * 2].Get<uint8>());
3374 itemTemplate.Socket[i].Content = fields[119 + i * 2].Get<uint32>();
3375 }
3376
3377 itemTemplate.socketBonus = fields[124].Get<uint32>();
3378 itemTemplate.GemProperties = fields[125].Get<uint32>();
3379 itemTemplate.RequiredDisenchantSkill = uint32(fields[126].Get<int16>());
3380 itemTemplate.ArmorDamageModifier = fields[127].Get<float>();
3381 itemTemplate.Duration = fields[128].Get<uint32>();
3382 itemTemplate.ItemLimitCategory = uint32(fields[129].Get<int16>());
3383 itemTemplate.HolidayId = fields[130].Get<uint32>();
3384 itemTemplate.ScriptId = GetScriptId(fields[131].Get<std::string>());
3385 itemTemplate.DisenchantID = fields[132].Get<uint32>();
3386 itemTemplate.FoodType = uint32(fields[133].Get<uint8>());
3387 itemTemplate.MinMoneyLoot = fields[134].Get<uint32>();
3388 itemTemplate.MaxMoneyLoot = fields[135].Get<uint32>();
3389 itemTemplate.FlagsCu = ItemFlagsCustom(fields[136].Get<uint32>());
3390
3391 // Checks
3392 ItemEntry const* dbcitem = sItemStore.LookupEntry(entry);
3393
3394 if (!dbcitem)
3395 {
3396 LOG_DEBUG("sql.sql", "Item (Entry: {}) does not exist in item.dbc! (not correct id?).", entry);
3397 continue;
3398 }
3399
3400 if (enforceDBCAttributes)
3401 {
3402 if (itemTemplate.Class != dbcitem->ClassID)
3403 {
3404 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Class value ({}), must be ({}).", entry, itemTemplate.Class, dbcitem->ClassID);
3405 itemTemplate.Class = dbcitem->ClassID;
3406 }
3407 if (itemTemplate.SubClass != dbcitem->SubclassID)
3408 {
3409 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Subclass value ({}) for class {}, must be ({}).", entry, itemTemplate.SubClass, itemTemplate.Class, dbcitem->SubclassID);
3410 itemTemplate.SubClass = dbcitem->SubclassID;
3411 }
3412 if (itemTemplate.SoundOverrideSubclass != dbcitem->SoundOverrideSubclassID)
3413 {
3414 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct SoundOverrideSubclass ({}), must be {}.", entry, itemTemplate.SoundOverrideSubclass, dbcitem->SoundOverrideSubclassID);
3415 itemTemplate.SoundOverrideSubclass = dbcitem->SoundOverrideSubclassID;
3416 }
3417 if (itemTemplate.Material != dbcitem->Material)
3418 {
3419 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct material ({}), must be {}.", entry, itemTemplate.Material, dbcitem->Material);
3420 itemTemplate.Material = dbcitem->Material;
3421 }
3422 if (itemTemplate.InventoryType != dbcitem->InventoryType)
3423 {
3424 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong InventoryType value ({}), must be {}.", entry, itemTemplate.InventoryType, dbcitem->InventoryType);
3425 itemTemplate.InventoryType = dbcitem->InventoryType;
3426 }
3427 if (itemTemplate.DisplayInfoID != dbcitem->DisplayInfoID)
3428 {
3429 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct display id ({}), must be {}.", entry, itemTemplate.DisplayInfoID, dbcitem->DisplayInfoID);
3430 itemTemplate.DisplayInfoID = dbcitem->DisplayInfoID;
3431 }
3432 if (itemTemplate.Sheath != dbcitem->SheatheType)
3433 {
3434 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Sheath ({}), must be {}.", entry, itemTemplate.Sheath, dbcitem->SheatheType);
3435 itemTemplate.Sheath = dbcitem->SheatheType;
3436 }
3437 }
3438
3439 if (itemTemplate.Quality >= MAX_ITEM_QUALITY)
3440 {
3441 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Quality value ({})", entry, itemTemplate.Quality);
3442 itemTemplate.Quality = ITEM_QUALITY_NORMAL;
3443 }
3444
3445 if (itemTemplate.HasFlag2(ITEM_FLAG2_FACTION_HORDE))
3446 {
3447 if (FactionEntry const* faction = sFactionStore.LookupEntry(HORDE))
3448 if ((itemTemplate.AllowableRace & faction->BaseRepRaceMask[0]) == 0)
3449 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.",
3450 entry, itemTemplate.AllowableRace, ITEM_FLAG2_FACTION_HORDE);
3451
3452 if (itemTemplate.HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE))
3453 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.",
3455 }
3456 else if (itemTemplate.HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE))
3457 {
3458 if (FactionEntry const* faction = sFactionStore.LookupEntry(ALLIANCE))
3459 if ((itemTemplate.AllowableRace & faction->BaseRepRaceMask[0]) == 0)
3460 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.",
3461 entry, itemTemplate.AllowableRace, ITEM_FLAG2_FACTION_ALLIANCE);
3462 }
3463
3464 if (itemTemplate.BuyCount <= 0)
3465 {
3466 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong BuyCount value ({}), set to default(1).", entry, itemTemplate.BuyCount);
3467 itemTemplate.BuyCount = 1;
3468 }
3469
3470 if (itemTemplate.RequiredSkill >= MAX_SKILL_TYPE)
3471 {
3472 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong RequiredSkill value ({})", entry, itemTemplate.RequiredSkill);
3473 itemTemplate.RequiredSkill = 0;
3474 }
3475
3476 {
3477 // can be used in equip slot, as page read use in inventory, or spell casting at use
3478 bool req = itemTemplate.InventoryType != INVTYPE_NON_EQUIP || itemTemplate.PageText;
3479 if (!req)
3480 for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
3481 {
3482 if (itemTemplate.Spells[j].SpellId)
3483 {
3484 req = true;
3485 break;
3486 }
3487 }
3488
3489 if (req)
3490 {
3491 if (!(itemTemplate.AllowableClass & CLASSMASK_ALL_PLAYABLE))
3492 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have any playable classes ({}) in `AllowableClass` and can't be equipped or used.", entry, itemTemplate.AllowableClass);
3493
3494 if (!(itemTemplate.AllowableRace & sRaceMgr->GetPlayableRaceMask()))
3495 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have any playable races ({}) in `AllowableRace` and can't be equipped or used.", entry, itemTemplate.AllowableRace);
3496 }
3497 }
3498
3499 if (itemTemplate.RequiredSpell && !sSpellMgr->GetSpellInfo(itemTemplate.RequiredSpell))
3500 {
3501 LOG_ERROR("sql.sql", "Item (Entry: {}) has a wrong (non-existing) spell in RequiredSpell ({})", entry, itemTemplate.RequiredSpell);
3502 itemTemplate.RequiredSpell = 0;
3503 }
3504
3505 if (itemTemplate.RequiredReputationRank >= MAX_REPUTATION_RANK)
3506 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong reputation rank in RequiredReputationRank ({}), item can't be used.", entry, itemTemplate.RequiredReputationRank);
3507
3508 if (itemTemplate.RequiredReputationFaction)
3509 {
3510 if (!sFactionStore.LookupEntry(itemTemplate.RequiredReputationFaction))
3511 {
3512 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (not existing) faction in RequiredReputationFaction ({})", entry, itemTemplate.RequiredReputationFaction);
3513 itemTemplate.RequiredReputationFaction = 0;
3514 }
3515
3516 if (itemTemplate.RequiredReputationRank == MIN_REPUTATION_RANK)
3517 LOG_ERROR("sql.sql", "Item (Entry: {}) has min. reputation rank in RequiredReputationRank (0) but RequiredReputationFaction > 0, faction setting is useless.", entry);
3518 }
3519
3520 if (itemTemplate.MaxCount < -1)
3521 {
3522 LOG_ERROR("sql.sql", "Item (Entry: {}) has too large negative in maxcount ({}), replace by value (-1) no storing limits.", entry, itemTemplate.MaxCount);
3523 itemTemplate.MaxCount = -1;
3524 }
3525
3526 if (itemTemplate.Stackable == 0)
3527 {
3528 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong value in stackable ({}), replace by default 1.", entry, itemTemplate.Stackable);
3529 itemTemplate.Stackable = 1;
3530 }
3531 else if (itemTemplate.Stackable < -1)
3532 {
3533 LOG_ERROR("sql.sql", "Item (Entry: {}) has too large negative in stackable ({}), replace by value (-1) no stacking limits.", entry, itemTemplate.Stackable);
3534 itemTemplate.Stackable = -1;
3535 }
3536
3537 if (itemTemplate.ContainerSlots > MAX_BAG_SIZE)
3538 {
3539 LOG_ERROR("sql.sql", "Item (Entry: {}) has too large value in ContainerSlots ({}), replace by hardcoded limit ({}).", entry, itemTemplate.ContainerSlots, MAX_BAG_SIZE);
3540 itemTemplate.ContainerSlots = MAX_BAG_SIZE;
3541 }
3542
3543 for (uint8 j = 0; j < itemTemplate.StatsCount; ++j)
3544 {
3545 // for ItemStatValue != 0
3546 if (itemTemplate.ItemStat[j].ItemStatValue && itemTemplate.ItemStat[j].ItemStatType >= MAX_ITEM_MOD)
3547 {
3548 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (non-existing?) stat_type{} ({})", entry, j + 1, itemTemplate.ItemStat[j].ItemStatType);
3549 itemTemplate.ItemStat[j].ItemStatType = 0;
3550 }
3551
3552 switch (itemTemplate.ItemStat[j].ItemStatType)
3553 {
3556 // Skip warning for specific items: 13113 (Feathermoon Headdress - Blizzard oversight), 34967 (test item)
3557 if (entry != 13113 && entry != 34967)
3558 LOG_WARN("sql.sql", "Item (Entry: {}) has deprecated stat_type{} ({})", entry, j + 1, itemTemplate.ItemStat[j].ItemStatType);
3559
3560 break;
3561 default:
3562 break;
3563 }
3564 }
3565
3566 for (uint8 j = 0; j < MAX_ITEM_PROTO_DAMAGES; ++j)
3567 {
3568 if (itemTemplate.Damage[j].DamageType >= MAX_SPELL_SCHOOL)
3569 {
3570 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong dmg_type{} ({})", entry, j + 1, itemTemplate.Damage[j].DamageType);
3571 itemTemplate.Damage[j].DamageType = 0;
3572 }
3573 }
3574
3575 // special format
3576 if ((itemTemplate.Spells[0].SpellId == 483) || (itemTemplate.Spells[0].SpellId == 55884))
3577 {
3578 // spell_1
3579 if (itemTemplate.Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
3580 {
3581 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);
3582 itemTemplate.Spells[0].SpellId = 0;
3583 itemTemplate.Spells[0].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3584 itemTemplate.Spells[1].SpellId = 0;
3585 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3586 }
3587
3588 // spell_2 have learning spell
3589 if (itemTemplate.Spells[1].SpellTrigger != ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
3590 {
3591 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);
3592 itemTemplate.Spells[0].SpellId = 0;
3593 itemTemplate.Spells[1].SpellId = 0;
3594 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3595 }
3596 else if (!itemTemplate.Spells[1].SpellId)
3597 {
3598 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have an expected spell in spellid_{} in special learning format.", entry, 1 + 1);
3599 itemTemplate.Spells[0].SpellId = 0;
3600 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3601 }
3602 else if (itemTemplate.Spells[1].SpellId != -1)
3603 {
3604 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemTemplate.Spells[1].SpellId);
3605 if (!spellInfo && !sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, itemTemplate.Spells[1].SpellId, nullptr))
3606 {
3607 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (not existing) spell in spellid_{} ({})", entry, 1 + 1, itemTemplate.Spells[1].SpellId);
3608 itemTemplate.Spells[0].SpellId = 0;
3609 itemTemplate.Spells[1].SpellId = 0;
3610 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3611 }
3612 // allowed only in special format
3613 else if ((itemTemplate.Spells[1].SpellId == 483) || (itemTemplate.Spells[1].SpellId == 55884))
3614 {
3615 LOG_ERROR("sql.sql", "Item (Entry: {}) has broken spell in spellid_{} ({})", entry, 1 + 1, itemTemplate.Spells[1].SpellId);
3616 itemTemplate.Spells[0].SpellId = 0;
3617 itemTemplate.Spells[1].SpellId = 0;
3618 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3619 }
3620 }
3621
3622 // spell_3*, spell_4*, spell_5* is empty
3623 for (uint8 j = 2; j < MAX_ITEM_PROTO_SPELLS; ++j)
3624 {
3625 if (itemTemplate.Spells[j].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
3626 {
3627 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong item spell trigger value in spelltrigger_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellTrigger);
3628 itemTemplate.Spells[j].SpellId = 0;
3629 itemTemplate.Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3630 }
3631 else if (itemTemplate.Spells[j].SpellId != 0)
3632 {
3633 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong spell in spellid_{} ({}) for learning special format", entry, j + 1, itemTemplate.Spells[j].SpellId);
3634 itemTemplate.Spells[j].SpellId = 0;
3635 }
3636 }
3637 }
3638 // normal spell list
3639 else
3640 {
3641 for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
3642 {
3643 if (itemTemplate.Spells[j].SpellTrigger >= MAX_ITEM_SPELLTRIGGER || itemTemplate.Spells[j].SpellTrigger == ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
3644 {
3645 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong item spell trigger value in spelltrigger_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellTrigger);
3646 itemTemplate.Spells[j].SpellId = 0;
3647 itemTemplate.Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3648 }
3649
3650 if (itemTemplate.Spells[j].SpellId && itemTemplate.Spells[j].SpellId != -1)
3651 {
3652 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemTemplate.Spells[j].SpellId);
3653 if (!spellInfo && !sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, itemTemplate.Spells[j].SpellId, nullptr))
3654 {
3655 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (not existing) spell in spellid_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellId);
3656 itemTemplate.Spells[j].SpellId = 0;
3657 }
3658 // allowed only in special format
3659 else if ((itemTemplate.Spells[j].SpellId == 483) || (itemTemplate.Spells[j].SpellId == 55884))
3660 {
3661 LOG_ERROR("sql.sql", "Item (Entry: {}) has broken spell in spellid_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellId);
3662 itemTemplate.Spells[j].SpellId = 0;
3663 }
3664 }
3665 }
3666 }
3667
3668 if (itemTemplate.Bonding >= MAX_BIND_TYPE)
3669 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Bonding value ({})", entry, itemTemplate.Bonding);
3670
3671 if (itemTemplate.PageText && !GetPageText(itemTemplate.PageText))
3672 LOG_ERROR("sql.sql", "Item (Entry: {}) has non existing first page (Id:{})", entry, itemTemplate.PageText);
3673
3674 if (itemTemplate.LockID && !sLockStore.LookupEntry(itemTemplate.LockID))
3675 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong LockID ({})", entry, itemTemplate.LockID);
3676
3677 if (itemTemplate.RandomProperty)
3678 {
3679 // To be implemented later
3680 if (itemTemplate.RandomProperty == -1)
3681 itemTemplate.RandomProperty = 0;
3682
3683 else if (!sItemRandomPropertiesStore.LookupEntry(GetItemEnchantMod(itemTemplate.RandomProperty)))
3684 {
3685 LOG_ERROR("sql.sql", "Item (Entry: {}) has unknown (wrong or not listed in `item_enchantment_template`) RandomProperty ({})", entry, itemTemplate.RandomProperty);
3686 itemTemplate.RandomProperty = 0;
3687 }
3688 }
3689
3690 if (itemTemplate.RandomSuffix && !sItemRandomSuffixStore.LookupEntry(GetItemEnchantMod(itemTemplate.RandomSuffix)))
3691 {
3692 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong RandomSuffix ({})", entry, itemTemplate.RandomSuffix);
3693 itemTemplate.RandomSuffix = 0;
3694 }
3695
3696 if (itemTemplate.ItemSet && !sItemSetStore.LookupEntry(itemTemplate.ItemSet))
3697 {
3698 LOG_ERROR("sql.sql", "Item (Entry: {}) have wrong ItemSet ({})", entry, itemTemplate.ItemSet);
3699 itemTemplate.ItemSet = 0;
3700 }
3701
3702 if (itemTemplate.Area && !sAreaTableStore.LookupEntry(itemTemplate.Area))
3703 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Area ({})", entry, itemTemplate.Area);
3704
3705 if (itemTemplate.Map && !sMapStore.LookupEntry(itemTemplate.Map))
3706 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Map ({})", entry, itemTemplate.Map);
3707
3708 if (itemTemplate.BagFamily)
3709 {
3710 // check bits
3711 for (uint32 j = 0; j < sizeof(itemTemplate.BagFamily) * 8; ++j)
3712 {
3713 uint32 mask = 1 << j;
3714 if ((itemTemplate.BagFamily & mask) == 0)
3715 continue;
3716
3717 ItemBagFamilyEntry const* bf = sItemBagFamilyStore.LookupEntry(j + 1);
3718 if (!bf)
3719 {
3720 LOG_ERROR("sql.sql", "Item (Entry: {}) has bag family bit set not listed in ItemBagFamily.dbc, remove bit", entry);
3721 itemTemplate.BagFamily &= ~mask;
3722 continue;
3723 }
3724
3726 {
3727 CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemTemplate.ItemId);
3728 if (!ctEntry)
3729 {
3730 LOG_ERROR("sql.sql", "Item (Entry: {}) has currency bag family bit set in BagFamily but not listed in CurrencyTypes.dbc, remove bit", entry);
3731 itemTemplate.BagFamily &= ~mask;
3732 }
3733 }
3734 }
3735 }
3736
3737 if (itemTemplate.TotemCategory && !sTotemCategoryStore.LookupEntry(itemTemplate.TotemCategory))
3738 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong TotemCategory ({})", entry, itemTemplate.TotemCategory);
3739
3740 for (uint8 j = 0; j < MAX_ITEM_PROTO_SOCKETS; ++j)
3741 {
3742 if (itemTemplate.Socket[j].Color && (itemTemplate.Socket[j].Color & SOCKET_COLOR_ALL) != itemTemplate.Socket[j].Color)
3743 {
3744 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong socketColor_{} ({})", entry, j + 1, itemTemplate.Socket[j].Color);
3745 itemTemplate.Socket[j].Color = 0;
3746 }
3747 }
3748
3749 if (itemTemplate.GemProperties && !sGemPropertiesStore.LookupEntry(itemTemplate.GemProperties))
3750 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong GemProperties ({})", entry, itemTemplate.GemProperties);
3751
3752 if (itemTemplate.FoodType >= MAX_PET_DIET)
3753 {
3754 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong FoodType value ({})", entry, itemTemplate.FoodType);
3755 itemTemplate.FoodType = 0;
3756 }
3757
3758 if (itemTemplate.ItemLimitCategory && !sItemLimitCategoryStore.LookupEntry(itemTemplate.ItemLimitCategory))
3759 {
3760 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong LimitCategory value ({})", entry, itemTemplate.ItemLimitCategory);
3761 itemTemplate.ItemLimitCategory = 0;
3762 }
3763
3764 if (itemTemplate.HolidayId && !sHolidaysStore.LookupEntry(itemTemplate.HolidayId))
3765 {
3766 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong HolidayId value ({})", entry, itemTemplate.HolidayId);
3767 itemTemplate.HolidayId = 0;
3768 }
3769
3770 if (itemTemplate.HasFlagCu(ITEM_FLAGS_CU_DURATION_REAL_TIME) && !itemTemplate.Duration)
3771 {
3772 LOG_ERROR("sql.sql", "Item (Entry {}) has flag ITEM_FLAGS_CU_DURATION_REAL_TIME but it does not have duration limit", entry);
3773 itemTemplate.FlagsCu = static_cast<ItemFlagsCustom>(static_cast<uint32>(itemTemplate.FlagsCu) & ~ITEM_FLAGS_CU_DURATION_REAL_TIME);
3774 }
3775
3776 // Set after checks to ensure valid item quality
3777 itemTemplate.BuyPrice *= sWorld->getRate(qualityToBuyValueConfig[itemTemplate.Quality]);
3778 itemTemplate.SellPrice *= sWorld->getRate(qualityToSellValueConfig[itemTemplate.Quality]);
3779
3780 // Fill categories map
3781 for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
3782 if (itemTemplate.Spells[i].SpellId && itemTemplate.Spells[i].SpellCategory && itemTemplate.Spells[i].SpellCategoryCooldown)
3783 {
3784 SpellCategoryStore::iterator ct = sSpellsByCategoryStore.find(itemTemplate.Spells[i].SpellCategory);
3785 if (ct != sSpellsByCategoryStore.end())
3786 {
3787 ct->second.emplace(true, itemTemplate.Spells[i].SpellId);
3788 }
3789 else
3790 sSpellsByCategoryStore[itemTemplate.Spells[i].SpellCategory].emplace(true, itemTemplate.Spells[i].SpellId);
3791 }
3792
3793 ++count;
3794 } while (result->NextRow());
3795
3796 // pussywizard:
3797 {
3798 uint32 max = 0;
3799 for (ItemTemplateContainer::const_iterator itr = _itemTemplateStore.begin(); itr != _itemTemplateStore.end(); ++itr)
3800 if (itr->first > max)
3801 max = itr->first;
3802 if (max)
3803 {
3804 _itemTemplateStoreFast.clear();
3805 _itemTemplateStoreFast.resize(max + 1, nullptr);
3806 for (ItemTemplateContainer::iterator itr = _itemTemplateStore.begin(); itr != _itemTemplateStore.end(); ++itr)
3807 _itemTemplateStoreFast[itr->first] = &(itr->second);
3808 }
3809 }
3810
3811 // Check if item templates for DBC referenced character start outfit are present
3812 std::set<uint32> notFoundOutfit;
3813 for (uint32 i = 1; i < sCharStartOutfitStore.GetNumRows(); ++i)
3814 {
3815 CharStartOutfitEntry const* entry = sCharStartOutfitStore.LookupEntry(i);
3816 if (!entry)
3817 continue;
3818
3819 for (int j = 0; j < MAX_OUTFIT_ITEMS; ++j)
3820 {
3821 if (entry->ItemId[j] <= 0)
3822 continue;
3823
3824 uint32 item_id = entry->ItemId[j];
3825
3826 if (!GetItemTemplate(item_id))
3827 notFoundOutfit.insert(item_id);
3828 }
3829 }
3830
3831 for (std::set<uint32>::const_iterator itr = notFoundOutfit.begin(); itr != notFoundOutfit.end(); ++itr)
3832 LOG_ERROR("sql.sql", "Item (Entry: {}) does not exist in `item_template` but is referenced in `CharStartOutfit.dbc`", *itr);
3833
3834 LOG_INFO("server.loading", ">> Loaded {} Item Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3835 LOG_INFO("server.loading", " ");
3836}
#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:3209
ServerConfigs const qualityToBuyValueConfig[MAX_ITEM_QUALITY]
Definition ObjectMgr.cpp:3197
#define MAX_REPUTATION_RANK
Definition SharedDefines.h:233
#define MIN_REPUTATION_RANK
Definition SharedDefines.h:232
#define MAX_PET_DIET
Definition SharedDefines.h:3448
@ ITEM_QUALITY_NORMAL
Definition SharedDefines.h:318
#define MAX_ITEM_QUALITY
Definition SharedDefines.h:327
#define MAX_SKILL_TYPE
Definition SharedDefines.h:3235
@ 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 ( )
1909{
1910 uint32 oldMSTime = getMSTime();
1911
1912 _linkedRespawnStore.clear();
1913 // 0 1 2
1914 QueryResult result = WorldDatabase.Query("SELECT guid, linkedGuid, linkType FROM linked_respawn ORDER BY guid ASC");
1915
1916 if (!result)
1917 {
1918 LOG_WARN("server.loading", ">> Loaded 0 linked respawns. DB table `linked_respawn` is empty.");
1919 LOG_INFO("server.loading", " ");
1920 return;
1921 }
1922
1923 do
1924 {
1925 Field* fields = result->Fetch();
1926
1927 ObjectGuid::LowType guidLow = fields[0].Get<uint32>();
1928 ObjectGuid::LowType linkedGuidLow = fields[1].Get<uint32>();
1929 uint8 linkType = fields[2].Get<uint8>();
1930
1931 ObjectGuid guid, linkedGuid;
1932 bool error = false;
1933 switch (linkType)
1934 {
1936 {
1937 const CreatureData* slave = GetCreatureData(guidLow);
1938 if (!slave)
1939 {
1940 LOG_ERROR("sql.sql", "LinkedRespawn: Creature (guid) {} not found in creature table", guidLow);
1941 error = true;
1942 break;
1943 }
1944
1945 const CreatureData* master = GetCreatureData(linkedGuidLow);
1946 if (!master)
1947 {
1948 LOG_ERROR("sql.sql", "LinkedRespawn: Creature (linkedGuid) {} not found in creature table", linkedGuidLow);
1949 error = true;
1950 break;
1951 }
1952
1953 MapEntry const* const map = sMapStore.LookupEntry(master->mapid);
1954 if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
1955 {
1956 LOG_ERROR("sql.sql", "LinkedRespawn: Creature '{}' linking to Creature '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1957 error = true;
1958 break;
1959 }
1960
1961 if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
1962 {
1963 LOG_ERROR("sql.sql", "LinkedRespawn: Creature '{}' linking to Creature '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1964 error = true;
1965 break;
1966 }
1967
1968 guid = ObjectGuid::Create<HighGuid::Unit>(slave->id1, guidLow);
1969 linkedGuid = ObjectGuid::Create<HighGuid::Unit>(master->id1, linkedGuidLow);
1970 break;
1971 }
1972 case CREATURE_TO_GO:
1973 {
1974 const CreatureData* slave = GetCreatureData(guidLow);
1975 if (!slave)
1976 {
1977 LOG_ERROR("sql.sql", "LinkedRespawn: Creature (guid) {} not found in creature table", guidLow);
1978 error = true;
1979 break;
1980 }
1981
1982 const GameObjectData* master = GetGameObjectData(linkedGuidLow);
1983 if (!master)
1984 {
1985 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (linkedGuid) {} not found in gameobject table", linkedGuidLow);
1986 error = true;
1987 break;
1988 }
1989
1990 MapEntry const* const map = sMapStore.LookupEntry(master->mapid);
1991 if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
1992 {
1993 LOG_ERROR("sql.sql", "LinkedRespawn: Creature '{}' linking to Gameobject '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1994 error = true;
1995 break;
1996 }
1997
1998 if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
1999 {
2000 LOG_ERROR("sql.sql", "LinkedRespawn: Creature '{}' linking to Gameobject '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
2001 error = true;
2002 break;
2003 }
2004
2005 guid = ObjectGuid::Create<HighGuid::Unit>(slave->id1, guidLow);
2006 linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->id, linkedGuidLow);
2007 break;
2008 }
2009 case GO_TO_GO:
2010 {
2011 const GameObjectData* slave = GetGameObjectData(guidLow);
2012 if (!slave)
2013 {
2014 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (guid) {} not found in gameobject table", guidLow);
2015 error = true;
2016 break;
2017 }
2018
2019 const GameObjectData* master = GetGameObjectData(linkedGuidLow);
2020 if (!master)
2021 {
2022 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (linkedGuid) {} not found in gameobject table", linkedGuidLow);
2023 error = true;
2024 break;
2025 }
2026
2027 MapEntry const* const map = sMapStore.LookupEntry(master->mapid);
2028 if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
2029 {
2030 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '{}' linking to Gameobject '{}' on an unpermitted map.", guidLow, linkedGuidLow);
2031 error = true;
2032 break;
2033 }
2034
2035 if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
2036 {
2037 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '{}' linking to Gameobject '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
2038 error = true;
2039 break;
2040 }
2041
2042 guid = ObjectGuid::Create<HighGuid::GameObject>(slave->id, guidLow);
2043 linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->id, linkedGuidLow);
2044 break;
2045 }
2046 case GO_TO_CREATURE:
2047 {
2048 const GameObjectData* slave = GetGameObjectData(guidLow);
2049 if (!slave)
2050 {
2051 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (guid) {} not found in gameobject table", guidLow);
2052 error = true;
2053 break;
2054 }
2055
2056 const CreatureData* master = GetCreatureData(linkedGuidLow);
2057 if (!master)
2058 {
2059 LOG_ERROR("sql.sql", "LinkedRespawn: Creature (linkedGuid) {} not found in creature table", linkedGuidLow);
2060 error = true;
2061 break;
2062 }
2063
2064 MapEntry const* const map = sMapStore.LookupEntry(master->mapid);
2065 if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
2066 {
2067 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '{}' linking to Creature '{}' on an unpermitted map.", guidLow, linkedGuidLow);
2068 error = true;
2069 break;
2070 }
2071
2072 if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
2073 {
2074 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '{}' linking to Creature '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
2075 error = true;
2076 break;
2077 }
2078
2079 guid = ObjectGuid::Create<HighGuid::GameObject>(slave->id, guidLow);
2080 linkedGuid = ObjectGuid::Create<HighGuid::Unit>(master->id1, linkedGuidLow);
2081 break;
2082 }
2083 }
2084
2085 if (!error)
2086 _linkedRespawnStore[guid] = linkedGuid;
2087 } while (result->NextRow());
2088
2089 LOG_INFO("server.loading", ">> Loaded {} Linked Respawns In {} ms", uint64(_linkedRespawnStore.size()), GetMSTimeDiffToNow(oldMSTime));
2090 LOG_INFO("server.loading", " ");
2091}
Definition ObjectGuid.h:118
bool Instanceable() const
Definition DBCStructure.h:1353

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

◆ LoadMailLevelRewards()

void ObjectMgr::LoadMailLevelRewards ( )
9657{
9658 uint32 oldMSTime = getMSTime();
9659
9660 _mailLevelRewardStore.clear(); // for reload case
9661
9662 // 0 1 2 3
9663 QueryResult result = WorldDatabase.Query("SELECT level, raceMask, mailTemplateId, senderEntry FROM mail_level_reward");
9664
9665 if (!result)
9666 {
9667 LOG_WARN("server.loading", ">> Loaded 0 level dependent mail rewards. DB table `mail_level_reward` is empty.");
9668 LOG_INFO("server.loading", " ");
9669 return;
9670 }
9671
9672 uint32 count = 0;
9673
9674 do
9675 {
9676 Field* fields = result->Fetch();
9677
9678 uint8 level = fields[0].Get<uint8>();
9679 uint32 raceMask = fields[1].Get<uint32>();
9680 uint32 mailTemplateId = fields[2].Get<uint32>();
9681 uint32 senderEntry = fields[3].Get<uint32>();
9682
9683 if (level > MAX_LEVEL)
9684 {
9685 LOG_ERROR("sql.sql", "Table `mail_level_reward` have data for level {} that more supported by client ({}), ignoring.", level, MAX_LEVEL);
9686 continue;
9687 }
9688
9689 if (!(raceMask & sRaceMgr->GetPlayableRaceMask()))
9690 {
9691 LOG_ERROR("sql.sql", "Table `mail_level_reward` have raceMask ({}) for level {} that not include any player races, ignoring.", raceMask, level);
9692 continue;
9693 }
9694
9695 if (!sMailTemplateStore.LookupEntry(mailTemplateId))
9696 {
9697 LOG_ERROR("sql.sql", "Table `mail_level_reward` have invalid mailTemplateId ({}) for level {} that invalid not include any player races, ignoring.", mailTemplateId, level);
9698 continue;
9699 }
9700
9701 if (!GetCreatureTemplate(senderEntry))
9702 {
9703 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);
9704 continue;
9705 }
9706
9707 _mailLevelRewardStore[level].push_back(MailLevelReward(raceMask, mailTemplateId, senderEntry));
9708
9709 ++count;
9710 } while (result->NextRow());
9711
9712 LOG_INFO("server.loading", ">> Loaded {} Level Dependent Mail Rewards in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9713 LOG_INFO("server.loading", " ");
9714}
#define MAX_LEVEL
Definition DBCEnums.h:39
DBCStorage< MailTemplateEntry > sMailTemplateStore(MailTemplateEntryfmt)
Definition ObjectMgr.h:545

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

◆ LoadModuleStrings()

bool ObjectMgr::LoadModuleStrings ( )
9236{
9237 uint32 oldMSTime = getMSTime();
9238
9239 _moduleStringStore.clear(); // for reload case
9240 QueryResult result = WorldDatabase.Query("SELECT module, id, string FROM module_string");
9241 if (!result)
9242 {
9243 LOG_WARN("server.loading", ">> Loaded 0 module strings. DB table `module_string` is empty.");
9244 LOG_INFO("server.loading", " ");
9245 return false;
9246 }
9247
9248 do
9249 {
9250 Field* fields = result->Fetch();
9251
9252 std::string module = fields[0].Get<std::string>();
9253 uint32 id = fields[1].Get<uint32>();
9254
9255 std::pair<std::string, uint32> pairKey = std::make_pair(module, id);
9256 ModuleString& data = _moduleStringStore[pairKey];
9257
9258 AddLocaleString(fields[2].Get<std::string>(), LOCALE_enUS, data.Content);
9259 } while (result->NextRow());
9260
9261 LOG_INFO("server.loading", ">> Loaded {} Module Strings in {} ms", _moduleStringStore.size(), GetMSTimeDiffToNow(oldMSTime));
9262 LOG_INFO("server.loading", " ");
9263
9264 return true;
9265}

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

◆ LoadModuleStringsLocale()

bool ObjectMgr::LoadModuleStringsLocale ( )
9268{
9269 uint32 oldMSTime = getMSTime();
9270
9271 QueryResult result = WorldDatabase.Query("SELECT module, id, locale, string FROM module_string_locale");
9272 if (!result)
9273 {
9274 LOG_WARN("server.loading", ">> Loaded 0 module strings locale. DB table `module_string_locale` is empty.");
9275 LOG_INFO("server.loading", " ");
9276 return false;
9277 }
9278
9279 uint32 localeCount = 0;
9280 do
9281 {
9282 Field* fields = result->Fetch();
9283
9284 std::string module = fields[0].Get<std::string>();
9285 uint32 id = fields[1].Get<uint32>();
9286
9287 std::pair<std::string, uint32> pairKey = std::make_pair(module, id);
9288 ModuleString& data = _moduleStringStore[pairKey];
9289
9290 ModuleStringContainer::iterator ms = _moduleStringStore.find(pairKey);
9291 if (ms == _moduleStringStore.end())
9292 {
9293 LOG_ERROR("sql.sql", "ModuleString (Module: {} Id: {}) found in table `module_string_locale` but does not exist in `module_string`. Skipped!", module, id);
9294 continue;
9295 }
9296
9297 LocaleConstant locale = GetLocaleByName(fields[2].Get<std::string>());
9298 if (locale == LOCALE_enUS)
9299 continue;
9300
9301 AddLocaleString(fields[3].Get<std::string>(), locale, data.Content);
9302 localeCount++;
9303 } while (result->NextRow());
9304
9305 LOG_INFO("server.loading", ">> Loaded {} Module Strings Locales in {} ms", localeCount, GetMSTimeDiffToNow(oldMSTime));
9306 LOG_INFO("server.loading", " ");
9307
9308 return true;
9309}

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

◆ LoadNPCSpellClickSpells()

void ObjectMgr::LoadNPCSpellClickSpells ( )
8589{
8590 uint32 oldMSTime = getMSTime();
8591
8592 _spellClickInfoStore.clear();
8593 // 0 1 2 3
8594 QueryResult result = WorldDatabase.Query("SELECT npc_entry, spell_id, cast_flags, user_type FROM npc_spellclick_spells");
8595
8596 if (!result)
8597 {
8598 LOG_WARN("server.loading", ">> Loaded 0 spellclick spells. DB table `npc_spellclick_spells` is empty.");
8599 LOG_INFO("server.loading", " ");
8600 return;
8601 }
8602
8603 uint32 count = 0;
8604
8605 do
8606 {
8607 Field* fields = result->Fetch();
8608
8609 uint32 npc_entry = fields[0].Get<uint32>();
8610 CreatureTemplate const* cInfo = GetCreatureTemplate(npc_entry);
8611 if (!cInfo)
8612 {
8613 LOG_ERROR("sql.sql", "Table npc_spellclick_spells references unknown creature_template {}. Skipping entry.", npc_entry);
8614 continue;
8615 }
8616
8617 uint32 spellid = fields[1].Get<uint32>();
8618 SpellInfo const* spellinfo = sSpellMgr->GetSpellInfo(spellid);
8619 if (!spellinfo)
8620 {
8621 LOG_ERROR("sql.sql", "Table npc_spellclick_spells references unknown spellid {}. Skipping entry.", spellid);
8622 continue;
8623 }
8624
8625 uint8 userType = fields[3].Get<uint16>();
8626 if (userType >= SPELL_CLICK_USER_MAX)
8627 LOG_ERROR("sql.sql", "Table npc_spellclick_spells references unknown user type {}. Skipping entry.", uint32(userType));
8628
8629 uint8 castFlags = fields[2].Get<uint8>();
8630 SpellClickInfo info;
8631 info.spellId = spellid;
8632 info.castFlags = castFlags;
8633 info.userType = SpellClickUserTypes(userType);
8634 _spellClickInfoStore.insert(SpellClickInfoContainer::value_type(npc_entry, info));
8635
8636 ++count;
8637 } while (result->NextRow());
8638
8639 // all spellclick data loaded, now we check if there are creatures with NPC_FLAG_SPELLCLICK but with no data
8640 // NOTE: It *CAN* be the other way around: no spellclick flag but with spellclick data, in case of creature-only vehicle accessories
8642 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
8643 {
8644 if ((itr->second.npcflag & UNIT_NPC_FLAG_SPELLCLICK) && _spellClickInfoStore.find(itr->second.Entry) == _spellClickInfoStore.end())
8645 {
8646 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);
8647 const_cast<CreatureTemplate*>(&itr->second)->npcflag &= ~UNIT_NPC_FLAG_SPELLCLICK;
8648 }
8649 }
8650
8651 LOG_INFO("server.loading", ">> Loaded {} Spellclick Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8652 LOG_INFO("server.loading", " ");
8653}
SpellClickUserTypes
Definition SharedDefines.h:668
@ SPELL_CLICK_USER_MAX
Definition SharedDefines.h:673
@ UNIT_NPC_FLAG_SPELLCLICK
Definition UnitDefines.h:343
Definition ObjectMgr.h:399
uint32 spellId
Definition ObjectMgr.h:400

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

◆ LoadNpcTextLocales()

void ObjectMgr::LoadNpcTextLocales ( )
6678{
6679 uint32 oldMSTime = getMSTime();
6680
6681 _npcTextLocaleStore.clear(); // need for reload case
6682
6683 QueryResult result = WorldDatabase.Query("SELECT ID, Locale, "
6684 // 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
6685 "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 "
6686 "FROM npc_text_locale");
6687
6688 if (!result)
6689 return;
6690
6691 do
6692 {
6693 Field* fields = result->Fetch();
6694
6695 uint32 ID = fields[0].Get<uint32>();
6696
6697 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
6698 if (locale == LOCALE_enUS)
6699 continue;
6700
6702 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
6703 {
6704 AddLocaleString(fields[2 + i * 2].Get<std::string>(), locale, data.Text_0[i]);
6705 AddLocaleString(fields[3 + i * 2].Get<std::string>(), locale, data.Text_1[i]);
6706 }
6707 } while (result->NextRow());
6708
6709 LOG_INFO("server.loading", ">> Loaded {} Npc Text Locale Strings in {} ms", (uint32)_npcTextLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
6710}
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 ( )
6425{
6426 uint32 oldMSTime = getMSTime();
6427
6428 _pageTextLocaleStore.clear(); // need for reload case
6429
6430 // 0 1 2
6431 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Text FROM page_text_locale");
6432
6433 if (!result)
6434 {
6435 LOG_WARN("server.loading", ">> Loaded 0 page texts. DB table `page_text_locale` is empty!");
6436 LOG_INFO("server.loading", " ");
6437 return;
6438 }
6439
6440 do
6441 {
6442 Field* fields = result->Fetch();
6443
6444 uint32 ID = fields[0].Get<uint32>();
6445
6446 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
6447 if (locale == LOCALE_enUS)
6448 continue;
6449
6451 AddLocaleString(fields[2].Get<std::string>(), locale, data.Text);
6452 } while (result->NextRow());
6453
6454 LOG_INFO("server.loading", ">> Loaded {} Page Text Locale Strings in {} ms", (uint32)_pageTextLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
6455}
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 ( )
6375{
6376 uint32 oldMSTime = getMSTime();
6377
6378 // 0 1 2
6379 QueryResult result = WorldDatabase.Query("SELECT ID, Text, NextPageID FROM page_text");
6380
6381 if (!result)
6382 {
6383 LOG_WARN("server.loading", ">> Loaded 0 page texts. DB table `page_text` is empty!");
6384 LOG_INFO("server.loading", " ");
6385 return;
6386 }
6387
6388 uint32 count = 0;
6389 do
6390 {
6391 Field* fields = result->Fetch();
6392
6393 PageText& pageText = _pageTextStore[fields[0].Get<uint32>()];
6394
6395 pageText.Text = fields[1].Get<std::string>();
6396 pageText.NextPage = fields[2].Get<uint32>();
6397
6398 ++count;
6399 } while (result->NextRow());
6400
6401 for (PageTextContainer::const_iterator itr = _pageTextStore.begin(); itr != _pageTextStore.end(); ++itr)
6402 {
6403 if (itr->second.NextPage)
6404 {
6405 PageTextContainer::const_iterator itr2 = _pageTextStore.find(itr->second.NextPage);
6406 if (itr2 == _pageTextStore.end())
6407 LOG_ERROR("sql.sql", "Page text (Id: {}) has not existing next page (Id: {})", itr->first, itr->second.NextPage);
6408 }
6409 }
6410
6411 LOG_INFO("server.loading", ">> Loaded {} Page Texts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6412 LOG_INFO("server.loading", " ");
6413}
Definition ObjectMgr.h:58
std::string Text
Definition ObjectMgr.h:59
uint32 NextPage
Definition ObjectMgr.h:60

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

◆ LoadPetLevelInfo()

void ObjectMgr::LoadPetLevelInfo ( )
4112{
4113 uint32 oldMSTime = getMSTime();
4114
4115 // 0 1 2 3 4 5 6 7 8 9 10 11
4116 QueryResult result = WorldDatabase.Query("SELECT creature_entry, level, hp, mana, str, agi, sta, inte, spi, armor, min_dmg, max_dmg FROM pet_levelstats");
4117
4118 if (!result)
4119 {
4120 LOG_WARN("server.loading", ">> Loaded 0 level pet stats definitions. DB table `pet_levelstats` is empty.");
4121 LOG_INFO("server.loading", " ");
4122 return;
4123 }
4124
4125 uint32 count = 0;
4126
4127 do
4128 {
4129 Field* fields = result->Fetch();
4130
4131 uint32 creature_id = fields[0].Get<uint32>();
4132 if (!GetCreatureTemplate(creature_id))
4133 {
4134 LOG_ERROR("sql.sql", "Wrong creature id {} in `pet_levelstats` table, ignoring.", creature_id);
4135 continue;
4136 }
4137
4138 uint32 current_level = fields[1].Get<uint8>();
4139 if (current_level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4140 {
4141 if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
4142 LOG_ERROR("sql.sql", "Wrong (> {}) level {} in `pet_levelstats` table, ignoring.", STRONG_MAX_LEVEL, current_level);
4143 else
4144 {
4145 LOG_DEBUG("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `pet_levelstats` table, ignoring.", current_level);
4146 ++count; // make result loading percent "expected" correct in case disabled detail mode for example.
4147 }
4148 continue;
4149 }
4150 else if (current_level < 1)
4151 {
4152 LOG_ERROR("sql.sql", "Wrong (<1) level {} in `pet_levelstats` table, ignoring.", current_level);
4153 continue;
4154 }
4155
4156 PetLevelInfo*& pInfoMapEntry = _petInfoStore[creature_id];
4157
4158 if (!pInfoMapEntry)
4159 pInfoMapEntry = new PetLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)];
4160
4161 // data for level 1 stored in [0] array element, ...
4162 PetLevelInfo* pLevelInfo = &pInfoMapEntry[current_level - 1];
4163
4164 pLevelInfo->health = fields[2].Get<uint32>();
4165 pLevelInfo->mana = fields[3].Get<uint32>();
4166 pLevelInfo->armor = fields[9].Get<uint32>();
4167 pLevelInfo->min_dmg = fields[10].Get<uint32>();
4168 pLevelInfo->max_dmg = fields[11].Get<uint32>();
4169 for (uint8 i = 0; i < MAX_STATS; i++)
4170 {
4171 pLevelInfo->stats[i] = fields[i + 4].Get<uint32>();
4172 }
4173
4174 ++count;
4175 } while (result->NextRow());
4176
4177 // Fill gaps and check integrity
4178 for (PetLevelInfoContainer::iterator itr = _petInfoStore.begin(); itr != _petInfoStore.end(); ++itr)
4179 {
4180 PetLevelInfo* pInfo = itr->second;
4181
4182 // fatal error if no level 1 data
4183 if (!pInfo || pInfo[0].health == 0)
4184 {
4185 LOG_ERROR("sql.sql", "Creature {} does not have pet stats data for Level 1!", itr->first);
4186 exit(1);
4187 }
4188
4189 // fill level gaps
4190 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4191 {
4192 if (pInfo[level].health == 0)
4193 {
4194 LOG_ERROR("sql.sql", "Creature {} has no data for Level {} pet stats data, using data of Level {}.", itr->first, level + 1, level);
4195 pInfo[level] = pInfo[level - 1];
4196 }
4197 }
4198 }
4199
4200 LOG_INFO("server.loading", ">> Loaded {} Level Pet Stats Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4201 LOG_INFO("server.loading", " ");
4202}
#define STRONG_MAX_LEVEL
Definition DBCEnums.h:43
#define MAX_STATS
Definition SharedDefines.h:253
Definition ObjectMgr.h:530
uint32 max_dmg
Definition ObjectMgr.h:541
uint32 mana
Definition ObjectMgr.h:538
uint32 min_dmg
Definition ObjectMgr.h:540
uint32 health
Definition ObjectMgr.h:537
std::array< uint32, MAX_STATS > stats
Definition ObjectMgr.h:536
uint32 armor
Definition ObjectMgr.h:539

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 ( )
8095{
8096 uint32 oldMSTime = getMSTime();
8097 // 0 1 2
8098 QueryResult result = WorldDatabase.Query("SELECT word, entry, half FROM pet_name_generation");
8099
8100 if (!result)
8101 {
8102 LOG_WARN("server.loading", ">> Loaded 0 pet name parts. DB table `pet_name_generation` is empty!");
8103 LOG_INFO("server.loading", " ");
8104 return;
8105 }
8106
8107 uint32 count = 0;
8108
8109 do
8110 {
8111 Field* fields = result->Fetch();
8112 std::string word = fields[0].Get<std::string>();
8113 uint32 entry = fields[1].Get<uint32>();
8114 bool half = fields[2].Get<bool>();
8115 if (half)
8116 _petHalfName1[entry].push_back(word);
8117 else
8118 _petHalfName0[entry].push_back(word);
8119 ++count;
8120 } while (result->NextRow());
8121
8122 LOG_INFO("server.loading", ">> Loaded {} Pet Name Parts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8123 LOG_INFO("server.loading", " ");
8124}

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

◆ LoadPetNamesLocales()

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

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

◆ LoadPetNumber()

void ObjectMgr::LoadPetNumber ( )
8127{
8128 uint32 oldMSTime = getMSTime();
8129
8130 QueryResult result = CharacterDatabase.Query("SELECT MAX(id) FROM character_pet");
8131 if (result)
8132 {
8133 Field* fields = result->Fetch();
8134 _hiPetNumber = fields[0].Get<uint32>() + 1;
8135 }
8136
8137 LOG_INFO("server.loading", ">> Loaded The Max Pet Number: {} in {} ms", _hiPetNumber - 1, GetMSTimeDiffToNow(oldMSTime));
8138 LOG_INFO("server.loading", " ");
8139}

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

◆ LoadPlayerInfo()

void ObjectMgr::LoadPlayerInfo ( )
4251{
4252 // Load playercreate
4253 {
4254 if (_playerInfo.empty() || _playerInfo.size() != sRaceMgr->GetMaxRaces())
4255 {
4256 _playerInfo.clear();
4257 _playerInfo.resize(sRaceMgr->GetMaxRaces());
4258 for (auto& classVec : _playerInfo)
4259 classVec.resize(MAX_CLASSES, nullptr);
4260 }
4261
4262 uint32 oldMSTime = getMSTime();
4263 // 0 1 2 3 4 5 6
4264 QueryResult result = WorldDatabase.Query("SELECT race, class, map, zone, position_x, position_y, position_z, orientation FROM playercreateinfo");
4265
4266 if (!result)
4267 {
4268 LOG_INFO("server.loading", " ");
4269 LOG_WARN("server.loading", ">> Loaded 0 player create definitions. DB table `playercreateinfo` is empty.");
4270 exit(1);
4271 }
4272 else
4273 {
4274 uint32 count = 0;
4275
4276 do
4277 {
4278 Field* fields = result->Fetch();
4279
4280 uint32 current_race = fields[0].Get<uint8>();
4281 uint32 current_class = fields[1].Get<uint8>();
4282 uint32 mapId = fields[2].Get<uint16>();
4283 uint32 areaId = fields[3].Get<uint32>(); // zone
4284 float positionX = fields[4].Get<float>();
4285 float positionY = fields[5].Get<float>();
4286 float positionZ = fields[6].Get<float>();
4287 float orientation = fields[7].Get<float>();
4288
4289 if (current_race >= sRaceMgr->GetMaxRaces())
4290 {
4291 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo` table, ignoring.", current_race);
4292 continue;
4293 }
4294
4295 ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(current_race);
4296 if (!rEntry)
4297 {
4298 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo` table, ignoring.", current_race);
4299 continue;
4300 }
4301
4302 if (current_class >= MAX_CLASSES)
4303 {
4304 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo` table, ignoring.", current_class);
4305 continue;
4306 }
4307
4308 if (!sChrClassesStore.LookupEntry(current_class))
4309 {
4310 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo` table, ignoring.", current_class);
4311 continue;
4312 }
4313
4314 // accept DB data only for valid position (and non instanceable)
4315 if (!MapMgr::IsValidMapCoord(mapId, positionX, positionY, positionZ, orientation))
4316 {
4317 LOG_ERROR("sql.sql", "Wrong home position for class {} race {} pair in `playercreateinfo` table, ignoring.", current_class, current_race);
4318 continue;
4319 }
4320
4321 if (sMapStore.LookupEntry(mapId)->Instanceable())
4322 {
4323 LOG_ERROR("sql.sql", "Home position in instanceable map for class {} race {} pair in `playercreateinfo` table, ignoring.", current_class, current_race);
4324 continue;
4325 }
4326
4327 PlayerInfo* info = new PlayerInfo();
4328 info->mapId = mapId;
4329 info->areaId = areaId;
4330 info->positionX = positionX;
4331 info->positionY = positionY;
4332 info->positionZ = positionZ;
4333 info->orientation = orientation;
4334 info->displayId_m = rEntry->model_m;
4335 info->displayId_f = rEntry->model_f;
4336 _playerInfo[current_race][current_class] = info;
4337
4338 ++count;
4339 } while (result->NextRow());
4340
4341 LOG_INFO("server.loading", ">> Loaded {} Player Create Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4342 LOG_INFO("server.loading", " ");
4343 }
4344 }
4345
4346 // Load playercreate items
4347 LOG_INFO("server.loading", "Loading Player Create Items Data...");
4348 {
4349 uint32 oldMSTime = getMSTime();
4350 // 0 1 2 3
4351 QueryResult result = WorldDatabase.Query("SELECT race, class, itemid, amount FROM playercreateinfo_item");
4352
4353 if (!result)
4354 {
4355 LOG_WARN("server.loading", ">> Loaded 0 Custom Player Create Items. DB Table `playercreateinfo_item` Is Empty.");
4356 LOG_INFO("server.loading", " ");
4357 }
4358 else
4359 {
4360 uint32 count = 0;
4361
4362 do
4363 {
4364 Field* fields = result->Fetch();
4365
4366 uint32 current_race = fields[0].Get<uint8>();
4367 if (current_race >= sRaceMgr->GetMaxRaces())
4368 {
4369 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo_item` table, ignoring.", current_race);
4370 continue;
4371 }
4372
4373 uint32 current_class = fields[1].Get<uint8>();
4374 if (current_class >= MAX_CLASSES)
4375 {
4376 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo_item` table, ignoring.", current_class);
4377 continue;
4378 }
4379
4380 uint32 item_id = fields[2].Get<uint32>();
4381
4382 if (!GetItemTemplate(item_id))
4383 {
4384 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);
4385 continue;
4386 }
4387
4388 int32 amount = fields[3].Get<int32>();
4389
4390 if (!amount)
4391 {
4392 LOG_ERROR("sql.sql", "Item id {} (class {} race {}) have amount == 0 in `playercreateinfo_item` table, ignoring.", item_id, current_race, current_class);
4393 continue;
4394 }
4395
4396 if (!current_race || !current_class)
4397 {
4398 uint32 min_race = current_race ? current_race : 1;
4399 uint32 max_race = current_race ? current_race + 1 : sRaceMgr->GetMaxRaces();
4400 uint32 min_class = current_class ? current_class : 1;
4401 uint32 max_class = current_class ? current_class + 1 : MAX_CLASSES;
4402 for (uint32 r = min_race; r < max_race; ++r)
4403 for (uint32 c = min_class; c < max_class; ++c)
4404 PlayerCreateInfoAddItemHelper(r, c, item_id, amount);
4405 }
4406 else
4407 PlayerCreateInfoAddItemHelper(current_race, current_class, item_id, amount);
4408
4409 ++count;
4410 } while (result->NextRow());
4411
4412 LOG_INFO("server.loading", ">> Loaded {} Custom Player Create Items in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4413 LOG_INFO("server.loading", " ");
4414 }
4415 }
4416
4417 // Load playercreate skills
4418 LOG_INFO("server.loading", "Loading Player Create Skill Data...");
4419 {
4420 uint32 oldMSTime = getMSTime();
4421
4422 QueryResult result = WorldDatabase.Query("SELECT raceMask, classMask, skill, `rank` FROM playercreateinfo_skills");
4423
4424 if (!result)
4425 {
4426 LOG_WARN("server.loading", ">> Loaded 0 Player Create Skills. DB Table `playercreateinfo_skills` Is Empty.");
4427 }
4428 else
4429 {
4430 uint32 count = 0;
4431
4432 do
4433 {
4434 Field* fields = result->Fetch();
4435 uint32 raceMask = fields[0].Get<uint32>();
4436 uint32 classMask = fields[1].Get<uint32>();
4438 skill.SkillId = fields[2].Get<uint16>();
4439 skill.Rank = fields[3].Get<uint16>();
4440
4441 if (skill.Rank >= MAX_SKILL_STEP)
4442 {
4443 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);
4444 continue;
4445 }
4446
4447 if (raceMask != 0 && !(raceMask & sRaceMgr->GetPlayableRaceMask()))
4448 {
4449 LOG_ERROR("sql.sql", "Wrong race mask {} in `playercreateinfo_skills` table, ignoring.", raceMask);
4450 continue;
4451 }
4452
4453 if (classMask != 0 && !(classMask & CLASSMASK_ALL_PLAYABLE))
4454 {
4455 LOG_ERROR("sql.sql", "Wrong class mask {} in `playercreateinfo_skills` table, ignoring.", classMask);
4456 continue;
4457 }
4458
4459 if (!sSkillLineStore.LookupEntry(skill.SkillId))
4460 {
4461 LOG_ERROR("sql.sql", "Wrong skill id {} in `playercreateinfo_skills` table, ignoring.", skill.SkillId);
4462 continue;
4463 }
4464
4465 for (uint32 raceIndex = RACE_HUMAN; raceIndex < sRaceMgr->GetMaxRaces(); ++raceIndex)
4466 {
4467 if (raceMask == 0 || ((1 << (raceIndex - 1)) & raceMask))
4468 {
4469 for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex)
4470 {
4471 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
4472 {
4473 if (!GetSkillRaceClassInfo(skill.SkillId, raceIndex, classIndex))
4474 continue;
4475
4476 if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
4477 {
4478 info->skills.push_back(skill);
4479 ++count;
4480 }
4481 }
4482 }
4483 }
4484 }
4485 } while (result->NextRow());
4486
4487 LOG_INFO("server.loading", ">> Loaded {} Player Create Skills in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4488 LOG_INFO("server.loading", " ");
4489 }
4490 }
4491
4492 // Load playercreate spells
4493 LOG_INFO("server.loading", "Loading Player Create Spell Data...");
4494 {
4495 uint32 oldMSTime = getMSTime();
4496
4497 QueryResult result = WorldDatabase.Query("SELECT racemask, classmask, Spell FROM playercreateinfo_spell_custom");
4498
4499 if (!result)
4500 {
4501 LOG_WARN("server.loading", ">> Loaded 0 player create spells. DB table `playercreateinfo_spell_custom` is empty.");
4502 }
4503 else
4504 {
4505 uint32 count = 0;
4506
4507 do
4508 {
4509 Field* fields = result->Fetch();
4510 uint32 raceMask = fields[0].Get<uint32>();
4511 uint32 classMask = fields[1].Get<uint32>();
4512 uint32 spellId = fields[2].Get<uint32>();
4513
4514 if (raceMask != 0 && !(raceMask & sRaceMgr->GetPlayableRaceMask()))
4515 {
4516 LOG_ERROR("sql.sql", "Wrong race mask {} in `playercreateinfo_spell_custom` table, ignoring.", raceMask);
4517 continue;
4518 }
4519
4520 if (classMask != 0 && !(classMask & CLASSMASK_ALL_PLAYABLE))
4521 {
4522 LOG_ERROR("sql.sql", "Wrong class mask {} in `playercreateinfo_spell_custom` table, ignoring.", classMask);
4523 continue;
4524 }
4525
4526 for (uint32 raceIndex = RACE_HUMAN; raceIndex < sRaceMgr->GetMaxRaces(); ++raceIndex)
4527 {
4528 if (raceMask == 0 || ((1 << (raceIndex - 1)) & raceMask))
4529 {
4530 for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex)
4531 {
4532 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
4533 {
4534 if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
4535 {
4536 info->customSpells.push_back(spellId);
4537 ++count;
4538 }
4539 }
4540 }
4541 }
4542 }
4543 } while (result->NextRow());
4544
4545 LOG_INFO("server.loading", ">> Loaded {} Custom Player Create Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4546 LOG_INFO("server.loading", " ");
4547 }
4548 }
4549
4550 // Load playercreate cast spell
4551 LOG_INFO("server.loading", "Loading Player Create Cast Spell Data...");
4552 {
4553 uint32 oldMSTime = getMSTime();
4554
4555 QueryResult result = WorldDatabase.Query("SELECT raceMask, classMask, spell FROM playercreateinfo_cast_spell");
4556
4557 if (!result)
4558 {
4559 LOG_WARN("server.loading", ">> Loaded 0 Player Create Cast Spells. DB Table `playercreateinfo_cast_spell` Is Empty.");
4560 }
4561 else
4562 {
4563 uint32 count = 0;
4564
4565 do
4566 {
4567 Field* fields = result->Fetch();
4568 uint32 raceMask = fields[0].Get<uint32>();
4569 uint32 classMask = fields[1].Get<uint32>();
4570 uint32 spellId = fields[2].Get<uint32>();
4571
4572 if (raceMask != 0 && !(raceMask & sRaceMgr->GetPlayableRaceMask()))
4573 {
4574 LOG_ERROR("sql.sql", "Wrong race mask {} in `playercreateinfo_cast_spell` table, ignoring.", raceMask);
4575 continue;
4576 }
4577
4578 if (classMask != 0 && !(classMask & CLASSMASK_ALL_PLAYABLE))
4579 {
4580 LOG_ERROR("sql.sql", "Wrong class mask {} in `playercreateinfo_cast_spell` table, ignoring.", classMask);
4581 continue;
4582 }
4583
4584 for (uint32 raceIndex = RACE_HUMAN; raceIndex < sRaceMgr->GetMaxRaces(); ++raceIndex)
4585 {
4586 if (raceMask == 0 || ((1 << (raceIndex - 1)) & raceMask))
4587 {
4588 for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex)
4589 {
4590 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
4591 {
4592 if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
4593 {
4594 info->castSpells.push_back(spellId);
4595 ++count;
4596 }
4597 }
4598 }
4599 }
4600 }
4601 } while (result->NextRow());
4602
4603 LOG_INFO("server.loading", ">> Loaded {} Player Create Cast Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4604 LOG_INFO("server.loading", " ");
4605 }
4606 }
4607
4608 // Load playercreate actions
4609 LOG_INFO("server.loading", "Loading Player Create Action Data...");
4610 {
4611 uint32 oldMSTime = getMSTime();
4612
4613 // 0 1 2 3 4
4614 QueryResult result = WorldDatabase.Query("SELECT race, class, button, action, type FROM playercreateinfo_action");
4615
4616 if (!result)
4617 {
4618 LOG_WARN("server.loading", ">> Loaded 0 Player Create Actions. DB Table `playercreateinfo_action` Is Empty.");
4619 LOG_INFO("server.loading", " ");
4620 }
4621 else
4622 {
4623 uint32 count = 0;
4624
4625 do
4626 {
4627 Field* fields = result->Fetch();
4628
4629 uint32 current_race = fields[0].Get<uint8>();
4630 if (current_race >= sRaceMgr->GetMaxRaces())
4631 {
4632 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo_action` table, ignoring.", current_race);
4633 continue;
4634 }
4635
4636 uint32 current_class = fields[1].Get<uint8>();
4637 if (current_class >= MAX_CLASSES)
4638 {
4639 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo_action` table, ignoring.", current_class);
4640 continue;
4641 }
4642
4643 if (PlayerInfo* info = _playerInfo[current_race][current_class])
4644 info->action.push_back(PlayerCreateInfoAction(fields[2].Get<uint16>(), fields[3].Get<uint32>(), fields[4].Get<uint16>()));
4645
4646 ++count;
4647 } while (result->NextRow());
4648
4649 LOG_INFO("server.loading", ">> Loaded {} Player Create Actions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4650 LOG_INFO("server.loading", " ");
4651 }
4652 }
4653
4654 // Loading levels data (class/race dependent)
4655 LOG_INFO("server.loading", "Loading Player Create Level Stats Data...");
4656 {
4657 struct RaceStats
4658 {
4659 int16 StatModifier[MAX_STATS];
4660 };
4661
4662 std::vector<RaceStats> raceStatModifiers;
4663
4664 raceStatModifiers.resize(sRaceMgr->GetMaxRaces());
4665
4666 uint32 oldMSTime = getMSTime();
4667
4668 // 0 1 2 3 4 5
4669 QueryResult raceStatsResult = WorldDatabase.Query("SELECT Race, Strength, Agility, Stamina, Intellect, Spirit FROM player_race_stats");
4670
4671 if (!raceStatsResult)
4672 {
4673 LOG_WARN("server.loading", ">> Loaded 0 race stats definitions. DB table `player_race_stats` is empty.");
4674 LOG_INFO("server.loading", " ");
4675 exit(1);
4676 }
4677
4678 do
4679 {
4680 Field* fields = raceStatsResult->Fetch();
4681
4682 uint32 current_race = fields[0].Get<uint8>();
4683 if (current_race >= sRaceMgr->GetMaxRaces())
4684 {
4685 LOG_ERROR("sql.sql", "Wrong race {} in `player_race_stats` table, ignoring.", current_race);
4686 continue;
4687 }
4688
4689 for (uint32 i = 0; i < MAX_STATS; ++i)
4690 raceStatModifiers[current_race].StatModifier[i] = fields[i + 1].Get<int16>();
4691
4692 } while (raceStatsResult->NextRow());
4693
4694 // 0 1 2 3 4 5 6 7 8
4695 QueryResult result = WorldDatabase.Query("SELECT Class, Level, Strength, Agility, Stamina, Intellect, Spirit, BaseHP, BaseMana FROM player_class_stats");
4696
4697 if (!result)
4698 {
4699 LOG_ERROR("server.loading", ">> Loaded 0 level stats definitions. DB table `player_class_stats` is empty.");
4700 exit(1);
4701 }
4702
4703 uint32 count = 0;
4704
4705 do
4706 {
4707 Field* fields = result->Fetch();
4708
4709 uint32 current_class = fields[0].Get<uint8>();
4710 if (current_class >= MAX_CLASSES)
4711 {
4712 LOG_ERROR("sql.sql", "Wrong class {} in `player_class_stats` table, ignoring.", current_class);
4713 continue;
4714 }
4715
4716 uint32 current_level = fields[1].Get<uint8>();
4717 if (current_level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4718 {
4719 if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
4720 LOG_ERROR("sql.sql", "Wrong (> {}) level {} in `player_class_stats` table, ignoring.", STRONG_MAX_LEVEL, current_level);
4721 else
4722 LOG_DEBUG("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_class_stats` table, ignoring.", current_level);
4723
4724 continue;
4725 }
4726
4727 for (std::size_t race = 0; race < raceStatModifiers.size(); ++race)
4728 {
4729 if (PlayerInfo* info = _playerInfo[race][current_class])
4730 {
4731 if (!info->levelInfo)
4732 info->levelInfo = new PlayerLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)];
4733
4734 PlayerLevelInfo& levelInfo = info->levelInfo[current_level - 1];
4735 for (int i = 0; i < MAX_STATS; ++i)
4736 levelInfo.stats[i] = fields[i + 2].Get<uint16>() + raceStatModifiers[race].StatModifier[i];
4737 }
4738 }
4739
4740 PlayerClassInfo* info = _playerClassInfo[current_class];
4741 if (!info)
4742 {
4743 info = new PlayerClassInfo();
4745 _playerClassInfo[current_class] = info;
4746 }
4747
4748 PlayerClassLevelInfo& levelInfo = info->levelInfo[current_level - 1];
4749
4750 levelInfo.basehealth = fields[7].Get<uint32>();
4751 levelInfo.basemana = fields[8].Get<uint32>();
4752
4753 ++count;
4754 } while (result->NextRow());
4755
4756 // Fill gaps and check integrity
4757 for (int race = RACE_HUMAN; race < sRaceMgr->GetMaxRaces(); ++race)
4758 {
4759 // skip non existed races
4760 if (!sChrRacesStore.LookupEntry(race))
4761 continue;
4762
4763 for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
4764 {
4765 // skip non existed classes
4766 if (!sChrClassesStore.LookupEntry(class_))
4767 continue;
4768
4769 PlayerClassInfo* pClassInfo = _playerClassInfo[class_];
4770 PlayerInfo* info = _playerInfo[race][class_];
4771 if (!info)
4772 continue;
4773
4774 // skip expansion races if not playing with expansion
4775 if (sWorld->getIntConfig(CONFIG_EXPANSION) < EXPANSION_THE_BURNING_CRUSADE && (race == RACE_BLOODELF || race == RACE_DRAENEI))
4776 continue;
4777
4778 // skip expansion classes if not playing with expansion
4780 continue;
4781
4782 // fatal error if no initial stats data
4783 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))
4784 {
4785 LOG_ERROR("sql.sql", "Race {} class {} initial level does not have stats data!", race, class_);
4786 exit(1);
4787 }
4788
4789 // fatal error if no initial health/mana data
4790 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))
4791 {
4792 LOG_ERROR("sql.sql", "Class {} initial level does not have health/mana data!", class_);
4793 exit(1);
4794 }
4795
4796 // fill level gaps for stats
4797 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4798 {
4799 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))
4800 {
4801 LOG_ERROR("sql.sql", "Race {} class {} level {} does not have stats data. Using stats data of level {}.", race, class_, level + 1, level);
4802 info->levelInfo[level] = info->levelInfo[level - 1];
4803 }
4804 }
4805
4806 // fill level gaps for health/mana
4807 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4808 {
4809 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))
4810 {
4811 LOG_ERROR("sql.sql", "Class {} level {} does not have health/mana data. Using stats data of level {}.", class_, level + 1, level);
4812 pClassInfo->levelInfo[level] = pClassInfo->levelInfo[level - 1];
4813 }
4814 }
4815 }
4816 }
4817
4818 LOG_INFO("server.loading", ">> Loaded {} Level Stats Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4819 LOG_INFO("server.loading", " ");
4820 }
4821
4822 // Loading xp per level data
4823 LOG_INFO("server.loading", "Loading Player Create XP Data...");
4824 {
4825 uint32 oldMSTime = getMSTime();
4826
4827 _playerXPperLevel.resize(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
4828 for (uint8 level = 0; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4829 _playerXPperLevel[level] = 0;
4830
4831 // 0 1
4832 QueryResult result = WorldDatabase.Query("SELECT Level, Experience FROM player_xp_for_level");
4833
4834 if (!result)
4835 {
4836 LOG_WARN("server.loading", ">> Loaded 0 xp for level definitions. DB table `player_xp_for_level` is empty.");
4837 LOG_INFO("server.loading", " ");
4838 exit(1);
4839 }
4840
4841 uint32 count = 0;
4842
4843 do
4844 {
4845 Field* fields = result->Fetch();
4846
4847 uint32 current_level = fields[0].Get<uint8>();
4848 uint32 current_xp = fields[1].Get<uint32>();
4849
4850 if (current_level >= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4851 {
4852 if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
4853 LOG_ERROR("sql.sql", "Wrong (> {}) level {} in `player_xp_for_level` table, ignoring.", STRONG_MAX_LEVEL, current_level);
4854 else
4855 {
4856 LOG_DEBUG("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_xp_for_levels` table, ignoring.", current_level);
4857 ++count; // make result loading percent "expected" correct in case disabled detail mode for example.
4858 }
4859 continue;
4860 }
4861 //PlayerXPperLevel
4862 _playerXPperLevel[current_level] = current_xp;
4863 ++count;
4864 } while (result->NextRow());
4865
4866 // fill level gaps
4867 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4868 {
4869 if (_playerXPperLevel[level] == 0)
4870 {
4871 LOG_ERROR("sql.sql", "Level {} does not have XP for level data. Using data of level [{}] + 100.", level + 1, level);
4872 _playerXPperLevel[level] = _playerXPperLevel[level - 1] + 100;
4873 }
4874 }
4875
4876 LOG_INFO("server.loading", ">> Loaded {} XP For Level Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4877 LOG_INFO("server.loading", " ");
4878 }
4879}
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:194
@ CONFIG_START_PLAYER_LEVEL
Definition WorldConfig.h:193
@ CONFIG_EXPANSION
Definition WorldConfig.h:230
void PlayerCreateInfoAddItemHelper(uint32 race_, uint32 class_, uint32 itemId, int32 count)
Definition ObjectMgr.cpp:4216
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 ( )
1835{
1836 uint32 oldMSTime = getMSTime();
1837
1838 QueryResult result = WorldDatabase.Query("SELECT ShapeshiftID, RaceID, CustomizationID, GenderID, ModelID from player_shapeshift_model");
1839
1840 if (!result)
1841 {
1842 LOG_INFO("server.loading", ">> Loaded 0 player shapeshift model records. DB table `player_shapeshift_model` is empty.");
1843 return;
1844 }
1845
1846 uint32 count = 0;
1847 do
1848 {
1849 Field* fields = result->Fetch();
1850
1851 ShapeshiftForm shapeshiftForm = ShapeshiftForm(fields[0].Get<uint8>());
1852 uint8 race = fields[1].Get<uint8>();
1853 uint8 customizationID = fields[2].Get<uint8>();
1854 uint8 genderID = Gender(fields[3].Get<uint8>());
1855 uint32 modelId = fields[4].Get<uint32>();
1856
1857 ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race);
1858 if (!raceEntry)
1859 {
1860 LOG_ERROR("sql.sql", "Race {} defined in `player_shapeshift_model` does not exists, skipped.", uint32(race));
1861 continue;
1862 }
1863
1864 CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(modelId);
1865 if (!displayEntry)
1866 {
1867 LOG_ERROR("sql.sql", "ShapeshiftForm: {}, Race: {} defined in `player_shapeshift_model` has non-existing model ({}), skipped.", shapeshiftForm, race, modelId);
1868 continue;
1869 }
1870
1871 _playerShapeshiftModel[std::make_tuple(shapeshiftForm, race, customizationID, genderID)] = modelId;
1872 ++count;
1873 } while (result->NextRow());
1874
1875 LOG_INFO("server.loading", ">> Loaded {} player totem model records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1876 LOG_INFO("server.loading", " ");
1877}
Gender
Definition SharedDefines.h:60
ShapeshiftForm
Definition UnitDefines.h:68

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

◆ LoadPlayerTotemModels()

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

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

◆ LoadPointsOfInterest()

void ObjectMgr::LoadPointsOfInterest ( )
8458{
8459 uint32 oldMSTime = getMSTime();
8460
8461 _pointsOfInterestStore.clear(); // need for reload case
8462
8463 uint32 count = 0;
8464
8465 // 0 1 2 3 4 5 6
8466 QueryResult result = WorldDatabase.Query("SELECT ID, PositionX, PositionY, Icon, Flags, Importance, Name FROM points_of_interest");
8467
8468 if (!result)
8469 {
8470 LOG_WARN("server.loading", ">> Loaded 0 Points of Interest definitions. DB table `points_of_interest` is empty.");
8471 LOG_INFO("server.loading", " ");
8472 return;
8473 }
8474
8475 do
8476 {
8477 Field* fields = result->Fetch();
8478
8479 uint32 point_id = fields[0].Get<uint32>();
8480
8481 PointOfInterest POI;
8482 POI.ID = point_id;
8483 POI.PositionX = fields[1].Get<float>();
8484 POI.PositionY = fields[2].Get<float>();
8485 POI.Icon = fields[3].Get<uint32>();
8486 POI.Flags = fields[4].Get<uint32>();
8487 POI.Importance = fields[5].Get<uint32>();
8488 POI.Name = fields[6].Get<std::string>();
8489
8490 if (!Acore::IsValidMapCoord(POI.PositionX, POI.PositionY))
8491 {
8492 LOG_ERROR("sql.sql", "Table `points_of_interest` (ID: {}) have invalid coordinates (X: {} Y: {}), ignored.", point_id, POI.PositionX, POI.PositionY);
8493 continue;
8494 }
8495
8496 _pointsOfInterestStore[point_id] = POI;
8497
8498 ++count;
8499 } while (result->NextRow());
8500
8501 LOG_INFO("server.loading", ">> Loaded {} Points of Interest Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8502 LOG_INFO("server.loading", " ");
8503}
bool IsValidMapCoord(float c)
Definition GridDefines.h:210
Definition ObjectMgr.h:590
uint32 ID
Definition ObjectMgr.h:591

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

◆ LoadProfanityNamesFromDB()

void ObjectMgr::LoadProfanityNamesFromDB ( )
8880{
8881 uint32 oldMSTime = getMSTime();
8882
8883 _profanityNamesStore.clear(); // need for reload case
8884
8885 QueryResult result = CharacterDatabase.Query("SELECT name FROM profanity_name");
8886
8887 if (!result)
8888 {
8889 LOG_WARN("server.loading", ">> Loaded 0 profanity names. DB table `profanity_name` is empty!");
8890 return;
8891 }
8892
8893 uint32 count = 0;
8894
8895 Field* fields;
8896 do
8897 {
8898 fields = result->Fetch();
8899 std::string name = fields[0].Get<std::string>();
8900
8901 std::wstring wstr;
8902 if (!Utf8toWStr (name, wstr))
8903 {
8904 LOG_ERROR("sql.sql", "Table `profanity_name` have invalid name: {}", name);
8905 continue;
8906 }
8907
8908 wstrToLower(wstr);
8909
8910 _profanityNamesStore.insert(wstr);
8911 ++count;
8912 } while (result->NextRow());
8913
8914 LOG_INFO("server.loading", ">> Loaded {} profanity names from DB in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8915}

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

◆ LoadProfanityNamesFromDBC()

void ObjectMgr::LoadProfanityNamesFromDBC ( )
8918{
8919 if (!sWorld->getBoolConfig(CONFIG_STRICT_NAMES_PROFANITY))
8920 {
8921 LOG_WARN("server.loading", ">> Loaded 0 profanity names from DBC. Config option disabled.");
8922 return;
8923 }
8924
8925 uint32 oldMSTime = getMSTime();
8926
8927 uint32 count = 0;
8928
8929 for (NamesProfanityEntry const* profanityStore : sNamesProfanityStore)
8930 {
8931 std::wstring wstr;
8932
8933 Utf8toWStr(profanityStore->Pattern, wstr);
8934
8935 // DBC does not have clean entries, remove the junk.
8936 boost::algorithm::replace_all(wstr, "\\<", "");
8937 boost::algorithm::replace_all(wstr, "\\>", "");
8938
8939 _profanityNamesStore.insert(wstr);
8940 count++;
8941 }
8942
8943 LOG_INFO("server.loading", ">> Loaded {} profanity names from DBC in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8944 LOG_INFO("server.loading", " ");
8945}
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 ( )
6836{
6837 uint32 oldMSTime = getMSTime();
6838
6839 _questAreaTriggerStore.clear(); // need for reload case
6840
6841 QueryResult result = WorldDatabase.Query("SELECT id, quest FROM areatrigger_involvedrelation");
6842
6843 if (!result)
6844 {
6845 LOG_WARN("server.loading", ">> Loaded 0 quest trigger points. DB table `areatrigger_involvedrelation` is empty.");
6846 LOG_INFO("server.loading", " ");
6847 return;
6848 }
6849
6850 uint32 count = 0;
6851
6852 do
6853 {
6854 ++count;
6855
6856 Field* fields = result->Fetch();
6857
6858 uint32 trigger_ID = fields[0].Get<uint32>();
6859 uint32 quest_ID = fields[1].Get<uint32>();
6860
6861 AreaTrigger const* atEntry = GetAreaTrigger(trigger_ID);
6862 if (!atEntry)
6863 {
6864 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", trigger_ID);
6865 continue;
6866 }
6867
6868 Quest const* quest = GetQuestTemplate(quest_ID);
6869
6870 if (!quest)
6871 {
6872 LOG_ERROR("sql.sql", "Table `areatrigger_involvedrelation` has record (id: {}) for not existing quest {}", trigger_ID, quest_ID);
6873 continue;
6874 }
6875
6877 {
6878 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);
6879
6880 // this will prevent quest completing without objective
6881 const_cast<Quest*>(quest)->SetSpecialFlag(QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT);
6882
6883 // continue; - quest modified to required objective and trigger can be allowed.
6884 }
6885
6886 _questAreaTriggerStore[trigger_ID] = quest_ID;
6887 } while (result->NextRow());
6888
6889 LOG_INFO("server.loading", ">> Loaded {} Quest Trigger Points in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6890 LOG_INFO("server.loading", " ");
6891}
@ 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 ( )
6912{
6913 uint32 oldMSTime = getMSTime();
6914
6915 _questGreetingStore.clear(); // For reload case
6916
6917 // 0 1 2 3 4
6918 QueryResult result = WorldDatabase.Query("SELECT ID, Type, GreetEmoteType, GreetEmoteDelay, Greeting FROM quest_greeting");
6919 if (!result)
6920 {
6921 LOG_WARN("server.loading", ">> Loaded 0 quest greetings. DB table `quest_greeting` is empty.");
6922 return;
6923 }
6924
6925 do
6926 {
6927 Field* fields = result->Fetch();
6928
6929 uint32 id = fields[0].Get<uint32>();
6930 uint8 type = fields[1].Get<uint8>();
6931 switch (type)
6932 {
6933 case 0: // Creature
6934 if (!GetCreatureTemplate(id))
6935 {
6936 LOG_ERROR("sql.sql", "Table `quest_greeting`: creature template entry {} does not exist.", id);
6937 continue;
6938 }
6939 break;
6940 case 1: // GameObject
6941 if (!GetGameObjectTemplate(id))
6942 {
6943 LOG_ERROR("sql.sql", "Table `quest_greeting`: gameobject template entry {} does not exist.", id);
6944 continue;
6945 }
6946 break;
6947 default:
6948 LOG_ERROR("sql.sql", "Table `quest_greeting` has unknown type {} for id {}, skipped.", type, id);
6949 continue;
6950 }
6951
6952 std::pair<uint32, uint8> pairKey = std::make_pair(id, type);
6953 QuestGreeting& data = _questGreetingStore[pairKey];
6954
6955 data.EmoteType = fields[2].Get<uint16>();
6956 data.EmoteDelay = fields[3].Get<uint32>();
6957 AddLocaleString(fields[4].Get<std::string>(), LOCALE_enUS, data.Greeting);
6958 }
6959 while (result->NextRow());
6960
6961 LOG_INFO("server.loading", ">> Loaded {} quest_greeting in {} ms", _questGreetingStore.size(), GetMSTimeDiffToNow(oldMSTime));
6962 LOG_INFO("server.loading", " ");
6963}
Definition ObjectMgr.h:601
uint32 EmoteDelay
Definition ObjectMgr.h:603
std::vector< std::string > Greeting
Definition ObjectMgr.h:604
uint16 EmoteType
Definition ObjectMgr.h:602

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 ( )
6966{
6967 uint32 oldMSTime = getMSTime();
6968
6969 // 0 1 2 3
6970 QueryResult result = WorldDatabase.Query("SELECT ID, Type, Locale, Greeting FROM quest_greeting_locale");
6971 if (!result)
6972 {
6973 LOG_WARN("server.loading", ">> Loaded 0 quest_greeting locales. DB table `quest_greeting_locale` is empty.");
6974 return;
6975 }
6976
6977 uint32 localeCount = 0;
6978 do
6979 {
6980 Field* fields = result->Fetch();
6981
6982 uint32 id = fields[0].Get<uint32>();
6983 uint8 type = fields[1].Get<uint8>();
6984 switch (type)
6985 {
6986 case 0: // Creature
6987 if (!GetCreatureTemplate(id))
6988 {
6989 LOG_ERROR("sql.sql", "Table `quest_greeting_locale`: creature template entry {} does not exist.", id);
6990 continue;
6991 }
6992 break;
6993 case 1: // GameObject
6994 if (!GetGameObjectTemplate(id))
6995 {
6996 LOG_ERROR("sql.sql", "Table `quest_greeting_locale`: gameobject template entry {} does not exist.", id);
6997 continue;
6998 }
6999 break;
7000 default:
7001 continue;
7002 }
7003
7004 std::pair<uint32, uint8> pairKey = std::make_pair(id, type);
7005 QuestGreeting& data = _questGreetingStore[pairKey];
7006
7007 QuestGreetingContainer::iterator qgc = _questGreetingStore.find(pairKey);
7008 if (qgc == _questGreetingStore.end())
7009 {
7010 LOG_ERROR("sql.sql", "QuestGreeting (Id: {} Type: {}) found in table `quest_greeting_locale` but does not exist in `quest_greeting`. Skipped!", id, type);
7011 continue;
7012 }
7013
7014 LocaleConstant locale = GetLocaleByName(fields[2].Get<std::string>());
7015 if (locale == LOCALE_enUS)
7016 continue;
7017
7018 AddLocaleString(fields[3].Get<std::string>(), locale, data.Greeting);
7019 localeCount++;
7020 } while (result->NextRow());
7021
7022 LOG_INFO("server.loading", ">> Loaded {} quest greeting Locale Strings in {} ms", localeCount, GetMSTimeDiffToNow(oldMSTime));
7023 LOG_INFO("server.loading", " ");
7024}

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 ( )
5796{
5797 uint32 oldMSTime = getMSTime();
5798
5799 _questLocaleStore.clear(); // need for reload case
5800
5801 // 0 1 2 3 4 5 6 7 8 9 10
5802 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Title, Details, Objectives, EndText, CompletedText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4 FROM quest_template_locale");
5803
5804 if (!result)
5805 return;
5806
5807 do
5808 {
5809 Field* fields = result->Fetch();
5810
5811 uint32 ID = fields[0].Get<uint32>();
5812
5813 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
5814 if (locale == LOCALE_enUS)
5815 continue;
5816
5817 QuestLocale& data = _questLocaleStore[ID];
5818 AddLocaleString(fields[2].Get<std::string>(), locale, data.Title);
5819 AddLocaleString(fields[3].Get<std::string>(), locale, data.Details);
5820 AddLocaleString(fields[4].Get<std::string>(), locale, data.Objectives);
5821 AddLocaleString(fields[5].Get<std::string>(), locale, data.AreaDescription);
5822 AddLocaleString(fields[6].Get<std::string>(), locale, data.CompletedText);
5823
5824 for (uint8 i = 0; i < 4; ++i)
5825 AddLocaleString(fields[i + 7].Get<std::string>(), locale, data.ObjectiveText[i]);
5826 } while (result->NextRow());
5827
5828 LOG_INFO("server.loading", ">> Loaded {} Quest Locale Strings in {} ms", (uint32)_questLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
5829}
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 ( )
10904{
10905 uint32 oldMSTime = getMSTime();
10906
10907 _questMoneyRewards.clear();
10908
10909 // 0 1 2 3 4 5 6 7 8 9 10
10910 QueryResult result = WorldDatabase.Query("SELECT `Level`, Money0, Money1, Money2, Money3, Money4, Money5, Money6, Money7, Money8, Money9 FROM `quest_money_reward` ORDER BY `Level`");
10911 if (!result)
10912 {
10913 LOG_WARN("server.loading", ">> Loaded 0 quest money rewards. DB table `quest_money_reward` is empty.");
10914 return;
10915 }
10916
10917 uint32 count = 0;
10918 do
10919 {
10920 Field* fields = result->Fetch();
10921 uint32 Level = fields[0].Get<uint32>();
10922
10923 QuestMoneyRewardArray& questMoneyReward = _questMoneyRewards[Level];
10924 questMoneyReward.fill(0);
10925
10926 for (uint8 i = 0; i < MAX_QUEST_MONEY_REWARDS; ++i)
10927 {
10928 questMoneyReward[i] = fields[1 + i].Get<uint32>();
10929 ++count;
10930 }
10931 } while (result->NextRow());
10932
10933 LOG_INFO("server.loading", ">> Loaded {} Quest Money Rewards in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10934 LOG_INFO("server.loading", " ");
10935}
std::array< uint32, MAX_QUEST_MONEY_REWARDS > QuestMoneyRewardArray
Definition ObjectMgr.h:720

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

◆ LoadQuestOfferRewardLocale()

void ObjectMgr::LoadQuestOfferRewardLocale ( )
7027{
7028 uint32 oldMSTime = getMSTime();
7029
7030 _questOfferRewardLocaleStore.clear(); // need for reload case
7031
7032 // 0 1 2
7033 QueryResult result = WorldDatabase.Query("SELECT Id, locale, RewardText FROM quest_offer_reward_locale");
7034 if (!result)
7035 return;
7036
7037 do
7038 {
7039 Field* fields = result->Fetch();
7040
7041 uint32 id = fields[0].Get<uint32>();
7042 std::string localeName = fields[1].Get<std::string>();
7043
7044 LocaleConstant locale = GetLocaleByName(localeName);
7045 if (locale == LOCALE_enUS)
7046 continue;
7047
7049 AddLocaleString(fields[2].Get<std::string>(), locale, data.RewardText);
7050 } while (result->NextRow());
7051
7052 LOG_INFO("server.loading", ">> Loaded {} Quest Offer Reward Locale Strings in {} ms", _questOfferRewardLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
7053}
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 ( )
8506{
8507 if (!sWorld->getBoolConfig(CONFIG_QUEST_POI_ENABLED))
8508 {
8509 LOG_INFO("server.loading", ">> Loaded 0 quest POI definitions. Disabled by config.");
8510 LOG_INFO("server.loading", " ");
8511 return;
8512 }
8513
8514 uint32 oldMSTime = getMSTime();
8515
8516 _questPOIStore.clear(); // need for reload case
8517
8518 uint32 count = 0;
8519
8520 // 0 1 2 3 4 5 6 7
8521 QueryResult result = WorldDatabase.Query("SELECT QuestID, id, ObjectiveIndex, MapID, WorldMapAreaId, Floor, Priority, Flags FROM quest_poi order by QuestID");
8522
8523 if (!result)
8524 {
8525 LOG_WARN("server.loading", ">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty.");
8526 LOG_INFO("server.loading", " ");
8527 return;
8528 }
8529
8530 // 0 1 2 3
8531 QueryResult points = WorldDatabase.Query("SELECT QuestID, Idx1, X, Y FROM quest_poi_points ORDER BY QuestID DESC, Idx2");
8532
8533 std::vector<std::vector<std::vector<QuestPOIPoint> > > POIs;
8534
8535 if (points)
8536 {
8537 // The first result should have the highest questId
8538 Field* fields = points->Fetch();
8539 uint32 questIdMax = fields[0].Get<uint32>();
8540 POIs.resize(questIdMax + 1);
8541
8542 do
8543 {
8544 fields = points->Fetch();
8545
8546 uint32 questId = fields[0].Get<uint32>();
8547 uint32 id = fields[1].Get<uint32>();
8548 int32 x = fields[2].Get<int32>();
8549 int32 y = fields[3].Get<int32>();
8550
8551 if (POIs[questId].size() <= id + 1)
8552 POIs[questId].resize(id + 10);
8553
8554 QuestPOIPoint point(x, y);
8555 POIs[questId][id].push_back(point);
8556 } while (points->NextRow());
8557 }
8558
8559 do
8560 {
8561 Field* fields = result->Fetch();
8562
8563 uint32 questId = fields[0].Get<uint32>();
8564 uint32 id = fields[1].Get<uint32>();
8565 int32 objIndex = fields[2].Get<int32>();
8566 uint32 mapId = fields[3].Get<uint32>();
8567 uint32 WorldMapAreaId = fields[4].Get<uint32>();
8568 uint32 FloorId = fields[5].Get<uint32>();
8569 uint32 unk3 = fields[6].Get<uint32>();
8570 uint32 unk4 = fields[7].Get<uint32>();
8571
8572 QuestPOI POI(id, objIndex, mapId, WorldMapAreaId, FloorId, unk3, unk4);
8573 if (questId < POIs.size() && id < POIs[questId].size())
8574 {
8575 POI.points = POIs[questId][id];
8576 _questPOIStore[questId].push_back(POI);
8577 }
8578 else
8579 LOG_ERROR("sql.sql", "Table quest_poi references unknown quest points for quest {} POI id {}", questId, id);
8580
8581 ++count;
8582 } while (result->NextRow());
8583
8584 LOG_INFO("server.loading", ">> Loaded {} Quest POI definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8585 LOG_INFO("server.loading", " ");
8586}
@ CONFIG_QUEST_POI_ENABLED
Definition WorldConfig.h:136
Definition ObjectMgr.h:640
Definition ObjectMgr.h:649

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
8676{
8677 uint32 oldMSTime = getMSTime();
8678
8679 map.clear(); // need for reload case
8680
8681 uint32 count = 0;
8682
8683 QueryResult result = WorldDatabase.Query("SELECT id, quest, pool_entry FROM {} qr LEFT JOIN pool_quest pq ON qr.quest = pq.entry", table);
8684
8685 if (!result)
8686 {
8687 LOG_WARN("server.loading", ">> Loaded 0 quest relations from `{}`, table is empty.", table);
8688 LOG_INFO("server.loading", " ");
8689 return;
8690 }
8691
8692 PooledQuestRelation* poolRelationMap = go ? &sPoolMgr->mQuestGORelation : &sPoolMgr->mQuestCreatureRelation;
8693 if (starter)
8694 poolRelationMap->clear();
8695
8696 do
8697 {
8698 uint32 id = result->Fetch()[0].Get<uint32>();
8699 uint32 quest = result->Fetch()[1].Get<uint32>();
8700 uint32 poolId = result->Fetch()[2].Get<uint32>();
8701
8702 if (_questTemplates.find(quest) == _questTemplates.end())
8703 {
8704 LOG_ERROR("sql.sql", "Table `{}`: Quest {} listed for entry {} does not exist.", table, quest, id);
8705 continue;
8706 }
8707
8708 if (!poolId || !starter)
8709 map.insert(QuestRelations::value_type(id, quest));
8710 else if (starter)
8711 poolRelationMap->insert(PooledQuestRelation::value_type(quest, id));
8712
8713 ++count;
8714 } while (result->NextRow());
8715
8716 LOG_INFO("server.loading", ">> Loaded {} Quest Relations From {} in {} ms", count, table, GetMSTimeDiffToNow(oldMSTime));
8717 LOG_INFO("server.loading", " ");
8718}
#define sPoolMgr
Definition PoolMgr.h:165
std::multimap< uint32, uint32 > PooledQuestRelation
Definition PoolMgr.h:98

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

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

◆ LoadQuestRequestItemsLocale()

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

References _breadcrumbsForQuest, _questTemplates, _questTemplatesFast, Quest::AllowableRaces, CLASSMASK_ALL_PLAYABLE, SpellMgr::ComputeIsSpellValid(), DISABLE_TYPE_QUEST, SpellInfo::Effects, Quest::ExclusiveGroup, Quest::Flags, Field::Get(), Quest::GetBreadcrumbForQuestId(), Quest::GetCharTitleId(), GetCreatureTemplate(), Quest::GetExclusiveGroup(), GetGameObjectTemplate(), GetItemTemplate(), getMSTime(), GetMSTimeDiffToNow(), Quest::GetNextQuestId(), Quest::GetPrevQuestId(), Quest::GetQuestId(), Quest::GetQuestMethod(), GetQuestTemplate(), GetTalentSpellCost(), Quest::HasSpecialFlag(), SpellInfo::Id, Quest::ItemDrop, Quest::ItemDropQuantity, LOG_ERROR, LOG_INFO, LOG_WARN, MAX_SPELL_EFFECTS, mExclusiveQuestGroups, Quest::NextQuestId, Quest::PrevQuestId, Quest::prevQuests, QUEST_FLAGS_DAILY, QUEST_FLAGS_TRACKING, QUEST_FLAGS_WEEKLY, QUEST_ITEM_OBJECTIVES_COUNT, QUEST_OBJECTIVES_COUNT, QUEST_REPUTATIONS_COUNT, QUEST_REWARD_CHOICES_COUNT, QUEST_REWARDS_COUNT, QUEST_SOURCE_ITEM_IDS_COUNT, QUEST_SPECIAL_FLAGS_CAST, QUEST_SPECIAL_FLAGS_DB_ALLOWED, QUEST_SPECIAL_FLAGS_DELIVER, QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT, QUEST_SPECIAL_FLAGS_KILL, QUEST_SPECIAL_FLAGS_MONTHLY, QUEST_SPECIAL_FLAGS_PLAYER_KILL, QUEST_SPECIAL_FLAGS_REPEATABLE, QUEST_SPECIAL_FLAGS_SPEAKTO, QUEST_SPECIAL_FLAGS_TIMED, 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
958 {
959 LOG_INFO("server.loading", "Loading GO Start Quest Data...");
961 LOG_INFO("server.loading", "Loading GO End Quest Data...");
963 LOG_INFO("server.loading", "Loading Creature Start Quest Data...");
965 LOG_INFO("server.loading", "Loading Creature End Quest Data...");
967 }
void LoadCreatureQuestEnders()
Definition ObjectMgr.cpp:8762
void LoadGameobjectQuestEnders()
Definition ObjectMgr.cpp:8734
void LoadGameobjectQuestStarters()
Definition ObjectMgr.cpp:8720
void LoadCreatureQuestStarters()
Definition ObjectMgr.cpp:8748

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

◆ LoadReferenceVendor()

int ObjectMgr::LoadReferenceVendor ( int32  vendor,
int32  item_id,
std::set< uint32 > *  skip_vendors 
)
9871{
9872 // find all items from the reference vendor
9874 stmt->SetData(0, uint32(item));
9875 PreparedQueryResult result = WorldDatabase.Query(stmt);
9876
9877 if (!result)
9878 return 0;
9879
9880 uint32 count = 0;
9881 do
9882 {
9883 Field* fields = result->Fetch();
9884
9885 int32 item_id = fields[0].Get<int32>();
9886
9887 // if item is a negative, its a reference
9888 if (item_id < 0)
9889 count += LoadReferenceVendor(vendor, -item_id, skip_vendors);
9890 else
9891 {
9892 uint32 maxcount = fields[1].Get<uint32>();
9893 uint32 incrtime = fields[2].Get<uint32>();
9894 uint32 ExtendedCost = fields[3].Get<uint32>();
9895
9896 if (!IsVendorItemValid(vendor, item_id, maxcount, incrtime, ExtendedCost, nullptr, skip_vendors))
9897 continue;
9898
9899 VendorItemData& vList = _cacheVendorItemStore[vendor];
9900
9901 vList.AddItem(item_id, maxcount, incrtime, ExtendedCost);
9902 ++count;
9903 }
9904 } while (result->NextRow());
9905
9906 return count;
9907}
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition DatabaseEnvFwd.h:45
@ WORLD_SEL_NPC_VENDOR_REF
Definition WorldDatabase.h:45
bool IsVendorItemValid(uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player *player=nullptr, std::set< uint32 > *skip_vendors=nullptr, uint32 ORnpcflag=0) const
Definition ObjectMgr.cpp:10132
int LoadReferenceVendor(int32 vendor, int32 item_id, std::set< uint32 > *skip_vendors)
Definition ObjectMgr.cpp:9870

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 ( )
8267{
8268 uint32 oldMSTime = getMSTime();
8269
8270 // For reload case
8271 _repOnKillStore.clear();
8272
8273 uint32 count = 0;
8274
8275 // 0 1 2
8276 QueryResult result = WorldDatabase.Query("SELECT creature_id, RewOnKillRepFaction1, RewOnKillRepFaction2, "
8277 // 3 4 5 6 7 8 9
8278 "IsTeamAward1, MaxStanding1, RewOnKillRepValue1, IsTeamAward2, MaxStanding2, RewOnKillRepValue2, TeamDependent "
8279 "FROM creature_onkill_reputation");
8280
8281 if (!result)
8282 {
8283 LOG_WARN("server.loading", ">> Loaded 0 creature award reputation definitions. DB table `creature_onkill_reputation` is empty.");
8284 LOG_INFO("server.loading", " ");
8285 return;
8286 }
8287
8288 do
8289 {
8290 Field* fields = result->Fetch();
8291
8292 uint32 creature_id = fields[0].Get<uint32>();
8293
8294 ReputationOnKillEntry repOnKill;
8295 repOnKill.RepFaction1 = fields[1].Get<int16>();
8296 repOnKill.RepFaction2 = fields[2].Get<int16>();
8297 repOnKill.IsTeamAward1 = fields[3].Get<bool>();
8298 repOnKill.ReputationMaxCap1 = fields[4].Get<uint8>();
8299 repOnKill.RepValue1 = fields[5].Get<float>();
8300 repOnKill.IsTeamAward2 = fields[6].Get<bool>();
8301 repOnKill.ReputationMaxCap2 = fields[7].Get<uint8>();
8302 repOnKill.RepValue2 = fields[8].Get<float>();
8303 repOnKill.TeamDependent = fields[9].Get<uint8>();
8304
8305 if (!GetCreatureTemplate(creature_id))
8306 {
8307 LOG_ERROR("sql.sql", "Table `creature_onkill_reputation` have data for not existed creature entry ({}), skipped", creature_id);
8308 continue;
8309 }
8310
8311 if (repOnKill.RepFaction1)
8312 {
8313 FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(repOnKill.RepFaction1);
8314 if (!factionEntry1)
8315 {
8316 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.RepFaction1);
8317 continue;
8318 }
8319 }
8320
8321 if (repOnKill.RepFaction2)
8322 {
8323 FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(repOnKill.RepFaction2);
8324 if (!factionEntry2)
8325 {
8326 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.RepFaction2);
8327 continue;
8328 }
8329 }
8330
8331 _repOnKillStore[creature_id] = repOnKill;
8332
8333 ++count;
8334 } while (result->NextRow());
8335
8336 LOG_INFO("server.loading", ">> Loaded {} Creature Award Reputation Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8337 LOG_INFO("server.loading", " ");
8338}
Definition ObjectMgr.h:570
uint32 RepFaction1
Definition ObjectMgr.h:571

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

◆ LoadReputationRewardRate()

void ObjectMgr::LoadReputationRewardRate ( )
8179{
8180 uint32 oldMSTime = getMSTime();
8181
8182 _repRewardRateStore.clear(); // for reload case
8183
8184 uint32 count = 0; // 0 1 2 3 4 5 6 7
8185 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");
8186 if (!result)
8187 {
8188 LOG_INFO("server.loading", ">> Loaded `reputation_reward_rate`, table is empty!");
8189 return;
8190 }
8191
8192 do
8193 {
8194 Field* fields = result->Fetch();
8195
8196 uint32 factionId = fields[0].Get<uint32>();
8197
8198 RepRewardRate repRate;
8199
8200 repRate.questRate = fields[1].Get<float>();
8201 repRate.questDailyRate = fields[2].Get<float>();
8202 repRate.questWeeklyRate = fields[3].Get<float>();
8203 repRate.questMonthlyRate = fields[4].Get<float>();
8204 repRate.questRepeatableRate = fields[5].Get<float>();
8205 repRate.creatureRate = fields[6].Get<float>();
8206 repRate.spellRate = fields[7].Get<float>();
8207
8208 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
8209 if (!factionEntry)
8210 {
8211 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_reward_rate`", factionId);
8212 continue;
8213 }
8214
8215 if (repRate.questRate < 0.0f)
8216 {
8217 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_rate with invalid rate {}, skipping data for faction {}", repRate.questRate, factionId);
8218 continue;
8219 }
8220
8221 if (repRate.questDailyRate < 0.0f)
8222 {
8223 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_daily_rate with invalid rate {}, skipping data for faction {}", repRate.questDailyRate, factionId);
8224 continue;
8225 }
8226
8227 if (repRate.questWeeklyRate < 0.0f)
8228 {
8229 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_weekly_rate with invalid rate {}, skipping data for faction {}", repRate.questWeeklyRate, factionId);
8230 continue;
8231 }
8232
8233 if (repRate.questMonthlyRate < 0.0f)
8234 {
8235 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_monthly_rate with invalid rate {}, skipping data for faction {}", repRate.questMonthlyRate, factionId);
8236 continue;
8237 }
8238
8239 if (repRate.questRepeatableRate < 0.0f)
8240 {
8241 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_repeatable_rate with invalid rate {}, skipping data for faction {}", repRate.questRepeatableRate, factionId);
8242 continue;
8243 }
8244
8245 if (repRate.creatureRate < 0.0f)
8246 {
8247 LOG_ERROR("sql.sql", "Table reputation_reward_rate has creature_rate with invalid rate {}, skipping data for faction {}", repRate.creatureRate, factionId);
8248 continue;
8249 }
8250
8251 if (repRate.spellRate < 0.0f)
8252 {
8253 LOG_ERROR("sql.sql", "Table reputation_reward_rate has spell_rate with invalid rate {}, skipping data for faction {}", repRate.spellRate, factionId);
8254 continue;
8255 }
8256
8257 _repRewardRateStore[factionId] = repRate;
8258
8259 ++count;
8260 } while (result->NextRow());
8261
8262 LOG_INFO("server.loading", ">> Loaded {} Reputation Reward Rate in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8263 LOG_INFO("server.loading", " ");
8264}
Definition ObjectMgr.h:559
float questRate
Definition ObjectMgr.h:560

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

◆ LoadReputationSpilloverTemplate()

void ObjectMgr::LoadReputationSpilloverTemplate ( )
8341{
8342 uint32 oldMSTime = getMSTime();
8343
8344 _repSpilloverTemplateStore.clear(); // for reload case
8345
8346 uint32 count = 0; // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
8347 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");
8348
8349 if (!result)
8350 {
8351 LOG_INFO("server.loading", ">> Loaded `reputation_spillover_template`, table is empty.");
8352 LOG_INFO("server.loading", " ");
8353 return;
8354 }
8355
8356 do
8357 {
8358 Field* fields = result->Fetch();
8359
8360 uint32 factionId = fields[0].Get<uint16>();
8361
8362 RepSpilloverTemplate repTemplate;
8363
8364 repTemplate.faction[0] = fields[1].Get<uint16>();
8365 repTemplate.faction_rate[0] = fields[2].Get<float>();
8366 repTemplate.faction_rank[0] = fields[3].Get<uint8>();
8367 repTemplate.faction[1] = fields[4].Get<uint16>();
8368 repTemplate.faction_rate[1] = fields[5].Get<float>();
8369 repTemplate.faction_rank[1] = fields[6].Get<uint8>();
8370 repTemplate.faction[2] = fields[7].Get<uint16>();
8371 repTemplate.faction_rate[2] = fields[8].Get<float>();
8372 repTemplate.faction_rank[2] = fields[9].Get<uint8>();
8373 repTemplate.faction[3] = fields[10].Get<uint16>();
8374 repTemplate.faction_rate[3] = fields[11].Get<float>();
8375 repTemplate.faction_rank[3] = fields[12].Get<uint8>();
8376 repTemplate.faction[4] = fields[13].Get<uint16>();
8377 repTemplate.faction_rate[4] = fields[14].Get<float>();
8378 repTemplate.faction_rank[4] = fields[15].Get<uint8>();
8379 repTemplate.faction[5] = fields[16].Get<uint16>();
8380 repTemplate.faction_rate[5] = fields[17].Get<float>();
8381 repTemplate.faction_rank[5] = fields[18].Get<uint8>();
8382
8383 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
8384
8385 if (!factionEntry)
8386 {
8387 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", factionId);
8388 continue;
8389 }
8390
8391 if (factionEntry->team == 0)
8392 {
8393 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} in `reputation_spillover_template` does not belong to any team, skipping", factionId);
8394 continue;
8395 }
8396
8397 for (uint32 i = 0; i < MAX_SPILLOVER_FACTIONS; ++i)
8398 {
8399 if (repTemplate.faction[i])
8400 {
8401 FactionEntry const* factionSpillover = sFactionStore.LookupEntry(repTemplate.faction[i]);
8402
8403 if (!factionSpillover)
8404 {
8405 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);
8406 continue;
8407 }
8408
8409 if (factionSpillover->reputationListID < 0)
8410 {
8411 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);
8412 continue;
8413 }
8414
8415 if (repTemplate.faction_rank[i] >= MAX_REPUTATION_RANK)
8416 {
8417 LOG_ERROR("sql.sql", "Rank {} used in `reputation_spillover_template` for spillover faction {} is not valid, skipping", repTemplate.faction_rank[i], repTemplate.faction[i]);
8418 continue;
8419 }
8420 }
8421 }
8422
8423 FactionEntry const* factionEntry0 = sFactionStore.LookupEntry(repTemplate.faction[0]);
8424 if (repTemplate.faction[0] && !factionEntry0)
8425 {
8426 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[0]);
8427 continue;
8428 }
8429 FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(repTemplate.faction[1]);
8430 if (repTemplate.faction[1] && !factionEntry1)
8431 {
8432 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[1]);
8433 continue;
8434 }
8435 FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(repTemplate.faction[2]);
8436 if (repTemplate.faction[2] && !factionEntry2)
8437 {
8438 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[2]);
8439 continue;
8440 }
8441 FactionEntry const* factionEntry3 = sFactionStore.LookupEntry(repTemplate.faction[3]);
8442 if (repTemplate.faction[3] && !factionEntry3)
8443 {
8444 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[3]);
8445 continue;
8446 }
8447
8448 _repSpilloverTemplateStore[factionId] = repTemplate;
8449
8450 ++count;
8451 } while (result->NextRow());
8452
8453 LOG_INFO("server.loading", ">> Loaded {} Reputation Spillover Template in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8454 LOG_INFO("server.loading", " ");
8455}
#define MAX_SPILLOVER_FACTIONS
Definition SharedDefines.h:235
int32 reputationListID
Definition DBCStructure.h:909
Definition ObjectMgr.h:583
uint32 faction[MAX_SPILLOVER_FACTIONS]
Definition ObjectMgr.h:584

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 ( )
8777{
8778 uint32 oldMSTime = getMSTime();
8779
8780 _reservedNamesStore.clear(); // need for reload case
8781
8782 QueryResult result = CharacterDatabase.Query("SELECT name FROM reserved_name");
8783
8784 if (!result)
8785 {
8786 LOG_WARN("server.loading", ">> Loaded 0 reserved names. DB table `reserved_name` is empty!");
8787 return;
8788 }
8789
8790 uint32 count = 0;
8791
8792 Field* fields;
8793 do
8794 {
8795 fields = result->Fetch();
8796 std::string name = fields[0].Get<std::string>();
8797
8798 std::wstring wstr;
8799 if (!Utf8toWStr (name, wstr))
8800 {
8801 LOG_ERROR("sql.sql", "Table `reserved_name` have invalid name: {}", name);
8802 continue;
8803 }
8804
8805 wstrToLower(wstr);
8806
8807 _reservedNamesStore.insert(wstr);
8808 ++count;
8809 } while (result->NextRow());
8810
8811 LOG_INFO("server.loading", ">> Loaded {} reserved names from DB in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8812}

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

◆ LoadReservedPlayerNamesDBC()

void ObjectMgr::LoadReservedPlayerNamesDBC ( )
8815{
8816 if (!sWorld->getBoolConfig(CONFIG_STRICT_NAMES_RESERVED))
8817 {
8818 LOG_WARN("server.loading", ">> Loaded 0 reserved names from DBC. Config option disabled.");
8819 return;
8820 }
8821
8822 uint32 oldMSTime = getMSTime();
8823
8824 uint32 count = 0;
8825
8826 for (NamesReservedEntry const* reservedStore : sNamesReservedStore)
8827 {
8828 std::wstring wstr;
8829
8830 Utf8toWStr(reservedStore->Pattern, wstr);
8831
8832 // DBC does not have clean entries, remove the junk.
8833 boost::algorithm::replace_all(wstr, "\\<", "");
8834 boost::algorithm::replace_all(wstr, "\\>", "");
8835
8836 _reservedNamesStore.insert(wstr);
8837 count++;
8838 }
8839
8840 LOG_INFO("server.loading", ">> Loaded {} reserved names from DBC in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8841 LOG_INFO("server.loading", " ");
8842}
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 ( )
10213{
10214 uint32 oldMSTime = getMSTime();
10215
10216 // We insert an empty placeholder here so we can use the
10217 // script id 0 as dummy for "no script found".
10218 _scriptNamesStore.emplace_back("");
10219
10220 QueryResult result = WorldDatabase.Query(
10221 "SELECT DISTINCT(ScriptName) FROM achievement_criteria_data WHERE ScriptName <> '' AND type = 11 "
10222 "UNION "
10223 "SELECT DISTINCT(ScriptName) FROM battleground_template WHERE ScriptName <> '' "
10224 "UNION "
10225 "SELECT DISTINCT(ScriptName) FROM creature WHERE ScriptName <> '' "
10226 "UNION "
10227 "SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' "
10228 "UNION "
10229 "SELECT DISTINCT(ScriptName) FROM gameobject WHERE ScriptName <> '' "
10230 "UNION "
10231 "SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' "
10232 "UNION "
10233 "SELECT DISTINCT(ScriptName) FROM item_template WHERE ScriptName <> '' "
10234 "UNION "
10235 "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
10236 "UNION "
10237 "SELECT DISTINCT(ScriptName) FROM spell_script_names WHERE ScriptName <> '' "
10238 "UNION "
10239 "SELECT DISTINCT(ScriptName) FROM transports WHERE ScriptName <> '' "
10240 "UNION "
10241 "SELECT DISTINCT(ScriptName) FROM game_weather WHERE ScriptName <> '' "
10242 "UNION "
10243 "SELECT DISTINCT(ScriptName) FROM conditions WHERE ScriptName <> '' "
10244 "UNION "
10245 "SELECT DISTINCT(ScriptName) FROM outdoorpvp_template WHERE ScriptName <> '' "
10246 "UNION "
10247 "SELECT DISTINCT(script) FROM instance_template WHERE script <> ''");
10248
10249 if (!result)
10250 {
10251 LOG_INFO("server.loading", " ");
10252 LOG_ERROR("sql.sql", ">> Loaded empty set of Script Names!");
10253 return;
10254 }
10255
10256 _scriptNamesStore.reserve(result->GetRowCount() + 1);
10257
10258 do
10259 {
10260 _scriptNamesStore.push_back((*result)[0].Get<std::string>());
10261 } while (result->NextRow());
10262
10263 std::sort(_scriptNamesStore.begin(), _scriptNamesStore.end());
10264 LOG_INFO("server.loading", ">> Loaded {} ScriptNames in {} ms", _scriptNamesStore.size(), GetMSTimeDiffToNow(oldMSTime));
10265 LOG_INFO("server.loading", " ");
10266}

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

◆ LoadScripts()

void ObjectMgr::LoadScripts ( ScriptsType  type)
private
5832{
5833 uint32 oldMSTime = getMSTime();
5834
5835 ScriptMapMap* scripts = GetScriptsMapByType(type);
5836 if (!scripts)
5837 return;
5838
5839 std::string tableName = GetScriptsTableNameByType(type);
5840 if (tableName.empty())
5841 return;
5842
5843 if (sScriptMgr->IsScriptScheduled()) // function cannot be called when scripts are in use.
5844 return;
5845
5846 LOG_INFO("server.loading", "Loading {}...", tableName);
5847
5848 scripts->clear(); // need for reload support
5849
5850 bool isSpellScriptTable = (type == SCRIPTS_SPELL);
5851 // 0 1 2 3 4 5 6 7 8 9
5852 QueryResult result = WorldDatabase.Query("SELECT id, delay, command, datalong, datalong2, dataint, x, y, z, o{} FROM {}", isSpellScriptTable ? ", effIndex" : "", tableName);
5853
5854 if (!result)
5855 {
5856 LOG_WARN("server.loading", ">> Loaded 0 script definitions. DB table `{}` is empty!", tableName);
5857 LOG_INFO("server.loading", " ");
5858 return;
5859 }
5860
5861 uint32 count = 0;
5862
5863 do
5864 {
5865 Field* fields = result->Fetch();
5866 ScriptInfo tmp;
5867 tmp.type = type;
5868 tmp.id = fields[0].Get<uint32>();
5869 if (isSpellScriptTable)
5870 tmp.id |= fields[10].Get<uint8>() << 24;
5871 tmp.delay = fields[1].Get<uint32>();
5872 tmp.command = ScriptCommands(fields[2].Get<uint32>());
5873 tmp.Raw.nData[0] = fields[3].Get<uint32>();
5874 tmp.Raw.nData[1] = fields[4].Get<uint32>();
5875 tmp.Raw.nData[2] = fields[5].Get<int32>();
5876 tmp.Raw.fData[0] = fields[6].Get<float>();
5877 tmp.Raw.fData[1] = fields[7].Get<float>();
5878 tmp.Raw.fData[2] = fields[8].Get<float>();
5879 tmp.Raw.fData[3] = fields[9].Get<float>();
5880
5881 // generic command args check
5882 switch (tmp.command)
5883 {
5885 {
5887 {
5888 LOG_ERROR("sql.sql", "Table `{}` has invalid talk type (datalong = {}) in SCRIPT_COMMAND_TALK for script id {}",
5889 tableName, tmp.Talk.ChatType, tmp.id);
5890 continue;
5891 }
5893 {
5894 LOG_ERROR("sql.sql", "Table `{}` has invalid talk text id (dataint = {}) in SCRIPT_COMMAND_TALK for script id {}",
5895 tableName, tmp.Talk.TextID, tmp.id);
5896 continue;
5897 }
5898 break;
5899 }
5900
5902 {
5903 if (!sEmotesStore.LookupEntry(tmp.Emote.EmoteID))
5904 {
5905 LOG_ERROR("sql.sql", "Table `{}` has invalid emote id (datalong = {}) in SCRIPT_COMMAND_EMOTE for script id {}",
5906 tableName, tmp.Emote.EmoteID, tmp.id);
5907 continue;
5908 }
5909 break;
5910 }
5911
5913 {
5914 if (!sMapStore.LookupEntry(tmp.TeleportTo.MapID))
5915 {
5916 LOG_ERROR("sql.sql", "Table `{}` has invalid map (Id: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
5917 tableName, tmp.TeleportTo.MapID, tmp.id);
5918 continue;
5919 }
5920
5922 {
5923 LOG_ERROR("sql.sql", "Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
5924 tableName, tmp.TeleportTo.DestX, tmp.TeleportTo.DestY, tmp.TeleportTo.DestZ, tmp.TeleportTo.Orientation, tmp.id);
5925 continue;
5926 }
5927 break;
5928 }
5929
5931 {
5932 Quest const* quest = GetQuestTemplate(tmp.QuestExplored.QuestID);
5933 if (!quest)
5934 {
5935 LOG_ERROR("sql.sql", "Table `{}` has invalid quest (ID: {}) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id {}",
5936 tableName, tmp.QuestExplored.QuestID, tmp.id);
5937 continue;
5938 }
5939
5941 {
5942 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.",
5943 tableName, tmp.QuestExplored.QuestID, tmp.id);
5944
5945 // this will prevent quest completing without objective
5946 const_cast<Quest*>(quest)->SetSpecialFlag(QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT);
5947
5948 // continue; - quest objective requirement set and command can be allowed
5949 }
5950
5952 {
5953 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 {}",
5954 tableName, tmp.QuestExplored.Distance, tmp.id);
5955 continue;
5956 }
5957
5959 {
5960 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",
5962 continue;
5963 }
5964
5966 {
5967 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",
5968 tableName, tmp.QuestExplored.Distance, tmp.id, INTERACTION_DISTANCE);
5969 continue;
5970 }
5971
5972 break;
5973 }
5974
5976 {
5978 {
5979 LOG_ERROR("sql.sql", "Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_KILL_CREDIT for script id {}",
5980 tableName, tmp.KillCredit.CreatureEntry, tmp.id);
5981 continue;
5982 }
5983 break;
5984 }
5985
5987 {
5989 if (!data)
5990 {
5991 LOG_ERROR("sql.sql", "Table `{}` has invalid gameobject (GUID: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5992 tableName, tmp.RespawnGameobject.GOGuid, tmp.id);
5993 continue;
5994 }
5995
5996 GameObjectTemplate const* info = GetGameObjectTemplate(data->id);
5997 if (!info)
5998 {
5999 LOG_ERROR("sql.sql", "Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
6000 tableName, tmp.RespawnGameobject.GOGuid, data->id, tmp.id);
6001 continue;
6002 }
6003
6004 if (info->type == GAMEOBJECT_TYPE_FISHINGNODE ||
6006 info->type == GAMEOBJECT_TYPE_DOOR ||
6007 info->type == GAMEOBJECT_TYPE_BUTTON ||
6008 info->type == GAMEOBJECT_TYPE_TRAP)
6009 {
6010 LOG_ERROR("sql.sql", "Table `{}` have gameobject type ({}) unsupported by command SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
6011 tableName, info->entry, tmp.id);
6012 continue;
6013 }
6014 break;
6015 }
6016
6018 {
6020 {
6021 LOG_ERROR("sql.sql", "Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
6023 continue;
6024 }
6025
6027 if (!GetCreatureTemplate(entry))
6028 {
6029 LOG_ERROR("sql.sql", "Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
6030 tableName, tmp.TempSummonCreature.CreatureEntry, tmp.id);
6031 continue;
6032 }
6033 break;
6034 }
6035
6038 {
6040 if (!data)
6041 {
6042 LOG_ERROR("sql.sql", "Table `{}` has invalid gameobject (GUID: {}) in {} for script id {}",
6043 tableName, tmp.ToggleDoor.GOGuid, GetScriptCommandName(tmp.command), tmp.id);
6044 continue;
6045 }
6046
6047 GameObjectTemplate const* info = GetGameObjectTemplate(data->id);
6048 if (!info)
6049 {
6050 LOG_ERROR("sql.sql", "Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in {} for script id {}",
6051 tableName, tmp.ToggleDoor.GOGuid, data->id, GetScriptCommandName(tmp.command), tmp.id);
6052 continue;
6053 }
6054
6055 if (info->type != GAMEOBJECT_TYPE_DOOR)
6056 {
6057 LOG_ERROR("sql.sql", "Table `{}` has gameobject type ({}) non supported by command {} for script id {}",
6058 tableName, info->entry, GetScriptCommandName(tmp.command), tmp.id);
6059 continue;
6060 }
6061
6062 break;
6063 }
6064
6066 {
6067 if (!sSpellMgr->GetSpellInfo(tmp.RemoveAura.SpellID))
6068 {
6069 LOG_ERROR("sql.sql", "Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
6070 tableName, tmp.RemoveAura.SpellID, tmp.id);
6071 continue;
6072 }
6073 if (tmp.RemoveAura.Flags & ~0x1) // 1 bits (0, 1)
6074 {
6075 LOG_ERROR("sql.sql", "Table `{}` using unknown flags in datalong2 ({}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
6076 tableName, tmp.RemoveAura.Flags, tmp.id);
6077 continue;
6078 }
6079 break;
6080 }
6081
6083 {
6084 if (!sSpellMgr->GetSpellInfo(tmp.CastSpell.SpellID))
6085 {
6086 LOG_ERROR("sql.sql", "Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
6087 tableName, tmp.CastSpell.SpellID, tmp.id);
6088 continue;
6089 }
6090 if (tmp.CastSpell.Flags > 4) // targeting type
6091 {
6092 LOG_ERROR("sql.sql", "Table `{}` using unknown target in datalong2 ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
6093 tableName, tmp.CastSpell.Flags, tmp.id);
6094 continue;
6095 }
6096 if (tmp.CastSpell.Flags != 4 && tmp.CastSpell.CreatureEntry & ~0x1) // 1 bit (0, 1)
6097 {
6098 LOG_ERROR("sql.sql", "Table `{}` using unknown flags in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
6099 tableName, tmp.CastSpell.CreatureEntry, tmp.id);
6100 continue;
6101 }
6102 else if (tmp.CastSpell.Flags == 4 && !GetCreatureTemplate(tmp.CastSpell.CreatureEntry))
6103 {
6104 LOG_ERROR("sql.sql", "Table `{}` using invalid creature entry in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
6105 tableName, tmp.CastSpell.CreatureEntry, tmp.id);
6106 continue;
6107 }
6108 break;
6109 }
6110
6112 {
6114 {
6115 LOG_ERROR("sql.sql", "Table `{}` has nonexistent item (entry: {}) in SCRIPT_COMMAND_CREATE_ITEM for script id {}",
6116 tableName, tmp.CreateItem.ItemEntry, tmp.id);
6117 continue;
6118 }
6119 if (!tmp.CreateItem.Amount)
6120 {
6121 LOG_ERROR("sql.sql", "Table `{}` SCRIPT_COMMAND_CREATE_ITEM but amount is {} for script id {}",
6122 tableName, tmp.CreateItem.Amount, tmp.id);
6123 continue;
6124 }
6125 break;
6126 }
6127 default:
6128 break;
6129 }
6130
6131 if (scripts->find(tmp.id) == scripts->end())
6132 {
6133 ScriptMap emptyMap;
6134 (*scripts)[tmp.id] = emptyMap;
6135 }
6136 (*scripts)[tmp.id].insert(std::pair<uint32, ScriptInfo>(tmp.delay, tmp));
6137
6138 ++count;
6139 } while (result->NextRow());
6140
6141 LOG_INFO("server.loading", ">> Loaded {} script definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6142 LOG_INFO("server.loading", " ");
6143}
@ CHAT_TYPE_WHISPER
Definition CreatureData.h:426
#define DEFAULT_VISIBILITY_DISTANCE
Definition ObjectDefines.h:39
#define INTERACTION_DISTANCE
Definition ObjectDefines.h:24
std::multimap< uint32, ScriptInfo > ScriptMap
Definition ObjectMgr.h:386
ScriptMapMap * GetScriptsMapByType(ScriptsType type)
Definition ObjectMgr.cpp:84
ScriptCommands
Definition ObjectMgr.h:92
@ SCRIPT_COMMAND_EMOTE
Definition ObjectMgr.h:94
@ SCRIPT_COMMAND_CREATE_ITEM
Definition ObjectMgr.h:110
@ SCRIPT_COMMAND_CLOSE_DOOR
Definition ObjectMgr.h:105
@ SCRIPT_COMMAND_CAST_SPELL
Definition ObjectMgr.h:108
@ SCRIPT_COMMAND_RESPAWN_GAMEOBJECT
Definition ObjectMgr.h:102
@ SCRIPT_COMMAND_QUEST_EXPLORED
Definition ObjectMgr.h:100
@ SCRIPT_COMMAND_TALK
Definition ObjectMgr.h:93
@ SCRIPT_COMMAND_OPEN_DOOR
Definition ObjectMgr.h:104
@ SCRIPT_COMMAND_TELEPORT_TO
Definition ObjectMgr.h:99
@ SCRIPT_COMMAND_TEMP_SUMMON_CREATURE
Definition ObjectMgr.h:103
@ SCRIPT_COMMAND_KILL_CREDIT
Definition ObjectMgr.h:101
@ SCRIPT_COMMAND_REMOVE_AURA
Definition ObjectMgr.h:107
std::string GetScriptCommandName(ScriptCommands command)
Definition ObjectMgr.cpp:104
std::map< uint32, ScriptMap > ScriptMapMap
Definition ObjectMgr.h:387
std::string GetScriptsTableNameByType(ScriptsType type)
Definition ObjectMgr.cpp:64
@ SCRIPTS_SPELL
Definition ObjectMgr.h:149
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition SharedDefines.h:1565
@ CHAT_MSG_RAID_BOSS_WHISPER
Definition SharedDefines.h:3411
Definition ObjectMgr.h:191
float Orientation
Definition ObjectMgr.h:251
uint32 Flags
Definition ObjectMgr.h:208
ScriptsType type
Definition ObjectMgr.h:192
uint32 QuestID
Definition ObjectMgr.h:256
int32 TextID
Definition ObjectMgr.h:209
struct ScriptInfo::@271::@285 RemoveAura
float DestX
Definition ObjectMgr.h:230
uint32 ItemEntry
Definition ObjectMgr.h:317
uint32 ChatType
Definition ObjectMgr.h:207
uint32 id
Definition ObjectMgr.h:193
struct ScriptInfo::@271::@279 TeleportTo
uint32 delay
Definition ObjectMgr.h:194
float fData[4]
Definition ObjectMgr.h:202
struct ScriptInfo::@271::@284 ToggleDoor
struct ScriptInfo::@271::@280 QuestExplored
float PosY
Definition ObjectMgr.h:279
ScriptCommands command
Definition ObjectMgr.h:195
float DestY
Definition ObjectMgr.h:231
struct ScriptInfo::@271::@274 Talk
uint32 MapID
Definition ObjectMgr.h:244
uint32 nData[3]
Definition ObjectMgr.h:201
struct ScriptInfo::@271::@281 KillCredit
struct ScriptInfo::@271::@282 RespawnGameobject
float PosZ
Definition ObjectMgr.h:280
struct ScriptInfo::@271::@286 CastSpell
struct ScriptInfo::@271::@273 Raw
struct ScriptInfo::@271::@288 CreateItem
float PosX
Definition ObjectMgr.h:278
uint32 Distance
Definition ObjectMgr.h:257
uint32 SpellID
Definition ObjectMgr.h:295
struct ScriptInfo::@271::@283 TempSummonCreature
float DestZ
Definition ObjectMgr.h:232
uint32 GOGuid
Definition ObjectMgr.h:268
struct ScriptInfo::@271::@275 Emote
uint32 CreatureEntry
Definition ObjectMgr.h:262
uint32 Amount
Definition ObjectMgr.h:318
uint32 EmoteID
Definition ObjectMgr.h:214

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

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

◆ LoadSpellScriptNames()

void ObjectMgr::LoadSpellScriptNames ( )
6245{
6246 uint32 oldMSTime = getMSTime();
6247
6248 _spellScriptsStore.clear(); // need for reload case
6249
6250 QueryResult result = WorldDatabase.Query("SELECT spell_id, ScriptName FROM spell_script_names");
6251
6252 if (!result)
6253 {
6254 LOG_WARN("server.loading", ">> Loaded 0 spell script names. DB table `spell_script_names` is empty!");
6255 LOG_INFO("server.loading", " ");
6256 return;
6257 }
6258
6259 uint32 count = 0;
6260
6261 do
6262 {
6263 Field* fields = result->Fetch();
6264
6265 int32 spellId = fields[0].Get<int32>();
6266 std::string scriptName = fields[1].Get<std::string>();
6267
6268 bool allRanks = false;
6269 if (spellId <= 0)
6270 {
6271 allRanks = true;
6272 spellId = -spellId;
6273 }
6274
6275 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
6276 if (!spellInfo)
6277 {
6278 LOG_ERROR("sql.sql", "Scriptname: `{}` spell (spell_id:{}) does not exist in `Spell.dbc`.", scriptName, fields[0].Get<int32>());
6279 continue;
6280 }
6281
6282 if (allRanks)
6283 {
6284 if (sSpellMgr->GetFirstSpellInChain(spellId) != uint32(spellId))
6285 {
6286 LOG_ERROR("sql.sql", "Scriptname: `{}` spell (spell_id:{}) is not first rank of spell.", scriptName, fields[0].Get<int32>());
6287 continue;
6288 }
6289 while (spellInfo)
6290 {
6291 _spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, GetScriptId(scriptName)));
6292 spellInfo = spellInfo->GetNextRankSpell();
6293 }
6294 }
6295 else
6296 _spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, GetScriptId(scriptName)));
6297 ++count;
6298 } while (result->NextRow());
6299
6300 LOG_INFO("server.loading", ">> Loaded {} spell script names in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6301 LOG_INFO("server.loading", " ");
6302}
SpellInfo const * GetNextRankSpell() const
Definition SpellInfo.cpp:2412

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

◆ LoadSpellScripts()

void ObjectMgr::LoadSpellScripts ( )
6146{
6148
6149 // check ids
6150 for (ScriptMapMap::const_iterator itr = sSpellScripts.begin(); itr != sSpellScripts.end(); ++itr)
6151 {
6152 uint32 spellId = uint32(itr->first) & 0x00FFFFFF;
6153 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
6154
6155 if (!spellInfo)
6156 {
6157 LOG_ERROR("sql.sql", "Table `spell_scripts` has not existing spell (Id: {}) as script id", spellId);
6158 continue;
6159 }
6160
6161 SpellEffIndex i = SpellEffIndex((uint32(itr->first) >> 24) & 0x000000FF);
6162 if (uint32(i) >= MAX_SPELL_EFFECTS)
6163 {
6164 LOG_ERROR("sql.sql", "Table `spell_scripts` has too high effect index {} for spell (Id: {}) as script id", uint32(i), spellId);
6165 }
6166
6167 //check for correct spellEffect
6168 if (!spellInfo->Effects[i].Effect || (spellInfo->Effects[i].Effect != SPELL_EFFECT_SCRIPT_EFFECT && spellInfo->Effects[i].Effect != SPELL_EFFECT_DUMMY))
6169 LOG_ERROR("sql.sql", "Table `spell_scripts` - spell {} effect {} is not SPELL_EFFECT_SCRIPT_EFFECT or SPELL_EFFECT_DUMMY", spellId, uint32(i));
6170 }
6171}
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 ( )
7085{
7086 uint32 oldMSTime = getMSTime();
7087
7088 _tavernAreaTriggerStore.clear(); // need for reload case
7089
7090 QueryResult result = WorldDatabase.Query("SELECT id, faction FROM areatrigger_tavern");
7091
7092 if (!result)
7093 {
7094 LOG_WARN("server.loading", ">> Loaded 0 tavern triggers. DB table `areatrigger_tavern` is empty.");
7095 LOG_INFO("server.loading", " ");
7096 return;
7097 }
7098
7099 uint32 count = 0;
7100
7101 do
7102 {
7103 ++count;
7104
7105 Field* fields = result->Fetch();
7106
7107 uint32 Trigger_ID = fields[0].Get<uint32>();
7108
7109 AreaTrigger const* atEntry = GetAreaTrigger(Trigger_ID);
7110 if (!atEntry)
7111 {
7112 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
7113 continue;
7114 }
7115
7116 uint32 faction = fields[1].Get<uint32>();
7117
7118 _tavernAreaTriggerStore.emplace(Trigger_ID, faction);
7119 } while (result->NextRow());
7120
7121 LOG_INFO("server.loading", ">> Loaded {} Tavern Triggers in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7122 LOG_INFO("server.loading", " ");
7123}

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

◆ LoadTempSummons()

void ObjectMgr::LoadTempSummons ( )
2141{
2142 uint32 oldMSTime = getMSTime();
2143
2144 // 0 1 2 3 4 5 6 7 8 9
2145 QueryResult result = WorldDatabase.Query("SELECT summonerId, summonerType, groupId, entry, position_x, position_y, position_z, orientation, summonType, summonTime FROM creature_summon_groups");
2146
2147 if (!result)
2148 {
2149 LOG_WARN("server.loading", ">> Loaded 0 temp summons. DB table `creature_summon_groups` is empty.");
2150 return;
2151 }
2152
2153 uint32 count = 0;
2154 do
2155 {
2156 Field* fields = result->Fetch();
2157
2158 uint32 summonerId = fields[0].Get<uint32>();
2159 SummonerType summonerType = SummonerType(fields[1].Get<uint8>());
2160 uint8 group = fields[2].Get<uint8>();
2161
2162 switch (summonerType)
2163 {
2165 if (!GetCreatureTemplate(summonerId))
2166 {
2167 LOG_ERROR("sql.sql", "Table `creature_summon_groups` has summoner with non existing entry {} for creature summoner type, skipped.", summonerId);
2168 continue;
2169 }
2170 break;
2172 if (!GetGameObjectTemplate(summonerId))
2173 {
2174 LOG_ERROR("sql.sql", "Table `creature_summon_groups` has summoner with non existing entry {} for gameobject summoner type, skipped.", summonerId);
2175 continue;
2176 }
2177 break;
2178 case SUMMONER_TYPE_MAP:
2179 if (!sMapStore.LookupEntry(summonerId))
2180 {
2181 LOG_ERROR("sql.sql", "Table `creature_summon_groups` has summoner with non existing entry {} for map summoner type, skipped.", summonerId);
2182 continue;
2183 }
2184 break;
2185 default:
2186 LOG_ERROR("sql.sql", "Table `creature_summon_groups` has unhandled summoner type {} for summoner {}, skipped.", summonerType, summonerId);
2187 continue;
2188 }
2189
2190 TempSummonData data;
2191 data.entry = fields[3].Get<uint32>();
2192
2193 if (!GetCreatureTemplate(data.entry))
2194 {
2195 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);
2196 continue;
2197 }
2198
2199 float posX = fields[4].Get<float>();
2200 float posY = fields[5].Get<float>();
2201 float posZ = fields[6].Get<float>();
2202 float orientation = fields[7].Get<float>();
2203
2204 data.pos.Relocate(posX, posY, posZ, orientation);
2205
2206 data.type = TempSummonType(fields[8].Get<uint8>());
2207
2209 {
2210 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);
2211 continue;
2212 }
2213
2214 data.time = fields[9].Get<uint32>();
2215
2216 TempSummonGroupKey key(summonerId, summonerType, group);
2217 _tempSummonDataStore[key].push_back(data);
2218
2219 ++count;
2220 } while (result->NextRow());
2221
2222 LOG_INFO("server.loading", ">> Loaded {} Temporary Summons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2223 LOG_INFO("server.loading", " ");
2224}
TempSummonType
Definition Object.h:47
@ TEMPSUMMON_MANUAL_DESPAWN
Definition Object.h:55
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 ( )
9717{
9718 uint32 oldMSTime = getMSTime();
9719
9720 // For reload case
9721 _trainers.clear();
9722
9723 std::unordered_map<int32, std::vector<Trainer::Spell>> spellsByTrainer;
9724 if (QueryResult trainerSpellsResult = WorldDatabase.Query("SELECT TrainerId, SpellId, MoneyCost, ReqSkillLine, ReqSkillRank, ReqAbility1, ReqAbility2, ReqAbility3, ReqLevel FROM trainer_spell"))
9725 {
9726 do
9727 {
9728 Field* fields = trainerSpellsResult->Fetch();
9729
9730 Trainer::Spell spell;
9731 uint32 trainerId = fields[0].Get<uint32>();
9732 spell.SpellId = fields[1].Get<uint32>();
9733 spell.MoneyCost = fields[2].Get<uint32>();
9734 spell.ReqSkillLine = fields[3].Get<uint32>();
9735 spell.ReqSkillRank = fields[4].Get<uint32>();
9736 spell.ReqAbility[0] = fields[5].Get<uint32>();
9737 spell.ReqAbility[1] = fields[6].Get<uint32>();
9738 spell.ReqAbility[2] = fields[7].Get<uint32>();
9739 spell.ReqLevel = fields[8].Get<uint8>();
9740
9741 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell.SpellId);
9742 if (!spellInfo)
9743 {
9744 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing spell (SpellId: {}) for TrainerId {}, ignoring", spell.SpellId, trainerId);
9745 continue;
9746 }
9747
9748 if (GetTalentSpellCost(spell.SpellId))
9749 {
9750 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing spell (SpellId: {}) which is a talent, for TrainerId {}, ignoring", spell.SpellId, trainerId);
9751 continue;
9752 }
9753
9754 if (spell.ReqSkillLine && !sSkillLineStore.LookupEntry(spell.ReqSkillLine))
9755 {
9756 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing skill (ReqSkillLine: {}) for TrainerId {} and SpellId {}, ignoring",
9757 spell.ReqSkillLine, spell.SpellId, trainerId);
9758 continue;
9759 }
9760
9761 bool allReqValid = true;
9762 for (std::size_t i = 0; i < spell.ReqAbility.size(); ++i)
9763 {
9764 uint32 requiredSpell = spell.ReqAbility[i];
9765 if (requiredSpell && !sSpellMgr->GetSpellInfo(requiredSpell))
9766 {
9767 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing spell (ReqAbility {} : {}) for TrainerId {} and SpellId {}, ignoring",
9768 i + 1, requiredSpell, trainerId, spell.SpellId);
9769 allReqValid = false;
9770 }
9771 }
9772
9773 if (!allReqValid)
9774 continue;
9775
9776 spellsByTrainer[trainerId].push_back(spell);
9777 } while (trainerSpellsResult->NextRow());
9778 }
9779
9780 if (QueryResult trainersResult = WorldDatabase.Query("SELECT Id, Type, Requirement, Greeting FROM trainer"))
9781 {
9782 do
9783 {
9784 Field* fields = trainersResult->Fetch();
9785
9786 uint32 trainerId = fields[0].Get<uint32>();
9787 Trainer::Type trainerType = Trainer::Type(fields[1].Get<uint8>());
9788 uint32 requirement = fields[2].Get<uint32>();
9789 std::string greeting = fields[3].Get<std::string>();
9790 std::vector<Trainer::Spell> spells;
9791 auto spellsItr = spellsByTrainer.find(trainerId);
9792 if (spellsItr != spellsByTrainer.end())
9793 {
9794 spells = std::move(spellsItr->second);
9795 spellsByTrainer.erase(spellsItr);
9796 }
9797
9798 _trainers.emplace(std::piecewise_construct, std::forward_as_tuple(trainerId), std::forward_as_tuple(trainerId, trainerType, requirement, std::move(greeting), std::move(spells)));
9799 } while (trainersResult->NextRow());
9800 }
9801
9802 for (auto const& unusedSpells : spellsByTrainer)
9803 {
9804 for (Trainer::Spell const& unusedSpell : unusedSpells.second)
9805 {
9806 LOG_ERROR("sql.sql", "Table `trainer_spell` references non-existing trainer (TrainerId: {}) for SpellId {}, ignoring", unusedSpells.first, unusedSpell.SpellId);
9807 }
9808 }
9809
9810 if (QueryResult trainerLocalesResult = WorldDatabase.Query("SELECT Id, locale, Greeting_lang FROM trainer_locale"))
9811 {
9812 do
9813 {
9814 Field* fields = trainerLocalesResult->Fetch();
9815 uint32 trainerId = fields[0].Get<uint32>();
9816 std::string localeName = fields[1].Get<std::string>();
9817
9818 LocaleConstant locale = GetLocaleByName(localeName);
9819 if (locale == LOCALE_enUS)
9820 continue;
9821
9823 trainer->AddGreetingLocale(locale, fields[2].Get<std::string>());
9824 else
9825 LOG_ERROR("sql.sql", "Table `trainer_locale` references non-existing trainer (TrainerId: {}) for locale %s, ignoring",
9826 trainerId, localeName.c_str());
9827 } while (trainerLocalesResult->NextRow());
9828 }
9829
9830 LOG_INFO("server.loading", ">> Loaded {} Trainers in {} ms", _trainers.size(), GetMSTimeDiffToNow(oldMSTime));
9831}
Definition Trainer.h:66
Type
Definition Trainer.h:32
Definition Trainer.h:54
uint32 ReqSkillLine
Definition Trainer.h:57
std::array< uint32, 3 > ReqAbility
Definition Trainer.h:59
uint8 ReqLevel
Definition Trainer.h:60
uint32 ReqSkillRank
Definition Trainer.h:58
uint32 SpellId
Definition Trainer.h:55
uint32 MoneyCost
Definition Trainer.h:56

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

◆ LoadVehicleAccessories()

void ObjectMgr::LoadVehicleAccessories ( )
4012{
4013 uint32 oldMSTime = getMSTime();
4014
4015 _vehicleAccessoryStore.clear(); // needed for reload case
4016
4017 uint32 count = 0;
4018
4019 // 0 1 2 3 4 5
4020 QueryResult result = WorldDatabase.Query("SELECT `guid`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer` FROM `vehicle_accessory`");
4021
4022 if (!result)
4023 {
4024 LOG_WARN("server.loading", ">> Loaded 0 Vehicle Accessories in {} ms", GetMSTimeDiffToNow(oldMSTime));
4025 LOG_INFO("server.loading", " ");
4026 return;
4027 }
4028
4029 do
4030 {
4031 Field* fields = result->Fetch();
4032
4033 uint32 uiGUID = fields[0].Get<uint32>();
4034 uint32 uiAccessory = fields[1].Get<uint32>();
4035 int8 uiSeat = int8(fields[2].Get<int16>());
4036 bool bMinion = fields[3].Get<bool>();
4037 uint8 uiSummonType = fields[4].Get<uint8>();
4038 uint32 uiSummonTimer = fields[5].Get<uint32>();
4039
4040 if (!GetCreatureTemplate(uiAccessory))
4041 {
4042 LOG_ERROR("sql.sql", "Table `vehicle_accessory`: Accessory {} does not exist.", uiAccessory);
4043 continue;
4044 }
4045
4046 _vehicleAccessoryStore[uiGUID].push_back(VehicleAccessory(uiAccessory, uiSeat, bMinion, uiSummonType, uiSummonTimer));
4047
4048 ++count;
4049 } while (result->NextRow());
4050
4051 LOG_INFO("server.loading", ">> Loaded {} Vehicle Accessories in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4052 LOG_INFO("server.loading", " ");
4053}
Definition VehicleDefines.h:115

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

◆ LoadVehicleSeatAddon()

void ObjectMgr::LoadVehicleSeatAddon ( )
4056{
4057 uint32 oldMSTime = getMSTime();
4058
4059 _vehicleSeatAddonStore.clear(); // needed for reload case
4060
4061 uint32 count = 0;
4062
4063 // 0 1 2 3 4 5 6
4064 QueryResult result = WorldDatabase.Query("SELECT `SeatEntry`, `SeatOrientation`, `ExitParamX`, `ExitParamY`, `ExitParamZ`, `ExitParamO`, `ExitParamValue` FROM `vehicle_seat_addon`");
4065
4066 if (!result)
4067 {
4068 LOG_ERROR("server.loading", ">> Loaded 0 vehicle seat addons. DB table `vehicle_seat_addon` is empty.");
4069 return;
4070 }
4071
4072 do
4073 {
4074 Field* fields = result->Fetch();
4075
4076 uint32 seatID = fields[0].Get<uint32>();
4077 float orientation = fields[1].Get<float>();
4078 float exitX = fields[2].Get<float>();
4079 float exitY = fields[3].Get<float>();
4080 float exitZ = fields[4].Get<float>();
4081 float exitO = fields[5].Get<float>();
4082 uint8 exitParam = fields[6].Get<uint8>();
4083
4084 if (!sVehicleSeatStore.LookupEntry(seatID))
4085 {
4086 LOG_ERROR("sql.sql", "Table `vehicle_seat_addon`: SeatID: {} does not exist in VehicleSeat.dbc. Skipping entry.", seatID);
4087 continue;
4088 }
4089
4090 // Sanitizing values
4091 if (orientation > float(M_PI * 2))
4092 {
4093 LOG_ERROR("sql.sql", "Table `vehicle_seat_addon`: SeatID: {} is using invalid angle offset value ({}). Set Value to 0.", seatID, orientation);
4094 orientation = 0.0f;
4095 }
4096
4098 {
4099 LOG_ERROR("sql.sql", "Table `vehicle_seat_addon`: SeatID: {} is using invalid exit parameter value ({}). Setting to 0 (none).", seatID, exitParam);
4100 continue;
4101 }
4102
4103 _vehicleSeatAddonStore[seatID] = VehicleSeatAddon(orientation, exitX, exitY, exitZ, exitO, exitParam);
4104
4105 ++count;
4106 } while (result->NextRow());
4107
4108 LOG_INFO("server.loading", ">> Loaded {} Vehicle Seat Addon entries in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4109}
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 ( )
3956{
3957 uint32 oldMSTime = getMSTime();
3958
3959 _vehicleTemplateAccessoryStore.clear(); // needed for reload case
3960
3961 uint32 count = 0;
3962
3963 // 0 1 2 3 4 5
3964 QueryResult result = WorldDatabase.Query("SELECT `entry`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer` FROM `vehicle_template_accessory`");
3965
3966 if (!result)
3967 {
3968 LOG_WARN("server.loading", ">> Loaded 0 vehicle template accessories. DB table `vehicle_template_accessory` is empty.");
3969 LOG_INFO("server.loading", " ");
3970 return;
3971 }
3972
3973 do
3974 {
3975 Field* fields = result->Fetch();
3976
3977 uint32 uiEntry = fields[0].Get<uint32>();
3978 uint32 uiAccessory = fields[1].Get<uint32>();
3979 int8 uiSeat = int8(fields[2].Get<int8>());
3980 bool bMinion = fields[3].Get<bool>();
3981 uint8 uiSummonType = fields[4].Get<uint8>();
3982 uint32 uiSummonTimer = fields[5].Get<uint32>();
3983
3984 if (!GetCreatureTemplate(uiEntry))
3985 {
3986 LOG_ERROR("sql.sql", "Table `vehicle_template_accessory`: creature template entry {} does not exist.", uiEntry);
3987 continue;
3988 }
3989
3990 if (!GetCreatureTemplate(uiAccessory))
3991 {
3992 LOG_ERROR("sql.sql", "Table `vehicle_template_accessory`: Accessory {} does not exist.", uiAccessory);
3993 continue;
3994 }
3995
3996 if (_spellClickInfoStore.find(uiEntry) == _spellClickInfoStore.end())
3997 {
3998 LOG_ERROR("sql.sql", "Table `vehicle_template_accessory`: creature template entry {} has no data in npc_spellclick_spells", uiEntry);
3999 continue;
4000 }
4001
4002 _vehicleTemplateAccessoryStore[uiEntry].push_back(VehicleAccessory(uiAccessory, uiSeat, bMinion, uiSummonType, uiSummonTimer));
4003
4004 ++count;
4005 } while (result->NextRow());
4006
4007 LOG_INFO("server.loading", ">> Loaded {} Vehicle Template Accessories in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4008 LOG_INFO("server.loading", " ");
4009}

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

◆ LoadVendors()

void ObjectMgr::LoadVendors ( )
9910{
9911 uint32 oldMSTime = getMSTime();
9912
9913 // For reload case
9914 for (CacheVendorItemContainer::iterator itr = _cacheVendorItemStore.begin(); itr != _cacheVendorItemStore.end(); ++itr)
9915 itr->second.Clear();
9916 _cacheVendorItemStore.clear();
9917
9918 std::set<uint32> skip_vendors;
9919
9920 QueryResult result = WorldDatabase.Query("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor ORDER BY entry, slot ASC, item, ExtendedCost");
9921 if (!result)
9922 {
9923 LOG_INFO("server.loading", " ");
9924 LOG_WARN("server.loading", ">> Loaded 0 Vendors. DB table `npc_vendor` is empty!");
9925 return;
9926 }
9927
9928 uint32 count = 0;
9929
9930 do
9931 {
9932 Field* fields = result->Fetch();
9933
9934 uint32 entry = fields[0].Get<uint32>();
9935 int32 item_id = fields[1].Get<int32>();
9936
9937 // if item is a negative, its a reference
9938 if (item_id < 0)
9939 count += LoadReferenceVendor(entry, -item_id, &skip_vendors);
9940 else
9941 {
9942 uint32 maxcount = fields[2].Get<uint32>();
9943 uint32 incrtime = fields[3].Get<uint32>();
9944 uint32 ExtendedCost = fields[4].Get<uint32>();
9945
9946 if (!IsVendorItemValid(entry, item_id, maxcount, incrtime, ExtendedCost, nullptr, &skip_vendors))
9947 continue;
9948
9949 VendorItemData& vList = _cacheVendorItemStore[entry];
9950
9951 vList.AddItem(item_id, maxcount, incrtime, ExtendedCost);
9952 ++count;
9953 }
9954 } while (result->NextRow());
9955
9956 LOG_INFO("server.loading", ">> Loaded {} Vendors in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9957 LOG_INFO("server.loading", " ");
9958}

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

◆ LoadWaypointScripts()

void ObjectMgr::LoadWaypointScripts ( )
6218{
6220
6221 std::set<uint32> actionSet;
6222
6223 for (ScriptMapMap::const_iterator itr = sWaypointScripts.begin(); itr != sWaypointScripts.end(); ++itr)
6224 actionSet.insert(itr->first);
6225
6227 PreparedQueryResult result = WorldDatabase.Query(stmt);
6228
6229 if (result)
6230 {
6231 do
6232 {
6233 Field* fields = result->Fetch();
6234 uint32 action = fields[0].Get<uint32>();
6235
6236 actionSet.erase(action);
6237 } while (result->NextRow());
6238 }
6239
6240 for (std::set<uint32>::iterator itr = actionSet.begin(); itr != actionSet.end(); ++itr)
6241 LOG_ERROR("sql.sql", "There is no waypoint which links to the waypoint script {}", *itr);
6242}
ScriptMapMap sWaypointScripts
Definition ObjectMgr.cpp:62
@ SCRIPTS_WAYPOINT
Definition ObjectMgr.h:151
@ WORLD_SEL_WAYPOINT_DATA_ACTION
Definition WorldDatabase.h:69

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

◆ NewGOData()

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

References _gameObjectDataStore.

Referenced by AddGOData().

◆ NewOrExistCreatureData()

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

References _creatureDataStore.

Referenced by AddCreData().

◆ PlayerCreateInfoAddItemHelper()

void ObjectMgr::PlayerCreateInfoAddItemHelper ( uint32  race_,
uint32  class_,
uint32  itemId,
int32  count 
)
private
4217{
4218 if (!_playerInfo[race_][class_])
4219 return;
4220
4221 if (count > 0)
4222 _playerInfo[race_][class_]->item.push_back(PlayerCreateInfoItem(itemId, count));
4223 else
4224 {
4225 if (count < -1)
4226 LOG_ERROR("sql.sql", "Invalid count {} specified on item {} be removed from original player create info (use -1)!", count, itemId);
4227
4228 for (uint32 gender = 0; gender < GENDER_NONE; ++gender)
4229 {
4230 if (CharStartOutfitEntry const* entry = GetCharStartOutfitEntry(race_, class_, gender))
4231 {
4232 bool found = false;
4233 for (uint8 x = 0; x < MAX_OUTFIT_ITEMS; ++x)
4234 {
4235 if (entry->ItemId[x] > 0 && uint32(entry->ItemId[x]) == itemId)
4236 {
4237 found = true;
4238 const_cast<CharStartOutfitEntry*>(entry)->ItemId[x] = 0;
4239 break;
4240 }
4241 }
4242
4243 if (!found)
4244 LOG_ERROR("sql.sql", "Item {} specified to be removed from original create info not found in dbc!", itemId);
4245 }
4246 }
4247 }
4248}
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 
)
2714{
2715 uint8 mask = data->spawnMask;
2716 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
2717 {
2718 if (mask & 1)
2719 {
2720 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
2721 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
2722 cell_guids.creatures.erase(guid);
2723 }
2724 }
2725}

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

Referenced by DeleteCreatureData().

◆ RemoveGameobjectFromGrid()

void ObjectMgr::RemoveGameobjectFromGrid ( ObjectGuid::LowType  guid,
GameObjectData const *  data 
)
3156{
3157 uint8 mask = data->spawnMask;
3158 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
3159 {
3160 if (mask & 1)
3161 {
3162 GridCoord gridCoord = Acore::ComputeGridCoord(data->posX, data->posY);
3163 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][gridCoord.GetId()];
3164 cell_guids.gameobjects.erase(guid);
3165 }
3166 }
3167}

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

Referenced by DeleteGOData().

◆ RemoveVendorItem()

bool ObjectMgr::RemoveVendorItem ( uint32  entry,
uint32  item,
bool  persist = true 
)
10111{
10112 CacheVendorItemContainer::iterator iter = _cacheVendorItemStore.find(entry);
10113 if (iter == _cacheVendorItemStore.end())
10114 return false;
10115
10116 if (!iter->second.RemoveItem(item))
10117 return false;
10118
10119 if (persist)
10120 {
10122
10123 stmt->SetData(0, entry);
10124 stmt->SetData(1, item);
10125
10126 WorldDatabase.Execute(stmt);
10127 }
10128
10129 return true;
10130}
@ WORLD_DEL_NPC_VENDOR
Definition WorldDatabase.h:44

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

◆ ReturnOrDeleteOldMails()

void ObjectMgr::ReturnOrDeleteOldMails ( bool  serverUp)
6713{
6714 uint32 oldMSTime = getMSTime();
6715
6716 time_t curTime = GameTime::GetGameTime().count();
6717
6719 stmt->SetData(0, uint32(curTime));
6720 PreparedQueryResult result = CharacterDatabase.Query(stmt);
6721 if (!result)
6722 return;
6723
6724 std::map<uint32 /*messageId*/, MailItemInfoVec> itemsCache;
6725 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_EXPIRED_MAIL_ITEMS);
6726 stmt->SetData(0, uint32(curTime));
6727 if (PreparedQueryResult items = CharacterDatabase.Query(stmt))
6728 {
6729 MailItemInfo item;
6730 do
6731 {
6732 Field* fields = items->Fetch();
6733 item.item_guid = fields[0].Get<uint32>();
6734 item.item_template = fields[1].Get<uint32>();
6735 uint32 mailId = fields[2].Get<uint32>();
6736 itemsCache[mailId].push_back(item);
6737 } while (items->NextRow());
6738 }
6739
6740 uint32 deletedCount = 0;
6741 uint32 returnedCount = 0;
6742 do
6743 {
6744 Field* fields = result->Fetch();
6745 Mail* m = new Mail;
6746 m->messageID = fields[0].Get<uint32>();
6747 m->messageType = fields[1].Get<uint8>();
6748 m->sender = fields[2].Get<uint32>();
6749 m->receiver = fields[3].Get<uint32>();
6750 bool has_items = fields[4].Get<bool>();
6751 m->expire_time = time_t(fields[5].Get<uint32>());
6752 m->deliver_time = time_t(0);
6753 m->stationery = fields[6].Get<uint8>();
6754 m->checked = fields[7].Get<uint8>();
6755 m->mailTemplateId = fields[8].Get<int16>();
6756
6757 Player* player = nullptr;
6758 if (serverUp)
6760
6761 if (player) // don't modify mails of a logged in player
6762 {
6763 delete m;
6764 continue;
6765 }
6766
6767 // Delete or return mail
6768 if (has_items)
6769 {
6770 // read items from cache
6771 m->items.swap(itemsCache[m->messageID]);
6772
6773 // If it is mail from non-player, or if it's already return mail, it shouldn't be returned, but deleted
6774 if (!m->IsSentByPlayer() || m->IsSentByGM() || (m->IsCODPayment() || m->IsReturnedMail()))
6775 {
6776 for (auto const& mailedItem : m->items)
6777 {
6778 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE);
6779 stmt->SetData(0, mailedItem.item_guid);
6780 CharacterDatabase.Execute(stmt);
6781 }
6782
6783 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID);
6784 stmt->SetData(0, m->messageID);
6785 CharacterDatabase.Execute(stmt);
6786 }
6787 else
6788 {
6789 // Mail will be returned
6790 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_MAIL_RETURNED);
6791 stmt->SetData(0, m->receiver);
6792 stmt->SetData(1, m->sender);
6793 stmt->SetData(2, uint32(curTime + 30 * DAY));
6794 stmt->SetData(3, uint32(curTime));
6796 stmt->SetData(5, m->messageID);
6797 CharacterDatabase.Execute(stmt);
6798 for (auto const& mailedItem : m->items)
6799 {
6800 // Update receiver in mail items for its proper delivery, and in instance_item for avoid lost item at sender delete
6801 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_MAIL_ITEM_RECEIVER);
6802 stmt->SetData(0, m->sender);
6803 stmt->SetData(1, mailedItem.item_guid);
6804 CharacterDatabase.Execute(stmt);
6805
6806 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_OWNER);
6807 stmt->SetData(0, m->sender);
6808 stmt->SetData(1, mailedItem.item_guid);
6809 CharacterDatabase.Execute(stmt);
6810 }
6811
6812 // xinef: update global data
6813 sCharacterCache->IncreaseCharacterMailCount(ObjectGuid(HighGuid::Player, m->sender));
6814 sCharacterCache->DecreaseCharacterMailCount(ObjectGuid(HighGuid::Player, m->receiver));
6815
6816 delete m;
6817 ++returnedCount;
6818 continue;
6819 }
6820 }
6821
6822 sCharacterCache->DecreaseCharacterMailCount(ObjectGuid(HighGuid::Player, m->receiver));
6823
6824 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_BY_ID);
6825 stmt->SetData(0, m->messageID);
6826 CharacterDatabase.Execute(stmt);
6827 delete m;
6828 ++deletedCount;
6829 } while (result->NextRow());
6830
6831 LOG_INFO("server.loading", ">> Processed {} expired mails: {} deleted and {} returned in {} ms", deletedCount + returnedCount, deletedCount, returnedCount, GetMSTimeDiffToNow(oldMSTime));
6832 LOG_INFO("server.loading", " ");
6833}
#define sCharacterCache
Definition CharacterCache.h:83
@ CHAR_UPD_ITEM_OWNER
Definition CharacterDatabase.h:118
@ CHAR_DEL_ITEM_INSTANCE
Definition CharacterDatabase.h:127
@ CHAR_UPD_MAIL_RETURNED
Definition CharacterDatabase.h:116
@ CHAR_SEL_EXPIRED_MAIL
Definition CharacterDatabase.h:114
@ CHAR_SEL_EXPIRED_MAIL_ITEMS
Definition CharacterDatabase.h:115
@ CHAR_DEL_MAIL_BY_ID
Definition CharacterDatabase.h:110
@ CHAR_DEL_MAIL_ITEM_BY_ID
Definition CharacterDatabase.h:382
@ CHAR_UPD_MAIL_ITEM_RECEIVER
Definition CharacterDatabase.h:117
std::vector< MailItemInfo > MailItemInfoVec
Definition Mail.h:164
@ MAIL_CHECK_MASK_RETURNED
Definition Mail.h:48
Definition Player.h:1084
Seconds GetGameTime()
Definition GameTime.cpp:38
Player * FindPlayerByLowGUID(ObjectGuid::LowType lowguid)
Definition ObjectAccessor.cpp:251
Definition Mail.h:160
ObjectGuid::LowType item_guid
Definition Mail.h:161
uint32 item_template
Definition Mail.h:162
Definition Mail.h:167
bool IsSentByGM() const
Definition Mail.h:208
bool IsCODPayment() const
Definition Mail.h:209
ObjectGuid::LowType receiver
Definition Mail.h:173
uint8 messageType
Definition Mail.h:169
bool IsSentByPlayer() const
Definition Mail.h:207
uint32 messageID
Definition Mail.h:168
time_t expire_time
Definition Mail.h:178
uint32 sender
Definition Mail.h:172
uint8 stationery
Definition Mail.h:170
std::vector< MailItemInfo > items
Definition Mail.h:176
time_t deliver_time
Definition Mail.h:179
bool IsReturnedMail() const
Definition Mail.h:210
uint32 checked
Definition Mail.h:182
uint16 mailTemplateId
Definition Mail.h:171

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

◆ SetCreatureLinkedRespawn()

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

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

◆ SetDBCLocaleIndex()

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

References DBCLocaleIndex.

◆ SetHighestGuids()

void ObjectMgr::SetHighestGuids ( )
7595{
7596 QueryResult result = CharacterDatabase.Query("SELECT MAX(guid) FROM characters");
7597 if (result)
7598 GetGuidSequenceGenerator<HighGuid::Player>().Set((*result)[0].Get<uint32>() + 1);
7599
7600 result = CharacterDatabase.Query("SELECT MAX(guid) FROM item_instance");
7601 if (result)
7602 GetGuidSequenceGenerator<HighGuid::Item>().Set((*result)[0].Get<uint32>() + 1);
7603
7604 // Cleanup other tables from not existed guids ( >= _hiItemGuid)
7605 CharacterDatabase.Execute("DELETE FROM character_inventory WHERE item >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7606 CharacterDatabase.Execute("DELETE FROM mail_items WHERE item_guid >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7607 CharacterDatabase.Execute("DELETE FROM auctionhouse WHERE itemguid >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7608 CharacterDatabase.Execute("DELETE FROM guild_bank_item WHERE item_guid >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
7609
7610 result = WorldDatabase.Query("SELECT MAX(guid) FROM transports");
7611 if (result)
7612 GetGuidSequenceGenerator<HighGuid::Mo_Transport>().Set((*result)[0].Get<uint32>() + 1);
7613
7614 result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse");
7615 if (result)
7616 _auctionId = (*result)[0].Get<uint32>() + 1;
7617
7618 result = CharacterDatabase.Query("SELECT MAX(id) FROM mail");
7619 if (result)
7620 _mailId = (*result)[0].Get<uint32>() + 1;
7621
7622 result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team");
7623 if (result)
7624 sArenaTeamMgr->SetNextArenaTeamId((*result)[0].Get<uint32>() + 1);
7625
7626 result = CharacterDatabase.Query("SELECT MAX(fight_id) FROM log_arena_fights");
7627 if (result)
7628 sArenaTeamMgr->SetLastArenaLogId((*result)[0].Get<uint32>());
7629
7630 result = CharacterDatabase.Query("SELECT MAX(setguid) FROM character_equipmentsets");
7631 if (result)
7632 _equipmentSetGuid = (*result)[0].Get<uint64>() + 1;
7633
7634 result = CharacterDatabase.Query("SELECT MAX(guildId) FROM guild");
7635 if (result)
7636 sGuildMgr->SetNextGuildId((*result)[0].Get<uint32>() + 1);
7637
7638 result = WorldDatabase.Query("SELECT MAX(guid) FROM creature");
7639 if (result)
7640 _creatureSpawnId = (*result)[0].Get<uint32>() + 1;
7641
7642 result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject");
7643 if (result)
7644 _gameObjectSpawnId = (*result)[0].Get<uint32>() + 1;
7645}
#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 ( )
6305{
6306 uint32 oldMSTime = getMSTime();
6307
6308 if (_spellScriptsStore.empty())
6309 {
6310 LOG_INFO("server.loading", ">> Validated 0 scripts.");
6311 LOG_INFO("server.loading", " ");
6312 return;
6313 }
6314
6315 uint32 count = 0;
6316
6317 for (SpellScriptsContainer::iterator itr = _spellScriptsStore.begin(); itr != _spellScriptsStore.end();)
6318 {
6319 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
6320 std::vector<std::pair<SpellScriptLoader*, SpellScriptsContainer::iterator> > SpellScriptLoaders;
6321 sScriptMgr->CreateSpellScriptLoaders(itr->first, SpellScriptLoaders);
6322 itr = _spellScriptsStore.upper_bound(itr->first);
6323
6324 for (std::vector<std::pair<SpellScriptLoader*, SpellScriptsContainer::iterator> >::iterator sitr = SpellScriptLoaders.begin(); sitr != SpellScriptLoaders.end(); ++sitr)
6325 {
6326 SpellScript* spellScript = sitr->first->GetSpellScript();
6327 AuraScript* auraScript = sitr->first->GetAuraScript();
6328 bool valid = true;
6329 if (!spellScript && !auraScript)
6330 {
6331 LOG_ERROR("sql.sql", "Functions GetSpellScript() and GetAuraScript() of script `{}` do not return objects - script skipped", GetScriptName(sitr->second->second));
6332 valid = false;
6333 }
6334 if (spellScript)
6335 {
6336 spellScript->_Init(&sitr->first->GetName(), spellInfo->Id);
6337 spellScript->_Register();
6338 if (!spellScript->_Validate(spellInfo))
6339 valid = false;
6340 delete spellScript;
6341 }
6342 if (auraScript)
6343 {
6344 auraScript->_Init(&sitr->first->GetName(), spellInfo->Id);
6345 auraScript->_Register();
6346 if (!auraScript->_Validate(spellInfo))
6347 valid = false;
6348 delete auraScript;
6349 }
6350 if (!valid)
6351 {
6352 _spellScriptsStore.erase(sitr->second);
6353 }
6354 }
6355 ++count;
6356 }
6357
6358 LOG_INFO("server.loading", ">> Validated {} scripts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6359 LOG_INFO("server.loading", " ");
6360}
Definition SpellScript.h:518
bool _Validate(SpellInfo const *entry) override
Definition SpellScript.cpp:662
std::string const & GetScriptName(uint32 id) const
Definition ObjectMgr.cpp:10268
Definition SpellScript.h:182
bool _Validate(SpellInfo const *entry) override
Definition SpellScript.cpp:316
virtual void _Register()
Definition SpellScript.cpp:45
virtual void _Init(std::string const *scriptname, uint32 spellId)
Definition SpellScript.cpp:59

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

Friends And Related Symbol Documentation

◆ PlayerDumpReader

friend class PlayerDumpReader
friend

Member Data Documentation

◆ _accessRequirementStore

DungeonProgressionRequirementsContainer ObjectMgr::_accessRequirementStore
private

◆ _acoreStringStore

AcoreStringContainer ObjectMgr::_acoreStringStore
private

Referenced by GetAcoreString(), and LoadAcoreStrings().

◆ _areaTriggerScriptStore

AreaTriggerScriptContainer ObjectMgr::_areaTriggerScriptStore
private

◆ _areaTriggerStore

AreaTriggerContainer ObjectMgr::_areaTriggerStore
private

Referenced by GetAreaTrigger(), and LoadAreaTriggers().

◆ _areaTriggerTeleportStore

◆ _auctionId

uint32 ObjectMgr::_auctionId
private

◆ _baseXPTable

BaseXPContainer ObjectMgr::_baseXPTable
private

Referenced by GetBaseXP(), and LoadExplorationBaseXP().

◆ _breadcrumbsForQuest

BreadcrumbQuestMap ObjectMgr::_breadcrumbsForQuest

◆ _broadcastTextStore

BroadcastTextContainer ObjectMgr::_broadcastTextStore
private

◆ _cacheVendorItemStore

◆ _creatureAddonStore

CreatureAddonContainer ObjectMgr::_creatureAddonStore
private

◆ _creatureBaseStatsStore

CreatureBaseStatsContainer ObjectMgr::_creatureBaseStatsStore
private

◆ _creatureCustomIDsStore

CreatureCustomIDsContainer ObjectMgr::_creatureCustomIDsStore
private

◆ _creatureDataStore

◆ _creatureDefaultTrainers

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

◆ _creatureLocaleStore

CreatureLocaleContainer ObjectMgr::_creatureLocaleStore
private

◆ _creatureModelStore

CreatureModelContainer ObjectMgr::_creatureModelStore
private

◆ _creatureMovementOverrides

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

◆ _creatureQuestInvolvedRelations

◆ _creatureQuestItemStore

CreatureQuestItemMap ObjectMgr::_creatureQuestItemStore
private

◆ _creatureQuestRelations

QuestRelations ObjectMgr::_creatureQuestRelations
private

◆ _creatureSparringStore

CreatureSparringContainer ObjectMgr::_creatureSparringStore
private

◆ _creatureSpawnId

ObjectGuid::LowType ObjectMgr::_creatureSpawnId
private

◆ _creatureTemplateAddonStore

CreatureAddonContainer ObjectMgr::_creatureTemplateAddonStore
private

◆ _creatureTemplateStore

◆ _creatureTemplateStoreFast

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

◆ _difficultyEntries

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

◆ _dungeonEncounterStore

DungeonEncounterContainer ObjectMgr::_dungeonEncounterStore
private

◆ _emptyCellObjectGuids

CellObjectGuids ObjectMgr::_emptyCellObjectGuids
private

Referenced by GetGridObjectGuids().

◆ _emptyCellObjectGuidsMap

CellObjectGuidsMap ObjectMgr::_emptyCellObjectGuidsMap
private

Referenced by GetMapObjectGuids().

◆ _equipmentInfoStore

EquipmentInfoContainer ObjectMgr::_equipmentInfoStore
private

◆ _equipmentSetGuid

uint64 ObjectMgr::_equipmentSetGuid
private

◆ _fishingBaseForAreaStore

◆ _gameObjectAddonStore

GameObjectAddonContainer ObjectMgr::_gameObjectAddonStore
private

◆ _gameObjectDataStore

◆ _gameObjectLocaleStore

GameObjectLocaleContainer ObjectMgr::_gameObjectLocaleStore
private

◆ _gameObjectQuestItemStore

GameObjectQuestItemMap ObjectMgr::_gameObjectQuestItemStore
private

◆ _gameObjectSpawnId

ObjectGuid::LowType ObjectMgr::_gameObjectSpawnId
private

◆ _gameObjectTemplateAddonStore

GameObjectTemplateAddonContainer ObjectMgr::_gameObjectTemplateAddonStore
private

◆ _gameObjectTemplateStore

GameObjectTemplateContainer ObjectMgr::_gameObjectTemplateStore
private

◆ _gameTeleStore

◆ _goQuestInvolvedRelations

QuestRelations ObjectMgr::_goQuestInvolvedRelations
private

◆ _goQuestRelations

QuestRelations ObjectMgr::_goQuestRelations
private

◆ _gossipMenuItemsLocaleStore

GossipMenuItemsLocaleContainer ObjectMgr::_gossipMenuItemsLocaleStore
private

◆ _gossipMenuItemsStore

◆ _gossipMenusStore

GossipMenusContainer ObjectMgr::_gossipMenusStore
private

◆ _gossipTextStore

GossipTextContainer ObjectMgr::_gossipTextStore
private

Referenced by GetGossipText(), and LoadGossipText().

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

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