/src/server/game/Globals/ObjectMgr.cpp
C++ | 9357 lines | 7458 code | 1565 blank | 334 comment | 1633 complexity | edca2f07d7e750a1406a24f1de8e96b8 MD5 | raw file
Possible License(s): GPL-2.0, BSD-2-Clause
Large files files are truncated, but you can click here to view the full file
- /*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include "AccountMgr.h"
- #include "AchievementMgr.h"
- #include "ArenaTeam.h"
- #include "ArenaTeamMgr.h"
- #include "BattlegroundMgr.h"
- #include "Chat.h"
- #include "Common.h"
- #include "DatabaseEnv.h"
- #include "DB2Structure.h"
- #include "DB2Stores.h"
- #include "DisableMgr.h"
- #include "GameEventMgr.h"
- #include "GossipDef.h"
- #include "GroupMgr.h"
- #include "GuildMgr.h"
- #include "InstanceSaveMgr.h"
- #include "Language.h"
- #include "LFGMgr.h"
- #include "Log.h"
- #include "MapManager.h"
- #include "Object.h"
- #include "ObjectMgr.h"
- #include "Pet.h"
- #include "PoolMgr.h"
- #include "ReputationMgr.h"
- #include "ScriptMgr.h"
- #include "SpellAuras.h"
- #include "Spell.h"
- #include "SpellMgr.h"
- #include "SpellScript.h"
- #include "Transport.h"
- #include "UpdateMask.h"
- #include "Util.h"
- #include "Vehicle.h"
- #include "WaypointManager.h"
- #include "World.h"
- ScriptMapMap sSpellScripts;
- ScriptMapMap sEventScripts;
- ScriptMapMap sWaypointScripts;
- std::string GetScriptsTableNameByType(ScriptsType type)
- {
- std::string res = "";
- switch (type)
- {
- case SCRIPTS_SPELL: res = "spell_scripts"; break;
- case SCRIPTS_EVENT: res = "event_scripts"; break;
- case SCRIPTS_WAYPOINT: res = "waypoint_scripts"; break;
- default: break;
- }
- return res;
- }
- ScriptMapMap* GetScriptsMapByType(ScriptsType type)
- {
- ScriptMapMap* res = NULL;
- switch (type)
- {
- case SCRIPTS_SPELL: res = &sSpellScripts; break;
- case SCRIPTS_EVENT: res = &sEventScripts; break;
- case SCRIPTS_WAYPOINT: res = &sWaypointScripts; break;
- default: break;
- }
- return res;
- }
- std::string GetScriptCommandName(ScriptCommands command)
- {
- std::string res = "";
- switch (command)
- {
- case SCRIPT_COMMAND_TALK: res = "SCRIPT_COMMAND_TALK"; break;
- case SCRIPT_COMMAND_EMOTE: res = "SCRIPT_COMMAND_EMOTE"; break;
- case SCRIPT_COMMAND_FIELD_SET: res = "SCRIPT_COMMAND_FIELD_SET"; break;
- case SCRIPT_COMMAND_MOVE_TO: res = "SCRIPT_COMMAND_MOVE_TO"; break;
- case SCRIPT_COMMAND_FLAG_SET: res = "SCRIPT_COMMAND_FLAG_SET"; break;
- case SCRIPT_COMMAND_FLAG_REMOVE: res = "SCRIPT_COMMAND_FLAG_REMOVE"; break;
- case SCRIPT_COMMAND_TELEPORT_TO: res = "SCRIPT_COMMAND_TELEPORT_TO"; break;
- case SCRIPT_COMMAND_QUEST_EXPLORED: res = "SCRIPT_COMMAND_QUEST_EXPLORED"; break;
- case SCRIPT_COMMAND_KILL_CREDIT: res = "SCRIPT_COMMAND_KILL_CREDIT"; break;
- case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT: res = "SCRIPT_COMMAND_RESPAWN_GAMEOBJECT"; break;
- case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE: res = "SCRIPT_COMMAND_TEMP_SUMMON_CREATURE"; break;
- case SCRIPT_COMMAND_OPEN_DOOR: res = "SCRIPT_COMMAND_OPEN_DOOR"; break;
- case SCRIPT_COMMAND_CLOSE_DOOR: res = "SCRIPT_COMMAND_CLOSE_DOOR"; break;
- case SCRIPT_COMMAND_ACTIVATE_OBJECT: res = "SCRIPT_COMMAND_ACTIVATE_OBJECT"; break;
- case SCRIPT_COMMAND_REMOVE_AURA: res = "SCRIPT_COMMAND_REMOVE_AURA"; break;
- case SCRIPT_COMMAND_CAST_SPELL: res = "SCRIPT_COMMAND_CAST_SPELL"; break;
- case SCRIPT_COMMAND_PLAY_SOUND: res = "SCRIPT_COMMAND_PLAY_SOUND"; break;
- case SCRIPT_COMMAND_CREATE_ITEM: res = "SCRIPT_COMMAND_CREATE_ITEM"; break;
- case SCRIPT_COMMAND_DESPAWN_SELF: res = "SCRIPT_COMMAND_DESPAWN_SELF"; break;
- case SCRIPT_COMMAND_LOAD_PATH: res = "SCRIPT_COMMAND_LOAD_PATH"; break;
- case SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT: res = "SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT"; break;
- case SCRIPT_COMMAND_KILL: res = "SCRIPT_COMMAND_KILL"; break;
- // TrinityCore only
- case SCRIPT_COMMAND_ORIENTATION: res = "SCRIPT_COMMAND_ORIENTATION"; break;
- case SCRIPT_COMMAND_EQUIP: res = "SCRIPT_COMMAND_EQUIP"; break;
- case SCRIPT_COMMAND_MODEL: res = "SCRIPT_COMMAND_MODEL"; break;
- case SCRIPT_COMMAND_CLOSE_GOSSIP: res = "SCRIPT_COMMAND_CLOSE_GOSSIP"; break;
- case SCRIPT_COMMAND_PLAYMOVIE: res = "SCRIPT_COMMAND_PLAYMOVIE"; break;
- default:
- {
- char sz[32];
- sprintf(sz, "Unknown command: %d", command);
- res = sz;
- break;
- }
- }
- return res;
- }
- std::string ScriptInfo::GetDebugInfo() const
- {
- char sz[256];
- sprintf(sz, "%s ('%s' script id: %u)", GetScriptCommandName(command).c_str(), GetScriptsTableNameByType(type).c_str(), id);
- return std::string(sz);
- }
- bool normalizePlayerName(std::string& name)
- {
- if (name.empty())
- return false;
- wchar_t wstr_buf[MAX_INTERNAL_PLAYER_NAME+1];
- size_t wstr_len = MAX_INTERNAL_PLAYER_NAME;
- if (!Utf8toWStr(name, &wstr_buf[0], wstr_len))
- return false;
- wstr_buf[0] = wcharToUpper(wstr_buf[0]);
- for (size_t i = 1; i < wstr_len; ++i)
- wstr_buf[i] = wcharToLower(wstr_buf[i]);
- if (!WStrToUtf8(wstr_buf, wstr_len, name))
- return false;
- return true;
- }
- LanguageDesc lang_description[LANGUAGES_COUNT] =
- {
- { LANG_ADDON, 0, 0 },
- { LANG_UNIVERSAL, 0, 0 },
- { LANG_ORCISH, 669, SKILL_LANG_ORCISH },
- { LANG_DARNASSIAN, 671, SKILL_LANG_DARNASSIAN },
- { LANG_TAURAHE, 670, SKILL_LANG_TAURAHE },
- { LANG_DWARVISH, 672, SKILL_LANG_DWARVEN },
- { LANG_COMMON, 668, SKILL_LANG_COMMON },
- { LANG_DEMONIC, 815, SKILL_LANG_DEMON_TONGUE },
- { LANG_TITAN, 816, SKILL_LANG_TITAN },
- { LANG_THALASSIAN, 813, SKILL_LANG_THALASSIAN },
- { LANG_DRACONIC, 814, SKILL_LANG_DRACONIC },
- { LANG_KALIMAG, 817, SKILL_LANG_OLD_TONGUE },
- { LANG_GNOMISH, 7340, SKILL_LANG_GNOMISH },
- { LANG_TROLL, 7341, SKILL_LANG_TROLL },
- { LANG_GUTTERSPEAK, 17737, SKILL_LANG_GUTTERSPEAK },
- { LANG_DRAENEI, 29932, SKILL_LANG_DRAENEI },
- { LANG_ZOMBIE, 0, 0 },
- { LANG_GNOMISH_BINARY, 0, 0 },
- { LANG_GOBLIN_BINARY, 0, 0 },
- { LANG_WORGEN, 69270, SKILL_LANG_WORGEN },
- { LANG_GOBLIN, 69269, SKILL_LANG_GOBLIN }
- };
- LanguageDesc const* GetLanguageDescByID(uint32 lang)
- {
- for (uint8 i = 0; i < LANGUAGES_COUNT; ++i)
- {
- if (uint32(lang_description[i].lang_id) == lang)
- return &lang_description[i];
- }
- return NULL;
- }
- bool SpellClickInfo::IsFitToRequirements(Unit const* clicker, Unit const* clickee) const
- {
- Player const* playerClicker = clicker->ToPlayer();
- if (!playerClicker)
- return true;
- Unit const* summoner = NULL;
- // Check summoners for party
- if (clickee->IsSummon())
- summoner = clickee->ToTempSummon()->GetSummoner();
- if (!summoner)
- summoner = clickee;
- // This only applies to players
- switch (userType)
- {
- case SPELL_CLICK_USER_FRIEND:
- if (!playerClicker->IsFriendlyTo(summoner))
- return false;
- break;
- case SPELL_CLICK_USER_RAID:
- if (!playerClicker->IsInRaidWith(summoner))
- return false;
- break;
- case SPELL_CLICK_USER_PARTY:
- if (!playerClicker->IsInPartyWith(summoner))
- return false;
- break;
- default:
- break;
- }
- return true;
- }
- ObjectMgr::ObjectMgr():
- _auctionId(1),
- _equipmentSetGuid(1),
- _itemTextId(1),
- _mailId(1),
- _hiPetNumber(1),
- _voidItemId(1),
- _hiCharGuid(1),
- _hiCreatureGuid(1),
- _hiPetGuid(1),
- _hiVehicleGuid(1),
- _hiItemGuid(1),
- _hiGoGuid(1),
- _hiDoGuid(1),
- _hiCorpseGuid(1),
- _hiAreaTriggerGuid(1),
- _hiMoTransGuid(1),
- DBCLocaleIndex(LOCALE_enUS)
- {
- for (uint8 i = 0; i < MAX_CLASSES; ++i)
- for (uint8 j = 0; j < MAX_RACES; ++j)
- _playerInfo[j][i] = NULL;
- }
- ObjectMgr::~ObjectMgr()
- {
- for (QuestMap::iterator i = _questTemplates.begin(); i != _questTemplates.end(); ++i)
- delete i->second;
- for (PetLevelInfoContainer::iterator i = _petInfoStore.begin(); i != _petInfoStore.end(); ++i)
- delete[] i->second;
- for (int race = 0; race < MAX_RACES; ++race)
- {
- for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
- {
- if (_playerInfo[race][class_])
- delete[] _playerInfo[race][class_]->levelInfo;
- delete _playerInfo[race][class_];
- }
- }
- for (CacheVendorItemContainer::iterator itr = _cacheVendorItemStore.begin(); itr != _cacheVendorItemStore.end(); ++itr)
- itr->second.Clear();
- _cacheTrainerSpellStore.clear();
- _graveyardOrientations.clear();
- for (DungeonEncounterContainer::iterator itr =_dungeonEncounterStore.begin(); itr != _dungeonEncounterStore.end(); ++itr)
- for (DungeonEncounterList::iterator encounterItr = itr->second.begin(); encounterItr != itr->second.end(); ++encounterItr)
- delete *encounterItr;
- for (AccessRequirementContainer::iterator itr = _accessRequirementStore.begin(); itr != _accessRequirementStore.end(); ++itr)
- delete itr->second;
- }
- void ObjectMgr::AddLocaleString(std::string const& s, LocaleConstant locale, StringVector& data)
- {
- if (!s.empty())
- {
- if (data.size() <= size_t(locale))
- data.resize(locale + 1);
- data[locale] = s;
- }
- }
- void ObjectMgr::LoadGraveyardOrientations()
- {
- uint32 oldMSTime = getMSTime();
- _graveyardOrientations.clear();
- QueryResult result = WorldDatabase.Query("SELECT id, orientation FROM graveyard_orientation");
- if (!result)
- return;
- do
- {
- Field* fields = result->Fetch();
- uint32 id = fields[0].GetUInt32();
- if (!sWorldSafeLocsStore.LookupEntry(id))
- {
- TC_LOG_ERROR("server.loading", "Graveyard %u referenced in graveyard_orientation doesn't exist.", id);
- continue;
- }
- _graveyardOrientations[id] = fields[1].GetFloat();
- } while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %lu graveyard orientations in %u ms", (unsigned long)_graveyardOrientations.size(), GetMSTimeDiffToNow(oldMSTime));
- }
- void ObjectMgr::LoadCreatureLocales()
- {
- uint32 oldMSTime = getMSTime();
- _creatureLocaleStore.clear(); // need for reload case
- QueryResult result = WorldDatabase.Query("SELECT entry, "
- "name_loc1, femaleName_loc1, subname_loc1, "
- "name_loc2, femaleName_loc2, subname_loc2, "
- "name_loc3, femaleName_loc3, subname_loc3, "
- "name_loc4, femaleName_loc4, subname_loc4, "
- "name_loc5, femaleName_loc5, subname_loc5, "
- "name_loc6, femaleName_loc6, subname_loc6, "
- "name_loc7, femaleName_loc7, subname_loc7, "
- "name_loc8, femaleName_loc8, subname_loc8 "
- "FROM locales_creature");
- if (!result)
- return;
- do
- {
- Field* fields = result->Fetch();
- uint32 entry = fields[0].GetUInt32();
- CreatureLocale& data = _creatureLocaleStore[entry];
- for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i)
- {
- LocaleConstant locale = (LocaleConstant) i;
- AddLocaleString(fields[1 + 3 * (i - 1)].GetString(), locale, data.Name);
- AddLocaleString(fields[1 + 3 * (i - 1) + 1].GetString(), locale, data.FemaleName);
- AddLocaleString(fields[1 + 3 * (i - 1) + 2].GetString(), locale, data.SubName);
- }
- } while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u creature locale strings in %u ms", uint32(_creatureLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime));
- }
- void ObjectMgr::LoadGossipMenuItemsLocales()
- {
- uint32 oldMSTime = getMSTime();
- _gossipMenuItemsLocaleStore.clear(); // need for reload case
- QueryResult result = WorldDatabase.Query("SELECT menu_id, id, "
- "option_text_loc1, box_text_loc1, option_text_loc2, box_text_loc2, "
- "option_text_loc3, box_text_loc3, option_text_loc4, box_text_loc4, "
- "option_text_loc5, box_text_loc5, option_text_loc6, box_text_loc6, "
- "option_text_loc7, box_text_loc7, option_text_loc8, box_text_loc8 "
- "FROM locales_gossip_menu_option");
- if (!result)
- return;
- do
- {
- Field* fields = result->Fetch();
- uint16 menuId = fields[0].GetUInt16();
- uint16 id = fields[1].GetUInt16();
- GossipMenuItemsLocale& data = _gossipMenuItemsLocaleStore[MAKE_PAIR32(menuId, id)];
- for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i)
- {
- LocaleConstant locale = (LocaleConstant) i;
- AddLocaleString(fields[2 + 2 * (i - 1)].GetString(), locale, data.OptionText);
- AddLocaleString(fields[2 + 2 * (i - 1) + 1].GetString(), locale, data.BoxText);
- }
- }
- while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u gossip_menu_option locale strings in %u ms", uint32(_gossipMenuItemsLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime));
- }
- void ObjectMgr::LoadPointOfInterestLocales()
- {
- uint32 oldMSTime = getMSTime();
- _pointOfInterestLocaleStore.clear(); // need for reload case
- QueryResult result = WorldDatabase.Query("SELECT entry, icon_name_loc1, icon_name_loc2, icon_name_loc3, icon_name_loc4, icon_name_loc5, icon_name_loc6, icon_name_loc7, icon_name_loc8 FROM locales_points_of_interest");
- if (!result)
- return;
- do
- {
- Field* fields = result->Fetch();
- uint32 entry = fields[0].GetUInt32();
- PointOfInterestLocale& data = _pointOfInterestLocaleStore[entry];
- for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i)
- AddLocaleString(fields[i].GetString(), LocaleConstant(i), data.IconName);
- } while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u points_of_interest locale strings in %u ms", uint32(_pointOfInterestLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime));
- }
- void ObjectMgr::LoadCreatureTemplates()
- {
- uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4 5 6 7 8
- QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, "
- // 9 10 11 12 13 14 15 16 17 18 19 20 21 22
- "modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, "
- // 23 24 25 26 27 28 29 30 31 32
- "scale, rank, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, "
- // 33 34 35 36 37 38
- "dynamicflags, family, trainer_type, trainer_class, trainer_race, type, "
- // 39 40 41 42 43 44 45 46 47 48 49
- "type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, "
- // 50 51 52 53 54 55 56 57 58 59 60 61 62 63
- "spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, "
- // 64 65 66 67 68 69 70 71 72
- "InhabitType, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, "
- // 73 74 75 76 77 78 79
- "RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, "
- // 80 81 82 83 84
- "movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName "
- "FROM creature_template");
- if (!result)
- {
- TC_LOG_INFO("server.loading", ">> Loaded 0 creature template definitions. DB table `creature_template` is empty.");
- return;
- }
- _creatureTemplateStore.rehash(result->GetRowCount());
- uint32 count = 0;
- do
- {
- Field* fields = result->Fetch();
- LoadCreatureTemplate(fields);
- ++count;
- }
- while (result->NextRow());
- // Checking needs to be done after loading because of the difficulty self referencing
- for (CreatureTemplateContainer::const_iterator itr = _creatureTemplateStore.begin(); itr != _creatureTemplateStore.end(); ++itr)
- CheckCreatureTemplate(&itr->second);
- TC_LOG_INFO("server.loading", ">> Loaded %u creature definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
- }
- void ObjectMgr::LoadCreatureTemplate(Field* fields)
- {
- uint32 entry = fields[0].GetUInt32();
- CreatureTemplate& creatureTemplate = _creatureTemplateStore[entry];
- creatureTemplate.Entry = entry;
- for (uint8 i = 0; i < MAX_DIFFICULTY - 1; ++i)
- creatureTemplate.DifficultyEntry[i] = fields[1 + i].GetUInt32();
- for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i)
- creatureTemplate.KillCredit[i] = fields[4 + i].GetUInt32();
- creatureTemplate.Modelid1 = fields[6].GetUInt32();
- creatureTemplate.Modelid2 = fields[7].GetUInt32();
- creatureTemplate.Modelid3 = fields[8].GetUInt32();
- creatureTemplate.Modelid4 = fields[9].GetUInt32();
- creatureTemplate.Name = fields[10].GetString();
- creatureTemplate.FemaleName = fields[11].GetString();
- creatureTemplate.SubName = fields[12].GetString();
- creatureTemplate.IconName = fields[13].GetString();
- creatureTemplate.GossipMenuId = fields[14].GetUInt32();
- creatureTemplate.minlevel = fields[15].GetUInt8();
- creatureTemplate.maxlevel = fields[16].GetUInt8();
- creatureTemplate.expansion = uint32(fields[17].GetInt16());
- creatureTemplate.expansionUnknown = uint32(fields[18].GetUInt16());
- creatureTemplate.faction = uint32(fields[19].GetUInt16());
- creatureTemplate.npcflag = fields[20].GetUInt32();
- creatureTemplate.speed_walk = fields[21].GetFloat();
- creatureTemplate.speed_run = fields[22].GetFloat();
- creatureTemplate.scale = fields[23].GetFloat();
- creatureTemplate.rank = uint32(fields[24].GetUInt8());
- creatureTemplate.dmgschool = uint32(fields[25].GetInt8());
- creatureTemplate.BaseAttackTime = fields[26].GetUInt32();
- creatureTemplate.RangeAttackTime = fields[27].GetUInt32();
- creatureTemplate.BaseVariance = fields[28].GetFloat();
- creatureTemplate.RangeVariance = fields[29].GetFloat();
- creatureTemplate.unit_class = uint32(fields[30].GetUInt8());
- creatureTemplate.unit_flags = fields[31].GetUInt32();
- creatureTemplate.unit_flags2 = fields[32].GetUInt32();
- creatureTemplate.dynamicflags = fields[33].GetUInt32();
- creatureTemplate.family = uint32(fields[34].GetUInt8());
- creatureTemplate.trainer_type = uint32(fields[35].GetUInt8());
- creatureTemplate.trainer_class = uint32(fields[36].GetUInt8());
- creatureTemplate.trainer_race = uint32(fields[37].GetUInt8());
- creatureTemplate.type = uint32(fields[38].GetUInt8());
- creatureTemplate.type_flags = fields[39].GetUInt32();
- creatureTemplate.type_flags2 = fields[40].GetUInt32();
- creatureTemplate.lootid = fields[41].GetUInt32();
- creatureTemplate.pickpocketLootId = fields[42].GetUInt32();
- creatureTemplate.SkinLootId = fields[43].GetUInt32();
- for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
- creatureTemplate.resistance[i] = fields[44 + i - 1].GetInt16();
- for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
- creatureTemplate.spells[i] = fields[50 + i].GetUInt32();
- creatureTemplate.PetSpellDataId = fields[58].GetUInt32();
- creatureTemplate.VehicleId = fields[59].GetUInt32();
- creatureTemplate.mingold = fields[60].GetUInt32();
- creatureTemplate.maxgold = fields[61].GetUInt32();
- creatureTemplate.AIName = fields[62].GetString();
- creatureTemplate.MovementType = uint32(fields[63].GetUInt8());
- creatureTemplate.InhabitType = uint32(fields[64].GetUInt8());
- creatureTemplate.HoverHeight = fields[65].GetFloat();
- creatureTemplate.ModHealth = fields[66].GetFloat();
- creatureTemplate.ModHealthExtra = fields[67].GetFloat();
- creatureTemplate.ModMana = fields[68].GetFloat();
- creatureTemplate.ModManaExtra = fields[69].GetFloat();
- creatureTemplate.ModArmor = fields[70].GetFloat();
- creatureTemplate.ModDamage = fields[71].GetFloat();
- creatureTemplate.ModExperience = fields[72].GetFloat();
- creatureTemplate.RacialLeader = fields[73].GetBool();
- for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
- creatureTemplate.questItems[i] = fields[74 + i].GetUInt32();
- creatureTemplate.movementId = fields[80].GetUInt32();
- creatureTemplate.RegenHealth = fields[81].GetBool();
- creatureTemplate.MechanicImmuneMask = fields[82].GetUInt32();
- creatureTemplate.flags_extra = fields[83].GetUInt32();
- creatureTemplate.ScriptID = GetScriptId(fields[84].GetCString());
- }
- void ObjectMgr::LoadCreatureTemplateAddons()
- {
- uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4 5 6
- QueryResult result = WorldDatabase.Query("SELECT entry, path_id, mount, bytes1, bytes2, emote, auras FROM creature_template_addon");
- if (!result)
- {
- TC_LOG_INFO("server.loading", ">> Loaded 0 creature template addon definitions. DB table `creature_template_addon` is empty.");
- return;
- }
- uint32 count = 0;
- do
- {
- Field* fields = result->Fetch();
- uint32 entry = fields[0].GetUInt32();
- if (!sObjectMgr->GetCreatureTemplate(entry))
- {
- TC_LOG_ERROR("sql.sql", "Creature template (Entry: %u) does not exist but has a record in `creature_template_addon`", entry);
- continue;
- }
- CreatureAddon& creatureAddon = _creatureTemplateAddonStore[entry];
- creatureAddon.path_id = fields[1].GetUInt32();
- creatureAddon.mount = fields[2].GetUInt32();
- creatureAddon.bytes1 = fields[3].GetUInt32();
- creatureAddon.bytes2 = fields[4].GetUInt32();
- creatureAddon.emote = fields[5].GetUInt32();
- Tokenizer tokens(fields[6].GetString(), ' ');
- uint8 i = 0;
- creatureAddon.auras.resize(tokens.size());
- for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
- {
- SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(uint32(atol(*itr)));
- if (!AdditionalSpellInfo)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong spell %u defined in `auras` field in `creature_template_addon`.", entry, uint32(atol(*itr)));
- continue;
- }
- if (AdditionalSpellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_template_addon`.", entry, uint32(atol(*itr)));
- creatureAddon.auras[i++] = uint32(atol(*itr));
- }
- if (creatureAddon.mount)
- {
- if (!sCreatureDisplayInfoStore.LookupEntry(creatureAddon.mount))
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has invalid displayInfoId (%u) for mount defined in `creature_template_addon`", entry, creatureAddon.mount);
- creatureAddon.mount = 0;
- }
- }
- if (!sEmotesStore.LookupEntry(creatureAddon.emote))
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has invalid emote (%u) defined in `creature_template_addon`.", entry, creatureAddon.emote);
- creatureAddon.emote = 0;
- }
- ++count;
- }
- while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u creature template addons in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
- }
- void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
- {
- if (!cInfo)
- return;
- bool ok = true; // bool to allow continue outside this loop
- for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff)
- {
- if (!cInfo->DifficultyEntry[diff])
- continue;
- ok = false; // will be set to true at the end of this loop again
- CreatureTemplate const* difficultyInfo = GetCreatureTemplate(cInfo->DifficultyEntry[diff]);
- if (!difficultyInfo)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has `difficulty_entry_%u`=%u but creature entry %u does not exist.",
- cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff], cInfo->DifficultyEntry[diff]);
- continue;
- }
- bool ok2 = true;
- for (uint32 diff2 = 0; diff2 < MAX_DIFFICULTY - 1 && ok2; ++diff2)
- {
- ok2 = false;
- if (_difficultyEntries[diff2].find(cInfo->Entry) != _difficultyEntries[diff2].end())
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) is listed as `difficulty_entry_%u` of another creature, but itself lists %u in `difficulty_entry_%u`.",
- cInfo->Entry, diff2 + 1, cInfo->DifficultyEntry[diff], diff + 1);
- continue;
- }
- if (_difficultyEntries[diff2].find(cInfo->DifficultyEntry[diff]) != _difficultyEntries[diff2].end())
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) already listed as `difficulty_entry_%u` for another entry.", cInfo->DifficultyEntry[diff], diff2 + 1);
- continue;
- }
- if (_hasDifficultyEntries[diff2].find(cInfo->DifficultyEntry[diff]) != _hasDifficultyEntries[diff2].end())
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has `difficulty_entry_%u`=%u but creature entry %u has itself a value in `difficulty_entry_%u`.",
- cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff], cInfo->DifficultyEntry[diff], diff2 + 1);
- continue;
- }
- ok2 = true;
- }
- if (!ok2)
- continue;
- if (cInfo->expansion > difficultyInfo->expansion)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, exp %u) has different `exp` in difficulty %u mode (Entry: %u, exp %u).",
- cInfo->Entry, cInfo->expansion, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->expansion);
- }
- if (cInfo->minlevel > difficultyInfo->minlevel)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, minlevel %u) has lower `minlevel` in difficulty %u mode (Entry: %u, minlevel %u).",
- cInfo->Entry, cInfo->minlevel, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->minlevel);
- }
- if (cInfo->maxlevel > difficultyInfo->maxlevel)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, maxlevel %u) has lower `maxlevel` in difficulty %u mode (Entry: %u, maxlevel %u).",
- cInfo->Entry, cInfo->maxlevel, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->maxlevel);
- }
- if (cInfo->faction != difficultyInfo->faction)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, faction %u) has different `faction` in difficulty %u mode (Entry: %u, faction %u).",
- cInfo->Entry, cInfo->faction, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->faction);
- TC_LOG_ERROR("sql.sql", "Possible FIX: UPDATE `creature_template` SET `faction`=%u WHERE `entry`=%u;",
- cInfo->faction, cInfo->DifficultyEntry[diff]);
- }
- if (cInfo->unit_class != difficultyInfo->unit_class)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, class %u) has different `unit_class` in difficulty %u mode (Entry: %u, class %u).",
- cInfo->Entry, cInfo->unit_class, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->unit_class);
- TC_LOG_ERROR("sql.sql", "Possible FIX: UPDATE `creature_template` SET `unit_class`=%u WHERE `entry`=%u;",
- cInfo->unit_class, cInfo->DifficultyEntry[diff]);
- continue;
- }
- if (cInfo->npcflag != difficultyInfo->npcflag)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, `npcflag`: %u) has different `npcflag` in difficulty %u mode (Entry: %u, `npcflag`: %u).",
- cInfo->Entry, cInfo->npcflag, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->npcflag);
- TC_LOG_ERROR("sql.sql", "Possible FIX: UPDATE `creature_template` SET `npcflag`=%u WHERE `entry`=%u;",
- cInfo->npcflag, cInfo->DifficultyEntry[diff]);
- continue;
- }
- if (cInfo->family != difficultyInfo->family)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, family %u) has different `family` in difficulty %u mode (Entry: %u, family %u).",
- cInfo->Entry, cInfo->family, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->family);
- TC_LOG_ERROR("sql.sql", "Possible FIX: UPDATE `creature_template` SET `family`=%u WHERE `entry`=%u;",
- cInfo->family, cInfo->DifficultyEntry[diff]);
- }
- if (cInfo->trainer_class != difficultyInfo->trainer_class)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, trainer_class: %u) has different `trainer_class` in difficulty %u mode (Entry: %u, trainer_class: %u).",
- cInfo->Entry, cInfo->trainer_class, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->trainer_class);
- TC_LOG_ERROR("sql.sql", "Possible FIX: UPDATE `creature_template` SET `trainer_class`=%u WHERE `entry`=%u;",
- cInfo->trainer_class, cInfo->DifficultyEntry[diff]);
- continue;
- }
- if (cInfo->trainer_race != difficultyInfo->trainer_race)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, trainer_race: %u) has different `trainer_race` in difficulty %u mode (Entry: %u, trainer_race: %u).",
- cInfo->Entry, cInfo->trainer_race, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->trainer_race);
- TC_LOG_ERROR("sql.sql", "Possible FIX: UPDATE `creature_template` SET `trainer_race`=%u WHERE `entry`=%u;",
- cInfo->trainer_race, cInfo->DifficultyEntry[diff]);
- continue;
- }
- if (cInfo->trainer_type != difficultyInfo->trainer_type)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, trainer_type: %u) has different `trainer_type` in difficulty %u mode (Entry: %u, trainer_type: %u).",
- cInfo->Entry, cInfo->trainer_type, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->trainer_type);
- TC_LOG_ERROR("sql.sql", "Possible FIX: UPDATE `creature_template` SET `trainer_type`=%u WHERE `entry`=%u;",
- cInfo->trainer_type, cInfo->DifficultyEntry[diff]);
- continue;
- }
- if (cInfo->type != difficultyInfo->type)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, type %u) has different `type` in difficulty %u mode (Entry: %u, type %u).",
- cInfo->Entry, cInfo->type, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->type);
- TC_LOG_ERROR("sql.sql", "Possible FIX: UPDATE `creature_template` SET `type`=%u WHERE `entry`=%u;",
- cInfo->type, cInfo->DifficultyEntry[diff]);
- }
- if (!cInfo->VehicleId && difficultyInfo->VehicleId)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, VehicleId %u) has different `VehicleId` in difficulty %u mode (Entry: %u, VehicleId %u).",
- cInfo->Entry, cInfo->VehicleId, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->VehicleId);
- }
- if (!difficultyInfo->AIName.empty())
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) lists difficulty %u mode entry %u with `AIName` filled in. `AIName` of difficulty 0 mode creature is always used instead.",
- cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
- continue;
- }
- if (difficultyInfo->ScriptID)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) lists difficulty %u mode entry %u with `ScriptName` filled in. `ScriptName` of difficulty 0 mode creature is always used instead.",
- cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
- continue;
- }
- _hasDifficultyEntries[diff].insert(cInfo->Entry);
- _difficultyEntries[diff].insert(cInfo->DifficultyEntry[diff]);
- ok = true;
- }
- FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction);
- if (!factionTemplate)
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has non-existing faction template (%u).", cInfo->Entry, cInfo->faction);
- // used later for scale
- CreatureDisplayInfoEntry const* displayScaleEntry = NULL;
- if (cInfo->Modelid1)
- {
- CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->Modelid1);
- if (!displayEntry)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) lists non-existing Modelid1 id (%u), this can crash the client.", cInfo->Entry, cInfo->Modelid1);
- const_cast<CreatureTemplate*>(cInfo)->Modelid1 = 0;
- }
- else if (!displayScaleEntry)
- displayScaleEntry = displayEntry;
- CreatureModelInfo const* modelInfo = GetCreatureModelInfo(cInfo->Modelid1);
- if (!modelInfo)
- TC_LOG_ERROR("sql.sql", "No model data exist for `Modelid1` = %u listed by creature (Entry: %u).", cInfo->Modelid1, cInfo->Entry);
- }
- if (cInfo->Modelid2)
- {
- CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->Modelid2);
- if (!displayEntry)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) lists non-existing Modelid2 id (%u), this can crash the client.", cInfo->Entry, cInfo->Modelid2);
- const_cast<CreatureTemplate*>(cInfo)->Modelid2 = 0;
- }
- else if (!displayScaleEntry)
- displayScaleEntry = displayEntry;
- CreatureModelInfo const* modelInfo = GetCreatureModelInfo(cInfo->Modelid2);
- if (!modelInfo)
- TC_LOG_ERROR("sql.sql", "No model data exist for `Modelid2` = %u listed by creature (Entry: %u).", cInfo->Modelid2, cInfo->Entry);
- }
- if (cInfo->Modelid3)
- {
- CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->Modelid3);
- if (!displayEntry)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) lists non-existing Modelid3 id (%u), this can crash the client.", cInfo->Entry, cInfo->Modelid3);
- const_cast<CreatureTemplate*>(cInfo)->Modelid3 = 0;
- }
- else if (!displayScaleEntry)
- displayScaleEntry = displayEntry;
- CreatureModelInfo const* modelInfo = GetCreatureModelInfo(cInfo->Modelid3);
- if (!modelInfo)
- TC_LOG_ERROR("sql.sql", "No model data exist for `Modelid3` = %u listed by creature (Entry: %u).", cInfo->Modelid3, cInfo->Entry);
- }
- if (cInfo->Modelid4)
- {
- CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->Modelid4);
- if (!displayEntry)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) lists non-existing Modelid4 id (%u), this can crash the client.", cInfo->Entry, cInfo->Modelid4);
- const_cast<CreatureTemplate*>(cInfo)->Modelid4 = 0;
- }
- else if (!displayScaleEntry)
- displayScaleEntry = displayEntry;
- CreatureModelInfo const* modelInfo = GetCreatureModelInfo(cInfo->Modelid4);
- if (!modelInfo)
- TC_LOG_ERROR("sql.sql", "No model data exist for `Modelid4` = %u listed by creature (Entry: %u).", cInfo->Modelid4, cInfo->Entry);
- }
- if (!displayScaleEntry)
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) does not have any existing display id in Modelid1/Modelid2/Modelid3/Modelid4.", cInfo->Entry);
- for (int k = 0; k < MAX_KILL_CREDIT; ++k)
- {
- if (cInfo->KillCredit[k])
- {
- if (!GetCreatureTemplate(cInfo->KillCredit[k]))
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) lists non-existing creature entry %u in `KillCredit%d`.", cInfo->Entry, cInfo->KillCredit[k], k + 1);
- const_cast<CreatureTemplate*>(cInfo)->KillCredit[k] = 0;
- }
- }
- }
- if (!cInfo->unit_class || ((1 << (cInfo->unit_class-1)) & CLASSMASK_ALL_CREATURES) == 0)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has invalid unit_class (%u) in creature_template. Set to 1 (UNIT_CLASS_WARRIOR).", cInfo->Entry, cInfo->unit_class);
- const_cast<CreatureTemplate*>(cInfo)->unit_class = UNIT_CLASS_WARRIOR;
- }
- if (cInfo->dmgschool >= MAX_SPELL_SCHOOL)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has invalid spell school value (%u) in `dmgschool`.", cInfo->Entry, cInfo->dmgschool);
- const_cast<CreatureTemplate*>(cInfo)->dmgschool = SPELL_SCHOOL_NORMAL;
- }
- if (cInfo->BaseAttackTime == 0)
- const_cast<CreatureTemplate*>(cInfo)->BaseAttackTime = BASE_ATTACK_TIME;
- if (cInfo->RangeAttackTime == 0)
- const_cast<CreatureTemplate*>(cInfo)->RangeAttackTime = BASE_ATTACK_TIME;
- if ((cInfo->npcflag & UNIT_NPC_FLAG_TRAINER) && cInfo->trainer_type >= MAX_TRAINER_TYPE)
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong trainer type %u.", cInfo->Entry, cInfo->trainer_type);
- if (cInfo->speed_walk == 0.0f)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong value (%f) in speed_walk, set to 1.", cInfo->Entry, cInfo->speed_walk);
- const_cast<CreatureTemplate*>(cInfo)->speed_walk = 1.0f;
- }
- if (cInfo->speed_run == 0.0f)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong value (%f) in speed_run, set to 1.14286.", cInfo->Entry, cInfo->speed_run);
- const_cast<CreatureTemplate*>(cInfo)->speed_run = 1.14286f;
- }
- if (cInfo->type && !sCreatureTypeStore.LookupEntry(cInfo->type))
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has invalid creature type (%u) in `type`.", cInfo->Entry, cInfo->type);
- const_cast<CreatureTemplate*>(cInfo)->type = CREATURE_TYPE_HUMANOID;
- }
- // must exist or used hidden but used in data horse case
- if (cInfo->family && !sCreatureFamilyStore.LookupEntry(cInfo->family) && cInfo->family != CREATURE_FAMILY_HORSE_CUSTOM)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has invalid creature family (%u) in `family`.", cInfo->Entry, cInfo->family);
- const_cast<CreatureTemplate*>(cInfo)->family = 0;
- }
- if (cInfo->InhabitType <= 0 || cInfo->InhabitType > INHABIT_ANYWHERE)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong value (%u) in `InhabitType`, creature will not correctly walk/swim/fly.", cInfo->Entry, cInfo->InhabitType);
- const_cast<CreatureTemplate*>(cInfo)->InhabitType = INHABIT_ANYWHERE;
- }
- if (cInfo->HoverHeight < 0.0f)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong value (%f) in `HoverHeight`", cInfo->Entry, cInfo->HoverHeight);
- const_cast<CreatureTemplate*>(cInfo)->HoverHeight = 1.0f;
- }
- if (cInfo->VehicleId)
- {
- VehicleEntry const* vehId = sVehicleStore.LookupEntry(cInfo->VehicleId);
- if (!vehId)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has a non-existing VehicleId (%u). This *WILL* cause the client to freeze!", cInfo->Entry, cInfo->VehicleId);
- const_cast<CreatureTemplate*>(cInfo)->VehicleId = 0;
- }
- }
- if (cInfo->PetSpellDataId)
- {
- CreatureSpellDataEntry const* spellDataId = sCreatureSpellDataStore.LookupEntry(cInfo->PetSpellDataId);
- if (!spellDataId)
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has non-existing PetSpellDataId (%u).", cInfo->Entry, cInfo->PetSpellDataId);
- }
- for (uint8 j = 0; j < CREATURE_MAX_SPELLS; ++j)
- {
- if (cInfo->spells[j] && !sSpellMgr->GetSpellInfo(cInfo->spells[j]))
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has non-existing Spell%d (%u), set to 0.", cInfo->Entry, j+1, cInfo->spells[j]);
- const_cast<CreatureTemplate*>(cInfo)->spells[j] = 0;
- }
- }
- if (cInfo->MovementType >= MAX_DB_MOTION_TYPE)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong movement generator type (%u), ignored and set to IDLE.", cInfo->Entry, cInfo->MovementType);
- const_cast<CreatureTemplate*>(cInfo)->MovementType = IDLE_MOTION_TYPE;
- }
- /// if not set custom creature scale then load scale from CreatureDisplayInfo.dbc
- if (cInfo->scale <= 0.0f)
- {
- if (displayScaleEntry)
- const_cast<CreatureTemplate*>(cInfo)->scale = displayScaleEntry->scale;
- else
- const_cast<CreatureTemplate*>(cInfo)->scale = 1.0f;
- }
- if (cInfo->expansion > (MAX_EXPANSIONS - 1))
- {
- TC_LOG_ERROR("sql.sql", "Table `creature_template` lists creature (Entry: %u) with `exp` %u. Ignored and set to 0.", cInfo->Entry, cInfo->expansion);
- const_cast<CreatureTemplate*>(cInfo)->expansion = 0;
- }
- if (cInfo->expansionUnknown > MAX_EXPANSIONS)
- {
- TC_LOG_ERROR("sql.sql", "Table `creature_template` lists creature (Entry: %u) with `exp_unk` %u. Ignored and set to 0.", cInfo->Entry, cInfo->expansionUnknown);
- const_cast<CreatureTemplate*>(cInfo)->expansionUnknown = 0;
- }
- if (uint32 badFlags = (cInfo->flags_extra & ~CREATURE_FLAG_EXTRA_DB_ALLOWED))
- {
- TC_LOG_ERROR("sql.sql", "Table `creature_template` lists creature (Entry: %u) with disallowed `flags_extra` %u, removing incorrect flag.", cInfo->Entry, badFlags);
- const_cast<CreatureTemplate*>(cInfo)->flags_extra &= CREATURE_FLAG_EXTRA_DB_ALLOWED;
- }
- const_cast<CreatureTemplate*>(cInfo)->ModDamage *= Creature::_GetDamageMod(cInfo->rank);
- }
- void ObjectMgr::LoadCreatureAddons()
- {
- uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4 5 6
- QueryResult result = WorldDatabase.Query("SELECT guid, path_id, mount, bytes1, bytes2, emote, auras FROM creature_addon");
- if (!result)
- {
- TC_LOG_INFO("server.loading", ">> Loaded 0 creature addon definitions. DB table `creature_addon` is empty.");
- return;
- }
- uint32 count = 0;
- do
- {
- Field* fields = result->Fetch();
- uint32 guid = fields[0].GetUInt32();
- CreatureData const* creData = GetCreatureData(guid);
- if (!creData)
- {
- TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) does not exist but has a record in `creature_addon`", guid);
- continue;
- }
- CreatureAddon& creatureAddon = _creatureAddonStore[guid];
- creatureAddon.path_id = fields[1].GetUInt32();
- if (creData->movementType == WAYPOINT_MOTION_TYPE && !creatureAddon.path_id)
- {
- const_cast<CreatureData*>(creData)->movementType = IDLE_MOTION_TYPE;
- TC_LOG_ERROR("sql.sql", "Creature (GUID %u) has movement type set to WAYPOINT_MOTION_TYPE but no path assigned", guid);
- }
- creatureAddon.mount = fields[2].GetUInt32();
- creatureAddon.bytes1 = fields[3].GetUInt32();
- creatureAddon.bytes2 = fields[4].GetUInt32();
- creatureAddon.emote = fields[5].GetUInt32();
- Tokenizer tokens(fields[6].GetString(), ' ');
- uint8 i = 0;
- creatureAddon.auras.resize(tokens.size());
- for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
- {
- SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(uint32(atol(*itr)));
- if (!AdditionalSpellInfo)
- {
- TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) has wrong spell %u defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr)));
- continue;
- }
- if (AdditionalSpellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
- TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr)));
- creatureAddon.auras[i++] = uint32(atol(*itr));
- }
- if (creatureAddon.mount)
- {
- if (!sCreatureDisplayInfoStore.LookupEntry(creatureAddon.mount))
- {
- TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) has invalid displayInfoId (%u) for mount defined in `creature_addon`", guid, creatureAddon.mount);
- creatureAddon.mount = 0;
- }
- }
- if (!sEmotesStore.LookupEntry(creatureAddon.emote))
- {
- TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) has invalid emote (%u) defined in `creature_addon`.", guid, creatureAddon.emote);
- creatureAddon.emote = 0;
- }
- ++count;
- }
- while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u creature addons in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
- }
- CreatureAddon const* ObjectMgr::GetCreatureAddon(uint32 lowguid)
- {
- CreatureAddonContainer::const_iterator itr = _creatureAddonStore.find(lowguid);
- if (itr != _creatureAddonStore.end())
- return &(itr->second);
- return NULL;
- }
- CreatureAddon const* ObjectMgr::GetCreatureTemplateAddon(uint32 entry)
- {
- CreatureAddonContainer::const_iterator itr = _creatureTemplateAddonStore.find(entry);
- if (itr != _creatureTemplateAddonStore.end())
- return &(itr->second);
- return NULL;
- }
- EquipmentInfo const* ObjectMgr::GetEquipmentInfo(uint32 entry, int8& id)
- {
- EquipmentInfoContainer::const_iterator itr = _equipmentInfoStore.find(entry);
- if (itr == _equipmentInfoStore.end())
- return NULL;
- if (itr->second.empty())
- return NULL;
- if (id == -1) // select a random element
- {
- EquipmentInfoContainerInternal::const_iterator ritr = itr->second.begin();
- std::advance(ritr, urand(0u, itr->second.size() - 1));
- id = std::distance(itr->second.begin(), ritr) + 1;
- return &ritr->second;
- }
- else
- {
- EquipmentInfoContainerInternal::const_iterator itr2 = itr->second.find(id);
- if (itr2 != itr->second.end())
- return &itr2->second;
- }
- return NULL;
- }
- void ObjectMgr::LoadEquipmentTemplates()
- {
- uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4
- QueryResult result = WorldDatabase.Query("SELECT entry, id, itemEntry1, itemEntry2, itemEntry3 FROM creature_equip_template");
- if (!result)
- {
- TC_LOG_INFO("server.loading", ">> Loaded 0 creature equipment templates. DB table `creature_equip_template` is empty!");
- return;
- }
- uint32 count = 0;
- do
- {
- Field* fields = result->Fetch();
- uint32 entry = fields[0].GetUInt32();
- if (!sObjectMgr->GetCreatureTemplate(entry))
- {
- TC_LOG_ERROR("sql.sql", "Creature template (Entry: %u) does not exist but has a record in `creature_equip_template`", entry);
- continue;
- }
- uint8 id = fields[1].GetUInt8();
- if (!id)
- {
- TC_LOG_ERROR("sql.sql", "Creature equipment template with id 0 found for creature %u, skipped.", entry);
- …
Large files files are truncated, but you can click here to view the full file