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::multimap< int32, uint32ExclusiveQuestGroups
 
typedef std::pair< ExclusiveQuestGroups::const_iterator, ExclusiveQuestGroups::const_iterator > ExclusiveQuestGroupsBounds
 

Public Member Functions

GameObjectTemplateContainer const * GetGameObjectTemplates () const
 
void AddGameobjectInfo (GameObjectTemplate *goinfo)
 
CreatureTemplateContainer const * GetCreatureTemplates () const
 
ItemTemplateContainer const * GetItemTemplateStore () const
 
std::vector< ItemTemplate * > const * GetItemTemplateStoreFast () const
 
ItemSetNameEntry const * GetItemSetNameEntry (uint32 itemId)
 
PlayerClassInfo const * GetPlayerClassInfo (uint32 class_) const
 
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
 
AreaTrigger const * GetAreaTrigger (uint32 trigger) const
 
AreaTriggerTeleport const * GetAreaTriggerTeleport (uint32 trigger) const
 
DungeonProgressionRequirements const * GetAccessRequirement (uint32 mapid, Difficulty difficulty) const
 
RepRewardRate const * GetRepRewardRate (uint32 factionId) const
 
ReputationOnKillEntry const * GetReputationOnKilEntry (uint32 id) const
 
RepSpilloverTemplate const * GetRepSpilloverTemplate (uint32 factionId) const
 
PointOfInterest const * GetPointOfInterest (uint32 id) const
 
QuestPOIVector const * GetQuestPOIVector (uint32 questId)
 
DungeonEncounterList const * GetDungeonEncounterList (uint32 mapId, Difficulty difficulty)
 
void LoadQuestStartersAndEnders ()
 
QuestRelationsGetGOQuestRelationMap ()
 
QuestRelationsGetGOQuestInvolvedRelationMap ()
 
QuestRelationBounds GetGOQuestRelationBounds (uint32 go_entry)
 
QuestRelationBounds GetGOQuestInvolvedRelationBounds (uint32 go_entry)
 
QuestRelationsGetCreatureQuestRelationMap ()
 
QuestRelationsGetCreatureQuestInvolvedRelationMap ()
 
QuestRelationBounds GetCreatureQuestRelationBounds (uint32 creature_entry)
 
QuestRelationBounds GetCreatureQuestInvolvedRelationBounds (uint32 creature_entry)
 
int32 GetFishingBaseSkillLevel (uint32 entry) const
 
template<HighGuid type>
ObjectGuidGeneratorBaseGetGenerator ()
 
MailLevelReward const * GetMailLevelReward (uint32 level, uint32 raceMask)
 
CellObjectGuids const & GetCellObjectGuids (uint16 mapid, uint8 spawnMode, uint32 cell_id)
 
CellObjectGuidsMap const & GetMapObjectGuids (uint16 mapid, uint8 spawnMode)
 
std::vector< TempSummonData > const * GetSummonGroup (uint32 summonerId, SummonerType summonerType, uint8 group) const
 
ServerMailContainer const & GetAllServerMailStore () const
 
BroadcastText const * GetBroadcastText (uint32 id) const
 
CreatureDataContainer const & GetAllCreatureData () const
 
CreatureData const * GetCreatureData (ObjectGuid::LowType spawnId) const
 
CreatureDataNewOrExistCreatureData (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
 
QuestGreetingLocale const * GetQuestGreetingLocale (TypeID type, uint32 id) const
 
QuestOfferRewardLocale const * GetQuestOfferRewardLocale (uint32 entry) const
 
QuestRequestItemsLocale const * GetQuestRequestItemsLocale (uint32 entry) const
 
NpcTextLocale const * GetNpcTextLocale (uint32 entry) const
 
GameObjectDataNewGOData (ObjectGuid::LowType guid)
 
AcoreString const * GetAcoreString (uint32 entry) const
 
char const * GetAcoreStringForDBCLocale (uint32 entry) const
 
LocaleConstant GetDBCLocaleIndex () const
 
void SetDBCLocaleIndex (LocaleConstant locale)
 
GameTele const * GetGameTele (uint32 id) const
 
GameTeleContainer const & GetGameTeleMap () const
 
TrainerSpellData const * GetNpcTrainerSpells (uint32 entry) const
 
VendorItemData const * GetNpcVendorItemList (uint32 entry) const
 
ScriptNameContainerGetScriptNames ()
 
SpellClickInfoMapBounds GetSpellClickInfoMapBounds (uint32 creature_id) const
 
GossipMenusMapBounds GetGossipMenusMapBounds (uint32 uiMenuId) const
 
GossipMenusMapBoundsNonConst GetGossipMenusMapBoundsNonConst (uint32 uiMenuId)
 
GossipMenuItemsMapBounds GetGossipMenuItemsMapBounds (uint32 uiMenuId) const
 
GossipMenuItemsMapBoundsNonConst GetGossipMenuItemsMapBoundsNonConst (uint32 uiMenuId)
 
bool IsTransportMap (uint32 mapId) const
 

Static Public Member Functions

static std::string_view GetLocaleString (std::vector< std::string > const &data, size_t locale)
 
static void GetLocaleString (const std::vector< std::string > &data, int loc_idx, std::string &value)
 

Public Attributes

ExclusiveQuestGroups mExclusiveQuestGroups
 
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

template<HighGuid high>
ObjectGuidGeneratorBaseGetGuidSequenceGenerator ()
 

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
 
ReservedNamesContainer _profanityNamesStore
 
GameTeleContainer _gameTeleStore
 
ScriptNameContainer _scriptNamesStore
 
SpellClickInfoContainer _spellClickInfoStore
 
SpellScriptsContainer _spellScriptsStore
 
VehicleAccessoryContainer _vehicleTemplateAccessoryStore
 
VehicleAccessoryContainer _vehicleAccessoryStore
 
LocaleConstant DBCLocaleIndex
 
PageTextContainer _pageTextStore
 
InstanceTemplateContainer _instanceTemplateStore
 
MailLevelRewardContainer _mailLevelRewardStore
 
CreatureBaseStatsContainer _creatureBaseStatsStore
 
PetLevelInfoContainer _petInfoStore
 
PlayerClassInfo_playerClassInfo [MAX_CLASSES]
 
PlayerInfo_playerInfo [MAX_RACES][MAX_CLASSES]
 
PlayerXPperLevel _playerXPperLevel
 
BaseXPContainer _baseXPTable
 
FishingBaseSkillContainer _fishingBaseForAreaStore
 
HalfNameContainer _petHalfName0
 
HalfNameContainer _petHalfName1
 
HalfNameContainerLocale _petHalfLocaleName0
 
HalfNameContainerLocale _petHalfLocaleName1
 
ItemSetNameContainer _itemSetNameStore
 
MapObjectGuids _mapObjectGuidsStore
 
CellObjectGuidsMap _emptyCellObjectGuidsMap
 
CellObjectGuids _emptyCellObjectGuids
 
CreatureDataContainer _creatureDataStore
 
CreatureTemplateContainer _creatureTemplateStore
 
CreatureCustomIDsContainer _creatureCustomIDsStore
 
std::vector< CreatureTemplate * > _creatureTemplateStoreFast
 
CreatureModelContainer _creatureModelStore
 
CreatureAddonContainer _creatureAddonStore
 
CreatureAddonContainer _creatureTemplateAddonStore
 
std::unordered_map< ObjectGuid::LowType, CreatureMovementData_creatureMovementOverrides
 
GameObjectAddonContainer _gameObjectAddonStore
 
GameObjectQuestItemMap _gameObjectQuestItemStore
 
CreatureQuestItemMap _creatureQuestItemStore
 
EquipmentInfoContainer _equipmentInfoStore
 
LinkedRespawnContainer _linkedRespawnStore
 
CreatureLocaleContainer _creatureLocaleStore
 
GameObjectDataContainer _gameObjectDataStore
 
GameObjectLocaleContainer _gameObjectLocaleStore
 
GameObjectTemplateContainer _gameObjectTemplateStore
 
GameObjectTemplateAddonContainer _gameObjectTemplateAddonStore
 
TempSummonDataContainer _tempSummonDataStore
 Stores temp summon data grouped by summoner's entry, summoner's type and group id.
 
BroadcastTextContainer _broadcastTextStore
 
ItemTemplateContainer _itemTemplateStore
 
std::vector< ItemTemplate * > _itemTemplateStoreFast
 
ItemLocaleContainer _itemLocaleStore
 
ItemSetNameLocaleContainer _itemSetNameLocaleStore
 
QuestLocaleContainer _questLocaleStore
 
QuestOfferRewardLocaleContainer _questOfferRewardLocaleStore
 
QuestRequestItemsLocaleContainer _questRequestItemsLocaleStore
 
NpcTextLocaleContainer _npcTextLocaleStore
 
PageTextLocaleContainer _pageTextLocaleStore
 
AcoreStringContainer _acoreStringStore
 
GossipMenuItemsLocaleContainer _gossipMenuItemsLocaleStore
 
PointOfInterestLocaleContainer _pointOfInterestLocaleStore
 
QuestGreetingLocaleContainer _questGreetingLocaleStore
 
CacheVendorItemContainer _cacheVendorItemStore
 
CacheTrainerSpellContainer _cacheTrainerSpellStore
 
ServerMailContainer _serverMailStore
 
std::set< uint32_difficultyEntries [MAX_DIFFICULTY - 1]
 
std::set< uint32_hasDifficultyEntries [MAX_DIFFICULTY - 1]
 
std::set< uint32_transportMaps
 
QuestMoneyRewardStore _questMoneyRewards
 
std::vector< GameobjectInstanceSavedStateGameobjectInstanceSavedStateList
 

Friends

class PlayerDumpReader
 

ProfanityNames

Checks NamesProfanity.dbc for reserved names

Parameters
nameName to check for match in NamesProfanity.dbc
Returns
true/false
 ObjectMgr ()
 
 ~ObjectMgr ()
 
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
 
static ObjectMgrinstance ()
 
static uint32 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)
 
GameObjectTemplate const * GetGameObjectTemplate (uint32 entry)
 
bool IsGameObjectStaticTransport (uint32 entry)
 
int LoadReferenceVendor (int32 vendor, int32 item_id, std::set< uint32 > *skip_vendors)
 
void LoadGameObjectTemplate ()
 
void LoadGameObjectTemplateAddons ()
 
CreatureTemplate const * GetCreatureTemplate (uint32 entry)
 
CreatureModelInfo const * GetCreatureModelInfo (uint32 modelId) const
 
CreatureModelInfo const * GetCreatureModelRandomGender (uint32 *displayID)
 
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)
 
InstanceTemplate const * GetInstanceTemplate (uint32 mapId)
 
PetLevelInfo const * GetPetLevelInfo (uint32 creature_id, uint8 level) 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)
 
GossipText const * GetGossipText (uint32 Text_ID) const
 
AreaTriggerTeleport const * GetGoBackTrigger (uint32 Map) const
 
AreaTriggerTeleport const * GetMapEntranceTrigger (uint32 Map) const
 
uint32 GetAreaTriggerScriptId (uint32 trigger_id)
 
SpellScriptsBounds GetSpellScriptsBounds (uint32 spell_id)
 
int32 GetBaseReputationOf (FactionEntry const *factionEntry, uint8 race, uint8 playerClass)
 
VehicleAccessoryList const * GetVehicleAccessoryList (Vehicle *veh) const
 
void LoadQuests ()
 
void LoadQuestMoneyRewards ()
 
void LoadGameobjectQuestStarters ()
 
void LoadGameobjectQuestEnders ()
 
void LoadCreatureQuestStarters ()
 
void LoadCreatureQuestEnders ()
 
void LoadEventScripts ()
 
void LoadSpellScripts ()
 
void LoadWaypointScripts ()
 
void LoadSpellScriptNames ()
 
void ValidateSpellScripts ()
 
void InitializeSpellInfoPrecomputedData ()
 
bool LoadAcoreStrings ()
 
void LoadBroadcastTexts ()
 
void LoadBroadcastTextLocales ()
 
void LoadCreatureClassLevelStats ()
 
void LoadCreatureLocales ()
 
void LoadCreatureTemplates ()
 
void LoadCreatureTemplate (Field *fields)
 
void LoadCreatureTemplateAddons ()
 
void LoadCreatureTemplateResistances ()
 
void LoadCreatureTemplateSpells ()
 
void LoadCreatureCustomIDs ()
 Load config option Creatures.CustomIDs into Store.
 
void CheckCreatureTemplate (CreatureTemplate const *cInfo)
 
void CheckCreatureMovement (char const *table, uint64 id, CreatureMovementData &creatureMovement)
 
void LoadGameObjectQuestItems ()
 
void LoadCreatureQuestItems ()
 
void LoadTempSummons ()
 
void LoadCreatures ()
 
void LoadLinkedRespawn ()
 
bool SetCreatureLinkedRespawn (ObjectGuid::LowType guid, ObjectGuid::LowType linkedGuid)
 
void LoadCreatureAddons ()
 
void LoadGameObjectAddons ()
 
void LoadCreatureModelInfo ()
 
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 LoadMailServerTemplates ()
 
void LoadVehicleTemplateAccessories ()
 
void LoadVehicleAccessories ()
 
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 LoadTrainerSpell ()
 
void AddSpellToTrainer (uint32 entry, uint32 spell, uint32 spellCost, uint32 reqSkill, uint32 reqSkillValue, uint32 reqLevel, uint32 reqSpell)
 
std::string GeneratePetName (uint32 entry)
 
std::string GeneratePetNameLocale (uint32 entry, LocaleConstant locale)
 
uint32 GetBaseXP (uint8 level)
 
uint32 GetXPForLevel (uint8 level) const
 
void ReturnOrDeleteOldMails (bool serverUp)
 
CreatureBaseStats const * GetCreatureBaseStats (uint8 level, uint8 unitClass)
 
void SetHighestGuids ()
 
uint32 GenerateAuctionID ()
 
uint64 GenerateEquipmentSetGuid ()
 
uint32 GenerateMailID ()
 
uint32 GeneratePetNumber ()
 
ObjectGuid::LowType GenerateCreatureSpawnId ()
 
ObjectGuid::LowType GenerateGameObjectSpawnId ()
 
void DeleteCreatureData (ObjectGuid::LowType spawnId)
 
QuestGreeting const * GetQuestGreeting (TypeID type, uint32 id) const
 
void DeleteGOData (ObjectGuid::LowType guid)
 
char const * GetAcoreString (uint32 entry, LocaleConstant locale) const
 
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)
 
uint32 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)
 
uint32 AddCreData (uint32 entry, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay=0)
 
void LoadReservedPlayersNames ()
 
bool IsReservedName (std::string_view name) const
 
void AddReservedPlayerName (std::string const &name)
 
void LoadProfanityPlayersNames ()
 
bool IsProfanityName (std::string_view name) const
 
void AddProfanityPlayerName (std::string const &name)
 
GameTele const * GetGameTele (std::string_view name) const
 
bool AddGameTele (GameTele &data)
 
bool DeleteGameTele (std::string_view name)
 
void AddVendorItem (uint32 entry, uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedCost, bool persist=true)
 
bool RemoveVendorItem (uint32 entry, uint32 item, bool persist=true)
 
bool IsVendorItemValid (uint32 vendor_entry, uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost, Player *player=nullptr, std::set< uint32 > *skip_vendors=nullptr, uint32 ORnpcflag=0) const
 
void LoadScriptNames ()
 
std::string const & GetScriptName (uint32 id) const
 
uint32 GetScriptId (std::string const &name)
 
void LoadFactionChangeAchievements ()
 
void LoadFactionChangeItems ()
 
void LoadFactionChangeQuests ()
 
void LoadFactionChangeReputations ()
 
void LoadFactionChangeSpells ()
 
void LoadFactionChangeTitles ()
 
uint32 GetQuestMoneyReward (uint8 level, uint32 questMoneyDifficulty) const
 
void SendServerMail (Player *player, uint32 id, uint32 reqLevel, uint32 reqPlayTime, uint32 rewardMoneyA, uint32 rewardMoneyH, uint32 rewardItemA, uint32 rewardItemCountA, uint32 rewardItemH, uint32 rewardItemCountH, std::string subject, std::string body, uint8 active) const
 
void LoadInstanceSavedGameobjectStateData ()
 
bool FindInstanceSavedGameobjectState (uint32 id, uint32 guid)
 
uint8 GetInstanceSavedGameobjectState (uint32 id, uint32 guid)
 
void SetInstanceSavedGameobjectState (uint32 id, uint32 guid, uint8 state)
 
void NewInstanceSavedGameobjectState (uint32 id, uint32 guid, uint8 state)
 

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

◆ CharacterConversionMap

◆ 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 
1620 {
1622 CREATURE_TO_GO, // Creature is dependant on GO
1623 GO_TO_GO,
1624 GO_TO_CREATURE, // GO is dependant on creature
1625 };
@ CREATURE_TO_GO
Definition: ObjectMgr.h:1622
@ CREATURE_TO_CREATURE
Definition: ObjectMgr.h:1621
@ GO_TO_GO
Definition: ObjectMgr.h:1623
@ GO_TO_CREATURE
Definition: ObjectMgr.h:1624

Constructor & Destructor Documentation

◆ ObjectMgr()

ObjectMgr::ObjectMgr ( )
private
355 :
356 _auctionId(1),
358 _mailId(1),
359 _hiPetNumber(1),
363{
364 for (uint8 i = 0; i < MAX_CLASSES; ++i)
365 {
366 _playerClassInfo[i] = nullptr;
367 for (uint8 j = 0; j < MAX_RACES; ++j)
368 _playerInfo[j][i] = nullptr;
369 }
370}
@ LOCALE_enUS
Definition: Common.h:75
std::uint8_t uint8
Definition: Define.h:110
#define MAX_RACES
Definition: SharedDefines.h:94
#define MAX_CLASSES
Definition: SharedDefines.h:127
PlayerInfo * _playerInfo[MAX_RACES][MAX_CLASSES]
Definition: ObjectMgr.h:1551
ObjectGuid::LowType _gameObjectSpawnId
Definition: ObjectMgr.h:1463
uint32 _mailId
Definition: ObjectMgr.h:1457
ObjectGuid::LowType _creatureSpawnId
Definition: ObjectMgr.h:1462
LocaleConstant DBCLocaleIndex
Definition: ObjectMgr.h:1529
PlayerClassInfo * _playerClassInfo[MAX_CLASSES]
Definition: ObjectMgr.h:1547
uint64 _equipmentSetGuid
Definition: ObjectMgr.h:1456
uint32 _auctionId
Definition: ObjectMgr.h:1455
uint32 _hiPetNumber
Definition: ObjectMgr.h:1459

References _playerClassInfo, _playerInfo, MAX_CLASSES, and MAX_RACES.

◆ ~ObjectMgr()

ObjectMgr::~ObjectMgr ( )
private
373{
374 for (QuestMap::iterator i = _questTemplates.begin(); i != _questTemplates.end(); ++i)
375 delete i->second;
376
377 for (PetLevelInfoContainer::iterator i = _petInfoStore.begin(); i != _petInfoStore.end(); ++i)
378 delete[] i->second;
379
380 // free only if loaded
381 for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
382 {
383 if (_playerClassInfo[class_])
384 delete[] _playerClassInfo[class_]->levelInfo;
385 delete _playerClassInfo[class_];
386 }
387
388 for (int race = 0; race < MAX_RACES; ++race)
389 {
390 for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
391 {
392 if (_playerInfo[race][class_])
393 delete[] _playerInfo[race][class_]->levelInfo;
394 delete _playerInfo[race][class_];
395 }
396 }
397
398 for (CacheVendorItemContainer::iterator itr = _cacheVendorItemStore.begin(); itr != _cacheVendorItemStore.end(); ++itr)
399 itr->second.Clear();
400
402
403 for (DungeonEncounterContainer::iterator itr = _dungeonEncounterStore.begin(); itr != _dungeonEncounterStore.end(); ++itr)
404 for (DungeonEncounterList::iterator encounterItr = itr->second.begin(); encounterItr != itr->second.end(); ++encounterItr)
405 delete *encounterItr;
406
407 for (DungeonProgressionRequirementsContainer::iterator itr = _accessRequirementStore.begin(); itr != _accessRequirementStore.end(); ++itr)
408 {
409 std::unordered_map<uint8, DungeonProgressionRequirements*> difficulties = itr->second;
410 for (auto difficultiesItr = difficulties.begin(); difficultiesItr != difficulties.end(); ++difficultiesItr)
411 {
412 for (auto questItr = difficultiesItr->second->quests.begin(); questItr != difficultiesItr->second->quests.end(); ++questItr)
413 {
414 delete* questItr;
415 }
416
417 for (auto achievementItr = difficultiesItr->second->achievements.begin(); achievementItr != difficultiesItr->second->achievements.end(); ++achievementItr)
418 {
419 delete* achievementItr;
420 }
421
422 for (auto itemsItr = difficultiesItr->second->items.begin(); itemsItr != difficultiesItr->second->items.end(); ++itemsItr)
423 {
424 delete* itemsItr;
425 }
426
427 delete difficultiesItr->second;
428 }
429 }
430}
PlayerClassLevelInfo * levelInfo
Definition: Player.h:300
PlayerLevelInfo * levelInfo
Definition: Player.h:354
CacheTrainerSpellContainer _cacheTrainerSpellStore
Definition: ObjectMgr.h:1612
PetLevelInfoContainer _petInfoStore
Definition: ObjectMgr.h:1545
QuestMap _questTemplates
Definition: ObjectMgr.h:1478
DungeonProgressionRequirementsContainer _accessRequirementStore
Definition: ObjectMgr.h:1492
DungeonEncounterContainer _dungeonEncounterStore
Definition: ObjectMgr.h:1493
CacheVendorItemContainer _cacheVendorItemStore
Definition: ObjectMgr.h:1611

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

Member Function Documentation

◆ AddCreatureToGrid()

void ObjectMgr::AddCreatureToGrid ( ObjectGuid::LowType  guid,
CreatureData const *  data 
)
2339{
2340 uint8 mask = data->spawnMask;
2341 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
2342 {
2343 if (mask & 1)
2344 {
2345 CellCoord cellCoord = Acore::ComputeCellCoord(data->posX, data->posY);
2346 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()];
2347 cell_guids.creatures.insert(guid);
2348 }
2349 }
2350}
uint32 MAKE_PAIR32(uint16 l, uint16 h)
Definition: ObjectDefines.h:87
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:191
Definition: ObjectMgr.h:479
CellGuidSet creatures
Definition: ObjectMgr.h:480
MapObjectGuids _mapObjectGuidsStore
Definition: ObjectMgr.h:1572
uint32 GetId() const
Definition: GridDefines.h:148

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

Referenced by AddCreData(), and LoadCreatures().

◆ AddCreData()

uint32 ObjectMgr::AddCreData ( uint32  entry,
uint32  map,
float  x,
float  y,
float  z,
float  o,
uint32  spawntimedelay = 0 
)
2418{
2419 CreatureTemplate const* cInfo = GetCreatureTemplate(entry);
2420 if (!cInfo)
2421 return 0;
2422
2423 uint32 level = cInfo->minlevel == cInfo->maxlevel ? cInfo->minlevel : urand(cInfo->minlevel, cInfo->maxlevel); // Only used for extracting creature base stats
2424 CreatureBaseStats const* stats = GetCreatureBaseStats(level, cInfo->unit_class);
2425 Map* map = sMapMgr->CreateBaseMap(mapId);
2426 if (!map)
2427 return 0;
2428
2430 CreatureData& data = NewOrExistCreatureData(spawnId);
2431 data.spawnMask = spawnId;
2432 data.id1 = entry;
2433 data.id2 = 0;
2434 data.id3 = 0;
2435 data.mapid = mapId;
2436 data.displayid = 0;
2437 data.equipmentId = 0;
2438 data.posX = x;
2439 data.posY = y;
2440 data.posZ = z;
2441 data.orientation = o;
2442 data.spawntimesecs = spawntimedelay;
2443 data.wander_distance = 0;
2444 data.currentwaypoint = 0;
2445 data.curhealth = stats->GenerateHealth(cInfo);
2446 data.curmana = stats->GenerateMana(cInfo);
2447 data.movementType = cInfo->MovementType;
2448 data.spawnMask = 1;
2450 data.dbData = false;
2451 data.npcflag = cInfo->npcflag;
2452 data.unit_flags = cInfo->unit_flags;
2453 data.dynamicflags = cInfo->dynamicflags;
2454
2455 AddCreatureToGrid(spawnId, &data);
2456
2457 // Spawn if necessary (loaded grids only)
2458 if (!map->Instanceable() && !map->IsRemovalGrid(x, y))
2459 {
2460 Creature* creature = new Creature();
2461 if (!creature->LoadCreatureFromDB(spawnId, map, true, false, true))
2462 {
2463 LOG_ERROR("sql.sql", "AddCreature: Cannot add creature entry {} to map", entry);
2464 delete creature;
2465 return 0;
2466 }
2467 }
2468
2469 return spawnId;
2470}
std::uint32_t uint32
Definition: Define.h:108
#define LOG_ERROR(filterType__,...)
Definition: Log.h:159
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:44
@ PHASEMASK_NORMAL
Definition: Object.h:56
#define sMapMgr
Definition: MapMgr.h:221
Definition: Creature.h:46
bool LoadCreatureFromDB(ObjectGuid::LowType guid, Map *map, bool addToMap=true, bool gridLoad=false, bool allowDuplicate=false)
Definition: Creature.cpp:1661
Definition: CreatureData.h:176
uint32 unit_flags
Definition: CreatureData.h:207
uint8 minlevel
Definition: CreatureData.h:188
uint8 maxlevel
Definition: CreatureData.h:189
uint32 MovementType
Definition: CreatureData.h:227
uint32 npcflag
Definition: CreatureData.h:192
uint32 unit_class
Definition: CreatureData.h:206
uint32 dynamicflags
Definition: CreatureData.h:209
Definition: CreatureData.h:292
uint32 GenerateMana(CreatureTemplate const *info) const
Definition: CreatureData.h:307
uint32 GenerateHealth(CreatureTemplate const *info) const
Definition: CreatureData.h:302
Definition: CreatureData.h:359
float wander_distance
Definition: CreatureData.h:373
uint32 phaseMask
Definition: CreatureData.h:365
uint32 spawntimesecs
Definition: CreatureData.h:372
uint32 dynamicflags
Definition: CreatureData.h:381
uint32 npcflag
Definition: CreatureData.h:379
bool dbData
Definition: CreatureData.h:383
uint32 displayid
Definition: CreatureData.h:366
uint8 movementType
Definition: CreatureData.h:377
uint8 spawnMask
Definition: CreatureData.h:378
uint32 unit_flags
Definition: CreatureData.h:380
uint32 id2
Definition: CreatureData.h:362
uint32 curhealth
Definition: CreatureData.h:375
float orientation
Definition: CreatureData.h:371
uint32 curmana
Definition: CreatureData.h:376
uint32 id3
Definition: CreatureData.h:363
float posY
Definition: CreatureData.h:369
float posX
Definition: CreatureData.h:368
int8 equipmentId
Definition: CreatureData.h:367
uint32 currentwaypoint
Definition: CreatureData.h:374
uint16 mapid
Definition: CreatureData.h:364
float posZ
Definition: CreatureData.h:370
uint32 id1
Definition: CreatureData.h:361
uint32 LowType
Definition: ObjectGuid.h:124
CreatureBaseStats const * GetCreatureBaseStats(uint8 level, uint8 unitClass)
Definition: ObjectMgr.cpp:9612
void AddCreatureToGrid(ObjectGuid::LowType guid, CreatureData const *data)
Definition: ObjectMgr.cpp:2338
ObjectGuid::LowType GenerateCreatureSpawnId()
Definition: ObjectMgr.cpp:7040
CreatureData & NewOrExistCreatureData(ObjectGuid::LowType spawnId)
Definition: ObjectMgr.h:1206
CreatureTemplate const * GetCreatureTemplate(uint32 entry)
Definition: ObjectMgr.cpp:9960
Definition: Map.h:312
bool IsRemovalGrid(float x, float y) const
Definition: Map.h:362
bool Instanceable() const
Definition: Map.h:446

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::IsRemovalGrid(), 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 
)
2645{
2646 uint8 mask = data->spawnMask;
2647 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
2648 {
2649 if (mask & 1)
2650 {
2651 CellCoord cellCoord = Acore::ComputeCellCoord(data->posX, data->posY);
2652 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()];
2653 cell_guids.gameobjects.insert(guid);
2654 }
2655 }
2656}
CellGuidSet gameobjects
Definition: ObjectMgr.h:481

References _mapObjectGuidsStore, Acore::ComputeCellCoord(), 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)
8844{
8845 // find max id
8846 uint32 new_id = 0;
8847 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
8848 if (itr->first > new_id)
8849 new_id = itr->first;
8850
8851 // use next
8852 ++new_id;
8853
8854 if (!Utf8toWStr(tele.name, tele.wnameLow))
8855 return false;
8856
8857 wstrToLower(tele.wnameLow);
8858
8859 _gameTeleStore[new_id] = tele;
8860
8862
8863 stmt->SetData(0, new_id);
8864 stmt->SetData(1, tele.position_x);
8865 stmt->SetData(2, tele.position_y);
8866 stmt->SetData(3, tele.position_z);
8867 stmt->SetData(4, tele.orientation);
8868 stmt->SetData(5, uint16(tele.mapId));
8869 stmt->SetData(6, tele.name);
8870
8871 WorldDatabase.Execute(stmt);
8872
8873 return true;
8874}
std::uint16_t uint16
Definition: Define.h:109
void wstrToLower(std::wstring &str)
Definition: Util.cpp:383
bool Utf8toWStr(char const *utf8str, size_t csize, wchar_t *wstr, size_t &wsize)
Definition: Util.cpp:282
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
@ WORLD_INS_GAME_TELE
Definition: WorldDatabase.h:41
Definition: PreparedStatement.h:158
Acore::Types::is_default< T > SetData(const uint8 index, T value)
Definition: PreparedStatement.h:78
GameTeleContainer _gameTeleStore
Definition: ObjectMgr.h:1518

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

uint32 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 
)
2367{
2368 GameObjectTemplate const* goinfo = GetGameObjectTemplate(entry);
2369 if (!goinfo)
2370 return 0;
2371
2372 Map* map = sMapMgr->CreateBaseMap(mapId);
2373 if (!map)
2374 return 0;
2375
2377
2378 GameObjectData& data = NewGOData(spawnId);
2379 data.id = entry;
2380 data.mapid = mapId;
2381 data.posX = x;
2382 data.posY = y;
2383 data.posZ = z;
2384 data.orientation = o;
2385 data.rotation.x = rotation0;
2386 data.rotation.y = rotation1;
2387 data.rotation.z = rotation2;
2388 data.rotation.w = rotation3;
2389 data.spawntimesecs = spawntimedelay;
2390 data.animprogress = 100;
2391 data.spawnMask = 1;
2392 data.go_state = GO_STATE_READY;
2394 data.artKit = goinfo->type == GAMEOBJECT_TYPE_CAPTURE_POINT ? 21 : 0;
2395 data.dbData = false;
2396
2397 AddGameobjectToGrid(spawnId, &data);
2398
2399 // Spawn if necessary (loaded grids only)
2400 // We use spawn coords to spawn
2401 if (!map->Instanceable() && map->IsGridLoaded(x, y))
2402 {
2403 GameObject* go = sObjectMgr->IsGameObjectStaticTransport(data.id) ? new StaticTransport() : new GameObject();
2404 if (!go->LoadGameObjectFromDB(spawnId, map))
2405 {
2406 LOG_ERROR("sql.sql", "AddGOData: cannot add gameobject entry {} to map", entry);
2407 delete go;
2408 return 0;
2409 }
2410 }
2411
2412 LOG_DEBUG("maps", "AddGOData: spawnId {} entry {} map {} x {} y {} z {} o {}", spawnId, entry, mapId, x, y, z, o);
2413
2414 return spawnId;
2415}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:171
@ GO_STATE_READY
Definition: GameObjectData.h:691
#define sObjectMgr
Definition: ObjectMgr.h:1640
@ GAMEOBJECT_TYPE_CAPTURE_POINT
Definition: SharedDefines.h:1561
Definition: GameObject.h:122
bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map *map, bool addToMap=true)
Definition: GameObject.cpp:1120
Definition: GameObjectData.h:32
uint32 type
Definition: GameObjectData.h:34
Definition: GameObjectData.h:697
bool dbData
Definition: GameObjectData.h:713
float orientation
Definition: GameObjectData.h:705
float posZ
Definition: GameObjectData.h:704
uint8 artKit
Definition: GameObjectData.h:712
int32 spawntimesecs
Definition: GameObjectData.h:707
uint8 spawnMask
Definition: GameObjectData.h:711
G3D::Quat rotation
Definition: GameObjectData.h:706
uint32 animprogress
Definition: GameObjectData.h:709
uint16 mapid
Definition: GameObjectData.h:700
float posX
Definition: GameObjectData.h:702
uint32 phaseMask
Definition: GameObjectData.h:701
float posY
Definition: GameObjectData.h:703
uint32 id
Definition: GameObjectData.h:699
GOState go_state
Definition: GameObjectData.h:710
Definition: Transport.h:112
void AddGameobjectToGrid(ObjectGuid::LowType guid, GameObjectData const *data)
Definition: ObjectMgr.cpp:2644
GameObjectTemplate const * GetGameObjectTemplate(uint32 entry)
Definition: ObjectMgr.cpp:9936
ObjectGuid::LowType GenerateGameObjectSpawnId()
Definition: ObjectMgr.cpp:7050
GameObjectData & NewGOData(ObjectGuid::LowType guid)
Definition: ObjectMgr.h:1311
bool IsGridLoaded(float x, float y) const
Definition: Map.h:368

References AddGameobjectToGrid(), GameObjectData::animprogress, GameObjectData::artKit, GameObjectData::dbData, GAMEOBJECT_TYPE_CAPTURE_POINT, GenerateGameObjectSpawnId(), GetGameObjectTemplate(), GameObjectData::go_state, GO_STATE_READY, GameObjectData::id, Map::Instanceable(), 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, sObjectMgr, GameObjectData::spawnMask, GameObjectData::spawntimesecs, and GameObjectTemplate::type.

◆ AddLocaleString()

void ObjectMgr::AddLocaleString ( std::string &&  s,
LocaleConstant  locale,
std::vector< std::string > &  data 
)
static

◆ AddProfanityPlayerName()

void ObjectMgr::AddProfanityPlayerName ( std::string const &  name)
8263{
8264 if (!IsProfanityName(name))
8265 {
8266 std::wstring wstr;
8267 if (!Utf8toWStr(name, wstr))
8268 {
8269 LOG_ERROR("server", "Could not add invalid name to profanity player names: {}", name);
8270 return;
8271 }
8272 wstrToLower(wstr);
8273
8274 _profanityNamesStore.insert(wstr);
8275
8277 stmt->SetData(0, name);
8278 CharacterDatabase.Execute(stmt);
8279 }
8280}
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
@ CHAR_INS_PROFANITY_PLAYER_NAME
Definition: CharacterDatabase.h:513
bool IsProfanityName(std::string_view name) const
Definition: ObjectMgr.cpp:8247
ReservedNamesContainer _profanityNamesStore
Definition: ObjectMgr.h:1516

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

◆ AddReservedPlayerName()

void ObjectMgr::AddReservedPlayerName ( std::string const &  name)
8188{
8189 if (!IsReservedName(name))
8190 {
8191 std::wstring wstr;
8192 if (!Utf8toWStr(name, wstr))
8193 {
8194 LOG_ERROR("server", "Could not add invalid name to reserved player names: {}", name);
8195 return;
8196 }
8197 wstrToLower(wstr);
8198
8199 _reservedNamesStore.insert(wstr);
8200
8202 stmt->SetData(0, name);
8203 CharacterDatabase.Execute(stmt);
8204 }
8205}
@ CHAR_INS_RESERVED_PLAYER_NAME
Definition: CharacterDatabase.h:512
bool IsReservedName(std::string_view name) const
Definition: ObjectMgr.cpp:8172
ReservedNamesContainer _reservedNamesStore
Definition: ObjectMgr.h:1512

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

◆ AddSpellToTrainer()

void ObjectMgr::AddSpellToTrainer ( uint32  entry,
uint32  spell,
uint32  spellCost,
uint32  reqSkill,
uint32  reqSkillValue,
uint32  reqLevel,
uint32  reqSpell 
)
8965{
8966 if (entry >= ACORE_TRAINER_START_REF)
8967 return;
8968
8969 CreatureTemplate const* cInfo = GetCreatureTemplate(entry);
8970 if (!cInfo)
8971 {
8972 LOG_ERROR("sql.sql", "Table `npc_trainer` contains an entry for a non-existing creature template (Entry: {}), ignoring", entry);
8973 return;
8974 }
8975
8976 if (!(cInfo->npcflag & UNIT_NPC_FLAG_TRAINER))
8977 {
8978 LOG_ERROR("sql.sql", "Table `npc_trainer` contains an entry for a creature template (Entry: {}) without trainer flag, ignoring", entry);
8979 return;
8980 }
8981
8982 SpellInfo const* spellinfo = sSpellMgr->GetSpellInfo(spell);
8983 if (!spellinfo)
8984 {
8985 LOG_ERROR("sql.sql", "Table `npc_trainer` contains an entry (Entry: {}) for a non-existing spell (Spell: {}), ignoring", entry, spell);
8986 return;
8987 }
8988
8989 if (!SpellMgr::ComputeIsSpellValid(spellinfo))
8990 {
8991 LOG_ERROR("sql.sql", "Table `npc_trainer` contains an entry (Entry: {}) for a broken spell (Spell: {}), ignoring", entry, spell);
8992 return;
8993 }
8994
8995 if (GetTalentSpellCost(spell))
8996 {
8997 LOG_ERROR("sql.sql", "Table `npc_trainer` contains an entry (Entry: {}) for a non-existing spell (Spell: {}) which is a talent, ignoring", entry, spell);
8998 return;
8999 }
9000
9001 if (reqSpell && !sSpellMgr->GetSpellInfo(reqSpell))
9002 {
9003 LOG_ERROR("sql.sql", "Table `npc_trainer` contains an entry (Entry: {}) for a non-existing reqSpell (Spell: {}), ignoring", entry, reqSpell);
9004 return;
9005 }
9006
9008
9009 TrainerSpell& trainerSpell = data.spellList[spell];
9010 trainerSpell.spell = spell;
9011 trainerSpell.spellCost = spellCost;
9012 trainerSpell.reqSkill = reqSkill;
9013 trainerSpell.reqSkillValue = reqSkillValue;
9014 trainerSpell.reqLevel = reqLevel;
9015 trainerSpell.reqSpell = reqSpell;
9016
9017 if (!trainerSpell.reqLevel)
9018 trainerSpell.reqLevel = spellinfo->SpellLevel;
9019
9020 // calculate learned spell for profession case when stored cast-spell
9021 trainerSpell.learnedSpell[0] = spell;
9022 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
9023 {
9024 if (spellinfo->Effects[i].Effect != SPELL_EFFECT_LEARN_SPELL)
9025 continue;
9026 if (trainerSpell.learnedSpell[0] == spell)
9027 trainerSpell.learnedSpell[0] = 0;
9028 // player must be able to cast spell on himself
9029 if (spellinfo->Effects[i].TargetA.GetTarget() != 0 && spellinfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_TARGET_ALLY
9030 && spellinfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_TARGET_ANY && spellinfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_CASTER)
9031 {
9032 LOG_ERROR("sql.sql", "Table `npc_trainer` has spell {} for trainer entry {} with learn effect which has incorrect target type, ignoring learn effect!", spell, entry);
9033 continue;
9034 }
9035
9036 trainerSpell.learnedSpell[i] = spellinfo->Effects[i].TriggerSpell;
9037
9038 if (trainerSpell.learnedSpell[i])
9039 {
9040 SpellInfo const* learnedSpellInfo = sSpellMgr->GetSpellInfo(trainerSpell.learnedSpell[i]);
9041 if (learnedSpellInfo && learnedSpellInfo->IsProfession())
9042 data.trainerType = 2;
9043 }
9044 }
9045
9046 return;
9047}
uint32 GetTalentSpellCost(uint32 spellId)
Definition: DBCStores.cpp:679
@ UNIT_NPC_FLAG_TRAINER
Definition: Unit.h:520
#define ACORE_TRAINER_START_REF
Definition: ObjectMgr.h:494
#define sSpellMgr
Definition: SpellMgr.h:818
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1610
@ SPELL_EFFECT_LEARN_SPELL
Definition: SharedDefines.h:786
@ TARGET_UNIT_TARGET_ALLY
Definition: SharedDefines.h:1397
@ TARGET_UNIT_TARGET_ANY
Definition: SharedDefines.h:1401
@ TARGET_UNIT_CASTER
Definition: SharedDefines.h:1382
Definition: CreatureData.h:496
uint32 reqSkillValue
Definition: CreatureData.h:506
uint32 learnedSpell[3]
Definition: CreatureData.h:508
uint32 reqSpell
Definition: CreatureData.h:509
uint32 spellCost
Definition: CreatureData.h:504
uint32 reqSkill
Definition: CreatureData.h:505
uint32 reqLevel
Definition: CreatureData.h:507
uint32 spell
Definition: CreatureData.h:503
Definition: CreatureData.h:518
TrainerSpellMap spellList
Definition: CreatureData.h:522
uint32 trainerType
Definition: CreatureData.h:523
Definition: SpellInfo.h:314
uint32 SpellLevel
Definition: SpellInfo.h:358
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:391
bool IsProfession() const
Definition: SpellInfo.cpp:937
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:371

References _cacheTrainerSpellStore, ACORE_TRAINER_START_REF, SpellMgr::ComputeIsSpellValid(), SpellInfo::Effects, GetCreatureTemplate(), GetTalentSpellCost(), SpellInfo::IsProfession(), TrainerSpell::learnedSpell, LOG_ERROR, MAX_SPELL_EFFECTS, CreatureTemplate::npcflag, TrainerSpell::reqLevel, TrainerSpell::reqSkill, TrainerSpell::reqSkillValue, TrainerSpell::reqSpell, TrainerSpell::spell, SPELL_EFFECT_LEARN_SPELL, TrainerSpell::spellCost, SpellInfo::SpellLevel, TrainerSpellData::spellList, sSpellMgr, TARGET_UNIT_CASTER, TARGET_UNIT_TARGET_ALLY, TARGET_UNIT_TARGET_ANY, TrainerSpellData::trainerType, and UNIT_NPC_FLAG_TRAINER.

Referenced by LoadTrainerSpell().

◆ AddVendorItem()

void ObjectMgr::AddVendorItem ( uint32  entry,
uint32  item,
int32  maxcount,
uint32  incrtime,
uint32  extendedCost,
bool  persist = true 
)
9290{
9291 VendorItemData& vList = _cacheVendorItemStore[entry];
9292 vList.AddItem(item, maxcount, incrtime, extendedCost);
9293
9294 if (persist)
9295 {
9297
9298 stmt->SetData(0, entry);
9299 stmt->SetData(1, item);
9300 stmt->SetData(2, maxcount);
9301 stmt->SetData(3, incrtime);
9302 stmt->SetData(4, extendedCost);
9303
9304 WorldDatabase.Execute(stmt);
9305 }
9306}
@ WORLD_INS_NPC_VENDOR
Definition: WorldDatabase.h:43
Definition: CreatureData.h:458
void AddItem(uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost)
Definition: CreatureData.h:470

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
4344{
4345 // base data (last known level)
4346 *info = _playerInfo[race][_class]->levelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) - 1];
4347
4348 // if conversion from uint32 to uint8 causes unexpected behaviour, change lvl to uint32
4349 for (uint8 lvl = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) - 1; lvl < level; ++lvl)
4350 {
4351 switch (_class)
4352 {
4353 case CLASS_WARRIOR:
4354 info->stats[STAT_STRENGTH] += (lvl > 23 ? 2 : (lvl > 1 ? 1 : 0));
4355 info->stats[STAT_STAMINA] += (lvl > 23 ? 2 : (lvl > 1 ? 1 : 0));
4356 info->stats[STAT_AGILITY] += (lvl > 36 ? 1 : (lvl > 6 && (lvl % 2) ? 1 : 0));
4357 info->stats[STAT_INTELLECT] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4358 info->stats[STAT_SPIRIT] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4359 break;
4360 case CLASS_PALADIN:
4361 info->stats[STAT_STRENGTH] += (lvl > 3 ? 1 : 0);
4362 info->stats[STAT_STAMINA] += (lvl > 33 ? 2 : (lvl > 1 ? 1 : 0));
4363 info->stats[STAT_AGILITY] += (lvl > 38 ? 1 : (lvl > 7 && !(lvl % 2) ? 1 : 0));
4364 info->stats[STAT_INTELLECT] += (lvl > 6 && (lvl % 2) ? 1 : 0);
4365 info->stats[STAT_SPIRIT] += (lvl > 7 ? 1 : 0);
4366 break;
4367 case CLASS_HUNTER:
4368 info->stats[STAT_STRENGTH] += (lvl > 4 ? 1 : 0);
4369 info->stats[STAT_STAMINA] += (lvl > 4 ? 1 : 0);
4370 info->stats[STAT_AGILITY] += (lvl > 33 ? 2 : (lvl > 1 ? 1 : 0));
4371 info->stats[STAT_INTELLECT] += (lvl > 8 && (lvl % 2) ? 1 : 0);
4372 info->stats[STAT_SPIRIT] += (lvl > 38 ? 1 : (lvl > 9 && !(lvl % 2) ? 1 : 0));
4373 break;
4374 case CLASS_ROGUE:
4375 info->stats[STAT_STRENGTH] += (lvl > 5 ? 1 : 0);
4376 info->stats[STAT_STAMINA] += (lvl > 4 ? 1 : 0);
4377 info->stats[STAT_AGILITY] += (lvl > 16 ? 2 : (lvl > 1 ? 1 : 0));
4378 info->stats[STAT_INTELLECT] += (lvl > 8 && !(lvl % 2) ? 1 : 0);
4379 info->stats[STAT_SPIRIT] += (lvl > 38 ? 1 : (lvl > 9 && !(lvl % 2) ? 1 : 0));
4380 break;
4381 case CLASS_PRIEST:
4382 info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4383 info->stats[STAT_STAMINA] += (lvl > 5 ? 1 : 0);
4384 info->stats[STAT_AGILITY] += (lvl > 38 ? 1 : (lvl > 8 && (lvl % 2) ? 1 : 0));
4385 info->stats[STAT_INTELLECT] += (lvl > 22 ? 2 : (lvl > 1 ? 1 : 0));
4386 info->stats[STAT_SPIRIT] += (lvl > 3 ? 1 : 0);
4387 break;
4388 case CLASS_SHAMAN:
4389 info->stats[STAT_STRENGTH] += (lvl > 34 ? 1 : (lvl > 6 && (lvl % 2) ? 1 : 0));
4390 info->stats[STAT_STAMINA] += (lvl > 4 ? 1 : 0);
4391 info->stats[STAT_AGILITY] += (lvl > 7 && !(lvl % 2) ? 1 : 0);
4392 info->stats[STAT_INTELLECT] += (lvl > 5 ? 1 : 0);
4393 info->stats[STAT_SPIRIT] += (lvl > 4 ? 1 : 0);
4394 break;
4395 case CLASS_MAGE:
4396 info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4397 info->stats[STAT_STAMINA] += (lvl > 5 ? 1 : 0);
4398 info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4399 info->stats[STAT_INTELLECT] += (lvl > 24 ? 2 : (lvl > 1 ? 1 : 0));
4400 info->stats[STAT_SPIRIT] += (lvl > 33 ? 2 : (lvl > 2 ? 1 : 0));
4401 break;
4402 case CLASS_WARLOCK:
4403 info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4404 info->stats[STAT_STAMINA] += (lvl > 38 ? 2 : (lvl > 3 ? 1 : 0));
4405 info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl % 2) ? 1 : 0);
4406 info->stats[STAT_INTELLECT] += (lvl > 33 ? 2 : (lvl > 2 ? 1 : 0));
4407 info->stats[STAT_SPIRIT] += (lvl > 38 ? 2 : (lvl > 3 ? 1 : 0));
4408 break;
4409 case CLASS_DRUID:
4410 info->stats[STAT_STRENGTH] += (lvl > 38 ? 2 : (lvl > 6 && (lvl % 2) ? 1 : 0));
4411 info->stats[STAT_STAMINA] += (lvl > 32 ? 2 : (lvl > 4 ? 1 : 0));
4412 info->stats[STAT_AGILITY] += (lvl > 38 ? 2 : (lvl > 8 && (lvl % 2) ? 1 : 0));
4413 info->stats[STAT_INTELLECT] += (lvl > 38 ? 3 : (lvl > 4 ? 1 : 0));
4414 info->stats[STAT_SPIRIT] += (lvl > 38 ? 3 : (lvl > 5 ? 1 : 0));
4415 }
4416 }
4417}
@ CONFIG_MAX_PLAYER_LEVEL
Definition: IWorld.h:234
@ CLASS_HUNTER
Definition: SharedDefines.h:115
@ CLASS_DRUID
Definition: SharedDefines.h:123
@ CLASS_SHAMAN
Definition: SharedDefines.h:119
@ CLASS_PRIEST
Definition: SharedDefines.h:117
@ CLASS_WARRIOR
Definition: SharedDefines.h:113
@ CLASS_WARLOCK
Definition: SharedDefines.h:121
@ CLASS_MAGE
Definition: SharedDefines.h:120
@ CLASS_PALADIN
Definition: SharedDefines.h:114
@ CLASS_ROGUE
Definition: SharedDefines.h:116
@ STAT_SPIRIT
Definition: SharedDefines.h:234
@ STAT_INTELLECT
Definition: SharedDefines.h:233
@ STAT_AGILITY
Definition: SharedDefines.h:231
@ STAT_STRENGTH
Definition: SharedDefines.h:230
@ STAT_STAMINA
Definition: SharedDefines.h:232
#define sWorld
Definition: World.h:451

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

Referenced by GetPlayerLevelInfo().

◆ ChangeFishingBaseSkillLevel()

void ObjectMgr::ChangeFishingBaseSkillLevel ( uint32  entry,
int32  skill 
)
8663{
8664 AreaTableEntry const* fArea = sAreaTableStore.LookupEntry(entry);
8665 if (!fArea)
8666 {
8667 LOG_ERROR("sql.sql", "AreaId {} defined in `skill_fishing_base_level` does not exist", entry);
8668 return;
8669 }
8670
8671 _fishingBaseForAreaStore[entry] = skill;
8672
8673 LOG_INFO("server.loading", ">> Fishing base skill level of area {} changed to {}", entry, skill);
8674 LOG_INFO("server.loading", " ");
8675}
#define LOG_INFO(filterType__,...)
Definition: Log.h:167
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
FishingBaseSkillContainer _fishingBaseForAreaStore
Definition: ObjectMgr.h:1560
Definition: DBCStructure.h:519

References _fishingBaseForAreaStore, LOG_ERROR, LOG_INFO, and sAreaTableStore.

◆ CheckCreatureMovement()

void ObjectMgr::CheckCreatureMovement ( char const *  table,
uint64  id,
CreatureMovementData creatureMovement 
)
1316{
1317 if (creatureMovement.Ground >= CreatureGroundMovementType::Max)
1318 {
1319 LOG_ERROR("sql.sql", "`{}`.`Ground` wrong value ({}) for Id {}, setting to Run.", table, uint32(creatureMovement.Ground), id);
1320 creatureMovement.Ground = CreatureGroundMovementType::Run;
1321 }
1322
1323 if (creatureMovement.Flight >= CreatureFlightMovementType::Max)
1324 {
1325 LOG_ERROR("sql.sql", "`{}`.`Flight` wrong value ({}) for Id {}, setting to None.", table, uint32(creatureMovement.Flight), id);
1326 creatureMovement.Flight = CreatureFlightMovementType::None;
1327 }
1328
1329 if (creatureMovement.Chase >= CreatureChaseMovementType::Max)
1330 {
1331 LOG_ERROR("sql.sql", "`{}`.`Chase` wrong value ({}) for Id {}, setting to Run.", table, uint32(creatureMovement.Chase), id);
1332 creatureMovement.Chase = CreatureChaseMovementType::Run;
1333 }
1334
1335 if (creatureMovement.Random >= CreatureRandomMovementType::Max)
1336 {
1337 LOG_ERROR("sql.sql", "`{}`.`Random` wrong value ({}) for Id {}, setting to Walk.", table, uint32(creatureMovement.Random), id);
1338 creatureMovement.Random = CreatureRandomMovementType::Walk;
1339 }
1340}
CreatureRandomMovementType Random
Definition: CreatureData.h:133
CreatureFlightMovementType Flight
Definition: CreatureData.h:129
CreatureChaseMovementType Chase
Definition: CreatureData.h:132
CreatureGroundMovementType Ground
Definition: CreatureData.h:128

References CreatureMovementData::Chase, CreatureMovementData::Flight, CreatureMovementData::Ground, LOG_ERROR, and CreatureMovementData::Random.

Referenced by CheckCreatureTemplate(), and LoadCreatureMovementOverrides().

◆ CheckCreatureTemplate()

void ObjectMgr::CheckCreatureTemplate ( CreatureTemplate const *  cInfo)

if not set custom creature scale then load scale from CreatureDisplayInfo.dbc

958{
959 if (!cInfo)
960 return;
961
962 bool ok = true; // bool to allow continue outside this loop
963 for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff)
964 {
965 if (!cInfo->DifficultyEntry[diff])
966 continue;
967 ok = false; // will be set to true at the end of this loop again
968
969 CreatureTemplate const* difficultyInfo = GetCreatureTemplate(cInfo->DifficultyEntry[diff]);
970 if (!difficultyInfo)
971 {
972 LOG_ERROR("sql.sql", "Creature (Entry: {}) has `difficulty_entry_{}`={} but creature entry {} does not exist.",
973 cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff], cInfo->DifficultyEntry[diff]);
974 continue;
975 }
976
977 bool ok2 = true;
978 for (uint32 diff2 = 0; diff2 < MAX_DIFFICULTY - 1 && ok2; ++diff2)
979 {
980 ok2 = false;
981 if (_difficultyEntries[diff2].find(cInfo->Entry) != _difficultyEntries[diff2].end())
982 {
983 LOG_ERROR("sql.sql", "Creature (Entry: {}) is listed as `difficulty_entry_{}` of another creature, but itself lists {} in `difficulty_entry_{}`.",
984 cInfo->Entry, diff2 + 1, cInfo->DifficultyEntry[diff], diff + 1);
985 continue;
986 }
987
988 if (_difficultyEntries[diff2].find(cInfo->DifficultyEntry[diff]) != _difficultyEntries[diff2].end())
989 {
990 LOG_ERROR("sql.sql", "Creature (Entry: {}) already listed as `difficulty_entry_{}` for another entry.", cInfo->DifficultyEntry[diff], diff2 + 1);
991 continue;
992 }
993
994 if (_hasDifficultyEntries[diff2].find(cInfo->DifficultyEntry[diff]) != _hasDifficultyEntries[diff2].end())
995 {
996 LOG_ERROR("sql.sql", "Creature (Entry: {}) has `difficulty_entry_{}`={} but creature entry {} has itself a value in `difficulty_entry_{}`.",
997 cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff], cInfo->DifficultyEntry[diff], diff2 + 1);
998 continue;
999 }
1000 ok2 = true;
1001 }
1002 if (!ok2)
1003 continue;
1004
1005 if (cInfo->expansion > difficultyInfo->expansion)
1006 {
1007 LOG_ERROR("sql.sql", "Creature (Entry: {}, expansion {}) has different `expansion` in difficulty {} mode (Entry: {}, expansion {}).",
1008 cInfo->Entry, cInfo->expansion, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->expansion);
1009 }
1010
1011 if (cInfo->faction != difficultyInfo->faction)
1012 {
1013 LOG_ERROR("sql.sql", "Creature (Entry: {}, faction {}) has different `faction` in difficulty {} mode (Entry: {}, faction {}).",
1014 cInfo->Entry, cInfo->faction, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->faction);
1015 }
1016
1017 if (cInfo->unit_class != difficultyInfo->unit_class)
1018 {
1019 LOG_ERROR("sql.sql", "Creature (Entry: {}, class {}) has different `unit_class` in difficulty {} mode (Entry: {}, class {}).",
1020 cInfo->Entry, cInfo->unit_class, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->unit_class);
1021 continue;
1022 }
1023
1024 if (cInfo->npcflag != difficultyInfo->npcflag)
1025 {
1026 LOG_ERROR("sql.sql", "Creature (Entry: {}) has different `npcflag` in difficulty {} mode (Entry: {}).", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
1027 continue;
1028 }
1029
1030 if (cInfo->family != difficultyInfo->family)
1031 {
1032 LOG_ERROR("sql.sql", "Creature (Entry: {}, family {}) has different `family` in difficulty {} mode (Entry: {}, family {}).",
1033 cInfo->Entry, cInfo->family, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->family);
1034 }
1035
1036 if (cInfo->trainer_class != difficultyInfo->trainer_class)
1037 {
1038 LOG_ERROR("sql.sql", "Creature (Entry: {}) has different `trainer_class` in difficulty {} mode (Entry: {}).", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
1039 continue;
1040 }
1041
1042 if (cInfo->trainer_race != difficultyInfo->trainer_race)
1043 {
1044 LOG_ERROR("sql.sql", "Creature (Entry: {}) has different `trainer_race` in difficulty {} mode (Entry: {}).", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
1045 continue;
1046 }
1047
1048 if (cInfo->trainer_type != difficultyInfo->trainer_type)
1049 {
1050 LOG_ERROR("sql.sql", "Creature (Entry: {}) has different `trainer_type` in difficulty {} mode (Entry: {}).", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
1051 continue;
1052 }
1053
1054 if (cInfo->trainer_spell != difficultyInfo->trainer_spell)
1055 {
1056 LOG_ERROR("sql.sql", "Creature (Entry: {}) has different `trainer_spell` in difficulty {} mode (Entry: {}).", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
1057 continue;
1058 }
1059
1060 if (cInfo->type != difficultyInfo->type)
1061 {
1062 LOG_ERROR("sql.sql", "Creature (Entry: {}, type {}) has different `type` in difficulty {} mode (Entry: {}, type {}).",
1063 cInfo->Entry, cInfo->type, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->type);
1064 }
1065
1066 if (!cInfo->VehicleId && difficultyInfo->VehicleId)
1067 {
1068 LOG_ERROR("sql.sql", "Creature (Entry: {}, VehicleId {}) has different `VehicleId` in difficulty {} mode (Entry: {}, VehicleId {}).",
1069 cInfo->Entry, cInfo->VehicleId, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->VehicleId);
1070 }
1071
1072 // Xinef: check dmg school
1073 if (cInfo->dmgschool != difficultyInfo->dmgschool)
1074 {
1075 LOG_ERROR("sql.sql", "Creature (Entry: {}) has different `dmgschool` in difficulty {} mode (Entry: {})", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
1076 }
1077
1078 if (!difficultyInfo->AIName.empty())
1079 {
1080 LOG_ERROR("sql.sql", "Creature (Entry: {}) lists difficulty {} mode entry {} with `AIName` filled in. `AIName` of difficulty 0 mode creature is always used instead.",
1081 cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
1082 continue;
1083 }
1084
1085 if (difficultyInfo->ScriptID)
1086 {
1087 LOG_ERROR("sql.sql", "Creature (Entry: {}) lists difficulty {} mode entry {} with `ScriptName` filled in. `ScriptName` of difficulty 0 mode creature is always used instead.",
1088 cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
1089 continue;
1090 }
1091
1092 _hasDifficultyEntries[diff].insert(cInfo->Entry);
1093 _difficultyEntries[diff].insert(cInfo->DifficultyEntry[diff]);
1094 ok = true;
1095 }
1096
1097 if (!cInfo->AIName.empty() && !sCreatureAIRegistry->HasItem(cInfo->AIName))
1098 {
1099 LOG_ERROR("sql.sql", "Creature (Entry: {}) has non-registered `AIName` '{}' set, removing", cInfo->Entry, cInfo->AIName);
1100 const_cast<CreatureTemplate*>(cInfo)->AIName.clear();
1101 }
1102
1103 FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction);
1104 if (!factionTemplate)
1105 LOG_ERROR("sql.sql", "Creature (Entry: {}) has non-existing faction template ({}).", cInfo->Entry, cInfo->faction);
1106
1107 // used later for scale
1108 CreatureDisplayInfoEntry const* displayScaleEntry = nullptr;
1109
1110 if (cInfo->Modelid1)
1111 {
1112 CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->Modelid1);
1113 if (!displayEntry)
1114 {
1115 LOG_ERROR("sql.sql", "Creature (Entry: {}) lists non-existing Modelid1 id ({}), this can crash the client.", cInfo->Entry, cInfo->Modelid1);
1116 const_cast<CreatureTemplate*>(cInfo)->Modelid1 = 0;
1117 }
1118 else if (!displayScaleEntry)
1119 displayScaleEntry = displayEntry;
1120
1121 CreatureModelInfo const* modelInfo = GetCreatureModelInfo(cInfo->Modelid1);
1122 if (!modelInfo)
1123 LOG_ERROR("sql.sql", "No model data exist for `Modelid1` = {} listed by creature (Entry: {}).", cInfo->Modelid1, cInfo->Entry);
1124 }
1125
1126 if (cInfo->Modelid2)
1127 {
1128 CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->Modelid2);
1129 if (!displayEntry)
1130 {
1131 LOG_ERROR("sql.sql", "Creature (Entry: {}) lists non-existing Modelid2 id ({}), this can crash the client.", cInfo->Entry, cInfo->Modelid2);
1132 const_cast<CreatureTemplate*>(cInfo)->Modelid2 = 0;
1133 }
1134 else if (!displayScaleEntry)
1135 displayScaleEntry = displayEntry;
1136
1137 CreatureModelInfo const* modelInfo = GetCreatureModelInfo(cInfo->Modelid2);
1138 if (!modelInfo)
1139 LOG_ERROR("sql.sql", "No model data exist for `Modelid2` = {} listed by creature (Entry: {}).", cInfo->Modelid2, cInfo->Entry);
1140 }
1141
1142 if (cInfo->Modelid3)
1143 {
1144 CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->Modelid3);
1145 if (!displayEntry)
1146 {
1147 LOG_ERROR("sql.sql", "Creature (Entry: {}) lists non-existing Modelid3 id ({}), this can crash the client.", cInfo->Entry, cInfo->Modelid3);
1148 const_cast<CreatureTemplate*>(cInfo)->Modelid3 = 0;
1149 }
1150 else if (!displayScaleEntry)
1151 displayScaleEntry = displayEntry;
1152
1153 CreatureModelInfo const* modelInfo = GetCreatureModelInfo(cInfo->Modelid3);
1154 if (!modelInfo)
1155 LOG_ERROR("sql.sql", "No model data exist for `Modelid3` = {} listed by creature (Entry: {}).", cInfo->Modelid3, cInfo->Entry);
1156 }
1157
1158 if (cInfo->Modelid4)
1159 {
1160 CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->Modelid4);
1161 if (!displayEntry)
1162 {
1163 LOG_ERROR("sql.sql", "Creature (Entry: {}) lists non-existing Modelid4 id ({}), this can crash the client.", cInfo->Entry, cInfo->Modelid4);
1164 const_cast<CreatureTemplate*>(cInfo)->Modelid4 = 0;
1165 }
1166 else if (!displayScaleEntry)
1167 displayScaleEntry = displayEntry;
1168
1169 CreatureModelInfo const* modelInfo = GetCreatureModelInfo(cInfo->Modelid4);
1170 if (!modelInfo)
1171 LOG_ERROR("sql.sql", "No model data exist for `Modelid4` = {} listed by creature (Entry: {}).", cInfo->Modelid4, cInfo->Entry);
1172 }
1173
1174 if (!displayScaleEntry)
1175 LOG_ERROR("sql.sql", "Creature (Entry: {}) does not have any existing display id in Modelid1/Modelid2/Modelid3/Modelid4.", cInfo->Entry);
1176
1177 for (int k = 0; k < MAX_KILL_CREDIT; ++k)
1178 {
1179 if (cInfo->KillCredit[k])
1180 {
1181 if (!GetCreatureTemplate(cInfo->KillCredit[k]))
1182 {
1183 LOG_ERROR("sql.sql", "Creature (Entry: {}) lists non-existing creature entry {} in `KillCredit{}`.", cInfo->Entry, cInfo->KillCredit[k], k + 1);
1184 const_cast<CreatureTemplate*>(cInfo)->KillCredit[k] = 0;
1185 }
1186 }
1187 }
1188
1189 if (!cInfo->unit_class || ((1 << (cInfo->unit_class - 1)) & CLASSMASK_ALL_CREATURES) == 0)
1190 {
1191 LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid unit_class ({}) in creature_template. Set to 1 (UNIT_CLASS_WARRIOR).", cInfo->Entry, cInfo->unit_class);
1192 const_cast<CreatureTemplate*>(cInfo)->unit_class = UNIT_CLASS_WARRIOR;
1193 }
1194
1195 if (cInfo->dmgschool >= MAX_SPELL_SCHOOL)
1196 {
1197 LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid spell school value ({}) in `dmgschool`.", cInfo->Entry, cInfo->dmgschool);
1198 const_cast<CreatureTemplate*>(cInfo)->dmgschool = SPELL_SCHOOL_NORMAL;
1199 }
1200
1201 if (cInfo->BaseAttackTime == 0)
1202 const_cast<CreatureTemplate*>(cInfo)->BaseAttackTime = BASE_ATTACK_TIME;
1203
1204 if (cInfo->RangeAttackTime == 0)
1205 const_cast<CreatureTemplate*>(cInfo)->RangeAttackTime = BASE_ATTACK_TIME;
1206
1207 if ((cInfo->npcflag & UNIT_NPC_FLAG_TRAINER) && cInfo->trainer_type >= MAX_TRAINER_TYPE)
1208 LOG_ERROR("sql.sql", "Creature (Entry: {}) has wrong trainer type {}.", cInfo->Entry, cInfo->trainer_type);
1209
1210 if (cInfo->speed_walk == 0.0f)
1211 {
1212 LOG_ERROR("sql.sql", "Creature (Entry: {}) has wrong value ({}) in speed_walk, set to 1.", cInfo->Entry, cInfo->speed_walk);
1213 const_cast<CreatureTemplate*>(cInfo)->speed_walk = 1.0f;
1214 }
1215
1216 if (cInfo->speed_run == 0.0f)
1217 {
1218 LOG_ERROR("sql.sql", "Creature (Entry: {}) has wrong value ({}) in speed_run, set to 1.14286.", cInfo->Entry, cInfo->speed_run);
1219 const_cast<CreatureTemplate*>(cInfo)->speed_run = 1.14286f;
1220 }
1221
1222 if (cInfo->type && !sCreatureTypeStore.LookupEntry(cInfo->type))
1223 {
1224 LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid creature type ({}) in `type`.", cInfo->Entry, cInfo->type);
1225 const_cast<CreatureTemplate*>(cInfo)->type = CREATURE_TYPE_HUMANOID;
1226 }
1227
1228 // must exist or used hidden but used in data horse case
1229 if (cInfo->family && !sCreatureFamilyStore.LookupEntry(cInfo->family) && cInfo->family != CREATURE_FAMILY_HORSE_CUSTOM)
1230 {
1231 LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid creature family ({}) in `family`.", cInfo->Entry, cInfo->family);
1232 const_cast<CreatureTemplate*>(cInfo)->family = 0;
1233 }
1234
1235 CheckCreatureMovement("creature_template_movement", cInfo->Entry, const_cast<CreatureTemplate*>(cInfo)->Movement);
1236
1237 if (cInfo->HoverHeight < 0.0f)
1238 {
1239 LOG_ERROR("sql.sql", "Creature (Entry: {}) has wrong value ({}) in `HoverHeight`", cInfo->Entry, cInfo->HoverHeight);
1240 const_cast<CreatureTemplate*>(cInfo)->HoverHeight = 1.0f;
1241 }
1242
1243 if (cInfo->VehicleId)
1244 {
1245 VehicleEntry const* vehId = sVehicleStore.LookupEntry(cInfo->VehicleId);
1246 if (!vehId)
1247 {
1248 LOG_ERROR("sql.sql", "Creature (Entry: {}) has a non-existing VehicleId ({}). This *WILL* cause the client to freeze!", cInfo->Entry, cInfo->VehicleId);
1249 const_cast<CreatureTemplate*>(cInfo)->VehicleId = 0;
1250 }
1251 }
1252
1253 if (cInfo->PetSpellDataId)
1254 {
1255 CreatureSpellDataEntry const* spellDataId = sCreatureSpellDataStore.LookupEntry(cInfo->PetSpellDataId);
1256 if (!spellDataId)
1257 LOG_ERROR("sql.sql", "Creature (Entry: {}) has non-existing PetSpellDataId ({}).", cInfo->Entry, cInfo->PetSpellDataId);
1258 }
1259
1260 for (uint8 j = 0; j < MAX_CREATURE_SPELLS; ++j)
1261 {
1262 if (cInfo->spells[j] && !sSpellMgr->GetSpellInfo(cInfo->spells[j]))
1263 {
1264 LOG_ERROR("sql.sql", "Creature (Entry: {}) has non-existing Spell{} ({}), set to 0.", cInfo->Entry, j + 1, cInfo->spells[j]);
1265 const_cast<CreatureTemplate*>(cInfo)->spells[j] = 0;
1266 }
1267 }
1268
1269 if (cInfo->MovementType >= MAX_DB_MOTION_TYPE)
1270 {
1271 LOG_ERROR("sql.sql", "Creature (Entry: {}) has wrong movement generator type ({}), ignored and set to IDLE.", cInfo->Entry, cInfo->MovementType);
1272 const_cast<CreatureTemplate*>(cInfo)->MovementType = IDLE_MOTION_TYPE;
1273 }
1274
1276 if (cInfo->scale <= 0.0f)
1277 {
1278 if (displayScaleEntry)
1279 const_cast<CreatureTemplate*>(cInfo)->scale = displayScaleEntry->scale;
1280 else
1281 const_cast<CreatureTemplate*>(cInfo)->scale = 1.0f;
1282 }
1283
1284 if (cInfo->expansion > (MAX_EXPANSIONS - 1))
1285 {
1286 LOG_ERROR("sql.sql", "Table `creature_template` lists creature (Entry: {}) with expansion {}. Ignored and set to 0.", cInfo->Entry, cInfo->expansion);
1287 const_cast<CreatureTemplate*>(cInfo)->expansion = 0;
1288 }
1289
1290 if (uint32 badFlags = (cInfo->flags_extra & ~CREATURE_FLAG_EXTRA_DB_ALLOWED))
1291 {
1292 LOG_ERROR("sql.sql", "Table `creature_template` lists creature (Entry: {}) with disallowed `flags_extra` {}, removing incorrect flag.", cInfo->Entry, badFlags);
1293 const_cast<CreatureTemplate*>(cInfo)->flags_extra &= CREATURE_FLAG_EXTRA_DB_ALLOWED;
1294 }
1295
1296 const_cast<CreatureTemplate*>(cInfo)->DamageModifier *= Creature::_GetDamageMod(cInfo->rank);
1297
1298 // Hack for modules
1299 for (auto itr : _creatureCustomIDsStore)
1300 {
1301 if (cInfo->Entry == itr)
1302 return;
1303 }
1304
1305 if ((cInfo->GossipMenuId && !(cInfo->npcflag & UNIT_NPC_FLAG_GOSSIP)) && !(cInfo->flags_extra & CREATURE_FLAG_EXTRA_MODULE))
1306 {
1307 LOG_ERROR("sql.sql", "Creature (Entry: {}) has assigned gossip menu {}, but npcflag does not include UNIT_NPC_FLAG_GOSSIP (1).", cInfo->Entry, cInfo->GossipMenuId);
1308 }
1309 else if ((!cInfo->GossipMenuId && (cInfo->npcflag & UNIT_NPC_FLAG_GOSSIP)) && !(cInfo->flags_extra & CREATURE_FLAG_EXTRA_MODULE))
1310 {
1311 LOG_INFO("sql.sql", "Creature (Entry: {}) has npcflag UNIT_NPC_FLAG_GOSSIP (1), but gossip menu is unassigned.", cInfo->Entry);
1312 }
1313}
#define sCreatureAIRegistry
Definition: CreatureAIFactory.h:48
DBCStorage< VehicleEntry > sVehicleStore(VehicleEntryfmt)
DBCStorage< CreatureSpellDataEntry > sCreatureSpellDataStore(CreatureSpellDatafmt)
DBCStorage< CreatureDisplayInfoEntry > sCreatureDisplayInfoStore(CreatureDisplayInfofmt)
DBCStorage< CreatureFamilyEntry > sCreatureFamilyStore(CreatureFamilyfmt)
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
DBCStorage< CreatureTypeEntry > sCreatureTypeStore(CreatureTypefmt)
@ CREATURE_FLAG_EXTRA_DB_ALLOWED
Definition: CreatureData.h:85
@ CREATURE_FLAG_EXTRA_MODULE
Definition: CreatureData.h:73
#define MAX_KILL_CREDIT
Definition: CreatureData.h:34
#define BASE_ATTACK_TIME
Definition: Unit.h:40
@ UNIT_NPC_FLAG_GOSSIP
Definition: Unit.h:516
static constexpr uint32 MAX_CREATURE_SPELLS
Definition: Unit.h:153
@ MAX_DB_MOTION_TYPE
Definition: MotionMaster.h:40
@ IDLE_MOTION_TYPE
Definition: MotionMaster.h:37
spells
Definition: boss_krystallus.cpp:25
#define MAX_DIFFICULTY
Definition: DBCEnums.h:288
@ SPELL_SCHOOL_NORMAL
Definition: SharedDefines.h:255
constexpr auto MAX_SPELL_SCHOOL
Definition: SharedDefines.h:264
@ CREATURE_FAMILY_HORSE_CUSTOM
Definition: SharedDefines.h:2631
@ UNIT_CLASS_WARRIOR
Definition: SharedDefines.h:138
@ CREATURE_TYPE_HUMANOID
Definition: SharedDefines.h:2606
#define CLASSMASK_ALL_CREATURES
Definition: SharedDefines.h:144
@ MAX_EXPANSIONS
Definition: SharedDefines.h:55
#define MAX_TRAINER_TYPE
Definition: SharedDefines.h:2595
static float _GetDamageMod(int32 Rank)
Definition: Creature.cpp:1561
float scale
Definition: CreatureData.h:198
uint32 trainer_spell
Definition: CreatureData.h:212
uint32 trainer_class
Definition: CreatureData.h:213
uint32 type
Definition: CreatureData.h:215
uint32 trainer_race
Definition: CreatureData.h:214
uint32 ScriptID
Definition: CreatureData.h:240
uint32 VehicleId
Definition: CreatureData.h:223
CreatureMovementData Movement
Definition: CreatureData.h:228
uint32 faction
Definition: CreatureData.h:191
uint32 dmgschool
Definition: CreatureData.h:200
uint32 expansion
Definition: CreatureData.h:190
uint32 trainer_type
Definition: CreatureData.h:211
std::string AIName
Definition: CreatureData.h:226
uint32 family
Definition: CreatureData.h:210
Definition: CreatureData.h:388
std::set< uint32 > _difficultyEntries[MAX_DIFFICULTY - 1]
Definition: ObjectMgr.h:1616
CreatureCustomIDsContainer _creatureCustomIDsStore
Definition: ObjectMgr.h:1577
std::set< uint32 > _hasDifficultyEntries[MAX_DIFFICULTY - 1]
Definition: ObjectMgr.h:1617
void CheckCreatureMovement(char const *table, uint64 id, CreatureMovementData &creatureMovement)
Definition: ObjectMgr.cpp:1315
CreatureModelInfo const * GetCreatureModelInfo(uint32 modelId) const
Definition: ObjectMgr.cpp:1708
Definition: DBCStructure.h:721
float scale
Definition: DBCStructure.h:726
Definition: DBCStructure.h:801
Definition: DBCStructure.h:930
Definition: DBCStructure.h:2003

References _creatureCustomIDsStore, _difficultyEntries, Creature::_GetDamageMod(), _hasDifficultyEntries, CreatureTemplate::AIName, BASE_ATTACK_TIME, CreatureTemplate::BaseAttackTime, CheckCreatureMovement(), CLASSMASK_ALL_CREATURES, CREATURE_FAMILY_HORSE_CUSTOM, CREATURE_FLAG_EXTRA_DB_ALLOWED, CREATURE_FLAG_EXTRA_MODULE, CREATURE_TYPE_HUMANOID, CreatureTemplate::DifficultyEntry, CreatureTemplate::dmgschool, CreatureTemplate::Entry, CreatureTemplate::expansion, CreatureTemplate::faction, CreatureTemplate::family, CreatureTemplate::flags_extra, GetCreatureModelInfo(), GetCreatureTemplate(), CreatureTemplate::GossipMenuId, CreatureTemplate::HoverHeight, IDLE_MOTION_TYPE, CreatureTemplate::KillCredit, LOG_ERROR, LOG_INFO, MAX_CREATURE_SPELLS, MAX_DB_MOTION_TYPE, MAX_DIFFICULTY, MAX_EXPANSIONS, MAX_KILL_CREDIT, MAX_SPELL_SCHOOL, MAX_TRAINER_TYPE, CreatureTemplate::Modelid1, CreatureTemplate::Modelid2, CreatureTemplate::Modelid3, CreatureTemplate::Modelid4, CreatureTemplate::Movement, CreatureTemplate::MovementType, CreatureTemplate::npcflag, CreatureTemplate::PetSpellDataId, CreatureTemplate::RangeAttackTime, CreatureTemplate::rank, CreatureTemplate::scale, CreatureDisplayInfoEntry::scale, sCreatureAIRegistry, sCreatureDisplayInfoStore, sCreatureFamilyStore, sCreatureSpellDataStore, sCreatureTypeStore, CreatureTemplate::ScriptID, sFactionTemplateStore, CreatureTemplate::speed_run, CreatureTemplate::speed_walk, SPELL_SCHOOL_NORMAL, CreatureTemplate::spells, sSpellMgr, sVehicleStore, CreatureTemplate::trainer_class, CreatureTemplate::trainer_race, CreatureTemplate::trainer_spell, CreatureTemplate::trainer_type, CreatureTemplate::type, CreatureTemplate::unit_class, UNIT_CLASS_WARRIOR, UNIT_NPC_FLAG_GOSSIP, UNIT_NPC_FLAG_TRAINER, and CreatureTemplate::VehicleId.

Referenced by LoadCreatureTemplates().

◆ CheckDeclinedNames()

bool ObjectMgr::CheckDeclinedNames ( std::wstring  w_ownname,
DeclinedName const &  names 
)
static
8678{
8679 // get main part of the name
8680 std::wstring mainpart = GetMainPartOfName(w_ownname, 0);
8681 // prepare flags
8682 bool x = true;
8683 bool y = true;
8684
8685 // check declined names
8686 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
8687 {
8688 std::wstring wname;
8689 if (!Utf8toWStr(names.name[i], wname))
8690 return false;
8691
8692 if (mainpart != GetMainPartOfName(wname, i + 1))
8693 x = false;
8694
8695 if (w_ownname != wname)
8696 y = false;
8697 }
8698 return (x || y);
8699}
std::wstring GetMainPartOfName(std::wstring const &wname, uint32 declension)
Definition: Util.cpp:387
#define MAX_DECLINED_NAME_CASES
Definition: Unit.h:969

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
8466{
8467 std::wstring wname;
8468 if (!Utf8toWStr(name, wname))
8469 return PET_NAME_INVALID;
8470
8471 if (wname.size() > MAX_PET_NAME)
8472 return PET_NAME_TOO_LONG;
8473
8474 uint32 minName = sWorld->getIntConfig(CONFIG_MIN_PET_NAME);
8475 if (wname.size() < minName)
8476 return PET_NAME_TOO_SHORT;
8477
8478 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_PET_NAMES);
8479 if (!isValidString(wname, strictMask, false))
8481
8482 // Check for Reserved Name from DBC
8483 if (sWorld->getBoolConfig(CONFIG_STRICT_NAMES_RESERVED))
8484 {
8485 if (ReservedNames(wname))
8486 {
8487 return PET_NAME_RESERVED;
8488 }
8489 }
8490
8491 // Check for Profanity
8492 if (sWorld->getBoolConfig(CONFIG_STRICT_NAMES_PROFANITY))
8493 {
8494 if (ProfanityNames(wname))
8495 {
8496 return PET_NAME_PROFANE;
8497 }
8498 }
8499
8500 return PET_NAME_SUCCESS;
8501}
bool isValidString(std::wstring wstr, uint32 strictMask, bool numericOrSpace, bool create=false)
Definition: ObjectMgr.cpp:8319
bool ReservedNames(std::wstring &name)
Definition: ObjectMgr.cpp:215
bool ProfanityNames(std::wstring &name)
Definition: ObjectMgr.cpp:243
#define MAX_PET_NAME
Definition: ObjectMgr.h:690
@ CONFIG_STRICT_PET_NAMES
Definition: IWorld.h:221
@ CONFIG_MIN_PET_NAME
Definition: IWorld.h:224
@ CONFIG_STRICT_NAMES_PROFANITY
Definition: IWorld.h:183
@ CONFIG_STRICT_NAMES_RESERVED
Definition: IWorld.h:182
@ PET_NAME_INVALID
Definition: SharedDefines.h:3632
@ PET_NAME_RESERVED
Definition: SharedDefines.h:3638
@ PET_NAME_SUCCESS
Definition: SharedDefines.h:3630
@ PET_NAME_MIXED_LANGUAGES
Definition: SharedDefines.h:3636
@ PET_NAME_TOO_SHORT
Definition: SharedDefines.h:3634
@ PET_NAME_TOO_LONG
Definition: SharedDefines.h:3635
@ PET_NAME_PROFANE
Definition: SharedDefines.h:3637

References CONFIG_MIN_PET_NAME, CONFIG_STRICT_NAMES_PROFANITY, CONFIG_STRICT_NAMES_RESERVED, 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, ProfanityNames(), ReservedNames(), sWorld, and Utf8toWStr().

Referenced by WorldSession::HandlePetRename().

◆ CheckPlayerName()

uint8 ObjectMgr::CheckPlayerName ( std::string_view  name,
bool  create = false 
)
static
8356{
8357 std::wstring wname;
8358
8359 // Check for invalid characters
8360 if (!Utf8toWStr(name, wname))
8362
8363 // Check for too long name
8364 if (wname.size() > MAX_PLAYER_NAME)
8365 return CHAR_NAME_TOO_LONG;
8366
8367 // Check for too short name
8368 uint32 minName = sWorld->getIntConfig(CONFIG_MIN_PLAYER_NAME);
8369 if (wname.size() < minName)
8370 return CHAR_NAME_TOO_SHORT;
8371
8372 // Check for mixed languages
8373 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_PLAYER_NAMES);
8374 if (!isValidString(wname, strictMask, false, create))
8376
8377 // Check for three consecutive letters
8378 wstrToLower(wname);
8379 for (size_t i = 2; i < wname.size(); ++i)
8380 if (wname[i] == wname[i - 1] && wname[i] == wname[i - 2])
8382
8383 // Check Reserved Name from Database
8384 if (sObjectMgr->IsReservedName(name))
8385 {
8386 return CHAR_NAME_RESERVED;
8387 }
8388
8389 if (sObjectMgr->IsProfanityName(name))
8390 {
8391 return CHAR_NAME_PROFANE;
8392 }
8393
8394 // Check for Reserved Name from DBC
8395 if (sWorld->getBoolConfig(CONFIG_STRICT_NAMES_RESERVED))
8396 {
8397 if (ReservedNames(wname))
8398 {
8399 return CHAR_NAME_RESERVED;
8400 }
8401 }
8402
8403 // Check for Profanity
8404 if (sWorld->getBoolConfig(CONFIG_STRICT_NAMES_PROFANITY))
8405 {
8406 if (ProfanityNames(wname))
8407 {
8408 return CHAR_NAME_PROFANE;
8409 }
8410 }
8411
8412 return CHAR_NAME_SUCCESS;
8413}
#define MAX_PLAYER_NAME
Definition: ObjectMgr.h:688
@ CONFIG_STRICT_PLAYER_NAMES
Definition: IWorld.h:218
@ CONFIG_MIN_PLAYER_NAME
Definition: IWorld.h:222
@ CHAR_NAME_TOO_SHORT
Definition: SharedDefines.h:3394
@ CHAR_NAME_THREE_CONSECUTIVE
Definition: SharedDefines.h:3402
@ CHAR_NAME_INVALID_CHARACTER
Definition: SharedDefines.h:3396
@ CHAR_NAME_TOO_LONG
Definition: SharedDefines.h:3395
@ CHAR_NAME_RESERVED
Definition: SharedDefines.h:3399
@ CHAR_NAME_MIXED_LANGUAGES
Definition: SharedDefines.h:3397
@ CHAR_NAME_PROFANE
Definition: SharedDefines.h:3398
@ CHAR_NAME_SUCCESS
Definition: SharedDefines.h:3391

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_NAMES_PROFANITY, CONFIG_STRICT_NAMES_RESERVED, CONFIG_STRICT_PLAYER_NAMES, isValidString(), MAX_PLAYER_NAME, ProfanityNames(), ReservedNames(), 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
1727{
1728 npcflag = cinfo->npcflag;
1729 unit_flags = cinfo->unit_flags;
1730 dynamicflags = cinfo->dynamicflags;
1731
1732 if (data)
1733 {
1734 if (data->npcflag)
1735 npcflag = data->npcflag;
1736
1737 if (data->unit_flags)
1738 unit_flags = data->unit_flags;
1739
1740 if (data->dynamicflags)
1741 dynamicflags = data->dynamicflags;
1742 }
1743}

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

Referenced by Creature::UpdateEntry().

◆ ChooseDisplayId()

uint32 ObjectMgr::ChooseDisplayId ( CreatureTemplate const *  cinfo,
CreatureData const *  data = nullptr 
)
static
1718{
1719 // Load creature model (display id)
1720 if (data && data->displayid)
1721 return data->displayid;
1722
1723 return cinfo->GetRandomValidModelId();
1724}

References CreatureData::displayid, and CreatureTemplate::GetRandomValidModelId().

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

◆ DeleteCreatureData()

void ObjectMgr::DeleteCreatureData ( ObjectGuid::LowType  spawnId)
8012{
8013 // remove mapid*cellid -> guid_set map
8014 CreatureData const* data = GetCreatureData(guid);
8015 if (data)
8016 RemoveCreatureFromGrid(guid, data);
8017
8018 _creatureDataStore.erase(guid);
8019}
CreatureDataContainer _creatureDataStore
Definition: ObjectMgr.h:1575
void RemoveCreatureFromGrid(ObjectGuid::LowType guid, CreatureData const *data)
Definition: ObjectMgr.cpp:2352
CreatureData const * GetCreatureData(ObjectGuid::LowType spawnId) const
Definition: ObjectMgr.h:1200

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

◆ DeleteGameTele()

bool ObjectMgr::DeleteGameTele ( std::string_view  name)
8877{
8878 // explicit name case
8879 std::wstring wname;
8880 if (!Utf8toWStr(name, wname))
8881 return false;
8882
8883 // converting string that we try to find to lower case
8884 wstrToLower(wname);
8885
8886 for (GameTeleContainer::iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
8887 {
8888 if (itr->second.wnameLow == wname)
8889 {
8891
8892 stmt->SetData(0, itr->second.name);
8893
8894 WorldDatabase.Execute(stmt);
8895
8896 _gameTeleStore.erase(itr);
8897 return true;
8898 }
8899 }
8900
8901 return false;
8902}
@ 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)
8022{
8023 // remove mapid*cellid -> guid_set map
8024 GameObjectData const* data = GetGameObjectData(guid);
8025 if (data)
8026 RemoveGameobjectFromGrid(guid, data);
8027
8028 _gameObjectDataStore.erase(guid);
8029}
GameObjectData const * GetGameObjectData(ObjectGuid::LowType spawnId) const
Definition: ObjectMgr.h:1217
GameObjectDataContainer _gameObjectDataStore
Definition: ObjectMgr.h:1589
void RemoveGameobjectFromGrid(ObjectGuid::LowType guid, GameObjectData const *data)
Definition: ObjectMgr.cpp:2658

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

◆ FindInstanceSavedGameobjectState()

bool ObjectMgr::FindInstanceSavedGameobjectState ( uint32  id,
uint32  guid 
)
10142{
10143 for (auto it = GameobjectInstanceSavedStateList.begin(); it != GameobjectInstanceSavedStateList.end(); it++)
10144 {
10145 if (it->m_guid == guid && it->m_instance == id)
10146 {
10147 return true;
10148 }
10149 }
10150 return false;
10151}
std::vector< GameobjectInstanceSavedState > GameobjectInstanceSavedStateList
Definition: ObjectMgr.h:1637

References GameobjectInstanceSavedStateList.

◆ GenerateAuctionID()

uint32 ObjectMgr::GenerateAuctionID ( )
7010{
7011 if (_auctionId >= 0xFFFFFFFE)
7012 {
7013 LOG_ERROR("server.worldserver", "Auctions ids overflow!! Can't continue, shutting down server. ");
7015 }
7016 return _auctionId++;
7017}
@ ERROR_EXIT_CODE
Definition: World.h:55
static void StopNow(uint8 exitcode)
Definition: World.h:261

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

◆ GenerateCreatureSpawnId()

uint32 ObjectMgr::GenerateCreatureSpawnId ( )
7041{
7042 if (_creatureSpawnId >= uint32(0xFFFFFF))
7043 {
7044 LOG_ERROR("server.worldserver", "Creature spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info.");
7046 }
7047 return _creatureSpawnId++;
7048}

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

Referenced by AddCreData().

◆ GenerateEquipmentSetGuid()

uint64 ObjectMgr::GenerateEquipmentSetGuid ( )
7020{
7021 if (_equipmentSetGuid >= uint64(0xFFFFFFFFFFFFFFFELL))
7022 {
7023 LOG_ERROR("server.worldserver", "EquipmentSet guid overflow!! Can't continue, shutting down server. ");
7025 }
7026 return _equipmentSetGuid++;
7027}
std::uint64_t uint64
Definition: Define.h:107

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

◆ GenerateGameObjectSpawnId()

uint32 ObjectMgr::GenerateGameObjectSpawnId ( )
7051{
7052 if (_gameObjectSpawnId >= uint32(0xFFFFFF))
7053 {
7054 LOG_ERROR("server.worldserver", "GameObject spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7056 }
7057 return _gameObjectSpawnId++;
7058}

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

Referenced by AddGOData().

◆ GenerateMailID()

uint32 ObjectMgr::GenerateMailID ( )
7030{
7031 if (_mailId >= 0xFFFFFFFE)
7032 {
7033 LOG_ERROR("server.worldserver", "Mail ids overflow!! Can't continue, shutting down server. ");
7035 }
7036 std::lock_guard<std::mutex> guard(_mailIdMutex);
7037 return _mailId++;
7038}
std::mutex _mailIdMutex
Definition: ObjectMgr.h:1458

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

◆ GeneratePetName()

std::string ObjectMgr::GeneratePetName ( uint32  entry)
7517{
7518 std::vector<std::string>& list0 = _petHalfName0[entry];
7519 std::vector<std::string>& list1 = _petHalfName1[entry];
7520
7521 if (list0.empty() || list1.empty())
7522 {
7523 CreatureTemplate const* cinfo = GetCreatureTemplate(entry);
7524 char const* petname = GetPetName(cinfo->family, sWorld->GetDefaultDbcLocale());
7525 if (!petname)
7526 return cinfo->Name;
7527
7528 return std::string(petname);
7529 }
7530
7531 return *(list0.begin() + urand(0, list0.size() - 1)) + *(list1.begin() + urand(0, list1.size() - 1));
7532}
char const * GetPetName(uint32 petfamily, uint32 dbclang)
Definition: DBCStores.cpp:658
std::string Name
Definition: CreatureData.h:184
HalfNameContainer _petHalfName1
Definition: ObjectMgr.h:1564
HalfNameContainer _petHalfName0
Definition: ObjectMgr.h:1563

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

Referenced by GeneratePetNameLocale().

◆ GeneratePetNameLocale()

std::string ObjectMgr::GeneratePetNameLocale ( uint32  entry,
LocaleConstant  locale 
)
7504{
7505 std::vector<std::string>& list0 = _petHalfLocaleName0[std::make_pair(entry, locale)];
7506 std::vector<std::string>& list1 = _petHalfLocaleName1[std::make_pair(entry, locale)];
7507
7508 if (list0.empty() || list1.empty())
7509 {
7510 return GeneratePetName(entry);
7511 }
7512
7513 return *(list0.begin() + urand(0, list0.size() - 1)) + *(list1.begin() + urand(0, list1.size() - 1));
7514}
HalfNameContainerLocale _petHalfLocaleName0
Definition: ObjectMgr.h:1566
HalfNameContainerLocale _petHalfLocaleName1
Definition: ObjectMgr.h:1567
std::string GeneratePetName(uint32 entry)
Definition: ObjectMgr.cpp:7516

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

◆ GeneratePetNumber()

uint32 ObjectMgr::GeneratePetNumber ( )
7535{
7536 std::lock_guard<std::mutex> guard(_hiPetNumberMutex);
7537 return ++_hiPetNumber;
7538}
std::mutex _hiPetNumberMutex
Definition: ObjectMgr.h:1460

References _hiPetNumber, and _hiPetNumberMutex.

◆ GetAccessRequirement()

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

References _accessRequirementStore.

◆ GetAcoreString() [1/2]

AcoreString const * ObjectMgr::GetAcoreString ( uint32  entry) const
inline
1315 {
1316 AcoreStringContainer::const_iterator itr = _acoreStringStore.find(entry);
1317 if (itr == _acoreStringStore.end())
1318 return nullptr;
1319
1320 return &itr->second;
1321 }
AcoreStringContainer _acoreStringStore
Definition: ObjectMgr.h:1606

References _acoreStringStore.

Referenced by GetAcoreString(), and GetAcoreStringForDBCLocale().

◆ GetAcoreString() [2/2]

char const * ObjectMgr::GetAcoreString ( uint32  entry,
LocaleConstant  locale 
) const
8610{
8611 if (AcoreString const* ts = GetAcoreString(entry))
8612 {
8613 if (ts->Content.size() > size_t(locale) && !ts->Content[locale].empty())
8614 return ts->Content[locale].c_str();
8615
8616 return ts->Content[DEFAULT_LOCALE].c_str();
8617 }
8618
8619 LOG_ERROR("sql.sql", "Acore string entry {} not found in DB.", entry);
8620
8621 return "<error>";
8622}
#define DEFAULT_LOCALE
Definition: Common.h:88
Definition: ObjectMgr.h:497
AcoreString const * GetAcoreString(uint32 entry) const
Definition: ObjectMgr.h:1314

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

◆ GetAcoreStringForDBCLocale()

char const * ObjectMgr::GetAcoreStringForDBCLocale ( uint32  entry) const
inline
1323{ return GetAcoreString(entry, DBCLocaleIndex); }

References DBCLocaleIndex, and GetAcoreString().

◆ GetAllCreatureData()

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

References _creatureDataStore.

◆ GetAllGOData()

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

References _gameObjectDataStore.

◆ GetAllServerMailStore()

ServerMailContainer const & ObjectMgr::GetAllServerMailStore ( ) const
inline
1190{ return _serverMailStore; }
ServerMailContainer _serverMailStore
Definition: ObjectMgr.h:1614

References _serverMailStore.

◆ GetAreaTrigger()

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

References _areaTriggerStore.

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

◆ GetAreaTriggerScriptId()

uint32 ObjectMgr::GetAreaTriggerScriptId ( uint32  trigger_id)
8702{
8703 AreaTriggerScriptContainer::const_iterator i = _areaTriggerScriptStore.find(trigger_id);
8704 if (i != _areaTriggerScriptStore.end())
8705 return i->second;
8706 return 0;
8707}
AreaTriggerScriptContainer _areaTriggerScriptStore
Definition: ObjectMgr.h:1491

References _areaTriggerScriptStore.

◆ GetAreaTriggerTeleport()

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

References _areaTriggerTeleportStore.

◆ GetBaseReputationOf()

int32 ObjectMgr::GetBaseReputationOf ( FactionEntry const *  factionEntry,
uint8  race,
uint8  playerClass 
)
8716{
8717 if (!factionEntry)
8718 return 0;
8719
8720 uint32 raceMask = (1 << (race - 1));
8721 uint32 classMask = (1 << (playerClass - 1));
8722
8723 for (int i = 0; i < 4; i++)
8724 {
8725 if ((!factionEntry->BaseRepClassMask[i] ||
8726 factionEntry->BaseRepClassMask[i] & classMask) &&
8727 (!factionEntry->BaseRepRaceMask[i] ||
8728 factionEntry->BaseRepRaceMask[i] & raceMask))
8729 return factionEntry->BaseRepValue[i];
8730 }
8731
8732 return 0;
8733}

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

◆ GetBaseXP()

uint32 ObjectMgr::GetBaseXP ( uint8  level)
7445{
7446 return _baseXPTable[level] ? _baseXPTable[level] : 0;
7447}
BaseXPContainer _baseXPTable
Definition: ObjectMgr.h:1557

References _baseXPTable.

◆ GetBroadcastText()

BroadcastText const * ObjectMgr::GetBroadcastText ( uint32  id) const
inline
1193 {
1194 BroadcastTextContainer::const_iterator itr = _broadcastTextStore.find(id);
1195 if (itr != _broadcastTextStore.end())
1196 return &itr->second;
1197 return nullptr;
1198 }
BroadcastTextContainer _broadcastTextStore
Definition: ObjectMgr.h:1596

References _broadcastTextStore.

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

◆ GetCellObjectGuids()

CellObjectGuids const & ObjectMgr::GetCellObjectGuids ( uint16  mapid,
uint8  spawnMode,
uint32  cell_id 
)
inline
1153 {
1154 MapObjectGuids::const_iterator itr1 = _mapObjectGuidsStore.find(MAKE_PAIR32(mapid, spawnMode));
1155 if (itr1 != _mapObjectGuidsStore.end())
1156 {
1157 CellObjectGuidsMap::const_iterator itr2 = itr1->second.find(cell_id);
1158 if (itr2 != itr1->second.end())
1159 return itr2->second;
1160 }
1161 return _emptyCellObjectGuids;
1162 }
CellObjectGuids _emptyCellObjectGuids
Definition: ObjectMgr.h:1574

References _emptyCellObjectGuids, _mapObjectGuidsStore, and MAKE_PAIR32().

◆ GetCreatureAddon()

CreatureAddon const * ObjectMgr::GetCreatureAddon ( ObjectGuid::LowType  lowguid)
1505{
1506 CreatureAddonContainer::const_iterator itr = _creatureAddonStore.find(lowguid);
1507 if (itr != _creatureAddonStore.end())
1508 return &(itr->second);
1509
1510 return nullptr;
1511}
CreatureAddonContainer _creatureAddonStore
Definition: ObjectMgr.h:1580

References _creatureAddonStore.

◆ GetCreatureBaseStats()

CreatureBaseStats const * ObjectMgr::GetCreatureBaseStats ( uint8  level,
uint8  unitClass 
)
9613{
9614 CreatureBaseStatsContainer::const_iterator it = _creatureBaseStatsStore.find(MAKE_PAIR16(level, unitClass));
9615
9616 if (it != _creatureBaseStatsStore.end())
9617 return &(it->second);
9618
9619 struct DefaultCreatureBaseStats : public CreatureBaseStats
9620 {
9621 DefaultCreatureBaseStats()
9622 {
9623 BaseArmor = 1;
9624 for (uint8 j = 0; j < MAX_EXPANSIONS; ++j)
9625 {
9626 BaseHealth[j] = 1;
9627 BaseDamage[j] = 0.0f;
9628 }
9629 BaseMana = 0;
9630 AttackPower = 0;
9631 RangedAttackPower = 0;
9632 }
9633 };
9634 static const DefaultCreatureBaseStats defStats;
9635 return &defStats;
9636}
uint16 MAKE_PAIR16(uint8 l, uint8 h)
Definition: ObjectDefines.h:82
CreatureBaseStatsContainer _creatureBaseStatsStore
Definition: ObjectMgr.h:1541

References _creatureBaseStatsStore, MAKE_PAIR16(), and MAX_EXPANSIONS.

Referenced by AddCreData().

◆ GetCreatureData()

CreatureData const * ObjectMgr::GetCreatureData ( ObjectGuid::LowType  spawnId) const
inline
1201 {
1202 CreatureDataContainer::const_iterator itr = _creatureDataStore.find(spawnId);
1203 if (itr == _creatureDataStore.end()) return nullptr;
1204 return &itr->second;
1205 }

References _creatureDataStore.

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

◆ GetCreatureLocale()

CreatureLocale const * ObjectMgr::GetCreatureLocale ( uint32  entry) const
inline
1224 {
1225 CreatureLocaleContainer::const_iterator itr = _creatureLocaleStore.find(entry);
1226 if (itr == _creatureLocaleStore.end()) return nullptr;
1227 return &itr->second;
1228 }
CreatureLocaleContainer _creatureLocaleStore
Definition: ObjectMgr.h:1588

References _creatureLocaleStore.

◆ GetCreatureModelInfo()

CreatureModelInfo const * ObjectMgr::GetCreatureModelInfo ( uint32  modelId) const
1709{
1710 CreatureModelContainer::const_iterator itr = _creatureModelStore.find(modelId);
1711 if (itr != _creatureModelStore.end())
1712 return &(itr->second);
1713
1714 return nullptr;
1715}
CreatureModelContainer _creatureModelStore
Definition: ObjectMgr.h:1579

References _creatureModelStore.

Referenced by CheckCreatureTemplate(), and GetCreatureModelRandomGender().

◆ GetCreatureModelRandomGender()

CreatureModelInfo const * ObjectMgr::GetCreatureModelRandomGender ( uint32 displayID)
1746{
1747 CreatureModelInfo const* modelInfo = GetCreatureModelInfo(*displayID);
1748 if (!modelInfo)
1749 return nullptr;
1750
1751 // If a model for another gender exists, 50% chance to use it
1752 if (modelInfo->modelid_other_gender != 0 && urand(0, 1) == 0)
1753 {
1754 CreatureModelInfo const* minfo_tmp = GetCreatureModelInfo(modelInfo->modelid_other_gender);
1755 if (!minfo_tmp)
1756 LOG_ERROR("sql.sql", "Model (Entry: {}) has modelid_other_gender {} not found in table `creature_model_info`. ", *displayID, modelInfo->modelid_other_gender);
1757 else
1758 {
1759 // Model ID changed
1760 *displayID = modelInfo->modelid_other_gender;
1761 return minfo_tmp;
1762 }
1763 }
1764
1765 return modelInfo;
1766}
uint32 modelid_other_gender
Definition: CreatureData.h:392

References GetCreatureModelInfo(), LOG_ERROR, CreatureModelInfo::modelid_other_gender, and urand().

Referenced by GetTaxiMountDisplayId().

◆ GetCreatureMovementOverride()

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

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

◆ GetCreatureQuestInvolvedRelationBounds()

QuestRelationBounds ObjectMgr::GetCreatureQuestInvolvedRelationBounds ( uint32  creature_entry)
inline
1005 {
1006 return _creatureQuestInvolvedRelations.equal_range(creature_entry);
1007 }
QuestRelations _creatureQuestInvolvedRelations
Definition: ObjectMgr.h:1508

References _creatureQuestInvolvedRelations.

◆ GetCreatureQuestInvolvedRelationMap()

QuestRelations * ObjectMgr::GetCreatureQuestInvolvedRelationMap ( )
inline

◆ GetCreatureQuestItemList()

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

References _creatureQuestItemStore.

◆ GetCreatureQuestItemMap()

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

References _creatureQuestItemStore.

◆ GetCreatureQuestRelationBounds()

QuestRelationBounds ObjectMgr::GetCreatureQuestRelationBounds ( uint32  creature_entry)
inline
1000 {
1001 return _creatureQuestRelations.equal_range(creature_entry);
1002 }
QuestRelations _creatureQuestRelations
Definition: ObjectMgr.h:1507

References _creatureQuestRelations.

◆ GetCreatureQuestRelationMap()

QuestRelations * ObjectMgr::GetCreatureQuestRelationMap ( )
inline
990 {
992 }

References _creatureQuestRelations.

◆ GetCreatureTemplate()

◆ GetCreatureTemplateAddon()

CreatureAddon const * ObjectMgr::GetCreatureTemplateAddon ( uint32  entry)
1514{
1515 CreatureAddonContainer::const_iterator itr = _creatureTemplateAddonStore.find(entry);
1516 if (itr != _creatureTemplateAddonStore.end())
1517 return &(itr->second);
1518
1519 return nullptr;
1520}
CreatureAddonContainer _creatureTemplateAddonStore
Definition: ObjectMgr.h:1581

References _creatureTemplateAddonStore.

◆ GetCreatureTemplates()

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

References _creatureTemplateStore.

◆ GetDBCLocaleIndex()

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

References DBCLocaleIndex.

◆ GetDungeonEncounterList()

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

References _dungeonEncounterStore, and MAKE_PAIR32().

◆ GetEquipmentInfo()

EquipmentInfo const * ObjectMgr::GetEquipmentInfo ( uint32  entry,
int8 id 
)
1528{
1529 EquipmentInfoContainer::const_iterator itr = _equipmentInfoStore.find(entry);
1530 if (itr == _equipmentInfoStore.end())
1531 return nullptr;
1532
1533 if (itr->second.empty())
1534 return nullptr;
1535
1536 if (id == -1) // select a random element
1537 {
1538 EquipmentInfoContainerInternal::const_iterator ritr = itr->second.begin();
1539 std::advance(ritr, urand(0u, itr->second.size() - 1));
1540 id = std::distance(itr->second.begin(), ritr) + 1;
1541 return &ritr->second;
1542 }
1543 else
1544 {
1545 EquipmentInfoContainerInternal::const_iterator itr2 = itr->second.find(id);
1546 if (itr2 != itr->second.end())
1547 return &itr2->second;
1548 }
1549
1550 return nullptr;
1551}
EquipmentInfoContainer _equipmentInfoStore
Definition: ObjectMgr.h:1586

References _equipmentInfoStore, and urand().

Referenced by LoadCreatures().

◆ GetFishingBaseSkillLevel()

int32 ObjectMgr::GetFishingBaseSkillLevel ( uint32  entry) const
inline
1109 {
1110 FishingBaseSkillContainer::const_iterator itr = _fishingBaseForAreaStore.find(entry);
1111 return itr != _fishingBaseForAreaStore.end() ? itr->second : 0;
1112 }

References _fishingBaseForAreaStore.

◆ GetGameObjectAddon()

GameObjectAddon const * ObjectMgr::GetGameObjectAddon ( ObjectGuid::LowType  lowguid)
1496{
1497 GameObjectAddonContainer::const_iterator itr = _gameObjectAddonStore.find(lowguid);
1498 if (itr != _gameObjectAddonStore.end())
1499 return &(itr->second);
1500
1501 return nullptr;
1502}
GameObjectAddonContainer _gameObjectAddonStore
Definition: ObjectMgr.h:1583

References _gameObjectAddonStore.

◆ GetGameObjectData()

GameObjectData const * ObjectMgr::GetGameObjectData ( ObjectGuid::LowType  spawnId) const
inline
1218 {
1219 GameObjectDataContainer::const_iterator itr = _gameObjectDataStore.find(spawnId);
1220 if (itr == _gameObjectDataStore.end()) return nullptr;
1221 return &itr->second;
1222 }

References _gameObjectDataStore.

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

◆ GetGameObjectLocale()

GameObjectLocale const * ObjectMgr::GetGameObjectLocale ( uint32  entry) const
inline
1230 {
1231 GameObjectLocaleContainer::const_iterator itr = _gameObjectLocaleStore.find(entry);
1232 if (itr == _gameObjectLocaleStore.end()) return nullptr;
1233 return &itr->second;
1234 }
GameObjectLocaleContainer _gameObjectLocaleStore
Definition: ObjectMgr.h:1590

References _gameObjectLocaleStore.

◆ GetGameObjectQuestItemList()

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

References _gameObjectQuestItemStore.

◆ GetGameObjectQuestItemMap()

GameObjectQuestItemMap const * ObjectMgr::GetGameObjectQuestItemMap ( ) const
inline

◆ GetGameObjectTemplate()

GameObjectTemplate const * ObjectMgr::GetGameObjectTemplate ( uint32  entry)
9937{
9938 GameObjectTemplateContainer::const_iterator itr = _gameObjectTemplateStore.find(entry);
9939 if (itr != _gameObjectTemplateStore.end())
9940 return &(itr->second);
9941
9942 return nullptr;
9943}
GameObjectTemplateContainer _gameObjectTemplateStore
Definition: ObjectMgr.h:1591

References _gameObjectTemplateStore.

Referenced by AddGOData(), IsGameObjectStaticTransport(), LoadGameobjectQuestEnders(), LoadGameobjectQuestStarters(), LoadGameobjects(), LoadQuests(), LoadScripts(), and LoadTempSummons().

◆ GetGameObjectTemplateAddon()

GameObjectTemplateAddon const * ObjectMgr::GetGameObjectTemplateAddon ( uint32  entry) const
9952{
9953 auto itr = _gameObjectTemplateAddonStore.find(entry);
9954 if (itr != _gameObjectTemplateAddonStore.end())
9955 return &itr->second;
9956
9957 return nullptr;
9958}
GameObjectTemplateAddonContainer _gameObjectTemplateAddonStore
Definition: ObjectMgr.h:1592

References _gameObjectTemplateAddonStore.

◆ GetGameObjectTemplates()

GameObjectTemplateContainer const * ObjectMgr::GetGameObjectTemplates ( ) const
inline

◆ GetGameTele() [1/2]

GameTele const * ObjectMgr::GetGameTele ( std::string_view  name) const
8821{
8822 // explicit name case
8823 std::wstring wname;
8824 if (!Utf8toWStr(name, wname))
8825 return nullptr;
8826
8827 // converting string that we try to find to lower case
8828 wstrToLower(wname);
8829
8830 // Alternative first GameTele what contains wnameLow as substring in case no GameTele location found
8831 const GameTele* alt = nullptr;
8832 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
8833 {
8834 if (itr->second.wnameLow == wname)
8835 return &itr->second;
8836 else if (!alt && itr->second.wnameLow.find(wname) != std::wstring::npos)
8837 alt = &itr->second;
8838 }
8839
8840 return alt;
8841}
Definition: ObjectMgr.h:135

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

◆ GetGameTele() [2/2]

GameTele const * ObjectMgr::GetGameTele ( uint32  id) const
inline
1354 {
1355 GameTeleContainer::const_iterator itr = _gameTeleStore.find(id);
1356 if (itr == _gameTeleStore.end()) return nullptr;
1357 return &itr->second;
1358 }

References _gameTeleStore.

◆ GetGameTeleMap()

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

References _gameTeleStore.

◆ GetGenerator()

template<HighGuid type>
ObjectGuidGeneratorBase & ObjectMgr::GetGenerator ( )
inline
1122 {
1123 static_assert(ObjectGuidTraits<type>::Global, "Only global guid can be generated in ObjectMgr context");
1124 return GetGuidSequenceGenerator<type>();
1125 }
Definition: ObjectGuid.h:78

◆ GetGoBackTrigger()

AreaTriggerTeleport const * ObjectMgr::GetGoBackTrigger ( uint32  Map) const
6909{
6910 bool useParentDbValue = false;
6911 uint32 parentId = 0;
6912 MapEntry const* mapEntry = sMapStore.LookupEntry(Map);
6913 if (!mapEntry || mapEntry->entrance_map < 0)
6914 return nullptr;
6915
6916 if (mapEntry->IsDungeon())
6917 {
6918 InstanceTemplate const* iTemplate = sObjectMgr->GetInstanceTemplate(Map);
6919
6920 if (!iTemplate)
6921 return nullptr;
6922
6923 parentId = iTemplate->Parent;
6924 useParentDbValue = true;
6925 }
6926
6927 uint32 entrance_map = uint32(mapEntry->entrance_map);
6928 for (AreaTriggerTeleportContainer::const_iterator itr = _areaTriggerTeleportStore.begin(); itr != _areaTriggerTeleportStore.end(); ++itr)
6929 if ((!useParentDbValue && itr->second.target_mapId == entrance_map) || (useParentDbValue && itr->second.target_mapId == parentId))
6930 {
6931 AreaTrigger const* atEntry = GetAreaTrigger(itr->first);
6932 if (atEntry && atEntry->map == Map)
6933 return &itr->second;
6934 }
6935 return nullptr;
6936}
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
Definition: ObjectMgr.h:421
uint32 map
Definition: ObjectMgr.h:423
AreaTrigger const * GetAreaTrigger(uint32 trigger) const
Definition: ObjectMgr.h:860
Definition: Map.h:273
uint32 Parent
Definition: Map.h:274
Definition: DBCStructure.h:1308
int32 entrance_map
Definition: DBCStructure.h:1323
bool IsDungeon() const
Definition: DBCStructure.h:1334

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

◆ GetGOQuestInvolvedRelationBounds()

QuestRelationBounds ObjectMgr::GetGOQuestInvolvedRelationBounds ( uint32  go_entry)
inline
985 {
986 return _goQuestInvolvedRelations.equal_range(go_entry);
987 }
QuestRelations _goQuestInvolvedRelations
Definition: ObjectMgr.h:1506

References _goQuestInvolvedRelations.

◆ GetGOQuestInvolvedRelationMap()

QuestRelations * ObjectMgr::GetGOQuestInvolvedRelationMap ( )
inline
975 {
977 }

References _goQuestInvolvedRelations.

◆ GetGOQuestRelationBounds()

QuestRelationBounds ObjectMgr::GetGOQuestRelationBounds ( uint32  go_entry)
inline
980 {
981 return _goQuestRelations.equal_range(go_entry);
982 }
QuestRelations _goQuestRelations
Definition: ObjectMgr.h:1505

References _goQuestRelations.

◆ GetGOQuestRelationMap()

QuestRelations * ObjectMgr::GetGOQuestRelationMap ( )
inline
970 {
971 return &_goQuestRelations;
972 }

References _goQuestRelations.

◆ GetGossipMenuItemsLocale()

GossipMenuItemsLocale const * ObjectMgr::GetGossipMenuItemsLocale ( uint32  entry) const
inline
1260 {
1261 GossipMenuItemsLocaleContainer::const_iterator itr = _gossipMenuItemsLocaleStore.find(entry);
1262 if (itr == _gossipMenuItemsLocaleStore.end()) return nullptr;
1263 return &itr->second;
1264 }
GossipMenuItemsLocaleContainer _gossipMenuItemsLocaleStore
Definition: ObjectMgr.h:1607

References _gossipMenuItemsLocaleStore.

◆ GetGossipMenuItemsMapBounds()

GossipMenuItemsMapBounds ObjectMgr::GetGossipMenuItemsMapBounds ( uint32  uiMenuId) const
inline
1407 {
1408 return _gossipMenuItemsStore.equal_range(uiMenuId);
1409 }
GossipMenuItemsContainer _gossipMenuItemsStore
Definition: ObjectMgr.h:1500

References _gossipMenuItemsStore.

◆ GetGossipMenuItemsMapBoundsNonConst()

GossipMenuItemsMapBoundsNonConst ObjectMgr::GetGossipMenuItemsMapBoundsNonConst ( uint32  uiMenuId)
inline
1411 {
1412 return _gossipMenuItemsStore.equal_range(uiMenuId);
1413 }

References _gossipMenuItemsStore.

◆ GetGossipMenusMapBounds()

GossipMenusMapBounds ObjectMgr::GetGossipMenusMapBounds ( uint32  uiMenuId) const
inline
1397 {
1398 return _gossipMenusStore.equal_range(uiMenuId);
1399 }
GossipMenusContainer _gossipMenusStore
Definition: ObjectMgr.h:1499

References _gossipMenusStore.

◆ GetGossipMenusMapBoundsNonConst()

GossipMenusMapBoundsNonConst ObjectMgr::GetGossipMenusMapBoundsNonConst ( uint32  uiMenuId)
inline
1402 {
1403 return _gossipMenusStore.equal_range(uiMenuId);
1404 }

References _gossipMenusStore.

◆ GetGossipText()

GossipText const * ObjectMgr::GetGossipText ( uint32  Text_ID) const
5963{
5964 GossipTextContainer::const_iterator itr = _gossipTextStore.find(Text_ID);
5965 if (itr != _gossipTextStore.end())
5966 return &itr->second;
5967 return nullptr;
5968}
GossipTextContainer _gossipTextStore
Definition: ObjectMgr.h:1487

References _gossipTextStore.

Referenced by LoadGossipMenu().

◆ GetGuidSequenceGenerator()

template<HighGuid high>
ObjectGuidGeneratorBase & ObjectMgr::GetGuidSequenceGenerator ( )
inlineprivate
1468 {
1469 auto itr = _guidGenerators.find(high);
1470 if (itr == _guidGenerators.end())
1471 itr = _guidGenerators.insert(std::make_pair(high, std::unique_ptr<ObjectGuidGenerator<high>>(new ObjectGuidGenerator<high>()))).first;
1472
1473 return *itr->second;
1474 }
Definition: ObjectGuid.h:299
std::map< HighGuid, std::unique_ptr< ObjectGuidGeneratorBase > > _guidGenerators
Definition: ObjectMgr.h:1476

References _guidGenerators.

◆ GetInstanceSavedGameobjectState()

uint8 ObjectMgr::GetInstanceSavedGameobjectState ( uint32  id,
uint32  guid 
)
10130{
10131 for (auto it = GameobjectInstanceSavedStateList.begin(); it != GameobjectInstanceSavedStateList.end(); it++)
10132 {
10133 if (it->m_guid == guid && it->m_instance == id)
10134 {
10135 return it->m_state;
10136 }
10137 }
10138 return 3; // Any state higher than 2 to get the default state
10139}

References GameobjectInstanceSavedStateList.

◆ GetInstanceTemplate()

InstanceTemplate const * ObjectMgr::GetInstanceTemplate ( uint32  mapId)
5869{
5870 InstanceTemplateContainer::const_iterator itr = _instanceTemplateStore.find(uint16(mapID));
5871 if (itr != _instanceTemplateStore.end())
5872 return &(itr->second);
5873
5874 return nullptr;
5875}
InstanceTemplateContainer _instanceTemplateStore
Definition: ObjectMgr.h:1532

References _instanceTemplateStore.

◆ GetItemLocale()

ItemLocale const * ObjectMgr::GetItemLocale ( uint32  entry) const
inline
1236 {
1237 ItemLocaleContainer::const_iterator itr = _itemLocaleStore.find(entry);
1238 if (itr == _itemLocaleStore.end()) return nullptr;
1239 return &itr->second;
1240 }
ItemLocaleContainer _itemLocaleStore
Definition: ObjectMgr.h:1599

References _itemLocaleStore.

◆ GetItemSetNameEntry()

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

References _itemSetNameStore.

◆ GetItemSetNameLocale()

ItemSetNameLocale const * ObjectMgr::GetItemSetNameLocale ( uint32  entry) const
inline
1242 {
1243 ItemSetNameLocaleContainer::const_iterator itr = _itemSetNameLocaleStore.find(entry);
1244 if (itr == _itemSetNameLocaleStore.end())return nullptr;
1245 return &itr->second;
1246 }
ItemSetNameLocaleContainer _itemSetNameLocaleStore
Definition: ObjectMgr.h:1600

References _itemSetNameLocaleStore.

◆ GetItemTemplate()

ItemTemplate const * ObjectMgr::GetItemTemplate ( uint32  entry)
3288{
3289 return entry < _itemTemplateStoreFast.size() ? _itemTemplateStoreFast[entry] : nullptr;
3290}
std::vector< ItemTemplate * > _itemTemplateStoreFast
Definition: ObjectMgr.h:1598

References _itemTemplateStoreFast.

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

◆ GetItemTemplateStore()

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

References _itemTemplateStore.

◆ GetItemTemplateStoreFast()

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

References _itemTemplateStoreFast.

◆ GetLinkedRespawnGuid()

ObjectGuid ObjectMgr::GetLinkedRespawnGuid ( ObjectGuid  guid) const
inline
1209 {
1210 LinkedRespawnContainer::const_iterator itr = _linkedRespawnStore.find(guid);
1211 if (itr == _linkedRespawnStore.end())
1212 return ObjectGuid::Empty;
1213 return itr->second;
1214 }
static ObjectGuid const Empty
Definition: ObjectGuid.h:122
LinkedRespawnContainer _linkedRespawnStore
Definition: ObjectMgr.h:1587

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
1424 {
1425 if (data.size() > size_t(loc_idx) && !data[loc_idx].empty())
1426 value = data[loc_idx];
1427 }

◆ GetLocaleString() [2/2]

◆ GetMailLevelReward()

MailLevelReward const * ObjectMgr::GetMailLevelReward ( uint32  level,
uint32  raceMask 
)
inline
1140 {
1141 MailLevelRewardContainer::const_iterator map_itr = _mailLevelRewardStore.find(level);
1142 if (map_itr == _mailLevelRewardStore.end())
1143 return nullptr;
1144
1145 for (const auto & set_itr : map_itr->second)
1146 if (set_itr.raceMask & raceMask)
1147 return &set_itr;
1148
1149 return nullptr;
1150 }
MailLevelRewardContainer _mailLevelRewardStore
Definition: ObjectMgr.h:1539

References _mailLevelRewardStore.

◆ GetMapEntranceTrigger()

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

Searches for the areatrigger which teleports players to the given map

6942{
6943 for (AreaTriggerTeleportContainer::const_iterator itr = _areaTriggerTeleportStore.begin(); itr != _areaTriggerTeleportStore.end(); ++itr)
6944 {
6945 if (itr->second.target_mapId == Map) // Id is used to determine correct Scarlet Monastery instance
6946 {
6947 // xinef: no need to check, already done at loading
6948 //AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(itr->first);
6949 //if (atEntry)
6950 return &itr->second;
6951 }
6952 }
6953 return nullptr;
6954}

References _areaTriggerTeleportStore.

◆ GetMapObjectGuids()

CellObjectGuidsMap const & ObjectMgr::GetMapObjectGuids ( uint16  mapid,
uint8  spawnMode 
)
inline
1165 {
1166 MapObjectGuids::const_iterator itr1 = _mapObjectGuidsStore.find(MAKE_PAIR32(mapid, spawnMode));
1167 if (itr1 != _mapObjectGuidsStore.end())
1168 return itr1->second;
1170 }
CellObjectGuidsMap _emptyCellObjectGuidsMap
Definition: ObjectMgr.h:1573

References _emptyCellObjectGuidsMap, _mapObjectGuidsStore, and MAKE_PAIR32().

◆ GetNearestTaxiNode()

uint32 ObjectMgr::GetNearestTaxiNode ( float  x,
float  y,
float  z,
uint32  mapid,
uint32  teamId 
)
6528{
6529 bool found = false;
6530 float dist = 10000;
6531 uint32 id = 0;
6532
6533 for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
6534 {
6535 TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i);
6536
6537 if (!node || node->map_id != mapid || (!node->MountCreatureID[teamId == TEAM_ALLIANCE ? 1 : 0] && node->MountCreatureID[0] != 32981)) // dk flight
6538 continue;
6539
6540 uint8 field = (uint8)((i - 1) / 32);
6541 uint32 submask = 1 << ((i - 1) % 32);
6542
6543 // skip not taxi network nodes
6544 if (field >= TaxiMaskSize || (sTaxiNodesMask[field] & submask) == 0)
6545 {
6546 continue;
6547 }
6548
6549 float dist2 = (node->x - x) * (node->x - x) + (node->y - y) * (node->y - y) + (node->z - z) * (node->z - z);
6550 if (found)
6551 {
6552 if (dist2 < dist)
6553 {
6554 dist = dist2;
6555 id = i;
6556 }
6557 }
6558 else
6559 {
6560 found = true;
6561 dist = dist2;
6562 id = i;
6563 }
6564 }
6565
6566 return id;
6567}
TaxiMask sTaxiNodesMask
Definition: DBCStores.cpp:174
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
static constexpr size_t TaxiMaskSize
Definition: DBCStructure.h:2221
@ TEAM_ALLIANCE
Definition: SharedDefines.h:732
Definition: DBCStructure.h:1929
float z
Definition: DBCStructure.h:1934
uint32 map_id
Definition: DBCStructure.h:1931
float x
Definition: DBCStructure.h:1932
float y
Definition: DBCStructure.h:1933
uint32 MountCreatureID[2]
Definition: DBCStructure.h:1937

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
1304 {
1305 NpcTextLocaleContainer::const_iterator itr = _npcTextLocaleStore.find(entry);
1306 if (itr == _npcTextLocaleStore.end()) return nullptr;
1307 return &itr->second;
1308 }
NpcTextLocaleContainer _npcTextLocaleStore
Definition: ObjectMgr.h:1604

References _npcTextLocaleStore.

◆ GetNpcTrainerSpells()

TrainerSpellData const * ObjectMgr::GetNpcTrainerSpells ( uint32  entry) const
inline
1365 {
1366 CacheTrainerSpellContainer::const_iterator iter = _cacheTrainerSpellStore.find(entry);
1367 if (iter == _cacheTrainerSpellStore.end())
1368 return nullptr;
1369
1370 return &iter->second;
1371 }

References _cacheTrainerSpellStore.

◆ GetNpcVendorItemList()

VendorItemData const * ObjectMgr::GetNpcVendorItemList ( uint32  entry) const
inline
1374 {
1375 CacheVendorItemContainer::const_iterator iter = _cacheVendorItemStore.find(entry);
1376 if (iter == _cacheVendorItemStore.end())
1377 return nullptr;
1378
1379 return &iter->second;
1380 }

References _cacheVendorItemStore.

Referenced by IsVendorItemValid().

◆ GetPageText()

PageText const * ObjectMgr::GetPageText ( uint32  pageEntry)
5789{
5790 PageTextContainer::const_iterator itr = _pageTextStore.find(pageEntry);
5791 if (itr != _pageTextStore.end())
5792 return &(itr->second);
5793
5794 return nullptr;
5795}
PageTextContainer _pageTextStore
Definition: ObjectMgr.h:1531

References _pageTextStore.

Referenced by LoadGameObjectTemplate(), and LoadItemTemplates().

◆ GetPageTextLocale()

PageTextLocale const * ObjectMgr::GetPageTextLocale ( uint32  entry) const
inline
1248 {
1249 PageTextLocaleContainer::const_iterator itr = _pageTextLocaleStore.find(entry);
1250 if (itr == _pageTextLocaleStore.end()) return nullptr;
1251 return &itr->second;
1252 }
PageTextLocaleContainer _pageTextLocaleStore
Definition: ObjectMgr.h:1605

References _pageTextLocaleStore.

◆ GetPetLevelInfo()

PetLevelInfo const * ObjectMgr::GetPetLevelInfo ( uint32  creature_id,
uint8  level 
) const
3598{
3599 if (level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
3600 level = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
3601
3602 PetLevelInfoContainer::const_iterator itr = _petInfoStore.find(creature_id);
3603 if (itr == _petInfoStore.end())
3604 return nullptr;
3605
3606 return &itr->second[level - 1]; // data for level 1 stored in [0] array element, ...
3607}

References _petInfoStore, CONFIG_MAX_PLAYER_LEVEL, and sWorld.

◆ GetPlayerClassInfo()

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

References _playerClassInfo, and MAX_CLASSES.

◆ GetPlayerClassLevelInfo()

void ObjectMgr::GetPlayerClassLevelInfo ( uint32  class_,
uint8  level,
PlayerClassLevelInfo info 
) const
4316{
4317 if (level < 1 || class_ >= MAX_CLASSES)
4318 return;
4319
4320 PlayerClassInfo const* pInfo = _playerClassInfo[class_];
4321
4322 if (level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4323 level = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
4324
4325 *info = pInfo->levelInfo[level - 1];
4326}
Definition: Player.h:297

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

◆ GetPlayerInfo()

PlayerInfo const * ObjectMgr::GetPlayerInfo ( uint32  race,
uint32  class_ 
) const
9983{
9984 if (race >= MAX_RACES)
9985 return nullptr;
9986 if (class_ >= MAX_CLASSES)
9987 return nullptr;
9988 PlayerInfo const* info = _playerInfo[race][class_];
9989 if (!info)
9990 return nullptr;
9991 return info;
9992}
Definition: Player.h:336

References _playerInfo, MAX_CLASSES, and MAX_RACES.

◆ GetPlayerLevelInfo()

void ObjectMgr::GetPlayerLevelInfo ( uint32  race,
uint32  class_,
uint8  level,
PlayerLevelInfo info 
) const
4329{
4330 if (level < 1 || race >= MAX_RACES || class_ >= MAX_CLASSES)
4331 return;
4332
4333 PlayerInfo const* pInfo = _playerInfo[race][class_];
4334 if (!pInfo)
4335 return;
4336
4337 if (level <= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4338 *info = pInfo->levelInfo[level - 1];
4339 else
4340 BuildPlayerLevelInfo(race, class_, level, info);
4341}
void BuildPlayerLevelInfo(uint8 race, uint8 class_, uint8 level, PlayerLevelInfo *plinfo) const
Definition: ObjectMgr.cpp:4343

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

◆ GetPointOfInterest()

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

References _pointsOfInterestStore.

Referenced by LoadGossipMenuItems().

◆ GetPointOfInterestLocale()

PointOfInterestLocale const * ObjectMgr::GetPointOfInterestLocale ( uint32  poi_id) const
inline
1266 {
1267 PointOfInterestLocaleContainer::const_iterator itr = _pointOfInterestLocaleStore.find(poi_id);
1268 if (itr == _pointOfInterestLocaleStore.end()) return nullptr;
1269 return &itr->second;
1270 }
PointOfInterestLocaleContainer _pointOfInterestLocaleStore
Definition: ObjectMgr.h:1608

References _pointOfInterestLocaleStore.

◆ GetQuestForAreaTrigger()

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

References _questAreaTriggerStore.

◆ GetQuestGreeting()

QuestGreeting const * ObjectMgr::GetQuestGreeting ( TypeID  type,
uint32  id 
) const
6263{
6264 uint32 typeIndex;
6265 if (type == TYPEID_UNIT)
6266 typeIndex = 0;
6267 else if (type == TYPEID_GAMEOBJECT)
6268 typeIndex = 1;
6269 else
6270 return nullptr;
6271
6273}
@ TYPEID_GAMEOBJECT
Definition: ObjectGuid.h:39
@ TYPEID_UNIT
Definition: ObjectGuid.h:37
QuestGreetingContainer _questGreetingStore
Definition: ObjectMgr.h:1488

References _questGreetingStore, Acore::Containers::MapGetValuePtr(), TYPEID_GAMEOBJECT, and TYPEID_UNIT.

◆ GetQuestGreetingLocale()

QuestGreetingLocale const * ObjectMgr::GetQuestGreetingLocale ( TypeID  type,
uint32  id 
) const
inline
1272 {
1273 uint32 typeIndex;
1274 if (type == TYPEID_UNIT)
1275 {
1276 typeIndex = 0;
1277 }
1278 else if (type == TYPEID_GAMEOBJECT)
1279 {
1280 typeIndex = 1;
1281 }
1282 else
1283 {
1284 return nullptr;
1285 }
1286
1287 QuestGreetingLocaleContainer::const_iterator itr = _questGreetingLocaleStore.find(MAKE_PAIR32(typeIndex, id));
1288 if (itr == _questGreetingLocaleStore.end()) return nullptr;
1289 return &itr->second;
1290 }
QuestGreetingLocaleContainer _questGreetingLocaleStore
Definition: ObjectMgr.h:1609

References _questGreetingLocaleStore, MAKE_PAIR32(), TYPEID_GAMEOBJECT, and TYPEID_UNIT.

◆ GetQuestLocale()

QuestLocale const * ObjectMgr::GetQuestLocale ( uint32  entry) const
inline
1254 {
1255 QuestLocaleContainer::const_iterator itr = _questLocaleStore.find(entry);
1256 if (itr == _questLocaleStore.end()) return nullptr;
1257 return &itr->second;
1258 }
QuestLocaleContainer _questLocaleStore
Definition: ObjectMgr.h:1601

References _questLocaleStore.

◆ GetQuestMoneyReward()

uint32 ObjectMgr::GetQuestMoneyReward ( uint8  level,
uint32  questMoneyDifficulty 
) const
10089{
10090 if (questMoneyDifficulty < MAX_QUEST_MONEY_REWARDS)
10091 {
10092 auto const& itr = _questMoneyRewards.find(level);
10093 if (itr != _questMoneyRewards.end())
10094 {
10095 return itr->second.at(questMoneyDifficulty);
10096 }
10097 }
10098
10099 return 0;
10100}
static constexpr uint32 MAX_QUEST_MONEY_REWARDS
Definition: ObjectMgr.h:722
QuestMoneyRewardStore _questMoneyRewards
Definition: ObjectMgr.h:1629

References _questMoneyRewards, and MAX_QUEST_MONEY_REWARDS.

◆ GetQuestOfferRewardLocale()

QuestOfferRewardLocale const * ObjectMgr::GetQuestOfferRewardLocale ( uint32  entry) const
inline
1292 {
1293 auto itr = _questOfferRewardLocaleStore.find(entry);
1294 if (itr == _questOfferRewardLocaleStore.end()) return nullptr;
1295 return &itr->second;
1296 }
QuestOfferRewardLocaleContainer _questOfferRewardLocaleStore
Definition: ObjectMgr.h:1602

References _questOfferRewardLocaleStore.

◆ GetQuestPOIVector()

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

References _questPOIStore.

◆ GetQuestRequestItemsLocale()

QuestRequestItemsLocale const * ObjectMgr::GetQuestRequestItemsLocale ( uint32  entry) const
inline
1298 {
1299 auto itr = _questRequestItemsLocaleStore.find(entry);
1300 if (itr == _questRequestItemsLocaleStore.end()) return nullptr;
1301 return &itr->second;
1302 }
QuestRequestItemsLocaleContainer _questRequestItemsLocaleStore
Definition: ObjectMgr.h:1603

References _questRequestItemsLocaleStore.

◆ GetQuestTemplate()

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

References _questTemplatesFast.

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

◆ GetQuestTemplates()

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

References _questTemplates.

◆ GetRepRewardRate()

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

References _repRewardRateStore.

◆ GetRepSpilloverTemplate()

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

References _repSpilloverTemplateStore.

◆ GetReputationOnKilEntry()

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

References _repOnKillStore.

◆ GetScriptId()

uint32 ObjectMgr::GetScriptId ( std::string const &  name)
9473{
9474 // use binary search to find the script name in the sorted vector
9475 // assume "" is the first element
9476 if (name.empty())
9477 return 0;
9478
9479 ScriptNameContainer::const_iterator itr = std::lower_bound(_scriptNamesStore.begin(), _scriptNamesStore.end(), name);
9480 if (itr == _scriptNamesStore.end() || (*itr != name))
9481 return 0;
9482
9483 return uint32(itr - _scriptNamesStore.begin());
9484}
ScriptNameContainer _scriptNamesStore
Definition: ObjectMgr.h:1520

References _scriptNamesStore.

Referenced by LoadAreaTriggerScripts(), LoadCreatures(), LoadCreatureTemplate(), LoadGameobjects(), LoadGameObjectTemplate(), and LoadSpellScriptNames().

◆ GetScriptName()

std::string const & ObjectMgr::GetScriptName ( uint32  id) const
9467{
9468 static std::string const empty = "";
9469 return (id < _scriptNamesStore.size()) ? _scriptNamesStore[id] : empty;
9470}

References _scriptNamesStore.

Referenced by ValidateSpellScripts().

◆ GetScriptNames()

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

References _scriptNamesStore.

◆ GetSpellClickInfoMapBounds()

SpellClickInfoMapBounds ObjectMgr::GetSpellClickInfoMapBounds ( uint32  creature_id) const
inline
1392 {
1393 return _spellClickInfoStore.equal_range(creature_id);
1394 }
SpellClickInfoContainer _spellClickInfoStore
Definition: ObjectMgr.h:1522

References _spellClickInfoStore.

◆ GetSpellScriptsBounds()

SpellScriptsBounds ObjectMgr::GetSpellScriptsBounds ( uint32  spell_id)
8710{
8711 return SpellScriptsBounds(_spellScriptsStore.lower_bound(spell_id), _spellScriptsStore.upper_bound(spell_id));
8712}
std::pair< SpellScriptsContainer::iterator, SpellScriptsContainer::iterator > SpellScriptsBounds
Definition: ObjectMgr.h:389
SpellScriptsContainer _spellScriptsStore
Definition: ObjectMgr.h:1524

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
1182 {
1183 TempSummonDataContainer::const_iterator itr = _tempSummonDataStore.find(TempSummonGroupKey(summonerId, summonerType, group));
1184 if (itr != _tempSummonDataStore.end())
1185 return &itr->second;
1186
1187 return nullptr;
1188 }
Key for storing temp summon data in TempSummonDataContainer.
Definition: ObjectMgr.h:67
TempSummonDataContainer _tempSummonDataStore
Stores temp summon data grouped by summoner's entry, summoner's type and group id.
Definition: ObjectMgr.h:1594

References _tempSummonDataStore.

◆ GetTaxiMountDisplayId()

uint32 ObjectMgr::GetTaxiMountDisplayId ( uint32  id,
TeamId  teamId,
bool  allowed_alt_team = false 
)
6594{
6595 uint32 mount_id = 0;
6596
6597 // select mount creature id
6598 TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id);
6599 if (node)
6600 {
6601 uint32 mount_entry = node->MountCreatureID[teamId == TEAM_ALLIANCE ? 1 : 0];
6602
6603 // Fix for Alliance not being able to use Acherus taxi
6604 // only one mount type for both sides
6605 if (mount_entry == 0 && allowed_alt_team)
6606 {
6607 // Simply reverse the selection. At least one team in theory should have a valid mount ID to choose.
6608 mount_entry = node->MountCreatureID[teamId];
6609 }
6610
6611 CreatureTemplate const* mount_info = GetCreatureTemplate(mount_entry);
6612 if (mount_info)
6613 {
6614 mount_id = mount_info->GetRandomValidModelId();
6615 if (!mount_id)
6616 {
6617 LOG_ERROR("sql.sql", "No displayid found for the taxi mount with the entry {}! Can't load it!", mount_entry);
6618 return 0;
6619 }
6620 }
6621 }
6622
6623 // minfo is not actually used but the mount_id was updated
6625
6626 return mount_id;
6627}
uint32 GetRandomValidModelId() const
Definition: Creature.cpp:120
CreatureModelInfo const * GetCreatureModelRandomGender(uint32 *displayID)
Definition: ObjectMgr.cpp:1745

References GetCreatureModelRandomGender(), GetCreatureTemplate(), CreatureTemplate::GetRandomValidModelId(), LOG_ERROR, TaxiNodesEntry::MountCreatureID, sTaxiNodesStore, and TEAM_ALLIANCE.

◆ GetTaxiPath()

void ObjectMgr::GetTaxiPath ( uint32  source,
uint32  destination,
uint32 path,
uint32 cost 
)
6570{
6571 TaxiPathSetBySource::iterator src_i = sTaxiPathSetBySource.find(source);
6572 if (src_i == sTaxiPathSetBySource.end())
6573 {
6574 path = 0;
6575 cost = 0;
6576 return;
6577 }
6578
6579 TaxiPathSetForSource& pathSet = src_i->second;
6580
6581 TaxiPathSetForSource::iterator dest_i = pathSet.find(destination);
6582 if (dest_i == pathSet.end())
6583 {
6584 path = 0;
6585 cost = 0;
6586 return;
6587 }
6588
6589 cost = dest_i->second->price;
6590 path = dest_i->second->ID;
6591}
TaxiPathSetBySource sTaxiPathSetBySource
Definition: DBCStores.cpp:181
std::map< uint32, TaxiPathEntry const * > TaxiPathSetForSource
Definition: DBCStructure.h:2215

References sTaxiPathSetBySource.

◆ GetVehicleAccessoryList()

VehicleAccessoryList const * ObjectMgr::GetVehicleAccessoryList ( Vehicle veh) const
9966{
9967 if (Creature* cre = veh->GetBase()->ToCreature())
9968 {
9969 // Give preference to GUID-based accessories
9970 VehicleAccessoryContainer::const_iterator itr = _vehicleAccessoryStore.find(cre->GetSpawnId());
9971 if (itr != _vehicleAccessoryStore.end())
9972 return &itr->second;
9973 }
9974
9975 // Otherwise return entry-based
9976 VehicleAccessoryContainer::const_iterator itr = _vehicleTemplateAccessoryStore.find(veh->GetCreatureEntry());
9977 if (itr != _vehicleTemplateAccessoryStore.end())
9978 return &itr->second;
9979 return nullptr;
9980}
Creature * ToCreature()
Definition: Object.h:197
Unit * GetBase() const
May be called from scripts.
Definition: Vehicle.h:39
uint32 GetCreatureEntry() const
Definition: Vehicle.h:41
VehicleAccessoryContainer _vehicleAccessoryStore
Definition: ObjectMgr.h:1527
VehicleAccessoryContainer _vehicleTemplateAccessoryStore
Definition: ObjectMgr.h:1526

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

◆ GetXPForLevel()

uint32 ObjectMgr::GetXPForLevel ( uint8  level) const
7450{
7451 if (level < _playerXPperLevel.size())
7452 return _playerXPperLevel[level];
7453 return 0;
7454}
PlayerXPperLevel _playerXPperLevel
Definition: ObjectMgr.h:1554

References _playerXPperLevel.

◆ InitializeSpellInfoPrecomputedData()

void ObjectMgr::InitializeSpellInfoPrecomputedData ( )
5736{
5737 uint32 limit = sSpellStore.GetNumRows();
5738 for(uint32 i = 0; i <= limit; ++i)
5739 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(i))
5740 {
5741 const_cast<SpellInfo*>(spellInfo)->SetStackableWithRanks(spellInfo->ComputeIsStackableWithRanks());
5742 const_cast<SpellInfo*>(spellInfo)->SetCritCapable(spellInfo->ComputeIsCritCapable());
5743 const_cast<SpellInfo*>(spellInfo)->SetSpellValid(SpellMgr::ComputeIsSpellValid(spellInfo, false));
5744 }
5745}
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)

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

◆ instance()

ObjectMgr * ObjectMgr::instance ( )
static
433{
434 static ObjectMgr instance;
435 return &instance;
436}
Definition: ObjectMgr.h:729
static ObjectMgr * instance()
Definition: ObjectMgr.cpp:432

References instance().

Referenced by instance().

◆ IsGameObjectStaticTransport()

bool ObjectMgr::IsGameObjectStaticTransport ( uint32  entry)
9946{
9947 GameObjectTemplate const* goinfo = GetGameObjectTemplate(entry);
9948 return goinfo && goinfo->type == GAMEOBJECT_TYPE_TRANSPORT;
9949}
@ GAMEOBJECT_TYPE_TRANSPORT
Definition: SharedDefines.h:1543

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

◆ IsProfanityName()

bool ObjectMgr::IsProfanityName ( std::string_view  name) const
8248{
8249 // pussywizard
8250 if (name.size() >= 2 && (name[name.size() - 2] == 'G' || name[name.size() - 2] == 'g') && (name[name.size() - 1] == 'M' || name[name.size() - 1] == 'm'))
8251 return true;
8252
8253 std::wstring wstr;
8254 if (!Utf8toWStr (name, wstr))
8255 return false;
8256
8257 wstrToLower(wstr);
8258
8259 return _profanityNamesStore.find(wstr) != _profanityNamesStore.end();
8260}

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

Referenced by AddProfanityPlayerName().

◆ IsReservedName()

bool ObjectMgr::IsReservedName ( std::string_view  name) const
8173{
8174 // pussywizard
8175 if (name.size() >= 2 && (name[name.size() - 2] == 'G' || name[name.size() - 2] == 'g') && (name[name.size() - 1] == 'M' || name[name.size() - 1] == 'm'))
8176 return true;
8177
8178 std::wstring wstr;
8179 if (!Utf8toWStr (name, wstr))
8180 return false;
8181
8182 wstrToLower(wstr);
8183
8184 return _reservedNamesStore.find(wstr) != _reservedNamesStore.end();
8185}

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

Referenced by AddReservedPlayerName().

◆ IsTavernAreaTrigger()

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

References _tavernAreaTriggerStore.

◆ IsTransportMap()

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

References _transportMaps.

◆ IsValidChannelName()

bool ObjectMgr::IsValidChannelName ( std::string const &  name)
static
8452{
8453 std::wstring wname;
8454 if (!Utf8toWStr(name, wname))
8455 return false;
8456
8457 if (wname.size() > MAX_CHANNEL_NAME)
8458 return false;
8459
8460 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_CHANNEL_NAMES);
8461
8462 return isValidString(wname, strictMask, true);
8463}
#define MAX_CHANNEL_NAME
Definition: ObjectMgr.h:692
@ CONFIG_STRICT_CHANNEL_NAMES
Definition: IWorld.h:220

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

◆ IsValidCharterName()

bool ObjectMgr::IsValidCharterName ( std::string_view  name)
static
8416{
8417 std::wstring wname;
8418 if (!Utf8toWStr(name, wname))
8419 return false;
8420
8421 if (wname.size() > MAX_CHARTER_NAME)
8422 return false;
8423
8424 uint32 minName = sWorld->getIntConfig(CONFIG_MIN_CHARTER_NAME);
8425 if (wname.size() < minName)
8426 return false;
8427
8428 // Check for Reserved Name from DBC
8429 if (sWorld->getBoolConfig(CONFIG_STRICT_NAMES_RESERVED))
8430 {
8431 if (ReservedNames(wname))
8432 {
8433 return false;
8434 }
8435 }
8436
8437 // Check for Profanity
8438 if (sWorld->getBoolConfig(CONFIG_STRICT_NAMES_PROFANITY))
8439 {
8440 if (ProfanityNames(wname))
8441 {
8442 return false;
8443 }
8444 }
8445
8446 uint32 strictMask = sWorld->getIntConfig(CONFIG_STRICT_CHARTER_NAMES);
8447
8448 return isValidString(wname, strictMask, true);
8449}
#define MAX_CHARTER_NAME
Definition: ObjectMgr.h:691
@ CONFIG_MIN_CHARTER_NAME
Definition: IWorld.h:223
@ CONFIG_STRICT_CHARTER_NAMES
Definition: IWorld.h:219

References CONFIG_MIN_CHARTER_NAME, CONFIG_STRICT_CHARTER_NAMES, CONFIG_STRICT_NAMES_PROFANITY, CONFIG_STRICT_NAMES_RESERVED, isValidString(), MAX_CHARTER_NAME, ProfanityNames(), ReservedNames(), sWorld, and Utf8toWStr().

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

◆ IsVendorItemValid()

bool ObjectMgr::IsVendorItemValid ( uint32  vendor_entry,
uint32  item,
int32  maxcount,
uint32  ptime,
uint32  ExtendedCost,
Player player = nullptr,
std::set< uint32 > *  skip_vendors = nullptr,
uint32  ORnpcflag = 0 
) const
9331{
9332 /*
9333 CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(vendor_entry);
9334 if (!cInfo)
9335 {
9336 if (player)
9337 ChatHandler(player->GetSession()).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
9338 else
9339 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have data for not existed creature template (Entry: {}), ignore", vendor_entry);
9340 return false;
9341 }
9342
9343 if (!((cInfo->npcflag | ORnpcflag) & UNIT_NPC_FLAG_VENDOR))
9344 {
9345 if (!skip_vendors || skip_vendors->count(vendor_entry) == 0)
9346 {
9347 if (player)
9348 ChatHandler(player->GetSession()).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
9349 else
9350 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have data for not creature template (Entry: {}) without vendor flag, ignore", vendor_entry);
9351
9352 if (skip_vendors)
9353 skip_vendors->insert(vendor_entry);
9354 }
9355 return false;
9356 }
9357 */
9358
9359 if (!sObjectMgr->GetItemTemplate(item_id))
9360 {
9361 if (player)
9363 else
9364 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` for Vendor (Entry: {}) have in item list non-existed item ({}), ignore", vendor_entry, item_id);
9365 return false;
9366 }
9367
9368 if (ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost))
9369 {
9370 if (player)
9372 else
9373 LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have Item (Entry: {}) with wrong ExtendedCost ({}) for vendor ({}), ignore", item_id, ExtendedCost, vendor_entry);
9374 return false;
9375 }
9376
9377 if (maxcount > 0 && incrtime == 0)
9378 {
9379 if (player)
9380 ChatHandler(player->GetSession()).PSendSysMessage("MaxCount != 0 (%u) but IncrTime == 0", maxcount);
9381 else
9382 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);
9383 return false;
9384 }
9385 else if (maxcount == 0 && incrtime > 0)
9386 {
9387 if (player)
9388 ChatHandler(player->GetSession()).PSendSysMessage("MaxCount == 0 but IncrTime<>= 0");
9389 else
9390 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);
9391 return false;
9392 }
9393
9394 VendorItemData const* vItems = GetNpcVendorItemList(vendor_entry);
9395 if (!vItems)
9396 return true; // later checks for non-empty lists
9397
9398 if (vItems->FindItemCostPair(item_id, ExtendedCost))
9399 {
9400 if (player)
9401 ChatHandler(player->GetSession()).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, item_id, ExtendedCost);
9402 else
9403 LOG_ERROR("sql.sql", "Table `npc_vendor` has duplicate items {} (with extended cost {}) for vendor (Entry: {}), ignoring", item_id, ExtendedCost, vendor_entry);
9404 return false;
9405 }
9406
9407 return true;
9408}
DBCStorage< ItemExtendedCostEntry > sItemExtendedCostStore(ItemExtendedCostEntryfmt)
@ LANG_ITEM_ALREADY_IN_LIST
Definition: Language.h:248
@ LANG_ITEM_NOT_FOUND
Definition: Language.h:245
@ LANG_EXTENDED_COST_NOT_EXIST
Definition: Language.h:372
Definition: Chat.h:38
void PSendSysMessage(char const *fmt, Args &&... args)
Definition: Chat.h:60
VendorItem const * FindItemCostPair(uint32 item_id, uint32 extendedCost) const
Definition: Creature.cpp:112
WorldSession * GetSession() const
Definition: Player.h:1948
VendorItemData const * GetNpcVendorItemList(uint32 entry) const
Definition: ObjectMgr.h:1373

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 ( )
6741{
6742 uint32 oldMSTime = getMSTime();
6743
6744 if (!_accessRequirementStore.empty())
6745 {
6746 for (DungeonProgressionRequirementsContainer::iterator itr = _accessRequirementStore.begin(); itr != _accessRequirementStore.end(); ++itr)
6747 {
6748 std::unordered_map<uint8, DungeonProgressionRequirements*> difficulties = itr->second;
6749 for (auto difficultiesItr = difficulties.begin(); difficultiesItr != difficulties.end(); ++difficultiesItr)
6750 {
6751 for (auto questItr = difficultiesItr->second->quests.begin(); questItr != difficultiesItr->second->quests.end(); ++questItr)
6752 {
6753 delete* questItr;
6754 }
6755
6756 for (auto achievementItr = difficultiesItr->second->achievements.begin(); achievementItr != difficultiesItr->second->achievements.end(); ++achievementItr)
6757 {
6758 delete* achievementItr;
6759 }
6760
6761 for (auto itemsItr = difficultiesItr->second->items.begin(); itemsItr != difficultiesItr->second->items.end(); ++itemsItr)
6762 {
6763 delete* itemsItr;
6764 }
6765
6766 delete difficultiesItr->second;
6767 }
6768 }
6769
6770 _accessRequirementStore.clear(); // need for reload case
6771 }
6772 // 0 1 2 3 4 5
6773 QueryResult access_template_result = WorldDatabase.Query("SELECT id, map_id, difficulty, min_level, max_level, min_avg_item_level FROM dungeon_access_template");
6774 if (!access_template_result)
6775 {
6776 LOG_WARN("server.loading", ">> Loaded 0 access requirement definitions. DB table `dungeon_access_template` is empty.");
6777 LOG_INFO("server.loading", " ");
6778 return;
6779 }
6780
6781 uint32 count = 0;
6782 uint32 countProgressionRequirements = 0;
6783
6784 do
6785 {
6786 Field* fields = access_template_result->Fetch();
6787
6788 //Get the common variables for the access requirements
6789 uint8 dungeon_access_id = fields[0].Get<uint8>();
6790 uint32 mapid = fields[1].Get<uint32>();
6791 uint8 difficulty = fields[2].Get<uint8>();
6792
6793 //Set up the access requirements
6795 ar->levelMin = fields[3].Get<uint8>();
6796 ar->levelMax = fields[4].Get<uint8>();
6797 ar->reqItemLevel = fields[5].Get<uint16>();
6798
6799 // 0 1 2 3 4 6
6800 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);
6801 if (progression_requirements_results)
6802 {
6803 do
6804 {
6805 Field* progression_requirement_row = progression_requirements_results->Fetch();
6806
6807 const uint8 requirement_type = progression_requirement_row[0].Get<uint8>();
6808 const uint32 requirement_id = progression_requirement_row[1].Get<uint32>();
6809 const std::string requirement_note = progression_requirement_row[2].Get<std::string>();
6810 const uint8 requirement_faction = progression_requirement_row[3].Get<uint8>();
6811 const uint8 requirement_priority = progression_requirement_row[4].IsNull() ? UINT8_MAX : progression_requirement_row[4].Get<uint8>();
6812 const bool requirement_checkLeaderOnly = progression_requirement_row[5].Get<bool>();
6813
6814 ProgressionRequirement* progression_requirement = new ProgressionRequirement();
6815 progression_requirement->id = requirement_id;
6816 progression_requirement->note = requirement_note;
6817 progression_requirement->faction = (TeamId)requirement_faction;
6818 progression_requirement->priority = requirement_priority;
6819 progression_requirement->checkLeaderOnly = requirement_checkLeaderOnly;
6820
6821 std::vector<ProgressionRequirement*>* currentRequirementsList = nullptr;
6822
6823 switch (requirement_type)
6824 {
6825 case 0:
6826 {
6827 //Achievement
6828 if (!sAchievementStore.LookupEntry(progression_requirement->id))
6829 {
6830 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);
6831 break;
6832 }
6833
6834 currentRequirementsList = &ar->achievements;
6835 break;
6836 }
6837 case 1:
6838 {
6839 //Quest
6840 if (!GetQuestTemplate(progression_requirement->id))
6841 {
6842 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);
6843 break;
6844 }
6845
6846 currentRequirementsList = &ar->quests;
6847 break;
6848 }
6849 case 2:
6850 {
6851 //Item
6852 ItemTemplate const* pProto = GetItemTemplate(progression_requirement->id);
6853 if (!pProto)
6854 {
6855 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);
6856 break;
6857 }
6858
6859 currentRequirementsList = &ar->items;
6860 break;
6861 }
6862 default:
6863 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);
6864 break;
6865 }
6866
6867 //Check if array is valid and delete the progression requirement
6868 if (!currentRequirementsList)
6869 {
6870 delete progression_requirement;
6871 continue;
6872 }
6873
6874 //Insert into the array
6875 if (currentRequirementsList->size() > requirement_priority)
6876 {
6877 currentRequirementsList->insert(currentRequirementsList->begin() + requirement_priority, progression_requirement);
6878 }
6879 else
6880 {
6881 currentRequirementsList->push_back(progression_requirement);
6882 }
6883
6884 } while (progression_requirements_results->NextRow());
6885 }
6886
6887 //Sort all arrays for priority
6888 auto sortFunction = [](const ProgressionRequirement* const a, const ProgressionRequirement* const b) {return a->priority > b->priority; };
6889 std::sort(ar->achievements.begin(), ar->achievements.end(), sortFunction);
6890 std::sort(ar->quests.begin(), ar->quests.end(), sortFunction);
6891 std::sort(ar->items.begin(), ar->items.end(), sortFunction);
6892
6893 countProgressionRequirements += ar->achievements.size();
6894 countProgressionRequirements += ar->quests.size();
6895 countProgressionRequirements += ar->items.size();
6896 count++;
6897
6898 _accessRequirementStore[mapid][difficulty] = ar;
6899 } while (access_template_result->NextRow());
6900
6901 LOG_INFO("server.loading", ">> Loaded {} Rows From dungeon_access_template And {} Rows From dungeon_access_requirements in {} ms", count, countProgressionRequirements, GetMSTimeDiffToNow(oldMSTime));
6902 LOG_INFO("server.loading", " ");
6903}
#define LOG_WARN(filterType__,...)
Definition: Log.h:163
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:131
uint32 getMSTime()
Definition: Timer.h:103
std::shared_ptr< ResultSet > QueryResult
Definition: DatabaseEnvFwd.h:28
DBCStorage< AchievementEntry > sAchievementStore(Achievementfmt)
TeamId
Definition: SharedDefines.h:731
Class used to access individual fields of database query result.
Definition: Field.h:99
bool IsNull() const
Definition: Field.h:107
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition: Field.h:113
Definition: ItemTemplate.h:628
Definition: Player.h:925
uint32 priority
Definition: Player.h:929
Definition: Player.h:934
ItemTemplate const * GetItemTemplate(uint32 entry)
Definition: ObjectMgr.cpp:3287
Quest const * GetQuestTemplate(uint32 quest_id) const
Definition: ObjectMgr.h:832

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 ( )
8577{
8578 uint32 oldMSTime = getMSTime();
8579
8580 _acoreStringStore.clear(); // for reload case
8581 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");
8582 if (!result)
8583 {
8584 LOG_WARN("server.loading", ">> Loaded 0 acore strings. DB table `acore_strings` is empty.");
8585 LOG_INFO("server.loading", " ");
8586 return false;
8587 }
8588
8589 do
8590 {
8591 Field* fields = result->Fetch();
8592
8593 uint32 entry = fields[0].Get<uint32>();
8594
8595 AcoreString& data = _acoreStringStore[entry];
8596
8597 data.Content.resize(DEFAULT_LOCALE + 1);
8598
8599 for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
8600 AddLocaleString(fields[i + 1].Get<std::string>(), LocaleConstant(i), data.Content);
8601 } while (result->NextRow());
8602
8603 LOG_INFO("server.loading", ">> Loaded {} Acore Strings in {} ms", (uint32)_acoreStringStore.size(), GetMSTimeDiffToNow(oldMSTime));
8604 LOG_INFO("server.loading", " ");
8605
8606 return true;
8607}
LocaleConstant
Definition: Common.h:74
@ TOTAL_LOCALES
Definition: Common.h:85
static void AddLocaleString(std::string &&s, LocaleConstant locale, std::vector< std::string > &data)
Definition: ObjectMgr.cpp:438

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

◆ LoadAreaTriggers()

void ObjectMgr::LoadAreaTriggers ( )
6630{
6631 uint32 oldMSTime = getMSTime();
6632
6633 _areaTriggerStore.clear();
6634
6635 QueryResult result = WorldDatabase.Query("SELECT entry, map, x, y, z, radius, length, width, height, orientation FROM areatrigger");
6636
6637 if (!result)
6638 {
6639 LOG_WARN("server.loading", ">> Loaded 0 area trigger definitions. DB table `areatrigger` is empty.");
6640 LOG_INFO("server.loading", " ");
6641 return;
6642 }
6643
6644 uint32 count = 0;
6645
6646 do
6647 {
6648 Field* fields = result->Fetch();
6649
6650 ++count;
6651
6652 AreaTrigger at;
6653
6654 at.entry = fields[0].Get<uint32>();
6655 at.map = fields[1].Get<uint32>();
6656 at.x = fields[2].Get<float>();
6657 at.y = fields[3].Get<float>();
6658 at.z = fields[4].Get<float>();
6659 at.radius = fields[5].Get<float>();
6660 at.length = fields[6].Get<float>();
6661 at.width = fields[7].Get<float>();
6662 at.height = fields[8].Get<float>();
6663 at.orientation = fields[9].Get<float>();
6664
6665 MapEntry const* mapEntry = sMapStore.LookupEntry(at.map);
6666 if (!mapEntry)
6667 {
6668 LOG_ERROR("sql.sql", "Area trigger (ID:{}) map (ID: {}) does not exist in `Map.dbc`.", at.entry, at.map);
6669 continue;
6670 }
6671
6672 _areaTriggerStore[at.entry] = at;
6673 } while (result->NextRow());
6674
6675 LOG_INFO("server.loading", ">> Loaded {} Area Trigger Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6676 LOG_INFO("server.loading", " ");
6677}
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 ( )
6490{
6491 uint32 oldMSTime = getMSTime();
6492
6493 _areaTriggerScriptStore.clear(); // need for reload case
6494 QueryResult result = WorldDatabase.Query("SELECT entry, ScriptName FROM areatrigger_scripts");
6495
6496 if (!result)
6497 {
6498 LOG_WARN("server.loading", ">> Loaded 0 Areatrigger Scripts. DB Table `areatrigger_scripts` Is Empty.");
6499 LOG_INFO("server.loading", " ");
6500 return;
6501 }
6502
6503 uint32 count = 0;
6504
6505 do
6506 {
6507 ++count;
6508
6509 Field* fields = result->Fetch();
6510
6511 uint32 Trigger_ID = fields[0].Get<uint32>();
6512 std::string scriptName = fields[1].Get<std::string>();
6513
6514 AreaTrigger const* atEntry = GetAreaTrigger(Trigger_ID);
6515 if (!atEntry)
6516 {
6517 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
6518 continue;
6519 }
6520 _areaTriggerScriptStore[Trigger_ID] = GetScriptId(scriptName);
6521 } while (result->NextRow());
6522
6523 LOG_INFO("server.loading", ">> Loaded {} Areatrigger Scripts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6524 LOG_INFO("server.loading", " ");
6525}
uint32 GetScriptId(std::string const &name)
Definition: ObjectMgr.cpp:9472

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

◆ LoadAreaTriggerTeleports()

void ObjectMgr::LoadAreaTriggerTeleports ( )
6680{
6681 uint32 oldMSTime = getMSTime();
6682
6683 _areaTriggerTeleportStore.clear(); // need for reload case
6684
6685 // 0 1 2 3 4 5
6686 QueryResult result = WorldDatabase.Query("SELECT ID, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM areatrigger_teleport");
6687
6688 if (!result)
6689 {
6690 LOG_WARN("server.loading", ">> Loaded 0 area trigger teleport definitions. DB table `areatrigger_teleport` is empty.");
6691 LOG_INFO("server.loading", " ");
6692 return;
6693 }
6694
6695 uint32 count = 0;
6696
6697 do
6698 {
6699 Field* fields = result->Fetch();
6700
6701 ++count;
6702
6703 uint32 Trigger_ID = fields[0].Get<uint32>();
6704
6706
6707 at.target_mapId = fields[1].Get<uint16>();
6708 at.target_X = fields[2].Get<float>();
6709 at.target_Y = fields[3].Get<float>();
6710 at.target_Z = fields[4].Get<float>();
6711 at.target_Orientation = fields[5].Get<float>();
6712
6713 AreaTrigger const* atEntry = GetAreaTrigger(Trigger_ID);
6714 if (!atEntry)
6715 {
6716 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
6717 continue;
6718 }
6719
6720 MapEntry const* mapEntry = sMapStore.LookupEntry(at.target_mapId);
6721 if (!mapEntry)
6722 {
6723 LOG_ERROR("sql.sql", "Area trigger (ID:{}) target map (ID: {}) does not exist in `Map.dbc`.", Trigger_ID, at.target_mapId);
6724 continue;
6725 }
6726
6727 if (at.target_X == 0 && at.target_Y == 0 && at.target_Z == 0)
6728 {
6729 LOG_ERROR("sql.sql", "Area trigger (ID:{}) target coordinates not provided.", Trigger_ID);
6730 continue;
6731 }
6732
6733 _areaTriggerTeleportStore[Trigger_ID] = at;
6734 } while (result->NextRow());
6735
6736 LOG_INFO("server.loading", ">> Loaded {} Area Trigger Teleport Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6737 LOG_INFO("server.loading", " ");
6738}
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 ( )
9572{
9573 uint32 oldMSTime = getMSTime();
9574
9575 // 0 1 2 3
9576 QueryResult result = WorldDatabase.Query("SELECT ID, locale, MaleText, FemaleText FROM broadcast_text_locale");
9577
9578 if (!result)
9579 {
9580 LOG_WARN("server.loading", ">> Loaded 0 broadcast text locales. DB table `broadcast_text_locale` is empty.");
9581 LOG_INFO("server.loading", " ");
9582 return;
9583 }
9584
9585 uint32 locales_count = 0;
9586 do
9587 {
9588 Field* fields = result->Fetch();
9589
9590 uint32 id = fields[0].Get<uint32>();
9591
9592 BroadcastTextContainer::iterator bct = _broadcastTextStore.find(id);
9593 if (bct == _broadcastTextStore.end())
9594 {
9595 LOG_ERROR("sql.sql", "BroadcastText (Id: {}) found in table `broadcast_text_locale` but does not exist in `broadcast_text`. Skipped!", id);
9596 continue;
9597 }
9598
9599 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
9600 if (locale == LOCALE_enUS)
9601 continue;
9602
9603 AddLocaleString(fields[2].Get<std::string>(), locale, bct->second.MaleText);
9604 AddLocaleString(fields[3].Get<std::string>(), locale, bct->second.FemaleText);
9605 locales_count++;
9606 } while (result->NextRow());
9607
9608 LOG_INFO("server.loading", ">> Loaded {} Broadcast Text Locales in {} ms", locales_count, GetMSTimeDiffToNow(oldMSTime));
9609 LOG_INFO("server.loading", " ");
9610}
LocaleConstant GetLocaleByName(const std::string &name)
Definition: Common.cpp:33

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

◆ LoadBroadcastTexts()

void ObjectMgr::LoadBroadcastTexts ( )
9487{
9488 uint32 oldMSTime = getMSTime();
9489
9490 _broadcastTextStore.clear(); // for reload case
9491
9492 // 0 1 2 3 4 5 6 7 8 9 10 11 12
9493 QueryResult result = WorldDatabase.Query("SELECT ID, LanguageID, MaleText, FemaleText, EmoteID1, EmoteID2, EmoteID3, EmoteDelay1, EmoteDelay2, EmoteDelay3, SoundEntriesID, EmotesID, Flags FROM broadcast_text");
9494 if (!result)
9495 {
9496 LOG_WARN("server.loading", ">> Loaded 0 broadcast texts. DB table `broadcast_text` is empty.");
9497 LOG_INFO("server.loading", " ");
9498 return;
9499 }
9500
9501 _broadcastTextStore.rehash(result->GetRowCount());
9502
9503 do
9504 {
9505 Field* fields = result->Fetch();
9506
9507 BroadcastText bct;
9508
9509 bct.Id = fields[0].Get<uint32>();
9510 bct.LanguageID = fields[1].Get<uint32>();
9511 bct.MaleText[DEFAULT_LOCALE] = fields[2].Get<std::string>();
9512 bct.FemaleText[DEFAULT_LOCALE] = fields[3].Get<std::string>();
9513 bct.EmoteId1 = fields[4].Get<uint32>();
9514 bct.EmoteId2 = fields[5].Get<uint32>();
9515 bct.EmoteId3 = fields[6].Get<uint32>();
9516 bct.EmoteDelay1 = fields[7].Get<uint32>();
9517 bct.EmoteDelay2 = fields[8].Get<uint32>();
9518 bct.EmoteDelay3 = fields[9].Get<uint32>();
9519 bct.SoundEntriesId = fields[10].Get<uint32>();
9520 bct.EmotesID = fields[11].Get<uint32>();
9521 bct.Flags = fields[12].Get<uint32>();
9522
9523 if (bct.SoundEntriesId)
9524 {
9525 if (!sSoundEntriesStore.LookupEntry(bct.SoundEntriesId))
9526 {
9527 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has SoundEntriesId {} but sound does not exist.", bct.Id, bct.SoundEntriesId);
9528 bct.SoundEntriesId = 0;
9529 }
9530 }
9531
9533 {
9534 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` using Language {} but Language does not exist.", bct.Id, bct.LanguageID);
9536 }
9537
9538 if (bct.EmoteId1)
9539 {
9540 if (!sEmotesStore.LookupEntry(bct.EmoteId1))
9541 {
9542 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has EmoteId1 {} but emote does not exist.", bct.Id, bct.EmoteId1);
9543 bct.EmoteId1 = 0;
9544 }
9545 }
9546
9547 if (bct.EmoteId2)
9548 {
9549 if (!sEmotesStore.LookupEntry(bct.EmoteId2))
9550 {
9551 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has EmoteId2 {} but emote does not exist.", bct.Id, bct.EmoteId2);
9552 bct.EmoteId2 = 0;
9553 }
9554 }
9555
9556 if (bct.EmoteId3)
9557 {
9558 if (!sEmotesStore.LookupEntry(bct.EmoteId3))
9559 {
9560 LOG_DEBUG("misc", "BroadcastText (Id: {}) in table `broadcast_text` has EmoteId3 {} but emote does not exist.", bct.Id, bct.EmoteId3);
9561 bct.EmoteId3 = 0;
9562 }
9563 }
9564
9565 _broadcastTextStore[bct.Id] = bct;
9566 } while (result->NextRow());
9567
9568 LOG_INFO("server.loading", ">> Loaded {} Broadcast Texts in {} ms", _broadcastTextStore.size(), GetMSTimeDiffToNow(oldMSTime));
9569}
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
DBCStorage< EmotesEntry > sEmotesStore(EmotesEntryfmt)
LanguageDesc const * GetLanguageDescByID(uint32 lang)
Definition: ObjectMgr.cpp:309
@ LANG_UNIVERSAL
Definition: SharedDefines.h:707
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 ( )
1343{
1344 uint32 oldMSTime = getMSTime();
1345
1346 // 0 1 2 3 4 5 6 7
1347 QueryResult result = WorldDatabase.Query("SELECT guid, path_id, mount, bytes1, bytes2, emote, visibilityDistanceType, auras FROM creature_addon");
1348
1349 if (!result)
1350 {
1351 LOG_WARN("server.loading", ">> Loaded 0 creature addon definitions. DB table `creature_addon` is empty.");
1352 LOG_INFO("server.loading", " ");
1353 return;
1354 }
1355
1356 uint32 count = 0;
1357 do
1358 {
1359 Field* fields = result->Fetch();
1360
1361 ObjectGuid::LowType guid = fields[0].Get<uint32>();
1362
1363 CreatureData const* creData = GetCreatureData(guid);
1364 if (!creData)
1365 {
1366 LOG_ERROR("sql.sql", "Creature (GUID: {}) does not exist but has a record in `creature_addon`", guid);
1367 continue;
1368 }
1369
1370 CreatureAddon& creatureAddon = _creatureAddonStore[guid];
1371
1372 creatureAddon.path_id = fields[1].Get<uint32>();
1373 if (creData->movementType == WAYPOINT_MOTION_TYPE && !creatureAddon.path_id)
1374 {
1375 const_cast<CreatureData*>(creData)->movementType = IDLE_MOTION_TYPE;
1376 LOG_ERROR("sql.sql", "Creature (GUID {}) has movement type set to WAYPOINT_MOTION_TYPE but no path assigned", guid);
1377 }
1378
1379 creatureAddon.mount = fields[2].Get<uint32>();
1380 creatureAddon.bytes1 = fields[3].Get<uint32>();
1381 creatureAddon.bytes2 = fields[4].Get<uint32>();
1382 creatureAddon.emote = fields[5].Get<uint32>();
1383 creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[6].Get<uint8>());
1384
1385 for (std::string_view aura : Acore::Tokenize(fields[7].Get<std::string_view>(), ' ', false))
1386 {
1387 SpellInfo const* spellInfo = nullptr;
1388
1389 if (Optional<uint32> spellId = Acore::StringTo<uint32>(aura))
1390 {
1391 spellInfo = sSpellMgr->GetSpellInfo(*spellId);
1392 }
1393
1394 if (!spellInfo)
1395 {
1396 LOG_ERROR("sql.sql", "Creature (GUID: {}) has wrong spell '{}' defined in `auras` field in `creature_addon`.", guid, aura);
1397 continue;
1398 }
1399
1400 if (std::find(creatureAddon.auras.begin(), creatureAddon.auras.end(), spellInfo->Id) != creatureAddon.auras.end())
1401 {
1402 LOG_ERROR("sql.sql", "Creature (GUID: {}) has duplicate aura (spell {}) in `auras` field in `creature_addon`.", guid, spellInfo->Id);
1403 continue;
1404 }
1405
1406 if (spellInfo->GetDuration() > 0)
1407 {
1408 LOG_DEBUG/*ERROR*/("sql.sql", "Creature (Entry: {}) has temporary aura (spell {}) in `auras` field in `creature_template_addon`.", guid, spellInfo->Id);
1409 // continue;
1410 }
1411
1412 creatureAddon.auras.push_back(spellInfo->Id);
1413 }
1414
1415 if (creatureAddon.mount)
1416 {
1417 if (!sCreatureDisplayInfoStore.LookupEntry(creatureAddon.mount))
1418 {
1419 LOG_ERROR("sql.sql", "Creature (GUID: {}) has invalid displayInfoId ({}) for mount defined in `creature_addon`", guid, creatureAddon.mount);
1420 creatureAddon.mount = 0;
1421 }
1422 }
1423
1424 if (!sEmotesStore.LookupEntry(creatureAddon.emote))
1425 {
1426 LOG_ERROR("sql.sql", "Creature (GUID: {}) has invalid emote ({}) defined in `creature_addon`.", guid, creatureAddon.emote);
1427 creatureAddon.emote = 0;
1428 }
1429
1430 if (creatureAddon.visibilityDistanceType >= VisibilityDistanceType::Max)
1431 {
1432 LOG_ERROR("sql.sql", "Creature (GUID: {}) has invalid visibilityDistanceType ({}) defined in `creature_addon`.", guid, AsUnderlyingType(creatureAddon.visibilityDistanceType));
1433 creatureAddon.visibilityDistanceType = VisibilityDistanceType::Normal;
1434 }
1435
1436 ++count;
1437 } while (result->NextRow());
1438
1439 LOG_INFO("server.loading", ">> Loaded {} Creature Addons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1440 LOG_INFO("server.loading", " ");
1441}
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:614
VisibilityDistanceType
Definition: ObjectDefines.h:61
@ WAYPOINT_MOTION_TYPE
Definition: MotionMaster.h:39
std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition: Tokenize.cpp:20
Definition: CreatureData.h:429
std::vector< uint32 > auras
Definition: CreatureData.h:435
uint32 mount
Definition: CreatureData.h:431
uint32 emote
Definition: CreatureData.h:434
uint32 path_id
Definition: CreatureData.h:430
VisibilityDistanceType visibilityDistanceType
Definition: CreatureData.h:436
uint32 bytes1
Definition: CreatureData.h:432
uint32 bytes2
Definition: CreatureData.h:433
uint32 Id
Definition: SpellInfo.h:318
int32 GetDuration() const
Definition: SpellInfo.cpp:2321

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, CreatureAddon::mount, CreatureAddon::path_id, sCreatureDisplayInfoStore, sEmotesStore, sSpellMgr, Acore::Tokenize(), CreatureAddon::visibilityDistanceType, WAYPOINT_MOTION_TYPE, and WorldDatabase.

◆ LoadCreatureClassLevelStats()

void ObjectMgr::LoadCreatureClassLevelStats ( )
9639{
9640 uint32 oldMSTime = getMSTime();
9641
9642 QueryResult result = WorldDatabase.Query("SELECT level, class, basehp0, basehp1, basehp2, basemana, basearmor, attackpower, rangedattackpower, damage_base, damage_exp1, damage_exp2 FROM creature_classlevelstats");
9643
9644 if (!result)
9645 {
9646 LOG_WARN("server.loading", ">> Loaded 0 creature base stats. DB table `creature_classlevelstats` is empty.");
9647 LOG_INFO("server.loading", " ");
9648 return;
9649 }
9650
9651 uint32 count = 0;
9652 do
9653 {
9654 Field* fields = result->Fetch();
9655
9656 uint8 Level = fields[0].Get<uint8>();
9657 uint8 Class = fields[1].Get<uint8>();
9658
9659 if (!Class || ((1 << (Class - 1)) & CLASSMASK_ALL_CREATURES) == 0)
9660 LOG_ERROR("sql.sql", "Creature base stats for level {} has invalid class {}", Level, Class);
9661
9662 CreatureBaseStats stats;
9663
9664 for (uint8 i = 0; i < MAX_EXPANSIONS; ++i)
9665 {
9666 stats.BaseHealth[i] = fields[2 + i].Get<uint32>();
9667
9668 if (stats.BaseHealth[i] == 0)
9669 {
9670 LOG_ERROR("sql.sql", "Creature base stats for class {}, level {} has invalid zero base HP[{}] - set to 1", Class, Level, i);
9671 stats.BaseHealth[i] = 1;
9672 }
9673
9674 // xinef: if no data is available, get them from lower expansions
9675 if (stats.BaseHealth[i] <= 1)
9676 {
9677 for (uint8 j = i; j > 0;)
9678 {
9679 --j;
9680 if (stats.BaseHealth[j] > 1)
9681 {
9682 stats.BaseHealth[i] = stats.BaseHealth[j];
9683 break;
9684 }
9685 }
9686 }
9687
9688 stats.BaseDamage[i] = fields[9 + i].Get<float>();
9689 if (stats.BaseDamage[i] < 0.0f)
9690 {
9691 LOG_ERROR("sql.sql", "Creature base stats for class {}, level {} has invalid negative base damage[{}] - set to 0.0", Class, Level, i);
9692 stats.BaseDamage[i] = 0.0f;
9693 }
9694 }
9695
9696 stats.BaseMana = fields[5].Get<uint32>();
9697 stats.BaseArmor = fields[6].Get<uint32>();
9698
9699 stats.AttackPower = fields[7].Get<uint32>();
9700 stats.RangedAttackPower = fields[8].Get<uint32>();
9701
9702 _creatureBaseStatsStore[MAKE_PAIR16(Level, Class)] = stats;
9703
9704 ++count;
9705 } while (result->NextRow());
9706
9707 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
9708 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
9709 {
9710 for (uint16 lvl = itr->second.minlevel; lvl <= itr->second.maxlevel; ++lvl)
9711 {
9712 if (_creatureBaseStatsStore.find(MAKE_PAIR16(lvl, itr->second.unit_class)) == _creatureBaseStatsStore.end())
9713 LOG_ERROR("sql.sql", "Missing base stats for creature class {} level {}", itr->second.unit_class, lvl);
9714 }
9715 }
9716
9717 LOG_INFO("server.loading", ">> Loaded {} Creature Base Stats in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9718 LOG_INFO("server.loading", " ");
9719}
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
Definition: CreatureData.h:281
uint32 BaseMana
Definition: CreatureData.h:294
uint32 BaseArmor
Definition: CreatureData.h:295
float BaseDamage[MAX_EXPANSIONS]
Definition: CreatureData.h:298
uint32 RangedAttackPower
Definition: CreatureData.h:297
uint32 AttackPower
Definition: CreatureData.h:296
uint32 BaseHealth[MAX_EXPANSIONS]
Definition: CreatureData.h:293

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

◆ LoadCreatureCustomIDs()

void ObjectMgr::LoadCreatureCustomIDs ( )

Load config option Creatures.CustomIDs into Store.

946{
947 // Hack for modules
948 std::string stringCreatureIds = sConfigMgr->GetOption<std::string>("Creatures.CustomIDs", "");
949 std::vector<std::string_view> CustomCreatures = Acore::Tokenize(stringCreatureIds, ',', false);
950
951 for (auto itr : CustomCreatures)
952 {
953 _creatureCustomIDsStore.push_back(Acore::StringTo<uint32>(itr).value());
954 }
955}
#define sConfigMgr
Definition: Config.h:92

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

◆ LoadCreatureLocales()

void ObjectMgr::LoadCreatureLocales ( )
450{
451 uint32 oldMSTime = getMSTime();
452
453 _creatureLocaleStore.clear(); // need for reload case
454
455 // 0 1 2 3
456 QueryResult result = WorldDatabase.Query("SELECT entry, locale, Name, Title FROM creature_template_locale");
457 if (!result)
458 return;
459
460 do
461 {
462 Field* fields = result->Fetch();
463
464 uint32 ID = fields[0].Get<uint32>();
465
466 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
467 if (locale == LOCALE_enUS)
468 continue;
469
471 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
472 AddLocaleString(fields[3].Get<std::string>(), locale, data.Title);
473 } while (result->NextRow());
474
475 LOG_INFO("server.loading", ">> Loaded {} Creature Locale Strings in {} ms", (unsigned long)_creatureLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
476}
Definition: CreatureData.h:332
std::vector< std::string > Title
Definition: CreatureData.h:334
std::vector< std::string > Name
Definition: CreatureData.h:333

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

◆ LoadCreatureModelInfo()

void ObjectMgr::LoadCreatureModelInfo ( )
1769{
1770 uint32 oldMSTime = getMSTime();
1771
1772 // 0 1 2 3 4
1773 QueryResult result = WorldDatabase.Query("SELECT DisplayID, BoundingRadius, CombatReach, Gender, DisplayID_Other_Gender FROM creature_model_info");
1774
1775 if (!result)
1776 {
1777 LOG_WARN("server.loading", ">> Loaded 0 creature model definitions. DB table `creature_model_info` is empty.");
1778 LOG_INFO("server.loading", " ");
1779 return;
1780 }
1781
1782 _creatureModelStore.rehash(result->GetRowCount());
1783 uint32 count = 0;
1784
1785 do
1786 {
1787 Field* fields = result->Fetch();
1788
1789 uint32 modelId = fields[0].Get<uint32>();
1790
1791 CreatureModelInfo& modelInfo = _creatureModelStore[modelId];
1792
1793 modelInfo.bounding_radius = fields[1].Get<float>();
1794 modelInfo.combat_reach = fields[2].Get<float>();
1795 modelInfo.gender = fields[3].Get<uint8>();
1796 modelInfo.modelid_other_gender = fields[4].Get<uint32>();
1797
1798 // Checks
1799
1800 if (!sCreatureDisplayInfoStore.LookupEntry(modelId))
1801 LOG_ERROR("sql.sql", "Table `creature_model_info` has model for not existed display id ({}).", modelId);
1802
1803 if (modelInfo.gender > GENDER_NONE)
1804 {
1805 LOG_ERROR("sql.sql", "Table `creature_model_info` has wrong gender ({}) for display id ({}).", uint32(modelInfo.gender), modelId);
1806 modelInfo.gender = GENDER_MALE;
1807 }
1808
1809 if (modelInfo.modelid_other_gender && !sCreatureDisplayInfoStore.LookupEntry(modelInfo.modelid_other_gender))
1810 {
1811 LOG_ERROR("sql.sql", "Table `creature_model_info` has not existed alt.gender model ({}) for existed display id ({}).", modelInfo.modelid_other_gender, modelId);
1812 modelInfo.modelid_other_gender = 0;
1813 }
1814
1815 if (modelInfo.combat_reach < 0.1f)
1816 modelInfo.combat_reach = DEFAULT_COMBAT_REACH;
1817
1818 ++count;
1819 } while (result->NextRow());
1820
1821 LOG_INFO("server.loading", ">> Loaded {} Creature Model Based Info in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1822 LOG_INFO("server.loading", " ");
1823}
#define DEFAULT_COMBAT_REACH
Definition: ObjectDefines.h:46
@ GENDER_MALE
Definition: SharedDefines.h:60
@ GENDER_NONE
Definition: SharedDefines.h:62

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

◆ LoadCreatureMovementOverrides()

void ObjectMgr::LoadCreatureMovementOverrides ( )
1632{
1633 uint32 oldMSTime = getMSTime();
1634
1636
1637 // Load the data from creature_movement_override and if NULL fallback to creature_template_movement
1638 QueryResult result = WorldDatabase.Query("SELECT cmo.SpawnId,"
1639 "COALESCE(cmo.Ground, ctm.Ground),"
1640 "COALESCE(cmo.Swim, ctm.Swim),"
1641 "COALESCE(cmo.Flight, ctm.Flight),"
1642 "COALESCE(cmo.Rooted, ctm.Rooted),"
1643 "COALESCE(cmo.Chase, ctm.Chase),"
1644 "COALESCE(cmo.Random, ctm.Random),"
1645 "COALESCE(cmo.InteractionPauseTimer, ctm.InteractionPauseTimer) "
1646 "FROM creature_movement_override AS cmo "
1647 "LEFT JOIN creature AS c ON c.guid = cmo.SpawnId "
1648 "LEFT JOIN creature_template_movement AS ctm ON ctm.CreatureId = c.id1");
1649 if (!result)
1650 {
1651 LOG_WARN("server.loading", ">> Loaded 0 creature movement overrides. DB table `creature_movement_override` is empty!");
1652 return;
1653 }
1654
1655 do
1656 {
1657 Field* fields = result->Fetch();
1658 ObjectGuid::LowType spawnId = fields[0].Get<uint32>();
1659 if (!GetCreatureData(spawnId))
1660 {
1661 LOG_ERROR("sql.sql", "Creature (GUID: {}) does not exist but has a record in `creature_movement_override`", spawnId);
1662 continue;
1663 }
1664
1666 if (!fields[1].IsNull())
1667 {
1668 movement.Ground = static_cast<CreatureGroundMovementType>(fields[1].Get<uint8>());
1669 }
1670
1671 if (!fields[2].IsNull())
1672 {
1673 movement.Swim = fields[2].Get<bool>();
1674 }
1675
1676 if (!fields[3].IsNull())
1677 {
1678 movement.Flight = static_cast<CreatureFlightMovementType>(fields[3].Get<uint8>());
1679 }
1680
1681 if (!fields[4].IsNull())
1682 {
1683 movement.Rooted = fields[4].Get<bool>();
1684 }
1685
1686 if (!fields[5].IsNull())
1687 {
1688 movement.Chase = static_cast<CreatureChaseMovementType>(fields[5].Get<uint8>());
1689 }
1690
1691 if (!fields[6].IsNull())
1692 {
1693 movement.Random = static_cast<CreatureRandomMovementType>(fields[6].Get<uint8>());
1694 }
1695
1696 if (!fields[7].IsNull())
1697 {
1698 movement.InteractionPauseTimer = fields[7].Get<uint32>();
1699 }
1700
1701 CheckCreatureMovement("creature_movement_override", spawnId, movement);
1702 } while (result->NextRow());
1703
1704 LOG_INFO("server.loading", ">> Loaded {} Movement Overrides in {} ms", _creatureMovementOverrides.size(), GetMSTimeDiffToNow(oldMSTime));
1705 LOG_INFO("server.loading", " ");
1706}
CreatureFlightMovementType
Definition: CreatureData.h:98
CreatureChaseMovementType
Definition: CreatureData.h:107
CreatureGroundMovementType
Definition: CreatureData.h:89
CreatureRandomMovementType
Definition: CreatureData.h:116
Definition: CreatureData.h:125
bool Swim
Definition: CreatureData.h:130
bool Rooted
Definition: CreatureData.h:131
uint32 InteractionPauseTimer
Definition: CreatureData.h:134

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 ( )
8119{
8120 LoadQuestRelationsHelper(_creatureQuestInvolvedRelations, "creature_questender", false, false);
8121
8122 for (QuestRelations::iterator itr = _creatureQuestInvolvedRelations.begin(); itr != _creatureQuestInvolvedRelations.end(); ++itr)
8123 {
8124 CreatureTemplate const* cInfo = GetCreatureTemplate(itr->first);
8125 if (!cInfo)
8126 LOG_ERROR("sql.sql", "Table `creature_questender` have data for not existed creature entry ({}) and existed quest {}", itr->first, itr->second);
8127 else if (!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER))
8128 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);
8129 }
8130}
@ UNIT_NPC_FLAG_QUESTGIVER
Definition: Unit.h:517
void LoadQuestRelationsHelper(QuestRelations &map, std::string const &table, bool starter, bool go)
Definition: ObjectMgr.cpp:8031

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

Referenced by LoadQuestStartersAndEnders().

◆ LoadCreatureQuestItems()

void ObjectMgr::LoadCreatureQuestItems ( )
10025{
10026 uint32 oldMSTime = getMSTime();
10027
10028 // 0 1
10029 QueryResult result = WorldDatabase.Query("SELECT CreatureEntry, ItemId FROM creature_questitem ORDER BY Idx ASC");
10030
10031 if (!result)
10032 {
10033 LOG_WARN("server.loading", ">> Loaded 0 creature quest items. DB table `creature_questitem` is empty.");
10034 return;
10035 }
10036
10037 uint32 count = 0;
10038 do
10039 {
10040 Field* fields = result->Fetch();
10041
10042 uint32 entry = fields[0].Get<uint32>();
10043 uint32 item = fields[1].Get<uint32>();
10044
10045 _creatureQuestItemStore[entry].push_back(item);
10046
10047 ++count;
10048 } while (result->NextRow());
10049
10050 LOG_INFO("server.loading", ">> Loaded {} Creature Quest Items in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10051 LOG_INFO("server.loading", " ");
10052}

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

◆ LoadCreatureQuestStarters()

void ObjectMgr::LoadCreatureQuestStarters ( )
8105{
8106 LoadQuestRelationsHelper(_creatureQuestRelations, "creature_queststarter", true, false);
8107
8108 for (QuestRelations::iterator itr = _creatureQuestRelations.begin(); itr != _creatureQuestRelations.end(); ++itr)
8109 {
8110 CreatureTemplate const* cInfo = GetCreatureTemplate(itr->first);
8111 if (!cInfo)
8112 LOG_ERROR("sql.sql", "Table `creature_queststarter` have data for not existed creature entry ({}) and existed quest {}", itr->first, itr->second);
8113 else if (!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER))
8114 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);
8115 }
8116}

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

Referenced by LoadQuestStartersAndEnders().

◆ LoadCreatures()

void ObjectMgr::LoadCreatures ( )
2144{
2145 uint32 oldMSTime = getMSTime();
2146
2147 // 0 1 2 3 4 5 6 7 8 9 10 11
2148 QueryResult result = WorldDatabase.Query("SELECT creature.guid, id1, id2, id3, map, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, wander_distance, "
2149 // 12 13 14 15 16 17 18 19 20 21 22
2150 "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags, "
2151 // 23
2152 "creature.ScriptName "
2153 "FROM creature "
2154 "LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid "
2155 "LEFT OUTER JOIN pool_creature ON creature.guid = pool_creature.guid");
2156
2157 if (!result)
2158 {
2159 LOG_WARN("server.loading", ">> Loaded 0 creatures. DB table `creature` is empty.");
2160 LOG_INFO("server.loading", " ");
2161 return;
2162 }
2163
2164 // Build single time for check spawnmask
2165 std::map<uint32, uint32> spawnMasks;
2166 for (uint32 i = 0; i < sMapStore.GetNumRows(); ++i)
2167 if (sMapStore.LookupEntry(i))
2168 for (int k = 0; k < MAX_DIFFICULTY; ++k)
2170 spawnMasks[i] |= (1 << k);
2171
2172 _creatureDataStore.rehash(result->GetRowCount());
2173 uint32 count = 0;
2174 do
2175 {
2176 Field* fields = result->Fetch();
2177
2178 ObjectGuid::LowType spawnId = fields[0].Get<uint32>();
2179 uint32 id1 = fields[1].Get<uint32>();
2180 uint32 id2 = fields[2].Get<uint32>();
2181 uint32 id3 = fields[3].Get<uint32>();
2182
2183 CreatureTemplate const* cInfo = GetCreatureTemplate(id1);
2184 if (!cInfo)
2185 {
2186 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non existing creature entry {} in id1 field, skipped.", spawnId, id1);
2187 continue;
2188 }
2189 CreatureTemplate const* cInfo2 = GetCreatureTemplate(id2);
2190 if (!cInfo2 && id2)
2191 {
2192 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non existing creature entry {} in id2 field, skipped.", spawnId, id2);
2193 continue;
2194 }
2195 CreatureTemplate const* cInfo3 = GetCreatureTemplate(id3);
2196 if (!cInfo3 && id3)
2197 {
2198 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with non existing creature entry {} in id3 field, skipped.", spawnId, id3);
2199 continue;
2200 }
2201 if (!id2 && id3)
2202 {
2203 LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: {}) with creature entry {} in id3 field but no entry in id2 field, skipped.", spawnId, id3);
2204 continue;
2205 }
2206 CreatureData& data = _creatureDataStore[spawnId];
2207 data.id1 = id1;
2208 data.id2 = id2;
2209 data.id3 = id3;
2210 data.mapid = fields[4].Get<uint16>();
2211 data.equipmentId = fields[5].Get<int8>();
2212 data.posX = fields[6].Get<float>();
2213 data.posY = fields[7].Get<float>();
2214 data.posZ = fields[8].Get<float>();
2215 data.orientation = fields[9].Get<float>();
2216 data.spawntimesecs = fields[10].Get<uint32>();
2217 data.wander_distance = fields[11].Get<float>();
2218 data.currentwaypoint = fields[12].Get<uint32>();
2219 data.curhealth = fields[13].Get<uint32>();
2220 data.curmana = fields[14].Get<uint32>();
2221 data.movementType = fields[15].Get<uint8>();
2222 data.spawnMask = fields[16].Get<uint8>();
2223 data.phaseMask = fields[17].Get<uint32>();
2224 int16 gameEvent = fields[18].Get<int8>();
2225 uint32 PoolId = fields[19].Get<uint32>();
2226 data.npcflag = fields[20].Get<uint32>();
2227 data.unit_flags = fields[21].Get<uint32>();
2228 data.dynamicflags = fields[22].Get<uint32>();
2229 data.ScriptId = GetScriptId(fields[23].Get<std::string>());
2230
2231 if (!data.ScriptId)
2232 data.ScriptId = cInfo->ScriptID;
2233
2234 MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid);
2235 if (!mapEntry)
2236 {
2237 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {}) that spawned at not existed map (Id: {}), skipped.", spawnId, data.mapid);
2238 continue;
2239 }
2240
2241 // pussywizard: 7 days means no reaspawn, so set it to 14 days, because manual id reset may be late
2242 if (mapEntry->IsRaid() && data.spawntimesecs >= 7 * DAY && data.spawntimesecs < 14 * DAY)
2243 data.spawntimesecs = 14 * DAY;
2244
2245 // Skip spawnMask check for transport maps
2246 if (!_transportMaps.count(data.mapid) && data.spawnMask & ~spawnMasks[data.mapid])
2247 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {}) that have wrong spawn mask {} including not supported difficulty modes for map (Id: {}).",
2248 spawnId, data.spawnMask, data.mapid);
2249
2250 bool ok = true;
2251 for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff)
2252 {
2253 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()))
2254 {
2255 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {}) that listed as difficulty {} template (Entries: {}, {}, {}) in `creature_template`, skipped.",
2256 spawnId, diff + 1, data.id1, data.id2, data.id3);
2257 ok = false;
2258 }
2259 }
2260 if (!ok)
2261 continue;
2262
2263 // -1 random, 0 no equipment,
2264 if (data.equipmentId != 0)
2265 {
2266 if ((!GetEquipmentInfo(data.id1, data.equipmentId)) || (data.id2 && !GetEquipmentInfo(data.id2, data.equipmentId)) || (data.id3 && !GetEquipmentInfo(data.id3, data.equipmentId)))
2267 {
2268 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.",
2269 data.id1, data.id2, data.id3, data.equipmentId);
2270 data.equipmentId = 0;
2271 }
2272 }
2273 if ((cInfo->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND) || (data.id2 && cInfo2->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND) || (data.id3 && cInfo3->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND))
2274 {
2275 if (!mapEntry->IsDungeon())
2276 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.",
2277 spawnId, data.id1, data.id2, data.id3);
2278 }
2279 if (data.movementType >= MAX_DB_MOTION_TYPE)
2280 {
2281 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);
2283 }
2284 if (data.wander_distance < 0.0f)
2285 {
2286 LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: {} Entries: {}, {}, {}) with `wander_distance`< 0, set to 0.", spawnId, data.id1, data.id2, data.id3);
2287 data.wander_distance = 0.0f;
2288 }
2289 else if (data.movementType == RANDOM_MOTION_TYPE)
2290 {
2291 if (data.wander_distance == 0.0f)
2292 {
2293 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).",
2294 spawnId, data.id1, data.id2, data.id3);
2296 }
2297 }
2298 else if (data.movementType == IDLE_MOTION_TYPE)
2299 {
2300 if (data.wander_distance != 0.0f)
2301 {
2302 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);
2303 data.wander_distance = 0.0f;
2304 }
2305 }
2306
2307 if (data.phaseMask == 0)
2308 {
2309 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);
2310 data.phaseMask = 1;
2311 }
2312
2314 {
2315 uint32 zoneId = sMapMgr->GetZoneId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
2316 uint32 areaId = sMapMgr->GetAreaId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
2317
2319
2320 stmt->SetData(0, zoneId);
2321 stmt->SetData(1, areaId);
2322 stmt->SetData(2, spawnId);
2323
2324 WorldDatabase.Execute(stmt);
2325 }
2326
2327 // Add to grid if not managed by the game event or pool system
2328 if (gameEvent == 0 && PoolId == 0)
2329 AddCreatureToGrid(spawnId, &data);
2330
2331 ++count;
2332 } while (result->NextRow());
2333
2334 LOG_INFO("server.loading", ">> Loaded {} Creatures in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2335 LOG_INFO("server.loading", " ");
2336}
constexpr auto DAY
Definition: Common.h:58
std::int8_t int8
Definition: Define.h:106
std::int16_t int16
Definition: Define.h:105
@ WORLD_UPD_CREATURE_ZONE_AREA_DATA
Definition: WorldDatabase.h:99
MapDifficulty const * GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
Definition: DBCStores.cpp:754
@ CREATURE_FLAG_EXTRA_INSTANCE_BIND
Definition: CreatureData.h:49
@ RANDOM_MOTION_TYPE
Definition: MotionMaster.h:38
@ CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA
Definition: IWorld.h:155
Difficulty
Definition: DBCEnums.h:271
uint32 flags_extra
Definition: CreatureData.h:239
uint32 ScriptId
Definition: CreatureData.h:382
EquipmentInfo const * GetEquipmentInfo(uint32 entry, int8 &id)
Definition: ObjectMgr.cpp:1527
bool IsRaid() const
Definition: DBCStructure.h:1337

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, CreatureTemplate::flags_extra, Field::Get(), GetCreatureTemplate(), GetEquipmentInfo(), GetMapDifficultyData(), getMSTime(), GetMSTimeDiffToNow(), GetScriptId(), 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.

◆ LoadCreatureTemplate()

void ObjectMgr::LoadCreatureTemplate ( Field fields)
644{
645 uint32 entry = fields[0].Get<uint32>();
646
647 CreatureTemplate& creatureTemplate = _creatureTemplateStore[entry];
648
649 creatureTemplate.Entry = entry;
650
651 for (uint8 i = 0; i < MAX_DIFFICULTY - 1; ++i)
652 {
653 creatureTemplate.DifficultyEntry[i] = fields[1 + i].Get<uint32>();
654 }
655
656 for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i)
657 {
658 creatureTemplate.KillCredit[i] = fields[4 + i].Get<uint32>();
659 }
660
661 creatureTemplate.Modelid1 = fields[6].Get<uint32>();
662 creatureTemplate.Modelid2 = fields[7].Get<uint32>();
663 creatureTemplate.Modelid3 = fields[8].Get<uint32>();
664 creatureTemplate.Modelid4 = fields[9].Get<uint32>();
665 creatureTemplate.Name = fields[10].Get<std::string>();
666 creatureTemplate.SubName = fields[11].Get<std::string>();
667 creatureTemplate.IconName = fields[12].Get<std::string>();
668 creatureTemplate.GossipMenuId = fields[13].Get<uint32>();
669 creatureTemplate.minlevel = fields[14].Get<uint8>();
670 creatureTemplate.maxlevel = fields[15].Get<uint8>();
671 creatureTemplate.expansion = uint32(fields[16].Get<int16>());
672 creatureTemplate.faction = uint32(fields[17].Get<uint16>());
673 creatureTemplate.npcflag = fields[18].Get<uint32>();
674 creatureTemplate.speed_walk = fields[19].Get<float>();
675 creatureTemplate.speed_run = fields[20].Get<float>();
676 creatureTemplate.speed_swim = fields[21].Get<float>();
677 creatureTemplate.speed_flight = fields[22].Get<float>();
678 creatureTemplate.detection_range = fields[23].Get<float>();
679 creatureTemplate.scale = fields[24].Get<float>();
680 creatureTemplate.rank = uint32(fields[25].Get<uint8>());
681 creatureTemplate.dmgschool = uint32(fields[26].Get<int8>());
682 creatureTemplate.DamageModifier = fields[27].Get<float>();
683 creatureTemplate.BaseAttackTime = fields[28].Get<uint32>();
684 creatureTemplate.RangeAttackTime = fields[29].Get<uint32>();
685 creatureTemplate.BaseVariance = fields[30].Get<float>();
686 creatureTemplate.RangeVariance = fields[31].Get<float>();
687 creatureTemplate.unit_class = uint32(fields[32].Get<uint8>());
688 creatureTemplate.unit_flags = fields[33].Get<uint32>();
689 creatureTemplate.unit_flags2 = fields[34].Get<uint32>();
690 creatureTemplate.dynamicflags = fields[35].Get<uint32>();
691 creatureTemplate.family = uint32(fields[36].Get<uint8>());
692 creatureTemplate.trainer_type = uint32(fields[37].Get<uint8>());
693 creatureTemplate.trainer_spell = fields[38].Get<uint32>();
694 creatureTemplate.trainer_class = uint32(fields[39].Get<uint8>());
695 creatureTemplate.trainer_race = uint32(fields[40].Get<uint8>());
696 creatureTemplate.type = uint32(fields[41].Get<uint8>());
697 creatureTemplate.type_flags = fields[42].Get<uint32>();
698 creatureTemplate.lootid = fields[43].Get<uint32>();
699 creatureTemplate.pickpocketLootId = fields[44].Get<uint32>();
700 creatureTemplate.SkinLootId = fields[45].Get<uint32>();
701
702 for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
703 {
704 creatureTemplate.resistance[i] = 0;
705 }
706
707 for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
708 {
709 creatureTemplate.spells[i] = 0;
710 }
711
712 creatureTemplate.PetSpellDataId = fields[46].Get<uint32>();
713 creatureTemplate.VehicleId = fields[47].Get<uint32>();
714 creatureTemplate.mingold = fields[48].Get<uint32>();
715 creatureTemplate.maxgold = fields[49].Get<uint32>();
716 creatureTemplate.AIName = fields[50].Get<std::string>();
717 creatureTemplate.MovementType = uint32(fields[51].Get<uint8>());
718 if (!fields[52].IsNull())
719 {
720 creatureTemplate.Movement.Ground = static_cast<CreatureGroundMovementType>(fields[52].Get<uint8>());
721 }
722
723 creatureTemplate.Movement.Swim = fields[53].Get<bool>();
724 if (!fields[54].IsNull())
725 {
726 creatureTemplate.Movement.Flight = static_cast<CreatureFlightMovementType>(fields[54].Get<uint8>());
727 }
728
729 creatureTemplate.Movement.Rooted = fields[55].Get<bool>();
730 if (!fields[56].IsNull())
731 {
732 creatureTemplate.Movement.Chase = static_cast<CreatureChaseMovementType>(fields[56].Get<uint8>());
733 }
734 if (!fields[57].IsNull())
735 {
736 creatureTemplate.Movement.Random = static_cast<CreatureRandomMovementType>(fields[57].Get<uint8>());
737 }
738 if (!fields[58].IsNull())
739 {
740 creatureTemplate.Movement.InteractionPauseTimer = fields[58].Get<uint32>();
741 }
742
743 creatureTemplate.HoverHeight = fields[59].Get<float>();
744 creatureTemplate.ModHealth = fields[60].Get<float>();
745 creatureTemplate.ModMana = fields[61].Get<float>();
746 creatureTemplate.ModArmor = fields[62].Get<float>();
747 creatureTemplate.ModExperience = fields[63].Get<float>();
748 creatureTemplate.RacialLeader = fields[64].Get<bool>();
749 creatureTemplate.movementId = fields[65].Get<uint32>();
750 creatureTemplate.RegenHealth = fields[66].Get<bool>();
751 creatureTemplate.MechanicImmuneMask = fields[67].Get<uint32>();
752 creatureTemplate.SpellSchoolImmuneMask = fields[68].Get<uint8>();
753 creatureTemplate.flags_extra = fields[69].Get<uint32>();
754 creatureTemplate.ScriptID = GetScriptId(fields[70].Get<std::string>());
755}
@ SPELL_SCHOOL_HOLY
Definition: SharedDefines.h:256

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

Referenced by LoadCreatureTemplates().

◆ LoadCreatureTemplateAddons()

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

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

◆ LoadCreatureTemplateResistances()

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

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 ( )
579{
580 uint32 oldMSTime = getMSTime();
581
582// 0 1 2 3 4 5 6 7 8
583 QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, "
584// 9 10 11 12 13 14 15 16 17 18 19 20 21 22
585 "modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction, npcflag, speed_walk, speed_run, speed_swim, speed_flight, "
586// 23 24 25 26 27 28 29 30 31 32 33 34
587 "detection_range, scale, `rank`, dmgschool, DamageModifier, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, "
588// 35 36 37 38 39 40 41
589 "dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, type, "
590// 42 43 44 45 46 47 48 49 50 51
591 "type_flags, lootid, pickpocketloot, skinloot, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, "
592// 52 53 54 55 56 57 58 59 60 61 62 63
593 "ctm.Ground, ctm.Swim, ctm.Flight, ctm.Rooted, ctm.Chase, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, ManaModifier, ArmorModifier, ExperienceModifier, "
594// 64 65 66 67 68 69 70
595 "RacialLeader, movementId, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, ScriptName "
596 "FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId;");
597
598 if (!result)
599 {
600 LOG_WARN("server.loading", ">> Loaded 0 creature template definitions. DB table `creature_template` is empty.");
601 return;
602 }
603
604 _creatureTemplateStore.rehash(result->GetRowCount());
605
606 uint32 count = 0;
607 do
608 {
609 Field* fields = result->Fetch();
610 LoadCreatureTemplate(fields);
611 ++count;
612 } while (result->NextRow());
613
614 // pussywizard:
615 {
616 uint32 max = 0;
617 for (CreatureTemplateContainer::const_iterator itr = _creatureTemplateStore.begin(); itr != _creatureTemplateStore.end(); ++itr)
618 if (itr->first > max)
619 max = itr->first;
620 if (max)
621 {
623 _creatureTemplateStoreFast.resize(max + 1, nullptr);
624 for (CreatureTemplateContainer::iterator itr = _creatureTemplateStore.begin(); itr != _creatureTemplateStore.end(); ++itr)
625 _creatureTemplateStoreFast[itr->first] = &(itr->second);
626 }
627 }
628
631
632 // Checking needs to be done after loading because of the difficulty self referencing
633 for (CreatureTemplateContainer::iterator itr = _creatureTemplateStore.begin(); itr != _creatureTemplateStore.end(); ++itr)
634 {
635 CheckCreatureTemplate(&itr->second);
636 itr->second.InitializeQueryData();
637 }
638
639 LOG_INFO("server.loading", ">> Loaded {} Creature Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
640 LOG_INFO("server.loading", " ");
641}
void LoadCreatureTemplateResistances()
Definition: ObjectMgr.cpp:757
void LoadCreatureTemplate(Field *fields)
Definition: ObjectMgr.cpp:643
void LoadCreatureTemplateSpells()
Definition: ObjectMgr.cpp:803
void CheckCreatureTemplate(CreatureTemplate const *cInfo)
Definition: ObjectMgr.cpp:957

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

◆ LoadCreatureTemplateSpells()

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

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 ( )
1554{
1555 uint32 oldMSTime = getMSTime();
1556
1557 // 0 1 2 3 4
1558 QueryResult result = WorldDatabase.Query("SELECT CreatureID, ID, ItemID1, ItemID2, ItemID3 FROM creature_equip_template");
1559
1560 if (!result)
1561 {
1562 LOG_WARN("server.loading", ">> Loaded 0 creature equipment templates. DB table `creature_equip_template` is empty!");
1563 LOG_INFO("server.loading", " ");
1564 return;
1565 }
1566
1567 uint32 count = 0;
1568 do
1569 {
1570 Field* fields = result->Fetch();
1571
1572 uint32 entry = fields[0].Get<uint32>();
1573
1574 if (!sObjectMgr->GetCreatureTemplate(entry))
1575 {
1576 LOG_ERROR("sql.sql", "Creature template (CreatureID: {}) does not exist but has a record in `creature_equip_template`", entry);
1577 continue;
1578 }
1579
1580 uint8 id = fields[1].Get<uint8>();
1581 if (!id)
1582 {
1583 LOG_ERROR("sql.sql", "Creature equipment template with id 0 found for creature {}, skipped.", entry);
1584 continue;
1585 }
1586
1587 EquipmentInfo& equipmentInfo = _equipmentInfoStore[entry][id];
1588
1589 equipmentInfo.ItemEntry[0] = fields[2].Get<uint32>();
1590 equipmentInfo.ItemEntry[1] = fields[3].Get<uint32>();
1591 equipmentInfo.ItemEntry[2] = fields[4].Get<uint32>();
1592
1593 for (uint8 i = 0; i < MAX_EQUIPMENT_ITEMS; ++i)
1594 {
1595 if (!equipmentInfo.ItemEntry[i])
1596 continue;
1597
1598 ItemTemplate const* item = GetItemTemplate(equipmentInfo.ItemEntry[i]);
1599
1600 if (!item)
1601 {
1602 LOG_ERROR("sql.sql", "Unknown item (ID={}) in creature_equip_template.ItemID{} for CreatureID = {} and ID = {}, forced to 0.",
1603 equipmentInfo.ItemEntry[i], i + 1, entry, id);
1604 equipmentInfo.ItemEntry[i] = 0;
1605 continue;
1606 }
1607
1608 if (item->InventoryType != INVTYPE_WEAPON &&
1609 item->InventoryType != INVTYPE_SHIELD &&
1610 item->InventoryType != INVTYPE_RANGED &&
1615 item->InventoryType != INVTYPE_THROWN &&
1617 {
1618 LOG_ERROR("sql.sql", "Item (ID={}) in creature_equip_template.ItemID{} for CreatureID = {} and ID = {} is not equipable in a hand, forced to 0.",
1619 equipmentInfo.ItemEntry[i], i + 1, entry, id);
1620 equipmentInfo.ItemEntry[i] = 0;
1621 }
1622 }
1623
1624 ++count;
1625 } while (result->NextRow());
1626
1627 LOG_INFO("server.loading", ">> Loaded {} Equipment Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1628 LOG_INFO("server.loading", " ");
1629}
#define MAX_EQUIPMENT_ITEMS
Definition: CreatureData.h:39
@ INVTYPE_HOLDABLE
Definition: ItemTemplate.h:288
@ INVTYPE_RANGED
Definition: ItemTemplate.h:280
@ INVTYPE_THROWN
Definition: ItemTemplate.h:290
@ INVTYPE_RANGEDRIGHT
Definition: ItemTemplate.h:291
@ INVTYPE_WEAPON
Definition: ItemTemplate.h:278
@ INVTYPE_WEAPONMAINHAND
Definition: ItemTemplate.h:286
@ INVTYPE_WEAPONOFFHAND
Definition: ItemTemplate.h:287
@ INVTYPE_2HWEAPON
Definition: ItemTemplate.h:282
@ INVTYPE_SHIELD
Definition: ItemTemplate.h:279
Definition: CreatureData.h:349
uint32 ItemEntry[MAX_EQUIPMENT_ITEMS]
Definition: CreatureData.h:350
uint32 InventoryType
Definition: ItemTemplate.h:641

References _equipmentInfoStore, Field::Get(), GetItemTemplate(), getMSTime(), GetMSTimeDiffToNow(), ItemTemplate::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, sObjectMgr, and WorldDatabase.

◆ LoadEventScripts()

void ObjectMgr::LoadEventScripts ( )
5547{
5549
5550 std::set<uint32> evt_scripts;
5551 // Load all possible script entries from gameobjects
5552 GameObjectTemplateContainer const* gotc = sObjectMgr->GetGameObjectTemplates();
5553 for (GameObjectTemplateContainer::const_iterator itr = gotc->begin(); itr != gotc->end(); ++itr)
5554 if (uint32 eventId = itr->second.GetEventScriptId())
5555 evt_scripts.insert(eventId);
5556
5557 // Load all possible script entries from spells
5558 for (uint32 i = 1; i < sSpellMgr->GetSpellInfoStoreSize(); ++i)
5559 if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(i))
5560 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
5561 if (spell->Effects[j].Effect == SPELL_EFFECT_SEND_EVENT)
5562 if (spell->Effects[j].MiscValue)
5563 evt_scripts.insert(spell->Effects[j].MiscValue);
5564
5565 for (size_t path_idx = 0; path_idx < sTaxiPathNodesByPath.size(); ++path_idx)
5566 {
5567 for (size_t node_idx = 0; node_idx < sTaxiPathNodesByPath[path_idx].size(); ++node_idx)
5568 {
5569 TaxiPathNodeEntry const* node = sTaxiPathNodesByPath[path_idx][node_idx];
5570
5571 if (node->arrivalEventID)
5572 evt_scripts.insert(node->arrivalEventID);
5573
5574 if (node->departureEventID)
5575 evt_scripts.insert(node->departureEventID);
5576 }
5577 }
5578
5579 // Then check if all scripts are in above list of possible script entries
5580 for (ScriptMapMap::const_iterator itr = sEventScripts.begin(); itr != sEventScripts.end(); ++itr)
5581 {
5582 std::set<uint32>::const_iterator itr2 = evt_scripts.find(itr->first);
5583 if (itr2 == evt_scripts.end())
5584 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 {}",
5585 itr->first, SPELL_EFFECT_SEND_EVENT);
5586 }
5587}
TaxiPathNodesByPath sTaxiPathNodesByPath
Definition: DBCStores.cpp:185
std::unordered_map< uint32, GameObjectTemplate > GameObjectTemplateContainer
Definition: GameObject.h:44
ScriptMapMap sEventScripts
Definition: ObjectMgr.cpp:60
@ SCRIPTS_EVENT
Definition: ObjectMgr.h:152
@ SPELL_EFFECT_SEND_EVENT
Definition: SharedDefines.h:811
void LoadScripts(ScriptsType type)
Definition: ObjectMgr.cpp:5204
Definition: DBCStructure.h:1949
uint32 arrivalEventID
Definition: DBCStructure.h:1959
uint32 departureEventID
Definition: DBCStructure.h:1960

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

◆ LoadExplorationBaseXP()

void ObjectMgr::LoadExplorationBaseXP ( )
7417{
7418 uint32 oldMSTime = getMSTime();
7419
7420 QueryResult result = WorldDatabase.Query("SELECT level, basexp FROM exploration_basexp");
7421
7422 if (!result)
7423 {
7424 LOG_WARN("server.loading", ">> Loaded 0 BaseXP definitions. DB table `exploration_basexp` is empty.");
7425 LOG_INFO("server.loading", " ");
7426 return;
7427 }
7428
7429 uint32 count = 0;
7430
7431 do
7432 {
7433 Field* fields = result->Fetch();
7434 uint8 level = fields[0].Get<uint8>();
7435 uint32 basexp = fields[1].Get<int32>();
7436 _baseXPTable[level] = basexp;
7437 ++count;
7438 } while (result->NextRow());
7439
7440 LOG_INFO("server.loading", ">> Loaded {} BaseXP Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7441 LOG_INFO("server.loading", " ");
7442}
std::int32_t int32
Definition: Define.h:104

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

◆ LoadFactionChangeAchievements()

void ObjectMgr::LoadFactionChangeAchievements ( )
9722{
9723 uint32 oldMSTime = getMSTime();
9724
9725 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_achievement");
9726
9727 if (!result)
9728 {
9729 LOG_WARN("server.loading", ">> Loaded 0 faction change achievement pairs. DB table `player_factionchange_achievement` is empty.");
9730 LOG_INFO("server.loading", " ");
9731 return;
9732 }
9733
9734 uint32 count = 0;
9735
9736 do
9737 {
9738 Field* fields = result->Fetch();
9739
9740 uint32 alliance = fields[0].Get<uint32>();
9741 uint32 horde = fields[1].Get<uint32>();
9742
9743 if (!sAchievementStore.LookupEntry(alliance))
9744 LOG_ERROR("sql.sql", "Achievement {} (alliance_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", alliance);
9745 else if (!sAchievementStore.LookupEntry(horde))
9746 LOG_ERROR("sql.sql", "Achievement {} (horde_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", horde);
9747 else
9748 FactionChangeAchievements[alliance] = horde;
9749
9750 ++count;
9751 } while (result->NextRow());
9752
9753 LOG_INFO("server.loading", ">> Loaded {} faction change achievement pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9754 LOG_INFO("server.loading", " ");
9755}
CharacterConversionMap FactionChangeAchievements
Definition: ObjectMgr.h:1429

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

◆ LoadFactionChangeItems()

void ObjectMgr::LoadFactionChangeItems ( )
9758{
9759 uint32 oldMSTime = getMSTime();
9760
9761 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_items");
9762
9763 if (!result)
9764 {
9765 LOG_WARN("server.loading", ">> Loaded 0 faction change item pairs. DB table `player_factionchange_items` is empty.");
9766 LOG_INFO("server.loading", " ");
9767 return;
9768 }
9769
9770 uint32 count = 0;
9771
9772 do
9773 {
9774 Field* fields = result->Fetch();
9775
9776 uint32 alliance = fields[0].Get<uint32>();
9777 uint32 horde = fields[1].Get<uint32>();
9778
9779 if (!GetItemTemplate(alliance))
9780 LOG_ERROR("sql.sql", "Item {} (alliance_id) referenced in `player_factionchange_items` does not exist, pair skipped!", alliance);
9781 else if (!GetItemTemplate(horde))
9782 LOG_ERROR("sql.sql", "Item {} (horde_id) referenced in `player_factionchange_items` does not exist, pair skipped!", horde);
9783 else
9784 FactionChangeItems[alliance] = horde;
9785
9786 ++count;
9787 } while (result->NextRow());
9788
9789 LOG_INFO("server.loading", ">> Loaded {} faction change item pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9790 LOG_INFO("server.loading", " ");
9791}
CharacterConversionMap FactionChangeItems
Definition: ObjectMgr.h:1430

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

◆ LoadFactionChangeQuests()

void ObjectMgr::LoadFactionChangeQuests ( )
9794{
9795 uint32 oldMSTime = getMSTime();
9796
9797 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_quests");
9798
9799 if (!result)
9800 {
9801 LOG_WARN("server.loading", ">> Loaded 0 faction change quest pairs. DB table `player_factionchange_quests` is empty.");
9802 LOG_INFO("server.loading", " ");
9803 return;
9804 }
9805
9806 uint32 count = 0;
9807
9808 do
9809 {
9810 Field* fields = result->Fetch();
9811
9812 uint32 alliance = fields[0].Get<uint32>();
9813 uint32 horde = fields[1].Get<uint32>();
9814
9815 if (!sObjectMgr->GetQuestTemplate(alliance))
9816 LOG_ERROR("sql.sql", "Quest {} (alliance_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", alliance);
9817 else if (!sObjectMgr->GetQuestTemplate(horde))
9818 LOG_ERROR("sql.sql", "Quest {} (horde_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", horde);
9819 else
9820 FactionChangeQuests[alliance] = horde;
9821
9822 ++count;
9823 } while (result->NextRow());
9824
9825 LOG_INFO("server.loading", ">> Loaded {} faction change quest pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9826 LOG_INFO("server.loading", " ");
9827}
CharacterConversionMap FactionChangeQuests
Definition: ObjectMgr.h:1431

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

◆ LoadFactionChangeReputations()

void ObjectMgr::LoadFactionChangeReputations ( )
9830{
9831 uint32 oldMSTime = getMSTime();
9832
9833 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_reputations");
9834
9835 if (!result)
9836 {
9837 LOG_WARN("server.loading", ">> Loaded 0 faction change reputation pairs. DB table `player_factionchange_reputations` is empty.");
9838 LOG_INFO("server.loading", " ");
9839 return;
9840 }
9841
9842 uint32 count = 0;
9843
9844 do
9845 {
9846 Field* fields = result->Fetch();
9847
9848 uint32 alliance = fields[0].Get<uint32>();
9849 uint32 horde = fields[1].Get<uint32>();
9850
9851 if (!sFactionStore.LookupEntry(alliance))
9852 LOG_ERROR("sql.sql", "Reputation {} (alliance_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", alliance);
9853 else if (!sFactionStore.LookupEntry(horde))
9854 LOG_ERROR("sql.sql", "Reputation {} (horde_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", horde);
9855 else
9856 FactionChangeReputation[alliance] = horde;
9857
9858 ++count;
9859 } while (result->NextRow());
9860
9861 LOG_INFO("server.loading", ">> Loaded {} faction change reputation pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9862 LOG_INFO("server.loading", " ");
9863}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
CharacterConversionMap FactionChangeReputation
Definition: ObjectMgr.h:1432

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

◆ LoadFactionChangeSpells()

void ObjectMgr::LoadFactionChangeSpells ( )
9866{
9867 uint32 oldMSTime = getMSTime();
9868
9869 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_spells");
9870
9871 if (!result)
9872 {
9873 LOG_WARN("server.loading", ">> Loaded 0 faction change spell pairs. DB table `player_factionchange_spells` is empty.");
9874 LOG_INFO("server.loading", " ");
9875 return;
9876 }
9877
9878 uint32 count = 0;
9879
9880 do
9881 {
9882 Field* fields = result->Fetch();
9883
9884 uint32 alliance = fields[0].Get<uint32>();
9885 uint32 horde = fields[1].Get<uint32>();
9886
9887 if (!sSpellMgr->GetSpellInfo(alliance))
9888 LOG_ERROR("sql.sql", "Spell {} (alliance_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", alliance);
9889 else if (!sSpellMgr->GetSpellInfo(horde))
9890 LOG_ERROR("sql.sql", "Spell {} (horde_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", horde);
9891 else
9892 FactionChangeSpells[alliance] = horde;
9893
9894 ++count;
9895 } while (result->NextRow());
9896
9897 LOG_INFO("server.loading", ">> Loaded {} faction change spell pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9898 LOG_INFO("server.loading", " ");
9899}
CharacterConversionMap FactionChangeSpells
Definition: ObjectMgr.h:1433

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

◆ LoadFactionChangeTitles()

void ObjectMgr::LoadFactionChangeTitles ( )
9902{
9903 uint32 oldMSTime = getMSTime();
9904
9905 QueryResult result = WorldDatabase.Query("SELECT alliance_id, horde_id FROM player_factionchange_titles");
9906
9907 if (!result)
9908 {
9909 LOG_WARN("server.loading", ">> Loaded 0 faction change title pairs. DB table `player_factionchange_title` is empty.");
9910 return;
9911 }
9912
9913 uint32 count = 0;
9914
9915 do
9916 {
9917 Field* fields = result->Fetch();
9918
9919 uint32 alliance = fields[0].Get<uint32>();
9920 uint32 horde = fields[1].Get<uint32>();
9921
9922 if (!sCharTitlesStore.LookupEntry(alliance))
9923 LOG_ERROR("sql.sql", "Title {} (alliance_id) referenced in `player_factionchange_title` does not exist, pair skipped!", alliance);
9924 else if (!sCharTitlesStore.LookupEntry(horde))
9925 LOG_ERROR("sql.sql", "Title {} (horde_id) referenced in `player_factionchange_title` does not exist, pair skipped!", horde);
9926 else
9927 FactionChangeTitles[alliance] = horde;
9928
9929 ++count;
9930 } while (result->NextRow());
9931
9932 LOG_INFO("server.loading", ">> Loaded {} faction change title pairs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9933 LOG_INFO("server.loading", " ");
9934}
DBCStorage< CharTitlesEntry > sCharTitlesStore(CharTitlesEntryfmt)
CharacterConversionMap FactionChangeTitles
Definition: ObjectMgr.h:1434

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

◆ LoadFishingBaseSkillLevel()

void ObjectMgr::LoadFishingBaseSkillLevel ( )
8625{
8626 uint32 oldMSTime = getMSTime();
8627
8628 _fishingBaseForAreaStore.clear(); // for reload case
8629
8630 QueryResult result = WorldDatabase.Query("SELECT entry, skill FROM skill_fishing_base_level");
8631
8632 if (!result)
8633 {
8634 LOG_WARN("server.loading", ">> Loaded 0 areas for fishing base skill level. DB table `skill_fishing_base_level` is empty.");
8635 LOG_INFO("server.loading", " ");
8636 return;
8637 }
8638
8639 uint32 count = 0;
8640
8641 do
8642 {
8643 Field* fields = result->Fetch();
8644 uint32 entry = fields[0].Get<uint32>();
8645 int32 skill = fields[1].Get<int16>();
8646
8647 AreaTableEntry const* fArea = sAreaTableStore.LookupEntry(entry);
8648 if (!fArea)
8649 {
8650 LOG_ERROR("sql.sql", "AreaId {} defined in `skill_fishing_base_level` does not exist", entry);
8651 continue;
8652 }
8653
8654 _fishingBaseForAreaStore[entry] = skill;
8655 ++count;
8656 } while (result->NextRow());
8657
8658 LOG_INFO("server.loading", ">> Loaded {} areas for fishing base skill level in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8659 LOG_INFO("server.loading", " ");
8660}

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

◆ LoadGameObjectAddons()

void ObjectMgr::LoadGameObjectAddons ( )
1444{
1445 uint32 oldMSTime = getMSTime();
1446
1447 // 0 1 2
1448 QueryResult result = WorldDatabase.Query("SELECT guid, invisibilityType, invisibilityValue FROM gameobject_addon");
1449
1450 if (!result)
1451 {
1452 LOG_WARN("server.loading", ">> Loaded 0 gameobject addon definitions. DB table `gameobject_addon` is empty.");
1453 LOG_INFO("server.loading", " ");
1454 return;
1455 }
1456
1457 uint32 count = 0;
1458 do
1459 {
1460 Field* fields = result->Fetch();
1461
1462 ObjectGuid::LowType guid = fields[0].Get<uint32>();
1463
1464 const GameObjectData* goData = GetGameObjectData(guid);
1465 if (!goData)
1466 {
1467 LOG_ERROR("sql.sql", "GameObject (GUID: {}) does not exist but has a record in `gameobject_addon`", guid);
1468 continue;
1469 }
1470
1471 GameObjectAddon& gameObjectAddon = _gameObjectAddonStore[guid];
1472 gameObjectAddon.invisibilityType = InvisibilityType(fields[1].Get<uint8>());
1473 gameObjectAddon.InvisibilityValue = fields[2].Get<uint32>();
1474
1475 if (gameObjectAddon.invisibilityType >= TOTAL_INVISIBILITY_TYPES)
1476 {
1477 LOG_ERROR("sql.sql", "GameObject (GUID: {}) has invalid InvisibilityType in `gameobject_addon`", guid);
1478 gameObjectAddon.invisibilityType = INVISIBILITY_GENERAL;
1479 gameObjectAddon.InvisibilityValue = 0;
1480 }
1481
1482 if (gameObjectAddon.invisibilityType && !gameObjectAddon.InvisibilityValue)
1483 {
1484 LOG_ERROR("sql.sql", "GameObject (GUID: {}) has InvisibilityType set but has no InvisibilityValue in `gameobject_addon`, set to 1", guid);
1485 gameObjectAddon.InvisibilityValue = 1;
1486 }
1487
1488 ++count;
1489 } while (result->NextRow());
1490
1491 LOG_INFO("server.loading", ">> Loaded {} Gameobject Addons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1492 LOG_INFO("server.loading", " ");
1493}
InvisibilityType
Definition: SharedDefines.h:1226
@ TOTAL_INVISIBILITY_TYPES
Definition: SharedDefines.h:1240
@ INVISIBILITY_GENERAL
Definition: SharedDefines.h:1227
Definition: GameObjectData.h:682
uint32 InvisibilityValue
Definition: GameObjectData.h:684
InvisibilityType invisibilityType
Definition: GameObjectData.h:683

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

◆ LoadGameObjectForQuests()

void ObjectMgr::LoadGameObjectForQuests ( )
8504{
8505 uint32 oldMSTime = getMSTime();
8506
8507 if (sObjectMgr->GetGameObjectTemplates()->empty())
8508 {
8509 LOG_WARN("server.loading", ">> Loaded 0 GameObjects for quests");
8510 LOG_INFO("server.loading", " ");
8511 return;
8512 }
8513
8514 uint32 count = 0;
8515
8516 // collect GO entries for GO that must activated
8517 GameObjectTemplateContainer* gotc = const_cast<GameObjectTemplateContainer*>(sObjectMgr->GetGameObjectTemplates());
8518 for (GameObjectTemplateContainer::iterator itr = gotc->begin(); itr != gotc->end(); ++itr)
8519 {
8520 itr->second.IsForQuests = false;
8521 switch (itr->second.type)
8522 {
8524 itr->second.IsForQuests = true;
8525 ++count;
8526 break;
8528 {
8529 // scan GO chest with loot including quest items
8530 uint32 loot_id = (itr->second.GetLootId());
8531
8532 // find quest loot for GO
8533 if (itr->second.chest.questId || LootTemplates_Gameobject.HaveQuestLootFor(loot_id))
8534 {
8535 itr->second.IsForQuests = true;
8536 ++count;
8537 }
8538 break;
8539 }
8541 {
8542 if (itr->second._generic.questID > 0) //quests objects
8543 {
8544 itr->second.IsForQuests = true;
8545 ++count;
8546 }
8547 break;
8548 }
8550 {
8551 if (itr->second.spellFocus.questID > 0) //quests objects
8552 {
8553 itr->second.IsForQuests = true;
8554 ++count;
8555 }
8556 break;
8557 }
8559 {
8560 if (itr->second.goober.questId > 0) //quests objects
8561 {
8562 itr->second.IsForQuests = true;
8563 ++count;
8564 }
8565 break;
8566 }
8567 default:
8568 break;
8569 }
8570 }
8571
8572 LOG_INFO("server.loading", ">> Loaded {} GameObjects for quests in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8573 LOG_INFO("server.loading", " ");
8574}
LootStore LootTemplates_Gameobject("gameobject_loot_template", "gameobject entry", true)
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition: SharedDefines.h:1540
@ GAMEOBJECT_TYPE_GENERIC
Definition: SharedDefines.h:1537
@ GAMEOBJECT_TYPE_CHEST
Definition: SharedDefines.h:1535
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition: SharedDefines.h:1534
@ GAMEOBJECT_TYPE_GOOBER
Definition: SharedDefines.h:1542
bool HaveQuestLootFor(uint32 loot_id) const
Definition: LootMgr.cpp:217

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

◆ LoadGameObjectLocales()

void ObjectMgr::LoadGameObjectLocales ( )
7061{
7062 uint32 oldMSTime = getMSTime();
7063
7064 _gameObjectLocaleStore.clear(); // need for reload case
7065
7066 // 0 1 2 3
7067 QueryResult result = WorldDatabase.Query("SELECT entry, locale, name, castBarCaption FROM gameobject_template_locale");
7068 if (!result)
7069 return;
7070
7071 do
7072 {
7073 Field* fields = result->Fetch();
7074
7075 uint32 ID = fields[0].Get<uint32>();
7076
7077 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
7078 if (locale == LOCALE_enUS)
7079 continue;
7080
7082 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
7083 AddLocaleString(fields[3].Get<std::string>(), locale, data.CastBarCaption);
7084 } while (result->NextRow());
7085
7086 LOG_INFO("server.loading", ">> Loaded {} Gameobject Locale Strings in {} ms", (uint32)_gameObjectLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
7087}
Definition: GameObjectData.h:675
std::vector< std::string > Name
Definition: GameObjectData.h:676
std::vector< std::string > CastBarCaption
Definition: GameObjectData.h:677

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

◆ LoadGameobjectQuestEnders()

void ObjectMgr::LoadGameobjectQuestEnders ( )
8091{
8092 LoadQuestRelationsHelper(_goQuestInvolvedRelations, "gameobject_questender", false, true);
8093
8094 for (QuestRelations::iterator itr = _goQuestInvolvedRelations.begin(); itr != _goQuestInvolvedRelations.end(); ++itr)
8095 {
8096 GameObjectTemplate const* goInfo = GetGameObjectTemplate(itr->first);
8097 if (!goInfo)
8098 LOG_ERROR("sql.sql", "Table `gameobject_questender` have data for not existed gameobject entry ({}) and existed quest {}", itr->first, itr->second);
8099 else if (goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER)
8100 LOG_ERROR("sql.sql", "Table `gameobject_questender` have data gameobject entry ({}) for quest {}, but GO is not GAMEOBJECT_TYPE_QUESTGIVER", itr->first, itr->second);
8101 }
8102}

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

Referenced by LoadQuestStartersAndEnders().

◆ LoadGameObjectQuestItems()

void ObjectMgr::LoadGameObjectQuestItems ( )
9995{
9996 uint32 oldMSTime = getMSTime();
9997
9998 // 0 1
9999 QueryResult result = WorldDatabase.Query("SELECT GameObjectEntry, ItemId FROM gameobject_questitem ORDER BY Idx ASC");
10000
10001 if (!result)
10002 {
10003 LOG_WARN("server.loading", ">> Loaded 0 gameobject quest items. DB table `gameobject_questitem` is empty.");
10004 return;
10005 }
10006
10007 uint32 count = 0;
10008 do
10009 {
10010 Field* fields = result->Fetch();
10011
10012 uint32 entry = fields[0].Get<uint32>();
10013 uint32 item = fields[1].Get<uint32>();
10014
10015 _gameObjectQuestItemStore[entry].push_back(item);
10016
10017 ++count;
10018 } while (result->NextRow());
10019
10020 LOG_INFO("server.loading", ">> Loaded {} Gameobject Quest Items in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10021 LOG_INFO("server.loading", " ");
10022}

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

◆ LoadGameobjectQuestStarters()

void ObjectMgr::LoadGameobjectQuestStarters ( )
8077{
8078 LoadQuestRelationsHelper(_goQuestRelations, "gameobject_queststarter", true, true);
8079
8080 for (QuestRelations::iterator itr = _goQuestRelations.begin(); itr != _goQuestRelations.end(); ++itr)
8081 {
8082 GameObjectTemplate const* goInfo = GetGameObjectTemplate(itr->first);
8083 if (!goInfo)
8084 LOG_ERROR("sql.sql", "Table `gameobject_queststarter` have data for not existed gameobject entry ({}) and existed quest {}", itr->first, itr->second);
8085 else if (goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER)
8086 LOG_ERROR("sql.sql", "Table `gameobject_queststarter` have data gameobject entry ({}) for quest {}, but GO is not GAMEOBJECT_TYPE_QUESTGIVER", itr->first, itr->second);
8087 }
8088}

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

Referenced by LoadQuestStartersAndEnders().

◆ LoadGameobjects()

void ObjectMgr::LoadGameobjects ( )
2473{
2474 uint32 oldMSTime = getMSTime();
2475
2476 uint32 count = 0;
2477
2478 // 0 1 2 3 4 5 6
2479 QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
2480 // 7 8 9 10 11 12 13 14 15 16 17
2481 "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, eventEntry, pool_entry, "
2482 // 18
2483 "ScriptName "
2484 "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid "
2485 "LEFT OUTER JOIN pool_gameobject ON gameobject.guid = pool_gameobject.guid");
2486
2487 if (!result)
2488 {
2489 LOG_WARN("server.loading", ">> Loaded 0 gameobjects. DB table `gameobject` is empty.");
2490 LOG_INFO("server.loading", " ");
2491 return;
2492 }
2493
2494 // build single time for check spawnmask
2495 std::map<uint32, uint32> spawnMasks;
2496 for (uint32 i = 0; i < sMapStore.GetNumRows(); ++i)
2497 if (sMapStore.LookupEntry(i))
2498 for (int k = 0; k < MAX_DIFFICULTY; ++k)
2500 spawnMasks[i] |= (1 << k);
2501
2502 _gameObjectDataStore.rehash(result->GetRowCount());
2503 do
2504 {
2505 Field* fields = result->Fetch();
2506
2507 ObjectGuid::LowType guid = fields[0].Get<uint32>();
2508 uint32 entry = fields[1].Get<uint32>();
2509
2510 GameObjectTemplate const* gInfo = GetGameObjectTemplate(entry);
2511 if (!gInfo)
2512 {
2513 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {}) with non existing gameobject entry {}, skipped.", guid, entry);
2514 continue;
2515 }
2516
2517 if (!gInfo->displayId)
2518 {
2519 switch (gInfo->type)
2520 {
2523 break;
2524 default:
2525 LOG_ERROR("sql.sql", "Gameobject (GUID: {} Entry {} GoType: {}) doesn't have a displayId ({}), not loaded.", guid, entry, gInfo->type, gInfo->displayId);
2526 break;
2527 }
2528 }
2529
2530 if (gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId))
2531 {
2532 LOG_ERROR("sql.sql", "Gameobject (GUID: {} Entry {} GoType: {}) has an invalid displayId ({}), not loaded.", guid, entry, gInfo->type, gInfo->displayId);
2533 continue;
2534 }
2535
2537
2538 data.id = entry;
2539 data.mapid = fields[2].Get<uint16>();
2540 data.posX = fields[3].Get<float>();
2541 data.posY = fields[4].Get<float>();
2542 data.posZ = fields[5].Get<float>();
2543 data.orientation = fields[6].Get<float>();
2544 data.rotation.x = fields[7].Get<float>();
2545 data.rotation.y = fields[8].Get<float>();
2546 data.rotation.z = fields[9].Get<float>();
2547 data.rotation.w = fields[10].Get<float>();
2548 data.spawntimesecs = fields[11].Get<int32>();
2549 data.ScriptId = GetScriptId(fields[18].Get<std::string>());
2550 if (!data.ScriptId)
2551 data.ScriptId = gInfo->ScriptId;
2552
2553 MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid);
2554 if (!mapEntry)
2555 {
2556 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) spawned on a non-existed map (Id: {}), skip", guid, data.id, data.mapid);
2557 continue;
2558 }
2559
2560 if (data.spawntimesecs == 0 && gInfo->IsDespawnAtAction())
2561 {
2562 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);
2563 }
2564
2565 data.animprogress = fields[12].Get<uint8>();
2566 data.artKit = 0;
2567
2568 uint32 go_state = fields[13].Get<uint8>();
2569 if (go_state >= MAX_GO_STATE)
2570 {
2571 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid `state` ({}) value, skip", guid, data.id, go_state);
2572 continue;
2573 }
2574 data.go_state = GOState(go_state);
2575
2576 data.spawnMask = fields[14].Get<uint8>();
2577
2578 if (!_transportMaps.count(data.mapid) && data.spawnMask & ~spawnMasks[data.mapid])
2579 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);
2580
2581 data.phaseMask = fields[15].Get<uint32>();
2582 int16 gameEvent = fields[16].Get<int8>();
2583 uint32 PoolId = fields[17].Get<uint32>();
2584
2585 if (data.rotation.x < -1.0f || data.rotation.x > 1.0f)
2586 {
2587 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationX ({}) value, skip", guid, data.id, data.rotation.x);
2588 continue;
2589 }
2590
2591 if (data.rotation.y < -1.0f || data.rotation.y > 1.0f)
2592 {
2593 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationY ({}) value, skip", guid, data.id, data.rotation.y);
2594 continue;
2595 }
2596
2597 if (data.rotation.z < -1.0f || data.rotation.z > 1.0f)
2598 {
2599 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationZ ({}) value, skip", guid, data.id, data.rotation.z);
2600 continue;
2601 }
2602
2603 if (data.rotation.w < -1.0f || data.rotation.w > 1.0f)
2604 {
2605 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationW ({}) value, skip", guid, data.id, data.rotation.w);
2606 continue;
2607 }
2608
2609 if (!MapMgr::IsValidMapCoord(data.mapid, data.posX, data.posY, data.posZ, data.orientation))
2610 {
2611 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid coordinates, skip", guid, data.id);
2612 continue;
2613 }
2614
2615 if (data.phaseMask == 0)
2616 {
2617 LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: {} Entry: {}) with `phaseMask`=0 (not visible for anyone), set to 1.", guid, data.id);
2618 data.phaseMask = 1;
2619 }
2620
2622 {
2623 uint32 zoneId = sMapMgr->GetZoneId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
2624 uint32 areaId = sMapMgr->GetAreaId(data.phaseMask, data.mapid, data.posX, data.posY, data.posZ);
2625
2627
2628 stmt->SetData(0, zoneId);
2629 stmt->SetData(1, areaId);
2630 stmt->SetData(2, guid);
2631
2632 WorldDatabase.Execute(stmt);
2633 }
2634
2635 if (gameEvent == 0 && PoolId == 0) // if not this is to be managed by GameEvent System or Pool system
2636 AddGameobjectToGrid(guid, &data);
2637 ++count;
2638 } while (result->NextRow());
2639
2640 LOG_INFO("server.loading", ">> Loaded {} Gameobjects in {} ms", (unsigned long)_gameObjectDataStore.size(), GetMSTimeDiffToNow(oldMSTime));
2641 LOG_INFO("server.loading", " ");
2642}
@ WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA
Definition: WorldDatabase.h:100
DBCStorage< GameObjectDisplayInfoEntry > sGameObjectDisplayInfoStore(GameObjectDisplayInfofmt)
#define MAX_GO_STATE
Definition: GameObjectData.h:28
GOState
Definition: GameObjectData.h:689
@ CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA
Definition: IWorld.h:156
@ GAMEOBJECT_TYPE_TRAP
Definition: SharedDefines.h:1538
uint32 ScriptId
Definition: GameObjectData.h:708
static bool IsValidMapCoord(uint32 mapid, Position const &pos)
Definition: MapMgr.h:91

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

◆ LoadGameObjectTemplate()

void ObjectMgr::LoadGameObjectTemplate ( )
7149{
7150 uint32 oldMSTime = getMSTime();
7151
7152 // 0 1 2 3 4 5 6 7
7153 QueryResult result = WorldDatabase.Query("SELECT entry, type, displayId, name, IconName, castBarCaption, unk1, size, "
7154 // 8 9 10 11 12 13 14 15 16 17 18 19 20
7155 "Data0, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11, Data12, "
7156 // 21 22 23 24 25 26 27 28 29 30 31 32 33
7157 "Data13, Data14, Data15, Data16, Data17, Data18, Data19, Data20, Data21, Data22, Data23, AIName, ScriptName "
7158 "FROM gameobject_template");
7159
7160 if (!result)
7161 {
7162 LOG_WARN("server.loading", ">> Loaded 0 gameobject definitions. DB table `gameobject_template` is empty.");
7163 LOG_INFO("server.loading", " ");
7164 return;
7165 }
7166
7167 _gameObjectTemplateStore.rehash(result->GetRowCount());
7168 uint32 count = 0;
7169 do
7170 {
7171 Field* fields = result->Fetch();
7172
7173 uint32 entry = fields[0].Get<uint32>();
7174
7176
7177 got.entry = entry;
7178 got.type = uint32(fields[1].Get<uint8>());
7179 got.displayId = fields[2].Get<uint32>();
7180 got.name = fields[3].Get<std::string>();
7181 got.IconName = fields[4].Get<std::string>();
7182 got.castBarCaption = fields[5].Get<std::string>();
7183 got.unk1 = fields[6].Get<std::string>();
7184 got.size = fields[7].Get<float>();
7185
7186 for (uint8 i = 0; i < MAX_GAMEOBJECT_DATA; ++i)
7187 got.raw.data[i] = fields[8 + i].Get<int32>(); // data1 and data6 can be -1
7188
7189 got.AIName = fields[32].Get<std::string>();
7190 got.ScriptId = GetScriptId(fields[33].Get<std::string>());
7191 got.IsForQuests = false;
7192
7193 // Checks
7194 if (!got.AIName.empty() && !sGameObjectAIRegistry->HasItem(got.AIName))
7195 {
7196 LOG_ERROR("sql.sql", "GameObject (Entry: {}) has non-registered `AIName` '{}' set, removing", got.entry, got.AIName);
7197 }
7198
7199 switch (got.type)
7200 {
7201 case GAMEOBJECT_TYPE_DOOR: //0
7202 {
7203 if (got.door.lockId)
7204 CheckGOLockId(&got, got.door.lockId, 1);
7205 CheckGONoDamageImmuneId(&got, got.door.noDamageImmune, 3);
7206 break;
7207 }
7208 case GAMEOBJECT_TYPE_BUTTON: //1
7209 {
7210 if (got.button.lockId)
7211 CheckGOLockId(&got, got.button.lockId, 1);
7212 CheckGONoDamageImmuneId(&got, got.button.noDamageImmune, 4);
7213 break;
7214 }
7216 {
7217 if (got.questgiver.lockId)
7218 CheckGOLockId(&got, got.questgiver.lockId, 0);
7219 CheckGONoDamageImmuneId(&got, got.questgiver.noDamageImmune, 5);
7220 break;
7221 }
7222 case GAMEOBJECT_TYPE_CHEST: //3
7223 {
7224 if (got.chest.lockId)
7225 CheckGOLockId(&got, got.chest.lockId, 0);
7226
7227 CheckGOConsumable(&got, got.chest.consumable, 3);
7228
7229 if (got.chest.linkedTrapId) // linked trap
7230 CheckGOLinkedTrapId(&got, got.chest.linkedTrapId, 7);
7231 break;
7232 }
7233 case GAMEOBJECT_TYPE_TRAP: //6
7234 {
7235 if (got.trap.lockId)
7236 CheckGOLockId(&got, got.trap.lockId, 0);
7237 break;
7238 }
7239 case GAMEOBJECT_TYPE_CHAIR: //7
7240 CheckAndFixGOChairHeightId(&got, got.chair.height, 1);
7241 break;
7243 {
7244 if (got.spellFocus.focusId)
7245 {
7246 if (!sSpellFocusObjectStore.LookupEntry(got.spellFocus.focusId))
7247 LOG_ERROR("sql.sql", "GameObject (Entry: {} GoType: {}) have data0={} but SpellFocus (Id: {}) not exist.",
7248 entry, got.type, got.spellFocus.focusId, got.spellFocus.focusId);
7249 }
7250
7251 if (got.spellFocus.linkedTrapId) // linked trap
7252 CheckGOLinkedTrapId(&got, got.spellFocus.linkedTrapId, 2);
7253 break;
7254 }
7255 case GAMEOBJECT_TYPE_GOOBER: //10
7256 {
7257 if (got.goober.lockId)
7258 CheckGOLockId(&got, got.goober.lockId, 0);
7259
7260 CheckGOConsumable(&got, got.goober.consumable, 3);
7261
7262 if (got.goober.pageId) // pageId
7263 {
7264 if (!GetPageText(got.goober.pageId))
7265 LOG_ERROR("sql.sql", "GameObject (Entry: {} GoType: {}) have data7={} but PageText (Entry {}) not exist.",
7266 entry, got.type, got.goober.pageId, got.goober.pageId);
7267 }
7268 CheckGONoDamageImmuneId(&got, got.goober.noDamageImmune, 11);
7269 if (got.goober.linkedTrapId) // linked trap
7270 CheckGOLinkedTrapId(&got, got.goober.linkedTrapId, 12);
7271 break;
7272 }
7274 {
7275 if (got.areadamage.lockId)
7276 CheckGOLockId(&got, got.areadamage.lockId, 0);
7277 break;
7278 }
7279 case GAMEOBJECT_TYPE_CAMERA: //13
7280 {
7281 if (got.camera.lockId)
7282 CheckGOLockId(&got, got.camera.lockId, 0);
7283 break;
7284 }
7286 {
7287 if (got.moTransport.taxiPathId)
7288 {
7289 if (got.moTransport.taxiPathId >= sTaxiPathNodesByPath.size() || sTaxiPathNodesByPath[got.moTransport.taxiPathId].empty())
7290 LOG_ERROR("sql.sql", "GameObject (Entry: {} GoType: {}) have data0={} but TaxiPath (Id: {}) not exist.",
7291 entry, got.type, got.moTransport.taxiPathId, got.moTransport.taxiPathId);
7292 }
7293 if (uint32 transportMap = got.moTransport.mapID)
7294 _transportMaps.insert(transportMap);
7295 break;
7296 }
7298 break;
7300 {
7301 // always must have spell
7302 CheckGOSpellId(&got, got.spellcaster.spellId, 0);
7303 break;
7304 }
7305 case GAMEOBJECT_TYPE_FLAGSTAND: //24
7306 {
7307 if (got.flagstand.lockId)
7308 CheckGOLockId(&got, got.flagstand.lockId, 0);
7309 CheckGONoDamageImmuneId(&got, got.flagstand.noDamageImmune, 5);
7310 break;
7311 }
7313 {
7314 if (got.fishinghole.lockId)
7315 CheckGOLockId(&got, got.fishinghole.lockId, 4);
7316 break;
7317 }
7318 case GAMEOBJECT_TYPE_FLAGDROP: //26
7319 {
7320 if (got.flagdrop.lockId)
7321 CheckGOLockId(&got, got.flagdrop.lockId, 0);
7322 CheckGONoDamageImmuneId(&got, got.flagdrop.noDamageImmune, 3);
7323 break;
7324 }
7326 CheckAndFixGOChairHeightId(&got, got.barberChair.chairheight, 0);
7327 break;
7328 }
7329
7330 ++count;
7331 } while (result->NextRow());
7332
7333 LOG_INFO("server.loading", ">> Loaded {} Game Object Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7334 LOG_INFO("server.loading", " ");
7335}
#define sGameObjectAIRegistry
Definition: GameObjectAIFactory.h:49
DBCStorage< SpellFocusObjectEntry > sSpellFocusObjectStore(SpellFocusObjectfmt)
void CheckGONoDamageImmuneId(GameObjectTemplate *goTemplate, uint32 dataN, uint32 N)
Definition: ObjectMgr.cpp:7129
void CheckGOSpellId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition: ObjectMgr.cpp:7108
void CheckAndFixGOChairHeightId(GameObjectTemplate const *goInfo, uint32 const &dataN, uint32 N)
Definition: ObjectMgr.cpp:7117
void CheckGOConsumable(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition: ObjectMgr.cpp:7138
void CheckGOLinkedTrapId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition: ObjectMgr.cpp:7098
void CheckGOLockId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
Definition: ObjectMgr.cpp:7089
@ GAMEOBJECT_TYPE_CAMERA
Definition: SharedDefines.h:1545
@ GAMEOBJECT_TYPE_BUTTON
Definition: SharedDefines.h:1533
@ GAMEOBJECT_TYPE_MO_TRANSPORT
Definition: SharedDefines.h:1547
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition: SharedDefines.h:1550
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition: SharedDefines.h:1557
@ GAMEOBJECT_TYPE_FLAGDROP
Definition: SharedDefines.h:1558
@ GAMEOBJECT_TYPE_SPELLCASTER
Definition: SharedDefines.h:1554
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition: SharedDefines.h:1556
@ GAMEOBJECT_TYPE_CHAIR
Definition: SharedDefines.h:1539
@ GAMEOBJECT_TYPE_AREADAMAGE
Definition: SharedDefines.h:1544
@ GAMEOBJECT_TYPE_BARBER_CHAIR
Definition: SharedDefines.h:1564
@ GAMEOBJECT_TYPE_DOOR
Definition: SharedDefines.h:1532
#define MAX_GAMEOBJECT_DATA
Definition: SharedDefines.h:1571
PageText const * GetPageText(uint32 pageEntry)
Definition: ObjectMgr.cpp:5788

References _gameObjectTemplateStore, _transportMaps, CheckAndFixGOChairHeightId(), CheckGOConsumable(), CheckGOLinkedTrapId(), CheckGOLockId(), CheckGONoDamageImmuneId(), CheckGOSpellId(), 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 ( )
7338{
7339 uint32 oldMSTime = getMSTime();
7340
7341 // 0 1 2 3 4 5 6 7 8
7342 QueryResult result = WorldDatabase.Query("SELECT entry, faction, flags, mingold, maxgold, artkit0, artkit1, artkit2, artkit3 FROM gameobject_template_addon");
7343
7344 if (!result)
7345 {
7346 LOG_WARN("server.loading", ">> Loaded 0 gameobject template addon definitions. DB table `gameobject_template_addon` is empty.");
7347 LOG_INFO("server.loading", " ");
7348 return;
7349 }
7350
7351 uint32 count = 0;
7352 do
7353 {
7354 Field* fields = result->Fetch();
7355
7356 uint32 entry = fields[0].Get<uint32>();
7357
7358 GameObjectTemplate const* got = sObjectMgr->GetGameObjectTemplate(entry);
7359 if (!got)
7360 {
7361 LOG_ERROR("sql.sql",
7362 "GameObject template (Entry: {}) does not exist but has a record in `gameobject_template_addon`",
7363 entry);
7364 continue;
7365 }
7366
7368 gameObjectAddon.faction = uint32(fields[1].Get<uint16>());
7369 gameObjectAddon.flags = fields[2].Get<uint32>();
7370 gameObjectAddon.mingold = fields[3].Get<uint32>();
7371 gameObjectAddon.maxgold = fields[4].Get<uint32>();
7372
7373 for (uint32 i = 0; i < gameObjectAddon.artKits.size(); i++)
7374 {
7375 uint32 artKitID = fields[5 + i].Get<uint32>();
7376 if (!artKitID)
7377 continue;
7378
7379 if (!sGameObjectArtKitStore.LookupEntry(artKitID))
7380 {
7381 LOG_ERROR("sql.sql", "GameObject (Entry: {}) has invalid `artkit{}` {} defined, set to zero instead.", entry, i, artKitID);
7382 continue;
7383 }
7384
7385 gameObjectAddon.artKits[i] = artKitID;
7386 }
7387
7388 // checks
7389 if (gameObjectAddon.faction && !sFactionTemplateStore.LookupEntry(gameObjectAddon.faction))
7390 LOG_ERROR("sql.sql",
7391 "GameObject (Entry: {}) has invalid faction ({}) defined in `gameobject_template_addon`.",
7392 entry, gameObjectAddon.faction);
7393
7394 if (gameObjectAddon.maxgold > 0)
7395 {
7396 switch (got->type)
7397 {
7400 break;
7401 default:
7402 LOG_ERROR("sql.sql",
7403 "GameObject (Entry {} GoType: {}) cannot be looted but has maxgold set in `gameobject_template_addon`.",
7404 entry, got->type);
7405 break;
7406 }
7407 }
7408
7409 ++count;
7410 } while (result->NextRow());
7411
7412 LOG_INFO("server.loading", ">> Loaded {} Game Object Template Addons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7413 LOG_INFO("server.loading", " ");
7414}
DBCStorage< GameObjectArtKitEntry > sGameObjectArtKitStore(GameObjectArtKitfmt)
Definition: GameObjectData.h:665
uint32 mingold
Definition: GameObjectData.h:669
uint32 flags
Definition: GameObjectData.h:668
uint32 faction
Definition: GameObjectData.h:667
std::array< uint32, 4 > artKits
Definition: GameObjectData.h:671
uint32 maxgold
Definition: GameObjectData.h:670

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

◆ LoadGameTele()

void ObjectMgr::LoadGameTele ( )
8765{
8766 uint32 oldMSTime = getMSTime();
8767
8768 _gameTeleStore.clear(); // for reload case
8769
8770 // 0 1 2 3 4 5 6
8771 QueryResult result = WorldDatabase.Query("SELECT id, position_x, position_y, position_z, orientation, map, name FROM game_tele");
8772
8773 if (!result)
8774 {
8775 LOG_WARN("server.loading", ">> Loaded 0 GameTeleports. DB table `game_tele` is empty!");
8776 LOG_INFO("server.loading", " ");
8777 return;
8778 }
8779
8780 uint32 count = 0;
8781
8782 do
8783 {
8784 Field* fields = result->Fetch();
8785
8786 uint32 id = fields[0].Get<uint32>();
8787
8788 GameTele gt;
8789
8790 gt.position_x = fields[1].Get<float>();
8791 gt.position_y = fields[2].Get<float>();
8792 gt.position_z = fields[3].Get<float>();
8793 gt.orientation = fields[4].Get<float>();
8794 gt.mapId = fields[5].Get<uint16>();
8795 gt.name = fields[6].Get<std::string>();
8796
8797 if (!MapMgr::IsValidMapCoord(gt.mapId, gt.position_x, gt.position_y, gt.position_z, gt.orientation))
8798 {
8799 LOG_ERROR("sql.sql", "Wrong position for id {} (name: {}) in `game_tele` table, ignoring.", id, gt.name);
8800 continue;
8801 }
8802
8803 if (!Utf8toWStr(gt.name, gt.wnameLow))
8804 {
8805 LOG_ERROR("sql.sql", "Wrong UTF8 name for id {} in `game_tele` table, ignoring.", id);
8806 continue;
8807 }
8808
8809 wstrToLower(gt.wnameLow);
8810
8811 _gameTeleStore[id] = gt;
8812
8813 ++count;
8814 } while (result->NextRow());
8815
8816 LOG_INFO("server.loading", ">> Loaded {} GameTeleports in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8817 LOG_INFO("server.loading", " ");
8818}
float position_x
Definition: ObjectMgr.h:136

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

◆ LoadGossipMenu()

void ObjectMgr::LoadGossipMenu ( )
9181{
9182 uint32 oldMSTime = getMSTime();
9183
9184 _gossipMenusStore.clear();
9185
9186 QueryResult result = WorldDatabase.Query("SELECT MenuID, TextID FROM gossip_menu");
9187
9188 if (!result)
9189 {
9190 LOG_WARN("server.loading", ">> Loaded 0 gossip_menu entries. DB table `gossip_menu` is empty!");
9191 LOG_INFO("server.loading", " ");
9192 return;
9193 }
9194
9195 do
9196 {
9197 Field* fields = result->Fetch();
9198
9199 GossipMenus gMenu;
9200
9201 gMenu.MenuID = fields[0].Get<uint16>();
9202 gMenu.TextID = fields[1].Get<uint32>();
9203
9204 if (!GetGossipText(gMenu.TextID))
9205 {
9206 LOG_ERROR("sql.sql", "Table gossip_menu entry {} are using non-existing TextID {}", gMenu.MenuID, gMenu.TextID);
9207 continue;
9208 }
9209
9210 _gossipMenusStore.insert(GossipMenusContainer::value_type(gMenu.MenuID, gMenu));
9211 } while (result->NextRow());
9212
9213 LOG_INFO("server.loading", ">> Loaded {} gossip_menu entries in {} ms", (uint32)_gossipMenusStore.size(), GetMSTimeDiffToNow(oldMSTime));
9214 LOG_INFO("server.loading", " ");
9215}
Definition: ObjectMgr.h:629
uint32 TextID
Definition: ObjectMgr.h:631
uint32 MenuID
Definition: ObjectMgr.h:630
GossipText const * GetGossipText(uint32 Text_ID) const
Definition: ObjectMgr.cpp:5962

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

◆ LoadGossipMenuItems()

void ObjectMgr::LoadGossipMenuItems ( )
9218{
9219 uint32 oldMSTime = getMSTime();
9220
9221 _gossipMenuItemsStore.clear();
9222
9223 QueryResult result = WorldDatabase.Query(
9224 // 0 1 2 3 4 5 6 7 8 9 10 11 12
9225 "SELECT MenuID, OptionID, OptionIcon, OptionText, OptionBroadcastTextID, OptionType, OptionNpcFlag, ActionMenuID, ActionPoiID, BoxCoded, BoxMoney, BoxText, BoxBroadcastTextID "
9226 "FROM gossip_menu_option ORDER BY MenuID, OptionID");
9227
9228 if (!result)
9229 {
9230 LOG_WARN("server.loading", ">> Loaded 0 gossip_menu_option IDs. DB table `gossip_menu_option` is empty!");
9231 LOG_INFO("server.loading", " ");
9232 return;
9233 }
9234
9235 do
9236 {
9237 Field* fields = result->Fetch();
9238
9239 GossipMenuItems gMenuItem;
9240
9241 gMenuItem.MenuID = fields[0].Get<uint16>();
9242 gMenuItem.OptionID = fields[1].Get<uint16>();
9243 gMenuItem.OptionIcon = fields[2].Get<uint32>();
9244 gMenuItem.OptionText = fields[3].Get<std::string>();
9245 gMenuItem.OptionBroadcastTextID = fields[4].Get<uint32>();
9246 gMenuItem.OptionType = fields[5].Get<uint8>();
9247 gMenuItem.OptionNpcFlag = fields[6].Get<uint32>();
9248 gMenuItem.ActionMenuID = fields[7].Get<uint32>();
9249 gMenuItem.ActionPoiID = fields[8].Get<uint32>();
9250 gMenuItem.BoxCoded = fields[9].Get<bool>();
9251 gMenuItem.BoxMoney = fields[10].Get<uint32>();
9252 gMenuItem.BoxText = fields[11].Get<std::string>();
9253 gMenuItem.BoxBroadcastTextID = fields[12].Get<uint32>();
9254
9255 if (gMenuItem.OptionIcon >= GOSSIP_ICON_MAX)
9256 {
9257 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);
9258 gMenuItem.OptionIcon = GOSSIP_ICON_CHAT;
9259 }
9260
9262 {
9263 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} has non-existing or incompatible OptionBroadcastTextID {}, ignoring.", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.OptionBroadcastTextID);
9264 gMenuItem.OptionBroadcastTextID = 0;
9265 }
9266
9267 if (gMenuItem.OptionType >= GOSSIP_OPTION_MAX)
9268 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);
9269
9270 if (gMenuItem.ActionPoiID && !GetPointOfInterest(gMenuItem.ActionPoiID))
9271 {
9272 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} use non-existing ActionPoiID {}, ignoring", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.ActionPoiID);
9273 gMenuItem.ActionPoiID = 0;
9274 }
9275
9276 if (gMenuItem.BoxBroadcastTextID && !GetBroadcastText(gMenuItem.BoxBroadcastTextID))
9277 {
9278 LOG_ERROR("sql.sql", "Table `gossip_menu_option` for menu {}, id {} has non-existing or incompatible BoxBroadcastTextID {}, ignoring.", gMenuItem.MenuID, gMenuItem.OptionID, gMenuItem.BoxBroadcastTextID);
9279 gMenuItem.BoxBroadcastTextID = 0;
9280 }
9281
9282 _gossipMenuItemsStore.insert(GossipMenuItemsContainer::value_type(gMenuItem.MenuID, gMenuItem));
9283 } while (result->NextRow());
9284
9285 LOG_INFO("server.loading", ">> Loaded {} gossip_menu_option entries in {} ms", uint32(_gossipMenuItemsStore.size()), GetMSTimeDiffToNow(oldMSTime));
9286 LOG_INFO("server.loading", " ");
9287}
@ GOSSIP_ICON_CHAT
Definition: GossipDef.h:60
@ GOSSIP_ICON_MAX
Definition: GossipDef.h:81
@ GOSSIP_OPTION_MAX
Definition: GossipDef.h:55
Definition: ObjectMgr.h:611
uint8 OptionIcon
Definition: ObjectMgr.h:614
uint32 BoxBroadcastTextID
Definition: ObjectMgr.h:625
std::string OptionText
Definition: ObjectMgr.h:615
uint32 ActionMenuID
Definition: ObjectMgr.h:619
bool BoxCoded
Definition: ObjectMgr.h:621
uint32 MenuID
Definition: ObjectMgr.h:612
uint32 OptionNpcFlag
Definition: ObjectMgr.h:618
uint32 ActionPoiID
Definition: ObjectMgr.h:620
uint32 BoxMoney
Definition: ObjectMgr.h:622
std::string BoxText
Definition: ObjectMgr.h:623
uint32 OptionID
Definition: ObjectMgr.h:613
uint32 OptionType
Definition: ObjectMgr.h:617
uint32 OptionBroadcastTextID
Definition: ObjectMgr.h:616
PointOfInterest const * GetPointOfInterest(uint32 id) const
Definition: ObjectMgr.h:925
BroadcastText const * GetBroadcastText(uint32 id) const
Definition: ObjectMgr.h:1192

References _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, and WorldDatabase.

◆ LoadGossipMenuItemsLocales()

void ObjectMgr::LoadGossipMenuItemsLocales ( )
479{
480 uint32 oldMSTime = getMSTime();
481
482 _gossipMenuItemsLocaleStore.clear(); // need for reload case
483
484 // 0 1 2 3 4
485 QueryResult result = WorldDatabase.Query("SELECT MenuID, OptionID, Locale, OptionText, BoxText FROM gossip_menu_option_locale");
486
487 if (!result)
488 return;
489
490 do
491 {
492 Field* fields = result->Fetch();
493
494 uint16 MenuID = fields[0].Get<uint16>();
495 uint16 OptionID = fields[1].Get<uint16>();
496
497 LocaleConstant locale = GetLocaleByName(fields[2].Get<std::string>());
498 if (locale == LOCALE_enUS)
499 continue;
500
502 AddLocaleString(fields[3].Get<std::string>(), locale, data.OptionText);
503 AddLocaleString(fields[4].Get<std::string>(), locale, data.BoxText);
504 } while (result->NextRow());
505
506 LOG_INFO("server.loading", ">> Loaded {} Gossip Menu Option Locale Strings in {} ms", (uint32)_gossipMenuItemsLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
507}
Definition: CreatureData.h:338
std::vector< std::string > BoxText
Definition: CreatureData.h:340
std::vector< std::string > OptionText
Definition: CreatureData.h:339

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

◆ LoadGossipText()

void ObjectMgr::LoadGossipText ( )
5971{
5972 uint32 oldMSTime = getMSTime();
5973
5974 QueryResult result = WorldDatabase.Query("SELECT ID, "
5975 "text0_0, text0_1, BroadcastTextID0, lang0, Probability0, em0_0, em0_1, em0_2, em0_3, em0_4, em0_5, "
5976 "text1_0, text1_1, BroadcastTextID1, lang1, Probability1, em1_0, em1_1, em1_2, em1_3, em1_4, em1_5, "
5977 "text2_0, text2_1, BroadcastTextID2, lang2, Probability2, em2_0, em2_1, em2_2, em2_3, em2_4, em2_5, "
5978 "text3_0, text3_1, BroadcastTextID3, lang3, Probability3, em3_0, em3_1, em3_2, em3_3, em3_4, em3_5, "
5979 "text4_0, text4_1, BroadcastTextID4, lang4, Probability4, em4_0, em4_1, em4_2, em4_3, em4_4, em4_5, "
5980 "text5_0, text5_1, BroadcastTextID5, lang5, Probability5, em5_0, em5_1, em5_2, em5_3, em5_4, em5_5, "
5981 "text6_0, text6_1, BroadcastTextID6, lang6, Probability6, em6_0, em6_1, em6_2, em6_3, em6_4, em6_5, "
5982 "text7_0, text7_1, BroadcastTextID7, lang7, Probability7, em7_0, em7_1, em7_2, em7_3, em7_4, em7_5 "
5983 "FROM npc_text");
5984
5985 if (!result)
5986 {
5987 LOG_WARN("server.loading", ">> Loaded 0 npc texts, table is empty!");
5988 LOG_INFO("server.loading", " ");
5989 return;
5990 }
5991
5992 _gossipTextStore.rehash(result->GetRowCount());
5993
5994 uint32 count = 0;
5995 uint8 cic;
5996
5997 do
5998 {
5999 cic = 0;
6000
6001 Field* fields = result->Fetch();
6002
6003 uint32 id = fields[cic++].Get<uint32>();
6004 if (!id)
6005 {
6006 LOG_ERROR("sql.sql", "Table `npc_text` has record wit reserved id 0, ignore.");
6007 continue;
6008 }
6009
6010 GossipText& gText = _gossipTextStore[id];
6011
6012 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
6013 {
6014 gText.Options[i].Text_0 = fields[cic++].Get<std::string>();
6015 gText.Options[i].Text_1 = fields[cic++].Get<std::string>();
6016 gText.Options[i].BroadcastTextID = fields[cic++].Get<uint32>();
6017 gText.Options[i].Language = fields[cic++].Get<uint8>();
6018 gText.Options[i].Probability = fields[cic++].Get<float>();
6019
6020 for (uint8 j = 0; j < MAX_GOSSIP_TEXT_EMOTES; ++j)
6021 {
6022 gText.Options[i].Emotes[j]._Delay = fields[cic++].Get<uint16>();
6023 gText.Options[i].Emotes[j]._Emote = fields[cic++].Get<uint16>();
6024 }
6025 }
6026
6027 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; i++)
6028 {
6029 if (gText.Options[i].BroadcastTextID)
6030 {
6032 {
6033 LOG_ERROR("sql.sql", "GossipText (Id: {}) in table `npc_text` has non-existing or incompatible BroadcastTextID{} {}.", id, i, gText.Options[i].BroadcastTextID);
6034 gText.Options[i].BroadcastTextID = 0;
6035 }
6036 }
6037 }
6038
6039 count++;
6040 } while (result->NextRow());
6041
6042 LOG_INFO("server.loading", ">> Loaded {} Npc Texts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6043 LOG_INFO("server.loading", " ");
6044}
#define MAX_GOSSIP_TEXT_OPTIONS
Definition: NPCHandler.h:42
#define MAX_GOSSIP_TEXT_EMOTES
Definition: NPCHandler.h:30
uint32 _Emote
Definition: NPCHandler.h:26
uint32 _Delay
Definition: NPCHandler.h:27
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

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 ( )
5878{
5879 uint32 oldMSTime = getMSTime();
5880
5881 // 0 1 2 3
5882 QueryResult result = WorldDatabase.Query("SELECT entry, creditType, creditEntry, lastEncounterDungeon FROM instance_encounters");
5883 if (!result)
5884 {
5885 LOG_WARN("server.loading", ">> Loaded 0 instance encounters, table is empty!");
5886 LOG_INFO("server.loading", " ");
5887 return;
5888 }
5889
5890 uint32 count = 0;
5891 std::map<uint32, DungeonEncounterEntry const*> dungeonLastBosses;
5892 do
5893 {
5894 Field* fields = result->Fetch();
5895 uint32 entry = fields[0].Get<uint32>();
5896 uint8 creditType = fields[1].Get<uint8>();
5897 uint32 creditEntry = fields[2].Get<uint32>();
5898 uint32 lastEncounterDungeon = fields[3].Get<uint16>();
5899 DungeonEncounterEntry const* dungeonEncounter = sDungeonEncounterStore.LookupEntry(entry);
5900 if (!dungeonEncounter)
5901 {
5902 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid encounter id {}, skipped!", entry);
5903 continue;
5904 }
5905
5906 if (lastEncounterDungeon && !sLFGMgr->GetLFGDungeonEntry(lastEncounterDungeon))
5907 {
5908 LOG_ERROR("sql.sql", "Table `instance_encounters` has an encounter {} ({}) marked as final for invalid dungeon id {}, skipped!", entry, dungeonEncounter->encounterName[0], lastEncounterDungeon);
5909 continue;
5910 }
5911
5912 std::map<uint32, DungeonEncounterEntry const*>::const_iterator itr = dungeonLastBosses.find(lastEncounterDungeon);
5913 if (lastEncounterDungeon)
5914 {
5915 if (itr != dungeonLastBosses.end())
5916 {
5917 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]);
5918 continue;
5919 }
5920
5921 dungeonLastBosses[lastEncounterDungeon] = dungeonEncounter;
5922 }
5923
5924 switch (creditType)
5925 {
5927 {
5928 CreatureTemplate const* creatureInfo = GetCreatureTemplate(creditEntry);
5929 if (!creatureInfo)
5930 {
5931 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid creature (entry {}) linked to the encounter {} ({}), skipped!", creditEntry, entry, dungeonEncounter->encounterName[0]);
5932 continue;
5933 }
5934 const_cast<CreatureTemplate*>(creatureInfo)->flags_extra |= CREATURE_FLAG_EXTRA_DUNGEON_BOSS;
5935 break;
5936 }
5938 {
5939 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(creditEntry);
5940 if (!spellInfo)
5941 {
5942 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid spell (entry {}) linked to the encounter {} ({}), skipped!", creditEntry, entry, dungeonEncounter->encounterName[0]);
5943 continue;
5944 }
5945 const_cast<SpellInfo*>(spellInfo)->AttributesCu |= SPELL_ATTR0_CU_ENCOUNTER_REWARD;
5946 break;
5947 }
5948 default:
5949 LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid credit type ({}) for encounter {} ({}), skipped!", creditType, entry, dungeonEncounter->encounterName[0]);
5950 continue;
5951 }
5952
5953 DungeonEncounterList& encounters = _dungeonEncounterStore[MAKE_PAIR32(dungeonEncounter->mapId, dungeonEncounter->difficulty)];
5954 encounters.push_back(new DungeonEncounter(dungeonEncounter, EncounterCreditType(creditType), creditEntry, lastEncounterDungeon));
5955 ++count;
5956 } while (result->NextRow());
5957
5958 LOG_INFO("server.loading", ">> Loaded {} Instance Encounters in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
5959 LOG_INFO("server.loading", " ");
5960}
DBCStorage< DungeonEncounterEntry > sDungeonEncounterStore(DungeonEncounterfmt)
#define sLFGMgr
Definition: LFGMgr.h:638
@ CREATURE_FLAG_EXTRA_DUNGEON_BOSS
Definition: CreatureData.h:77
std::list< DungeonEncounter const * > DungeonEncounterList
Definition: ObjectMgr.h:719
EncounterCreditType
Definition: Map.h:306
@ ENCOUNTER_CREDIT_KILL_CREATURE
Definition: Map.h:307
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition: Map.h:308
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition: SpellInfo.h:206
Definition: ObjectMgr.h:709
Definition: DBCStructure.h:857

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.

◆ LoadInstanceSavedGameobjectStateData()

void ObjectMgr::LoadInstanceSavedGameobjectStateData ( )
10103{
10104 uint32 oldMSTime = getMSTime();
10105
10107 PreparedQueryResult result = CharacterDatabase.Query(stmt);
10108
10109 if (!result)
10110 {
10111 // There's no gameobject with this GUID saved on the DB
10112 LOG_INFO("sql.sql", ">> Loaded 0 Instance saved gameobject state data. DB table `instance_saved_go_state_data` is empty.");
10113 return;
10114 }
10115
10116 Field* fields;
10117 uint32 count = 0;
10118 do
10119 {
10120 fields = result->Fetch();
10121 GameobjectInstanceSavedStateList.push_back({ fields[0].Get<uint32>(), fields[1].Get<uint32>(), fields[2].Get<unsigned short>() });
10122 count++;
10123 } while (result->NextRow());
10124
10125 LOG_INFO("server.loading", ">> Loaded {} instance saved gameobject state data in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10126 LOG_INFO("server.loading", " ");
10127}
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition: DatabaseEnvFwd.h:46
@ CHAR_SELECT_INSTANCE_SAVED_DATA
Definition: CharacterDatabase.h:519

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

◆ LoadInstanceTemplate()

void ObjectMgr::LoadInstanceTemplate ( )
5827{
5828 uint32 oldMSTime = getMSTime();
5829
5830 // 0 1 2 4
5831 QueryResult result = WorldDatabase.Query("SELECT map, parent, script, allowMount FROM instance_template");
5832
5833 if (!result)
5834 {
5835 LOG_WARN("server.loading", ">> Loaded 0 instance templates. DB table `page_text` is empty!");
5836 LOG_INFO("server.loading", " ");
5837 return;
5838 }
5839
5840 uint32 count = 0;
5841 do
5842 {
5843 Field* fields = result->Fetch();
5844
5845 uint16 mapID = fields[0].Get<uint16>();
5846
5847 if (!MapMgr::IsValidMAP(mapID, true))
5848 {
5849 LOG_ERROR("sql.sql", "ObjectMgr::LoadInstanceTemplate: bad mapid {} for template!", mapID);
5850 continue;
5851 }
5852
5853 InstanceTemplate instanceTemplate;
5854
5855 instanceTemplate.AllowMount = fields[3].Get<bool>();
5856 instanceTemplate.Parent = uint32(fields[1].Get<uint16>());
5857 instanceTemplate.ScriptId = sObjectMgr->GetScriptId(fields[2].Get<std::string>());
5858
5859 _instanceTemplateStore[mapID] = instanceTemplate;
5860
5861 ++count;
5862 } while (result->NextRow());
5863
5864 LOG_INFO("server.loading", ">> Loaded {} Instance Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
5865 LOG_INFO("server.loading", " ");
5866}
bool AllowMount
Definition: Map.h:276
uint32 ScriptId
Definition: Map.h:275
static bool IsValidMAP(uint32 mapid, bool startUp)
Definition: MapMgr.cpp:310

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

◆ LoadItemLocales()

void ObjectMgr::LoadItemLocales ( )
2673{
2674 uint32 oldMSTime = getMSTime();
2675
2676 _itemLocaleStore.clear(); // need for reload case
2677
2678 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Name, Description FROM item_template_locale");
2679 if (!result)
2680 return;
2681
2682 do
2683 {
2684 Field* fields = result->Fetch();
2685
2686 uint32 ID = fields[0].Get<uint32>();
2687
2688 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
2689 if (locale == LOCALE_enUS)
2690 continue;
2691
2692 ItemLocale& data = _itemLocaleStore[ID];
2693 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
2694 AddLocaleString(fields[3].Get<std::string>(), locale, data.Description);
2695 } while (result->NextRow());
2696
2697 LOG_INFO("server.loading", ">> Loaded {} Item Locale Strings in {} ms", (uint32)_itemLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
2698}
Definition: ItemTemplate.h:841
std::vector< std::string > Description
Definition: ItemTemplate.h:843
std::vector< std::string > Name
Definition: ItemTemplate.h:842

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

◆ LoadItemSetNameLocales()

void ObjectMgr::LoadItemSetNameLocales ( )
3293{
3294 uint32 oldMSTime = getMSTime();
3295
3296 _itemSetNameLocaleStore.clear(); // need for reload case
3297
3298 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Name FROM item_set_names_locale");
3299
3300 if (!result)
3301 return;
3302
3303 do
3304 {
3305 Field* fields = result->Fetch();
3306
3307 uint32 ID = fields[0].Get<uint32>();
3308
3309 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
3310 if (locale == LOCALE_enUS)
3311 continue;
3312
3314 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
3315 } while (result->NextRow());
3316
3317 LOG_INFO("server.loading", ">> Loaded {} Item Set Name Locale Strings in {} ms", uint32(_itemSetNameLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime));
3318}
Definition: ItemTemplate.h:853
std::vector< std::string > Name
Definition: ItemTemplate.h:854

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

◆ LoadItemSetNames()

void ObjectMgr::LoadItemSetNames ( )
3321{
3322 uint32 oldMSTime = getMSTime();
3323
3324 _itemSetNameStore.clear(); // needed for reload case
3325
3326 std::set<uint32> itemSetItems;
3327
3328 // fill item set member ids
3329 for (uint32 entryId = 0; entryId < sItemSetStore.GetNumRows(); ++entryId)
3330 {
3331 ItemSetEntry const* setEntry = sItemSetStore.LookupEntry(entryId);
3332 if (!setEntry)
3333 continue;
3334
3335 for (uint32 i = 0; i < MAX_ITEM_SET_ITEMS; ++i)
3336 if (setEntry->itemId[i])
3337 itemSetItems.insert(setEntry->itemId[i]);
3338 }
3339
3340 // 0 1 2
3341 QueryResult result = WorldDatabase.Query("SELECT `entry`, `name`, `InventoryType` FROM `item_set_names`");
3342
3343 if (!result)
3344 {
3345 LOG_WARN("server.loading", ">> Loaded 0 item set names. DB table `item_set_names` is empty.");
3346 LOG_INFO("server.loading", " ");
3347 return;
3348 }
3349
3350 _itemSetNameStore.rehash(result->GetRowCount());
3351 uint32 count = 0;
3352
3353 do
3354 {
3355 Field* fields = result->Fetch();
3356
3357 uint32 entry = fields[0].Get<uint32>();
3358 if (itemSetItems.find(entry) == itemSetItems.end())
3359 {
3360 LOG_ERROR("sql.sql", "Item set name (Entry: {}) not found in ItemSet.dbc, data useless.", entry);
3361 continue;
3362 }
3363
3364 ItemSetNameEntry& data = _itemSetNameStore[entry];
3365 data.name = fields[1].Get<std::string>();
3366
3367 uint32 invType = fields[2].Get<uint8>();
3368 if (invType >= MAX_INVTYPE)
3369 {
3370 LOG_ERROR("sql.sql", "Item set name (Entry: {}) has wrong InventoryType value ({})", entry, invType);
3371 invType = INVTYPE_NON_EQUIP;
3372 }
3373
3374 data.InventoryType = invType;
3375 itemSetItems.erase(entry);
3376 ++count;
3377 } while (result->NextRow());
3378
3379 if (!itemSetItems.empty())
3380 {
3381 ItemTemplate const* pProto;
3382 for (std::set<uint32>::iterator itr = itemSetItems.begin(); itr != itemSetItems.end(); ++itr)
3383 {
3384 uint32 entry = *itr;
3385 // add data from item_template if available
3386 pProto = sObjectMgr->GetItemTemplate(entry);
3387 if (pProto)
3388 {
3389 LOG_ERROR("sql.sql", "Item set part (Entry: {}) does not have entry in `item_set_names`, adding data from `item_template`.", entry);
3390 ItemSetNameEntry& data = _itemSetNameStore[entry];
3391 data.name = pProto->Name1;
3392 data.InventoryType = pProto->InventoryType;
3393 ++count;
3394 }
3395 else
3396 LOG_ERROR("sql.sql", "Item set part (Entry: {}) does not have entry in `item_set_names`, set will not display properly.", entry);
3397 }
3398 }
3399
3400 LOG_INFO("server.loading", ">> Loaded {} Item Set Names in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3401 LOG_INFO("server.loading", " ");
3402}
DBCStorage< ItemSetEntry > sItemSetStore(ItemSetEntryfmt)
@ INVTYPE_NON_EQUIP
Definition: ItemTemplate.h:265
#define MAX_INVTYPE
Definition: ItemTemplate.h:296
#define MAX_ITEM_SET_ITEMS
Definition: DBCStructure.h:1207
std::string Name1
Definition: ItemTemplate.h:633
Definition: ItemTemplate.h:847
uint32 InventoryType
Definition: ItemTemplate.h:849
std::string name
Definition: ItemTemplate.h:848
Definition: DBCStructure.h:1211
uint32 itemId[MAX_ITEM_SET_ITEMS]
Definition: DBCStructure.h:1215

References _itemSetNameStore, Field::Get(), 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, sObjectMgr, and WorldDatabase.

◆ LoadItemTemplates()

void ObjectMgr::LoadItemTemplates ( )
2701{
2702 uint32 oldMSTime = getMSTime();
2703
2704 // 0 1 2 3 4 5 6 7 8 9 10 11 12
2705 QueryResult result = WorldDatabase.Query("SELECT entry, class, subclass, SoundOverrideSubclass, name, displayid, Quality, Flags, FlagsExtra, BuyCount, BuyPrice, SellPrice, InventoryType, "
2706 // 13 14 15 16 17 18 19 20
2707 "AllowableClass, AllowableRace, ItemLevel, RequiredLevel, RequiredSkill, RequiredSkillRank, requiredspell, requiredhonorrank, "
2708 // 21 22 23 24 25 26 27 28
2709 "RequiredCityRank, RequiredReputationFaction, RequiredReputationRank, maxcount, stackable, ContainerSlots, StatsCount, stat_type1, "
2710 // 29 30 31 32 33 34 35 36 37 38
2711 "stat_value1, stat_type2, stat_value2, stat_type3, stat_value3, stat_type4, stat_value4, stat_type5, stat_value5, stat_type6, "
2712 // 39 40 41 42 43 44 45 46 47
2713 "stat_value6, stat_type7, stat_value7, stat_type8, stat_value8, stat_type9, stat_value9, stat_type10, stat_value10, "
2714 // 48 49 50 51 52 53 54 55 56 57 58
2715 "ScalingStatDistribution, ScalingStatValue, dmg_min1, dmg_max1, dmg_type1, dmg_min2, dmg_max2, dmg_type2, armor, holy_res, fire_res, "
2716 // 59 60 61 62 63 64 65 66 67 68
2717 "nature_res, frost_res, shadow_res, arcane_res, delay, ammo_type, RangedModRange, spellid_1, spelltrigger_1, spellcharges_1, "
2718 // 69 70 71 72 73 74 75
2719 "spellppmRate_1, spellcooldown_1, spellcategory_1, spellcategorycooldown_1, spellid_2, spelltrigger_2, spellcharges_2, "
2720 // 76 77 78 79 80 81 82
2721 "spellppmRate_2, spellcooldown_2, spellcategory_2, spellcategorycooldown_2, spellid_3, spelltrigger_3, spellcharges_3, "
2722 // 83 84 85 86 87 88 89
2723 "spellppmRate_3, spellcooldown_3, spellcategory_3, spellcategorycooldown_3, spellid_4, spelltrigger_4, spellcharges_4, "
2724 // 90 91 92 93 94 95 96
2725 "spellppmRate_4, spellcooldown_4, spellcategory_4, spellcategorycooldown_4, spellid_5, spelltrigger_5, spellcharges_5, "
2726 // 97 98 99 100 101 102 103 104 105
2727 "spellppmRate_5, spellcooldown_5, spellcategory_5, spellcategorycooldown_5, bonding, description, PageText, LanguageID, PageMaterial, "
2728 // 106 107 108 109 110 111 112 113 114 115 116 117
2729 "startquest, lockid, Material, sheath, RandomProperty, RandomSuffix, block, itemset, MaxDurability, area, Map, BagFamily, "
2730 // 118 119 120 121 122 123 124 125
2731 "TotemCategory, socketColor_1, socketContent_1, socketColor_2, socketContent_2, socketColor_3, socketContent_3, socketBonus, "
2732 // 126 127 128 129 130 131 132 133
2733 "GemProperties, RequiredDisenchantSkill, ArmorDamageModifier, duration, ItemLimitCategory, HolidayId, ScriptName, DisenchantID, "
2734 // 134 135 136
2735 "FoodType, minMoneyLoot, maxMoneyLoot, flagsCustom FROM item_template");
2736
2737 if (!result)
2738 {
2739 LOG_WARN("server.loading", ">> Loaded 0 item templates. DB table `item_template` is empty.");
2740 LOG_INFO("server.loading", " ");
2741 return;
2742 }
2743
2744 _itemTemplateStore.rehash(result->GetRowCount());
2745 uint32 count = 0;
2746
2747 do
2748 {
2749 Field* fields = result->Fetch();
2750
2751 uint32 entry = fields[0].Get<uint32>();
2752
2753 ItemTemplate& itemTemplate = _itemTemplateStore[entry];
2754
2755 itemTemplate.ItemId = entry;
2756 itemTemplate.Class = uint32(fields[1].Get<uint8>());
2757 itemTemplate.SubClass = uint32(fields[2].Get<uint8>());
2758 itemTemplate.SoundOverrideSubclass = int32(fields[3].Get<int8>());
2759 itemTemplate.Name1 = fields[4].Get<std::string>();
2760 itemTemplate.DisplayInfoID = fields[5].Get<uint32>();
2761 itemTemplate.Quality = uint32(fields[6].Get<uint8>());
2762 itemTemplate.Flags = fields[7].Get<uint32>();
2763 itemTemplate.Flags2 = fields[8].Get<uint32>();
2764 itemTemplate.BuyCount = uint32(fields[9].Get<uint8>());
2765 itemTemplate.BuyPrice = int32(fields[10].Get<int64>() * sWorld->getRate((Rates)(RATE_BUYVALUE_ITEM_POOR + itemTemplate.Quality)));
2766 itemTemplate.SellPrice = uint32(fields[11].Get<uint32>() * sWorld->getRate((Rates)(RATE_SELLVALUE_ITEM_POOR + itemTemplate.Quality)));
2767 itemTemplate.InventoryType = uint32(fields[12].Get<uint8>());
2768 itemTemplate.AllowableClass = fields[13].Get<int32>();
2769 itemTemplate.AllowableRace = fields[14].Get<int32>();
2770 itemTemplate.ItemLevel = uint32(fields[15].Get<uint16>());
2771 itemTemplate.RequiredLevel = uint32(fields[16].Get<uint8>());
2772 itemTemplate.RequiredSkill = uint32(fields[17].Get<uint16>());
2773 itemTemplate.RequiredSkillRank = uint32(fields[18].Get<uint16>());
2774 itemTemplate.RequiredSpell = fields[19].Get<uint32>();
2775 itemTemplate.RequiredHonorRank = fields[20].Get<uint32>();
2776 itemTemplate.RequiredCityRank = fields[21].Get<uint32>();
2777 itemTemplate.RequiredReputationFaction = uint32(fields[22].Get<uint16>());
2778 itemTemplate.RequiredReputationRank = uint32(fields[23].Get<uint16>());
2779 itemTemplate.MaxCount = fields[24].Get<int32>();
2780 itemTemplate.Stackable = fields[25].Get<int32>();
2781 itemTemplate.ContainerSlots = uint32(fields[26].Get<uint8>());
2782 itemTemplate.StatsCount = uint32(fields[27].Get<uint8>());
2783
2784 for (uint8 i = 0; i < itemTemplate.StatsCount; ++i)
2785 {
2786 itemTemplate.ItemStat[i].ItemStatType = uint32(fields[28 + i * 2].Get<uint8>());
2787 itemTemplate.ItemStat[i].ItemStatValue = fields[29 + i * 2].Get<int32>();
2788 }
2789
2790 itemTemplate.ScalingStatDistribution = uint32(fields[48].Get<uint16>());
2791 itemTemplate.ScalingStatValue = fields[49].Get<int32>();
2792
2793 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
2794 {
2795 itemTemplate.Damage[i].DamageMin = fields[50 + i * 3].Get<float>();
2796 itemTemplate.Damage[i].DamageMax = fields[51 + i * 3].Get<float>();
2797 itemTemplate.Damage[i].DamageType = uint32(fields[52 + i * 3].Get<uint8>());
2798 }
2799
2800 itemTemplate.Armor = fields[56].Get<uint32>();
2801 itemTemplate.HolyRes = fields[57].Get<int32>();
2802 itemTemplate.FireRes = fields[58].Get<int32>();
2803 itemTemplate.NatureRes = fields[59].Get<int32>();
2804 itemTemplate.FrostRes = fields[60].Get<int32>();
2805 itemTemplate.ShadowRes = fields[61].Get<int32>();
2806 itemTemplate.ArcaneRes = fields[62].Get<int32>();
2807 itemTemplate.Delay = uint32(fields[63].Get<uint16>());
2808 itemTemplate.AmmoType = uint32(fields[64].Get<uint8>());
2809 itemTemplate.RangedModRange = fields[65].Get<float>();
2810
2811 for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
2812 {
2813 itemTemplate.Spells[i].SpellId = fields[66 + i * 7 ].Get<int32>();
2814 itemTemplate.Spells[i].SpellTrigger = uint32(fields[67 + i * 7].Get<uint8>());
2815 itemTemplate.Spells[i].SpellCharges = int32(fields[68 + i * 7].Get<int16>());
2816 itemTemplate.Spells[i].SpellPPMRate = fields[69 + i * 7].Get<float>();
2817 itemTemplate.Spells[i].SpellCooldown = fields[70 + i * 7].Get<int32>();
2818 itemTemplate.Spells[i].SpellCategory = uint32(fields[71 + i * 7].Get<uint16>());
2819 itemTemplate.Spells[i].SpellCategoryCooldown = fields[72 + i * 7].Get<int32>();
2820 }
2821
2822 itemTemplate.Bonding = uint32(fields[101].Get<uint8>());
2823 itemTemplate.Description = fields[102].Get<std::string>();
2824 itemTemplate.PageText = fields[103].Get<uint32>();
2825 itemTemplate.LanguageID = uint32(fields[104].Get<uint8>());
2826 itemTemplate.PageMaterial = uint32(fields[105].Get<uint8>());
2827 itemTemplate.StartQuest = fields[106].Get<uint32>();
2828 itemTemplate.LockID = fields[107].Get<uint32>();
2829 itemTemplate.Material = int32(fields[108].Get<int8>());
2830 itemTemplate.Sheath = uint32(fields[109].Get<uint8>());
2831 itemTemplate.RandomProperty = fields[110].Get<int32>();
2832 itemTemplate.RandomSuffix = fields[111].Get<int32>();
2833 itemTemplate.Block = fields[112].Get<uint32>();
2834 itemTemplate.ItemSet = fields[113].Get<uint32>();
2835 itemTemplate.MaxDurability = uint32(fields[114].Get<uint16>());
2836 itemTemplate.Area = fields[115].Get<uint32>();
2837 itemTemplate.Map = uint32(fields[116].Get<uint16>());
2838 itemTemplate.BagFamily = fields[117].Get<uint32>();
2839 itemTemplate.TotemCategory = fields[118].Get<uint32>();
2840
2841 for (uint8 i = 0; i < MAX_ITEM_PROTO_SOCKETS; ++i)
2842 {
2843 itemTemplate.Socket[i].Color = uint32(fields[119 + i * 2].Get<uint8>());
2844 itemTemplate.Socket[i].Content = fields[120 + i * 2].Get<uint32>();
2845 }
2846
2847 itemTemplate.socketBonus = fields[125].Get<uint32>();
2848 itemTemplate.GemProperties = fields[126].Get<uint32>();
2849 itemTemplate.RequiredDisenchantSkill = uint32(fields[127].Get<int16>());
2850 itemTemplate.ArmorDamageModifier = fields[128].Get<float>();
2851 itemTemplate.Duration = fields[129].Get<uint32>();
2852 itemTemplate.ItemLimitCategory = uint32(fields[130].Get<int16>());
2853 itemTemplate.HolidayId = fields[131].Get<uint32>();
2854 itemTemplate.ScriptId = sObjectMgr->GetScriptId(fields[132].Get<std::string>());
2855 itemTemplate.DisenchantID = fields[133].Get<uint32>();
2856 itemTemplate.FoodType = uint32(fields[134].Get<uint8>());
2857 itemTemplate.MinMoneyLoot = fields[135].Get<uint32>();
2858 itemTemplate.MaxMoneyLoot = fields[136].Get<uint32>();
2859 itemTemplate.FlagsCu = fields[137].Get<uint32>();
2860
2861 // Checks
2862 if (itemTemplate.Class >= MAX_ITEM_CLASS)
2863 {
2864 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Class value ({})", entry, itemTemplate.Class);
2865 itemTemplate.Class = ITEM_CLASS_MISC;
2866 }
2867
2868 if (itemTemplate.SubClass >= MaxItemSubclassValues[itemTemplate.Class])
2869 {
2870 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Subclass value ({}) for class {}", entry, itemTemplate.SubClass, itemTemplate.Class);
2871 itemTemplate.SubClass = 0;// exist for all item classes
2872 }
2873
2874 if (itemTemplate.Quality >= MAX_ITEM_QUALITY)
2875 {
2876 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Quality value ({})", entry, itemTemplate.Quality);
2877 itemTemplate.Quality = ITEM_QUALITY_NORMAL;
2878 }
2879
2880 if (itemTemplate.Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY)
2881 {
2882 if (FactionEntry const* faction = sFactionStore.LookupEntry(HORDE))
2883 if ((itemTemplate.AllowableRace & faction->BaseRepRaceMask[0]) == 0)
2884 LOG_ERROR("sql.sql", "Item (Entry: {}) has value ({}) in `AllowableRace` races, not compatible with ITEM_FLAGS_EXTRA_HORDE_ONLY ({}) in Flags field, item cannot be equipped or used by these races.",
2885 entry, itemTemplate.AllowableRace, ITEM_FLAGS_EXTRA_HORDE_ONLY);
2886
2887 if (itemTemplate.Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY)
2888 LOG_ERROR("sql.sql", "Item (Entry: {}) has value ({}) in `Flags2` flags (ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) and ITEM_FLAGS_EXTRA_HORDE_ONLY ({}) in Flags field, this is a wrong combination.",
2890 }
2891 else if (itemTemplate.Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY)
2892 {
2893 if (FactionEntry const* faction = sFactionStore.LookupEntry(ALLIANCE))
2894 if ((itemTemplate.AllowableRace & faction->BaseRepRaceMask[0]) == 0)
2895 LOG_ERROR("sql.sql", "Item (Entry: {}) has value ({}) in `AllowableRace` races, not compatible with ITEM_FLAGS_EXTRA_ALLIANCE_ONLY ({}) in Flags field, item cannot be equipped or used by these races.",
2896 entry, itemTemplate.AllowableRace, ITEM_FLAGS_EXTRA_ALLIANCE_ONLY);
2897 }
2898
2899 if (itemTemplate.BuyCount <= 0)
2900 {
2901 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong BuyCount value ({}), set to default(1).", entry, itemTemplate.BuyCount);
2902 itemTemplate.BuyCount = 1;
2903 }
2904
2905 if (itemTemplate.InventoryType >= MAX_INVTYPE)
2906 {
2907 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong InventoryType value ({})", entry, itemTemplate.InventoryType);
2908 itemTemplate.InventoryType = INVTYPE_NON_EQUIP;
2909 }
2910
2911 if (itemTemplate.RequiredSkill >= MAX_SKILL_TYPE)
2912 {
2913 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong RequiredSkill value ({})", entry, itemTemplate.RequiredSkill);
2914 itemTemplate.RequiredSkill = 0;
2915 }
2916
2917 {
2918 // can be used in equip slot, as page read use in inventory, or spell casting at use
2919 bool req = itemTemplate.InventoryType != INVTYPE_NON_EQUIP || itemTemplate.PageText;
2920 if (!req)
2921 for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
2922 {
2923 if (itemTemplate.Spells[j].SpellId)
2924 {
2925 req = true;
2926 break;
2927 }
2928 }
2929
2930 if (req)
2931 {
2932 if (!(itemTemplate.AllowableClass & CLASSMASK_ALL_PLAYABLE))
2933 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have any playable classes ({}) in `AllowableClass` and can't be equipped or used.", entry, itemTemplate.AllowableClass);
2934
2935 if (!(itemTemplate.AllowableRace & RACEMASK_ALL_PLAYABLE))
2936 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have any playable races ({}) in `AllowableRace` and can't be equipped or used.", entry, itemTemplate.AllowableRace);
2937 }
2938 }
2939
2940 if (itemTemplate.RequiredSpell && !sSpellMgr->GetSpellInfo(itemTemplate.RequiredSpell))
2941 {
2942 LOG_ERROR("sql.sql", "Item (Entry: {}) has a wrong (non-existing) spell in RequiredSpell ({})", entry, itemTemplate.RequiredSpell);
2943 itemTemplate.RequiredSpell = 0;
2944 }
2945
2946 if (itemTemplate.RequiredReputationRank >= MAX_REPUTATION_RANK)
2947 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong reputation rank in RequiredReputationRank ({}), item can't be used.", entry, itemTemplate.RequiredReputationRank);
2948
2949 if (itemTemplate.RequiredReputationFaction)
2950 {
2951 if (!sFactionStore.LookupEntry(itemTemplate.RequiredReputationFaction))
2952 {
2953 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (not existing) faction in RequiredReputationFaction ({})", entry, itemTemplate.RequiredReputationFaction);
2954 itemTemplate.RequiredReputationFaction = 0;
2955 }
2956
2957 if (itemTemplate.RequiredReputationRank == MIN_REPUTATION_RANK)
2958 LOG_ERROR("sql.sql", "Item (Entry: {}) has min. reputation rank in RequiredReputationRank (0) but RequiredReputationFaction > 0, faction setting is useless.", entry);
2959 }
2960
2961 if (itemTemplate.MaxCount < -1)
2962 {
2963 LOG_ERROR("sql.sql", "Item (Entry: {}) has too large negative in maxcount ({}), replace by value (-1) no storing limits.", entry, itemTemplate.MaxCount);
2964 itemTemplate.MaxCount = -1;
2965 }
2966
2967 if (itemTemplate.Stackable == 0)
2968 {
2969 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong value in stackable ({}), replace by default 1.", entry, itemTemplate.Stackable);
2970 itemTemplate.Stackable = 1;
2971 }
2972 else if (itemTemplate.Stackable < -1)
2973 {
2974 LOG_ERROR("sql.sql", "Item (Entry: {}) has too large negative in stackable ({}), replace by value (-1) no stacking limits.", entry, itemTemplate.Stackable);
2975 itemTemplate.Stackable = -1;
2976 }
2977
2978 if (itemTemplate.ContainerSlots > MAX_BAG_SIZE)
2979 {
2980 LOG_ERROR("sql.sql", "Item (Entry: {}) has too large value in ContainerSlots ({}), replace by hardcoded limit ({}).", entry, itemTemplate.ContainerSlots, MAX_BAG_SIZE);
2981 itemTemplate.ContainerSlots = MAX_BAG_SIZE;
2982 }
2983
2984 if (itemTemplate.StatsCount > MAX_ITEM_PROTO_STATS)
2985 {
2986 LOG_ERROR("sql.sql", "Item (Entry: {}) has too large value in statscount ({}), replace by hardcoded limit ({}).", entry, itemTemplate.StatsCount, MAX_ITEM_PROTO_STATS);
2987 itemTemplate.StatsCount = MAX_ITEM_PROTO_STATS;
2988 }
2989
2990 for (uint8 j = 0; j < itemTemplate.StatsCount; ++j)
2991 {
2992 // for ItemStatValue != 0
2993 if (itemTemplate.ItemStat[j].ItemStatValue && itemTemplate.ItemStat[j].ItemStatType >= MAX_ITEM_MOD)
2994 {
2995 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (non-existing?) stat_type{} ({})", entry, j + 1, itemTemplate.ItemStat[j].ItemStatType);
2996 itemTemplate.ItemStat[j].ItemStatType = 0;
2997 }
2998
2999 switch (itemTemplate.ItemStat[j].ItemStatType)
3000 {
3003 LOG_ERROR("sql.sql", "Item (Entry: {}) has deprecated stat_type{} ({})", entry, j + 1, itemTemplate.ItemStat[j].ItemStatType);
3004 break;
3005 default:
3006 break;
3007 }
3008 }
3009
3010 for (uint8 j = 0; j < MAX_ITEM_PROTO_DAMAGES; ++j)
3011 {
3012 if (itemTemplate.Damage[j].DamageType >= MAX_SPELL_SCHOOL)
3013 {
3014 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong dmg_type{} ({})", entry, j + 1, itemTemplate.Damage[j].DamageType);
3015 itemTemplate.Damage[j].DamageType = 0;
3016 }
3017 }
3018
3019 // special format
3020 if ((itemTemplate.Spells[0].SpellId == 483) || (itemTemplate.Spells[0].SpellId == 55884))
3021 {
3022 // spell_1
3023 if (itemTemplate.Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
3024 {
3025 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);
3026 itemTemplate.Spells[0].SpellId = 0;
3027 itemTemplate.Spells[0].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3028 itemTemplate.Spells[1].SpellId = 0;
3029 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3030 }
3031
3032 // spell_2 have learning spell
3033 if (itemTemplate.Spells[1].SpellTrigger != ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
3034 {
3035 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);
3036 itemTemplate.Spells[0].SpellId = 0;
3037 itemTemplate.Spells[1].SpellId = 0;
3038 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3039 }
3040 else if (!itemTemplate.Spells[1].SpellId)
3041 {
3042 LOG_ERROR("sql.sql", "Item (Entry: {}) does not have an expected spell in spellid_{} in special learning format.", entry, 1 + 1);
3043 itemTemplate.Spells[0].SpellId = 0;
3044 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3045 }
3046 else if (itemTemplate.Spells[1].SpellId != -1)
3047 {
3048 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemTemplate.Spells[1].SpellId);
3049 if (!spellInfo && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, itemTemplate.Spells[1].SpellId, nullptr))
3050 {
3051 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (not existing) spell in spellid_{} ({})", entry, 1 + 1, itemTemplate.Spells[1].SpellId);
3052 itemTemplate.Spells[0].SpellId = 0;
3053 itemTemplate.Spells[1].SpellId = 0;
3054 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3055 }
3056 // allowed only in special format
3057 else if ((itemTemplate.Spells[1].SpellId == 483) || (itemTemplate.Spells[1].SpellId == 55884))
3058 {
3059 LOG_ERROR("sql.sql", "Item (Entry: {}) has broken spell in spellid_{} ({})", entry, 1 + 1, itemTemplate.Spells[1].SpellId);
3060 itemTemplate.Spells[0].SpellId = 0;
3061 itemTemplate.Spells[1].SpellId = 0;
3062 itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3063 }
3064 }
3065
3066 // spell_3*, spell_4*, spell_5* is empty
3067 for (uint8 j = 2; j < MAX_ITEM_PROTO_SPELLS; ++j)
3068 {
3069 if (itemTemplate.Spells[j].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
3070 {
3071 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong item spell trigger value in spelltrigger_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellTrigger);
3072 itemTemplate.Spells[j].SpellId = 0;
3073 itemTemplate.Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3074 }
3075 else if (itemTemplate.Spells[j].SpellId != 0)
3076 {
3077 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong spell in spellid_{} ({}) for learning special format", entry, j + 1, itemTemplate.Spells[j].SpellId);
3078 itemTemplate.Spells[j].SpellId = 0;
3079 }
3080 }
3081 }
3082 // normal spell list
3083 else
3084 {
3085 for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
3086 {
3087 if (itemTemplate.Spells[j].SpellTrigger >= MAX_ITEM_SPELLTRIGGER || itemTemplate.Spells[j].SpellTrigger == ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
3088 {
3089 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong item spell trigger value in spelltrigger_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellTrigger);
3090 itemTemplate.Spells[j].SpellId = 0;
3091 itemTemplate.Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3092 }
3093
3094 if (itemTemplate.Spells[j].SpellId && itemTemplate.Spells[j].SpellId != -1)
3095 {
3096 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemTemplate.Spells[j].SpellId);
3097 if (!spellInfo && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, itemTemplate.Spells[j].SpellId, nullptr))
3098 {
3099 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong (not existing) spell in spellid_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellId);
3100 itemTemplate.Spells[j].SpellId = 0;
3101 }
3102 // allowed only in special format
3103 else if ((itemTemplate.Spells[j].SpellId == 483) || (itemTemplate.Spells[j].SpellId == 55884))
3104 {
3105 LOG_ERROR("sql.sql", "Item (Entry: {}) has broken spell in spellid_{} ({})", entry, j + 1, itemTemplate.Spells[j].SpellId);
3106 itemTemplate.Spells[j].SpellId = 0;
3107 }
3108 }
3109 }
3110 }
3111
3112 if (itemTemplate.Bonding >= MAX_BIND_TYPE)
3113 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Bonding value ({})", entry, itemTemplate.Bonding);
3114
3115 if (itemTemplate.PageText && !GetPageText(itemTemplate.PageText))
3116 LOG_ERROR("sql.sql", "Item (Entry: {}) has non existing first page (Id:{})", entry, itemTemplate.PageText);
3117
3118 if (itemTemplate.LockID && !sLockStore.LookupEntry(itemTemplate.LockID))
3119 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong LockID ({})", entry, itemTemplate.LockID);
3120
3121 if (itemTemplate.Sheath >= MAX_SHEATHETYPE)
3122 {
3123 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Sheath ({})", entry, itemTemplate.Sheath);
3124 itemTemplate.Sheath = SHEATHETYPE_NONE;
3125 }
3126
3127 if (itemTemplate.RandomProperty)
3128 {
3129 // To be implemented later
3130 if (itemTemplate.RandomProperty == -1)
3131 itemTemplate.RandomProperty = 0;
3132
3133 else if (!sItemRandomPropertiesStore.LookupEntry(GetItemEnchantMod(itemTemplate.RandomProperty)))
3134 {
3135 LOG_ERROR("sql.sql", "Item (Entry: {}) has unknown (wrong or not listed in `item_enchantment_template`) RandomProperty ({})", entry, itemTemplate.RandomProperty);
3136 itemTemplate.RandomProperty = 0;
3137 }
3138 }
3139
3140 if (itemTemplate.RandomSuffix && !sItemRandomSuffixStore.LookupEntry(GetItemEnchantMod(itemTemplate.RandomSuffix)))
3141 {
3142 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong RandomSuffix ({})", entry, itemTemplate.RandomSuffix);
3143 itemTemplate.RandomSuffix = 0;
3144 }
3145
3146 if (itemTemplate.ItemSet && !sItemSetStore.LookupEntry(itemTemplate.ItemSet))
3147 {
3148 LOG_ERROR("sql.sql", "Item (Entry: {}) have wrong ItemSet ({})", entry, itemTemplate.ItemSet);
3149 itemTemplate.ItemSet = 0;
3150 }
3151
3152 if (itemTemplate.Area && !sAreaTableStore.LookupEntry(itemTemplate.Area))
3153 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Area ({})", entry, itemTemplate.Area);
3154
3155 if (itemTemplate.Map && !sMapStore.LookupEntry(itemTemplate.Map))
3156 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Map ({})", entry, itemTemplate.Map);
3157
3158 if (itemTemplate.BagFamily)
3159 {
3160 // check bits
3161 for (uint32 j = 0; j < sizeof(itemTemplate.BagFamily) * 8; ++j)
3162 {
3163 uint32 mask = 1 << j;
3164 if ((itemTemplate.BagFamily & mask) == 0)
3165 continue;
3166
3167 ItemBagFamilyEntry const* bf = sItemBagFamilyStore.LookupEntry(j + 1);
3168 if (!bf)
3169 {
3170 LOG_ERROR("sql.sql", "Item (Entry: {}) has bag family bit set not listed in ItemBagFamily.dbc, remove bit", entry);
3171 itemTemplate.BagFamily &= ~mask;
3172 continue;
3173 }
3174
3176 {
3177 CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemTemplate.ItemId);
3178 if (!ctEntry)
3179 {
3180 LOG_ERROR("sql.sql", "Item (Entry: {}) has currency bag family bit set in BagFamily but not listed in CurrencyTypes.dbc, remove bit", entry);
3181 itemTemplate.BagFamily &= ~mask;
3182 }
3183 }
3184 }
3185 }
3186
3187 if (itemTemplate.TotemCategory && !sTotemCategoryStore.LookupEntry(itemTemplate.TotemCategory))
3188 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong TotemCategory ({})", entry, itemTemplate.TotemCategory);
3189
3190 for (uint8 j = 0; j < MAX_ITEM_PROTO_SOCKETS; ++j)
3191 {
3192 if (itemTemplate.Socket[j].Color && (itemTemplate.Socket[j].Color & SOCKET_COLOR_ALL) != itemTemplate.Socket[j].Color)
3193 {
3194 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong socketColor_{} ({})", entry, j + 1, itemTemplate.Socket[j].Color);
3195 itemTemplate.Socket[j].Color = 0;
3196 }
3197 }
3198
3199 if (itemTemplate.GemProperties && !sGemPropertiesStore.LookupEntry(itemTemplate.GemProperties))
3200 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong GemProperties ({})", entry, itemTemplate.GemProperties);
3201
3202 if (itemTemplate.FoodType >= MAX_PET_DIET)
3203 {
3204 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong FoodType value ({})", entry, itemTemplate.FoodType);
3205 itemTemplate.FoodType = 0;
3206 }
3207
3208 if (itemTemplate.ItemLimitCategory && !sItemLimitCategoryStore.LookupEntry(itemTemplate.ItemLimitCategory))
3209 {
3210 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong LimitCategory value ({})", entry, itemTemplate.ItemLimitCategory);
3211 itemTemplate.ItemLimitCategory = 0;
3212 }
3213
3214 if (itemTemplate.HolidayId && !sHolidaysStore.LookupEntry(itemTemplate.HolidayId))
3215 {
3216 LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong HolidayId value ({})", entry, itemTemplate.HolidayId);
3217 itemTemplate.HolidayId = 0;
3218 }
3219
3220 if (itemTemplate.FlagsCu & ITEM_FLAGS_CU_DURATION_REAL_TIME && !itemTemplate.Duration)
3221 {
3222 LOG_ERROR("sql.sql", "Item (Entry {}) has flag ITEM_FLAGS_CU_DURATION_REAL_TIME but it does not have duration limit", entry);
3223 itemTemplate.FlagsCu &= ~ITEM_FLAGS_CU_DURATION_REAL_TIME;
3224 }
3225
3226 // Fill categories map
3227 for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
3228 if (itemTemplate.Spells[i].SpellId && itemTemplate.Spells[i].SpellCategory && itemTemplate.Spells[i].SpellCategoryCooldown)
3229 {
3230 SpellCategoryStore::iterator ct = sSpellsByCategoryStore.find(itemTemplate.Spells[i].SpellCategory);
3231 if (ct != sSpellsByCategoryStore.end())
3232 {
3233 ct->second.emplace(true, itemTemplate.Spells[i].SpellId);
3234 }
3235 else
3236 sSpellsByCategoryStore[itemTemplate.Spells[i].SpellCategory].emplace(true, itemTemplate.Spells[i].SpellId);
3237 }
3238
3239 ++count;
3240 } while (result->NextRow());
3241
3242 // pussywizard:
3243 {
3244 uint32 max = 0;
3245 for (ItemTemplateContainer::const_iterator itr = _itemTemplateStore.begin(); itr != _itemTemplateStore.end(); ++itr)
3246 if (itr->first > max)
3247 max = itr->first;
3248 if (max)
3249 {
3250 _itemTemplateStoreFast.clear();
3251 _itemTemplateStoreFast.resize(max + 1, nullptr);
3252 for (ItemTemplateContainer::iterator itr = _itemTemplateStore.begin(); itr != _itemTemplateStore.end(); ++itr)
3253 _itemTemplateStoreFast[itr->first] = &(itr->second);
3254 }
3255 }
3256
3257 for (ItemTemplateContainer::iterator itr = _itemTemplateStore.begin(); itr != _itemTemplateStore.end(); ++itr)
3258 itr->second.InitializeQueryData();
3259
3260 // Check if item templates for DBC referenced character start outfit are present
3261 std::set<uint32> notFoundOutfit;
3262 for (uint32 i = 1; i < sCharStartOutfitStore.GetNumRows(); ++i)
3263 {
3264 CharStartOutfitEntry const* entry = sCharStartOutfitStore.LookupEntry(i);
3265 if (!entry)
3266 continue;
3267
3268 for (int j = 0; j < MAX_OUTFIT_ITEMS; ++j)
3269 {
3270 if (entry->ItemId[j] <= 0)
3271 continue;
3272
3273 uint32 item_id = entry->ItemId[j];
3274
3275 if (!GetItemTemplate(item_id))
3276 notFoundOutfit.insert(item_id);
3277 }
3278 }
3279
3280 for (std::set<uint32>::const_iterator itr = notFoundOutfit.begin(); itr != notFoundOutfit.end(); ++itr)
3281 LOG_ERROR("sql.sql", "Item (Entry: {}) does not exist in `item_template` but is referenced in `CharStartOutfit.dbc`", *itr);
3282
3283 LOG_INFO("server.loading", ">> Loaded {} Item Templates in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3284 LOG_INFO("server.loading", " ");
3285}
@ DISABLE_TYPE_SPELL
Definition: DisableMgr.h:29
DBCStorage< ItemLimitCategoryEntry > sItemLimitCategoryStore(ItemLimitCategoryEntryfmt)
SpellCategoryStore sSpellsByCategoryStore
Definition: DBCStores.cpp:150
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_BAG_SIZE
Definition: Bag.h:22
uint32 GetItemEnchantMod(int32 entry)
Definition: ItemEnchantmentMgr.cpp:81
@ ITEM_SPELLTRIGGER_LEARN_SPELL_ID
Definition: ItemTemplate.h:89
@ ITEM_SPELLTRIGGER_ON_USE
Definition: ItemTemplate.h:78
@ BAG_FAMILY_MASK_CURRENCY_TOKENS
Definition: ItemTemplate.h:249
@ ITEM_MOD_SPELL_HEALING_DONE
Definition: ItemTemplate.h:64
@ ITEM_MOD_SPELL_DAMAGE_DONE
Definition: ItemTemplate.h:65
#define MAX_ITEM_CLASS
Definition: ItemTemplate.h:319
@ ITEM_FLAGS_EXTRA_ALLIANCE_ONLY
Definition: ItemTemplate.h:221
@ ITEM_FLAGS_EXTRA_HORDE_ONLY
Definition: ItemTemplate.h:220
#define MAX_ITEM_PROTO_SOCKETS
Definition: ItemTemplate.h:623
#define MAX_ITEM_PROTO_DAMAGES
Definition: ItemTemplate.h:622
#define MAX_ITEM_PROTO_SPELLS
Definition: ItemTemplate.h:624
#define SOCKET_COLOR_ALL
Definition: ItemTemplate.h:261
@ ITEM_CLASS_MISC
Definition: ItemTemplate.h:315
#define MAX_BIND_TYPE
Definition: ItemTemplate.h:104
#define MAX_ITEM_SPELLTRIGGER
Definition: ItemTemplate.h:92
#define MAX_ITEM_PROTO_STATS
Definition: ItemTemplate.h:625
const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS]
Definition: ItemTemplate.h:545
#define MAX_ITEM_MOD
Definition: ItemTemplate.h:74
@ ITEM_FLAGS_CU_DURATION_REAL_TIME
Definition: ItemTemplate.h:228
Rates
Server rates.
Definition: IWorld.h:420
@ RATE_BUYVALUE_ITEM_POOR
Definition: IWorld.h:448
@ RATE_SELLVALUE_ITEM_POOR
Definition: IWorld.h:440
#define MAX_OUTFIT_ITEMS
Definition: DBCStructure.h:617
#define MAX_REPUTATION_RANK
Definition: SharedDefines.h:217
#define MIN_REPUTATION_RANK
Definition: SharedDefines.h:216
#define MAX_PET_DIET
Definition: SharedDefines.h:3203
#define MAX_SHEATHETYPE
Definition: SharedDefines.h:679
@ ITEM_QUALITY_NORMAL
Definition: SharedDefines.h:302
#define MAX_ITEM_QUALITY
Definition: SharedDefines.h:311
#define MAX_SKILL_TYPE
Definition: SharedDefines.h:2990
@ ALLIANCE
Definition: SharedDefines.h:740
@ HORDE
Definition: SharedDefines.h:739
@ SHEATHETYPE_NONE
Definition: SharedDefines.h:669
#define CLASSMASK_ALL_PLAYABLE
Definition: SharedDefines.h:129
#define RACEMASK_ALL_PLAYABLE
Definition: SharedDefines.h:96
bool IsDisabledFor(DisableType type, uint32 entry, Unit const *unit, uint8 flags)
Definition: DisableMgr.cpp:306
Definition: DBCStructure.h:620
int32 ItemId[MAX_OUTFIT_ITEMS]
Definition: DBCStructure.h:626
Definition: DBCStructure.h:826
Definition: DBCStructure.h:898
Definition: DBCStructure.h:1131

References _itemTemplateStore, _itemTemplateStoreFast, ALLIANCE, BAG_FAMILY_MASK_CURRENCY_TOKENS, CLASSMASK_ALL_PLAYABLE, DISABLE_TYPE_SPELL, Field::Get(), GetItemEnchantMod(), GetItemTemplate(), getMSTime(), GetMSTimeDiffToNow(), GetPageText(), HORDE, INVTYPE_NON_EQUIP, DisableMgr::IsDisabledFor(), ITEM_CLASS_MISC, ITEM_FLAGS_CU_DURATION_REAL_TIME, ITEM_FLAGS_EXTRA_ALLIANCE_ONLY, ITEM_FLAGS_EXTRA_HORDE_ONLY, ITEM_MOD_SPELL_DAMAGE_DONE, ITEM_MOD_SPELL_HEALING_DONE, ITEM_QUALITY_NORMAL, ITEM_SPELLTRIGGER_LEARN_SPELL_ID, ITEM_SPELLTRIGGER_ON_USE, CharStartOutfitEntry::ItemId, LOG_ERROR, LOG_INFO, LOG_WARN, MAX_BAG_SIZE, MAX_BIND_TYPE, MAX_INVTYPE, MAX_ITEM_CLASS, 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_SHEATHETYPE, MAX_SKILL_TYPE, MAX_SPELL_SCHOOL, MaxItemSubclassValues, MIN_REPUTATION_RANK, RACEMASK_ALL_PLAYABLE, RATE_BUYVALUE_ITEM_POOR, RATE_SELLVALUE_ITEM_POOR, sAreaTableStore, sCharStartOutfitStore, sCurrencyTypesStore, sFactionStore, sGemPropertiesStore, SHEATHETYPE_NONE, sHolidaysStore, sItemBagFamilyStore, sItemLimitCategoryStore, sItemRandomPropertiesStore, sItemRandomSuffixStore, sItemSetStore, sLockStore, sMapStore, sObjectMgr, SOCKET_COLOR_ALL, sSpellMgr, sSpellsByCategoryStore, sTotemCategoryStore, sWorld, and WorldDatabase.

◆ LoadLinkedRespawn()

void ObjectMgr::LoadLinkedRespawn ( )
1826{
1827 uint32 oldMSTime = getMSTime();
1828
1829 _linkedRespawnStore.clear();
1830 // 0 1 2
1831 QueryResult result = WorldDatabase.Query("SELECT guid, linkedGuid, linkType FROM linked_respawn ORDER BY guid ASC");
1832
1833 if (!result)
1834 {
1835 LOG_WARN("server.loading", ">> Loaded 0 linked respawns. DB table `linked_respawn` is empty.");
1836 LOG_INFO("server.loading", " ");
1837 return;
1838 }
1839
1840 do
1841 {
1842 Field* fields = result->Fetch();
1843
1844 ObjectGuid::LowType guidLow = fields[0].Get<uint32>();
1845 ObjectGuid::LowType linkedGuidLow = fields[1].Get<uint32>();
1846 uint8 linkType = fields[2].Get<uint8>();
1847
1848 ObjectGuid guid, linkedGuid;
1849 bool error = false;
1850 switch (linkType)
1851 {
1853 {
1854 const CreatureData* slave = GetCreatureData(guidLow);
1855 if (!slave)
1856 {
1857 LOG_ERROR("sql.sql", "LinkedRespawn: Creature (guid) {} not found in creature table", guidLow);
1858 error = true;
1859 break;
1860 }
1861
1862 const CreatureData* master = GetCreatureData(linkedGuidLow);
1863 if (!master)
1864 {
1865 LOG_ERROR("sql.sql", "LinkedRespawn: Creature (linkedGuid) {} not found in creature table", linkedGuidLow);
1866 error = true;
1867 break;
1868 }
1869
1870 MapEntry const* const map = sMapStore.LookupEntry(master->mapid);
1871 if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
1872 {
1873 LOG_ERROR("sql.sql", "LinkedRespawn: Creature '{}' linking to Creature '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1874 error = true;
1875 break;
1876 }
1877
1878 if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
1879 {
1880 LOG_ERROR("sql.sql", "LinkedRespawn: Creature '{}' linking to Creature '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1881 error = true;
1882 break;
1883 }
1884
1885 guid = ObjectGuid::Create<HighGuid::Unit>(slave->id1, guidLow);
1886 linkedGuid = ObjectGuid::Create<HighGuid::Unit>(master->id1, linkedGuidLow);
1887 break;
1888 }
1889 case CREATURE_TO_GO:
1890 {
1891 const CreatureData* slave = GetCreatureData(guidLow);
1892 if (!slave)
1893 {
1894 LOG_ERROR("sql.sql", "LinkedRespawn: Creature (guid) {} not found in creature table", guidLow);
1895 error = true;
1896 break;
1897 }
1898
1899 const GameObjectData* master = GetGameObjectData(linkedGuidLow);
1900 if (!master)
1901 {
1902 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (linkedGuid) {} not found in gameobject table", linkedGuidLow);
1903 error = true;
1904 break;
1905 }
1906
1907 MapEntry const* const map = sMapStore.LookupEntry(master->mapid);
1908 if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
1909 {
1910 LOG_ERROR("sql.sql", "LinkedRespawn: Creature '{}' linking to Gameobject '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1911 error = true;
1912 break;
1913 }
1914
1915 if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
1916 {
1917 LOG_ERROR("sql.sql", "LinkedRespawn: Creature '{}' linking to Gameobject '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1918 error = true;
1919 break;
1920 }
1921
1922 guid = ObjectGuid::Create<HighGuid::Unit>(slave->id1, guidLow);
1923 linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->id, linkedGuidLow);
1924 break;
1925 }
1926 case GO_TO_GO:
1927 {
1928 const GameObjectData* slave = GetGameObjectData(guidLow);
1929 if (!slave)
1930 {
1931 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (guid) {} not found in gameobject table", guidLow);
1932 error = true;
1933 break;
1934 }
1935
1936 const GameObjectData* master = GetGameObjectData(linkedGuidLow);
1937 if (!master)
1938 {
1939 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (linkedGuid) {} not found in gameobject table", linkedGuidLow);
1940 error = true;
1941 break;
1942 }
1943
1944 MapEntry const* const map = sMapStore.LookupEntry(master->mapid);
1945 if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
1946 {
1947 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '{}' linking to Gameobject '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1948 error = true;
1949 break;
1950 }
1951
1952 if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
1953 {
1954 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '{}' linking to Gameobject '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1955 error = true;
1956 break;
1957 }
1958
1959 guid = ObjectGuid::Create<HighGuid::GameObject>(slave->id, guidLow);
1960 linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->id, linkedGuidLow);
1961 break;
1962 }
1963 case GO_TO_CREATURE:
1964 {
1965 const GameObjectData* slave = GetGameObjectData(guidLow);
1966 if (!slave)
1967 {
1968 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (guid) {} not found in gameobject table", guidLow);
1969 error = true;
1970 break;
1971 }
1972
1973 const CreatureData* master = GetCreatureData(linkedGuidLow);
1974 if (!master)
1975 {
1976 LOG_ERROR("sql.sql", "LinkedRespawn: Creature (linkedGuid) {} not found in creature table", linkedGuidLow);
1977 error = true;
1978 break;
1979 }
1980
1981 MapEntry const* const map = sMapStore.LookupEntry(master->mapid);
1982 if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
1983 {
1984 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '{}' linking to Creature '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1985 error = true;
1986 break;
1987 }
1988
1989 if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
1990 {
1991 LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '{}' linking to Creature '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1992 error = true;
1993 break;
1994 }
1995
1996 guid = ObjectGuid::Create<HighGuid::GameObject>(slave->id, guidLow);
1997 linkedGuid = ObjectGuid::Create<HighGuid::Unit>(master->id1, linkedGuidLow);
1998 break;
1999 }
2000 }
2001
2002 if (!error)
2003 _linkedRespawnStore[guid] = linkedGuid;
2004 } while (result->NextRow());
2005
2006 LOG_INFO("server.loading", ">> Loaded {} Linked Respawns In {} ms", uint64(_linkedRespawnStore.size()), GetMSTimeDiffToNow(oldMSTime));
2007 LOG_INFO("server.loading", " ");
2008}
Definition: ObjectGuid.h:120
bool Instanceable() const
Definition: DBCStructure.h:1336

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 ( )
8905{
8906 uint32 oldMSTime = getMSTime();
8907
8908 _mailLevelRewardStore.clear(); // for reload case
8909
8910 // 0 1 2 3
8911 QueryResult result = WorldDatabase.Query("SELECT level, raceMask, mailTemplateId, senderEntry FROM mail_level_reward");
8912
8913 if (!result)
8914 {
8915 LOG_WARN("server.loading", ">> Loaded 0 level dependent mail rewards. DB table `mail_level_reward` is empty.");
8916 LOG_INFO("server.loading", " ");
8917 return;
8918 }
8919
8920 uint32 count = 0;
8921
8922 do
8923 {
8924 Field* fields = result->Fetch();
8925
8926 uint8 level = fields[0].Get<uint8>();
8927 uint32 raceMask = fields[1].Get<uint32>();
8928 uint32 mailTemplateId = fields[2].Get<uint32>();
8929 uint32 senderEntry = fields[3].Get<uint32>();
8930
8931 if (level > MAX_LEVEL)
8932 {
8933 LOG_ERROR("sql.sql", "Table `mail_level_reward` have data for level {} that more supported by client ({}), ignoring.", level, MAX_LEVEL);
8934 continue;
8935 }
8936
8937 if (!(raceMask & RACEMASK_ALL_PLAYABLE))
8938 {
8939 LOG_ERROR("sql.sql", "Table `mail_level_reward` have raceMask ({}) for level {} that not include any player races, ignoring.", raceMask, level);
8940 continue;
8941 }
8942
8943 if (!sMailTemplateStore.LookupEntry(mailTemplateId))
8944 {
8945 LOG_ERROR("sql.sql", "Table `mail_level_reward` have invalid mailTemplateId ({}) for level {} that invalid not include any player races, ignoring.", mailTemplateId, level);
8946 continue;
8947 }
8948
8949 if (!GetCreatureTemplate(senderEntry))
8950 {
8951 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);
8952 continue;
8953 }
8954
8955 _mailLevelRewardStore[level].push_back(MailLevelReward(raceMask, mailTemplateId, senderEntry));
8956
8957 ++count;
8958 } while (result->NextRow());
8959
8960 LOG_INFO("server.loading", ">> Loaded {} Level Dependent Mail Rewards in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8961 LOG_INFO("server.loading", " ");
8962}
DBCStorage< MailTemplateEntry > sMailTemplateStore(MailTemplateEntryfmt)
#define MAX_LEVEL
Definition: DBCEnums.h:45
Definition: ObjectMgr.h:537

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

◆ LoadMailServerTemplates()

void ObjectMgr::LoadMailServerTemplates ( )
10203{
10204 uint32 oldMSTime = getMSTime();
10205
10206 _serverMailStore.clear(); // for reload case
10207
10208 // 0 1 2 3 4 5 6 7 8 9 10 11
10209 QueryResult result = CharacterDatabase.Query("SELECT `id`, `reqLevel`, `reqPlayTime`, `moneyA`, `moneyH`, `itemA`, `itemCountA`, `itemH`,`itemCountH`, `subject`, `body`, `active` FROM `mail_server_template`");
10210 if (!result)
10211 {
10212 LOG_INFO("sql.sql", ">> Loaded 0 server mail rewards. DB table `mail_server_template` is empty.");
10213 LOG_INFO("server.loading", " ");
10214 return;
10215 }
10216
10217 _serverMailStore.rehash(result->GetRowCount());
10218
10219 do
10220 {
10221 Field* fields = result->Fetch();
10222
10223 uint32 id = fields[0].Get<uint32>();
10224
10225 ServerMail& servMail = _serverMailStore[id];
10226
10227 servMail.id = id;
10228 servMail.reqLevel = fields[1].Get<uint8>();
10229 servMail.reqPlayTime = fields[2].Get<uint32>();
10230 servMail.moneyA = fields[3].Get<uint32>();
10231 servMail.moneyH = fields[4].Get<uint32>();
10232 servMail.itemA = fields[5].Get<uint32>();
10233 servMail.itemCountA = fields[6].Get<uint32>();
10234 servMail.itemH = fields[7].Get<uint32>();
10235 servMail.itemCountH = fields[8].Get<uint32>();
10236 servMail.subject = fields[9].Get<std::string>();
10237 servMail.body = fields[10].Get<std::string>();
10238 servMail.active = fields[11].Get<uint8>();
10239
10240 if (servMail.reqLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
10241 {
10242 LOG_ERROR("sql.sql", "Table `mail_server_template` has reqLevel {} but max level is {} for id {}, skipped.", servMail.reqLevel, sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL), servMail.id);
10243 return;
10244 }
10245
10246 if (servMail.moneyA > MAX_MONEY_AMOUNT || servMail.moneyH > MAX_MONEY_AMOUNT)
10247 {
10248 LOG_ERROR("sql.sql", "Table `mail_server_template` has moneyA {} or moneyH {} larger than MAX_MONEY_AMOUNT {} for id {}, skipped.", servMail.moneyA, servMail.moneyH, MAX_MONEY_AMOUNT, servMail.id);
10249 return;
10250 }
10251
10252 ItemTemplate const* itemTemplateA = sObjectMgr->GetItemTemplate(servMail.itemA);
10253 if (!itemTemplateA && servMail.itemA)
10254 {
10255 LOG_ERROR("sql.sql", "Table `mail_server_template` has invalid item in itemA {} for id {}, skipped.", servMail.itemA, servMail.id);
10256 return;
10257 }
10258 ItemTemplate const* itemTemplateH = sObjectMgr->GetItemTemplate(servMail.itemH);
10259 if (!itemTemplateH && servMail.itemH)
10260 {
10261 LOG_ERROR("sql.sql", "Table `mail_server_template` has invalid item in itemH {} for id {}, skipped.", servMail.itemH, servMail.id);
10262 return;
10263 }
10264
10265 if (!servMail.itemA && servMail.itemCountA)
10266 {
10267 LOG_ERROR("sql.sql", "Table `mail_server_template` has itemCountA {} with no ItemA, set to 0", servMail.itemCountA);
10268 servMail.itemCountA = 0;
10269 }
10270 if (!servMail.itemH && servMail.itemCountH)
10271 {
10272 LOG_ERROR("sql.sql", "Table `mail_server_template` has itemCountH {} with no ItemH, set to 0", servMail.itemCountH);
10273 servMail.itemCountH = 0;
10274 }
10275 } while (result->NextRow());
10276
10277 LOG_INFO("server.loading", ">> Loaded {} Mail Server Template in {} ms", _serverMailStore.size(), GetMSTimeDiffToNow(oldMSTime));
10278 LOG_INFO("server.loading", " ");
10279}
#define MAX_MONEY_AMOUNT
Definition: Player.h:922
Definition: Mail.h:215

References _serverMailStore, CharacterDatabase, CONFIG_MAX_PLAYER_LEVEL, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, MAX_MONEY_AMOUNT, sObjectMgr, and sWorld.

◆ LoadNPCSpellClickSpells()

void ObjectMgr::LoadNPCSpellClickSpells ( )
7945{
7946 uint32 oldMSTime = getMSTime();
7947
7948 _spellClickInfoStore.clear();
7949 // 0 1 2 3
7950 QueryResult result = WorldDatabase.Query("SELECT npc_entry, spell_id, cast_flags, user_type FROM npc_spellclick_spells");
7951
7952 if (!result)
7953 {
7954 LOG_WARN("server.loading", ">> Loaded 0 spellclick spells. DB table `npc_spellclick_spells` is empty.");
7955 LOG_INFO("server.loading", " ");
7956 return;
7957 }
7958
7959 uint32 count = 0;
7960
7961 do
7962 {
7963 Field* fields = result->Fetch();
7964
7965 uint32 npc_entry = fields[0].Get<uint32>();
7966 CreatureTemplate const* cInfo = GetCreatureTemplate(npc_entry);
7967 if (!cInfo)
7968 {
7969 LOG_ERROR("sql.sql", "Table npc_spellclick_spells references unknown creature_template {}. Skipping entry.", npc_entry);
7970 continue;
7971 }
7972
7973 uint32 spellid = fields[1].Get<uint32>();
7974 SpellInfo const* spellinfo = sSpellMgr->GetSpellInfo(spellid);
7975 if (!spellinfo)
7976 {
7977 LOG_ERROR("sql.sql", "Table npc_spellclick_spells references unknown spellid {}. Skipping entry.", spellid);
7978 continue;
7979 }
7980
7981 uint8 userType = fields[3].Get<uint16>();
7982 if (userType >= SPELL_CLICK_USER_MAX)
7983 LOG_ERROR("sql.sql", "Table npc_spellclick_spells references unknown user type {}. Skipping entry.", uint32(userType));
7984
7985 uint8 castFlags = fields[2].Get<uint8>();
7986 SpellClickInfo info;
7987 info.spellId = spellid;
7988 info.castFlags = castFlags;
7989 info.userType = SpellClickUserTypes(userType);
7990 _spellClickInfoStore.insert(SpellClickInfoContainer::value_type(npc_entry, info));
7991
7992 ++count;
7993 } while (result->NextRow());
7994
7995 // all spellclick data loaded, now we check if there are creatures with NPC_FLAG_SPELLCLICK but with no data
7996 // NOTE: It *CAN* be the other way around: no spellclick flag but with spellclick data, in case of creature-only vehicle accessories
7997 CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
7998 for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
7999 {
8000 if ((itr->second.npcflag & UNIT_NPC_FLAG_SPELLCLICK) && _spellClickInfoStore.find(itr->second.Entry) == _spellClickInfoStore.end())
8001 {
8002 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);
8003 const_cast<CreatureTemplate*>(&itr->second)->npcflag &= ~UNIT_NPC_FLAG_SPELLCLICK;
8004 }
8005 }
8006
8007 LOG_INFO("server.loading", ">> Loaded {} Spellclick Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8008 LOG_INFO("server.loading", " ");
8009}
@ UNIT_NPC_FLAG_SPELLCLICK
Definition: Unit.h:540
SpellClickUserTypes
Definition: SharedDefines.h:652
@ SPELL_CLICK_USER_MAX
Definition: SharedDefines.h:657
Definition: ObjectMgr.h:399
uint32 spellId
Definition: ObjectMgr.h:400

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

◆ LoadNpcTextLocales()

void ObjectMgr::LoadNpcTextLocales ( )
6047{
6048 uint32 oldMSTime = getMSTime();
6049
6050 _npcTextLocaleStore.clear(); // need for reload case
6051
6052 QueryResult result = WorldDatabase.Query("SELECT ID, Locale, "
6053 // 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
6054 "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 "
6055 "FROM npc_text_locale");
6056
6057 if (!result)
6058 return;
6059
6060 do
6061 {
6062 Field* fields = result->Fetch();
6063
6064 uint32 ID = fields[0].Get<uint32>();
6065
6066 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
6067 if (locale == LOCALE_enUS)
6068 continue;
6069
6071 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
6072 {
6073 AddLocaleString(fields[2 + i * 2].Get<std::string>(), locale, data.Text_0[i]);
6074 AddLocaleString(fields[3 + i * 2].Get<std::string>(), locale, data.Text_1[i]);
6075 }
6076 } while (result->NextRow());
6077
6078 LOG_INFO("server.loading", ">> Loaded {} Npc Text Locale Strings in {} ms", (uint32)_npcTextLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
6079}
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 ( )
5798{
5799 uint32 oldMSTime = getMSTime();
5800
5801 _pageTextLocaleStore.clear(); // need for reload case
5802
5803 // 0 1 2
5804 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Text FROM page_text_locale");
5805
5806 if (!result)
5807 return;
5808
5809 do
5810 {
5811 Field* fields = result->Fetch();
5812
5813 uint32 ID = fields[0].Get<uint32>();
5814
5815 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
5816 if (locale == LOCALE_enUS)
5817 continue;
5818
5820 AddLocaleString(fields[2].Get<std::string>(), locale, data.Text);
5821 } while (result->NextRow());
5822
5823 LOG_INFO("server.loading", ">> Loaded {} Page Text Locale Strings in {} ms", (uint32)_pageTextLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
5824}
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, PageTextLocale::Text, and WorldDatabase.

◆ LoadPageTexts()

void ObjectMgr::LoadPageTexts ( )
5748{
5749 uint32 oldMSTime = getMSTime();
5750
5751 // 0 1 2
5752 QueryResult result = WorldDatabase.Query("SELECT ID, Text, NextPageID FROM page_text");
5753
5754 if (!result)
5755 {
5756 LOG_WARN("server.loading", ">> Loaded 0 page texts. DB table `page_text` is empty!");
5757 LOG_INFO("server.loading", " ");
5758 return;
5759 }
5760
5761 uint32 count = 0;
5762 do
5763 {
5764 Field* fields = result->Fetch();
5765
5766 PageText& pageText = _pageTextStore[fields[0].Get<uint32>()];
5767
5768 pageText.Text = fields[1].Get<std::string>();
5769 pageText.NextPage = fields[2].Get<uint32>();
5770
5771 ++count;
5772 } while (result->NextRow());
5773
5774 for (PageTextContainer::const_iterator itr = _pageTextStore.begin(); itr != _pageTextStore.end(); ++itr)
5775 {
5776 if (itr->second.NextPage)
5777 {
5778 PageTextContainer::const_iterator itr2 = _pageTextStore.find(itr->second.NextPage);
5779 if (itr2 == _pageTextStore.end())
5780 LOG_ERROR("sql.sql", "Page text (Id: {}) has not existing next page (Id: {})", itr->first, itr->second.NextPage);
5781 }
5782 }
5783
5784 LOG_INFO("server.loading", ">> Loaded {} Page Texts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
5785 LOG_INFO("server.loading", " ");
5786}
Definition: ObjectMgr.h:60
uint16 NextPage
Definition: ObjectMgr.h:62
std::string Text
Definition: ObjectMgr.h:61

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

◆ LoadPetLevelInfo()

void ObjectMgr::LoadPetLevelInfo ( )
3505{
3506 uint32 oldMSTime = getMSTime();
3507
3508 // 0 1 2 3 4 5 6 7 8 9 10 11
3509 QueryResult result = WorldDatabase.Query("SELECT creature_entry, level, hp, mana, str, agi, sta, inte, spi, armor, min_dmg, max_dmg FROM pet_levelstats");
3510
3511 if (!result)
3512 {
3513 LOG_WARN("server.loading", ">> Loaded 0 level pet stats definitions. DB table `pet_levelstats` is empty.");
3514 LOG_INFO("server.loading", " ");
3515 return;
3516 }
3517
3518 uint32 count = 0;
3519
3520 do
3521 {
3522 Field* fields = result->Fetch();
3523
3524 uint32 creature_id = fields[0].Get<uint32>();
3525 if (!sObjectMgr->GetCreatureTemplate(creature_id))
3526 {
3527 LOG_ERROR("sql.sql", "Wrong creature id {} in `pet_levelstats` table, ignoring.", creature_id);
3528 continue;
3529 }
3530
3531 uint32 current_level = fields[1].Get<uint8>();
3532 if (current_level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
3533 {
3534 if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
3535 LOG_ERROR("sql.sql", "Wrong (> {}) level {} in `pet_levelstats` table, ignoring.", STRONG_MAX_LEVEL, current_level);
3536 else
3537 {
3538 LOG_DEBUG("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `pet_levelstats` table, ignoring.", current_level);
3539 ++count; // make result loading percent "expected" correct in case disabled detail mode for example.
3540 }
3541 continue;
3542 }
3543 else if (current_level < 1)
3544 {
3545 LOG_ERROR("sql.sql", "Wrong (<1) level {} in `pet_levelstats` table, ignoring.", current_level);
3546 continue;
3547 }
3548
3549 PetLevelInfo*& pInfoMapEntry = _petInfoStore[creature_id];
3550
3551 if (!pInfoMapEntry)
3552 pInfoMapEntry = new PetLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)];
3553
3554 // data for level 1 stored in [0] array element, ...
3555 PetLevelInfo* pLevelInfo = &pInfoMapEntry[current_level - 1];
3556
3557 pLevelInfo->health = fields[2].Get<uint32>();
3558 pLevelInfo->mana = fields[3].Get<uint32>();
3559 pLevelInfo->armor = fields[9].Get<uint32>();
3560 pLevelInfo->min_dmg = fields[10].Get<uint32>();
3561 pLevelInfo->max_dmg = fields[11].Get<uint32>();
3562 for (uint8 i = 0; i < MAX_STATS; i++)
3563 {
3564 pLevelInfo->stats[i] = fields[i + 4].Get<uint32>();
3565 }
3566
3567 ++count;
3568 } while (result->NextRow());
3569
3570 // Fill gaps and check integrity
3571 for (PetLevelInfoContainer::iterator itr = _petInfoStore.begin(); itr != _petInfoStore.end(); ++itr)
3572 {
3573 PetLevelInfo* pInfo = itr->second;
3574
3575 // fatal error if no level 1 data
3576 if (!pInfo || pInfo[0].health == 0)
3577 {
3578 LOG_ERROR("sql.sql", "Creature {} does not have pet stats data for Level 1!", itr->first);
3579 exit(1);
3580 }
3581
3582 // fill level gaps
3583 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
3584 {
3585 if (pInfo[level].health == 0)
3586 {
3587 LOG_ERROR("sql.sql", "Creature {} has no data for Level {} pet stats data, using data of Level {}.", itr->first, level + 1, level);
3588 pInfo[level] = pInfo[level - 1];
3589 }
3590 }
3591 }
3592
3593 LOG_INFO("server.loading", ">> Loaded {} Level Pet Stats Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3594 LOG_INFO("server.loading", " ");
3595}
#define STRONG_MAX_LEVEL
Definition: DBCEnums.h:49
#define MAX_STATS
Definition: SharedDefines.h:237
Definition: ObjectMgr.h:522
uint32 max_dmg
Definition: ObjectMgr.h:533
uint32 mana
Definition: ObjectMgr.h:530
uint32 min_dmg
Definition: ObjectMgr.h:532
uint32 health
Definition: ObjectMgr.h:529
std::array< uint32, MAX_STATS > stats
Definition: ObjectMgr.h:528
uint32 armor
Definition: ObjectMgr.h:531

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

◆ LoadPetNames()

void ObjectMgr::LoadPetNames ( )
7457{
7458 uint32 oldMSTime = getMSTime();
7459 // 0 1 2
7460 QueryResult result = WorldDatabase.Query("SELECT word, entry, half FROM pet_name_generation");
7461
7462 if (!result)
7463 {
7464 LOG_WARN("server.loading", ">> Loaded 0 pet name parts. DB table `pet_name_generation` is empty!");
7465 LOG_INFO("server.loading", " ");
7466 return;
7467 }
7468
7469 uint32 count = 0;
7470
7471 do
7472 {
7473 Field* fields = result->Fetch();
7474 std::string word = fields[0].Get<std::string>();
7475 uint32 entry = fields[1].Get<uint32>();
7476 bool half = fields[2].Get<bool>();
7477 if (half)
7478 _petHalfName1[entry].push_back(word);
7479 else
7480 _petHalfName0[entry].push_back(word);
7481 ++count;
7482 } while (result->NextRow());
7483
7484 LOG_INFO("server.loading", ">> Loaded {} Pet Name Parts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7485 LOG_INFO("server.loading", " ");
7486}

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

◆ LoadPetNamesLocales()

void ObjectMgr::LoadPetNamesLocales ( )
510{
511 uint32 oldMSTime = getMSTime();
512
513 // 0 1 2 3
514 QueryResult result = WorldDatabase.Query("SELECT Locale, Word, Entry, Half FROM pet_name_generation_locale");
515
516 if (!result)
517 {
518 LOG_WARN("server.loading", ">> Loaded 0 pet name locales parts. DB table `pet_name_generation_locale` is empty!");
519 LOG_INFO("server.loading", " ");
520 return;
521 }
522
523 uint32 count = 0;
524
525 do
526 {
527 Field* fields = result->Fetch();
528 LocaleConstant locale = GetLocaleByName(fields[0].Get<std::string>());
529 std::string word = fields[1].Get<std::string>();
530
531 uint32 entry = fields[2].Get<uint32>();
532 bool half = fields[3].Get<bool>();
533 std::pair<uint32, LocaleConstant> pairkey = std::make_pair(entry, locale);
534 if (half)
535 {
536 _petHalfLocaleName1[pairkey].push_back(word);
537 }
538 else
539 {
540 _petHalfLocaleName0[pairkey].push_back(word);
541 }
542 ++count;
543 } while (result->NextRow());
544
545 LOG_INFO("server.loading", ">> Loaded {} Pet Name Locales Parts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
546 LOG_INFO("server.loading", " ");
547}

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

◆ LoadPetNumber()

void ObjectMgr::LoadPetNumber ( )
7489{
7490 uint32 oldMSTime = getMSTime();
7491
7492 QueryResult result = CharacterDatabase.Query("SELECT MAX(id) FROM character_pet");
7493 if (result)
7494 {
7495 Field* fields = result->Fetch();
7496 _hiPetNumber = fields[0].Get<uint32>() + 1;
7497 }
7498
7499 LOG_INFO("server.loading", ">> Loaded The Max Pet Number: {} in {} ms", _hiPetNumber - 1, GetMSTimeDiffToNow(oldMSTime));
7500 LOG_INFO("server.loading", " ");
7501}

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

◆ LoadPlayerInfo()

void ObjectMgr::LoadPlayerInfo ( )
3644{
3645 // Load playercreate
3646 {
3647 uint32 oldMSTime = getMSTime();
3648 // 0 1 2 3 4 5 6
3649 QueryResult result = WorldDatabase.Query("SELECT race, class, map, zone, position_x, position_y, position_z, orientation FROM playercreateinfo");
3650
3651 if (!result)
3652 {
3653 LOG_INFO("server.loading", " ");
3654 LOG_WARN("server.loading", ">> Loaded 0 player create definitions. DB table `playercreateinfo` is empty.");
3655 exit(1);
3656 }
3657 else
3658 {
3659 uint32 count = 0;
3660
3661 do
3662 {
3663 Field* fields = result->Fetch();
3664
3665 uint32 current_race = fields[0].Get<uint8>();
3666 uint32 current_class = fields[1].Get<uint8>();
3667 uint32 mapId = fields[2].Get<uint16>();
3668 uint32 areaId = fields[3].Get<uint32>(); // zone
3669 float positionX = fields[4].Get<float>();
3670 float positionY = fields[5].Get<float>();
3671 float positionZ = fields[6].Get<float>();
3672 float orientation = fields[7].Get<float>();
3673
3674 if (current_race >= MAX_RACES)
3675 {
3676 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo` table, ignoring.", current_race);
3677 continue;
3678 }
3679
3680 ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(current_race);
3681 if (!rEntry)
3682 {
3683 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo` table, ignoring.", current_race);
3684 continue;
3685 }
3686
3687 if (current_class >= MAX_CLASSES)
3688 {
3689 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo` table, ignoring.", current_class);
3690 continue;
3691 }
3692
3693 if (!sChrClassesStore.LookupEntry(current_class))
3694 {
3695 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo` table, ignoring.", current_class);
3696 continue;
3697 }
3698
3699 // accept DB data only for valid position (and non instanceable)
3700 if (!MapMgr::IsValidMapCoord(mapId, positionX, positionY, positionZ, orientation))
3701 {
3702 LOG_ERROR("sql.sql", "Wrong home position for class {} race {} pair in `playercreateinfo` table, ignoring.", current_class, current_race);
3703 continue;
3704 }
3705
3706 if (sMapStore.LookupEntry(mapId)->Instanceable())
3707 {
3708 LOG_ERROR("sql.sql", "Home position in instanceable map for class {} race {} pair in `playercreateinfo` table, ignoring.", current_class, current_race);
3709 continue;
3710 }
3711
3712 PlayerInfo* info = new PlayerInfo();
3713 info->mapId = mapId;
3714 info->areaId = areaId;
3715 info->positionX = positionX;
3716 info->positionY = positionY;
3717 info->positionZ = positionZ;
3718 info->orientation = orientation;
3719 info->displayId_m = rEntry->model_m;
3720 info->displayId_f = rEntry->model_f;
3721 _playerInfo[current_race][current_class] = info;
3722
3723 ++count;
3724 } while (result->NextRow());
3725
3726 LOG_INFO("server.loading", ">> Loaded {} Player Create Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3727 LOG_INFO("server.loading", " ");
3728 }
3729 }
3730
3731 // Load playercreate items
3732 LOG_INFO("server.loading", "Loading Player Create Items Data...");
3733 {
3734 uint32 oldMSTime = getMSTime();
3735 // 0 1 2 3
3736 QueryResult result = WorldDatabase.Query("SELECT race, class, itemid, amount FROM playercreateinfo_item");
3737
3738 if (!result)
3739 {
3740 LOG_WARN("server.loading", ">> Loaded 0 Custom Player Create Items. DB Table `playercreateinfo_item` Is Empty.");
3741 LOG_INFO("server.loading", " ");
3742 }
3743 else
3744 {
3745 uint32 count = 0;
3746
3747 do
3748 {
3749 Field* fields = result->Fetch();
3750
3751 uint32 current_race = fields[0].Get<uint8>();
3752 if (current_race >= MAX_RACES)
3753 {
3754 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo_item` table, ignoring.", current_race);
3755 continue;
3756 }
3757
3758 uint32 current_class = fields[1].Get<uint8>();
3759 if (current_class >= MAX_CLASSES)
3760 {
3761 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo_item` table, ignoring.", current_class);
3762 continue;
3763 }
3764
3765 uint32 item_id = fields[2].Get<uint32>();
3766
3767 if (!GetItemTemplate(item_id))
3768 {
3769 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);
3770 continue;
3771 }
3772
3773 int32 amount = fields[3].Get<int32>();
3774
3775 if (!amount)
3776 {
3777 LOG_ERROR("sql.sql", "Item id {} (class {} race {}) have amount == 0 in `playercreateinfo_item` table, ignoring.", item_id, current_race, current_class);
3778 continue;
3779 }
3780
3781 if (!current_race || !current_class)
3782 {
3783 uint32 min_race = current_race ? current_race : 1;
3784 uint32 max_race = current_race ? current_race + 1 : MAX_RACES;
3785 uint32 min_class = current_class ? current_class : 1;
3786 uint32 max_class = current_class ? current_class + 1 : MAX_CLASSES;
3787 for (uint32 r = min_race; r < max_race; ++r)
3788 for (uint32 c = min_class; c < max_class; ++c)
3789 PlayerCreateInfoAddItemHelper(r, c, item_id, amount);
3790 }
3791 else
3792 PlayerCreateInfoAddItemHelper(current_race, current_class, item_id, amount);
3793
3794 ++count;
3795 } while (result->NextRow());
3796
3797 LOG_INFO("server.loading", ">> Loaded {} Custom Player Create Items in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3798 LOG_INFO("server.loading", " ");
3799 }
3800 }
3801
3802 // Load playercreate skills
3803 LOG_INFO("server.loading", "Loading Player Create Skill Data...");
3804 {
3805 uint32 oldMSTime = getMSTime();
3806
3807 QueryResult result = WorldDatabase.Query("SELECT raceMask, classMask, skill, `rank` FROM playercreateinfo_skills");
3808
3809 if (!result)
3810 {
3811 LOG_WARN("server.loading", ">> Loaded 0 Player Create Skills. DB Table `playercreateinfo_skills` Is Empty.");
3812 }
3813 else
3814 {
3815 uint32 count = 0;
3816
3817 do
3818 {
3819 Field* fields = result->Fetch();
3820 uint32 raceMask = fields[0].Get<uint32>();
3821 uint32 classMask = fields[1].Get<uint32>();
3823 skill.SkillId = fields[2].Get<uint16>();
3824 skill.Rank = fields[3].Get<uint16>();
3825
3826 if (skill.Rank >= MAX_SKILL_STEP)
3827 {
3828 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);
3829 continue;
3830 }
3831
3832 if (raceMask != 0 && !(raceMask & RACEMASK_ALL_PLAYABLE))
3833 {
3834 LOG_ERROR("sql.sql", "Wrong race mask {} in `playercreateinfo_skills` table, ignoring.", raceMask);
3835 continue;
3836 }
3837
3838 if (classMask != 0 && !(classMask & CLASSMASK_ALL_PLAYABLE))
3839 {
3840 LOG_ERROR("sql.sql", "Wrong class mask {} in `playercreateinfo_skills` table, ignoring.", classMask);
3841 continue;
3842 }
3843
3844 if (!sSkillLineStore.LookupEntry(skill.SkillId))
3845 {
3846 LOG_ERROR("sql.sql", "Wrong skill id {} in `playercreateinfo_skills` table, ignoring.", skill.SkillId);
3847 continue;
3848 }
3849
3850 for (uint32 raceIndex = RACE_HUMAN; raceIndex < MAX_RACES; ++raceIndex)
3851 {
3852 if (raceMask == 0 || ((1 << (raceIndex - 1)) & raceMask))
3853 {
3854 for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex)
3855 {
3856 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
3857 {
3858 if (!GetSkillRaceClassInfo(skill.SkillId, raceIndex, classIndex))
3859 continue;
3860
3861 if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
3862 {
3863 info->skills.push_back(skill);
3864 ++count;
3865 }
3866 }
3867 }
3868 }
3869 }
3870 } while (result->NextRow());
3871
3872 LOG_INFO("server.loading", ">> Loaded {} Player Create Skills in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3873 LOG_INFO("server.loading", " ");
3874 }
3875 }
3876
3877 // Load playercreate spells
3878 LOG_INFO("server.loading", "Loading Player Create Spell Data...");
3879 {
3880 uint32 oldMSTime = getMSTime();
3881
3882 QueryResult result = WorldDatabase.Query("SELECT racemask, classmask, Spell FROM playercreateinfo_spell_custom");
3883
3884 if (!result)
3885 {
3886 LOG_WARN("server.loading", ">> Loaded 0 player create spells. DB table `playercreateinfo_spell_custom` is empty.");
3887 }
3888 else
3889 {
3890 uint32 count = 0;
3891
3892 do
3893 {
3894 Field* fields = result->Fetch();
3895 uint32 raceMask = fields[0].Get<uint32>();
3896 uint32 classMask = fields[1].Get<uint32>();
3897 uint32 spellId = fields[2].Get<uint32>();
3898
3899 if (raceMask != 0 && !(raceMask & RACEMASK_ALL_PLAYABLE))
3900 {
3901 LOG_ERROR("sql.sql", "Wrong race mask {} in `playercreateinfo_spell_custom` table, ignoring.", raceMask);
3902 continue;
3903 }
3904
3905 if (classMask != 0 && !(classMask & CLASSMASK_ALL_PLAYABLE))
3906 {
3907 LOG_ERROR("sql.sql", "Wrong class mask {} in `playercreateinfo_spell_custom` table, ignoring.", classMask);
3908 continue;
3909 }
3910
3911 for (uint32 raceIndex = RACE_HUMAN; raceIndex < MAX_RACES; ++raceIndex)
3912 {
3913 if (raceMask == 0 || ((1 << (raceIndex - 1)) & raceMask))
3914 {
3915 for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex)
3916 {
3917 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
3918 {
3919 if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
3920 {
3921 info->customSpells.push_back(spellId);
3922 ++count;
3923 }
3924 }
3925 }
3926 }
3927 }
3928 } while (result->NextRow());
3929
3930 LOG_INFO("server.loading", ">> Loaded {} Custom Player Create Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3931 LOG_INFO("server.loading", " ");
3932 }
3933 }
3934
3935 // Load playercreate cast spell
3936 LOG_INFO("server.loading", "Loading Player Create Cast Spell Data...");
3937 {
3938 uint32 oldMSTime = getMSTime();
3939
3940 QueryResult result = WorldDatabase.Query("SELECT raceMask, classMask, spell FROM playercreateinfo_cast_spell");
3941
3942 if (!result)
3943 {
3944 LOG_WARN("server.loading", ">> Loaded 0 Player Create Cast Spells. DB Table `playercreateinfo_cast_spell` Is Empty.");
3945 }
3946 else
3947 {
3948 uint32 count = 0;
3949
3950 do
3951 {
3952 Field* fields = result->Fetch();
3953 uint32 raceMask = fields[0].Get<uint32>();
3954 uint32 classMask = fields[1].Get<uint32>();
3955 uint32 spellId = fields[2].Get<uint32>();
3956
3957 if (raceMask != 0 && !(raceMask & RACEMASK_ALL_PLAYABLE))
3958 {
3959 LOG_ERROR("sql.sql", "Wrong race mask {} in `playercreateinfo_cast_spell` table, ignoring.", raceMask);
3960 continue;
3961 }
3962
3963 if (classMask != 0 && !(classMask & CLASSMASK_ALL_PLAYABLE))
3964 {
3965 LOG_ERROR("sql.sql", "Wrong class mask {} in `playercreateinfo_cast_spell` table, ignoring.", classMask);
3966 continue;
3967 }
3968
3969 for (uint32 raceIndex = RACE_HUMAN; raceIndex < MAX_RACES; ++raceIndex)
3970 {
3971 if (raceMask == 0 || ((1 << (raceIndex - 1)) & raceMask))
3972 {
3973 for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex)
3974 {
3975 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
3976 {
3977 if (PlayerInfo* info = _playerInfo[raceIndex][classIndex])
3978 {
3979 info->castSpells.push_back(spellId);
3980 ++count;
3981 }
3982 }
3983 }
3984 }
3985 }
3986 } while (result->NextRow());
3987
3988 LOG_INFO("server.loading", ">> Loaded {} Player Create Cast Spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3989 LOG_INFO("server.loading", " ");
3990 }
3991 }
3992
3993 // Load playercreate actions
3994 LOG_INFO("server.loading", "Loading Player Create Action Data...");
3995 {
3996 uint32 oldMSTime = getMSTime();
3997
3998 // 0 1 2 3 4
3999 QueryResult result = WorldDatabase.Query("SELECT race, class, button, action, type FROM playercreateinfo_action");
4000
4001 if (!result)
4002 {
4003 LOG_WARN("server.loading", ">> Loaded 0 Player Create Actions. DB Table `playercreateinfo_action` Is Empty.");
4004 LOG_INFO("server.loading", " ");
4005 }
4006 else
4007 {
4008 uint32 count = 0;
4009
4010 do
4011 {
4012 Field* fields = result->Fetch();
4013
4014 uint32 current_race = fields[0].Get<uint8>();
4015 if (current_race >= MAX_RACES)
4016 {
4017 LOG_ERROR("sql.sql", "Wrong race {} in `playercreateinfo_action` table, ignoring.", current_race);
4018 continue;
4019 }
4020
4021 uint32 current_class = fields[1].Get<uint8>();
4022 if (current_class >= MAX_CLASSES)
4023 {
4024 LOG_ERROR("sql.sql", "Wrong class {} in `playercreateinfo_action` table, ignoring.", current_class);
4025 continue;
4026 }
4027
4028 if (PlayerInfo* info = _playerInfo[current_race][current_class])
4029 info->action.push_back(PlayerCreateInfoAction(fields[2].Get<uint16>(), fields[3].Get<uint32>(), fields[4].Get<uint16>()));
4030
4031 ++count;
4032 } while (result->NextRow());
4033
4034 LOG_INFO("server.loading", ">> Loaded {} Player Create Actions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4035 LOG_INFO("server.loading", " ");
4036 }
4037 }
4038
4039 // Loading levels data (class only dependent)
4040 LOG_INFO("server.loading", "Loading Player Create Level HP/Mana Data...");
4041 {
4042 uint32 oldMSTime = getMSTime();
4043
4044 // 0 1 2 3
4045 QueryResult result = WorldDatabase.Query("SELECT class, level, basehp, basemana FROM player_classlevelstats");
4046
4047 if (!result)
4048 {
4049 LOG_FATAL("server.loading", ">> Loaded 0 level health/mana definitions. DB table `player_classlevelstats` is empty.");
4050 exit(1);
4051 }
4052
4053 uint32 count = 0;
4054
4055 do
4056 {
4057 Field* fields = result->Fetch();
4058
4059 uint32 current_class = fields[0].Get<uint8>();
4060 if (current_class >= MAX_CLASSES)
4061 {
4062 LOG_ERROR("sql.sql", "Wrong class {} in `player_classlevelstats` table, ignoring.", current_class);
4063 continue;
4064 }
4065
4066 uint8 current_level = fields[1].Get<uint8>(); // Can't be > than STRONG_MAX_LEVEL (hardcoded level maximum) due to var type
4067 if (current_level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4068 {
4069 LOG_INFO("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_classlevelstats` table, ignoring.", current_level);
4070 ++count; // make result loading percent "expected" correct in case disabled detail mode for example.
4071 continue;
4072 }
4073
4074 PlayerClassInfo* info = _playerClassInfo[current_class];
4075 if (!info)
4076 {
4077 info = new PlayerClassInfo();
4079 _playerClassInfo[current_class] = info;
4080 }
4081
4082 PlayerClassLevelInfo& levelInfo = info->levelInfo[current_level - 1];
4083
4084 levelInfo.basehealth = fields[2].Get<uint32>();
4085 levelInfo.basemana = fields[3].Get<uint32>();
4086
4087 ++count;
4088 } while (result->NextRow());
4089
4090 // Fill gaps and check integrity
4091 for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
4092 {
4093 // skip non existed classes
4094 if (!sChrClassesStore.LookupEntry(class_))
4095 continue;
4096
4097 PlayerClassInfo* pClassInfo = _playerClassInfo[class_];
4098
4099 // fatal error if no initial level data
4100 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))
4101 {
4102 LOG_ERROR("sql.sql", "Class {} initial level does not have health/mana data!", class_);
4103 exit(1);
4104 }
4105
4106 // fill level gaps
4107 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4108 {
4109 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))
4110 {
4111 LOG_ERROR("sql.sql", "Class {} level {} does not have health/mana data. Using stats data of level {}.", class_, level + 1, level);
4112 pClassInfo->levelInfo[level] = pClassInfo->levelInfo[level - 1];
4113 }
4114 }
4115 }
4116
4117 LOG_INFO("server.loading", ">> Loaded {} Level Health/Mana Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4118 LOG_INFO("server.loading", " ");
4119 }
4120
4121 // Loading levels data (class/race dependent)
4122 LOG_INFO("server.loading", "Loading Player Create Level Stats Data...");
4123 {
4124 struct RaceStats
4125 {
4126 int16 StatModifier[MAX_STATS];
4127 };
4128
4129 std::array<RaceStats, MAX_RACES> raceStatModifiers;
4130
4131 uint32 oldMSTime = getMSTime();
4132
4133 // 0 1 2 3 4 5
4134 QueryResult raceStatsResult = WorldDatabase.Query("SELECT Race, Strength, Agility, Stamina, Intellect, Spirit FROM player_race_stats");
4135
4136 if (!raceStatsResult)
4137 {
4138 LOG_WARN("server.loading", ">> Loaded 0 race stats definitions. DB table `player_race_stats` is empty.");
4139 LOG_INFO("server.loading", " ");
4140 exit(1);
4141 }
4142
4143 do
4144 {
4145 Field* fields = raceStatsResult->Fetch();
4146
4147 uint32 current_race = fields[0].Get<uint8>();
4148 if (current_race >= MAX_RACES)
4149 {
4150 LOG_ERROR("sql.sql", "Wrong race {} in `player_race_stats` table, ignoring.", current_race);
4151 continue;
4152 }
4153
4154 for (uint32 i = 0; i < MAX_STATS; ++i)
4155 raceStatModifiers[current_race].StatModifier[i] = fields[i + 1].Get<int16>();
4156
4157 } while (raceStatsResult->NextRow());
4158
4159 // 0 1 2 3 4 5 6
4160 QueryResult result = WorldDatabase.Query("SELECT Class, Level, Strength, Agility, Stamina, Intellect, Spirit FROM player_class_stats");
4161
4162 if (!result)
4163 {
4164 LOG_ERROR("server.loading", ">> Loaded 0 level stats definitions. DB table `player_class_stats` is empty.");
4165 exit(1);
4166 }
4167
4168 uint32 count = 0;
4169
4170 do
4171 {
4172 Field* fields = result->Fetch();
4173
4174 uint32 current_class = fields[0].Get<uint8>();
4175 if (current_class >= MAX_CLASSES)
4176 {
4177 LOG_ERROR("sql.sql", "Wrong class {} in `player_class_stats` table, ignoring.", current_class);
4178 continue;
4179 }
4180
4181 uint32 current_level = fields[1].Get<uint8>();
4182 if (current_level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4183 {
4184 if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
4185 LOG_ERROR("sql.sql", "Wrong (> {}) level {} in `player_class_stats` table, ignoring.", STRONG_MAX_LEVEL, current_level);
4186 else
4187 LOG_DEBUG("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_class_stats` table, ignoring.", current_level);
4188
4189 continue;
4190 }
4191
4192 for (std::size_t race = 0; race < raceStatModifiers.size(); ++race)
4193 {
4194 if (PlayerInfo* info = _playerInfo[race][current_class])
4195 {
4196 if (!info->levelInfo)
4197 info->levelInfo = new PlayerLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)];
4198
4199 PlayerLevelInfo& levelInfo = info->levelInfo[current_level - 1];
4200 for (int i = 0; i < MAX_STATS; ++i)
4201 levelInfo.stats[i] = fields[i + 2].Get<uint16>() + raceStatModifiers[race].StatModifier[i];
4202 }
4203 }
4204
4205 ++count;
4206 } while (result->NextRow());
4207
4208 // Fill gaps and check integrity
4209 for (int race = 0; race < MAX_RACES; ++race)
4210 {
4211 // skip non existed races
4212 if (!sChrRacesStore.LookupEntry(race))
4213 continue;
4214
4215 for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
4216 {
4217 // skip non existed classes
4218 if (!sChrClassesStore.LookupEntry(class_))
4219 continue;
4220
4221 PlayerInfo* info = _playerInfo[race][class_];
4222 if (!info)
4223 continue;
4224
4225 // skip expansion races if not playing with expansion
4226 if (sWorld->getIntConfig(CONFIG_EXPANSION) < EXPANSION_THE_BURNING_CRUSADE && (race == RACE_BLOODELF || race == RACE_DRAENEI))
4227 continue;
4228
4229 // skip expansion classes if not playing with expansion
4231 continue;
4232
4233 // fatal error if no initial level data
4234 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))
4235 {
4236 LOG_ERROR("sql.sql", "Race {} class {} initial level does not have stats data!", race, class_);
4237 exit(1);
4238 }
4239
4240 // fill level gaps
4241 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4242 {
4243 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))
4244 {
4245 LOG_ERROR("sql.sql", "Race {} class {} level {} does not have stats data. Using stats data of level {}.", race, class_, level + 1, level);
4246 info->levelInfo[level] = info->levelInfo[level - 1];
4247 }
4248 }
4249 }
4250 }
4251
4252 LOG_INFO("server.loading", ">> Loaded {} Level Stats Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4253 LOG_INFO("server.loading", " ");
4254 }
4255
4256 // Loading xp per level data
4257 LOG_INFO("server.loading", "Loading Player Create XP Data...");
4258 {
4259 uint32 oldMSTime = getMSTime();
4260
4261 _playerXPperLevel.resize(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
4262 for (uint8 level = 0; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4263 _playerXPperLevel[level] = 0;
4264
4265 // 0 1
4266 QueryResult result = WorldDatabase.Query("SELECT Level, Experience FROM player_xp_for_level");
4267
4268 if (!result)
4269 {
4270 LOG_WARN("server.loading", ">> Loaded 0 xp for level definitions. DB table `player_xp_for_level` is empty.");
4271 LOG_INFO("server.loading", " ");
4272 exit(1);
4273 }
4274
4275 uint32 count = 0;
4276
4277 do
4278 {
4279 Field* fields = result->Fetch();
4280
4281 uint32 current_level = fields[0].Get<uint8>();
4282 uint32 current_xp = fields[1].Get<uint32>();
4283
4284 if (current_level >= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
4285 {
4286 if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
4287 LOG_ERROR("sql.sql", "Wrong (> {}) level {} in `player_xp_for_level` table, ignoring.", STRONG_MAX_LEVEL, current_level);
4288 else
4289 {
4290 LOG_DEBUG("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_xp_for_levels` table, ignoring.", current_level);
4291 ++count; // make result loading percent "expected" correct in case disabled detail mode for example.
4292 }
4293 continue;
4294 }
4295 //PlayerXPperLevel
4296 _playerXPperLevel[current_level] = current_xp;
4297 ++count;
4298 } while (result->NextRow());
4299
4300 // fill level gaps
4301 for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
4302 {
4303 if (_playerXPperLevel[level] == 0)
4304 {
4305 LOG_ERROR("sql.sql", "Level {} does not have XP for level data. Using data of level [{}] + 100.", level + 1, level);
4306 _playerXPperLevel[level] = _playerXPperLevel[level - 1] + 100;
4307 }
4308 }
4309
4310 LOG_INFO("server.loading", ">> Loaded {} XP For Level Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
4311 LOG_INFO("server.loading", " ");
4312 }
4313}
#define LOG_FATAL(filterType__,...)
Definition: Log.h:155
SkillRaceClassInfoEntry const * GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_)
Definition: DBCStores.cpp:882
DBCStorage< ChrRacesEntry > sChrRacesStore(ChrRacesEntryfmt)
DBCStorage< SkillLineEntry > sSkillLineStore(SkillLinefmt)
DBCStorage< ChrClassesEntry > sChrClassesStore(ChrClassesEntryfmt)
@ CONFIG_START_HEROIC_PLAYER_LEVEL
Definition: IWorld.h:237
@ CONFIG_START_PLAYER_LEVEL
Definition: IWorld.h:236
@ CONFIG_EXPANSION
Definition: IWorld.h:274
#define MAX_SKILL_STEP
Definition: DBCStructure.h:1553
@ CLASS_DEATH_KNIGHT
Definition: SharedDefines.h:118
@ RACE_DRAENEI
Definition: SharedDefines.h:80
@ RACE_BLOODELF
Definition: SharedDefines.h:79
@ RACE_HUMAN
Definition: SharedDefines.h:70
@ EXPANSION_THE_BURNING_CRUSADE
Definition: SharedDefines.h:53
@ EXPANSION_WRATH_OF_THE_LICH_KING
Definition: SharedDefines.h:54
Definition: Player.h:290
uint32 basehealth
Definition: Player.h:292
uint32 basemana
Definition: Player.h:293
Definition: Player.h:304
std::array< uint32, MAX_STATS > stats
Definition: Player.h:310
Definition: Player.h:316
Definition: Player.h:328
uint16 SkillId
Definition: Player.h:329
float orientation
Definition: Player.h:345
uint16 displayId_m
Definition: Player.h:346
float positionX
Definition: Player.h:342
uint32 areaId
Definition: Player.h:341
float positionY
Definition: Player.h:343
float positionZ
Definition: Player.h:344
uint32 mapId
Definition: Player.h:340
uint16 displayId_f
Definition: Player.h:347
void PlayerCreateInfoAddItemHelper(uint32 race_, uint32 class_, uint32 itemId, int32 count)
Definition: ObjectMgr.cpp:3609
Definition: DBCStructure.h:679
uint32 model_f
Definition: DBCStructure.h:685
uint32 model_m
Definition: DBCStructure.h:684

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_FATAL, LOG_INFO, LOG_WARN, PlayerInfo::mapId, MAX_CLASSES, MAX_RACES, MAX_SKILL_STEP, MAX_STATS, ChrRacesEntry::model_f, ChrRacesEntry::model_m, PlayerInfo::orientation, PlayerCreateInfoAddItemHelper(), PlayerInfo::positionX, PlayerInfo::positionY, PlayerInfo::positionZ, RACE_BLOODELF, RACE_DRAENEI, RACE_HUMAN, RACEMASK_ALL_PLAYABLE, sChrClassesStore, sChrRacesStore, PlayerCreateInfoSkill::SkillId, sMapStore, sSkillLineStore, PlayerLevelInfo::stats, STRONG_MAX_LEVEL, sWorld, and WorldDatabase.

◆ LoadPointOfInterestLocales()

void ObjectMgr::LoadPointOfInterestLocales ( )
550{
551 uint32 oldMSTime = getMSTime();
552
553 _pointOfInterestLocaleStore.clear(); // need for reload case
554
555 // 0 1 2
556 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Name FROM points_of_interest_locale");
557
558 if (!result)
559 return;
560
561 do
562 {
563 Field* fields = result->Fetch();
564
565 uint32 ID = fields[0].Get<uint32>();
566
567 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
568 if (locale == LOCALE_enUS)
569 continue;
570
572 AddLocaleString(fields[2].Get<std::string>(), locale, data.Name);
573 } while (result->NextRow());
574
575 LOG_INFO("server.loading", ">> Loaded {} Points Of Interest Locale Strings in {} ms", (uint32)_pointOfInterestLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
576}
Definition: CreatureData.h:344
std::vector< std::string > Name
Definition: CreatureData.h:345

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

◆ LoadPointsOfInterest()

void ObjectMgr::LoadPointsOfInterest ( )
7814{
7815 uint32 oldMSTime = getMSTime();
7816
7817 _pointsOfInterestStore.clear(); // need for reload case
7818
7819 uint32 count = 0;
7820
7821 // 0 1 2 3 4 5 6
7822 QueryResult result = WorldDatabase.Query("SELECT ID, PositionX, PositionY, Icon, Flags, Importance, Name FROM points_of_interest");
7823
7824 if (!result)
7825 {
7826 LOG_WARN("server.loading", ">> Loaded 0 Points of Interest definitions. DB table `points_of_interest` is empty.");
7827 LOG_INFO("server.loading", " ");
7828 return;
7829 }
7830
7831 do
7832 {
7833 Field* fields = result->Fetch();
7834
7835 uint32 point_id = fields[0].Get<uint32>();
7836
7837 PointOfInterest POI;
7838 POI.ID = point_id;
7839 POI.PositionX = fields[1].Get<float>();
7840 POI.PositionY = fields[2].Get<float>();
7841 POI.Icon = fields[3].Get<uint32>();
7842 POI.Flags = fields[4].Get<uint32>();
7843 POI.Importance = fields[5].Get<uint32>();
7844 POI.Name = fields[6].Get<std::string>();
7845
7846 if (!Acore::IsValidMapCoord(POI.PositionX, POI.PositionY))
7847 {
7848 LOG_ERROR("sql.sql", "Table `points_of_interest` (ID: {}) have invalid coordinates (X: {} Y: {}), ignored.", point_id, POI.PositionX, POI.PositionY);
7849 continue;
7850 }
7851
7852 _pointsOfInterestStore[point_id] = POI;
7853
7854 ++count;
7855 } while (result->NextRow());
7856
7857 LOG_INFO("server.loading", ">> Loaded {} Points of Interest Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7858 LOG_INFO("server.loading", " ");
7859}
bool IsValidMapCoord(float c)
Definition: GridDefines.h:216
Definition: ObjectMgr.h:582
uint32 ID
Definition: ObjectMgr.h:583

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

◆ LoadProfanityPlayersNames()

void ObjectMgr::LoadProfanityPlayersNames ( )
8208{
8209 uint32 oldMSTime = getMSTime();
8210
8211 _profanityNamesStore.clear(); // need for reload case
8212
8213 QueryResult result = CharacterDatabase.Query("SELECT name FROM profanity_name");
8214
8215 if (!result)
8216 {
8217 LOG_WARN("server.loading", ">> Loaded 0 profanity player names. DB table `profanity_name` is empty!");
8218 LOG_INFO("server.loading", " ");
8219 return;
8220 }
8221
8222 uint32 count = 0;
8223
8224 Field* fields;
8225 do
8226 {
8227 fields = result->Fetch();
8228 std::string name = fields[0].Get<std::string>();
8229
8230 std::wstring wstr;
8231 if (!Utf8toWStr (name, wstr))
8232 {
8233 LOG_ERROR("sql.sql", "Table `profanity_name` have invalid name: {}", name);
8234 continue;
8235 }
8236
8237 wstrToLower(wstr);
8238
8239 _profanityNamesStore.insert(wstr);
8240 ++count;
8241 } while (result->NextRow());
8242
8243 LOG_INFO("server.loading", ">> Loaded {} profanity player names in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8244 LOG_INFO("server.loading", " ");
8245}

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

◆ LoadQuestAreaTriggers()

void ObjectMgr::LoadQuestAreaTriggers ( )
6205{
6206 uint32 oldMSTime = getMSTime();
6207
6208 _questAreaTriggerStore.clear(); // need for reload case
6209
6210 QueryResult result = WorldDatabase.Query("SELECT id, quest FROM areatrigger_involvedrelation");
6211
6212 if (!result)
6213 {
6214 LOG_WARN("server.loading", ">> Loaded 0 quest trigger points. DB table `areatrigger_involvedrelation` is empty.");
6215 LOG_INFO("server.loading", " ");
6216 return;
6217 }
6218
6219 uint32 count = 0;
6220
6221 do
6222 {
6223 ++count;
6224
6225 Field* fields = result->Fetch();
6226
6227 uint32 trigger_ID = fields[0].Get<uint32>();
6228 uint32 quest_ID = fields[1].Get<uint32>();
6229
6230 AreaTrigger const* atEntry = GetAreaTrigger(trigger_ID);
6231 if (!atEntry)
6232 {
6233 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", trigger_ID);
6234 continue;
6235 }
6236
6237 Quest const* quest = GetQuestTemplate(quest_ID);
6238
6239 if (!quest)
6240 {
6241 LOG_ERROR("sql.sql", "Table `areatrigger_involvedrelation` has record (id: {}) for not existing quest {}", trigger_ID, quest_ID);
6242 continue;
6243 }
6244
6246 {
6247 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);
6248
6249 // this will prevent quest completing without objective
6250 const_cast<Quest*>(quest)->SetSpecialFlag(QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT);
6251
6252 // continue; - quest modified to required objective and trigger can be allowed.
6253 }
6254
6255 _questAreaTriggerStore[trigger_ID] = quest_ID;
6256 } while (result->NextRow());
6257
6258 LOG_INFO("server.loading", ">> Loaded {} Quest Trigger Points in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6259 LOG_INFO("server.loading", " ");
6260}
@ QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT
Definition: QuestDef.h:161
Definition: QuestDef.h:207
bool HasSpecialFlag(uint32 flag) const
Definition: QuestDef.h:221

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 ( )
6276{
6277 uint32 oldMSTime = getMSTime();
6278
6279 for (std::size_t i = 0; i < _questGreetingStore.size(); ++i)
6280 _questGreetingStore[i].clear();
6281
6282 // 0 1 2 3 4
6283 QueryResult result = WorldDatabase.Query("SELECT ID, Type, GreetEmoteType, GreetEmoteDelay, Greeting FROM quest_greeting");
6284 if (!result)
6285 {
6286 LOG_WARN("server.loading", ">> Loaded 0 quest greetings. DB table `quest_greeting` is empty.");
6287 return;
6288 }
6289
6290 uint32 count = 0;
6291
6292 do
6293 {
6294 Field* fields = result->Fetch();
6295
6296 uint32 id = fields[0].Get<uint32>();
6297 uint8 type = fields[1].Get<uint8>();
6298 switch (type)
6299 {
6300 case 0: // Creature
6301 if (!sObjectMgr->GetCreatureTemplate(id))
6302 {
6303 LOG_ERROR("sql.sql", "Table `quest_greeting`: creature template entry {} does not exist.", id);
6304 continue;
6305 }
6306 break;
6307 case 1: // GameObject
6308 if (!sObjectMgr->GetGameObjectTemplate(id))
6309 {
6310 LOG_ERROR("sql.sql", "Table `quest_greeting`: gameobject template entry {} does not exist.", id);
6311 continue;
6312 }
6313 break;
6314 default:
6315 continue;
6316 }
6317
6318 uint16 greetEmoteType = fields[2].Get<uint16>();
6319 uint32 greetEmoteDelay = fields[3].Get<uint32>();
6320 std::string greeting = fields[4].Get<std::string>();
6321
6322 _questGreetingStore[type].emplace(std::piecewise_construct, std::forward_as_tuple(id), std::forward_as_tuple(greetEmoteType, greetEmoteDelay, std::move(greeting)));
6323
6324 ++count;
6325 }
6326 while (result->NextRow());
6327
6328 LOG_INFO("server.loading", ">> Loaded {} quest_greeting in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6329 LOG_INFO("server.loading", " ");
6330}

References _questGreetingStore, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, sObjectMgr, and WorldDatabase.

◆ LoadQuestGreetingsLocales()

void ObjectMgr::LoadQuestGreetingsLocales ( )
6333{
6334 uint32 oldMSTime = getMSTime();
6335
6337
6338 // 0 1 2 3
6339 QueryResult result = WorldDatabase.Query("SELECT ID, Type, Locale, Greeting FROM quest_greeting_locale");
6340 if (!result)
6341 {
6342 LOG_WARN("server.loading", ">> Loaded 0 quest_greeting locales. DB table `quest_greeting_locale` is empty.");
6343 return;
6344 }
6345
6346 uint32 count = 0;
6347
6348 do
6349 {
6350 Field* fields = result->Fetch();
6351
6352 uint32 id = fields[0].Get<uint32>();
6353 uint8 type = fields[1].Get<uint8>();
6354 switch (type)
6355 {
6356 case 0: // Creature
6357 if (!sObjectMgr->GetCreatureTemplate(id))
6358 {
6359 LOG_ERROR("sql.sql", "Table `quest_greeting_locale`: creature template entry {} does not exist.", id);
6360 continue;
6361 }
6362 break;
6363 case 1: // GameObject
6364 if (!sObjectMgr->GetGameObjectTemplate(id))
6365 {
6366 LOG_ERROR("sql.sql", "Table `quest_greeting_locale`: gameobject template entry {} does not exist.", id);
6367 continue;
6368 }
6369 break;
6370 default:
6371 continue;
6372 }
6373
6374 std::string localeName = fields[2].Get<std::string>();
6375
6376 LocaleConstant locale = GetLocaleByName(localeName);
6377 if (locale == LOCALE_enUS)
6378 continue;
6379
6381 AddLocaleString(fields[3].Get<std::string>(), locale, data.Greeting);
6382
6383 ++count;
6384 } while (result->NextRow());
6385
6386 LOG_INFO("server.loading", ">> Loaded {} quest greeting Locale Strings in {} ms", (uint32)_questGreetingLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
6387 LOG_INFO("server.loading", " ");
6388}
Definition: ObjectMgr.h:604
std::vector< std::string > Greeting
Definition: ObjectMgr.h:605

References _questGreetingLocaleStore, AddLocaleString(), Field::Get(), GetLocaleByName(), getMSTime(), GetMSTimeDiffToNow(), QuestGreetingLocale::Greeting, LOCALE_enUS, LOG_ERROR, LOG_INFO, LOG_WARN, MAKE_PAIR32(), sObjectMgr, and WorldDatabase.

◆ LoadQuestLocales()

void ObjectMgr::LoadQuestLocales ( )
5169{
5170 uint32 oldMSTime = getMSTime();
5171
5172 _questLocaleStore.clear(); // need for reload case
5173
5174 // 0 1 2 3 4 5 6 7 8 9 10
5175 QueryResult result = WorldDatabase.Query("SELECT ID, locale, Title, Details, Objectives, EndText, CompletedText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4 FROM quest_template_locale");
5176
5177 if (!result)
5178 return;
5179
5180 do
5181 {
5182 Field* fields = result->Fetch();
5183
5184 uint32 ID = fields[0].Get<uint32>();
5185
5186 LocaleConstant locale = GetLocaleByName(fields[1].Get<std::string>());
5187 if (locale == LOCALE_enUS)
5188 continue;
5189
5190 QuestLocale& data = _questLocaleStore[ID];
5191 AddLocaleString(fields[2].Get<std::string>(), locale, data.Title);
5192 AddLocaleString(fields[3].Get<std::string>(), locale, data.Details);
5193 AddLocaleString(fields[4].Get<std::string>(), locale, data.Objectives);
5194 AddLocaleString(fields[5].Get<std::string>(), locale, data.AreaDescription);
5195 AddLocaleString(fields[6].Get<std::string>(), locale, data.CompletedText);
5196
5197 for (uint8 i = 0; i < 4; ++i)
5198 AddLocaleString(fields[i + 7].Get<std::string>(), locale, data.ObjectiveText[i]);
5199 } while (result->NextRow());
5200
5201 LOG_INFO("server.loading", ">> Loaded {} Quest Locale Strings in {} ms", (uint32)_questLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
5202}
Definition: QuestDef.h:180
std::vector< std::string > AreaDescription
Definition: QuestDef.h:188
std::vector< std::string > CompletedText
Definition: QuestDef.h:189
std::vector< std::string > Title
Definition: QuestDef.h:183
std::vector< std::string > Objectives
Definition: QuestDef.h:185
std::vector< std::vector< std::string > > ObjectiveText
Definition: QuestDef.h:190
std::vector< std::string > Details
Definition: QuestDef.h:184

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 ( )
10055{
10056 uint32 oldMSTime = getMSTime();
10057
10058 _questMoneyRewards.clear();
10059
10060 // 0 1 2 3 4 5 6 7 8 9 10
10061 QueryResult result = WorldDatabase.Query("SELECT `Level`, Money0, Money1, Money2, Money3, Money4, Money5, Money6, Money7, Money8, Money9 FROM `quest_money_reward` ORDER BY `Level`");
10062 if (!result)
10063 {
10064 LOG_WARN("server.loading", ">> Loaded 0 quest money rewards. DB table `quest_money_reward` is empty.");
10065 return;
10066 }
10067
10068 uint32 count = 0;
10069 do
10070 {
10071 Field* fields = result->Fetch();
10072 uint32 Level = fields[0].Get<uint32>();
10073
10074 QuestMoneyRewardArray& questMoneyReward = _questMoneyRewards[Level];
10075 questMoneyReward.fill(0);
10076
10077 for (uint8 i = 0; i < MAX_QUEST_MONEY_REWARDS; ++i)
10078 {
10079 questMoneyReward[i] = fields[1 + i].Get<uint32>();
10080 ++count;
10081 }
10082 } while (result->NextRow());
10083
10084 LOG_INFO("server.loading", ">> Loaded {} Quest Money Rewards in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
10085 LOG_INFO("server.loading", " ");
10086}
std::array< uint32, MAX_QUEST_MONEY_REWARDS > QuestMoneyRewardArray
Definition: ObjectMgr.h:723

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

◆ LoadQuestOfferRewardLocale()

void ObjectMgr::LoadQuestOfferRewardLocale ( )
6391{
6392 uint32 oldMSTime = getMSTime();
6393
6394 _questOfferRewardLocaleStore.clear(); // need for reload case
6395
6396 // 0 1 2
6397 QueryResult result = WorldDatabase.Query("SELECT Id, locale, RewardText FROM quest_offer_reward_locale");
6398 if (!result)
6399 return;
6400
6401 do
6402 {
6403 Field* fields = result->Fetch();
6404
6405 uint32 id = fields[0].Get<uint32>();
6406 std::string localeName = fields[1].Get<std::string>();
6407
6408 LocaleConstant locale = GetLocaleByName(localeName);
6409 if (locale == LOCALE_enUS)
6410 continue;
6411
6413 AddLocaleString(fields[2].Get<std::string>(), locale, data.RewardText);
6414 } while (result->NextRow());
6415
6416 LOG_INFO("server.loading", ">> Loaded {} Quest Offer Reward Locale Strings in {} ms", _questOfferRewardLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
6417}
Definition: QuestDef.h:199
std::vector< std::string > RewardText
Definition: QuestDef.h:200

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

◆ LoadQuestPOI()

void ObjectMgr::LoadQuestPOI ( )
7862{
7863 if (!sWorld->getBoolConfig(CONFIG_QUEST_POI_ENABLED))
7864 {
7865 LOG_INFO("server.loading", ">> Loaded 0 quest POI definitions. Disabled by config.");
7866 LOG_INFO("server.loading", " ");
7867 return;
7868 }
7869
7870 uint32 oldMSTime = getMSTime();
7871
7872 _questPOIStore.clear(); // need for reload case
7873
7874 uint32 count = 0;
7875
7876 // 0 1 2 3 4 5 6 7
7877 QueryResult result = WorldDatabase.Query("SELECT QuestID, id, ObjectiveIndex, MapID, WorldMapAreaId, Floor, Priority, Flags FROM quest_poi order by QuestID");
7878
7879 if (!result)
7880 {
7881 LOG_WARN("server.loading", ">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty.");
7882 LOG_INFO("server.loading", " ");
7883 return;
7884 }
7885
7886 // 0 1 2 3
7887 QueryResult points = WorldDatabase.Query("SELECT QuestID, Idx1, X, Y FROM quest_poi_points ORDER BY QuestID DESC, Idx2");
7888
7889 std::vector<std::vector<std::vector<QuestPOIPoint> > > POIs;
7890
7891 if (points)
7892 {
7893 // The first result should have the highest questId
7894 Field* fields = points->Fetch();
7895 uint32 questIdMax = fields[0].Get<uint32>();
7896 POIs.resize(questIdMax + 1);
7897
7898 do
7899 {
7900 fields = points->Fetch();
7901
7902 uint32 questId = fields[0].Get<uint32>();
7903 uint32 id = fields[1].Get<uint32>();
7904 int32 x = fields[2].Get<int32>();
7905 int32 y = fields[3].Get<int32>();
7906
7907 if (POIs[questId].size() <= id + 1)
7908 POIs[questId].resize(id + 10);
7909
7910 QuestPOIPoint point(x, y);
7911 POIs[questId][id].push_back(point);
7912 } while (points->NextRow());
7913 }
7914
7915 do
7916 {
7917 Field* fields = result->Fetch();
7918
7919 uint32 questId = fields[0].Get<uint32>();
7920 uint32 id = fields[1].Get<uint32>();
7921 int32 objIndex = fields[2].Get<int32>();
7922 uint32 mapId = fields[3].Get<uint32>();
7923 uint32 WorldMapAreaId = fields[4].Get<uint32>();
7924 uint32 FloorId = fields[5].Get<uint32>();
7925 uint32 unk3 = fields[6].Get<uint32>();
7926 uint32 unk4 = fields[7].Get<uint32>();
7927
7928 QuestPOI POI(id, objIndex, mapId, WorldMapAreaId, FloorId, unk3, unk4);
7929 if (questId < POIs.size() && id < POIs[questId].size())
7930 {
7931 POI.points = POIs[questId][id];
7932 _questPOIStore[questId].push_back(POI);
7933 }
7934 else
7935 LOG_ERROR("sql.sql", "Table quest_poi references unknown quest points for quest {} POI id {}", questId, id);
7936
7937 ++count;
7938 } while (result->NextRow());
7939
7940 LOG_INFO("server.loading", ">> Loaded {} Quest POI definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7941 LOG_INFO("server.loading", " ");
7942}
@ CONFIG_QUEST_POI_ENABLED
Definition: IWorld.h:177
Definition: ObjectMgr.h:643
Definition: ObjectMgr.h:652

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
8032{
8033 uint32 oldMSTime = getMSTime();
8034
8035 map.clear(); // need for reload case
8036
8037 uint32 count = 0;
8038
8039 QueryResult result = WorldDatabase.Query("SELECT id, quest, pool_entry FROM {} qr LEFT JOIN pool_quest pq ON qr.quest = pq.entry", table);
8040
8041 if (!result)
8042 {
8043 LOG_WARN("server.loading", ">> Loaded 0 quest relations from `{}`, table is empty.", table);
8044 LOG_INFO("server.loading", " ");
8045 return;
8046 }
8047
8048 PooledQuestRelation* poolRelationMap = go ? &sPoolMgr->mQuestGORelation : &sPoolMgr->mQuestCreatureRelation;
8049 if (starter)
8050 poolRelationMap->clear();
8051
8052 do
8053 {
8054 uint32 id = result->Fetch()[0].Get<uint32>();
8055 uint32 quest = result->Fetch()[1].Get<uint32>();
8056 uint32 poolId = result->Fetch()[2].Get<uint32>();
8057
8058 if (_questTemplates.find(quest) == _questTemplates.end())
8059 {
8060 LOG_ERROR("sql.sql", "Table `{}`: Quest {} listed for entry {} does not exist.", table, quest, id);
8061 continue;
8062 }
8063
8064 if (!poolId || !starter)
8065 map.insert(QuestRelations::value_type(id, quest));
8066 else if (starter)
8067 poolRelationMap->insert(PooledQuestRelation::value_type(quest, id));
8068
8069 ++count;
8070 } while (result->NextRow());
8071
8072 LOG_INFO("server.loading", ">> Loaded {} Quest Relations From {} in {} ms", count, table, GetMSTimeDiffToNow(oldMSTime));
8073 LOG_INFO("server.loading", " ");
8074}
#define sPoolMgr
Definition: PoolMgr.h:163
std::multimap< uint32, uint32 > PooledQuestRelation
Definition: PoolMgr.h:98

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

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

◆ LoadQuestRequestItemsLocale()

void ObjectMgr::LoadQuestRequestItemsLocale ( )
6420{
6421 uint32 oldMSTime = getMSTime();
6422
6423 _questRequestItemsLocaleStore.clear(); // need for reload case
6424
6425 // 0 1 2
6426 QueryResult result = WorldDatabase.Query("SELECT Id, locale, CompletionText FROM quest_request_items_locale");
6427 if (!result)
6428 return;
6429
6430 do
6431 {
6432 Field* fields = result->Fetch();
6433
6434 uint32 id = fields[0].Get<uint32>();
6435 std::string localeName = fields[1].Get<std::string>();
6436
6437 LocaleConstant locale = GetLocaleByName(localeName);
6438 if (locale == LOCALE_enUS)
6439 continue;
6440
6442 AddLocaleString(fields[2].Get<std::string>(), locale, data.CompletionText);
6443 } while (result->NextRow());
6444
6445 LOG_INFO("server.loading", ">> Loaded {} Quest Request Items Locale Strings in {} ms", _questRequestItemsLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
6446}
Definition: QuestDef.h:194
std::vector< std::string > CompletionText
Definition: QuestDef.h:195

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

◆ LoadQuests()

void ObjectMgr::LoadQuests ( )
4420{
4421 uint32 oldMSTime = getMSTime();
4422
4423 // For reload case
4424 for (QuestMap::const_iterator itr = _questTemplates.begin(); itr != _questTemplates.end(); ++itr)
4425 delete itr->second;
4426 _questTemplates.clear();
4427
4428 mExclusiveQuestGroups.clear();
4429
4430 QueryResult result = WorldDatabase.Query("SELECT "
4431 //0 1 2 3 4 5 6 7 8
4432 "ID, QuestType, QuestLevel, MinLevel, QuestSortID, QuestInfoID, SuggestedGroupNum, TimeAllowed, AllowableRaces,"
4433 // 9 10 11 12
4434 "RequiredFactionId1, RequiredFactionId2, RequiredFactionValue1, RequiredFactionValue2, "
4435 // 13 14 15 16 17 18 19 20 21
4436 "RewardNextQuest, RewardXPDifficulty, RewardMoney, RewardMoneyDifficulty, RewardBonusMoney, RewardDisplaySpell, RewardSpell, RewardHonor, RewardKillHonor, "
4437 // 22 23 24 25 26 27
4438 "StartItem, Flags, RewardTitle, RequiredPlayerKills, RewardTalents, RewardArenaPoints, "
4439 // 28 29 30 31 32 33 34 35
4440 "RewardItem1, RewardAmount1, RewardItem2, RewardAmount2, RewardItem3, RewardAmount3, RewardItem4, RewardAmount4, "
4441 // 36 37 38 39 40 41 42 43 44 45 46 47
4442 "RewardChoiceItemID1, RewardChoiceItemQuantity1, RewardChoiceItemID2, RewardChoiceItemQuantity2, RewardChoiceItemID3, RewardChoiceItemQuantity3, RewardChoiceItemID4, RewardChoiceItemQuantity4, RewardChoiceItemID5, RewardChoiceItemQuantity5, RewardChoiceItemID6, RewardChoiceItemQuantity6, "
4443 // 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
4444 "RewardFactionID1, RewardFactionValue1, RewardFactionOverride1, RewardFactionID2, RewardFactionValue2, RewardFactionOverride2, RewardFactionID3, RewardFactionValue3, RewardFactionOverride3, RewardFactionID4, RewardFactionValue4, RewardFactionOverride4, RewardFactionID5, RewardFactionValue5, RewardFactionOverride5,"
4445 // 62 64 65 66
4446 "POIContinent, POIx, POIy, POIPriority, "
4447 // 67 68 69 70 71
4448 "LogTitle, LogDescription, QuestDescription, AreaDescription, QuestCompletionLog, "
4449 // 72 73 74 75 76 77 78 79
4450 "RequiredNpcOrGo1, RequiredNpcOrGo2, RequiredNpcOrGo3, RequiredNpcOrGo4, RequiredNpcOrGoCount1, RequiredNpcOrGoCount2, RequiredNpcOrGoCount3, RequiredNpcOrGoCount4, "
4451 // 80 81 82 83 84 85 86 87
4452 "ItemDrop1, ItemDrop2, ItemDrop3, ItemDrop4, ItemDropQuantity1, ItemDropQuantity2, ItemDropQuantity3, ItemDropQuantity4, "
4453 // 88 89 90 91 92 93 94 95 96 97 98 99
4454 "RequiredItemId1, RequiredItemId2, RequiredItemId3, RequiredItemId4, RequiredItemId5, RequiredItemId6, RequiredItemCount1, RequiredItemCount2, RequiredItemCount3, RequiredItemCount4, RequiredItemCount5, RequiredItemCount6, "
4455 // 100 101 102 103 104
4456 "Unknown0, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4"
4457 " FROM quest_template");
4458 if (!result)
4459 {
4460 LOG_WARN("server.loading", ">> Loaded 0 quests definitions. DB table `quest_template` is empty.");
4461 LOG_INFO("server.loading", " ");
4462 return;
4463 }
4464
4465 // create multimap previous quest for each existed quest
4466 // some quests can have many previous maps set by NextQuestId in previous quest
4467 // for example set of race quests can lead to single not race specific quest
4468 do
4469 {
4470 Field* fields = result->Fetch();
4471
4472 Quest* newQuest = new Quest(fields);
4473 _questTemplates[newQuest->GetQuestId()] = newQuest;
4474 } while (result->NextRow());
4475
4476 // pussywizard:
4477 {
4478 uint32 max = 0;
4479 for (QuestMap::const_iterator itr = _questTemplates.begin(); itr != _questTemplates.end(); ++itr)
4480 if (itr->first > max)
4481 max = itr->first;
4482 if (max)
4483 {
4484 _questTemplatesFast.clear();
4485 _questTemplatesFast.resize(max + 1, nullptr);
4486 for (QuestMap::iterator itr = _questTemplates.begin(); itr != _questTemplates.end(); ++itr)
4487 _questTemplatesFast[itr->first] = itr->second;
4488 }
4489 }
4490
4491 for (QuestMap::iterator itr = _questTemplates.begin(); itr != _questTemplates.end(); ++itr)
4492 itr->second->InitializeQueryData();
4493
4494 std::map<uint32, uint32> usedMailTemplates;
4495
4496 // Load `quest_details`
4497 // 0 1 2 3 4 5 6 7 8
4498 result = WorldDatabase.Query("SELECT ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4 FROM quest_details");
4499
4500 if (!result)
4501 {
4502 LOG_WARN("server.loading", ">> Loaded 0 quest details. DB table `quest_details` is empty.");
4503 }
4504 else
4505 {
4506 do
4507 {
4508 Field* fields = result->Fetch();
4509 uint32 questId = fields[0].Get<uint32>();
4510
4511 auto itr = _questTemplates.find(questId);
4512 if (itr != _questTemplates.end())
4513 itr->second->LoadQuestDetails(fields);
4514 else
4515 LOG_ERROR("sql.sql", "Table `quest_details` has data for quest {} but such quest does not exist", questId);
4516 } while (result->NextRow());
4517 }
4518
4519 // Load `quest_request_items`
4520 // 0 1 2 3
4521 result = WorldDatabase.Query("SELECT ID, EmoteOnComplete, EmoteOnIncomplete, CompletionText FROM quest_request_items");
4522
4523 if (!result)
4524 {
4525 LOG_WARN("server.loading", ">> Loaded 0 quest request items. DB table `quest_request_items` is empty.");
4526 }
4527 else
4528 {
4529 do
4530 {
4531 Field* fields = result->Fetch();
4532 uint32 questId = fields[0].Get<uint32>();
4533
4534 auto itr = _questTemplates.find(questId);
4535 if (itr != _questTemplates.end())
4536 itr->second->LoadQuestRequestItems(fields);
4537 else
4538 LOG_ERROR("sql.sql", "Table `quest_request_items` has data for quest {} but such quest does not exist", questId);
4539 } while (result->NextRow());
4540 }
4541
4542 // Load `quest_offer_reward`
4543 // 0 1 2 3 4 5 6 7 8 9
4544 result = WorldDatabase.Query("SELECT ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4, RewardText FROM quest_offer_reward");
4545
4546 if (!result)
4547 {
4548 LOG_WARN("server.loading", ">> Loaded 0 quest reward emotes. DB table `quest_offer_reward` is empty.");
4549 }
4550 else
4551 {
4552 do
4553 {
4554 Field* fields = result->Fetch();
4555 uint32 questId = fields[0].Get<uint32>();
4556
4557 auto itr = _questTemplates.find(questId);
4558 if (itr != _questTemplates.end())
4559 itr->second->LoadQuestOfferReward(fields);
4560 else
4561 LOG_ERROR("sql.sql", "Table `quest_offer_reward` has data for quest {} but such quest does not exist", questId);
4562 } while (result->NextRow());
4563 }
4564
4565 // Load `quest_template_addon`
4566 // 0 1 2 3 4 5 6 7 8
4567 result = WorldDatabase.Query("SELECT ID, MaxLevel, AllowableClasses, SourceSpellID, PrevQuestID, NextQuestID, ExclusiveGroup, RewardMailTemplateID, RewardMailDelay, "
4568 //9 10 11 12 13 14 15 16 17
4569 "RequiredSkillID, RequiredSkillPoints, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, ProvidedItemCount, RewardMailSenderEntry, SpecialFlags FROM quest_template_addon LEFT JOIN quest_mail_sender ON Id=QuestId");
4570
4571 if (!result)
4572 {
4573 LOG_WARN("server.loading", ">> Loaded 0 quest template addons. DB table `quest_template_addon` is empty.");
4574 }
4575 else
4576 {
4577 do
4578 {
4579 Field* fields = result->Fetch();
4580 uint32 questId = fields[0].Get<uint32>();
4581
4582 auto itr = _questTemplates.find(questId);
4583 if (itr != _questTemplates.end())
4584 itr->second->LoadQuestTemplateAddon(fields);
4585 else
4586 LOG_ERROR("sql.sql", "Table `quest_template_addon` has data for quest {} but such quest does not exist", questId);
4587 } while (result->NextRow());
4588 }
4589
4590 // Post processing
4591 for (QuestMap::iterator iter = _questTemplates.begin(); iter != _questTemplates.end(); ++iter)
4592 {
4593 // skip post-loading checks for disabled quests
4594 if (DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, iter->first, nullptr))
4595 continue;
4596
4597 Quest* qinfo = iter->second;
4598
4599 // additional quest integrity checks (GO, creature_template and item_template must be loaded already)
4600
4601 if (qinfo->GetQuestMethod() >= 3)
4602 LOG_ERROR("sql.sql", "Quest {} has `Method` = {}, expected values are 0, 1 or 2.", qinfo->GetQuestId(), qinfo->GetQuestMethod());
4603
4605 {
4606 LOG_ERROR("sql.sql", "Quest {} has `SpecialFlags` = {} > max allowed value. Correct `SpecialFlags` to value <= {}",
4609 }
4610
4611 if (qinfo->Flags & QUEST_FLAGS_DAILY && qinfo->Flags & QUEST_FLAGS_WEEKLY)
4612 {
4613 LOG_ERROR("sql.sql", "Weekly Quest {} is marked as daily quest in `Flags`, removed daily flag.", qinfo->GetQuestId());
4614 qinfo->Flags &= ~QUEST_FLAGS_DAILY;
4615 }
4616
4617 if (qinfo->Flags & QUEST_FLAGS_DAILY)
4618 {
4620 {
4621 LOG_ERROR("sql.sql", "Daily Quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->GetQuestId());
4623 }
4624 }
4625
4626 if (qinfo->Flags & QUEST_FLAGS_WEEKLY)
4627 {
4629 {
4630 LOG_ERROR("sql.sql", "Weekly Quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->GetQuestId());
4632 }
4633 }
4634
4636 {
4638 {
4639 LOG_ERROR("sql.sql", "Monthly quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->GetQuestId());
4641 }
4642 }
4643
4644 if (qinfo->Flags & QUEST_FLAGS_TRACKING)
4645 {
4646 // at auto-reward can be rewarded only RewardChoiceItemId[0]
4647 for (int j = 1; j < QUEST_REWARD_CHOICES_COUNT; ++j )
4648 {
4649 if (uint32 id = qinfo->RewardChoiceItemId[j])
4650 {
4651 LOG_ERROR("sql.sql", "Quest {} has `RewardChoiceItemId{}` = {} but item from `RewardChoiceItemId{}` can't be rewarded with quest flag QUEST_FLAGS_TRACKING.",
4652 qinfo->GetQuestId(), j + 1, id, j + 1);
4653 // no changes, quest ignore this data
4654 }
4655 }
4656 }
4657
4658 // client quest log visual (area case)
4659 if (qinfo->ZoneOrSort > 0)
4660 {
4661 if (!sAreaTableStore.LookupEntry(qinfo->ZoneOrSort))
4662 {
4663 LOG_ERROR("sql.sql", "Quest {} has `ZoneOrSort` = {} (zone case) but zone with this id does not exist.",
4664 qinfo->GetQuestId(), qinfo->ZoneOrSort);
4665 // no changes, quest not dependent from this value but can have problems at client
4666 }
4667 }
4668 // client quest log visual (sort case)
4669 if (qinfo->ZoneOrSort < 0)
4670 {
4671 QuestSortEntry const* qSort = sQuestSortStore.LookupEntry(-int32(qinfo->ZoneOrSort));
4672 if (!qSort)
4673 {
4674 LOG_ERROR("sql.sql", "Quest {} has `ZoneOrSort` = {} (sort case) but quest sort with this id does not exist.",
4675 qinfo->GetQuestId(), qinfo->ZoneOrSort);
4676 // 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)
4677 }
4678 //check for proper RequiredSkillId value (skill case)
4679 if (uint32 skill_id = SkillByQuestSort(-int32(qinfo->ZoneOrSort)))
4680 {
4681 if (qinfo->RequiredSkillId != skill_id)
4682 {
4683 LOG_ERROR("sql.sql", "Quest {} has `ZoneOrSort` = {} but `RequiredSkillId` does not have a corresponding value ({}).",
4684 qinfo->GetQuestId(), qinfo->ZoneOrSort, skill_id);
4685 //override, and force proper value here?
4686 }
4687 }
4688 }
4689
4690 // RequiredClasses, can be 0/CLASSMASK_ALL_PLAYABLE to allow any class
4691 if (qinfo->RequiredClasses)
4692 {
4694 {
4695 LOG_ERROR("sql.sql", "Quest {} does not contain any playable classes in `RequiredClasses` ({}), value set to 0 (all classes).", qinfo->GetQuestId(), qinfo->RequiredClasses);
4696 qinfo->RequiredClasses = 0;
4697 }
4698 }
4699 // AllowableRaces, can be 0/RACEMASK_ALL_PLAYABLE to allow any race
4700 if (qinfo->AllowableRaces)
4701 {
4702 if (!(qinfo->AllowableRaces & RACEMASK_ALL_PLAYABLE))
4703 {
4704 LOG_ERROR("sql.sql", "Quest {} does not contain any playable races in `AllowableRaces` ({}), value set to 0 (all races).", qinfo->GetQuestId(), qinfo->AllowableRaces);
4705 qinfo->AllowableRaces = 0;
4706 }
4707 }
4708 // RequiredSkillId, can be 0
4709 if (qinfo->RequiredSkillId)
4710 {
4711 if (!sSkillLineStore.LookupEntry(qinfo->RequiredSkillId))
4712 {
4713 LOG_ERROR("sql.sql", "Quest {} has `RequiredSkillId` = {} but this skill does not exist",
4714 qinfo->GetQuestId(), qinfo->RequiredSkillId);
4715 }
4716 }
4717
4718 if (qinfo->RequiredSkillPoints)
4719 {
4720 if (qinfo->RequiredSkillPoints > sWorld->GetConfigMaxSkillValue())
4721 {
4722 LOG_ERROR("sql.sql", "Quest {} has `RequiredSkillPoints` = {} but max possible skill is {}, quest can't be done.",
4723 qinfo->GetQuestId(), qinfo->RequiredSkillPoints, sWorld->GetConfigMaxSkillValue());
4724 // no changes, quest can't be done for this requirement
4725 }
4726 }
4727 // else Skill quests can have 0 skill level, this is ok
4728
4729 if (qinfo->RequiredFactionId2 && !sFactionStore.LookupEntry(qinfo->RequiredFactionId2))
4730 {
4731 LOG_ERROR("sql.sql", "Quest {} has `RequiredFactionId2` = {} but faction template {} does not exist, quest can't be done.",
4732 qinfo->GetQuestId(), qinfo->RequiredFactionId2, qinfo->RequiredFactionId2);
4733 // no changes, quest can't be done for this requirement
4734 }
4735
4736 if (qinfo->RequiredFactionId1 && !sFactionStore.LookupEntry(qinfo->RequiredFactionId1))
4737 {
4738 LOG_ERROR("sql.sql", "Quest {} has `RequiredFactionId1` = {} but faction template {} does not exist, quest can't be done.",
4739 qinfo->GetQuestId(), qinfo->RequiredFactionId1, qinfo->RequiredFactionId1);
4740 // no changes, quest can't be done for this requirement
4741 }
4742
4743 if (qinfo->RequiredMinRepFaction && !sFactionStore.LookupEntry(qinfo->RequiredMinRepFaction))
4744 {
4745 LOG_ERROR("sql.sql", "Quest {} has `RequiredMinRepFaction` = {} but faction template {} does not exist, quest can't be done.",
4746 qinfo->GetQuestId(), qinfo->RequiredMinRepFaction, qinfo->RequiredMinRepFaction);
4747 // no changes, quest can't be done for this requirement
4748 }
4749
4750 if (qinfo->RequiredMaxRepFaction && !sFactionStore.LookupEntry(qinfo->RequiredMaxRepFaction))
4751 {
4752 LOG_ERROR("sql.sql", "Quest {} has `RequiredMaxRepFaction` = {} but faction template {} does not exist, quest can't be done.",
4753 qinfo->GetQuestId(), qinfo->RequiredMaxRepFaction, qinfo->RequiredMaxRepFaction);
4754 // no changes, quest can't be done for this requirement
4755 }
4756
4758 {
4759 LOG_ERROR("sql.sql", "Quest {} has `RequiredMinRepValue` = {} but max reputation is {}, quest can't be done.",
4761 // no changes, quest can't be done for this requirement
4762 }
4763
4764 if (qinfo->RequiredMinRepValue && qinfo->RequiredMaxRepValue && qinfo->RequiredMaxRepValue <= qinfo->RequiredMinRepValue)
4765 {
4766 LOG_ERROR("sql.sql", "Quest {} has `RequiredMaxRepValue` = {} and `RequiredMinRepValue` = {}, quest can't be done.",
4767 qinfo->GetQuestId(), qinfo->RequiredMaxRepValue, qinfo->RequiredMinRepValue);
4768 // no changes, quest can't be done for this requirement
4769 }
4770
4771 if (!qinfo->RequiredFactionId1 && qinfo->RequiredFactionValue1 != 0)
4772 {
4773 LOG_ERROR("sql.sql", "Quest {} has `RequiredFactionValue1` = {} but `RequiredFactionId1` is 0, value has no effect",
4774 qinfo->GetQuestId(), qinfo->RequiredFactionValue1);
4775 // warning
4776 }
4777
4778 if (!qinfo->RequiredFactionId2 && qinfo->RequiredFactionValue2 != 0)
4779 {
4780 LOG_ERROR("sql.sql", "Quest {} has `RequiredFactionValue2` = {} but `RequiredFactionId2` is 0, value has no effect",
4781 qinfo->GetQuestId(), qinfo->RequiredFactionValue2);
4782 // warning
4783 }
4784
4785 if (!qinfo->RequiredMinRepFaction && qinfo->RequiredMinRepValue != 0)
4786 {
4787 LOG_ERROR("sql.sql", "Quest {} has `RequiredMinRepValue` = {} but `RequiredMinRepFaction` is 0, value has no effect",
4788 qinfo->GetQuestId(), qinfo->RequiredMinRepValue);
4789 // warning
4790 }
4791
4792 if (!qinfo->RequiredMaxRepFaction && qinfo->RequiredMaxRepValue != 0)
4793 {
4794 LOG_ERROR("sql.sql", "Quest {} has `RequiredMaxRepValue` = {} but `RequiredMaxRepFaction` is 0, value has no effect",
4795 qinfo->GetQuestId(), qinfo->RequiredMaxRepValue);
4796 // warning
4797 }
4798
4799 if (qinfo->RewardTitleId && !sCharTitlesStore.LookupEntry(qinfo->RewardTitleId))
4800 {
4801 LOG_ERROR("sql.sql", "Quest {} has `RewardTitleId` = {} but CharTitle Id {} does not exist, quest can't be rewarded with title.",
4802 qinfo->GetQuestId(), qinfo->GetCharTitleId(), qinfo->GetCharTitleId());
4803 qinfo->RewardTitleId = 0;
4804 // quest can't reward this title
4805 }
4806
4807 if (qinfo->StartItem)
4808 {
4809 if (!sObjectMgr->GetItemTemplate(qinfo->StartItem))
4810 {
4811 LOG_ERROR("sql.sql", "Quest {} has `StartItem` = {} but item with entry {} does not exist, quest can't be done.",
4812 qinfo->GetQuestId(), qinfo->StartItem, qinfo->StartItem);
4813 qinfo->StartItem = 0; // quest can't be done for this requirement
4814 }
4815 else if (qinfo->StartItemCount == 0)
4816 {
4817 LOG_ERROR("sql.sql", "Quest {} has `StartItem` = {} but `StartItemCount` = 0, set to 1 but need fix in DB.",
4818 qinfo->GetQuestId(), qinfo->StartItem);
4819 qinfo->StartItemCount = 1; // update to 1 for allow quest work for backward compatibility with DB
4820 }
4821 }
4822 else if (qinfo->StartItemCount > 0)
4823 {
4824 LOG_ERROR("sql.sql", "Quest {} has `StartItem` = 0 but `StartItemCount` = {}, useless value.",
4825 qinfo->GetQuestId(), qinfo->StartItemCount);
4826 qinfo->StartItemCount = 0; // no quest work changes in fact
4827 }
4828
4829 if (qinfo->SourceSpellid)
4830 {
4831 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->SourceSpellid);
4832 if (!spellInfo)
4833 {
4834 LOG_ERROR("sql.sql", "Quest {} has `SourceSpellid` = {} but spell {} doesn't exist, quest can't be done.",
4835 qinfo->GetQuestId(), qinfo->SourceSpellid, qinfo->SourceSpellid);
4836 qinfo->SourceSpellid = 0; // quest can't be done for this requirement
4837 }
4838 else if (!SpellMgr::ComputeIsSpellValid(spellInfo))
4839 {
4840 LOG_ERROR("sql.sql", "Quest {} has `SourceSpellid` = {} but spell {} is broken, quest can't be done.",
4841 qinfo->GetQuestId(), qinfo->SourceSpellid, qinfo->SourceSpellid);
4842 qinfo->SourceSpellid = 0; // quest can't be done for this requirement
4843 }
4844 }
4845
4846 for (uint8 j = 0; j < QUEST_ITEM_OBJECTIVES_COUNT; ++j)
4847 {
4848 uint32 id = qinfo->RequiredItemId[j];
4849 if (id)
4850 {
4851 if (qinfo->RequiredItemCount[j] == 0)
4852 {
4853 LOG_ERROR("sql.sql", "Quest {} has `RequiredItemId{}` = {} but `RequiredItemCount{}` = 0, quest can't be done.",
4854 qinfo->GetQuestId(), j + 1, id, j + 1);
4855 // no changes, quest can't be done for this requirement
4856 }
4857
4859
4860 if (!sObjectMgr->GetItemTemplate(id))
4861 {
4862 LOG_ERROR("sql.sql", "Quest {} has `RequiredItemId{}` = {} but item with entry {} does not exist, quest can't be done.",
4863 qinfo->GetQuestId(), j + 1, id, id);
4864 qinfo->RequiredItemCount[j] = 0; // prevent incorrect work of quest
4865 }
4866 }
4867 else if (qinfo->RequiredItemCount[j] > 0)
4868 {
4869 LOG_ERROR("sql.sql", "Quest {} has `RequiredItemId{}` = 0 but `RequiredItemCount{}` = {}, quest can't be done.",
4870 qinfo->GetQuestId(), j + 1, j + 1, qinfo->RequiredItemCount[j]);
4871 qinfo->RequiredItemCount[j] = 0; // prevent incorrect work of quest
4872 }
4873 }
4874
4875 for (uint8 j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j)
4876 {
4877 uint32 id = qinfo->ItemDrop[j];
4878 if (id)
4879 {
4880 if (!sObjectMgr->GetItemTemplate(id))
4881 {
4882 LOG_ERROR("sql.sql", "Quest {} has `ItemDrop{}` = {} but item with entry {} does not exist, quest can't be done.",
4883 qinfo->GetQuestId(), j + 1, id, id);
4884 // no changes, quest can't be done for this requirement
4885 }
4886 }
4887 else
4888 {
4889 if (qinfo->ItemDropQuantity[j] > 0)
4890 {
4891 LOG_ERROR("sql.sql", "Quest {} has `ItemDrop{}` = 0 but `ItemDropQuantity{}` = {}.",
4892 qinfo->GetQuestId(), j + 1, j + 1, qinfo->ItemDropQuantity[j]);
4893 // no changes, quest ignore this data
4894 }
4895 }
4896 }
4897
4898 for (uint8 j = 0; j < QUEST_OBJECTIVES_COUNT; ++j)
4899 {
4900 int32 id = qinfo->RequiredNpcOrGo[j];
4901 if (id < 0 && !sObjectMgr->GetGameObjectTemplate(-id))
4902 {
4903 LOG_ERROR("sql.sql", "Quest {} has `RequiredNpcOrGo{}` = {} but gameobject {} does not exist, quest can't be done.",
4904 qinfo->GetQuestId(), j + 1, id, uint32(-id));
4905 qinfo->RequiredNpcOrGo[j] = 0; // quest can't be done for this requirement
4906 }
4907
4908 if (id > 0 && !sObjectMgr->GetCreatureTemplate(id))
4909 {
4910 LOG_ERROR("sql.sql", "Quest {} has `RequiredNpcOrGo{}` = {} but creature with entry {} does not exist, quest can't be done.",
4911 qinfo->GetQuestId(), j + 1, id, uint32(id));
4912 qinfo->RequiredNpcOrGo[j] = 0; // quest can't be done for this requirement
4913 }
4914
4915 if (id)
4916 {
4917 // In fact SpeakTo and Kill are quite same: either you can speak to mob:SpeakTo or you can't:Kill/Cast
4918
4920
4921 if (!qinfo->RequiredNpcOrGoCount[j])
4922 {
4923 LOG_ERROR("sql.sql", "Quest {} has `RequiredNpcOrGo{}` = {} but `RequiredNpcOrGoCount{}` = 0, quest can't be done.",
4924 qinfo->GetQuestId(), j + 1, id, j + 1);
4925 // no changes, quest can be incorrectly done, but we already report this
4926 }
4927 }
4928 else if (qinfo->RequiredNpcOrGoCount[j] > 0)
4929 {
4930 LOG_ERROR("sql.sql", "Quest {} has `RequiredNpcOrGo{}` = 0 but `RequiredNpcOrGoCount{}` = {}.",
4931 qinfo->GetQuestId(), j + 1, j + 1, qinfo->RequiredNpcOrGoCount[j]);
4932 // no changes, quest ignore this data
4933 }
4934 }
4935
4936 for (uint8 j = 0; j < QUEST_REWARD_CHOICES_COUNT; ++j)
4937 {
4938 uint32 id = qinfo->RewardChoiceItemId[j];
4939 if (id)
4940 {
4941 if (!sObjectMgr->GetItemTemplate(id))
4942 {
4943 LOG_ERROR("sql.sql", "Quest {} has `RewardChoiceItemId{}` = {} but item with entry {} does not exist, quest will not reward this item.",
4944 qinfo->GetQuestId(), j + 1, id, id);
4945 qinfo->RewardChoiceItemId[j] = 0; // no changes, quest will not reward this
4946 }
4947
4948 if (!qinfo->RewardChoiceItemCount[j])
4949 {
4950 LOG_ERROR("sql.sql", "Quest {} has `RewardChoiceItemId{}` = {} but `RewardChoiceItemCount{}` = 0, quest can't be done.",
4951 qinfo->GetQuestId(), j + 1, id, j + 1);
4952 // no changes, quest can't be done
4953 }
4954 }
4955 else if (qinfo->RewardChoiceItemCount[j] > 0)
4956 {
4957 LOG_ERROR("sql.sql", "Quest {} has `RewardChoiceItemId{}` = 0 but `RewardChoiceItemCount{}` = {}.",
4958 qinfo->GetQuestId(), j + 1, j + 1, qinfo->RewardChoiceItemCount[j]);
4959 // no changes, quest ignore this data
4960 }
4961 }
4962
4963 for (uint8 j = 0; j < QUEST_REWARDS_COUNT; ++j)
4964 {
4965 uint32 id = qinfo->RewardItemId[j];
4966 if (id)
4967 {
4968 if (!sObjectMgr->GetItemTemplate(id))
4969 {
4970 LOG_ERROR("sql.sql", "Quest {} has `RewardItemId{}` = {} but item with entry {} does not exist, quest will not reward this item.",
4971 qinfo->GetQuestId(), j + 1, id, id);
4972 qinfo->RewardItemId[j] = 0; // no changes, quest will not reward this item
4973 }
4974
4975 if (!qinfo->RewardItemIdCount[j])
4976 {
4977 LOG_ERROR("sql.sql", "Quest {} has `RewardItemId{}` = {} but `RewardItemIdCount{}` = 0, quest will not reward this item.",
4978 qinfo->GetQuestId(), j + 1, id, j + 1);
4979 // no changes
4980 }
4981 }
4982 else if (qinfo->RewardItemIdCount[j] > 0)
4983 {
4984 LOG_ERROR("sql.sql", "Quest {} has `RewardItemId{}` = 0 but `RewardItemIdCount{}` = {}.",
4985 qinfo->GetQuestId(), j + 1, j + 1, qinfo->RewardItemIdCount[j]);
4986 // no changes, quest ignore this data
4987 }
4988 }
4989
4990 for (uint8 j = 0; j < QUEST_REPUTATIONS_COUNT; ++j)
4991 {
4992 if (qinfo->RewardFactionId[j])
4993 {
4994 if (std::abs(qinfo->RewardFactionValueId[j]) > 9)
4995 {
4996 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]);
4997 }
4998 if (!sFactionStore.LookupEntry(qinfo->RewardFactionId[j]))
4999 {
5000 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]);
5001 qinfo->RewardFactionId[j] = 0; // quest will not reward this
5002 }
5003 }
5004
5005 else if (qinfo->RewardFactionValueIdOverride[j] != 0)
5006 {
5007 LOG_ERROR("sql.sql", "Quest {} has `RewardFactionId{}` = 0 but `RewardFactionValueIdOverride{}` = {}.",
5008 qinfo->GetQuestId(), j + 1, j + 1, qinfo->RewardFactionValueIdOverride[j]);
5009 // no changes, quest ignore this data
5010 }
5011 }
5012
5013 if (qinfo->RewardDisplaySpell)
5014 {
5015 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardDisplaySpell);
5016
5017 if (!spellInfo)
5018 {
5019 LOG_ERROR("sql.sql", "Quest {} has `RewardDisplaySpell` = {} but spell {} does not exist, spell removed as display reward.",
5020 qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell);
5021 qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest
5022 }
5023
5024 else if (!SpellMgr::ComputeIsSpellValid(spellInfo))
5025 {
5026 LOG_ERROR("sql.sql", "Quest {} has `RewardDisplaySpell` = {} but spell {} is broken, quest will not have a spell reward.",
5027 qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell);
5028 qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest
5029 }
5030
5031 else if (GetTalentSpellCost(qinfo->RewardDisplaySpell))
5032 {
5033 LOG_ERROR("sql.sql", "Quest {} has `RewardDisplaySpell` = {} but spell {} is talent, quest will not have a spell reward.",
5034 qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell);
5035 qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest
5036 }
5037 }
5038
5039 if (qinfo->RewardSpell > 0)
5040 {
5041 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardSpell);
5042
5043 if (!spellInfo)
5044 {
5045 LOG_ERROR("sql.sql", "Quest {} has `RewardSpell` = {} but spell {} does not exist, quest will not have a spell reward.",
5046 qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
5047 qinfo->RewardSpell = 0; // no spell will be casted on player
5048 }
5049
5050 else if (!SpellMgr::ComputeIsSpellValid(spellInfo))
5051 {
5052 LOG_ERROR("sql.sql", "Quest {} has `RewardSpell` = {} but spell {} is broken, quest will not have a spell reward.",
5053 qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
5054 qinfo->RewardSpell = 0; // no spell will be casted on player
5055 }
5056
5057 else if (GetTalentSpellCost(qinfo->RewardSpell))
5058 {
5059 LOG_ERROR("sql.sql", "Quest {} has `RewardDisplaySpell` = {} but spell {} is talent, quest will not have a spell reward.",
5060 qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
5061 qinfo->RewardSpell = 0; // no spell will be casted on player
5062 }
5063 }
5064
5065 if (qinfo->RewardMailTemplateId)
5066 {
5067 if (!sMailTemplateStore.LookupEntry(qinfo->RewardMailTemplateId))
5068 {
5069 LOG_ERROR("sql.sql", "Quest {} has `RewardMailTemplateId` = {} but mail template {} does not exist, quest will not have a mail reward.",
5070 qinfo->GetQuestId(), qinfo->RewardMailTemplateId, qinfo->RewardMailTemplateId);
5071 qinfo->RewardMailTemplateId = 0; // no mail will send to player
5072 qinfo->RewardMailDelay = 0; // no mail will send to player
5073 qinfo->RewardMailSenderEntry = 0;
5074 }
5075 else if (usedMailTemplates.find(qinfo->RewardMailTemplateId) != usedMailTemplates.end())
5076 {
5077 std::map<uint32, uint32>::const_iterator used_mt_itr = usedMailTemplates.find(qinfo->RewardMailTemplateId);
5078 LOG_ERROR("sql.sql", "Quest {} has `RewardMailTemplateId` = {} but mail template {} already used for quest {}, quest will not have a mail reward.",
5079 qinfo->GetQuestId(), qinfo->RewardMailTemplateId, qinfo->RewardMailTemplateId, used_mt_itr->second);
5080 qinfo->RewardMailTemplateId = 0; // no mail will send to player
5081 qinfo->RewardMailDelay = 0; // no mail will send to player
5082 qinfo->RewardMailSenderEntry = 0;
5083 }
5084 else
5085 usedMailTemplates[qinfo->RewardMailTemplateId] = qinfo->GetQuestId();
5086 }
5087
5088 if (qinfo->RewardNextQuest)
5089 {
5090 QuestMap::iterator qNextItr = _questTemplates.find(qinfo->RewardNextQuest);
5091 if (qNextItr == _questTemplates.end())
5092 {
5093 LOG_ERROR("sql.sql", "Quest {} has `RewardNextQuest` = {} but quest {} does not exist, quest chain will not work.",
5094 qinfo->GetQuestId(), qinfo->RewardNextQuest, qinfo->RewardNextQuest);
5095 qinfo->RewardNextQuest = 0;
5096 }
5097 else
5098 qNextItr->second->prevChainQuests.push_back(qinfo->GetQuestId());
5099 }
5100
5101 // fill additional data stores
5102 if (qinfo->PrevQuestId)
5103 {
5104 if (_questTemplates.find(std::abs(qinfo->GetPrevQuestId())) == _questTemplates.end())
5105 {
5106 LOG_ERROR("sql.sql", "Quest {} has PrevQuestId {}, but no such quest", qinfo->GetQuestId(), qinfo->GetPrevQuestId());
5107 }
5108 else
5109 {
5110 qinfo->prevQuests.push_back(qinfo->PrevQuestId);
5111 }
5112 }
5113
5114 if (qinfo->NextQuestId)
5115 {
5116 QuestMap::iterator qNextItr = _questTemplates.find(qinfo->GetNextQuestId());
5117 if (qNextItr == _questTemplates.end())
5118 {
5119 LOG_ERROR("sql.sql", "Quest {} has NextQuestId {}, but no such quest", qinfo->GetQuestId(), qinfo->GetNextQuestId());
5120 }
5121 else
5122 qNextItr->second->prevQuests.push_back(static_cast<int32>(qinfo->GetQuestId()));
5123 }
5124
5125 if (qinfo->ExclusiveGroup)
5126 mExclusiveQuestGroups.insert(std::pair<int32, uint32>(qinfo->ExclusiveGroup, qinfo->GetQuestId()));
5127 if (qinfo->TimeAllowed)
5129 if (qinfo->RequiredPlayerKills)
5131 }
5132
5133 // check QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT for spell with SPELL_EFFECT_QUEST_COMPLETE
5134 for (uint32 i = 0; i < sSpellMgr->GetSpellInfoStoreSize(); ++i)
5135 {
5136 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(i);
5137 if (!spellInfo)
5138 continue;
5139
5140 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
5141 {
5142 if (spellInfo->Effects[j].Effect != SPELL_EFFECT_QUEST_COMPLETE)
5143 continue;
5144
5145 uint32 quest_id = spellInfo->Effects[j].MiscValue;
5146
5147 Quest const* quest = GetQuestTemplate(quest_id);
5148
5149 // some quest referenced in spells not exist (outdated spells)
5150 if (!quest)
5151 continue;
5152
5154 {
5155 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);
5156
5157 // this will prevent quest completing without objective
5158 // xinef: remove this, leave error but do not break the quest
5159 // const_cast<Quest*>(quest)->SetSpecialFlag(QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT);
5160 }
5161 }
5162 }
5163
5164 LOG_INFO("server.loading", ">> Loaded {} Quests Definitions in {} ms", (unsigned long)_questTemplates.size(), GetMSTimeDiffToNow(oldMSTime));
5165 LOG_INFO("server.loading", " ");
5166}
@ DISABLE_TYPE_QUEST
Definition: DisableMgr.h:30
DBCStorage< QuestSortEntry > sQuestSortStore(QuestSortEntryfmt)
#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:175
@ QUEST_SPECIAL_FLAGS_DELIVER
Definition: QuestDef.h:172
@ QUEST_SPECIAL_FLAGS_REPEATABLE
Definition: QuestDef.h:160
@ QUEST_SPECIAL_FLAGS_KILL
Definition: QuestDef.h:174
@ QUEST_SPECIAL_FLAGS_DB_ALLOWED
Definition: QuestDef.h:169
@ QUEST_SPECIAL_FLAGS_SPEAKTO
Definition: QuestDef.h:173
@ QUEST_SPECIAL_FLAGS_MONTHLY
Definition: QuestDef.h:164
@ QUEST_SPECIAL_FLAGS_PLAYER_KILL
Definition: QuestDef.h:176
@ SPELL_EFFECT_QUEST_COMPLETE
Definition: SharedDefines.h:766
uint32 SkillByQuestSort(int32 QuestSort)
Definition: SharedDefines.h:3012
ExclusiveQuestGroups mExclusiveQuestGroups
Definition: ObjectMgr.h:1137
uint32 ItemDropQuantity[QUEST_SOURCE_ITEM_IDS_COUNT]
Definition: QuestDef.h:300
uint32 RewardMailDelay
Definition: QuestDef.h:392
uint32 RewardMailSenderEntry
Definition: QuestDef.h:400
int32 RequiredNpcOrGo[QUEST_OBJECTIVES_COUNT]
Definition: QuestDef.h:301
uint32 RequiredMaxRepFaction
Definition: QuestDef.h:397
uint32 SourceSpellid
Definition: QuestDef.h:387
uint32 RequiredMinRepFaction
Definition: QuestDef.h:395
int32 RequiredFactionValue2
Definition: QuestDef.h:352
int32 RequiredFactionValue1
Definition: QuestDef.h:350
int32 ZoneOrSort
Definition: QuestDef.h:344
uint32 RequiredNpcOrGoCount[QUEST_OBJECTIVES_COUNT]
Definition: QuestDef.h:302
uint32 StartItemCount
Definition: QuestDef.h:399
void SetSpecialFlag(uint32 flag)
Definition: QuestDef.h:222
uint32 GetCharTitleId() const
Definition: QuestDef.h:250
uint32 RewardTitleId
Definition: QuestDef.h:356
uint32 RewardItemIdCount[QUEST_REWARDS_COUNT]
Definition: QuestDef.h:306
uint32 RewardChoiceItemId[QUEST_REWARD_CHOICES_COUNT]
Definition: QuestDef.h:303
uint32 NextQuestId
Definition: QuestDef.h:389
uint32 RewardMailTemplateId
Definition: QuestDef.h:391
uint32 ItemDrop[QUEST_SOURCE_ITEM_IDS_COUNT]
Definition: QuestDef.h:299
int32 RewardFactionValueIdOverride[QUEST_REPUTATIONS_COUNT]
Definition: QuestDef.h:309
uint32 RequiredSkillPoints
Definition: QuestDef.h:394
int32 RewardSpell
Definition: QuestDef.h:376
uint32 RewardChoiceItemCount[QUEST_REWARD_CHOICES_COUNT]
Definition: QuestDef.h:304
uint32 AllowableRaces
Definition: QuestDef.h:348
uint32 RewardNextQuest
Definition: QuestDef.h:360
uint32 RequiredPlayerKills
Definition: QuestDef.h:357
int32 GetPrevQuestId() const
Definition: QuestDef.h:246
uint32 StartItem
Definition: QuestDef.h:362
uint32 GetQuestId() const
Definition: QuestDef.h:225
int32 RequiredMaxRepValue
Definition: QuestDef.h:398
uint32 RequiredClasses
Definition: QuestDef.h:386
uint32 Flags
Definition: QuestDef.h:355
uint32 RequiredItemCount[QUEST_ITEM_OBJECTIVES_COUNT]
Definition: QuestDef.h:298
uint32 TimeAllowed
Definition: QuestDef.h:354
uint32 RequiredFactionId1
Definition: QuestDef.h:349
uint32 RequiredFactionId2
Definition: QuestDef.h:351
PrevQuests prevQuests
Definition: QuestDef.h:321
uint32 RewardDisplaySpell
Definition: QuestDef.h:375
uint32 RequiredItemId[QUEST_ITEM_OBJECTIVES_COUNT]
Definition: QuestDef.h:297
int32 PrevQuestId
Definition: QuestDef.h:388
uint32 GetNextQuestId() const
Definition: QuestDef.h:247
uint32 RewardFactionId[QUEST_REPUTATIONS_COUNT]
Definition: QuestDef.h:307
int32 ExclusiveGroup
Definition: QuestDef.h:390
uint32 RequiredSkillId
Definition: QuestDef.h:393
int32 RewardFactionValueId[QUEST_REPUTATIONS_COUNT]
Definition: QuestDef.h:308
uint32 RewardItemId[QUEST_REWARDS_COUNT]
Definition: QuestDef.h:305
uint32 GetQuestMethod() const
Definition: QuestDef.h:226
int32 RequiredMinRepValue
Definition: QuestDef.h:396
uint32 SpecialFlags
Definition: QuestDef.h:401
static const int32 Reputation_Cap
Definition: ReputationMgr.h:68
Definition: DBCStructure.h:1428

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

◆ LoadQuestStartersAndEnders()

void ObjectMgr::LoadQuestStartersAndEnders ( )
inline
954 {
955 LOG_INFO("server.loading", "Loading GO Start Quest Data...");
957 LOG_INFO("server.loading", "Loading GO End Quest Data...");
959 LOG_INFO("server.loading", "Loading Creature Start Quest Data...");
961 LOG_INFO("server.loading", "Loading Creature End Quest Data...");
963 }
void LoadCreatureQuestEnders()
Definition: ObjectMgr.cpp:8118
void LoadGameobjectQuestEnders()
Definition: ObjectMgr.cpp:8090
void LoadGameobjectQuestStarters()
Definition: ObjectMgr.cpp:8076
void LoadCreatureQuestStarters()
Definition: ObjectMgr.cpp:8104

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

◆ LoadReferenceVendor()

int ObjectMgr::LoadReferenceVendor ( int32  vendor,
int32  item_id,
std::set< uint32 > *  skip_vendors 
)
9091{
9092 // find all items from the reference vendor
9094 stmt->SetData(0, uint32(item));
9095 PreparedQueryResult result = WorldDatabase.Query(stmt);
9096
9097 if (!result)
9098 return 0;
9099
9100 uint32 count = 0;
9101 do
9102 {
9103 Field* fields = result->Fetch();
9104
9105 int32 item_id = fields[0].Get<int32>();
9106
9107 // if item is a negative, its a reference
9108 if (item_id < 0)
9109 count += LoadReferenceVendor(vendor, -item_id, skip_vendors);
9110 else
9111 {
9112 int32 maxcount = fields[1].Get<uint8>();
9113 uint32 incrtime = fields[2].Get<uint32>();
9114 uint32 ExtendedCost = fields[3].Get<uint32>();
9115
9116 if (!IsVendorItemValid(vendor, item_id, maxcount, incrtime, ExtendedCost, nullptr, skip_vendors))
9117 continue;
9118
9119 VendorItemData& vList = _cacheVendorItemStore[vendor];
9120
9121 vList.AddItem(item_id, maxcount, incrtime, ExtendedCost);
9122 ++count;
9123 }
9124 } while (result->NextRow());
9125
9126 return count;
9127}
@ WORLD_SEL_NPC_VENDOR_REF
Definition: WorldDatabase.h:45
bool IsVendorItemValid(uint32 vendor_entry, uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost, Player *player=nullptr, std::set< uint32 > *skip_vendors=nullptr, uint32 ORnpcflag=0) const
Definition: ObjectMgr.cpp:9330
int LoadReferenceVendor(int32 vendor, int32 item_id, std::set< uint32 > *skip_vendors)
Definition: ObjectMgr.cpp:9090

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 ( )
7629{
7630 uint32 oldMSTime = getMSTime();
7631
7632 // For reload case
7633 _repOnKillStore.clear();
7634
7635 uint32 count = 0;
7636
7637 // 0 1 2
7638 QueryResult result = WorldDatabase.Query("SELECT creature_id, RewOnKillRepFaction1, RewOnKillRepFaction2, "
7639 // 3 4 5 6 7 8 9
7640 "IsTeamAward1, MaxStanding1, RewOnKillRepValue1, IsTeamAward2, MaxStanding2, RewOnKillRepValue2, TeamDependent "
7641 "FROM creature_onkill_reputation");
7642
7643 if (!result)
7644 {
7645 LOG_WARN("server.loading", ">> Loaded 0 creature award reputation definitions. DB table `creature_onkill_reputation` is empty.");
7646 LOG_INFO("server.loading", " ");
7647 return;
7648 }
7649
7650 do
7651 {
7652 Field* fields = result->Fetch();
7653
7654 uint32 creature_id = fields[0].Get<uint32>();
7655
7656 ReputationOnKillEntry repOnKill;
7657 repOnKill.RepFaction1 = fields[1].Get<int16>();
7658 repOnKill.RepFaction2 = fields[2].Get<int16>();
7659 repOnKill.IsTeamAward1 = fields[3].Get<bool>();
7660 repOnKill.ReputationMaxCap1 = fields[4].Get<uint8>();
7661 repOnKill.RepValue1 = fields[5].Get<int32>();
7662 repOnKill.IsTeamAward2 = fields[6].Get<bool>();
7663 repOnKill.ReputationMaxCap2 = fields[7].Get<uint8>();
7664 repOnKill.RepValue2 = fields[8].Get<int32>();
7665 repOnKill.TeamDependent = fields[9].Get<uint8>();
7666
7667 if (!GetCreatureTemplate(creature_id))
7668 {
7669 LOG_ERROR("sql.sql", "Table `creature_onkill_reputation` have data for not existed creature entry ({}), skipped", creature_id);
7670 continue;
7671 }
7672
7673 if (repOnKill.RepFaction1)
7674 {
7675 FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(repOnKill.RepFaction1);
7676 if (!factionEntry1)
7677 {
7678 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.RepFaction1);
7679 continue;
7680 }
7681 }
7682
7683 if (repOnKill.RepFaction2)
7684 {
7685 FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(repOnKill.RepFaction2);
7686 if (!factionEntry2)
7687 {
7688 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.RepFaction2);
7689 continue;
7690 }
7691 }
7692
7693 _repOnKillStore[creature_id] = repOnKill;
7694
7695 ++count;
7696 } while (result->NextRow());
7697
7698 LOG_INFO("server.loading", ">> Loaded {} Creature Award Reputation Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7699 LOG_INFO("server.loading", " ");
7700}
Definition: ObjectMgr.h:562
uint32 RepFaction1
Definition: ObjectMgr.h:563

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

◆ LoadReputationRewardRate()

void ObjectMgr::LoadReputationRewardRate ( )
7541{
7542 uint32 oldMSTime = getMSTime();
7543
7544 _repRewardRateStore.clear(); // for reload case
7545
7546 uint32 count = 0; // 0 1 2 3 4 5 6 7
7547 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");
7548 if (!result)
7549 {
7550 LOG_INFO("server.loading", ">> Loaded `reputation_reward_rate`, table is empty!");
7551 return;
7552 }
7553
7554 do
7555 {
7556 Field* fields = result->Fetch();
7557
7558 uint32 factionId = fields[0].Get<uint32>();
7559
7560 RepRewardRate repRate;
7561
7562 repRate.questRate = fields[1].Get<float>();
7563 repRate.questDailyRate = fields[2].Get<float>();
7564 repRate.questWeeklyRate = fields[3].Get<float>();
7565 repRate.questMonthlyRate = fields[4].Get<float>();
7566 repRate.questRepeatableRate = fields[5].Get<float>();
7567 repRate.creatureRate = fields[6].Get<float>();
7568 repRate.spellRate = fields[7].Get<float>();
7569
7570 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
7571 if (!factionEntry)
7572 {
7573 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_reward_rate`", factionId);
7574 continue;
7575 }
7576
7577 if (repRate.questRate < 0.0f)
7578 {
7579 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_rate with invalid rate {}, skipping data for faction {}", repRate.questRate, factionId);
7580 continue;
7581 }
7582
7583 if (repRate.questDailyRate < 0.0f)
7584 {
7585 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_daily_rate with invalid rate {}, skipping data for faction {}", repRate.questDailyRate, factionId);
7586 continue;
7587 }
7588
7589 if (repRate.questWeeklyRate < 0.0f)
7590 {
7591 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_weekly_rate with invalid rate {}, skipping data for faction {}", repRate.questWeeklyRate, factionId);
7592 continue;
7593 }
7594
7595 if (repRate.questMonthlyRate < 0.0f)
7596 {
7597 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_monthly_rate with invalid rate {}, skipping data for faction {}", repRate.questMonthlyRate, factionId);
7598 continue;
7599 }
7600
7601 if (repRate.questRepeatableRate < 0.0f)
7602 {
7603 LOG_ERROR("sql.sql", "Table reputation_reward_rate has quest_repeatable_rate with invalid rate {}, skipping data for faction {}", repRate.questRepeatableRate, factionId);
7604 continue;
7605 }
7606
7607 if (repRate.creatureRate < 0.0f)
7608 {
7609 LOG_ERROR("sql.sql", "Table reputation_reward_rate has creature_rate with invalid rate {}, skipping data for faction {}", repRate.creatureRate, factionId);
7610 continue;
7611 }
7612
7613 if (repRate.spellRate < 0.0f)
7614 {
7615 LOG_ERROR("sql.sql", "Table reputation_reward_rate has spell_rate with invalid rate {}, skipping data for faction {}", repRate.spellRate, factionId);
7616 continue;
7617 }
7618
7619 _repRewardRateStore[factionId] = repRate;
7620
7621 ++count;
7622 } while (result->NextRow());
7623
7624 LOG_INFO("server.loading", ">> Loaded {} Reputation Reward Rate in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7625 LOG_INFO("server.loading", " ");
7626}
Definition: ObjectMgr.h:551
float questRate
Definition: ObjectMgr.h:552

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

◆ LoadReputationSpilloverTemplate()

void ObjectMgr::LoadReputationSpilloverTemplate ( )
7703{
7704 uint32 oldMSTime = getMSTime();
7705
7706 _repSpilloverTemplateStore.clear(); // for reload case
7707
7708 uint32 count = 0; // 0 1 2 3 4 5 6 7 8 9 10 11 12
7709 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 FROM reputation_spillover_template");
7710
7711 if (!result)
7712 {
7713 LOG_INFO("server.loading", ">> Loaded `reputation_spillover_template`, table is empty.");
7714 LOG_INFO("server.loading", " ");
7715 return;
7716 }
7717
7718 do
7719 {
7720 Field* fields = result->Fetch();
7721
7722 uint32 factionId = fields[0].Get<uint16>();
7723
7724 RepSpilloverTemplate repTemplate;
7725
7726 repTemplate.faction[0] = fields[1].Get<uint16>();
7727 repTemplate.faction_rate[0] = fields[2].Get<float>();
7728 repTemplate.faction_rank[0] = fields[3].Get<uint8>();
7729 repTemplate.faction[1] = fields[4].Get<uint16>();
7730 repTemplate.faction_rate[1] = fields[5].Get<float>();
7731 repTemplate.faction_rank[1] = fields[6].Get<uint8>();
7732 repTemplate.faction[2] = fields[7].Get<uint16>();
7733 repTemplate.faction_rate[2] = fields[8].Get<float>();
7734 repTemplate.faction_rank[2] = fields[9].Get<uint8>();
7735 repTemplate.faction[3] = fields[10].Get<uint16>();
7736 repTemplate.faction_rate[3] = fields[11].Get<float>();
7737 repTemplate.faction_rank[3] = fields[12].Get<uint8>();
7738
7739 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
7740
7741 if (!factionEntry)
7742 {
7743 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", factionId);
7744 continue;
7745 }
7746
7747 if (factionEntry->team == 0)
7748 {
7749 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} in `reputation_spillover_template` does not belong to any team, skipping", factionId);
7750 continue;
7751 }
7752
7753 for (uint32 i = 0; i < MAX_SPILLOVER_FACTIONS; ++i)
7754 {
7755 if (repTemplate.faction[i])
7756 {
7757 FactionEntry const* factionSpillover = sFactionStore.LookupEntry(repTemplate.faction[i]);
7758
7759 if (!factionSpillover)
7760 {
7761 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);
7762 continue;
7763 }
7764
7765 if (factionSpillover->reputationListID < 0)
7766 {
7767 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);
7768 continue;
7769 }
7770
7771 if (repTemplate.faction_rank[i] >= MAX_REPUTATION_RANK)
7772 {
7773 LOG_ERROR("sql.sql", "Rank {} used in `reputation_spillover_template` for spillover faction {} is not valid, skipping", repTemplate.faction_rank[i], repTemplate.faction[i]);
7774 continue;
7775 }
7776 }
7777 }
7778
7779 FactionEntry const* factionEntry0 = sFactionStore.LookupEntry(repTemplate.faction[0]);
7780 if (repTemplate.faction[0] && !factionEntry0)
7781 {
7782 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[0]);
7783 continue;
7784 }
7785 FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(repTemplate.faction[1]);
7786 if (repTemplate.faction[1] && !factionEntry1)
7787 {
7788 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[1]);
7789 continue;
7790 }
7791 FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(repTemplate.faction[2]);
7792 if (repTemplate.faction[2] && !factionEntry2)
7793 {
7794 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[2]);
7795 continue;
7796 }
7797 FactionEntry const* factionEntry3 = sFactionStore.LookupEntry(repTemplate.faction[3]);
7798 if (repTemplate.faction[3] && !factionEntry3)
7799 {
7800 LOG_ERROR("sql.sql", "Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", repTemplate.faction[3]);
7801 continue;
7802 }
7803
7804 _repSpilloverTemplateStore[factionId] = repTemplate;
7805
7806 ++count;
7807 } while (result->NextRow());
7808
7809 LOG_INFO("server.loading", ">> Loaded {} Reputation Spillover Template in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
7810 LOG_INFO("server.loading", " ");
7811}
#define MAX_SPILLOVER_FACTIONS
Definition: SharedDefines.h:219
Definition: ObjectMgr.h:575
uint32 faction[MAX_SPILLOVER_FACTIONS]
Definition: ObjectMgr.h:576
int32 reputationListID
Definition: DBCStructure.h:900

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

◆ LoadReservedPlayersNames()

void ObjectMgr::LoadReservedPlayersNames ( )
8133{
8134 uint32 oldMSTime = getMSTime();
8135
8136 _reservedNamesStore.clear(); // need for reload case
8137
8138 QueryResult result = CharacterDatabase.Query("SELECT name FROM reserved_name");
8139
8140 if (!result)
8141 {
8142 LOG_WARN("server.loading", ">> Loaded 0 reserved player names. DB table `reserved_name` is empty!");
8143 LOG_INFO("server.loading", " ");
8144 return;
8145 }
8146
8147 uint32 count = 0;
8148
8149 Field* fields;
8150 do
8151 {
8152 fields = result->Fetch();
8153 std::string name = fields[0].Get<std::string>();
8154
8155 std::wstring wstr;
8156 if (!Utf8toWStr (name, wstr))
8157 {
8158 LOG_ERROR("sql.sql", "Table `reserved_name` have invalid name: {}", name);
8159 continue;
8160 }
8161
8162 wstrToLower(wstr);
8163
8164 _reservedNamesStore.insert(wstr);
8165 ++count;
8166 } while (result->NextRow());
8167
8168 LOG_INFO("server.loading", ">> Loaded {} reserved player names in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
8169 LOG_INFO("server.loading", " ");
8170}

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

◆ LoadScriptNames()

void ObjectMgr::LoadScriptNames ( )
9411{
9412 uint32 oldMSTime = getMSTime();
9413
9414 // We insert an empty placeholder here so we can use the
9415 // script id 0 as dummy for "no script found".
9416 _scriptNamesStore.emplace_back("");
9417
9418 QueryResult result = WorldDatabase.Query(
9419 "SELECT DISTINCT(ScriptName) FROM achievement_criteria_data WHERE ScriptName <> '' AND type = 11 "
9420 "UNION "
9421 "SELECT DISTINCT(ScriptName) FROM battleground_template WHERE ScriptName <> '' "
9422 "UNION "
9423 "SELECT DISTINCT(ScriptName) FROM creature WHERE ScriptName <> '' "
9424 "UNION "
9425 "SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' "
9426 "UNION "
9427 "SELECT DISTINCT(ScriptName) FROM gameobject WHERE ScriptName <> '' "
9428 "UNION "
9429 "SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' "
9430 "UNION "
9431 "SELECT DISTINCT(ScriptName) FROM item_template WHERE ScriptName <> '' "
9432 "UNION "
9433 "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
9434 "UNION "
9435 "SELECT DISTINCT(ScriptName) FROM spell_script_names WHERE ScriptName <> '' "
9436 "UNION "
9437 "SELECT DISTINCT(ScriptName) FROM transports WHERE ScriptName <> '' "
9438 "UNION "
9439 "SELECT DISTINCT(ScriptName) FROM game_weather WHERE ScriptName <> '' "
9440 "UNION "
9441 "SELECT DISTINCT(ScriptName) FROM conditions WHERE ScriptName <> '' "
9442 "UNION "
9443 "SELECT DISTINCT(ScriptName) FROM outdoorpvp_template WHERE ScriptName <> '' "
9444 "UNION "
9445 "SELECT DISTINCT(script) FROM instance_template WHERE script <> ''");
9446
9447 if (!result)
9448 {
9449 LOG_INFO("server.loading", " ");
9450 LOG_ERROR("sql.sql", ">> Loaded empty set of Script Names!");
9451 return;
9452 }
9453
9454 _scriptNamesStore.reserve(result->GetRowCount() + 1);
9455
9456 do
9457 {
9458 _scriptNamesStore.push_back((*result)[0].Get<std::string>());
9459 } while (result->NextRow());
9460
9461 std::sort(_scriptNamesStore.begin(), _scriptNamesStore.end());
9462 LOG_INFO("server.loading", ">> Loaded {} ScriptNames in {} ms", _scriptNamesStore.size(), GetMSTimeDiffToNow(oldMSTime));
9463 LOG_INFO("server.loading", " ");
9464}

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

◆ LoadScripts()

void ObjectMgr::LoadScripts ( ScriptsType  type)
private
5205{
5206 uint32 oldMSTime = getMSTime();
5207
5208 ScriptMapMap* scripts = GetScriptsMapByType(type);
5209 if (!scripts)
5210 return;
5211
5212 std::string tableName = GetScriptsTableNameByType(type);
5213 if (tableName.empty())
5214 return;
5215
5216 if (sScriptMgr->IsScriptScheduled()) // function cannot be called when scripts are in use.
5217 return;
5218
5219 LOG_INFO("server.loading", "Loading {}...", tableName);
5220
5221 scripts->clear(); // need for reload support
5222
5223 bool isSpellScriptTable = (type == SCRIPTS_SPELL);
5224 // 0 1 2 3 4 5 6 7 8 9
5225 QueryResult result = WorldDatabase.Query("SELECT id, delay, command, datalong, datalong2, dataint, x, y, z, o{} FROM {}", isSpellScriptTable ? ", effIndex" : "", tableName);
5226
5227 if (!result)
5228 {
5229 LOG_WARN("server.loading", ">> Loaded 0 script definitions. DB table `{}` is empty!", tableName);
5230 LOG_INFO("server.loading", " ");
5231 return;
5232 }
5233
5234 uint32 count = 0;
5235
5236 do
5237 {
5238 Field* fields = result->Fetch();
5239 ScriptInfo tmp;
5240 tmp.type = type;
5241 tmp.id = fields[0].Get<uint32>();
5242 if (isSpellScriptTable)
5243 tmp.id |= fields[10].Get<uint8>() << 24;
5244 tmp.delay = fields[1].Get<uint32>();
5245 tmp.command = ScriptCommands(fields[2].Get<uint32>());
5246 tmp.Raw.nData[0] = fields[3].Get<uint32>();
5247 tmp.Raw.nData[1] = fields[4].Get<uint32>();
5248 tmp.Raw.nData[2] = fields[5].Get<int32>();
5249 tmp.Raw.fData[0] = fields[6].Get<float>();
5250 tmp.Raw.fData[1] = fields[7].Get<float>();
5251 tmp.Raw.fData[2] = fields[8].Get<float>();
5252 tmp.Raw.fData[3] = fields[9].Get<float>();
5253
5254 // generic command args check
5255 switch (tmp.command)
5256 {
5258 {
5260 {
5261 LOG_ERROR("sql.sql", "Table `{}` has invalid talk type (datalong = {}) in SCRIPT_COMMAND_TALK for script id {}",
5262 tableName, tmp.Talk.ChatType, tmp.id);
5263 continue;
5264 }
5266 {
5267 LOG_ERROR("sql.sql", "Table `{}` has invalid talk text id (dataint = {}) in SCRIPT_COMMAND_TALK for script id {}",
5268 tableName, tmp.Talk.TextID, tmp.id);
5269 continue;
5270 }
5271 break;
5272 }
5273
5275 {
5276 if (!sEmotesStore.LookupEntry(tmp.Emote.EmoteID))
5277 {
5278 LOG_ERROR("sql.sql", "Table `{}` has invalid emote id (datalong = {}) in SCRIPT_COMMAND_EMOTE for script id {}",
5279 tableName, tmp.Emote.EmoteID, tmp.id);
5280 continue;
5281 }
5282 break;
5283 }
5284
5286 {
5287 if (!sMapStore.LookupEntry(tmp.TeleportTo.MapID))
5288 {
5289 LOG_ERROR("sql.sql", "Table `{}` has invalid map (Id: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
5290 tableName, tmp.TeleportTo.MapID, tmp.id);
5291 continue;
5292 }
5293
5295 {
5296 LOG_ERROR("sql.sql", "Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
5297 tableName, tmp.TeleportTo.DestX, tmp.TeleportTo.DestY, tmp.TeleportTo.DestZ, tmp.TeleportTo.Orientation, tmp.id);
5298 continue;
5299 }
5300 break;
5301 }
5302
5304 {
5305 Quest const* quest = GetQuestTemplate(tmp.QuestExplored.QuestID);
5306 if (!quest)
5307 {
5308 LOG_ERROR("sql.sql", "Table `{}` has invalid quest (ID: {}) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id {}",
5309 tableName, tmp.QuestExplored.QuestID, tmp.id);
5310 continue;
5311 }
5312
5314 {
5315 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.",
5316 tableName, tmp.QuestExplored.QuestID, tmp.id);
5317
5318 // this will prevent quest completing without objective
5319 const_cast<Quest*>(quest)->SetSpecialFlag(QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT);
5320
5321 // continue; - quest objective requirement set and command can be allowed
5322 }
5323
5325 {
5326 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 {}",
5327 tableName, tmp.QuestExplored.Distance, tmp.id);
5328 continue;
5329 }
5330
5332 {
5333 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",
5335 continue;
5336 }
5337
5339 {
5340 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",
5341 tableName, tmp.QuestExplored.Distance, tmp.id, INTERACTION_DISTANCE);
5342 continue;
5343 }
5344
5345 break;
5346 }
5347
5349 {
5351 {
5352 LOG_ERROR("sql.sql", "Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_KILL_CREDIT for script id {}",
5353 tableName, tmp.KillCredit.CreatureEntry, tmp.id);
5354 continue;
5355 }
5356 break;
5357 }
5358
5360 {
5362 if (!data)
5363 {
5364 LOG_ERROR("sql.sql", "Table `{}` has invalid gameobject (GUID: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5365 tableName, tmp.RespawnGameobject.GOGuid, tmp.id);
5366 continue;
5367 }
5368
5369 GameObjectTemplate const* info = GetGameObjectTemplate(data->id);
5370 if (!info)
5371 {
5372 LOG_ERROR("sql.sql", "Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5373 tableName, tmp.RespawnGameobject.GOGuid, data->id, tmp.id);
5374 continue;
5375 }
5376
5377 if (info->type == GAMEOBJECT_TYPE_FISHINGNODE ||
5379 info->type == GAMEOBJECT_TYPE_DOOR ||
5380 info->type == GAMEOBJECT_TYPE_BUTTON ||
5381 info->type == GAMEOBJECT_TYPE_TRAP)
5382 {
5383 LOG_ERROR("sql.sql", "Table `{}` have gameobject type ({}) unsupported by command SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5384 tableName, info->entry, tmp.id);
5385 continue;
5386 }
5387 break;
5388 }
5389
5391 {
5393 {
5394 LOG_ERROR("sql.sql", "Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
5396 continue;
5397 }
5398
5400 if (!GetCreatureTemplate(entry))
5401 {
5402 LOG_ERROR("sql.sql", "Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
5403 tableName, tmp.TempSummonCreature.CreatureEntry, tmp.id);
5404 continue;
5405 }
5406 break;
5407 }
5408
5411 {
5413 if (!data)
5414 {
5415 LOG_ERROR("sql.sql", "Table `{}` has invalid gameobject (GUID: {}) in {} for script id {}",
5416 tableName, tmp.ToggleDoor.GOGuid, GetScriptCommandName(tmp.command), tmp.id);
5417 continue;
5418 }
5419
5420 GameObjectTemplate const* info = GetGameObjectTemplate(data->id);
5421 if (!info)
5422 {
5423 LOG_ERROR("sql.sql", "Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in {} for script id {}",
5424 tableName, tmp.ToggleDoor.GOGuid, data->id, GetScriptCommandName(tmp.command), tmp.id);
5425 continue;
5426 }
5427
5428 if (info->type != GAMEOBJECT_TYPE_DOOR)
5429 {
5430 LOG_ERROR("sql.sql", "Table `{}` has gameobject type ({}) non supported by command {} for script id {}",
5431 tableName, info->entry, GetScriptCommandName(tmp.command), tmp.id);
5432 continue;
5433 }
5434
5435 break;
5436 }
5437
5439 {
5440 if (!sSpellMgr->GetSpellInfo(tmp.RemoveAura.SpellID))
5441 {
5442 LOG_ERROR("sql.sql", "Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
5443 tableName, tmp.RemoveAura.SpellID, tmp.id);
5444 continue;
5445 }
5446 if (tmp.RemoveAura.Flags & ~0x1) // 1 bits (0, 1)
5447 {
5448 LOG_ERROR("sql.sql", "Table `{}` using unknown flags in datalong2 ({}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
5449 tableName, tmp.RemoveAura.Flags, tmp.id);
5450 continue;
5451 }
5452 break;
5453 }
5454
5456 {
5457 if (!sSpellMgr->GetSpellInfo(tmp.CastSpell.SpellID))
5458 {
5459 LOG_ERROR("sql.sql", "Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5460 tableName, tmp.CastSpell.SpellID, tmp.id);
5461 continue;
5462 }
5463 if (tmp.CastSpell.Flags > 4) // targeting type
5464 {
5465 LOG_ERROR("sql.sql", "Table `{}` using unknown target in datalong2 ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5466 tableName, tmp.CastSpell.Flags, tmp.id);
5467 continue;
5468 }
5469 if (tmp.CastSpell.Flags != 4 && tmp.CastSpell.CreatureEntry & ~0x1) // 1 bit (0, 1)
5470 {
5471 LOG_ERROR("sql.sql", "Table `{}` using unknown flags in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5472 tableName, tmp.CastSpell.CreatureEntry, tmp.id);
5473 continue;
5474 }
5475 else if (tmp.CastSpell.Flags == 4 && !GetCreatureTemplate(tmp.CastSpell.CreatureEntry))
5476 {
5477 LOG_ERROR("sql.sql", "Table `{}` using invalid creature entry in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5478 tableName, tmp.CastSpell.CreatureEntry, tmp.id);
5479 continue;
5480 }
5481 break;
5482 }
5483
5485 {
5487 {
5488 LOG_ERROR("sql.sql", "Table `{}` has nonexistent item (entry: {}) in SCRIPT_COMMAND_CREATE_ITEM for script id {}",
5489 tableName, tmp.CreateItem.ItemEntry, tmp.id);
5490 continue;
5491 }
5492 if (!tmp.CreateItem.Amount)
5493 {
5494 LOG_ERROR("sql.sql", "Table `{}` SCRIPT_COMMAND_CREATE_ITEM but amount is {} for script id {}",
5495 tableName, tmp.CreateItem.Amount, tmp.id);
5496 continue;
5497 }
5498 break;
5499 }
5500 default:
5501 break;
5502 }
5503
5504 if (scripts->find(tmp.id) == scripts->end())
5505 {
5506 ScriptMap emptyMap;
5507 (*scripts)[tmp.id] = emptyMap;
5508 }
5509 (*scripts)[tmp.id].insert(std::pair<uint32, ScriptInfo>(tmp.delay, tmp));
5510
5511 ++count;
5512 } while (result->NextRow());
5513
5514 LOG_INFO("server.loading", ">> Loaded {} script definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
5515 LOG_INFO("server.loading", " ");
5516}
@ CHAT_TYPE_WHISPER
Definition: CreatureData.h:414
#define DEFAULT_VISIBILITY_DISTANCE
Definition: ObjectDefines.h:40
#define INTERACTION_DISTANCE
Definition: ObjectDefines.h:24
std::multimap< uint32, ScriptInfo > ScriptMap
Definition: ObjectMgr.h:386
ScriptMapMap * GetScriptsMapByType(ScriptsType type)
Definition: ObjectMgr.cpp:83
ScriptCommands
Definition: ObjectMgr.h:94
@ SCRIPT_COMMAND_EMOTE
Definition: ObjectMgr.h:96
@ SCRIPT_COMMAND_CREATE_ITEM
Definition: ObjectMgr.h:112
@ SCRIPT_COMMAND_CLOSE_DOOR
Definition: ObjectMgr.h:107
@ SCRIPT_COMMAND_CAST_SPELL
Definition: ObjectMgr.h:110
@ SCRIPT_COMMAND_RESPAWN_GAMEOBJECT
Definition: ObjectMgr.h:104
@ SCRIPT_COMMAND_QUEST_EXPLORED
Definition: ObjectMgr.h:102
@ SCRIPT_COMMAND_TALK
Definition: ObjectMgr.h:95
@ SCRIPT_COMMAND_OPEN_DOOR
Definition: ObjectMgr.h:106
@ SCRIPT_COMMAND_TELEPORT_TO
Definition: ObjectMgr.h:101
@ SCRIPT_COMMAND_TEMP_SUMMON_CREATURE
Definition: ObjectMgr.h:105
@ SCRIPT_COMMAND_KILL_CREDIT
Definition: ObjectMgr.h:103
@ SCRIPT_COMMAND_REMOVE_AURA
Definition: ObjectMgr.h:109
std::string GetScriptCommandName(ScriptCommands command)
Definition: ObjectMgr.cpp:103
std::map< uint32, ScriptMap > ScriptMapMap
Definition: ObjectMgr.h:387
std::string GetScriptsTableNameByType(ScriptsType type)
Definition: ObjectMgr.cpp:63
@ SCRIPTS_SPELL
Definition: ObjectMgr.h:151
#define sScriptMgr
Definition: ScriptMgr.h:2702
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition: SharedDefines.h:1549
@ CHAT_MSG_RAID_BOSS_WHISPER
Definition: SharedDefines.h:3166
uint32 entry
Definition: GameObjectData.h:33
Definition: ObjectMgr.h:192
float Orientation
Definition: ObjectMgr.h:252
uint32 Flags
Definition: ObjectMgr.h:209
ScriptsType type
Definition: ObjectMgr.h:193
struct ScriptInfo::@250::@258 TeleportTo
uint32 QuestID
Definition: ObjectMgr.h:257
int32 TextID
Definition: ObjectMgr.h:210
struct ScriptInfo::@250::@252 Raw
struct ScriptInfo::@250::@254 Emote
float DestX
Definition: ObjectMgr.h:231
struct ScriptInfo::@250::@253 Talk
uint32 ItemEntry
Definition: ObjectMgr.h:317
uint32 ChatType
Definition: ObjectMgr.h:208
struct ScriptInfo::@250::@259 QuestExplored
uint32 id
Definition: ObjectMgr.h:194
uint32 delay
Definition: ObjectMgr.h:195
float fData[4]
Definition: ObjectMgr.h:203
struct ScriptInfo::@250::@265 CastSpell
struct ScriptInfo::@250::@261 RespawnGameobject
struct ScriptInfo::@250::@267 CreateItem
float PosY
Definition: ObjectMgr.h:280
ScriptCommands command
Definition: ObjectMgr.h:196
float DestY
Definition: ObjectMgr.h:232
uint32 MapID
Definition: ObjectMgr.h:245
uint32 nData[3]
Definition: ObjectMgr.h:202
struct ScriptInfo::@250::@260 KillCredit
float PosZ
Definition: ObjectMgr.h:281
struct ScriptInfo::@250::@263 ToggleDoor
float PosX
Definition: ObjectMgr.h:279
struct ScriptInfo::@250::@262 TempSummonCreature
uint32 Distance
Definition: ObjectMgr.h:258
uint32 SpellID
Definition: ObjectMgr.h:296
float DestZ
Definition: ObjectMgr.h:233
struct ScriptInfo::@250::@264 RemoveAura
uint32 GOGuid
Definition: ObjectMgr.h:269
uint32 CreatureEntry
Definition: ObjectMgr.h:263
uint32 Amount
Definition: ObjectMgr.h:318
uint32 EmoteID
Definition: ObjectMgr.h:215

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 ( )
5618{
5619 uint32 oldMSTime = getMSTime();
5620
5621 _spellScriptsStore.clear(); // need for reload case
5622
5623 QueryResult result = WorldDatabase.Query("SELECT spell_id, ScriptName FROM spell_script_names");
5624
5625 if (!result)
5626 {
5627 LOG_WARN("server.loading", ">> Loaded 0 spell script names. DB table `spell_script_names` is empty!");
5628 LOG_INFO("server.loading", " ");
5629 return;
5630 }
5631
5632 uint32 count = 0;
5633
5634 do
5635 {
5636 Field* fields = result->Fetch();
5637
5638 int32 spellId = fields[0].Get<int32>();
5639 std::string scriptName = fields[1].Get<std::string>();
5640
5641 bool allRanks = false;
5642 if (spellId <= 0)
5643 {
5644 allRanks = true;
5645 spellId = -spellId;
5646 }
5647
5648 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
5649 if (!spellInfo)
5650 {
5651 LOG_ERROR("sql.sql", "Scriptname: `{}` spell (spell_id:{}) does not exist in `Spell.dbc`.", scriptName, fields[0].Get<int32>());
5652 continue;
5653 }
5654
5655 if (allRanks)
5656 {
5657 if (sSpellMgr->GetFirstSpellInChain(spellId) != uint32(spellId))
5658 {
5659 LOG_ERROR("sql.sql", "Scriptname: `{}` spell (spell_id:{}) is not first rank of spell.", scriptName, fields[0].Get<int32>());
5660 continue;
5661 }
5662 while (spellInfo)
5663 {
5664 _spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, GetScriptId(scriptName)));
5665 spellInfo = spellInfo->GetNextRankSpell();
5666 }
5667 }
5668 else
5669 _spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, GetScriptId(scriptName)));
5670 ++count;
5671 } while (result->NextRow());
5672
5673 LOG_INFO("server.loading", ">> Loaded {} spell script names in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
5674 LOG_INFO("server.loading", " ");
5675}
SpellInfo const * GetNextRankSpell() const
Definition: SpellInfo.cpp:2496

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

◆ LoadSpellScripts()

void ObjectMgr::LoadSpellScripts ( )
5519{
5521
5522 // check ids
5523 for (ScriptMapMap::const_iterator itr = sSpellScripts.begin(); itr != sSpellScripts.end(); ++itr)
5524 {
5525 uint32 spellId = uint32(itr->first) & 0x00FFFFFF;
5526 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
5527
5528 if (!spellInfo)
5529 {
5530 LOG_ERROR("sql.sql", "Table `spell_scripts` has not existing spell (Id: {}) as script id", spellId);
5531 continue;
5532 }
5533
5534 SpellEffIndex i = SpellEffIndex((uint32(itr->first) >> 24) & 0x000000FF);
5535 if (uint32(i) >= MAX_SPELL_EFFECTS)
5536 {
5537 LOG_ERROR("sql.sql", "Table `spell_scripts` has too high effect index {} for spell (Id: {}) as script id", uint32(i), spellId);
5538 }
5539
5540 //check for correct spellEffect
5541 if (!spellInfo->Effects[i].Effect || (spellInfo->Effects[i].Effect != SPELL_EFFECT_SCRIPT_EFFECT && spellInfo->Effects[i].Effect != SPELL_EFFECT_DUMMY))
5542 LOG_ERROR("sql.sql", "Table `spell_scripts` - spell {} effect {} is not SPELL_EFFECT_SCRIPT_EFFECT or SPELL_EFFECT_DUMMY", spellId, uint32(i));
5543 }
5544}
ScriptMapMap sSpellScripts
Definition: ObjectMgr.cpp:59
SpellEffIndex
Definition: SharedDefines.h:29
@ SPELL_EFFECT_DUMMY
Definition: SharedDefines.h:753
@ SPELL_EFFECT_SCRIPT_EFFECT
Definition: SharedDefines.h:827

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 ( )
6449{
6450 uint32 oldMSTime = getMSTime();
6451
6452 _tavernAreaTriggerStore.clear(); // need for reload case
6453
6454 QueryResult result = WorldDatabase.Query("SELECT id, faction FROM areatrigger_tavern");
6455
6456 if (!result)
6457 {
6458 LOG_WARN("server.loading", ">> Loaded 0 tavern triggers. DB table `areatrigger_tavern` is empty.");
6459 LOG_INFO("server.loading", " ");
6460 return;
6461 }
6462
6463 uint32 count = 0;
6464
6465 do
6466 {
6467 ++count;
6468
6469 Field* fields = result->Fetch();
6470
6471 uint32 Trigger_ID = fields[0].Get<uint32>();
6472
6473 AreaTrigger const* atEntry = GetAreaTrigger(Trigger_ID);
6474 if (!atEntry)
6475 {
6476 LOG_ERROR("sql.sql", "Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
6477 continue;
6478 }
6479
6480 uint32 faction = fields[1].Get<uint32>();
6481
6482 _tavernAreaTriggerStore.emplace(Trigger_ID, faction);
6483 } while (result->NextRow());
6484
6485 LOG_INFO("server.loading", ">> Loaded {} Tavern Triggers in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
6486 LOG_INFO("server.loading", " ");
6487}

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

◆ LoadTempSummons()

void ObjectMgr::LoadTempSummons ( )
2058{
2059 uint32 oldMSTime = getMSTime();
2060
2061 // 0 1 2 3 4 5 6 7 8 9
2062 QueryResult result = WorldDatabase.Query("SELECT summonerId, summonerType, groupId, entry, position_x, position_y, position_z, orientation, summonType, summonTime FROM creature_summon_groups");
2063
2064 if (!result)
2065 {
2066 LOG_WARN("server.loading", ">> Loaded 0 temp summons. DB table `creature_summon_groups` is empty.");
2067 return;
2068 }
2069
2070 uint32 count = 0;
2071 do
2072 {
2073 Field* fields = result->Fetch();
2074
2075 uint32 summonerId = fields[0].Get<uint32>();
2076 SummonerType summonerType = SummonerType(fields[1].Get<uint8>());
2077 uint8 group = fields[2].Get<uint8>();
2078
2079 switch (summonerType)
2080 {
2082 if (!GetCreatureTemplate(summonerId))
2083 {
2084 LOG_ERROR("sql.sql", "Table `creature_summon_groups` has summoner with non existing entry {} for creature summoner type, skipped.", summonerId);
2085 continue;
2086 }
2087 break;
2089 if (!GetGameObjectTemplate(summonerId))
2090 {
2091 LOG_ERROR("sql.sql", "Table `creature_summon_groups` has summoner with non existing entry {} for gameobject summoner type, skipped.", summonerId);
2092 continue;
2093 }
2094 break;
2095 case SUMMONER_TYPE_MAP:
2096 if (!sMapStore.LookupEntry(summonerId))
2097 {
2098 LOG_ERROR("sql.sql", "Table `creature_summon_groups` has summoner with non existing entry {} for map summoner type, skipped.", summonerId);
2099 continue;
2100 }
2101 break;
2102 default:
2103 LOG_ERROR("sql.sql", "Table `creature_summon_groups` has unhandled summoner type {} for summoner {}, skipped.", summonerType, summonerId);
2104 continue;
2105 }
2106
2107 TempSummonData data;
2108 data.entry = fields[3].Get<uint32>();
2109
2110 if (!GetCreatureTemplate(data.entry))
2111 {
2112 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);
2113 continue;
2114 }
2115
2116 float posX = fields[4].Get<float>();
2117 float posY = fields[5].Get<float>();
2118 float posZ = fields[6].Get<float>();
2119 float orientation = fields[7].Get<float>();
2120
2121 data.pos.Relocate(posX, posY, posZ, orientation);
2122
2123 data.type = TempSummonType(fields[8].Get<uint8>());
2124
2126 {
2127 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);
2128 continue;
2129 }
2130
2131 data.time = fields[9].Get<uint32>();
2132
2133 TempSummonGroupKey key(summonerId, summonerType, group);
2134 _tempSummonDataStore[key].push_back(data);
2135
2136 ++count;
2137 } while (result->NextRow());
2138
2139 LOG_INFO("server.loading", ">> Loaded {} Temporary Summons in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
2140 LOG_INFO("server.loading", " ");
2141}
SummonerType
Definition: TemporarySummon.h:24
@ SUMMONER_TYPE_MAP
Definition: TemporarySummon.h:27
@ SUMMONER_TYPE_CREATURE
Definition: TemporarySummon.h:25
@ SUMMONER_TYPE_GAMEOBJECT
Definition: TemporarySummon.h:26
TempSummonType
Definition: Object.h:41
@ TEMPSUMMON_MANUAL_DESPAWN
Definition: Object.h:49
Stores data for temp summons.
Definition: TemporarySummon.h:32
TempSummonType type
Summon type, see TempSummonType for available types.
Definition: TemporarySummon.h:35
uint32 time
Despawn time, usable only with certain temp summon types.
Definition: TemporarySummon.h:36
uint32 entry
Entry of summoned creature.
Definition: TemporarySummon.h:33
Position pos
Position, where should be creature spawned.
Definition: TemporarySummon.h:34
void Relocate(float x, float y)
Definition: Position.h:73

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.

◆ LoadTrainerSpell()

void ObjectMgr::LoadTrainerSpell ( )
9050{
9051 uint32 oldMSTime = getMSTime();
9052
9053 // For reload case
9055
9056 QueryResult result = WorldDatabase.Query("SELECT b.ID, a.SpellID, a.MoneyCost, a.ReqSkillLine, a.ReqSkillRank, a.ReqLevel, a.ReqSpell FROM npc_trainer AS a "
9057 "INNER JOIN npc_trainer AS b ON a.ID = -(b.SpellID) "
9058 "UNION SELECT * FROM npc_trainer WHERE SpellID > 0");
9059
9060 if (!result)
9061 {
9062 LOG_WARN("server.loading", ">> Loaded 0 Trainers. DB table `npc_trainer` is empty!");
9063 LOG_INFO("server.loading", " ");
9064 return;
9065 }
9066
9067 uint32 count = 0;
9068
9069 do
9070 {
9071 Field* fields = result->Fetch();
9072
9073 uint32 entry = fields[0].Get<uint32>();
9074 uint32 spell = fields[1].Get<uint32>();
9075 uint32 spellCost = fields[2].Get<uint32>();
9076 uint32 reqSkill = fields[3].Get<uint16>();
9077 uint32 reqSkillValue = fields[4].Get<uint16>();
9078 uint32 reqLevel = fields[5].Get<uint8>();
9079 uint32 reqSpell = fields[6].Get<uint32>();
9080
9081 AddSpellToTrainer(entry, spell, spellCost, reqSkill, reqSkillValue, reqLevel, reqSpell);
9082
9083 ++count;
9084 } while (result->NextRow());
9085
9086 LOG_INFO("server.loading", ">> Loaded {} Trainers in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9087 LOG_INFO("server.loading", " ");
9088}
void AddSpellToTrainer(uint32 entry, uint32 spell, uint32 spellCost, uint32 reqSkill, uint32 reqSkillValue, uint32 reqLevel, uint32 reqSpell)
Definition: ObjectMgr.cpp:8964

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

◆ LoadVehicleAccessories()

void ObjectMgr::LoadVehicleAccessories ( )
3461{
3462 uint32 oldMSTime = getMSTime();
3463
3464 _vehicleAccessoryStore.clear(); // needed for reload case
3465
3466 uint32 count = 0;
3467
3468 // 0 1 2 3 4 5
3469 QueryResult result = WorldDatabase.Query("SELECT `guid`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer` FROM `vehicle_accessory`");
3470
3471 if (!result)
3472 {
3473 LOG_WARN("server.loading", ">> Loaded 0 Vehicle Accessories in {} ms", GetMSTimeDiffToNow(oldMSTime));
3474 LOG_INFO("server.loading", " ");
3475 return;
3476 }
3477
3478 do
3479 {
3480 Field* fields = result->Fetch();
3481
3482 uint32 uiGUID = fields[0].Get<uint32>();
3483 uint32 uiAccessory = fields[1].Get<uint32>();
3484 int8 uiSeat = int8(fields[2].Get<int16>());
3485 bool bMinion = fields[3].Get<bool>();
3486 uint8 uiSummonType = fields[4].Get<uint8>();
3487 uint32 uiSummonTimer = fields[5].Get<uint32>();
3488
3489 if (!sObjectMgr->GetCreatureTemplate(uiAccessory))
3490 {
3491 LOG_ERROR("sql.sql", "Table `vehicle_accessory`: Accessory {} does not exist.", uiAccessory);
3492 continue;
3493 }
3494
3495 _vehicleAccessoryStore[uiGUID].push_back(VehicleAccessory(uiAccessory, uiSeat, bMinion, uiSummonType, uiSummonTimer));
3496
3497 ++count;
3498 } while (result->NextRow());
3499
3500 LOG_INFO("server.loading", ">> Loaded {} Vehicle Accessories in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3501 LOG_INFO("server.loading", " ");
3502}
Definition: VehicleDefines.h:92

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

◆ LoadVehicleTemplateAccessories()

void ObjectMgr::LoadVehicleTemplateAccessories ( )
3405{
3406 uint32 oldMSTime = getMSTime();
3407
3408 _vehicleTemplateAccessoryStore.clear(); // needed for reload case
3409
3410 uint32 count = 0;
3411
3412 // 0 1 2 3 4 5
3413 QueryResult result = WorldDatabase.Query("SELECT `entry`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer` FROM `vehicle_template_accessory`");
3414
3415 if (!result)
3416 {
3417 LOG_WARN("server.loading", ">> Loaded 0 vehicle template accessories. DB table `vehicle_template_accessory` is empty.");
3418 LOG_INFO("server.loading", " ");
3419 return;
3420 }
3421
3422 do
3423 {
3424 Field* fields = result->Fetch();
3425
3426 uint32 uiEntry = fields[0].Get<uint32>();
3427 uint32 uiAccessory = fields[1].Get<uint32>();
3428 int8 uiSeat = int8(fields[2].Get<int8>());
3429 bool bMinion = fields[3].Get<bool>();
3430 uint8 uiSummonType = fields[4].Get<uint8>();
3431 uint32 uiSummonTimer = fields[5].Get<uint32>();
3432
3433 if (!sObjectMgr->GetCreatureTemplate(uiEntry))
3434 {
3435 LOG_ERROR("sql.sql", "Table `vehicle_template_accessory`: creature template entry {} does not exist.", uiEntry);
3436 continue;
3437 }
3438
3439 if (!sObjectMgr->GetCreatureTemplate(uiAccessory))
3440 {
3441 LOG_ERROR("sql.sql", "Table `vehicle_template_accessory`: Accessory {} does not exist.", uiAccessory);
3442 continue;
3443 }
3444
3445 if (_spellClickInfoStore.find(uiEntry) == _spellClickInfoStore.end())
3446 {
3447 LOG_ERROR("sql.sql", "Table `vehicle_template_accessory`: creature template entry {} has no data in npc_spellclick_spells", uiEntry);
3448 continue;
3449 }
3450
3451 _vehicleTemplateAccessoryStore[uiEntry].push_back(VehicleAccessory(uiAccessory, uiSeat, bMinion, uiSummonType, uiSummonTimer));
3452
3453 ++count;
3454 } while (result->NextRow());
3455
3456 LOG_INFO("server.loading", ">> Loaded {} Vehicle Template Accessories in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
3457 LOG_INFO("server.loading", " ");
3458}

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

◆ LoadVendors()

void ObjectMgr::LoadVendors ( )
9130{
9131 uint32 oldMSTime = getMSTime();
9132
9133 // For reload case
9134 for (CacheVendorItemContainer::iterator itr = _cacheVendorItemStore.begin(); itr != _cacheVendorItemStore.end(); ++itr)
9135 itr->second.Clear();
9136 _cacheVendorItemStore.clear();
9137
9138 std::set<uint32> skip_vendors;
9139
9140 QueryResult result = WorldDatabase.Query("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor ORDER BY entry, slot ASC, item, ExtendedCost");
9141 if (!result)
9142 {
9143 LOG_INFO("server.loading", " ");
9144 LOG_WARN("server.loading", ">> Loaded 0 Vendors. DB table `npc_vendor` is empty!");
9145 return;
9146 }
9147
9148 uint32 count = 0;
9149
9150 do
9151 {
9152 Field* fields = result->Fetch();
9153
9154 uint32 entry = fields[0].Get<uint32>();
9155 int32 item_id = fields[1].Get<int32>();
9156
9157 // if item is a negative, its a reference
9158 if (item_id < 0)
9159 count += LoadReferenceVendor(entry, -item_id, &skip_vendors);
9160 else
9161 {
9162 uint32 maxcount = fields[2].Get<uint8>();
9163 uint32 incrtime = fields[3].Get<uint32>();
9164 uint32 ExtendedCost = fields[4].Get<uint32>();
9165
9166 if (!IsVendorItemValid(entry, item_id, maxcount, incrtime, ExtendedCost, nullptr, &skip_vendors))
9167 continue;
9168
9169 VendorItemData& vList = _cacheVendorItemStore[entry];
9170
9171 vList.AddItem(item_id, maxcount, incrtime, ExtendedCost);
9172 ++count;
9173 }
9174 } while (result->NextRow());
9175
9176 LOG_INFO("server.loading", ">> Loaded {} Vendors in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
9177 LOG_INFO("server.loading", " ");
9178}

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

◆ LoadWaypointScripts()

void ObjectMgr::LoadWaypointScripts ( )
5591{
5593
5594 std::set<uint32> actionSet;
5595
5596 for (ScriptMapMap::const_iterator itr = sWaypointScripts.begin(); itr != sWaypointScripts.end(); ++itr)
5597 actionSet.insert(itr->first);
5598
5600 PreparedQueryResult result = WorldDatabase.Query(stmt);
5601
5602 if (result)
5603 {
5604 do
5605 {
5606 Field* fields = result->Fetch();
5607 uint32 action = fields[0].Get<uint32>();
5608
5609 actionSet.erase(action);
5610 } while (result->NextRow());
5611 }
5612
5613 for (std::set<uint32>::iterator itr = actionSet.begin(); itr != actionSet.end(); ++itr)
5614 LOG_ERROR("sql.sql", "There is no waypoint which links to the waypoint script {}", *itr);
5615}
@ WORLD_SEL_WAYPOINT_DATA_ACTION
Definition: WorldDatabase.h:69
ScriptMapMap sWaypointScripts
Definition: ObjectMgr.cpp:61
@ SCRIPTS_WAYPOINT
Definition: ObjectMgr.h:153

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

◆ NewGOData()

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

References _gameObjectDataStore.

Referenced by AddGOData().

◆ NewInstanceSavedGameobjectState()

void ObjectMgr::NewInstanceSavedGameobjectState ( uint32  id,
uint32  guid,
uint8  state 
)
10164{
10165 GameobjectInstanceSavedStateList.push_back({ id, guid, state });
10166}

References GameobjectInstanceSavedStateList.

◆ NewOrExistCreatureData()

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

References _creatureDataStore.

Referenced by AddCreData().

◆ PlayerCreateInfoAddItemHelper()

void ObjectMgr::PlayerCreateInfoAddItemHelper ( uint32  race_,
uint32  class_,
uint32  itemId,
int32  count 
)
private
3610{
3611 if (!_playerInfo[race_][class_])
3612 return;
3613
3614 if (count > 0)
3615 _playerInfo[race_][class_]->item.push_back(PlayerCreateInfoItem(itemId, count));
3616 else
3617 {
3618 if (count < -1)
3619 LOG_ERROR("sql.sql", "Invalid count {} specified on item {} be removed from original player create info (use -1)!", count, itemId);
3620
3621 for (uint32 gender = 0; gender < GENDER_NONE; ++gender)
3622 {
3623 if (CharStartOutfitEntry const* entry = GetCharStartOutfitEntry(race_, class_, gender))
3624 {
3625 bool found = false;
3626 for (uint8 x = 0; x < MAX_OUTFIT_ITEMS; ++x)
3627 {
3628 if (entry->ItemId[x] > 0 && uint32(entry->ItemId[x]) == itemId)
3629 {
3630 found = true;
3631 const_cast<CharStartOutfitEntry*>(entry)->ItemId[x] = 0;
3632 break;
3633 }
3634 }
3635
3636 if (!found)
3637 LOG_ERROR("sql.sql", "Item {} specified to be removed from original create info not found in dbc!", itemId);
3638 }
3639 }
3640 }
3641}
CharStartOutfitEntry const * GetCharStartOutfitEntry(uint8 race, uint8 class_, uint8 gender)
Definition: DBCStores.cpp:835
Definition: Player.h:280
PlayerCreateInfoItems item
Definition: Player.h:348

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

Referenced by LoadPlayerInfo().

◆ RemoveCreatureFromGrid()

void ObjectMgr::RemoveCreatureFromGrid ( ObjectGuid::LowType  guid,
CreatureData const *  data 
)
2353{
2354 uint8 mask = data->spawnMask;
2355 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
2356 {
2357 if (mask & 1)
2358 {
2359 CellCoord cellCoord = Acore::ComputeCellCoord(data->posX, data->posY);
2360 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()];
2361 cell_guids.creatures.erase(guid);
2362 }
2363 }
2364}

References _mapObjectGuidsStore, Acore::ComputeCellCoord(), 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 
)
2659{
2660 uint8 mask = data->spawnMask;
2661 for (uint8 i = 0; mask != 0; i++, mask >>= 1)
2662 {
2663 if (mask & 1)
2664 {
2665 CellCoord cellCoord = Acore::ComputeCellCoord(data->posX, data->posY);
2666 CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()];
2667 cell_guids.gameobjects.erase(guid);
2668 }
2669 }
2670}

References _mapObjectGuidsStore, Acore::ComputeCellCoord(), 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 
)
9309{
9310 CacheVendorItemContainer::iterator iter = _cacheVendorItemStore.find(entry);
9311 if (iter == _cacheVendorItemStore.end())
9312 return false;
9313
9314 if (!iter->second.RemoveItem(item))
9315 return false;
9316
9317 if (persist)
9318 {
9320
9321 stmt->SetData(0, entry);
9322 stmt->SetData(1, item);
9323
9324 WorldDatabase.Execute(stmt);
9325 }
9326
9327 return true;
9328}
@ WORLD_DEL_NPC_VENDOR
Definition: WorldDatabase.h:44

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

◆ ReturnOrDeleteOldMails()

void ObjectMgr::ReturnOrDeleteOldMails ( bool  serverUp)
6082{
6083 uint32 oldMSTime = getMSTime();
6084
6085 time_t curTime = GameTime::GetGameTime().count();
6086
6088 stmt->SetData(0, uint32(curTime));
6089 PreparedQueryResult result = CharacterDatabase.Query(stmt);
6090 if (!result)
6091 return;
6092
6093 std::map<uint32 /*messageId*/, MailItemInfoVec> itemsCache;
6094 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_EXPIRED_MAIL_ITEMS);
6095 stmt->SetData(0, uint32(curTime));
6096 if (PreparedQueryResult items = CharacterDatabase.Query(stmt))
6097 {
6098 MailItemInfo item;
6099 do
6100 {
6101 Field* fields = items->Fetch();
6102 item.item_guid = fields[0].Get<uint32>();
6103 item.item_template = fields[1].Get<uint32>();
6104 uint32 mailId = fields[2].Get<uint32>();
6105 itemsCache[mailId].push_back(item);
6106 } while (items->NextRow());
6107 }
6108
6109 uint32 deletedCount = 0;
6110 uint32 returnedCount = 0;
6111 do
6112 {
6113 Field* fields = result->Fetch();
6114 Mail* m = new Mail;
6115 m->messageID = fields[0].Get<uint32>();
6116 m->messageType = fields[1].Get<uint8>();
6117 m->sender = fields[2].Get<uint32>();
6118 m->receiver = fields[3].Get<uint32>();
6119 bool has_items = fields[4].Get<bool>();
6120 m->expire_time = time_t(fields[5].Get<uint32>());
6121 m->deliver_time = time_t(0);
6122 m->stationery = fields[6].Get<uint8>();
6123 m->checked = fields[7].Get<uint8>();
6124 m->mailTemplateId = fields[8].Get<int16>();
6125
6126 Player* player = nullptr;
6127 if (serverUp)
6129
6130 if (player) // don't modify mails of a logged in player
6131 {
6132 delete m;
6133 continue;
6134 }
6135
6136 // Delete or return mail
6137 if (has_items)
6138 {
6139 // read items from cache
6140 m->items.swap(itemsCache[m->messageID]);
6141
6142 // If it is mail from non-player, or if it's already return mail, it shouldn't be returned, but deleted
6143 if (!m->IsSentByPlayer() || m->IsSentByGM() || (m->IsCODPayment() || m->IsReturnedMail()))
6144 {
6145 for (auto const& mailedItem : m->items)
6146 {
6147 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE);
6148 stmt->SetData(0, mailedItem.item_guid);
6149 CharacterDatabase.Execute(stmt);
6150 }
6151
6152 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID);
6153 stmt->SetData(0, m->messageID);
6154 CharacterDatabase.Execute(stmt);
6155 }
6156 else
6157 {
6158 // Mail will be returned
6159 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_MAIL_RETURNED);
6160 stmt->SetData(0, m->receiver);
6161 stmt->SetData(1, m->sender);
6162 stmt->SetData(2, uint32(curTime + 30 * DAY));
6163 stmt->SetData(3, uint32(curTime));
6165 stmt->SetData(5, m->messageID);
6166 CharacterDatabase.Execute(stmt);
6167 for (auto const& mailedItem : m->items)
6168 {
6169 // Update receiver in mail items for its proper delivery, and in instance_item for avoid lost item at sender delete
6170 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_MAIL_ITEM_RECEIVER);
6171 stmt->SetData(0, m->sender);
6172 stmt->SetData(1, mailedItem.item_guid);
6173 CharacterDatabase.Execute(stmt);
6174
6175 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_OWNER);
6176 stmt->SetData(0, m->sender);
6177 stmt->SetData(1, mailedItem.item_guid);
6178 CharacterDatabase.Execute(stmt);
6179 }
6180
6181 // xinef: update global data
6182 sCharacterCache->IncreaseCharacterMailCount(ObjectGuid(HighGuid::Player, m->sender));
6183 sCharacterCache->DecreaseCharacterMailCount(ObjectGuid(HighGuid::Player, m->receiver));
6184
6185 delete m;
6186 ++returnedCount;
6187 continue;
6188 }
6189 }
6190
6191 sCharacterCache->DecreaseCharacterMailCount(ObjectGuid(HighGuid::Player, m->receiver));
6192
6193 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_BY_ID);
6194 stmt->SetData(0, m->messageID);
6195 CharacterDatabase.Execute(stmt);
6196 delete m;
6197 ++deletedCount;
6198 } while (result->NextRow());
6199
6200 LOG_INFO("server.loading", ">> Processed {} expired mails: {} deleted and {} returned in {} ms", deletedCount + returnedCount, deletedCount, returnedCount, GetMSTimeDiffToNow(oldMSTime));
6201 LOG_INFO("server.loading", " ");
6202}
@ 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:377
@ CHAR_UPD_MAIL_ITEM_RECEIVER
Definition: CharacterDatabase.h:117
#define sCharacterCache
Definition: CharacterCache.h:83
@ MAIL_CHECK_MASK_RETURNED
Definition: Mail.h:49
std::vector< MailItemInfo > MailItemInfoVec
Definition: Mail.h:165
Player * FindPlayerByLowGUID(ObjectGuid::LowType lowguid)
Definition: ObjectAccessor.cpp:256
Seconds GetGameTime()
Definition: GameTime.cpp:38
Definition: Player.h:1046
Definition: Mail.h:161
ObjectGuid::LowType item_guid
Definition: Mail.h:162
uint32 item_template
Definition: Mail.h:163
Definition: Mail.h:168
bool IsSentByGM() const
Definition: Mail.h:209
bool IsCODPayment() const
Definition: Mail.h:210
ObjectGuid::LowType receiver
Definition: Mail.h:174
uint8 messageType
Definition: Mail.h:170
bool IsSentByPlayer() const
Definition: Mail.h:208
uint32 messageID
Definition: Mail.h:169
time_t expire_time
Definition: Mail.h:179
uint32 sender
Definition: Mail.h:173
uint8 stationery
Definition: Mail.h:171
std::vector< MailItemInfo > items
Definition: Mail.h:177
time_t deliver_time
Definition: Mail.h:180
bool IsReturnedMail() const
Definition: Mail.h:211
uint32 checked
Definition: Mail.h:183
uint16 mailTemplateId
Definition: Mail.h:172

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, Mail::receiver, sCharacterCache, Mail::sender, PreparedStatementBase::SetData(), and Mail::stationery.

◆ SendServerMail()

void ObjectMgr::SendServerMail ( Player player,
uint32  id,
uint32  reqLevel,
uint32  reqPlayTime,
uint32  rewardMoneyA,
uint32  rewardMoneyH,
uint32  rewardItemA,
uint32  rewardItemCountA,
uint32  rewardItemH,
uint32  rewardItemCountH,
std::string  subject,
std::string  body,
uint8  active 
) const
10169{
10170 if (active)
10171 {
10172 if (player->GetLevel() < reqLevel)
10173 return;
10174
10175 if (player->GetTotalPlayedTime() < reqPlayTime)
10176 return;
10177
10178 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
10179
10181 MailDraft draft(subject, body);
10182
10183 draft.AddMoney(player->GetTeamId() == TEAM_ALLIANCE ? rewardMoneyA : rewardMoneyH);
10184 if (Item* mailItem = Item::CreateItem(player->GetTeamId() == TEAM_ALLIANCE ? rewardItemA : rewardItemH, player->GetTeamId() == TEAM_ALLIANCE ? rewardItemCountA : rewardItemCountH))
10185 {
10186 mailItem->SaveToDB(trans);
10187 draft.AddItem(mailItem);
10188 }
10189
10190 draft.SendMailTo(trans, MailReceiver(player), sender);
10191 CharacterDatabase.CommitTransaction(trans);
10192
10194 stmt->SetData(0, player->GetGUID().GetCounter());
10195 stmt->SetData(1, id);
10196 CharacterDatabase.Execute(stmt);
10197
10198 LOG_DEBUG("entities.player", "ObjectMgr::SendServerMail() Sent mail id {} to {}", id, player->GetGUID().ToString());
10199 }
10200}
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
Definition: DatabaseEnvFwd.h:70
@ CHAR_REP_MAIL_SERVER_CHARACTER
Definition: CharacterDatabase.h:85
@ MAIL_STATIONERY_GM
Definition: Mail.h:60
@ MAIL_NORMAL
Definition: Mail.h:38
Definition: Item.h:214
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition: Item.cpp:1089
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:106
LowType GetCounter() const
Definition: ObjectGuid.h:147
std::string ToString() const
Definition: ObjectGuid.cpp:47
uint32 GetTotalPlayedTime()
Definition: Player.h:1162
TeamId GetTeamId(bool original=false) const
Definition: Player.h:2059
uint8 GetLevel() const
Definition: Unit.h:1420
Definition: Mail.h:84
Definition: Mail.h:106
Definition: Mail.h:120

References MailDraft::AddItem(), MailDraft::AddMoney(), CHAR_REP_MAIL_SERVER_CHARACTER, CharacterDatabase, Item::CreateItem(), ObjectGuid::GetCounter(), Object::GetGUID(), Unit::GetLevel(), Player::GetTeamId(), Player::GetTotalPlayedTime(), LOG_DEBUG, MAIL_NORMAL, MAIL_STATIONERY_GM, MailDraft::SendMailTo(), PreparedStatementBase::SetData(), TEAM_ALLIANCE, and ObjectGuid::ToString().

◆ SetCreatureLinkedRespawn()

bool ObjectMgr::SetCreatureLinkedRespawn ( ObjectGuid::LowType  guid,
ObjectGuid::LowType  linkedGuid 
)
2011{
2012 if (!guidLow)
2013 return false;
2014
2015 CreatureData const* master = GetCreatureData(guidLow);
2016 ObjectGuid guid = ObjectGuid::Create<HighGuid::Unit>(master->id1, guidLow);
2017
2018 if (!linkedGuidLow) // we're removing the linking
2019 {
2020 _linkedRespawnStore.erase(guid);
2022 stmt->SetData(0, guidLow);
2023 WorldDatabase.Execute(stmt);
2024 return true;
2025 }
2026
2027 CreatureData const* slave = GetCreatureData(linkedGuidLow);
2028 if (!slave)
2029 {
2030 LOG_ERROR("sql.sql", "Creature '{}' linking to non-existent creature '{}'.", guidLow, linkedGuidLow);
2031 return false;
2032 }
2033
2034 MapEntry const* map = sMapStore.LookupEntry(master->mapid);
2035 if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
2036 {
2037 LOG_ERROR("sql.sql", "Creature '{}' linking to '{}' on an unpermitted map.", guidLow, linkedGuidLow);
2038 return false;
2039 }
2040
2041 if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
2042 {
2043 LOG_ERROR("sql.sql", "LinkedRespawn: Creature '{}' linking to '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
2044 return false;
2045 }
2046
2047 ObjectGuid linkedGuid = ObjectGuid::Create<HighGuid::Unit>(slave->id1, linkedGuidLow);
2048
2049 _linkedRespawnStore[guid] = linkedGuid;
2051 stmt->SetData(0, guidLow);
2052 stmt->SetData(1, linkedGuidLow);
2053 WorldDatabase.Execute(stmt);
2054 return true;
2055}
@ 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
1325{ DBCLocaleIndex = locale; }

References DBCLocaleIndex.

◆ SetHighestGuids()

void ObjectMgr::SetHighestGuids ( )
6957{
6958 QueryResult result = CharacterDatabase.Query("SELECT MAX(guid) FROM characters");
6959 if (result)
6960 GetGuidSequenceGenerator<HighGuid::Player>().Set((*result)[0].Get<uint32>() + 1);
6961
6962 result = CharacterDatabase.Query("SELECT MAX(guid) FROM item_instance");
6963 if (result)
6964 GetGuidSequenceGenerator<HighGuid::Item>().Set((*result)[0].Get<uint32>() + 1);
6965
6966 // Cleanup other tables from not existed guids ( >= _hiItemGuid)
6967 CharacterDatabase.Execute("DELETE FROM character_inventory WHERE item >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
6968 CharacterDatabase.Execute("DELETE FROM mail_items WHERE item_guid >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
6969 CharacterDatabase.Execute("DELETE FROM auctionhouse WHERE itemguid >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
6970 CharacterDatabase.Execute("DELETE FROM guild_bank_item WHERE item_guid >= '{}'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query
6971
6972 result = WorldDatabase.Query("SELECT MAX(guid) FROM transports");
6973 if (result)
6974 GetGuidSequenceGenerator<HighGuid::Mo_Transport>().Set((*result)[0].Get<uint32>() + 1);
6975
6976 result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse");
6977 if (result)
6978 _auctionId = (*result)[0].Get<uint32>() + 1;
6979
6980 result = CharacterDatabase.Query("SELECT MAX(id) FROM mail");
6981 if (result)
6982 _mailId = (*result)[0].Get<uint32>() + 1;
6983
6984 result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team");
6985 if (result)
6986 sArenaTeamMgr->SetNextArenaTeamId((*result)[0].Get<uint32>() + 1);
6987
6988 result = CharacterDatabase.Query("SELECT MAX(fight_id) FROM log_arena_fights");
6989 if (result)
6990 sArenaTeamMgr->SetLastArenaLogId((*result)[0].Get<uint32>());
6991
6992 result = CharacterDatabase.Query("SELECT MAX(setguid) FROM character_equipmentsets");
6993 if (result)
6994 _equipmentSetGuid = (*result)[0].Get<uint64>() + 1;
6995
6996 result = CharacterDatabase.Query("SELECT MAX(guildId) FROM guild");
6997 if (result)
6998 sGuildMgr->SetNextGuildId((*result)[0].Get<uint32>() + 1);
6999
7000 result = WorldDatabase.Query("SELECT MAX(guid) FROM creature");
7001 if (result)
7002 _creatureSpawnId = (*result)[0].Get<uint32>() + 1;
7003
7004 result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject");
7005 if (result)
7006 _gameObjectSpawnId = (*result)[0].Get<uint32>() + 1;
7007}
#define sArenaTeamMgr
Definition: ArenaTeamMgr.h:67
#define sGuildMgr
Definition: GuildMgr.h:51

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

◆ SetInstanceSavedGameobjectState()

void ObjectMgr::SetInstanceSavedGameobjectState ( uint32  id,
uint32  guid,
uint8  state 
)
10154{
10155 for (auto it = GameobjectInstanceSavedStateList.begin(); it != GameobjectInstanceSavedStateList.end(); it++)
10156 {
10157 if (it->m_guid == guid && it->m_instance == id)
10158 {
10159 it->m_state = state;
10160 }
10161 }
10162}

References GameobjectInstanceSavedStateList.

◆ ValidateSpellScripts()

void ObjectMgr::ValidateSpellScripts ( )
5678{
5679 uint32 oldMSTime = getMSTime();
5680
5681 if (_spellScriptsStore.empty())
5682 {
5683 LOG_INFO("server.loading", ">> Validated 0 scripts.");
5684 LOG_INFO("server.loading", " ");
5685 return;
5686 }
5687
5688 uint32 count = 0;
5689
5690 for (SpellScriptsContainer::iterator itr = _spellScriptsStore.begin(); itr != _spellScriptsStore.end();)
5691 {
5692 SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(itr->first);
5693 std::vector<std::pair<SpellScriptLoader*, SpellScriptsContainer::iterator> > SpellScriptLoaders;
5694 sScriptMgr->CreateSpellScriptLoaders(itr->first, SpellScriptLoaders);
5695 itr = _spellScriptsStore.upper_bound(itr->first);
5696
5697 for (std::vector<std::pair<SpellScriptLoader*, SpellScriptsContainer::iterator> >::iterator sitr = SpellScriptLoaders.begin(); sitr != SpellScriptLoaders.end(); ++sitr)
5698 {
5699 SpellScript* spellScript = sitr->first->GetSpellScript();
5700 AuraScript* auraScript = sitr->first->GetAuraScript();
5701 bool valid = true;
5702 if (!spellScript && !auraScript)
5703 {
5704 LOG_ERROR("sql.sql", "Functions GetSpellScript() and GetAuraScript() of script `{}` do not return objects - script skipped", GetScriptName(sitr->second->second));
5705 valid = false;
5706 }
5707 if (spellScript)
5708 {
5709 spellScript->_Init(&sitr->first->GetName(), spellEntry->Id);
5710 spellScript->_Register();
5711 if (!spellScript->_Validate(spellEntry))
5712 valid = false;
5713 delete spellScript;
5714 }
5715 if (auraScript)
5716 {
5717 auraScript->_Init(&sitr->first->GetName(), spellEntry->Id);
5718 auraScript->_Register();
5719 if (!auraScript->_Validate(spellEntry))
5720 valid = false;
5721 delete auraScript;
5722 }
5723 if (!valid)
5724 {
5725 _spellScriptsStore.erase(sitr->second);
5726 }
5727 }
5728 ++count;
5729 }
5730
5731 LOG_INFO("server.loading", ">> Validated {} scripts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
5732 LOG_INFO("server.loading", " ");
5733}
std::string const & GetScriptName(uint32 id) const
Definition: ObjectMgr.cpp:9466
virtual void _Register()
Definition: SpellScript.cpp:45
virtual void _Init(std::string const *scriptname, uint32 spellId)
Definition: SpellScript.cpp:59
Definition: SpellScript.h:182
bool _Validate(SpellInfo const *entry) override
Definition: SpellScript.cpp:316
Definition: SpellScript.h:517
bool _Validate(SpellInfo const *entry) override
Definition: SpellScript.cpp:662

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

◆ _broadcastTextStore

BroadcastTextContainer ObjectMgr::_broadcastTextStore
private

◆ _cacheTrainerSpellStore

CacheTrainerSpellContainer ObjectMgr::_cacheTrainerSpellStore
private

◆ _cacheVendorItemStore

◆ _creatureAddonStore

CreatureAddonContainer ObjectMgr::_creatureAddonStore
private

◆ _creatureBaseStatsStore

CreatureBaseStatsContainer ObjectMgr::_creatureBaseStatsStore
private

◆ _creatureCustomIDsStore

CreatureCustomIDsContainer ObjectMgr::_creatureCustomIDsStore
private

◆ _creatureDataStore

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

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

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

GameObjectDataContainer ObjectMgr::_gameObjectDataStore
private

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

GameTeleContainer ObjectMgr::_gameTeleStore
private

◆ _goQuestInvolvedRelations

QuestRelations ObjectMgr::_goQuestInvolvedRelations
private

◆ _goQuestRelations

QuestRelations ObjectMgr::_goQuestRelations
private

◆ _gossipMenuItemsLocaleStore

GossipMenuItemsLocaleContainer ObjectMgr::_gossipMenuItemsLocaleStore
private

◆ _gossipMenuItemsStore

◆ _gossipMenusStore

GossipMenusContainer ObjectMgr::_gossipMenusStore
private

◆ _gossipTextStore

GossipTextContainer ObjectMgr::_gossipTextStore
private

Referenced by GetGossipText(), and LoadGossipText().

◆ _guidGenerators

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

◆ _hasDifficultyEntries

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

Referenced by CheckCreatureTemplate().

◆ _hiPetNumber

uint32 ObjectMgr::_hiPetNumber
private

Referenced by GeneratePetNumber(), and LoadPetNumber().

◆ _hiPetNumberMutex

std::mutex ObjectMgr::_hiPetNumberMutex
private

Referenced by GeneratePetNumber().

◆ _instanceTemplateStore

InstanceTemplateContainer ObjectMgr::_instanceTemplateStore
private

◆ _itemLocaleStore

ItemLocaleContainer ObjectMgr::_itemLocaleStore
private

Referenced by GetItemLocale(), and LoadItemLocales().

◆ _itemSetNameLocaleStore

ItemSetNameLocaleContainer ObjectMgr::_itemSetNameLocaleStore
private

◆ _itemSetNameStore

ItemSetNameContainer ObjectMgr::_itemSetNameStore
private

◆ _itemTemplateStore

ItemTemplateContainer ObjectMgr::_itemTemplateStore
private

◆ _itemTemplateStoreFast

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

◆ _linkedRespawnStore

LinkedRespawnContainer ObjectMgr::_linkedRespawnStore
private

◆ _mailId

uint32 ObjectMgr::_mailId
private

Referenced by GenerateMailID(), and SetHighestGuids().

◆ _mailIdMutex

std::mutex ObjectMgr::_mailIdMutex
private

Referenced by GenerateMailID().

◆ _mailLevelRewardStore

MailLevelRewardContainer ObjectMgr::_mailLevelRewardStore
private

◆ _mapObjectGuidsStore

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

◆ _playerXPperLevel

PlayerXPperLevel ObjectMgr::_playerXPperLevel
private

Referenced by GetXPForLevel(), and LoadPlayerInfo().

◆ _pointOfInterestLocaleStore

PointOfInterestLocaleContainer ObjectMgr::_pointOfInterestLocaleStore
private

◆ _pointsOfInterestStore

PointOfInterestContainer ObjectMgr::_pointsOfInterestStore
private

◆ _profanityNamesStore

ReservedNamesContainer ObjectMgr::_profanityNamesStore
private

◆ _questAreaTriggerStore

QuestAreaTriggerContainer ObjectMgr::_questAreaTriggerStore
private

◆ _questGreetingLocaleStore

QuestGreetingLocaleContainer ObjectMgr::_questGreetingLocaleStore
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

ReservedNamesContainer ObjectMgr::_reservedNamesStore
private

◆ _scriptNamesStore

ScriptNameContainer ObjectMgr::_scriptNamesStore
private

◆ _serverMailStore

ServerMailContainer ObjectMgr::_serverMailStore
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().

◆ _transportMaps

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

◆ _vehicleAccessoryStore

VehicleAccessoryContainer ObjectMgr::_vehicleAccessoryStore
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

◆ mExclusiveQuestGroups

ExclusiveQuestGroups ObjectMgr::mExclusiveQuestGroups

Referenced by LoadQuests().