80#include <G3D/g3dmath.h>
110 std::string res =
"";
179 size_t pos = name.find(
'-');
180 if (pos != std::string::npos)
192 Unit const* summoner =
nullptr;
223 _equipmentSetGuid(1),
227 _gameObjectSpawnId(1),
244 if (data.size() <=
size_t(localeConstant))
247 data.resize(localeConstant + 1);
250 data[localeConstant] = value.empty() ?
"" : value;
260 QueryResult result =
WorldDatabase.Query(
"SELECT entry, locale, Name, NameAlt, Title, TitleAlt FROM creature_template_locale");
266 Field* fields = result->Fetch();
281 }
while (result->NextRow());
293 QueryResult result =
WorldDatabase.Query(
"SELECT MenuID, OptionID, Locale, OptionText, BoxText FROM gossip_menu_option_locale");
300 Field* fields = result->Fetch();
313 }
while (result->NextRow());
331 Field* fields = result->Fetch();
342 }
while (result->NextRow());
377 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template definitions. DB table `creature_template` is empty.");
384 Field* fields = result->Fetch();
386 }
while (result->NextRow());
406 creatureTemplate.
Entry = entry;
435 creatureTemplate.
type =
uint32(fields[27].GetUInt8());
441 creatureTemplate.
spells[i] = 0;
447 if (!fields[31].IsNull())
480 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template gossip definitions. DB table `creature_template_gossip` is empty.");
488 Field* fields = result->Fetch();
496 TC_LOG_ERROR(
"sql.sql",
"creature_template_gossip has gossip definitions for creature {} but this creature doesn't exist", creatureID);
501 if (menuBounds.first == menuBounds.second)
503 TC_LOG_ERROR(
"sql.sql",
"creature_template_gossip has gossip definitions for menu id {} but this menu doesn't exist", menuID);
512 }
while (result->NextRow());
522 QueryResult result =
WorldDatabase.Query(
"SELECT CreatureID, School, Resistance FROM creature_template_resistance");
526 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template resistance definitions. DB table `creature_template_resistance` is empty.");
534 Field* fields = result->Fetch();
541 TC_LOG_ERROR(
"sql.sql",
"creature_template_resistance has resistance definitions for creature {} but this school {} doesn't exist", creatureID, school);
548 TC_LOG_ERROR(
"sql.sql",
"creature_template_resistance has resistance definitions for creature {} but this creature doesn't exist", creatureID);
557 }
while (result->NextRow());
571 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template spell definitions. DB table `creature_template_spell` is empty.");
579 Field* fields = result->Fetch();
586 TC_LOG_ERROR(
"sql.sql",
"creature_template_spell has spell definitions for creature {} with a incorrect index {}", creatureID, index);
593 TC_LOG_ERROR(
"sql.sql",
"creature_template_spell has spell definitions for creature {} but this creature doesn't exist", creatureID);
602 }
while (result->NextRow());
612 QueryResult result =
WorldDatabase.Query(
"SELECT CreatureID, CreatureDisplayID, DisplayScale, Probability FROM creature_template_model ORDER BY Idx ASC");
616 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template model definitions. DB table `creature_template_model` is empty.");
623 Field* fields = result->Fetch();
627 float displayScale = fields[2].
GetFloat();
628 float probability = fields[3].
GetFloat();
633 TC_LOG_ERROR(
"sql.sql",
"Creature template (Entry: {}) does not exist but has a record in `creature_template_model`", creatureId);
640 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) lists non-existing CreatureDisplayID id ({}), this can crash the client.", creatureId, creatureDisplayId);
646 TC_LOG_ERROR(
"sql.sql",
"No model data exist for `CreatureDisplayID` = {} listed by creature (Entry: {}).", creatureDisplayId, creatureId);
648 if (displayScale <= 0.0f)
655 while (result->NextRow());
665 QueryResult result =
WorldDatabase.Query(
"SELECT CreatureID, CreatureIDVisibleToSummoner, GroundMountDisplayID, FlyingMountDisplayID, DespawnOnQuestsRemoved FROM creature_summoned_data");
669 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature summoned data definitions. DB table `creature_summoned_data` is empty.");
675 Field* fields = result->Fetch();
680 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summoned_data` references non-existing creature {}, skipped", creatureId);
691 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summoned_data` references non-existing creature {} in CreatureIDVisibleToSummoner for creature {}, set to 0",
698 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summoned_data` references non-existing display id {} in GroundMountDisplayID for creature {}, set to 0",
705 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summoned_data` references non-existing display id {} in FlyingMountDisplayID for creature {}, set to 0",
713 for (std::string_view questStr :
Trinity::Tokenize(*despawnOnQuestsRemoved,
',',
false))
722 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summoned_data` references non-existing quest {} in DespawnOnQuestsRemoved for creature {}, skipping",
723 *questId, creatureId);
734 }
while (result->NextRow());
744 QueryResult result =
WorldDatabase.Query(
"SELECT entry, PathId, mount, StandState, AnimTier, VisFlags, SheathState, PvPFlags, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_template_addon");
748 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template addon definitions. DB table `creature_template_addon` is empty.");
755 Field* fields = result->Fetch();
761 TC_LOG_ERROR(
"sql.sql",
"Creature template (Entry: {}) does not exist but has a record in `creature_template_addon`", entry);
780 for (std::string_view aura :
Trinity::Tokenize(fields[13].GetStringView(),
' ',
false))
788 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has wrong spell '{}' defined in `auras` field in `creature_template_addon`.", entry, aura);
793 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has SPELL_AURA_CONTROL_VEHICLE aura {} defined in `auras` field in `creature_template_addon`.", entry, spellInfo->
Id);
795 if (std::find(creatureAddon.
auras.begin(), creatureAddon.
auras.end(), spellInfo->
Id) != creatureAddon.
auras.end())
797 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has duplicate aura (spell {}) in `auras` field in `creature_template_addon`.", entry, spellInfo->
Id);
803 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has temporary aura (spell {}) in `auras` field in `creature_template_addon`.", entry, spellInfo->
Id);
807 creatureAddon.
auras.push_back(spellInfo->
Id);
810 if (creatureAddon.
mount)
814 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid displayInfoId ({}) for mount defined in `creature_template_addon`", entry, creatureAddon.
mount);
815 creatureAddon.
mount = 0;
821 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid unit stand state ({}) defined in `creature_template_addon`. Truncated to 0.", entry, creatureAddon.
standState);
827 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid animation tier ({}) defined in `creature_template_addon`. Truncated to 0.", entry, creatureAddon.
animTier);
833 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid sheath state ({}) defined in `creature_template_addon`. Truncated to 0.", entry, creatureAddon.
sheathState);
841 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid emote ({}) defined in `creature_template_addon`.", entry, creatureAddon.
emote);
842 creatureAddon.
emote = 0;
847 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid aiAnimKit ({}) defined in `creature_template_addon`.", entry, creatureAddon.
aiAnimKit);
853 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid movementAnimKit ({}) defined in `creature_template_addon`.", entry, creatureAddon.
movementAnimKit);
859 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid meleeAnimKit ({}) defined in `creature_template_addon`.", entry, creatureAddon.
meleeAnimKit);
865 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid visibilityDistanceType ({}) defined in `creature_template_addon`.",
872 while (result->NextRow());
882 QueryResult result =
WorldDatabase.Query(
"SELECT Entry, NoNPCDamageBelowHealthPct FROM creature_template_sparring");
886 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template sparring definitions. DB table `creature_template_sparring` is empty.");
893 Field* fields = result->Fetch();
896 float noNPCDamageBelowHealthPct = fields[1].
GetFloat();
900 TC_LOG_ERROR(
"sql.sql",
"Creature template (Entry: {}) does not exist but has a record in `creature_template_sparring`", entry);
904 if (noNPCDamageBelowHealthPct <= 0 || noNPCDamageBelowHealthPct > 100)
906 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid NoNPCDamageBelowHealthPct ({}) defined in `creature_template_sparring`. Skipping",
907 entry, noNPCDamageBelowHealthPct);
913 }
while (result->NextRow());
923 QueryResult result =
WorldDatabase.Query(
"SELECT Entry, DifficultyID, LevelScalingDeltaMin, LevelScalingDeltaMax, ContentTuningID, HealthScalingExpansion, "
925 "HealthModifier, ManaModifier, ArmorModifier, DamageModifier, CreatureDifficultyID, TypeFlags, TypeFlags2, TypeFlags3, "
927 "LootID, PickPocketLootID, SkinLootID, GoldMin, GoldMax,"
929 "StaticFlags1, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, StaticFlags6, StaticFlags7, StaticFlags8 "
930 "FROM creature_template_difficulty ORDER BY Entry");
934 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template difficulty definitions. DB table `creature_template_difficulty` is empty.");
941 Field* fields = result->Fetch();
949 TC_LOG_ERROR(
"sql.sql",
"Creature template (Entry: {}) does not exist but has a record in `creature_template_difficulty`", entry);
953 CreatureDifficulty& creatureDifficulty = itr->second.difficultyStore.try_emplace(difficulty).first->second;
980 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template_difficulty` lists creature (ID: {}) with invalid `HealthScalingExpansion` {}. Ignored and set to 0.",
987 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template_difficulty` lists creature (ID: {}) with `GoldMin` {} greater than `GoldMax` {}, setting `GoldMax` to {}.",
993 }
while (result->NextRow());
1003 if (!cInfo->
AIName.empty())
1008 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has non-registered `AIName` '{}' set, removing", cInfo->
Entry, cInfo->
AIName);
1016 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has not-allowed `AIName` '{}' set, removing", cInfo->
Entry, cInfo->
AIName);
1023 if (!factionTemplate)
1025 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has non-existing faction template ({}). This can lead to crashes, set to faction 35.", cInfo->
Entry, cInfo->
faction);
1035 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) lists non-existing creature entry {} in `KillCredit{}`.", cInfo->
Entry, cInfo->
KillCredit[k], k + 1);
1041 if (cInfo->
Models.empty())
1042 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) does not have any existing display id in creature_template_model.", cInfo->
Entry);
1046 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid unit_class ({}) in creature_template. Set to 1 (UNIT_CLASS_WARRIOR).", cInfo->
Entry, cInfo->
unit_class);
1052 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid spell school value ({}) in `dmgschool`.", cInfo->
Entry, cInfo->
dmgschool);
1070 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has wrong value ({}) in speed_run, set to 1.14286.", cInfo->
Entry, cInfo->
speed_run);
1076 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid creature type ({}) in `type`.", cInfo->
Entry, cInfo->
type);
1082 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid creature family ({}) in `family`.", cInfo->
Entry, cInfo->
family);
1093 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has a non-existing VehicleId ({}). This *WILL* cause the client to freeze!", cInfo->
Entry, cInfo->
VehicleId);
1102 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has non-existing Spell{} ({}), set to 0.", cInfo->
Entry, j+1, cInfo->
spells[j]);
1109 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has wrong movement generator type ({}), ignored and set to IDLE.", cInfo->
Entry, cInfo->
MovementType);
1115 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template` lists creature (Entry: {}) with `RequiredExpansion` {}. Ignored and set to 0.", cInfo->
Entry, cInfo->
RequiredExpansion);
1121 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template` lists creature (Entry: {}) with disallowed `flags_extra` {}, removing incorrect flag.", cInfo->
Entry, badFlags);
1127 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template` lists creature (Entry: {}) with disallowed `unit_flags` {}, removing incorrect flag.", cInfo->
Entry, disallowedUnitFlags);
1133 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template` lists creature (Entry: {}) with disallowed `unit_flags2` {}, removing incorrect flag.", cInfo->
Entry, disallowedUnitFlags2);
1139 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template` lists creature (Entry: {}) with disallowed `unit_flags3` {}, removing incorrect flag.", cInfo->
Entry, disallowedUnitFlags3);
1144 TC_LOG_INFO(
"sql.sql",
"Creature (Entry: {}) has assigned gossip menu, but npcflag does not include UNIT_NPC_FLAG_GOSSIP.", cInfo->
Entry);
1146 TC_LOG_INFO(
"sql.sql",
"Creature (Entry: {}) has npcflag UNIT_NPC_FLAG_GOSSIP, but gossip menu is unassigned.", cInfo->
Entry);
1159 TC_LOG_ERROR(
"sql.sql",
"`{}`.`Chase` wrong value ({}) for Id {}, setting to Run.",
1166 TC_LOG_ERROR(
"sql.sql",
"`{}`.`Random` wrong value ({}) for Id {}, setting to Walk.",
1177 QueryResult result =
WorldDatabase.Query(
"SELECT guid, PathId, mount, StandState, AnimTier, VisFlags, SheathState, PvPFlags, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_addon");
1181 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature addon definitions. DB table `creature_addon` is empty.");
1188 Field* fields = result->Fetch();
1195 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) does not exist but has a record in `creature_addon`", guid);
1205 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID {}) has movement type set to WAYPOINT_MOTION_TYPE but no path assigned", guid);
1220 for (std::string_view aura :
Trinity::Tokenize(fields[13].GetStringView(),
' ',
false))
1228 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has wrong spell '{}' defined in `auras` field in `creature_addon`.", guid, aura);
1233 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has SPELL_AURA_CONTROL_VEHICLE aura {} defined in `auras` field in `creature_addon`.", guid, spellInfo->
Id);
1235 if (std::find(creatureAddon.
auras.begin(), creatureAddon.
auras.end(), spellInfo->
Id) != creatureAddon.
auras.end())
1237 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has duplicate aura (spell {}) in `auras` field in `creature_addon`.", guid, spellInfo->
Id);
1243 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has temporary aura (spell {}) in `auras` field in `creature_addon`.", guid, spellInfo->
Id);
1247 creatureAddon.
auras.push_back(spellInfo->
Id);
1250 if (creatureAddon.
mount)
1254 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid displayInfoId ({}) for mount defined in `creature_addon`", guid, creatureAddon.
mount);
1255 creatureAddon.
mount = 0;
1261 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid unit stand state ({}) defined in `creature_addon`. Truncated to 0.", guid, creatureAddon.
standState);
1267 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid animation tier ({}) defined in `creature_addon`. Truncated to 0.", guid, creatureAddon.
animTier);
1273 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid sheath state ({}) defined in `creature_addon`. Truncated to 0.", guid, creatureAddon.
sheathState);
1281 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid emote ({}) defined in `creature_addon`.", guid, creatureAddon.
emote);
1282 creatureAddon.
emote = 0;
1287 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid aiAnimKit ({}) defined in `creature_addon`.", guid, creatureAddon.
aiAnimKit);
1293 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid movementAnimKit ({}) defined in `creature_addon`.", guid, creatureAddon.
movementAnimKit);
1299 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid meleeAnimKit ({}) defined in `creature_addon`.", guid, creatureAddon.
meleeAnimKit);
1305 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid visibilityDistanceType ({}) defined in `creature_addon`.",
1312 while (result->NextRow());
1322 QueryResult result =
WorldDatabase.Query(
"SELECT guid, parent_rotation0, parent_rotation1, parent_rotation2, parent_rotation3, invisibilityType, invisibilityValue, WorldEffectID, AIAnimKitID FROM gameobject_addon");
1326 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject addon definitions. DB table `gameobject_addon` is empty.");
1333 Field* fields = result->Fetch();
1340 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) does not exist but has a record in `gameobject_addon`", guid);
1345 gameObjectAddon.
ParentRotation =
QuaternionData(fields[1].GetFloat(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat());
1353 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) has invalid InvisibilityType in `gameobject_addon`, disabled invisibility", guid);
1360 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) has InvisibilityType set but has no InvisibilityValue in `gameobject_addon`, set to 1", guid);
1366 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) has invalid parent rotation in `gameobject_addon`, set to default", guid);
1372 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) has invalid WorldEffectID ({}) in `gameobject_addon`, set to 0.", guid, gameObjectAddon.
WorldEffectID);
1378 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) has invalid AIAnimKitID ({}) in `gameobject_addon`, set to 0.", guid, gameObjectAddon.
AIAnimKitID);
1384 while (result->NextRow());
1393 return &(itr->second);
1402 return &(itr->second);
1411 return &(itr->second);
1432 if (itr->second.empty())
1437 EquipmentInfoContainerInternal::const_iterator ritr = itr->second.begin();
1438 std::advance(ritr,
urand(0u, itr->second.size() - 1));
1439 id = std::distance(itr->second.begin(), ritr) + 1;
1440 return &ritr->second;
1444 EquipmentInfoContainerInternal::const_iterator itr2 = itr->second.find(
id);
1445 if (itr2 != itr->second.end())
1446 return &itr2->second;
1459 "ItemID2, AppearanceModID2, ItemVisual2, "
1461 "ItemID3, AppearanceModID3, ItemVisual3 "
1462 "FROM creature_equip_template");
1466 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature equipment templates. DB table `creature_equip_template` is empty!");
1473 Field* fields = result->Fetch();
1479 TC_LOG_ERROR(
"sql.sql",
"Creature template (CreatureID: {}) does not exist but has a record in `creature_equip_template`", entry);
1486 TC_LOG_ERROR(
"sql.sql",
"Creature equipment template with id 0 found for creature {}, skipped.", entry);
1503 TC_LOG_ERROR(
"sql.sql",
"Unknown item (ID={}) in creature_equip_template.ItemID{} for CreatureID = {} and ID={}, forced to 0.",
1512 TC_LOG_ERROR(
"sql.sql",
"Unknown item appearance for (ID={}, AppearanceModID={}) pair in creature_equip_template.ItemID{} creature_equip_template.AppearanceModID{} "
1513 "for CreatureID = {} and ID={}, forced to default.",
1524 TC_LOG_ERROR(
"sql.sql",
"Item (ID={}) in creature_equip_template.ItemID{} for CreatureID = {} and ID = {} is not equipable in a hand, forced to 0.",
1532 while (result->NextRow());
1545 "SELECT cmo.SpawnId,"
1546 "COALESCE(cmo.HoverInitiallyEnabled, ctm.HoverInitiallyEnabled),"
1547 "COALESCE(cmo.Chase, ctm.Chase),"
1548 "COALESCE(cmo.Random, ctm.Random),"
1549 "COALESCE(cmo.InteractionPauseTimer, ctm.InteractionPauseTimer) "
1550 "FROM creature_movement_override AS cmo "
1551 "LEFT JOIN creature AS c ON c.guid = cmo.SpawnId "
1552 "LEFT JOIN creature_template_movement AS ctm ON ctm.CreatureId = c.id");
1556 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature movement overrides. DB table `creature_movement_override` is empty!");
1562 Field* fields = result->Fetch();
1566 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) does not exist but has a record in `creature_movement_override`", spawnId);
1571 if (!fields[1].IsNull())
1582 while (result->NextRow());
1591 return &(itr->second);
1617#define ChooseCreatureFlagSource(field) ((data && data->field.has_value()) ? *data->field : cInfo->field)
1652#undef ChooseCreatureFlagSource
1671 if (creatureTemplate)
1673 auto itr = std::find_if(creatureTemplate->
Models.begin(), creatureTemplate->
Models.end(), [&](
CreatureModel const& templateModel)
1675 return templateModel.CreatureDisplayID == modelInfo->displayId_other_gender;
1677 if (itr != creatureTemplate->
Models.end())
1691 QueryResult result =
WorldDatabase.Query(
"SELECT DisplayID, BoundingRadius, CombatReach, DisplayID_Other_Gender FROM creature_model_info");
1695 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature model definitions. DB table `creature_model_info` is empty.");
1703 uint32 trigggerCreatureModelFileID[5] = { 124640, 124641, 124642, 343863, 439302 };
1707 Field* fields = result->Fetch();
1712 if (!creatureDisplay)
1714 TC_LOG_ERROR(
"sql.sql",
"Table `creature_model_info` has a non-existent DisplayID (ID: {}). Skipped.", displayId);
1738 TC_LOG_ERROR(
"sql.sql",
"Table `creature_model_info` has a non-existent DisplayID_Other_Gender (ID: {}) being used by DisplayID (ID: {}).", modelInfo.
displayId_other_gender, displayId);
1747 for (
uint32 i = 0; i < 5; ++i)
1749 if (modelData->FileDataID == trigggerCreatureModelFileID[i])
1759 while (result->NextRow());
1770 QueryResult result =
WorldDatabase.Query(
"SELECT guid, linkedGuid, linkType FROM linked_respawn ORDER BY guid ASC");
1774 TC_LOG_INFO(
"server.loading",
">> Loaded 0 linked respawns. DB table `linked_respawn` is empty.");
1780 Field* fields = result->Fetch();
1795 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature (guid) '{}' not found in creature table", guidLow);
1803 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature (linkedGuid) '{}' not found in creature table", linkedGuidLow);
1811 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature '{}' linking to Creature '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1819 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature '{}' linking to Creature '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1824 guid = ObjectGuid::Create<HighGuid::Creature>(slave->
mapId, slave->
id, guidLow);
1825 linkedGuid = ObjectGuid::Create<HighGuid::Creature>(master->
mapId, master->
id, linkedGuidLow);
1833 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature (guid) '{}' not found in creature table", guidLow);
1841 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject (linkedGuid) '{}' not found in gameobject table", linkedGuidLow);
1849 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature '{}' linking to Gameobject '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1857 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature '{}' linking to Gameobject '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1862 guid = ObjectGuid::Create<HighGuid::Creature>(slave->
mapId, slave->
id, guidLow);
1863 linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->
mapId, master->
id, linkedGuidLow);
1871 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject (guid) '{}' not found in gameobject table", guidLow);
1879 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject (linkedGuid) '{}' not found in gameobject table", linkedGuidLow);
1887 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject '{}' linking to Gameobject '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1895 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject '{}' linking to Gameobject '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1900 guid = ObjectGuid::Create<HighGuid::GameObject>(slave->
mapId, slave->
id, guidLow);
1901 linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->
mapId, master->
id, linkedGuidLow);
1909 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject (guid) '{}' not found in gameobject table", guidLow);
1917 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature (linkedGuid) '{}' not found in creature table", linkedGuidLow);
1925 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject '{}' linking to Creature '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1933 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject '{}' linking to Creature '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1938 guid = ObjectGuid::Create<HighGuid::GameObject>(slave->
mapId, slave->
id, guidLow);
1939 linkedGuid = ObjectGuid::Create<HighGuid::Creature>(master->
mapId, master->
id, linkedGuidLow);
1947 while (result->NextRow());
1959 ObjectGuid guid = ObjectGuid::Create<HighGuid::Creature>(master->
mapId, master->
id, guidLow);
1974 TC_LOG_ERROR(
"sql.sql",
"Creature '{}' linking to non-existent creature '{}'.", guidLow, linkedGuidLow);
1981 TC_LOG_ERROR(
"sql.sql",
"Creature '{}' linking to '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1988 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature '{}' linking to '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1992 ObjectGuid linkedGuid = ObjectGuid::Create<HighGuid::Creature>(slave->
mapId, slave->
id, linkedGuidLow);
2010 QueryResult result =
WorldDatabase.Query(
"SELECT summonerId, summonerType, groupId, entry, position_x, position_y, position_z, orientation, summonType, summonTime FROM creature_summon_groups");
2014 TC_LOG_INFO(
"server.loading",
">> Loaded 0 temp summons. DB table `creature_summon_groups` is empty.");
2021 Field* fields = result->Fetch();
2027 switch (summonerType)
2032 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summon_groups` has summoner with non existing entry {} for creature summoner type, skipped.", summonerId);
2039 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summon_groups` has summoner with non existing entry {} for gameobject summoner type, skipped.", summonerId);
2046 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summon_groups` has summoner with non existing entry {} for map summoner type, skipped.", summonerId);
2051 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summon_groups` has unhandled summoner type {} for summoner {}, skipped.", summonerType, summonerId);
2060 TC_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);
2067 float orientation = fields[7].
GetFloat();
2075 TC_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);
2086 }
while (result->NextRow());
2092 std::set<Difficulty>
const& mapDifficulties)
2094 std::vector<Difficulty> difficulties;
2095 bool isTransportMap =
sObjectMgr->IsTransportMap(mapId);
2101 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has {} (GUID: {}) with non invalid difficulty id {}, skipped.",
2102 table, table, spawnId,
uint32(difficultyId));
2106 if (!isTransportMap && mapDifficulties.find(difficultyId) == mapDifficulties.end())
2108 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has {} (GUID: {}) has unsupported difficulty {} for map (Id: {}).",
2109 table, table, spawnId,
uint32(difficultyId), mapId);
2113 difficulties.push_back(difficultyId);
2116 std::sort(difficulties.begin(), difficulties.end());
2117 return difficulties;
2125 QueryResult result =
WorldDatabase.Query(
"SELECT creature.guid, id, map, position_x, position_y, position_z, orientation, modelid, equipment_id, spawntimesecs, wander_distance, "
2127 "currentwaypoint, curHealthPct, MovementType, spawnDifficulties, eventEntry, poolSpawnId, creature.npcflag, creature.unit_flags, creature.unit_flags2, creature.unit_flags3, "
2129 "creature.phaseUseFlags, creature.phaseid, creature.phasegroup, creature.terrainSwapMap, creature.ScriptName, creature.StringId "
2131 "LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid "
2132 "LEFT OUTER JOIN pool_members ON pool_members.type = 0 AND creature.guid = pool_members.spawnId");
2136 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creatures. DB table `creature` is empty.");
2141 std::unordered_map<uint32, std::set<Difficulty>> spawnMasks;
2143 spawnMasks[mapDifficulty->MapID].insert(
Difficulty(mapDifficulty->DifficultyID));
2151 Field* fields = result->Fetch();
2159 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {}) with non existing creature entry {}, skipped.", guid, entry);
2167 data.
spawnPoint.
Relocate(fields[3].GetFloat(), fields[4].GetFloat(), fields[5].GetFloat(), fields[6].GetFloat());
2168 if (
uint32 displayId = fields[7].GetUInt32())
2194 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {}) that spawned at nonexistent map (Id: {}), skipped.", guid, data.
mapId);
2210 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {} MapID: {}) spawned on a possible invalid position ({})",
2218 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {}) that is not spawned in any difficulty, skipped.", guid);
2226 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with invalid `modelid` {}, ignoring.", guid, data.
id, data.
display->CreatureDisplayID);
2236 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (Entry: {}) with equipment_id {} not found in table `creature_equip_template`, set to no equipment.", data.
id, data.
equipmentId);
2244 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with `creature_template`.`flags_extra` including CREATURE_FLAG_EXTRA_INSTANCE_BIND but creature is not in instance.", guid, data.
id);
2249 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with wrong movement generator type ({}), ignored and set to IDLE.", guid, data.
id, data.
movementType);
2255 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with `wander_distance`< 0, set to 0.", guid, data.
id);
2260 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with `wander_distance` below the allowed minimum distance of 0.1, set to 0.", guid, data.
id);
2267 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with `MovementType`=1 (random movement) but with `wander_distance`=0, replace by idle movement type (0).", guid, data.
id);
2275 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with `MovementType`=0 (idle) have `wander_distance`<>0, set to 0.", guid, data.
id);
2282 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.
id);
2288 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE,"
2289 " removing PHASE_USE_FLAGS_INVERSE.", guid, data.
id);
2295 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.
id);
2303 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) with `phaseid` {} does not exist, set to 0", guid, data.
id, data.
phaseId);
2312 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) with `phasegroup` {} does not exist, set to 0", guid, data.
id, data.
phaseGroup);
2320 if (!terrainSwapEntry)
2322 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) with `terrainSwapMap` {} does not exist, set to -1", guid, data.
id, data.
terrainSwapMap);
2327 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) with `terrainSwapMap` {} which cannot be used on spawn map, set to -1", guid, data.
id, data.
terrainSwapMap);
2336 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with disallowed `unit_flags` {}, removing incorrect flag.", guid, data.
id, disallowedUnitFlags);
2345 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with disallowed `unit_flags2` {}, removing incorrect flag.", guid, data.
id, disallowedUnitFlags2);
2351 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) has UNIT_FLAG2_FEIGN_DEATH set without IMMUNE_TO_PC | IMMUNE_TO_NPC, removing incorrect flag.", guid, data.
id);
2360 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with disallowed `unit_flags3` {}, removing incorrect flag.", guid, data.
id, disallowedUnitFlags3);
2366 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) has UNIT_FLAG3_FAKE_DEAD set without IMMUNE_TO_PC | IMMUNE_TO_NPC, removing incorrect flag.", guid, data.
id);
2376 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with invalid `curHealthPct` {}, set to {}.", guid, data.
id, *data.
curHealthPct, healthPct);
2382 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with `curHealthPct` {}, but health regeneration is not disabled in `creature_template`, set to 100.", guid, data.
id, *data.
curHealthPct);
2407 while (result->NextRow());
2438template<Gr
idGu
idSet Gr
idObjectGu
ids::*gu
ids>
2454template<Gr
idGu
idSet Gr
idObjectGu
ids::*gu
ids>
2472 AddSpawnDataToGrid<&GridObjectGuids::creatures>(data);
2477 RemoveSpawnDataFromGrid<&GridObjectGuids::creatures>(data);
2485 QueryResult result =
WorldDatabase.Query(
"SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
2487 "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnDifficulties, eventEntry, poolSpawnId, "
2489 "phaseUseFlags, phaseid, phasegroup, terrainSwapMap, ScriptName, StringId "
2490 "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid "
2491 "LEFT OUTER JOIN pool_members ON pool_members.type = 1 AND gameobject.guid = pool_members.spawnId");
2495 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobjects. DB table `gameobject` is empty.");
2500 std::unordered_map<uint32, std::set<Difficulty>> spawnMasks;
2502 spawnMasks[mapDifficulty->MapID].insert(
Difficulty(mapDifficulty->DifficultyID));
2510 Field* fields = result->Fetch();
2518 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {}) with non existing gameobject entry {}, skipped.", guid, entry);
2524 switch (gInfo->
type)
2530 TC_LOG_ERROR(
"sql.sql",
"Gameobject (GUID: {} Entry {} GoType: {}) doesn't have a displayId ({}), not loaded.", guid, entry, gInfo->
type, gInfo->
displayId);
2537 TC_LOG_ERROR(
"sql.sql",
"Gameobject (GUID: {} Entry {} GoType: {}) has an invalid displayId ({}), not loaded.", guid, entry, gInfo->
type, gInfo->
displayId);
2546 data.
spawnPoint.
Relocate(fields[3].GetFloat(), fields[4].GetFloat(), fields[5].GetFloat(), fields[6].GetFloat());
2557 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) spawned on a non-existed map (Id: {}), skip", guid, data.
id, data.
mapId);
2573 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {} MapID: {}) spawned on a possible invalid position ({})",
2581 TC_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);
2592 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid `state` ({}) value, skip", guid, data.
id, go_state);
2601 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {}) that is not spawned in any difficulty, skipped.", guid);
2613 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.
id);
2619 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE,"
2620 " removing PHASE_USE_FLAGS_INVERSE.", guid, data.
id);
2626 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.
id);
2634 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) with `phaseid` {} does not exist, set to 0", guid, data.
id, data.
phaseId);
2643 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) with `phaseGroup` {} does not exist, set to 0", guid, data.
id, data.
phaseGroup);
2652 if (!terrainSwapEntry)
2654 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) with `terrainSwapMap` {} does not exist, set to -1", guid, data.
id, data.
terrainSwapMap);
2659 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) with `terrainSwapMap` {} which cannot be used on spawn map, set to -1", guid, data.
id, data.
terrainSwapMap);
2669 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationX ({}) value, skip", guid, data.
id, data.
rotation.
x);
2675 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationY ({}) value, skip", guid, data.
id, data.
rotation.
y);
2681 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationZ ({}) value, skip", guid, data.
id, data.
rotation.
z);
2687 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationW ({}) value, skip", guid, data.
id, data.
rotation.
w);
2693 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid coordinates, skip", guid, data.
id);
2699 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotation quaternion (non-unit), defaulting to orientation on Z axis only", guid, data.
id);
2722 while (result->NextRow());
2738 Field* fields = result->Fetch();
2752 flags &= ~SPAWNGROUP_FLAG_MANUAL_SPAWN;
2753 TC_LOG_ERROR(
"sql.sql",
"System spawn group {} ({}) has invalid manual spawn flag. Ignored.", groupId, group.
name);
2756 }
while (result->NextRow());
2761 TC_LOG_ERROR(
"sql.sql",
"Default spawn group (index 0) is missing from DB! Manually inserted.");
2764 data.
name =
"Default Group";
2770 TC_LOG_ERROR(
"sql.sql",
"Default legacy spawn group (index 1) is missing from DB! Manually inserted.");
2773 data.
name =
"Legacy Group";
2781 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spawn group templates. DB table `spawn_group_template` is empty.");
2795 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spawn group members. DB table `spawn_group` is empty.");
2802 Field* fields = result->Fetch();
2807 TC_LOG_ERROR(
"sql.sql",
"Spawn data with invalid type {} listed for spawn group {}. Skipped.",
uint32(spawnType), groupId);
2815 TC_LOG_ERROR(
"sql.sql",
"Spawn data with ID ({},{}) not found, but is listed as a member of spawn group {}!",
uint32(spawnType), spawnId, groupId);
2820 TC_LOG_ERROR(
"sql.sql",
"Spawn with ID ({},{}) is listed as a member of spawn group {}, but is already a member of spawn group {}. Skipping.",
uint32(spawnType), spawnId, groupId, data->
spawnGroupData->
groupId);
2826 TC_LOG_ERROR(
"sql.sql",
"Spawn group {} assigned to spawn ID ({},{}), but group is found!", groupId,
uint32(spawnType), spawnId);
2839 TC_LOG_ERROR(
"sql.sql",
"Spawn group {} has map ID {}, but spawn ({},{}) has map id {} - spawn NOT added to group!", groupId, groupTemplate.
mapId,
uint32(spawnType), spawnId, data->
mapId);
2842 const_cast<SpawnMetadata*
>(data)->spawnGroupData = &groupTemplate;
2847 }
while (result->NextRow());
2857 QueryResult result =
WorldDatabase.Query(
"SELECT instanceMapId, bossStateId, bossStates, spawnGroupId, flags FROM instance_spawn_groups");
2861 TC_LOG_INFO(
"server.loading",
">> Loaded 0 instance spawn groups. DB table `instance_spawn_groups` is empty.");
2868 Field* fields = result->Fetch();
2873 TC_LOG_ERROR(
"sql.sql",
"Invalid spawn group {} specified for instance {}. Skipped.", spawnGroupId, fields[0].GetUInt16());
2878 if (it->second.mapId != instanceMapId)
2880 TC_LOG_ERROR(
"sql.sql",
"Instance spawn group {} specified for instance {} has spawns on a different map {}. Skipped.",
2881 spawnGroupId, instanceMapId, it->second.mapId);
2891 if (states & ~ALL_STATES)
2894 TC_LOG_ERROR(
"sql.sql",
"Instance spawn group ({},{}) had invalid boss state mask {} - truncated to {}.", instanceMapId, spawnGroupId, states, info.
BossStates);
2903 TC_LOG_ERROR(
"sql.sql",
"Instance spawn group ({},{}) had invalid flags {} - truncated to {}.", instanceMapId, spawnGroupId,
flags, info.
Flags);
2911 TC_LOG_ERROR(
"sql.sql",
"Instance spawn group ({},{}) FLAG_ALLIANCE_ONLY and FLAG_HORDE_ONLY may not be used together in a single entry - truncated to {}.", instanceMapId, spawnGroupId, info.
Flags);
2915 }
while (result->NextRow());
2946 bool erased =
false;
2947 for (
auto it = pair.first; it != pair.second; ++it)
2949 if (it->second != data)
2965 for (
auto it = pair.first; it != pair.second; ++it)
2967 if (it->second != data)
2977 AddSpawnDataToGrid<&GridObjectGuids::gameobjects>(data);
2982 RemoveSpawnDataFromGrid<&GridObjectGuids::gameobjects>(data);
2992 0.92f, 0.92f, 0.92f, 1.11f, 1.32f, 1.61f, 0.0f, 0.0f
2995 static float const armorMultipliers[
MAX_INVTYPE] =
3059 float levelPenalty = 1.0f;
3060 if (itemLevel <= 28)
3061 levelPenalty = 0.966f - float(28u - itemLevel) / 54.0f;
3068 return 5 *
uint32(round(25.0f * qualityMultipliers[quality] * armorMultipliers[inventoryType] * levelPenalty));
3071 return 5 *
uint32(round(18.0f * qualityMultipliers[quality] * weaponMultipliers[itemSubClass] * levelPenalty));
3231 switch (itemStatType)
3310 if (std::vector<ItemSpecOverrideEntry const*>
const* itemSpecOverrides =
sDB2Manager.GetItemSpecOverrides(sparse->ID))
3329 if (itemSpecStats.
ItemType != itemSpec->ItemType)
3339 hasSecondary =
true;
3342 if (!hasPrimary || !hasSecondary)
3347 if ((1 << (specialization->ClassID - 1)) & sparse->AllowableClass)
3352 if (itemSpec->MaxLevel > 40)
3354 if (itemSpec->MaxLevel >= 110)
3363 if (specs.count() == 0)
3375 item->Effects.insert(itr, effect);
3388 QueryResult result =
WorldDatabase.Query(
"SELECT Id, FlagsCu, FoodType, MinMoneyLoot, MaxMoneyLoot, SpellPPMChance, RandomBonusListTemplateId, QuestLogItemId FROM item_template_addon");
3393 Field* fields = result->Fetch();
3398 TC_LOG_ERROR(
"sql.sql",
"Item {} specified in `item_template_addon` does not exist, skipped.", itemId);
3404 if (minMoneyLoot > maxMoneyLoot)
3406 TC_LOG_ERROR(
"sql.sql",
"Minimum money loot specified in `item_template_addon` for item {} was greater than maximum amount, swapping.", itemId);
3407 std::swap(minMoneyLoot, maxMoneyLoot);
3417 }
while (result->NextRow());
3432 Field* fields = result->Fetch();
3437 TC_LOG_ERROR(
"sql.sql",
"Item {} specified in `item_script_names` does not exist, skipped.", itemId);
3443 }
while (result->NextRow());
3463 QueryResult result =
WorldDatabase.Query(
"SELECT `entry`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer`, `RideSpellID` FROM `vehicle_template_accessory`");
3467 TC_LOG_INFO(
"server.loading",
">> Loaded 0 vehicle template accessories. DB table `vehicle_template_accessory` is empty.");
3473 Field* fields = result->Fetch();
3478 bool isMinion = fields[3].
GetBool();
3485 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template_accessory`: rideSpellId {} does not exist for entry {}.", *rideSpellId, entry);
3491 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template_accessory`: creature template entry {} does not exist.", entry);
3497 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template_accessory`: Accessory {} does not exist.", accessory);
3503 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template_accessory`: creature template entry {} has no data in npc_spellclick_spells", entry);
3511 while (result->NextRow());
3523 QueryResult result =
WorldDatabase.Query(
"SELECT creatureId, despawnDelayMs, Pitch, CustomFlags FROM vehicle_template");
3527 TC_LOG_INFO(
"server.loading",
">> Loaded 0 vehicle template. DB table `vehicle_template` is empty.");
3533 Field* fields = result->Fetch();
3540 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template`: Creature (Entry: {}) does not exist.", creatureId);
3546 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template`: Creature (Entry: {}) is not a vehicle.", creatureId);
3557 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template`: Creature (Entry: {}) has negative despawnDelayMs ({}).`. Ignoring",
3564 if (vehicleTemplate.
Pitch)
3568 if (*vehicleTemplate.
Pitch < vehicle->PitchMin || *vehicleTemplate.
Pitch > vehicle->PitchMax)
3570 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template`: Creature (Entry: {}) has invalid Pitch ({}).`. Ignoring",
3571 creatureId, *vehicleTemplate.
Pitch);
3572 vehicleTemplate.
Pitch.reset();
3577 }
while (result->NextRow());
3591 QueryResult result =
WorldDatabase.Query(
"SELECT `guid`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer`, `RideSpellID` FROM `vehicle_accessory`");
3595 TC_LOG_INFO(
"server.loading",
">> Loaded 0 vehicle accessories. DB table `vehicle_accessory` is empty.");
3601 Field* fields = result->Fetch();
3605 int8 uiSeat =
int8(fields[2].GetInt16());
3606 bool bMinion = fields[3].
GetBool();
3613 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_accessory`: rideSpellId {} does not exist for guid {}.", *rideSpellId, uiGUID);
3619 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_accessory`: Accessory {} does not exist.", uiAccessory);
3627 while (result->NextRow());
3641 QueryResult result =
WorldDatabase.Query(
"SELECT `SeatEntry`, `SeatOrientation`, `ExitParamX`, `ExitParamY`, `ExitParamZ`, `ExitParamO`, `ExitParamValue` FROM `vehicle_seat_addon`");
3645 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 vehicle seat addons. DB table `vehicle_seat_addon` is empty.");
3651 Field* fields = result->Fetch();
3654 float orientation = fields[1].
GetFloat();
3655 float exitX = fields[2].
GetFloat();
3656 float exitY = fields[3].
GetFloat();
3657 float exitZ = fields[4].
GetFloat();
3658 float exitO = fields[5].
GetFloat();
3663 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_seat_addon`: SeatID: {} does not exist in VehicleSeat.dbc. Skipping entry.", seatID);
3668 if (orientation >
float(
M_PI * 2))
3670 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_seat_addon`: SeatID: {} is using invalid angle offset value ({}). Set Value to 0.", seatID, orientation);
3676 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_seat_addon`: SeatID: {} is using invalid exit parameter value ({}). Setting to 0 (none).", seatID, exitParam);
3683 }
while (result->NextRow());
3693 QueryResult result =
WorldDatabase.Query(
"SELECT creature_entry, level, hp, mana, str, agi, sta, inte, spi, armor FROM pet_levelstats");
3697 TC_LOG_INFO(
"server.loading",
">> Loaded 0 level pet stats definitions. DB table `pet_levelstats` is empty.");
3705 Field* fields = result->Fetch();
3710 TC_LOG_ERROR(
"sql.sql",
"Wrong creature id {} in `pet_levelstats` table, ignoring.", creature_id);
3721 TC_LOG_INFO(
"misc",
"Unused (> MaxPlayerLevel in worldserver.conf) level {} in `pet_levelstats` table, ignoring.", current_level);
3726 else if (current_level < 1)
3728 TC_LOG_ERROR(
"sql.sql",
"Wrong (<1) level {} in `pet_levelstats` table, ignoring.", current_level);
3737 PetLevelInfo* pLevelInfo = &pInfoMapEntry[current_level - 1];
3748 while (result->NextRow());
3753 auto& pInfo = itr->second;
3756 if (!pInfo || pInfo[0].health == 0)
3758 TC_LOG_ERROR(
"sql.sql",
"Creature {} does not have pet stats data for Level 1!", itr->first);
3765 if (pInfo[level].health == 0)
3767 TC_LOG_ERROR(
"sql.sql",
"Creature {} has no data for Level {} pet stats data, using data of Level {}.", itr->first, level + 1, level);
3768 pInfo[level] = pInfo[level - 1];
3785 return &itr->second[level - 1];
3795 playerInfo->
item.emplace_back(itemId, count);
3799 TC_LOG_ERROR(
"sql.sql",
"Invalid count {} specified on item {} be removed from original player create info (use -1)!", count, itemId);
3803 auto erased = std::remove_if(items.begin(), items.end(), [itemId](
PlayerCreateInfoItem const& item) { return item.item_id == itemId; });
3804 if (erased == items.end())
3806 TC_LOG_ERROR(
"sql.sql",
"Item {} specified to be removed from original create info not found in db2!", itemId);
3810 items.erase(erased, items.end());
3820 QueryResult result =
WorldDatabase.Query(
"SELECT race, class, map, position_x, position_y, position_z, orientation, npe_map, npe_position_x, npe_position_y, npe_position_z, npe_orientation, npe_transport_guid, intro_movie_id, intro_scene_id, npe_intro_scene_id FROM playercreateinfo");
3824 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 player create definitions. DB table `playercreateinfo` is empty.");
3833 Field* fields = result->Fetch();
3838 float positionX = fields[3].
GetFloat();
3839 float positionY = fields[4].
GetFloat();
3840 float positionZ = fields[5].
GetFloat();
3841 float orientation = fields[6].
GetFloat();
3845 TC_LOG_ERROR(
"sql.sql",
"Wrong race {} in `playercreateinfo` table, ignoring.", current_race);
3851 TC_LOG_ERROR(
"sql.sql",
"Wrong class {} in `playercreateinfo` table, ignoring.", current_class);
3858 TC_LOG_ERROR(
"sql.sql",
"Wrong home position for class {} race {} pair in `playercreateinfo` table, ignoring.", current_class, current_race);
3862 if (
sMapStore.LookupEntry(mapId)->Instanceable())
3864 TC_LOG_ERROR(
"sql.sql",
"Home position in instanceable map for class {} race {} pair in `playercreateinfo` table, ignoring.", current_class, current_race);
3870 TC_LOG_ERROR(
"sql.sql",
"Missing male model for race {}, ignoring.", current_race);
3876 TC_LOG_ERROR(
"sql.sql",
"Missing female model for race {}, ignoring.", current_race);
3880 std::unique_ptr<PlayerInfo> info = std::make_unique<PlayerInfo>();
3881 info->createPosition.Loc.WorldRelocate(mapId, positionX, positionY, positionZ, orientation);
3883 if (std::none_of(fields + 7, fields + 12, [](
Field const& field) {
return field.
IsNull(); }))
3885 info->createPositionNPE.emplace();
3887 info->createPositionNPE->Loc.WorldRelocate(fields[7].GetUInt32(), fields[8].GetFloat(), fields[9].GetFloat(), fields[10].GetFloat(), fields[11].GetFloat());
3888 info->createPositionNPE->TransportGuid = fields[12].
GetUInt64OrNull();
3890 if (!
sMapStore.LookupEntry(info->createPositionNPE->Loc.GetMapId()))
3892 TC_LOG_ERROR(
"sql.sql",
"Invalid NPE map id {} for class {} race {} pair in `playercreateinfo` table, ignoring.",
3893 info->createPositionNPE->Loc.GetMapId(), current_class, current_race);
3894 info->createPositionNPE.reset();
3897 if (info->createPositionNPE && info->createPositionNPE->TransportGuid && !
sTransportMgr->GetTransportSpawn(*info->createPositionNPE->TransportGuid))
3899 TC_LOG_ERROR(
"sql.sql",
"Invalid NPE transport spawn id {} for class {} race {} pair in `playercreateinfo` table, ignoring.",
3900 *info->createPositionNPE->TransportGuid, current_class, current_race);
3901 info->createPositionNPE.reset();
3906 if (info->introMovieId && !
sMovieStore.LookupEntry(*info->introMovieId))
3908 TC_LOG_ERROR(
"sql.sql",
"Invalid intro movie id {} for class {} race {} pair in `playercreateinfo` table, ignoring.",
3909 *info->introMovieId, current_class, current_race);
3910 info->introMovieId.reset();
3916 TC_LOG_ERROR(
"sql.sql",
"Invalid intro scene id {} for class {} race {} pair in `playercreateinfo` table, ignoring.",
3917 *info->introSceneId, current_class, current_race);
3918 info->introSceneId.reset();
3924 TC_LOG_ERROR(
"sql.sql",
"Invalid NPE intro scene id {} for class {} race {} pair in `playercreateinfo` table, ignoring.",
3925 *info->introSceneIdNPE, current_class, current_race);
3926 info->introSceneIdNPE.reset();
3933 while (result->NextRow());
3940 TC_LOG_INFO(
"server.loading",
"Loading Player Create Items Data...");
3942 std::unordered_map<uint32, std::vector<ItemTemplate const*>> itemsByCharacterLoadout;
3945 itemsByCharacterLoadout[characterLoadoutItem->CharacterLoadoutID].push_back(itemTemplate);
3949 if (!characterLoadout->IsForNewCharacter())
3958 if (!characterLoadout->RaceMask.HasRace(race->ID))
3963 playerInfo->itemContext =
ItemContext(characterLoadout->ItemContext);
3968 uint32 count = itemTemplate->GetBuyCount();
3973 if (!itemTemplate->Effects.empty())
3975 switch (itemTemplate->Effects[0]->SpellCategoryID)
3985 if (itemTemplate->GetMaxStackSize() < count)
3986 count = itemTemplate->GetMaxStackSize();
3989 playerInfo->item.emplace_back(itemTemplate->GetId(), count);
3996 TC_LOG_INFO(
"server.loading",
"Loading Player Create Items Override Data...");
4004 TC_LOG_INFO(
"server.loading",
">> Loaded 0 custom player create items. DB table `playercreateinfo_item` is empty.");
4012 Field* fields = result->Fetch();
4017 TC_LOG_ERROR(
"sql.sql",
"Wrong race {} in `playercreateinfo_item` table, ignoring.", current_race);
4024 TC_LOG_ERROR(
"sql.sql",
"Wrong class {} in `playercreateinfo_item` table, ignoring.", current_class);
4032 TC_LOG_ERROR(
"sql.sql",
"Item id {} (race {} class {}) in `playercreateinfo_item` table but it does not exist, ignoring.", item_id, current_race, current_class);
4040 TC_LOG_ERROR(
"sql.sql",
"Item id {} (class {} race {}) have amount == 0 in `playercreateinfo_item` table, ignoring.", item_id, current_race, current_class);
4044 if (!current_race || !current_class)
4046 uint32 min_race = current_race ? current_race : 1;
4048 uint32 min_class = current_class ? current_class : 1;
4050 for (
uint32 r = min_race; r < max_race; ++r)
4051 for (
uint32 c = min_class; c < max_class; ++c)
4059 while (result->NextRow());
4066 TC_LOG_INFO(
"server.loading",
"Loading Player Create Skill Data...");
4071 if (rcInfo->Availability == 1)
4073 if (rcInfo->RaceMask.IsEmpty() || rcInfo->RaceMask.HasRace(race->ID))
4075 if (rcInfo->ClassMask == -1 || rcInfo->ClassMask == 0 || ((1 << (classIndex - 1)) & rcInfo->ClassMask))
4077 playerInfo->skills.push_back(rcInfo);
4083 TC_LOG_INFO(
"server.loading",
"Loading Player Create Custom Spell Data...");
4091 TC_LOG_INFO(
"server.loading",
">> Loaded 0 player create custom spells. DB table `playercreateinfo_spell_custom` is empty.");
4099 Field* fields = result->Fetch();
4106 TC_LOG_ERROR(
"sql.sql",
"Wrong race mask {} in `playercreateinfo_spell_custom` table, ignoring.", raceMask.
RawValue[0]);
4112 TC_LOG_ERROR(
"sql.sql",
"Wrong class mask {} in `playercreateinfo_spell_custom` table, ignoring.", classMask);
4122 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
4126 playerInfo->customSpells.push_back(spellId);
4138 while (result->NextRow());
4145 TC_LOG_INFO(
"server.loading",
"Loading Player Create Cast Spell Data...");
4149 QueryResult result =
WorldDatabase.PQuery(
"SELECT raceMask, classMask, spell, createMode FROM playercreateinfo_cast_spell");
4152 TC_LOG_INFO(
"server.loading",
">> Loaded 0 player create cast spells. DB table `playercreateinfo_cast_spell` is empty.");
4159 Field* fields = result->Fetch();
4167 TC_LOG_ERROR(
"sql.sql",
"Wrong race mask {} in `playercreateinfo_cast_spell` table, ignoring.", raceMask.
RawValue[0]);
4173 TC_LOG_ERROR(
"sql.sql",
"Wrong class mask {} in `playercreateinfo_cast_spell` table, ignoring.", classMask);
4179 TC_LOG_ERROR(
"sql.sql",
"Uses invalid createMode {} in `playercreateinfo_cast_spell` table, ignoring.", playerCreateMode);
4189 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
4193 playerInfo->castSpells[playerCreateMode].push_back(spellId);
4200 }
while (result->NextRow());
4207 TC_LOG_INFO(
"server.loading",
"Loading Player Create Action Data...");
4216 TC_LOG_INFO(
"server.loading",
">> Loaded 0 player create actions. DB table `playercreateinfo_action` is empty.");
4224 Field* fields = result->Fetch();
4229 TC_LOG_ERROR(
"sql.sql",
"Wrong race {} in `playercreateinfo_action` table, ignoring.", current_race);
4236 TC_LOG_ERROR(
"sql.sql",
"Wrong class {} in `playercreateinfo_action` table, ignoring.", current_class);
4245 while (result->NextRow());
4252 TC_LOG_INFO(
"server.loading",
"Loading Player Create Level Stats Data...");
4257 std::array<int16, MAX_STATS> StatModifier = { };
4259 explicit RaceStats(
Races race) :
Race(race) { }
4260 std::strong_ordering
operator<=>(RaceStats
const& right)
const {
return Race <=> right.Race; }
4261 bool operator==(RaceStats
const& right)
const {
return Race == right.Race; }
4270 if (!raceStatsResult)
4272 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 race stats definitions. DB table `player_racestats` is empty.");
4278 Field* fields = raceStatsResult->Fetch();
4283 TC_LOG_ERROR(
"sql.sql",
"Wrong race {} in `player_racestats` table, ignoring.", current_race);
4287 RaceStats& stats = *raceStatModifiers.
emplace(
Races(current_race)).first;
4289 stats.StatModifier[i] = fields[i + 1].
GetInt16();
4291 }
while (raceStatsResult->NextRow());
4294 QueryResult result =
WorldDatabase.Query(
"SELECT class, level, str, agi, sta, inte, spi FROM player_classlevelstats");
4298 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 level stats definitions. DB table `player_classlevelstats` is empty.");
4306 Field* fields = result->Fetch();
4311 TC_LOG_ERROR(
"sql.sql",
"Wrong class {} in `player_classlevelstats` table, ignoring.", current_class);
4321 TC_LOG_INFO(
"misc",
"Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_classlevelstats` table, ignoring.", current_level);
4326 for (RaceStats
const& raceStats : raceStatModifiers)
4330 if (!playerInfo->levelInfo)
4333 PlayerLevelInfo& levelInfo = playerInfo->levelInfo[current_level - 1];
4335 levelInfo.
stats[i] = fields[i + 2].
GetInt32() + raceStats.StatModifier[i];
4341 while (result->NextRow());
4344 for (
auto const& [raceClass, playerInfo] :
_playerInfo)
4346 auto [race, class_] = raceClass;
4349 if (!playerInfo->levelInfo || playerInfo->levelInfo[0].stats[0] == 0)
4351 TC_LOG_ERROR(
"sql.sql",
"Race {} Class {} Level 1 does not have stats data!", race, class_);
4358 if (playerInfo->levelInfo[level].stats[0] == 0)
4360 TC_LOG_ERROR(
"sql.sql",
"Race {} Class {} Level {} does not have stats data. Using stats data of level {}.", race, class_, level + 1, level);
4361 playerInfo->levelInfo[level] = playerInfo->levelInfo[level - 1];
4370 TC_LOG_INFO(
"server.loading",
"Loading Player Create XP Data...");
4390 Field* fields = result->Fetch();
4401 TC_LOG_INFO(
"misc",
"Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_xp_for_level` table, ignoring.", current_level);
4409 }
while (result->NextRow());
4417 TC_LOG_ERROR(
"sql.sql",
"Level {} does not have XP for level data. Using data of level [{}] + 12000.", level + 1, level);
4437 TC_LOG_ERROR(
"misc",
"Tried to get non-existant Class-Level combination data for base hp/mp. Class {} Level {}", class_, level);
4555 "ID, QuestType, QuestPackageID, ContentTuningID, QuestSortID, QuestInfoID, SuggestedGroupNum, RewardNextQuest, RewardXPDifficulty, RewardXPMultiplier, "
4556 "RewardMoneyDifficulty, RewardMoneyMultiplier, RewardBonusMoney, RewardSpell, RewardHonor, RewardKillHonor, RewardFavor, StartItem, "
4557 "RewardArtifactXPDifficulty, RewardArtifactXPMultiplier, RewardArtifactCategoryID, Flags, FlagsEx, FlagsEx2, FlagsEx3, "
4558 "RewardItem1, RewardAmount1, ItemDrop1, ItemDropQuantity1, RewardItem2, RewardAmount2, ItemDrop2, ItemDropQuantity2, "
4559 "RewardItem3, RewardAmount3, ItemDrop3, ItemDropQuantity3, RewardItem4, RewardAmount4, ItemDrop4, ItemDropQuantity4, "
4560 "RewardChoiceItemID1, RewardChoiceItemQuantity1, RewardChoiceItemDisplayID1, RewardChoiceItemID2, RewardChoiceItemQuantity2, RewardChoiceItemDisplayID2, "
4561 "RewardChoiceItemID3, RewardChoiceItemQuantity3, RewardChoiceItemDisplayID3, RewardChoiceItemID4, RewardChoiceItemQuantity4, RewardChoiceItemDisplayID4, "
4562 "RewardChoiceItemID5, RewardChoiceItemQuantity5, RewardChoiceItemDisplayID5, RewardChoiceItemID6, RewardChoiceItemQuantity6, RewardChoiceItemDisplayID6, "
4563 "POIContinent, POIx, POIy, POIPriority, RewardTitle, RewardArenaPoints, RewardSkillLineID, RewardNumSkillUps, "
4564 "PortraitGiver, PortraitGiverMount, PortraitGiverModelSceneID, PortraitTurnIn, "
4565 "RewardFactionID1, RewardFactionValue1, RewardFactionOverride1, RewardFactionCapIn1, RewardFactionID2, RewardFactionValue2, RewardFactionOverride2, RewardFactionCapIn2, "
4566 "RewardFactionID3, RewardFactionValue3, RewardFactionOverride3, RewardFactionCapIn3, RewardFactionID4, RewardFactionValue4, RewardFactionOverride4, RewardFactionCapIn4, "
4567 "RewardFactionID5, RewardFactionValue5, RewardFactionOverride5, RewardFactionCapIn5, RewardFactionFlags, "
4568 "RewardCurrencyID1, RewardCurrencyQty1, RewardCurrencyID2, RewardCurrencyQty2, RewardCurrencyID3, RewardCurrencyQty3, RewardCurrencyID4, RewardCurrencyQty4, "
4569 "AcceptedSoundKitID, CompleteSoundKitID, AreaGroupID, TimeAllowed, AllowableRaces, ResetByScheduler, Expansion, ManagedWorldStateID, QuestSessionBonus, "
4570 "LogTitle, LogDescription, QuestDescription, AreaDescription, PortraitGiverText, PortraitGiverName, PortraitTurnInText, PortraitTurnInName, QuestCompletionLog "
4571 "FROM quest_template");
4574 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quests definitions. DB table `quest_template` is empty.");
4585 Field* fields = result->Fetch();
4588 auto itr =
_questTemplates.emplace(std::piecewise_construct, std::forward_as_tuple(questId), std::forward_as_tuple(
new Quest(result))).first;
4589 itr->second->_weakRef = itr->second;
4590 if (itr->second->IsAutoPush())
4592 }
while (result->NextRow());
4594 struct QuestLoaderHelper
4596 typedef void(
Quest::* QuestLoaderFunction)(
Field* fields);
4598 char const* QueryFields;
4599 char const* TableName;
4600 char const* QueryExtra;
4601 char const* TableDesc;
4602 QuestLoaderFunction LoaderFunction;
4606 QuestLoaderHelper
const QuestLoaderHelpers[] =
4609 {
"QuestID, Type1, Type2, Type3, Type4, Type5, Type6",
"quest_reward_choice_items",
"",
"reward choice items", &
Quest::LoadRewardChoiceItems },
4612 {
"QuestID, SpellID, PlayerConditionID, Type",
"quest_reward_display_spell",
"ORDER BY QuestID ASC, Idx ASC",
"reward display spells", &
Quest::LoadRewardDisplaySpell },
4615 {
"ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4",
"quest_details",
"",
"details", &
Quest::LoadQuestDetails },
4618 {
"ID, EmoteOnComplete, EmoteOnIncomplete, EmoteOnCompleteDelay, EmoteOnIncompleteDelay, CompletionText",
"quest_request_items",
"",
"request items", &
Quest::LoadQuestRequestItems },
4621 {
"ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4, RewardText",
"quest_offer_reward",
"",
"reward emotes", &
Quest::LoadQuestOfferReward },
4624 {
"ID, MaxLevel, AllowableClasses, SourceSpellID, PrevQuestID, NextQuestID, ExclusiveGroup, BreadcrumbForQuestId, RewardMailTemplateID, RewardMailDelay,"
4626 " RequiredSkillID, RequiredSkillPoints, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, ProvidedItemCount, SpecialFlags,"
4634 {
"qo.QuestID, qo.ID, qo.Type, qo.StorageIndex, qo.ObjectID, qo.Amount, qo.ConditionalAmount, qo.Flags, qo.Flags2, qo.ProgressBarWeight, qo.ParentObjectiveID, qo.Visible, qo.Description, "
4636 "qoce.GameEventID, qoce.SpellID, qoce.ConversationID, qoce.UpdatePhaseShift, qoce.UpdateZoneAuras",
"quest_objectives qo",
"LEFT JOIN quest_objectives_completion_effect qoce ON qo.ID = qoce.ObjectiveID ORDER BY `Order` ASC, StorageIndex ASC",
"quest objectives", &
Quest::LoadQuestObjective },
4651 {
"QuestID, TreasurePickerID",
"quest_treasure_pickers",
"ORDER BY OrderIndex",
"treasure pickers", &
Quest::LoadTreasurePickers },
4654 {
"QuestID, HouseRoomID",
"quest_reward_house_room",
"ORDER BY OrderIndex",
"house room rewards", &
Quest::LoadRewardHouseRoom },
4657 {
"QuestID, HouseDecorID",
"quest_reward_house_decor",
"ORDER BY OrderIndex",
"house decor rewards", &
Quest::LoadRewardHouseDecor }
4660 for (QuestLoaderHelper
const& loader : QuestLoaderHelpers)
4662 result =
WorldDatabase.PQuery(
"SELECT {} FROM {} {}", loader.QueryFields, loader.TableName, loader.QueryExtra);
4665 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quest {}. DB table `{}` is empty.", loader.TableDesc, loader.TableName);
4670 Field* fields = result->Fetch();
4675 (itr->second.get()->*loader.LoaderFunction)(fields);
4677 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has data for quest {} but such quest does not exist", loader.TableName, questId);
4678 }
while (result->NextRow());
4684 result =
WorldDatabase.Query(
"SELECT v.ID AS vID, o.ID AS oID, o.QuestID, v.Index, v.VisualEffect FROM quest_visual_effect AS v LEFT JOIN quest_objectives AS o ON v.ID = o.ID ORDER BY v.Index DESC");
4687 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quest visual effects. DB table `quest_visual_effect` is empty.");
4692 Field* fields = result->Fetch();
4698 TC_LOG_ERROR(
"sql.sql",
"Table `quest_visual_effect` has visual effect for null objective id");
4705 TC_LOG_ERROR(
"sql.sql",
"Table `quest_visual_effect` has visual effect for objective {} but such objective does not exist.", vID);
4714 itr->second->LoadQuestObjectiveVisualEffect(fields);
4715 }
while (result->NextRow());
4718 std::map<uint32, uint32> usedMailTemplates;
4727 Quest* qinfo = questPair.second.get();
4736 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SpecialFlags` = {} > max allowed value. Correct `SpecialFlags` to value <= {}",
4743 TC_LOG_ERROR(
"sql.sql",
"Weekly Quest {} is marked as daily quest in `Flags`, removed daily flag.", qinfo->
GetQuestId());
4744 qinfo->
_flags &= ~QUEST_FLAGS_DAILY;
4751 TC_LOG_DEBUG(
"sql.sql",
"Daily Quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->
GetQuestId());
4760 TC_LOG_DEBUG(
"sql.sql",
"Weekly Quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->
GetQuestId());
4769 TC_LOG_DEBUG(
"sql.sql",
"Monthly quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->
GetQuestId());
4781 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemId{}` = {} but item from `RewardChoiceItemId{}` can't be rewarded with quest flag QUEST_FLAGS_TRACKING.",
4790 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `ContentTuningID` = {} but content tuning with this id does not exist.",
4799 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `QuestSortID` = {} (zone case) but zone with this id does not exist.",
4810 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `QuestSortID` = {} (sort case) but quest sort with this id does not exist.",
4819 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `QuestSortID` = {} but `RequiredSkillId` does not have a corresponding value ({}).",
4840 TC_LOG_ERROR(
"sql.sql",
"Quest {} does not contain any playable races in `AllowableRaces` (0x{:X}{:08X}), value set to -1 (all races).",
4850 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredSkillId` = {} but this skill does not exist",
4859 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredSkillPoints` = {} but max possible skill is {}, quest can't be done.",
4868 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMinRepFaction` = {} but faction template {} does not exist, quest can't be done.",
4875 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMaxRepFaction` = {} but faction template {} does not exist, quest can't be done.",
4882 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMinRepValue` = {} but max reputation is {}, quest can't be done.",
4889 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMaxRepValue` = {} and `RequiredMinRepValue` = {}, quest can't be done.",
4896 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMinRepValue` = {} but `RequiredMinRepFaction` is 0, value has no effect",
4903 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMaxRepValue` = {} but `RequiredMaxRepFaction` is 0, value has no effect",
4910 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardTitleId` = {} but CharTitle Id {} does not exist, quest can't be rewarded with title.",
4920 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SourceItemId` = {} but item with entry {} does not exist, quest can't be done.",
4926 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `StartItem` = {} but `ProvidedItemCount` = 0, set to 1 but need fix in DB.",
4933 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SourceItemId` = 0 but `SourceItemIdCount` = {}, useless value.",
4943 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SourceSpellid` = {} but spell {} doesn't exist, quest can't be done.",
4949 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SourceSpellid` = {} but spell {} is broken, quest can't be done.",
4961 if (obj.IsStoringValue() && obj.StorageIndex < 0)
4962 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has invalid StorageIndex = {} for objective type {}", qinfo->
GetQuestId(), obj.ID, obj.StorageIndex, obj.Type);
4968 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing item entry {}, quest can't be done.",
4973 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing creature entry {}, quest can't be done.",
4978 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing gameobject entry {}, quest can't be done.",
4983 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing creature entry {}, quest can't be done.",
4990 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing faction id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
4993 if (obj.Amount <= 0)
4994 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has invalid player kills count {}", qinfo->
GetQuestId(), obj.ID, obj.Amount);
5000 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing currency {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
5001 if (obj.Amount <= 0)
5002 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has invalid currency amount {}", qinfo->
GetQuestId(), obj.ID, obj.Amount);
5006 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing spell id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
5010 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing creature entry {}, quest can't be done.",
5015 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing battlepet species id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
5019 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing criteria tree id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
5023 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing AreaTrigger.db2 id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
5028 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing areatrigger id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
5036 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has unhandled type {}", qinfo->
GetQuestId(), obj.ID, obj.Type);
5051 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `ItemDrop{}` = {} but item with entry {} does not exist, quest can't be done.",
5060 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `ItemDrop{}` = 0 but `ItemDropQuantity{}` = {}.",
5076 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemId{}` = {} but item with entry {} does not exist, quest will not reward this item.",
5084 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemId{}` = {} but currency with id {} does not exist, quest will not reward this currency.",
5090 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemType{}` = {} but it is not a valid item type, reward removed.",
5098 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemId{}` = {} but `RewardChoiceItemCount{}` = 0.",
5104 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemId{}` = 0 but `RewardChoiceItemCount{}` = {}.",
5117 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardItemId{}` = {} but item with entry {} does not exist, quest will not reward this item.",
5124 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardItemId{}` = {} but `RewardItemCount{}` = 0, quest will not reward this item.",
5131 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardItemId{}` = 0 but `RewardItemCount{}` = {}.",
5154 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardFactionId{}` = 0 but `RewardFactionValueIdOverride{}` = {}.",
5166 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSpellCast` = {} but spell {} does not exist, quest will not have a spell reward.",
5173 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSpellCast` = {} but spell {} is broken, quest will not have a spell reward.",
5183 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardMailTemplateId` = {} but mail template {} does not exist, quest will not have a mail reward.",
5192 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardMailTemplateId` = {} but mail template {} already used for quest {}, quest will not have a mail reward.",
5206 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardNextQuest` = {} but quest {} does not exist, quest chain will not work.",
5218 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardCurrencyId{}` = {} but `RewardCurrencyCount{}` = 0, quest can't be done.",
5225 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardCurrencyId{}` = {} but currency with entry {} does not exist, quest can't be done.",
5232 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardCurrencyId{}` = 0 but `RewardCurrencyCount{}` = {}, quest can't be done.",
5242 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SoundAccept` = {} but sound {} does not exist, set to 0.",
5252 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SoundTurnIn` = {} but sound {} does not exist, set to 0.",
5262 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSkillId` = {} but this skill does not exist",
5267 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSkillId` = {} but `RewardSkillPoints` is 0",
5276 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSkillPoints` = {} but max possible skill is {}, quest can't be done.",
5282 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSkillPoints` = {} but `RewardSkillId` is 0",
5293 else if (prevQuestItr->second->_breadcrumbForQuestId)
5294 TC_LOG_ERROR(
"sql.sql",
"Quest {} should not be unlocked by breadcrumb quest {}", qinfo->
_id, prevQuestId);
5305 nextQuestItr->second->DependentPreviousQuests.push_back(qinfo->
GetQuestId());
5312 TC_LOG_ERROR(
"sql.sql",
"Quest {} is a breadcrumb for quest {}, but no such quest exists", qinfo->
_id, breadcrumbForQuestId);
5330 Quest* qinfo = questPair.second.get();
5333 std::set<uint32> questSet;
5335 while(breadcrumbForQuestId)
5339 if (!questSet.insert(qinfo->
_id).second)
5341 TC_LOG_ERROR(
"sql.sql",
"Breadcrumb quests {} and {} are in a loop", qid, breadcrumbForQuestId);
5367 TC_LOG_INFO(
"server.loading",
"Loading GO Start Quest Data...");
5369 TC_LOG_INFO(
"server.loading",
"Loading GO End Quest Data...");
5371 TC_LOG_INFO(
"server.loading",
"Loading Creature Start Quest Data...");
5373 TC_LOG_INFO(
"server.loading",
"Loading Creature End Quest Data...");
5385 "LogTitle, LogDescription, QuestDescription, AreaDescription, PortraitGiverText, PortraitGiverName, PortraitTurnInText, PortraitTurnInName, QuestCompletionLog"
5386 " FROM quest_template_locale");
5392 Field* fields = result->Fetch();
5411 }
while (result->NextRow());
5428 Field* fields = result->Fetch();
5440 while (result->NextRow());
5460 Field* fields = result->Fetch();
5469 TC_LOG_ERROR(
"sql.sql",
"Table `quest_greeting_locale`: creature template entry {} does not exist.",
id);
5476 TC_LOG_ERROR(
"sql.sql",
"Table `quest_greeting_locale`: gameobject template entry {} does not exist.",
id);
5494 while (result->NextRow());
5511 Field* fields = result->Fetch();
5522 }
while (result->NextRow());
5539 Field* fields = result->Fetch();
5550 }
while (result->NextRow());
5564 if (tableName.empty())
5567 if (
sMapMgr->IsScriptScheduled())
5570 TC_LOG_INFO(
"server.loading",
"Loading {}...", tableName);
5575 QueryResult result =
WorldDatabase.PQuery(
"SELECT id, delay, command, datalong, datalong2, dataint, x, y, z, o FROM {}", tableName);
5579 TC_LOG_INFO(
"server.loading",
">> Loaded 0 script definitions. DB table `{}` is empty!", tableName);
5587 Field* fields = result->Fetch();
5608 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid talk type (datalong = {}) in SCRIPT_COMMAND_TALK for script id {}",
5614 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid talk text id (dataint = {}) in SCRIPT_COMMAND_TALK for script id {}",
5626 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid emote id (datalong = {}) in SCRIPT_COMMAND_EMOTE for script id {}",
5637 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid map (Id: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
5644 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
5656 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid quest (ID: {}) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id {}",
5663 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has quest (ID: {}) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id {}, but quest not have QUEST_FLAGS_COMPLETION_EVENT or QUEST_FLAGS_COMPLETION_AREA_TRIGGER in quest flags. Script command will do nothing.",
5670 TC_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 {}",
5677 TC_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",
5684 TC_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",
5696 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_KILL_CREDIT for script id {}",
5708 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid gameobject (GUID: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5716 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5727 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has gameobject type ({}) unsupported by command SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5728 tableName, info->
entry, tmp.
id);
5738 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
5745 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
5758 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid gameobject (GUID: {}) in {} for script id {}",
5766 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in {} for script id {}",
5773 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has gameobject type ({}) unsupported by command {} for script id {}",
5785 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
5791 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using unknown flags in datalong2 ({}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
5802 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5808 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using unknown target in datalong2 ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5814 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using unknown flags in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5820 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using invalid creature entry in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5831 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has nonexistent item (entry: {}) in SCRIPT_COMMAND_CREATE_ITEM for script id {}",
5837 TC_LOG_ERROR(
"sql.sql",
"Table `{}` SCRIPT_COMMAND_CREATE_ITEM but amount is {} for script id {}",
5847 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid AnimKid id (datalong = {}) in SCRIPT_COMMAND_PLAY_ANIMKIT for script id {}",
5864 if (scripts->find(tmp.
id) == scripts->end())
5867 (*scripts)[tmp.
id] = emptyMap;
5869 (*scripts)[tmp.
id].insert(std::pair<uint32, ScriptInfo>(tmp.
delay, tmp));
5873 while (result->NextRow());
5885 EventContainer eventSet = gameObjectTemplatePair.second.GetEventScriptSet();
5886 _eventStore.insert(eventSet.begin(), eventSet.end());
5892 _eventStore.insert(spellEffect->EffectMiscValue[0]);
5897 if (node->ArrivalEventID)
5900 if (node->DepartureEventID)
5911 if (criteria->Asset.EventID)
5938 TC_LOG_ERROR(
"sql.sql",
"Table `event_scripts` has script (Id: {}) not referring to any gameobject_template (data field referencing GameEvent), any taxi path node, any criteria asset or any spell effect {}",
5949 TC_LOG_INFO(
"server.loading",
">> Loaded 0 event scripts. DB table `event_script_names` is empty.");
5955 Field* fields = result->Fetch();
5962 TC_LOG_ERROR(
"sql.sql",
"Event (ID: {}) not referring to any gameobject_template (data field referencing GameEvent), any taxi path node, any criteria asset or any spell effect {}",
5967 }
while (result->NextRow());
5982 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spell script names. DB table `spell_script_names` is empty!");
5991 Field* fields = result->Fetch();
5996 bool allRanks =
false;
6006 TC_LOG_ERROR(
"sql.sql",
"Scriptname: `{}` spell (Id: {}) does not exist.", scriptName, fields[0].GetInt32());
6013 TC_LOG_ERROR(
"sql.sql",
"Scriptname: `{}` spell (Id: {}) has no ranks of spell.", scriptName, fields[0].GetInt32());
6017 TC_LOG_ERROR(
"sql.sql",
"Scriptname: `{}` spell (Id: {}) is not first rank of spell.", scriptName, fields[0].GetInt32());
6030 TC_LOG_ERROR(
"sql.sql",
"Scriptname: `{}` spell (Id: {}) is ranked spell. Perhaps not all ranks are assigned to this script.", scriptName, spellId);
6037 while (result->NextRow());
6048 TC_LOG_INFO(
"server.loading",
">> Validated 0 scripts.");
6062 std::unique_ptr<SpellScript> spellScript(spellScriptLoader->GetSpellScript());
6063 std::unique_ptr<AuraScript> auraScript(spellScriptLoader->GetAuraScript());
6065 if (!spellScript && !auraScript)
6067 TC_LOG_ERROR(
"scripts",
"Functions GetSpellScript() and GetAuraScript() of script `{}` do not return objects - script skipped",
GetScriptName(spell.second.first));
6069 spell.second.second =
false;
6075 spellScript->_Init(spellScriptLoader->GetName(), spellEntry->
Id);
6076 spellScript->_Register();
6078 if (!spellScript->_Validate(spellEntry))
6080 spell.second.second =
false;
6087 auraScript->_Init(spellScriptLoader->GetName(), spellEntry->
Id);
6088 auraScript->_Register();
6090 if (!auraScript->_Validate(spellEntry))
6092 spell.second.second =
false;
6098 spell.second.second =
true;
6101 spell.second.second =
false;
6112 QueryResult result =
WorldDatabase.Query(
"SELECT ID, `Text`, NextPageID, PlayerConditionID, Flags FROM page_text");
6115 TC_LOG_INFO(
"server.loading",
">> Loaded 0 page texts. DB table `page_text` is empty!");
6122 Field* fields = result->Fetch();
6134 while (result->NextRow());
6137 if (itr->second.NextPageID)
6139 TC_LOG_ERROR(
"sql.sql",
"Page text (ID: {}) has non-existing `NextPageID` ({})", itr->first, itr->second.NextPageID);
6146 PageTextContainer::const_iterator itr =
_pageTextStore.find(pageEntry);
6148 return &(itr->second);
6166 Field* fields = result->Fetch();
6177 }
while (result->NextRow());
6191 TC_LOG_INFO(
"server.loading",
">> Loaded 0 instance templates. DB table `page_text` is empty!");
6198 Field* fields = result->Fetch();
6204 TC_LOG_ERROR(
"sql.sql",
"ObjectMgr::LoadInstanceTemplate: bad mapid {} for template!", mapID);
6210 instanceTemplate.
Parent =
uint32(fields[1].GetUInt16());
6217 while (result->NextRow());
6226 return &(itr->second);
6233 NpcTextContainer::const_iterator itr =
_npcTextStore.find(Text_ID);
6235 return &itr->second;
6244 "Probability0, Probability1, Probability2, Probability3, Probability4, Probability5, Probability6, Probability7, "
6245 "BroadcastTextID0, BroadcastTextID1, BroadcastTextID2, BroadcastTextID3, BroadcastTextID4, BroadcastTextID5, BroadcastTextID6, BroadcastTextID7"
6249 TC_LOG_INFO(
"server.loading",
">> Loaded 0 npc texts, table is empty!");
6257 Field* fields = result->Fetch();
6262 TC_LOG_ERROR(
"sql.sql",
"Table `npc_text` has record with reserved id 0, ignore.");
6291 TC_LOG_ERROR(
"sql.sql",
"NPCText (ID: {}) has a probability (Index: {}) set, but no BroadcastTextID to go with it", textID, i);
6296 float probabilitySum = std::accumulate(std::begin(npcText.
Data), std::end(npcText.
Data), 0.0f, [](
float sum,
NpcTextData const& data) { return sum + data.Probability; });
6297 if (probabilitySum <= 0.0f)
6299 TC_LOG_ERROR(
"sql.sql",
"NPCText (ID: {}) has a probability sum 0, no text can be selected from it, skipped.", textID);
6305 while (result->NextRow());
6317 localtime_r(&curTime, <);
6318 TC_LOG_INFO(
"misc",
"Returning mails current time: hour: {}, minute: {}, second: {} ", lt.tm_hour, lt.tm_min, lt.tm_sec);
6332 TC_LOG_INFO(
"server.loading",
">> No expired mails found.");
6344 Field* fields = items->Fetch();
6348 itemsCache[mailId].push_back(item);
6349 }
while (items->NextRow());
6353 uint32 returnedCount = 0;
6356 Field* fields = result->Fetch();
6366 bool has_items = fields[4].
GetBool();
6384 for (MailItemInfoVec::iterator itr2 = m->
items.begin(); itr2 != m->
items.end(); ++itr2)
6406 for (MailItemInfoVec::iterator itr2 = m->
items.begin(); itr2 != m->
items.end(); ++itr2)
6431 while (result->NextRow());
6433 TC_LOG_INFO(
"server.loading",
">> Processed {} expired mails: {} deleted and {} returned in {} ms", deletedCount + returnedCount, deletedCount, returnedCount,
GetMSTimeDiffToNow(oldMSTime));
6446 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quest trigger points. DB table `areatrigger_involvedrelation` is empty.");
6456 Field* fields = result->Fetch();
6464 TC_LOG_ERROR(
"sql.sql",
"Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", trigger_ID);
6472 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger_involvedrelation` has record (id: {}) for not existing quest {}", trigger_ID, quest_ID);
6478 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger_involvedrelation` has record (id: {}) for not quest {}, but quest not have flag QUEST_FLAGS_COMPLETION_AREA_TRIGGER and no objective with type QUEST_OBJECTIVE_AREATRIGGER. Trigger is obsolete, skipped.", trigger_ID, quest_ID);
6484 }
while (result->NextRow());
6530 QueryResult result =
WorldDatabase.Query(
"SELECT ID, type, GreetEmoteType, GreetEmoteDelay, Greeting FROM quest_greeting");
6533 TC_LOG_INFO(
"server.loading",
">> Loaded 0 npc texts, table is empty!");
6540 Field* fields = result->Fetch();
6549 TC_LOG_ERROR(
"sql.sql",
"Table `quest_greeting`: creature template entry {} does not exist.",
id);
6556 TC_LOG_ERROR(
"sql.sql",
"Table `quest_greeting`: gameobject template entry {} does not exist.",
id);
6566 std::string greeting = fields[4].
GetString();
6568 _questGreetingStore[type].emplace(std::piecewise_construct, std::forward_as_tuple(
id), std::forward_as_tuple(greetEmoteType, greetEmoteDelay, std::move(greeting)));
6571 while (result->NextRow());
6586 TC_LOG_INFO(
"server.loading",
">> Loaded 0 tavern triggers. DB table `areatrigger_tavern` is empty.");
6596 Field* fields = result->Fetch();
6603 TC_LOG_ERROR(
"sql.sql",
"Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
6608 }
while (result->NextRow());
6622 TC_LOG_INFO(
"server.loading",
">> Loaded 0 areatrigger scripts. DB table `areatrigger_scripts` is empty.");
6628 Field* fields = result->Fetch();
6636 TC_LOG_ERROR(
"sql.sql",
"AreaTrigger (ID: {}) does not exist in `AreaTrigger.dbc`.", triggerId);
6641 while (result->NextRow());
6675 float dist2 = (node->Pos.X - x)*(node->Pos.X - x) + (node->Pos.Y - y)*(node->Pos.Y - y) + (node->Pos.Z - z)*(node->Pos.Z - z);
6700 path = taxiPath->
ID;
6701 cost = taxiPath->
Cost;
6727 if (mount_entry == 0 && allowed_alt_team)
6739 TC_LOG_ERROR(
"sql.sql",
"No displayid found for the taxi mount with the entry {}! Can't load it!", mount_entry);
6742 mountModel = *model;
6774 TC_LOG_INFO(
"server.loading",
">> Loaded 0 graveyard-zone links. DB table `graveyard_zone` is empty.");
6784 Field* fields = result->Fetch();
6792 TC_LOG_ERROR(
"sql.sql",
"Table `graveyard_zone` has a record for non-existing graveyard (WorldSafeLocsID: {}), skipped.", safeLocId);
6799 TC_LOG_ERROR(
"sql.sql",
"Table `graveyard_zone` has a record for non-existing Zone (ID: {}), skipped.", zoneId);
6804 TC_LOG_ERROR(
"sql.sql",
"Table `graveyard_zone` has a duplicate record for Graveyard (ID: {}) and Zone (ID: {}), skipped.", safeLocId, zoneId);
6805 }
while (result->NextRow());
6812 enum DefaultGraveyard
6814 HORDE_GRAVEYARD = 10,
6815 ALLIANCE_GRAVEYARD = 4
6822 else return nullptr;
6838 TC_LOG_ERROR(
"misc",
"ZoneId not found for map {} coords ({}, {}, {}), object name: {} {}", MapId, x, y, z,
6848 while (!graveyard && parentEntry)
6854 parentEntry =
nullptr;
6857 if (!graveyard && !
sMapStore.LookupEntry(MapId)->IsBattlegroundOrArena())
6860 TC_LOG_ERROR(
"sql.sql",
"Table `graveyard_zone` incomplete: Zone {} Team {} does not have a linked graveyard.", zoneId, team);
6895 for (; range.first != range.second; ++range.first)
6901 if (conditionObject)
6911 bool teamConditionMet =
true;
6914 for (
Condition const& cond : *conditions)
6919 if (cond.ConditionValue1 == team)
6922 teamConditionMet =
false;
6926 if (!teamConditionMet)
6946 if (!distEntr || dist2 < *distEntr)
6956 if (!distNear || dist2 < *distNear)
6976 for (; range.first != range.second; ++range.first)
6990 if (
QueryResult result =
WorldDatabase.Query(
"SELECT ID, MapID, LocX, LocY, LocZ, Facing, TransportSpawnId FROM world_safe_locs"))
6994 Field* fields = result->Fetch();
6996 WorldLocation loc(fields[1].GetUInt32(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat(),
DegToRad(fields[5].GetFloat()));
6999 TC_LOG_ERROR(
"sql.sql",
"World location (ID: {}) has a invalid position {}, skipped",
id, loc);
7004 if (transportSpawnId && !
sTransportMgr->GetTransportSpawn(*transportSpawnId))
7006 TC_LOG_ERROR(
"sql.sql",
"World location (ID: {}) has a invalid transportSpawnID {}, skipped.",
id, *transportSpawnId);
7011 worldSafeLocs.
ID = id;
7015 }
while (result->NextRow());
7020 TC_LOG_INFO(
"server.loading",
">> Loaded 0 world locations. DB table `world_safe_locs` is empty.");
7052 GraveyardStore.insert(GraveyardContainer::value_type(zoneId, data));
7105 TC_LOG_INFO(
"server.loading",
">> Loaded 0 area trigger teleport definitions. DB table `areatrigger_teleport` is empty.");
7113 Field* fields = result->Fetch();
7123 TC_LOG_ERROR(
"sql.sql",
"Area Trigger (ID: {}) does not exist in AreaTrigger.dbc.", Trigger_ID);
7130 TC_LOG_ERROR(
"sql.sql",
"Area Trigger (ID: {}) has a non-existing Port Loc (ID: {}) in WorldSafeLocs.dbc, skipped", Trigger_ID, PortLocID);
7136 }
while (result->NextRow());
7149 if (!path || path->
Locations.size() < 4)
7156 return Position(pos.X, pos.Y, pos.Z);
7161 polygon.
Height = pathProperty->Value * 0.001f + 0.02f;
7172 QueryResult result =
WorldDatabase.Query(
"SELECT mapid, difficulty, level_min, level_max, item, item2, quest_done_A, quest_done_H, completed_achievement, quest_failed_text FROM access_requirement");
7176 TC_LOG_INFO(
"server.loading",
">> Loaded 0 access requirement definitions. DB table `access_requirement` is empty.");
7184 Field* fields = result->Fetch();
7189 TC_LOG_ERROR(
"sql.sql",
"Map {} referenced in `access_requirement` does not exist, skipped.", mapid);
7194 if (!
sDB2Manager.GetMapDifficultyData(mapid, difficulty))
7196 TC_LOG_ERROR(
"sql.sql",
"Map {} referenced in `access_requirement` does not have difficulty {}, skipped", mapid, difficulty);
7217 TC_LOG_ERROR(
"sql.sql",
"Key item {} does not exist for map {} difficulty {}, removing key requirement.", ar->
item, mapid, difficulty);
7227 TC_LOG_ERROR(
"sql.sql",
"Second item {} does not exist for map {} difficulty {}, removing key requirement.", ar->
item2, mapid, difficulty);
7236 TC_LOG_ERROR(
"sql.sql",
"Required Alliance Quest {} not exist for map {} difficulty {}, remove quest done requirement.", ar->
quest_A, mapid, difficulty);
7245 TC_LOG_ERROR(
"sql.sql",
"Required Horde Quest {} not exist for map {} difficulty {}, remove quest done requirement.", ar->
quest_H, mapid, difficulty);
7254 TC_LOG_ERROR(
"sql.sql",
"Required Achievement {} not exist for map {} difficulty {}, remove quest done requirement.", ar->
achievement, mapid, difficulty);
7260 }
while (result->NextRow());
7277 parentId = iTemplate->Parent;
7282 if (itr->second->Loc.GetMapId() == entrance_map)
7299 if (itr->second->Loc.GetMapId() ==
Map)
7316 GetGenerator<HighGuid::Item>().Set((*result)[0].GetUInt64() + 1);
7319 CharacterDatabase.PExecute(
"DELETE FROM character_inventory WHERE item >= '{}'", GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed());
7320 CharacterDatabase.PExecute(
"DELETE FROM mail_items WHERE item_guid >= '{}'", GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed());
7321 CharacterDatabase.PExecute(
"DELETE a, ab, ai FROM auctionhouse a LEFT JOIN auction_bidders ab ON ab.auctionId = a.id LEFT JOIN auction_items ai ON ai.auctionId = a.id WHERE ai.itemGuid >= '{}'",
7322 GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed());
7323 CharacterDatabase.PExecute(
"DELETE FROM guild_bank_item WHERE item_guid >= '{}'", GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed());
7325 result =
WorldDatabase.Query(
"SELECT MAX(guid) FROM transports");
7335 _mailId = (*result)[0].GetUInt64()+1;
7339 sArenaTeamMgr->SetNextArenaTeamId((*result)[0].GetUInt32()+1);
7341 result =
CharacterDatabase.Query(
"SELECT MAX(maxguid) FROM ((SELECT MAX(setguid) AS maxguid FROM character_equipmentsets) UNION (SELECT MAX(setguid) AS maxguid FROM character_transmog_outfits)) allsets");
7347 sGuildMgr->SetNextGuildId((*result)[0].GetUInt64()+1);
7351 sGroupMgr->SetGroupDbStoreSize((*result)[0].GetUInt32()+1);
7353 result =
WorldDatabase.Query(
"SELECT MAX(guid) FROM creature");
7357 result =
WorldDatabase.Query(
"SELECT MAX(guid) FROM gameobject");
7371 TC_LOG_ERROR(
"misc",
"Auctions ids overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7381 TC_LOG_ERROR(
"misc",
"EquipmentSet guid overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7391 TC_LOG_ERROR(
"misc",
"Mail ids overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7401 TC_LOG_ERROR(
"misc",
"_hiPetNumber Id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info.");
7411 TC_LOG_ERROR(
"misc",
"Creature spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info.");
7421 TC_LOG_ERROR(
"misc",
"GameObject spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7434 QueryResult result =
WorldDatabase.Query(
"SELECT entry, locale, name, castBarCaption, unk1 FROM gameobject_template_locale");
7440 Field* fields = result->Fetch();
7454 }
while (result->NextRow());
7472 Field* fields = result->Fetch();
7481 }
while (result->NextRow());
7491 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but lock (Id: {}) not found.",
7492 goInfo->
entry, goInfo->
type, N, dataN, dataN);
7500 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but GO (Entry {}) have not GAMEOBJECT_TYPE_TRAP ({}) type.",
7510 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but Spell (Entry {}) not exist.",
7511 goInfo->
entry, goInfo->
type, N, dataN, dataN);
7519 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but correct chair height in range 0..{}.",
7532 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but expected boolean (0/1) noDamageImmune field value.", goTemplate->
entry, goTemplate->
type, N, dataN);
7541 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but expected boolean (0/1) consumable field value.",
7552 go.
entry = db2go->ID;
7553 go.
type = db2go->TypeID;
7555 go.
name = db2go->Name[
sWorld->GetDefaultDbcLocale()];
7556 go.
size = db2go->Scale;
7558 std::ranges::copy(db2go->PropValue, std::begin(go.
raw.
data));
7565 QueryResult result =
WorldDatabase.Query(
"SELECT entry, type, displayId, name, IconName, castBarCaption, unk1, size, "
7567 "Data0, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11, Data12, "
7569 "Data13, Data14, Data15, Data16, Data17, Data18, Data19, Data20, Data21, Data22, Data23, Data24, Data25, Data26, Data27, Data28, "
7571 "Data29, Data30, Data31, Data32, Data33, Data34, ContentTuningId, RequiredLevel, AIName, ScriptName, StringId "
7572 "FROM gameobject_template");
7576 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject definitions. DB table `gameobject_template` is empty.");
7583 Field* fields = result->Fetch();
7609 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {}) has non-registered `AIName` '{}' set, removing", got.
entry, got.
AIName);
7659 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {} GoType: {}) have data0={} but SpellFocus (Id: {}) not exist.",
7677 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {} GoType: {}) have data7={} but PageText (Entry {}) not exist.",
7702 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {} GoType: {}) have data0={} but TaxiPath (Id: {}) not exist.",
7742 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {} GoType: {}) have data2 = {} but AnimKit.dbc (Id: {}) not exist, set to 0.",
7762 }
while (result->NextRow());
7772 QueryResult result =
WorldDatabase.Query(
"SELECT entry, faction, flags, mingold, maxgold, artkit0, artkit1, artkit2, artkit3, artkit4, WorldEffectID, AIAnimKitID FROM gameobject_template_addon");
7776 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject template addon definitions. DB table `gameobject_template_addon` is empty.");
7783 Field* fields = result->Fetch();
7790 TC_LOG_ERROR(
"sql.sql",
"GameObject template (Entry: {}) does not exist but has a record in `gameobject_template_addon`", entry);
7810 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {}) has invalid `artkit{}` ({}) defined, set to zero instead.", entry, i, artKitID);
7814 gameObjectAddon.
ArtKits[i] = artKitID;
7819 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {}) has invalid faction ({}) defined in `gameobject_template_addon`.", entry, gameObjectAddon.
Faction);
7821 if (gameObjectAddon.
Maxgold > 0)
7829 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry {} GoType: {}) cannot be looted but has maxgold set in `gameobject_template_addon`.", entry, got->
type);
7836 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {}) has invalid WorldEffectID ({}) defined in `gameobject_template_addon`, set to 0.", entry, gameObjectAddon.
WorldEffectID);
7842 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {}) has invalid AIAnimKitID ({}) defined in `gameobject_template_addon`, set to 0.", entry, gameObjectAddon.
AIAnimKitID);
7848 while (result->NextRow());
7861 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject faction and flags overrides. DB table `gameobject_overrides` is empty.");
7868 Field* fields = result->Fetch();
7874 TC_LOG_ERROR(
"sql.sql",
"GameObject (SpawnId: {}) does not exist but has a record in `gameobject_overrides`", spawnId);
7883 TC_LOG_ERROR(
"sql.sql",
"GameObject (SpawnId: {}) has invalid faction ({}) defined in `gameobject_overrides`.", spawnId, gameObjectOverride.
Faction);
7886 }
while (result->NextRow());
7899 TC_LOG_INFO(
"server.loading",
">> Loaded 0 BaseXP definitions. DB table `exploration_basexp` is empty.");
7907 Field* fields = result->Fetch();
7913 while (result->NextRow());
7944 TC_LOG_ERROR(
"sql.sql",
"Fishable areaId {} is not properly defined in `skill_fishing_base_level`.", areaEntry->
ID);
7952 return itr !=
_skillTiers.end() ? &itr->second :
nullptr;
7960 while (
Value[tierIndex] == 0 && tierIndex > 0)
7963 return Value[tierIndex];
7974 TC_LOG_INFO(
"server.loading",
">> Loaded 0 pet name parts. DB table `pet_name_generation` is empty!");
7982 Field* fields = result->Fetch();
7983 std::string word = fields[0].
GetString();
7985 bool half = fields[2].
GetBool();
7992 while (result->NextRow());
8004 Field* fields = result->Fetch();
8016 if (list0.empty() || list1.empty())
8020 return std::string();
8024 return std::string(petname);
8029 return *(list0.begin()+
urand(0, list0.size()-1)) + *(list1.begin()+
urand(0, list1.size()-1));
8039 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");
8042 TC_LOG_INFO(
"server.loading",
">> Loaded `reputation_reward_rate`, table is empty!");
8048 Field* fields = result->Fetch();
8065 TC_LOG_ERROR(
"sql.sql",
"Faction (faction.dbc) {} does not exist but is used in `reputation_reward_rate`", factionId);
8071 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has quest_rate with invalid rate {}, skipping data for faction {}", repRate.
questRate, factionId);
8077 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has quest_daily_rate with invalid rate {}, skipping data for faction {}", repRate.
questDailyRate, factionId);
8083 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has quest_weekly_rate with invalid rate {}, skipping data for faction {}", repRate.
questWeeklyRate, factionId);
8089 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has quest_monthly_rate with invalid rate {}, skipping data for faction {}", repRate.
questMonthlyRate, factionId);
8095 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has quest_repeatable_rate with invalid rate {}, skipping data for faction {}", repRate.
questRepeatableRate, factionId);
8101 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has creature_rate with invalid rate {}, skipping data for faction {}", repRate.
creatureRate, factionId);
8107 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has spell_rate with invalid rate {}, skipping data for faction {}", repRate.
spellRate, factionId);
8115 while (result->NextRow());
8132 "IsTeamAward1, MaxStanding1, RewOnKillRepValue1, IsTeamAward2, MaxStanding2, RewOnKillRepValue2, TeamDependent "
8133 "FROM creature_onkill_reputation");
8137 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature award reputation definitions. DB table `creature_onkill_reputation` is empty.");
8143 Field* fields = result->Fetch();
8160 TC_LOG_ERROR(
"sql.sql",
"Table `creature_onkill_reputation` has data for nonexistent creature entry ({}), skipped", creature_id);
8169 TC_LOG_ERROR(
"sql.sql",
"Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.
RepFaction1);
8179 TC_LOG_ERROR(
"sql.sql",
"Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.
RepFaction2);
8187 }
while (result->NextRow());
8199 QueryResult result =
WorldDatabase.Query(
"SELECT faction, faction1, rate_1, rank_1, faction2, rate_2, rank_2, faction3, rate_3, rank_3, faction4, rate_4, rank_4, faction5, rate_5, rank_5 FROM reputation_spillover_template");
8203 TC_LOG_INFO(
"server.loading",
">> Loaded `reputation_spillover_template`, table is empty.");
8209 Field* fields = result->Fetch();
8235 TC_LOG_ERROR(
"sql.sql",
"Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", factionId);
8241 TC_LOG_ERROR(
"sql.sql",
"Faction (faction.dbc) {} in `reputation_spillover_template` does not belong to any team, skipping", factionId);
8245 bool invalidSpilloverFaction =
false;
8252 if (!factionSpillover)
8254 TC_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);
8255 invalidSpilloverFaction =
true;
8261 TC_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);
8262 invalidSpilloverFaction =
true;
8268 TC_LOG_ERROR(
"sql.sql",
"Rank {} used in `reputation_spillover_template` for spillover faction {} is not valid, skipping", repTemplate.
faction_rank[i], repTemplate.
faction[i]);
8269 invalidSpilloverFaction =
true;
8275 if (invalidSpilloverFaction)
8282 while (result->NextRow());
8296 QueryResult result =
WorldDatabase.Query(
"SELECT ID, PositionX, PositionY, PositionZ, Icon, Flags, Importance, Name, WMOGroupID FROM points_of_interest");
8300 TC_LOG_INFO(
"server.loading",
">> Loaded 0 Points of Interest definitions. DB table `points_of_interest` is empty.");
8306 Field* fields = result->Fetch();
8311 pointOfInterest.
ID = id;
8312 pointOfInterest.
Pos.
Relocate(fields[1].GetFloat(), fields[2].GetFloat(), fields[3].GetFloat());
8321 TC_LOG_ERROR(
"sql.sql",
"Table `points_of_interest` (ID: {}) have invalid coordinates (PositionX: {} PositionY: {}, PositionZ: {}), ignored.",
8329 }
while (result->NextRow());
8341 QueryResult result =
WorldDatabase.Query(
"SELECT QuestID, BlobIndex, Idx1, ObjectiveIndex, QuestObjectiveID, QuestObjectID, MapID, UiMapID, Priority, Flags, WorldEffectID, PlayerConditionID, NavigationPlayerConditionID, SpawnTrackingID, AlwaysAllowMergingBlobs FROM quest_poi order by QuestID, Idx1");
8344 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty.");
8349 QueryResult pointsResult =
WorldDatabase.Query(
"SELECT QuestID, Idx1, X, Y, Z FROM quest_poi_points ORDER BY QuestID DESC, Idx1, Idx2");
8351 std::unordered_map<int32, std::map<int32, std::vector<QuestPOIBlobPoint>>> allPoints;
8357 Field* fields = pointsResult->Fetch();
8365 allPoints[QuestID][Idx1].emplace_back(x, y, z);
8366 }
while (pointsResult->NextRow());
8371 Field* fields = result->Fetch();
8387 bool alwaysAllowMergingBlobs = fields[14].
GetBool();
8390 TC_LOG_ERROR(
"sql.sql",
"`quest_poi` quest id ({}) Idx1 ({}) does not exist in `quest_template`", questID, idx1);
8398 poiData.
Blobs.emplace_back(blobIndex, objectiveIndex, questObjectiveID, questObjectID, mapID, uiMapID, priority,
flags,
8399 worldEffectID, playerConditionID, navigationPlayerConditionID, spawnTrackingID, std::move(*points), alwaysAllowMergingBlobs);
8404 TC_LOG_ERROR(
"sql.sql",
"Table quest_poi references unknown quest points for quest {} POI id {}", questID, blobIndex);
8406 }
while (result->NextRow());
8417 QueryResult result =
WorldDatabase.Query(
"SELECT npc_entry, spell_id, cast_flags, user_type FROM npc_spellclick_spells");
8421 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spellclick spells. DB table `npc_spellclick_spells` is empty.");
8429 Field* fields = result->Fetch();
8435 TC_LOG_ERROR(
"sql.sql",
"Table npc_spellclick_spells references unknown creature_template {}. Skipping entry.", npc_entry);
8443 TC_LOG_ERROR(
"sql.sql",
"Table npc_spellclick_spells creature: {} references unknown spellid {}. Skipping entry.", npc_entry, spellid);
8449 TC_LOG_ERROR(
"sql.sql",
"Table npc_spellclick_spells creature: {} references unknown user type {}. Skipping entry.", npc_entry,
uint32(userType));
8460 while (result->NextRow());
8468 TC_LOG_ERROR(
"sql.sql",
"npc_spellclick_spells: Creature template {} has UNIT_NPC_FLAG_SPELLCLICK but no data in spellclick table! Removing flag", creatureTemplatePair.first);
8469 creatureTemplatePair.second.npcflag &= ~UNIT_NPC_FLAG_SPELLCLICK;
8524 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quest relations from `{}`, table is empty.", table);
8530 uint32 id = result->Fetch()[0].GetUInt32();
8531 uint32 quest = result->Fetch()[1].GetUInt32();
8535 TC_LOG_ERROR(
"sql.sql",
"Table `{}`: Quest {} listed for entry {} does not exist.", table, quest,
id);
8539 map.insert(QuestRelations::value_type(
id, quest));
8541 reverseMap->insert(QuestRelationsReverse::value_type(quest,
id));
8543 }
while (result->NextRow());
8556 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject_queststarter` has data for nonexistent gameobject entry ({}) and existed quest {}", itr->first, itr->second);
8558 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject_queststarter` has data gameobject entry ({}) for quest {}, but GO is not GAMEOBJECT_TYPE_QUESTGIVER", itr->first, itr->second);
8570 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject_questender` has data for nonexistent gameobject entry ({}) and existed quest {}", itr->first, itr->second);
8572 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject_questender` has data gameobject entry ({}) for quest {}, but GO is not GAMEOBJECT_TYPE_QUESTGIVER", itr->first, itr->second);
8584 TC_LOG_ERROR(
"sql.sql",
"Table `creature_queststarter` has data for nonexistent creature entry ({}) and existed quest {}", itr->first, itr->second);
8586 TC_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);
8598 TC_LOG_ERROR(
"sql.sql",
"Table `creature_questender` has data for nonexistent creature entry ({}) and existed quest {}", itr->first, itr->second);
8600 TC_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);
8619 _reservedNamesStore.clear();
8625 TC_LOG_INFO(
"server.loading",
">> Loaded 0 reserved player names. DB table `reserved_name` is empty!");
8634 fields = result->Fetch();
8635 std::string name= fields[0].
GetString();
8640 TC_LOG_ERROR(
"misc",
"Table `reserved_name` has invalid name: {}", name);
8646 _reservedNamesStore.insert(wstr);
8649 while (result->NextRow());
8662 return _reservedNamesStore.find(wstr) != _reservedNamesStore.end();
8667 if (std::shared_ptr<Realm const> currentRealm =
sRealmList->GetCurrentRealm())
8669 return create ? category->GetCreateCharsetMask() : category->GetExistingCharsetMask();
8676 if (strictMask == 0)
8689 if (strictMask & 0x2)
8706 if (strictMask & 0x1)
8725 if (wname.size() < minName)
8733 for (
size_t i = 2; i < wname.size(); ++i)
8734 if (wname[i] == wname[i-1] && wname[i] == wname[i-2])
8750 if (wname.size() < minName)
8768 if (wname.size() < minName)
8782 _gameObjectForQuestStore.clear();
8784 if (_gameObjectTemplateStore.empty())
8786 TC_LOG_INFO(
"server.loading",
">> Loaded 0 GameObjects for quests");
8793 for (
auto const& gameObjectTemplatePair : _gameObjectTemplateStore)
8795 switch (gameObjectTemplatePair.second.type)
8803 if (gameObjectTemplatePair.second.chest.questID
8812 if (gameObjectTemplatePair.second.generic.questID > 0)
8818 if (gameObjectTemplatePair.second.spellFocus.questID > 0)
8824 if (gameObjectTemplatePair.second.goober.questID > 0)
8840 _gameObjectForQuestStore.insert(gameObjectTemplatePair.first);
8844 for (
auto [questObjectiveId, objective] : _questObjectives)
8849 _gameObjectForQuestStore.insert(objective->ObjectID);
8860 _trinityStringStore.clear();
8862 QueryResult result =
WorldDatabase.Query(
"SELECT entry, content_default, content_loc1, content_loc2, content_loc3, content_loc4, content_loc5, content_loc6, content_loc7, content_loc8 FROM trinity_string");
8865 TC_LOG_INFO(
"server.loading",
">> Loaded 0 trinity strings. DB table `trinity_string` is empty. You have imported an incorrect database for more info search for TCE00003 on forum.");
8871 Field* fields = result->Fetch();
8882 while (result->NextRow());
8892 if (ts->Content.size() >
size_t(locale) && !ts->Content[locale].empty())
8893 return ts->
Content[locale].c_str();
8897 TC_LOG_ERROR(
"sql.sql",
"Trinity string entry {} not found in DB.", entry);
8905 _fishingBaseForAreaStore.clear();
8911 TC_LOG_INFO(
"server.loading",
">> Loaded 0 areas for fishing base skill level. DB table `skill_fishing_base_level` is empty.");
8919 Field* fields = result->Fetch();
8926 TC_LOG_ERROR(
"sql.sql",
"AreaId {} defined in `skill_fishing_base_level` does not exist", entry);
8930 _fishingBaseForAreaStore[entry] = skill;
8933 while (result->NextRow());
8942 QueryResult result =
WorldDatabase.Query(
"SELECT ID, Value1, Value2, Value3, Value4, Value5, Value6, Value7, Value8, Value9, Value10, "
8943 " Value11, Value12, Value13, Value14, Value15, Value16 FROM skill_tiers");
8947 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 skill max values. DB table `skill_tiers` is empty.");
8953 Field* fields = result->Fetch();
8959 }
while (result->NextRow());
8982 if (w_ownname != wname)
8990 AreaTriggerScriptContainer::const_iterator i = _areaTriggerScriptStore.find(trigger_id);
8991 if (i!= _areaTriggerScriptStore.end())
9003 EventScriptContainer::const_iterator i = _eventScriptStore.find(eventId);
9004 if (i != _eventScriptStore.end())
9036 _gameTeleStore.clear();
9039 QueryResult result =
WorldDatabase.Query(
"SELECT id, position_x, position_y, position_z, orientation, map, name FROM game_tele");
9043 TC_LOG_INFO(
"server.loading",
">> Loaded 0 GameTeleports. DB table `game_tele` is empty!");
9051 Field* fields = result->Fetch();
9066 TC_LOG_ERROR(
"sql.sql",
"Wrong position for id {} (name: {}) in `game_tele` table, ignoring.",
id, gt.
name);
9072 TC_LOG_ERROR(
"sql.sql",
"Wrong UTF8 name for id {} in `game_tele` table, ignoring.",
id);
9078 _gameTeleStore[id] = gt;
9082 while (result->NextRow());
9099 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9101 if (itr->second.wnameLow == wname)
9102 return &itr->second;
9103 else if (!alt && itr->second.
wnameLow.find(wname) != std::wstring::npos)
9120 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9122 if (itr->second.wnameLow == wname)
9123 return &itr->second;
9133 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9134 if (itr->first > new_id)
9135 new_id = itr->first;
9145 _gameTeleStore[new_id] = tele;
9172 for (GameTeleContainer::iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9174 if (itr->second.wnameLow == wname)
9182 _gameTeleStore.erase(itr);
9194 _mailLevelRewardStore.clear();
9197 QueryResult result =
WorldDatabase.Query(
"SELECT level, raceMask, mailTemplateId, senderEntry FROM mail_level_reward");
9201 TC_LOG_INFO(
"server.loading",
">> Loaded 0 level dependent mail rewards. DB table `mail_level_reward` is empty.");
9209 Field* fields = result->Fetch();
9218 TC_LOG_ERROR(
"sql.sql",
"Table `mail_level_reward` has data for level {} that more supported by client ({}), ignoring.", level,
MAX_LEVEL);
9224 TC_LOG_ERROR(
"sql.sql",
"Table `mail_level_reward` has raceMask ({}) for level {} that not include any player races, ignoring.", raceMask.
RawValue[0], level);
9230 TC_LOG_ERROR(
"sql.sql",
"Table `mail_level_reward` has invalid mailTemplateId ({}) for level {} that invalid not include any player races, ignoring.", mailTemplateId, level);
9234 if (!GetCreatureTemplate(senderEntry))
9236 TC_LOG_ERROR(
"sql.sql",
"Table `mail_level_reward` has nonexistent sender creature entry ({}) for level {} that invalid not include any player races, ignoring.", senderEntry, level);
9240 _mailLevelRewardStore[level].emplace_back(raceMask, mailTemplateId, senderEntry);
9244 while (result->NextRow());
9256 std::unordered_map<int32, std::vector<Trainer::Spell>> spellsByTrainer;
9257 if (
QueryResult trainerSpellsResult =
WorldDatabase.Query(
"SELECT TrainerId, SpellId, MoneyCost, ReqSkillLine, ReqSkillRank, ReqAbility1, ReqAbility2, ReqAbility3, ReqLevel FROM trainer_spell"))
9261 Field* fields = trainerSpellsResult->Fetch();
9277 TC_LOG_ERROR(
"sql.sql",
"Table `trainer_spell` references non-existing spell (SpellId: {}) for TrainerId {}, ignoring", spell.
SpellId, trainerId);
9283 TC_LOG_ERROR(
"sql.sql",
"Table `trainer_spell` references non-existing skill (ReqSkillLine: {}) for TrainerId {} and SpellId {}, ignoring",
9288 bool allReqValid =
true;
9289 for (std::size_t i = 0; i < spell.
ReqAbility.size(); ++i)
9294 TC_LOG_ERROR(
"sql.sql",
"Table `trainer_spell` references non-existing spell (ReqAbility{}: {}) for TrainerId {} and SpellId {}, ignoring",
9295 i + 1, requiredSpell, trainerId, spell.
SpellId);
9296 allReqValid =
false;
9303 spellsByTrainer[trainerId].push_back(spell);
9305 }
while (trainerSpellsResult->NextRow());
9312 Field* fields = trainersResult->Fetch();
9316 std::vector<Trainer::Spell> spells;
9317 auto spellsItr = spellsByTrainer.find(trainerId);
9318 if (spellsItr != spellsByTrainer.end())
9320 spells = std::move(spellsItr->second);
9321 spellsByTrainer.erase(spellsItr);
9324 _trainers.emplace(std::piecewise_construct, std::forward_as_tuple(trainerId), std::forward_as_tuple(trainerId, trainerType, greeting, std::move(spells)));
9326 }
while (trainersResult->NextRow());
9329 for (
auto const& unusedSpells : spellsByTrainer)
9333 TC_LOG_ERROR(
"sql.sql",
"Table `trainer_spell` references non-existing trainer (TrainerId: {}) for SpellId {}, ignoring", unusedSpells.first, unusedSpell.SpellId);
9337 if (
QueryResult trainerLocalesResult =
WorldDatabase.Query(
"SELECT Id, locale, Greeting_lang FROM trainer_locale"))
9341 Field* fields = trainerLocalesResult->Fetch();
9343 std::string localeName = fields[1].
GetString();
9350 trainer->AddGreetingLocale(locale, fields[2].GetString());
9352 TC_LOG_ERROR(
"sql.sql",
"Table `trainer_locale` references non-existing trainer (TrainerId: {}) for locale {}, ignoring",
9353 trainerId, localeName);
9355 }
while (trainerLocalesResult->NextRow());
9365 _creatureDefaultTrainers.clear();
9367 if (
QueryResult result =
WorldDatabase.Query(
"SELECT CreatureID, TrainerID, MenuID, OptionID FROM creature_trainer"))
9371 Field* fields = result->Fetch();
9377 if (!GetCreatureTemplate(creatureId))
9379 TC_LOG_ERROR(
"sql.sql",
"Table `creature_trainer` references non-existing creature template (CreatureID: {}), ignoring", creatureId);
9383 if (!GetTrainer(trainerId))
9385 TC_LOG_ERROR(
"sql.sql",
"Table `creature_trainer` references non-existing trainer (TrainerID: {}) for CreatureID {} MenuID {} OptionID {}, ignoring",
9386 trainerId, creatureId, gossipMenuId, gossipOptionId);
9390 if (gossipMenuId || gossipOptionId)
9393 auto gossipOptionItr = std::find_if(gossipMenuItems.
begin(), gossipMenuItems.
end(), [gossipOptionId](std::pair<uint32 const, GossipMenuItems>
const& entry)
9395 return entry.second.OrderIndex == gossipOptionId;
9397 if (gossipOptionItr == gossipMenuItems.
end())
9399 TC_LOG_ERROR(
"sql.sql",
"Table `creature_trainer` references non-existing gossip menu option (MenuID {} OptionID {}) for CreatureID {} and TrainerID {}, ignoring",
9400 gossipMenuId, gossipOptionId, creatureId, trainerId);
9405 _creatureDefaultTrainers[std::make_tuple(creatureId, gossipMenuId, gossipOptionId)] = trainerId;
9406 }
while (result->NextRow());
9425 Field* fields = result->Fetch();
9431 count += LoadReferenceVendor(vendor, -item_id, skip_vendors);
9435 vItem.
item = item_id;
9443 for (std::string_view token :
Trinity::Tokenize(fields[5].GetStringView(),
' ',
false))
9447 if (!IsVendorItemValid(vendor, vItem,
nullptr, skip_vendors))
9451 vList.
AddItem(std::move(vItem));
9454 }
while (result->NextRow());
9464 for (CacheVendorItemContainer::iterator itr = _cacheVendorItemStore.begin(); itr != _cacheVendorItemStore.end(); ++itr)
9465 itr->second.Clear();
9466 _cacheVendorItemStore.clear();
9468 std::set<uint32> skip_vendors;
9470 QueryResult result =
WorldDatabase.Query(
"SELECT entry, item, maxcount, incrtime, ExtendedCost, type, BonusListIDs, PlayerConditionID, IgnoreFiltering FROM npc_vendor ORDER BY entry, slot ASC");
9473 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 Vendors. DB table `npc_vendor` is empty!");
9481 Field* fields = result->Fetch();
9488 count += LoadReferenceVendor(entry, -item_id, &skip_vendors);
9492 vItem.
item = item_id;
9500 for (std::string_view token :
Trinity::Tokenize(fields[6].GetStringView(),
' ',
false))
9504 if (!IsVendorItemValid(entry, vItem,
nullptr, &skip_vendors))
9508 vList.
AddItem(std::move(vItem));
9512 while (result->NextRow());
9521 _gossipMenusStore.clear();
9528 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gossip_menu IDs. DB table `gossip_menu` is empty!");
9534 Field* fields = result->Fetch();
9541 if (!GetNpcText(gMenu.
TextID))
9547 _gossipMenusStore.insert(GossipMenusContainer::value_type(gMenu.
MenuID, gMenu));
9548 }
while (result->NextRow());
9557 _gossipMenuItemsStore.clear();
9561 "SELECT MenuID, GossipOptionID, OptionID, OptionNpc, OptionText, OptionBroadcastTextID, Language, Flags, ActionMenuID, ActionPoiID, GossipNpcOptionID, "
9563 "BoxCoded, BoxMoney, BoxText, BoxBroadcastTextID, SpellID, OverrideIconID "
9564 "FROM gossip_menu_option ORDER BY MenuID, OptionID");
9568 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gossip_menu_option IDs. DB table `gossip_menu_option` is empty!");
9572 std::unordered_map<int32, int32> optionToNpcOption;
9574 optionToNpcOption[npcOption->GossipOptionID] = npcOption->ID;
9578 Field* fields = result->Fetch();
9623 TC_LOG_ERROR(
"sql.sql",
"Table `gossip_menu_option` for menu {}, id {} can not use ActionMenuID for GossipOptionNpc different from GossipOptionNpc::None, ignoring", gMenuItem.
MenuID, gMenuItem.
OrderIndex);
9631 TC_LOG_ERROR(
"sql.sql",
"Table `gossip_menu_option` for menu {}, id {} can not use ActionPoiID for GossipOptionNpc different from GossipOptionNpc::None, ignoring", gMenuItem.
MenuID, gMenuItem.
OrderIndex);
9634 else if (!GetPointOfInterest(gMenuItem.
ActionPoiID))
9645 TC_LOG_ERROR(
"sql.sql",
"Table `gossip_menu_option` for menu {}, id {} use non-existing GossipNPCOption {}, ignoring",
9666 TC_LOG_ERROR(
"sql.sql",
"Table `gossip_menu_option` for menu {}, id {} use non-existing Spell {}, ignoring",
9672 _gossipMenuItemsStore.insert(GossipMenuItemsContainer::value_type(gMenuItem.
MenuID, gMenuItem));
9673 }
while (result->NextRow());
9675 TC_LOG_INFO(
"server.loading",
">> Loaded {} gossip_menu_option entries in {} ms", _gossipMenuItemsStore.size(),
GetMSTimeDiffToNow(oldMSTime));
9682 _gossipMenuAddonStore.clear();
9685 QueryResult result =
WorldDatabase.Query(
"SELECT MenuID, FriendshipFactionID, LfgDungeonsID FROM gossip_menu_addon");
9689 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gossip_menu_addon IDs. DB table `gossip_menu_addon` is empty!");
9695 Field* fields = result->Fetch();
9708 TC_LOG_ERROR(
"sql.sql",
"Table gossip_menu_addon: ID {} is using FriendshipFactionID {} referencing non-existing FriendshipRepID {}",
9722 TC_LOG_ERROR(
"sql.sql",
"Table gossip_menu_addon: ID {} is using non-existing LfgDungeonsID {}", menuID, addon.
LfgDungeonsID);
9726 }
while (result->NextRow());
9738 auto itr = _creatureDefaultTrainers.find(std::make_tuple(creatureId, gossipMenuId, gossipOptionId));
9739 if (itr != _creatureDefaultTrainers.end())
9767 CacheVendorItemContainer::iterator iter = _cacheVendorItemStore.find(entry);
9768 if (iter == _cacheVendorItemStore.end())
9771 if (!iter->second.RemoveItem(item, type))
9796 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` has data for nonexistent creature template (Entry: {}), ignore", vendor_entry);
9802 if (!skip_vendors || skip_vendors->count(vendor_entry) == 0)
9807 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` has data for creature template (Entry: {}) without vendor flag, ignore", vendor_entry);
9810 skip_vendors->insert(vendor_entry);
9821 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` for Vendor (Entry: {}) have in item list non-existed item ({}, type {}), ignore", vendor_entry, vItem.
item, vItem.
Type);
9829 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` has Item (Entry: {}) with serverside PlayerConditionId ({}) for vendor ({}) without conditions, ignore", vItem.
item, vItem.
PlayerConditionId, vendor_entry);
9839 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` has Item (Entry: {}) with wrong ExtendedCost ({}) for vendor ({}), ignore", vItem.
item, vItem.
ExtendedCost, vendor_entry);
9850 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` has `maxcount` ({}) for item {} of vendor (Entry: {}) but `incrtime`=0, ignore", vItem.
maxcount, vItem.
item, vendor_entry);
9858 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` has `maxcount`=0 for item {} of vendor (Entry: {}) but `incrtime`<>0, ignore", vItem.
item, vendor_entry);
9866 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` have Item (Entry: {}) with invalid bonus {} for vendor ({}), ignore", vItem.
item, bonusListId, vendor_entry);
9872 VendorItemData const* vItems = GetNpcVendorItemList(vendor_entry);
9881 TC_LOG_ERROR(
"sql.sql",
"Table `npc_vendor` has duplicate items {} (with extended cost {}, type {}) for vendor (Entry: {}), ignoring", vItem.
item, vItem.
ExtendedCost, vItem.
Type, vendor_entry);
9887 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` have Item (Entry: {}, type: {}) with missing maxcount for vendor ({}), ignore", vItem.
item, vItem.
Type, vendor_entry);
9898 [[maybe_unused]]
uint32 const id = insert(
"",
false);
9905 IndexToName.reserve(capacity);
9910 auto result = NameToIndex.lower_bound(scriptName);
9911 if (result == NameToIndex.end() || NameToIndex.key_comp()(scriptName, result->first))
9913 ASSERT(NameToIndex.size() <= std::numeric_limits<uint32>::max());
9914 result = NameToIndex.emplace_hint(result, scriptName,
Entry(
static_cast<uint32>(NameToIndex.size()), isScriptNameBound));
9915 IndexToName.emplace_back(result);
9918 return result->second.Id;
9923 return IndexToName.size();
9928 return index < IndexToName.size() ? IndexToName[index] :
end();
9937 return NameToIndex.find(name);
9942 return NameToIndex.end();
9947 std::unordered_set<std::string> scriptNames;
9949 for (std::pair<std::string const, Entry>
const& entry : NameToIndex)
9951 if (entry.second.IsScriptDatabaseBound)
9953 scriptNames.insert(entry.first);
9962 return _scriptNamesStore.GetAllDBScriptNames();
9967 auto const itr = _scriptNamesStore.find(
id);
9968 if (itr != _scriptNamesStore.end())
9974 static std::string
const empty;
9981 auto const itr = _scriptNamesStore.find(
id);
9982 if (itr != _scriptNamesStore.end())
9984 return itr->second.IsScriptDatabaseBound;
9994 return _scriptNamesStore.insert(name, isDatabaseBound);
9999 CreatureBaseStatsContainer::const_iterator it = _creatureBaseStatsStore.find(
MAKE_PAIR16(level, unitClass));
10001 if (it != _creatureBaseStatsStore.end())
10002 return &(it->second);
10008 .RangedAttackPower = 0
10017 QueryResult result =
WorldDatabase.Query(
"SELECT level, class, basemana, attackpower, rangedattackpower FROM creature_classlevelstats");
10021 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature base stats. DB table `creature_classlevelstats` is empty.");
10028 Field* fields = result->Fetch();
10047 while (result->NextRow());
10050 for (
uint8 unitLevel = 1; unitLevel <= maxLevel + 3; ++unitLevel)
10054 uint8 unitClassMask = 1 << (unitClass - 1);
10055 if (!_creatureBaseStatsStore.count(
MAKE_PAIR16(unitLevel, unitClassMask)))
10056 TC_LOG_ERROR(
"sql.sql",
"Missing base stats for creature class {} level {}", unitClassMask, unitLevel);
10071 TC_LOG_INFO(
"server.loading",
">> Loaded 0 faction change achievement pairs. DB table `player_factionchange_achievement` is empty.");
10079 Field* fields = result->Fetch();
10085 TC_LOG_ERROR(
"sql.sql",
"Achievement {} (alliance_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", alliance);
10087 TC_LOG_ERROR(
"sql.sql",
"Achievement {} (horde_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", horde);
10089 FactionChangeAchievements[alliance] = horde;
10093 while (result->NextRow());
10103 for (std::pair<uint32 const, ItemTemplate>
const& itemPair : _itemTemplateStore)
10105 if (!itemPair.second.GetOtherFactionItemId())
10109 FactionChangeItemsHordeToAlliance[itemPair.first] = itemPair.second.GetOtherFactionItemId();
10112 FactionChangeItemsAllianceToHorde[itemPair.first] = itemPair.second.GetOtherFactionItemId();
10128 TC_LOG_INFO(
"server.loading",
">> Loaded 0 faction change quest pairs. DB table `player_factionchange_quests` is empty.");
10136 Field* fields = result->Fetch();
10141 if (!GetQuestTemplate(alliance))
10142 TC_LOG_ERROR(
"sql.sql",
"Quest {} (alliance_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", alliance);
10143 else if (!GetQuestTemplate(horde))
10144 TC_LOG_ERROR(
"sql.sql",
"Quest {} (horde_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", horde);
10146 FactionChangeQuests[alliance] = horde;
10150 while (result->NextRow());
10163 TC_LOG_INFO(
"server.loading",
">> Loaded 0 faction change reputation pairs. DB table `player_factionchange_reputations` is empty.");
10171 Field* fields = result->Fetch();
10177 TC_LOG_ERROR(
"sql.sql",
"Reputation {} (alliance_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", alliance);
10179 TC_LOG_ERROR(
"sql.sql",
"Reputation {} (horde_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", horde);
10181 FactionChangeReputation[alliance] = horde;
10185 while (result->NextRow());
10198 TC_LOG_INFO(
"server.loading",
">> Loaded 0 faction change spell pairs. DB table `player_factionchange_spells` is empty.");
10206 Field* fields = result->Fetch();
10212 TC_LOG_ERROR(
"sql.sql",
"Spell {} (alliance_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", alliance);
10214 TC_LOG_ERROR(
"sql.sql",
"Spell {} (horde_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", horde);
10216 FactionChangeSpells[alliance] = horde;
10220 while (result->NextRow());
10233 TC_LOG_INFO(
"server.loading",
">> Loaded 0 faction change title pairs. DB table `player_factionchange_title` is empty.");
10241 Field* fields = result->Fetch();
10247 TC_LOG_ERROR(
"sql.sql",
"Title {} (alliance_id) referenced in `player_factionchange_title` does not exist, pair skipped!", alliance);
10249 TC_LOG_ERROR(
"sql.sql",
"Title {} (horde_id) referenced in `player_factionchange_title` does not exist, pair skipped!", horde);
10251 FactionChangeTitles[alliance] = horde;
10255 while (result->NextRow());
10263 _phaseInfoById.emplace(std::make_pair(phase->ID,
PhaseInfoStruct{ phase->ID, std::unordered_set<uint32>{} }));
10266 if (map->ParentMapID != -1)
10269 TC_LOG_INFO(
"server.loading",
"Loading Terrain World Map definitions...");
10270 LoadTerrainWorldMaps();
10272 TC_LOG_INFO(
"server.loading",
"Loading Terrain Swap Default definitions...");
10273 LoadTerrainSwapDefaults();
10275 TC_LOG_INFO(
"server.loading",
"Loading Phase Area definitions...");
10281 for (
auto itr = _phaseInfoByArea.begin(); itr != _phaseInfoByArea.end(); ++itr)
10283 phase.Conditions.clear();
10295 TC_LOG_INFO(
"server.loading",
">> Loaded 0 terrain world maps. DB table `terrain_worldmap` is empty.");
10302 Field* fields = result->Fetch();
10309 TC_LOG_ERROR(
"sql.sql",
"TerrainSwapMap {} defined in `terrain_worldmap` does not exist, skipped.", mapId);
10315 TC_LOG_ERROR(
"sql.sql",
"Phase {} defined in `terrain_worldmap` is not a valid terrain swap phase, skipped.", uiMapPhaseId);
10320 terrainSwapInfo->
Id = mapId;
10324 }
while (result->NextRow());
10338 TC_LOG_INFO(
"server.loading",
">> Loaded 0 terrain swap defaults. DB table `terrain_swap_defaults` is empty.");
10345 Field* fields = result->Fetch();
10351 TC_LOG_ERROR(
"sql.sql",
"Map {} defined in `terrain_swap_defaults` does not exist, skipped.", mapId);
10357 if (!
sMapStore.LookupEntry(terrainSwap))
10359 TC_LOG_ERROR(
"sql.sql",
"TerrainSwapMap {} defined in `terrain_swap_defaults` does not exist, skipped.", terrainSwap);
10363 TerrainSwapInfo* terrainSwapInfo = &_terrainSwapInfoById[terrainSwap];
10364 terrainSwapInfo->
Id = terrainSwap;
10365 _terrainSwapInfoByMap[mapId].push_back(terrainSwapInfo);
10368 }
while (result->NextRow());
10382 TC_LOG_INFO(
"server.loading",
">> Loaded 0 phase areas. DB table `phase_area` is empty.");
10386 auto getOrCreatePhaseIfMissing = [
this](
uint32 phaseId)
10389 phaseInfo->
Id = phaseId;
10396 Field* fields = result->Fetch();
10401 TC_LOG_ERROR(
"sql.sql",
"Area {} defined in `phase_area` does not exist, skipped.", area);
10407 TC_LOG_ERROR(
"sql.sql",
"Phase {} defined in `phase_area` does not exist, skipped.", phaseId);
10412 phase->
Areas.insert(area);
10413 _phaseInfoByArea[area].emplace_back(phase);
10416 }
while (result->NextRow());
10418 for (
auto itr = _phaseInfoByArea.begin(); itr != _phaseInfoByArea.end(); ++itr)
10422 uint32 parentAreaId = itr->first;
10435 if (parentAreaPhase.PhaseInfo->Id == phase.PhaseInfo->Id)
10436 parentAreaPhase.SubAreaExclusions.insert(itr->first);
10447 return std::any_of(
Areas.begin(),
Areas.end(), [areaId](
uint32 areaToCheck)
10449 return DB2Manager::IsInArea(areaId, areaToCheck);
10480 auto itr = _gameObjectTemplateAddonStore.find(entry);
10481 if (itr != _gameObjectTemplateAddonStore.end())
10482 return &itr->second;
10512 VehicleAccessoryContainer::const_iterator itr = _vehicleAccessoryStore.find(cre->GetSpawnId());
10513 if (itr != _vehicleAccessoryStore.end())
10514 return &itr->second;
10518 VehicleAccessoryTemplateContainer::const_iterator itr = _vehicleTemplateAccessoryStore.find(veh->
GetCreatureEntry());
10519 if (itr != _vehicleTemplateAccessoryStore.end())
10520 return &itr->second;
10532 _raceClassRequirementStore.clear();
10535 QueryResult result =
WorldDatabase.Query(
"SELECT ClassID, RaceID, ActiveExpansionLevel, AccountExpansionLevel FROM `class_expansion_requirement`");
10539 std::map<uint8, std::map<uint8, std::pair<uint8, uint8>>> temp;
10540 std::array<uint8, MAX_CLASSES> minRequirementForClass = { };
10545 Field* fields = result->Fetch();
10555 TC_LOG_ERROR(
"sql.sql",
"Class {} (race {}) defined in `class_expansion_requirement` does not exists, skipped.",
10563 TC_LOG_ERROR(
"sql.sql",
"Race {} (class {}) defined in `class_expansion_requirement` does not exists, skipped.",
10570 TC_LOG_ERROR(
"sql.sql",
"Class {} Race {} defined in `class_expansion_requirement` has incorrect ActiveExpansionLevel {}, skipped.",
10571 uint32(classID),
uint32(raceID), activeExpansionLevel);
10577 TC_LOG_ERROR(
"sql.sql",
"Class {} Race {} defined in `class_expansion_requirement` has incorrect AccountExpansionLevel {}, skipped.",
10578 uint32(classID),
uint32(raceID), accountExpansionLevel);
10582 temp[raceID][classID] = { activeExpansionLevel, accountExpansionLevel };
10583 minRequirementForClass[classID] = std::min(minRequirementForClass[classID], activeExpansionLevel);
10587 while (result->NextRow());
10589 for (
auto&& race : temp)
10593 raceClassAvailability.
RaceID = race.first;
10595 for (
auto&& class_ : race.second)
10599 classAvailability.
ClassID = class_.first;
10609 TC_LOG_INFO(
"server.loading",
">> Loaded 0 class expansion requirements. DB table `class_expansion_requirement` is empty.");
10614 result =
WorldDatabase.Query(
"SELECT raceID, expansion, achievementId FROM `race_unlock_requirement`");
10621 Field* fields = result->Fetch();
10630 TC_LOG_ERROR(
"sql.sql",
"Race {} defined in `race_unlock_requirement` does not exists, skipped.", raceID);
10636 TC_LOG_ERROR(
"sql.sql",
"Race {} defined in `race_unlock_requirement` has incorrect expansion {}, skipped.", raceID, expansion);
10642 TC_LOG_ERROR(
"sql.sql",
"Race {} defined in `race_unlock_requirement` has incorrect achievement {}, skipped.", raceID, achievementId);
10647 if (itr == _raceClassRequirementStore.end())
10649 itr = _raceClassRequirementStore.emplace(_raceClassRequirementStore.end());
10650 itr->RaceID = raceID;
10654 raceUnlockRequirement.
Expansion = expansion;
10658 while (result->NextRow());
10662 TC_LOG_INFO(
"server.loading",
">> Loaded 0 race expansion requirements. DB table `race_expansion_requirement` is empty.");
10668 if (raceItr == _raceClassRequirementStore.end())
10671 return &raceItr->UnlockRequirement;
10677 if (raceItr == _raceClassRequirementStore.end())
10681 if (classItr == raceItr->Classes.end())
10684 return &(*classItr);
10690 for (
ClassAvailability const& classAvailability : raceClassAvailability.Classes)
10691 if (classAvailability.ClassID == classId)
10692 return &classAvailability;
10710 if (staticFlagsOverride)
10711 return staticFlagsOverride;
10715 if (difficultyEntry)
10726 QueryResult result =
WorldDatabase.Query(
"SELECT GameObjectEntry, ItemId, Idx FROM gameobject_questitem ORDER BY Idx ASC");
10730 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject quest items. DB table `gameobject_questitem` is empty.");
10737 Field* fields = result->Fetch();
10746 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject_questitem` has data for nonexistent gameobject (entry: {}, idx: {}), skipped", entry, idx);
10753 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject_questitem` has nonexistent item (ID: {}) in gameobject (entry: {}, idx: {}), skipped", item, entry, idx);
10757 _gameObjectQuestItemStore[entry].push_back(item);
10761 while (result->NextRow());
10771 QueryResult result =
WorldDatabase.Query(
"SELECT CreatureEntry, DifficultyID, ItemId, Idx FROM creature_questitem ORDER BY Idx ASC");
10775 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature quest items. DB table `creature_questitem` is empty.");
10782 Field* fields = result->Fetch();
10792 TC_LOG_ERROR(
"sql.sql",
"Table `creature_questitem` has data for nonexistent creature (entry: {}, difficulty: {}, idx: {}), skipped", entry, difficulty, idx);
10799 TC_LOG_ERROR(
"sql.sql",
"Table `creature_questitem` has nonexistent item (ID: {}) in creature (entry: {}, difficulty: {}, idx: {}), skipped", item, entry, difficulty, idx);
10803 _creatureQuestItemStore[std::make_pair(entry, difficulty)].push_back(item);
10807 while (result->NextRow());
10817 QueryResult result =
WorldDatabase.Query(
"SELECT CreatureId, CurrencyId FROM creature_quest_currency ORDER BY CreatureId, CurrencyId ASC");
10821 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature quest currencies. DB table `creature_quest_currency` is empty.");
10828 Field* fields = result->Fetch();
10833 if (!GetCreatureTemplate(entry))
10835 TC_LOG_ERROR(
"sql.sql",
"Table `creature_quest_currency` has data for nonexistent creature (entry: {}, currency: {}), skipped", entry, currency);
10841 TC_LOG_ERROR(
"sql.sql",
"Table `creature_quest_currency` has nonexistent currency (ID: {}) in creature (entry: {}, currency: {}), skipped", currency, entry, currency);
10845 _creatureQuestCurrenciesStore[entry].push_back(currency);
10849 while (result->NextRow());
10857 _creatureStaticFlagsOverrideStore.clear();
10862 QueryResult result =
WorldDatabase.Query(
"SELECT SpawnId, DifficultyId, StaticFlags1, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, StaticFlags6, StaticFlags7, StaticFlags8 FROM creature_static_flags_override");
10866 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature static flag overrides. DB table `creature_static_flags_override` is empty.");
10873 Field* fields = result->Fetch();
10881 TC_LOG_ERROR(
"sql.sql",
"Table `creature_static_flags_override` has data for nonexistent creature (SpawnId: {}), skipped", spawnId);
10890 TC_LOG_ERROR(
"sql.sql",
"Table `creature_static_flags_override` has data for a creature that is not available for the specified DifficultyId (SpawnId: {}, DifficultyId: {}), skipped", spawnId, difficultyId);
10896 if (!fields[2].IsNull())
10898 if (!fields[3].IsNull())
10900 if (!fields[4].IsNull())
10902 if (!fields[5].IsNull())
10904 if (!fields[6].IsNull())
10906 if (!fields[7].IsNull())
10908 if (!fields[8].IsNull())
10910 if (!fields[9].IsNull())
10914 }
while (result->NextRow());
10926 TC_LOG_INFO(
"server.loading",
">> Query data caching is disabled. Skipped initialization.");
10934 for (
auto& creatureTemplatePair : _creatureTemplateStore)
10935 pool.
PostWork([creature = &creatureTemplatePair.second]() { creature->InitializeQueryData(); });
10939 for (
auto& gameObjectTemplatePair : _gameObjectTemplateStore)
10940 pool.
PostWork([gobj = &gameObjectTemplatePair.second]() { gobj->InitializeQueryData(); });
10944 for (
auto& questTemplatePair : _questTemplates)
10945 pool.
PostWork([quest = questTemplatePair.second.get()]() { quest->InitializeQueryData(); });
10949 for (
auto& poiWrapperPair : _questPOIStore)
10950 pool.
PostWork([poi = &poiWrapperPair.second]() { poi->InitializeQueryData(); });
10960 tempBuffer << *
this;
10963 QueryDataBuffer = std::move(tempBuffer).Release();
10969 _sceneTemplateStore.clear();
10971 QueryResult templates =
WorldDatabase.Query(
"SELECT SceneId, Flags, ScriptPackageID, Encrypted, ScriptName FROM scene_template");
10975 TC_LOG_INFO(
"server.loading",
">> Loaded 0 scene templates. DB table `scene_template` is empty.");
10981 Field* fields = templates->Fetch();
10984 SceneTemplate& sceneTemplate = _sceneTemplateStore[sceneId];
10985 sceneTemplate.
SceneId = sceneId;
10989 sceneTemplate.
ScriptId = GetScriptId(fields[4].GetStringView());
10991 }
while (templates->NextRow());
10999 _playerChoices.clear();
11001 QueryResult choices =
WorldDatabase.Query(
"SELECT ChoiceId, UiTextureKitId, SoundKitId, CloseSoundKitId, Duration, Question, PendingChoiceText, "
11002 "InfiniteRange, HideWarboardHeader, KeepOpenAfterChoice, ShowChoicesAsList, RequiresSelection, ShowChoicesAsGrid, HideAnswerArt, "
11003 "ShowChoicesAsColumns, MaxResponses, ScriptName FROM playerchoice");
11006 TC_LOG_INFO(
"server.loading",
">> Loaded 0 player choices. DB table `playerchoice` is empty.");
11010 uint32 responseCount = 0;
11012 uint32 itemRewardCount = 0;
11013 uint32 currencyRewardCount = 0;
11014 uint32 factionRewardCount = 0;
11015 uint32 itemChoiceRewardCount = 0;
11016 uint32 mawPowersCount = 0;
11022 (InfiniteRange)(HideWarboardHeader)(KeepOpenAfterChoice)(ShowChoicesAsList)(RequiresSelection)(ShowChoicesAsGrid)(HideAnswerArt)
11023 (ShowChoicesAsColumns)(MaxResponses)(ScriptName)) fields { *choices };
11025 int32 choiceId = fields.ChoiceId().GetInt32();
11030 choice.
SoundKitId = fields.SoundKitId().GetUInt32();
11032 if (!fields.Duration().IsNull())
11034 choice.
Question = fields.Question().GetStringView();
11044 choice.
MaxResponses = fields.MaxResponses().GetUInt32OrNull();
11045 choice.
ScriptId = GetScriptId(fields.ScriptName().GetStringView());
11047 }
while (choices->NextRow());
11050 if (
QueryResult responses =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, NULL, ChoiceArtFileId, Flags, WidgetSetID, "
11051 "UiTextureAtlasElementID, SoundKitID, GroupID, UiTextureKitID, Answer, Header, SubHeader, ButtonTooltip, Description, Confirmation, RewardQuestID "
11052 "FROM playerchoice_response ORDER BY `Index` ASC"))
11057 (GroupID)(UiTextureKitID)(Answer)(
Header)(SubHeader)(ButtonTooltip)(
Description)(Confirmation)(RewardQuestID)) fields{ *responses };
11059 int32 choiceId = fields.ChoiceId().GetInt32();
11060 int32 responseId = fields.ResponseId().GetInt32();
11065 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11075 response.
WidgetSetID = fields.WidgetSetID().GetUInt32();
11077 response.
SoundKitID = fields.SoundKitID().GetUInt32();
11078 response.
GroupID = fields.GroupID().GetUInt8();
11080 response.
Answer = fields.Answer().GetStringView();
11081 response.
Header = fields.Header().GetStringView();
11082 response.
SubHeader = fields.SubHeader().GetStringView();
11083 response.
ButtonTooltip = fields.ButtonTooltip().GetStringView();
11084 response.
Description = fields.Description().GetStringView();
11085 response.
Confirmation = fields.Confirmation().GetStringView();
11086 response.
RewardQuestID = fields.RewardQuestID().GetUInt32OrNull();
11090 }
while (responses->NextRow());
11093 if (
QueryResult rewards =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, TitleId, PackageId, SkillLineId, SkillPointCount, ArenaPointCount, HonorPointCount, Money, Xp FROM playerchoice_response_reward"))
11098 (SkillPointCount)(ArenaPointCount)(HonorPointCount)(
Money)(Xp)) fields{ *rewards };
11100 int32 choiceId = fields.ChoiceId().GetInt32();
11101 int32 responseId = fields.ResponseId().GetInt32();
11106 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11111 if (responseItr == choice->
Responses.end())
11113 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11118 reward->
TitleId = fields.TitleId().GetInt32();
11119 reward->
PackageId = fields.PackageId().GetInt32();
11120 reward->
SkillLineId = fields.SkillLineId().GetInt32();
11124 reward->
Money = fields.Money().GetUInt64();
11125 reward->
Xp = fields.Xp().GetUInt32();
11130 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward` references non-existing Title {} for ChoiceId {}, ResponseId: {}, set to 0",
11131 reward->
TitleId, choiceId, responseId);
11137 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward` references non-existing QuestPackage {} for ChoiceId {}, ResponseId: {}, set to 0",
11138 reward->
TitleId, choiceId, responseId);
11144 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward` references non-existing SkillLine {} for ChoiceId {}, ResponseId: {}, set to 0",
11145 reward->
TitleId, choiceId, responseId);
11150 }
while (rewards->NextRow());
11153 if (
QueryResult rewards =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, ItemId, BonusListIDs, Quantity FROM playerchoice_response_reward_item ORDER BY `Index` ASC"))
11159 int32 choiceId = fields.ChoiceId().GetInt32();
11160 int32 responseId = fields.ResponseId().GetInt32();
11161 uint32 itemId = fields.ItemId().GetUInt32();
11162 std::vector<int32> bonusListIds;
11163 for (std::string_view token :
Trinity::Tokenize(fields.BonusListIDs().GetStringView(),
' ',
false))
11165 bonusListIds.push_back(*bonusListID);
11166 int32 quantity = fields.Quantity().GetInt32();
11171 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11176 if (responseItr == choice->
Responses.end())
11178 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11182 if (!responseItr->Reward)
11184 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item` references non-existing player choice reward for ChoiceId {}, ResponseId: {}, skipped",
11185 choiceId, responseId);
11189 if (!GetItemTemplate(itemId))
11191 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item` references non-existing item {} for ChoiceId {}, ResponseId: {}, skipped",
11192 itemId, choiceId, responseId);
11196 responseItr->Reward->Items.emplace_back(itemId, std::move(bonusListIds), quantity);
11199 }
while (rewards->NextRow());
11202 if (
QueryResult rewards =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, CurrencyId, Quantity FROM playerchoice_response_reward_currency ORDER BY `Index` ASC"))
11208 int32 choiceId = fields.ChoiceId().GetInt32();
11209 int32 responseId = fields.ResponseId().GetInt32();
11210 uint32 currencyId = fields.CurrencyId().GetUInt32();
11211 int32 quantity = fields.Quantity().GetInt32();
11216 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_currency` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11221 if (responseItr == choice->
Responses.end())
11223 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_currency` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11227 if (!responseItr->Reward)
11229 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_currency` references non-existing player choice reward for ChoiceId {}, ResponseId: {}, skipped",
11230 choiceId, responseId);
11236 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_currency` references non-existing currency {} for ChoiceId {}, ResponseId: {}, skipped",
11237 currencyId, choiceId, responseId);
11241 responseItr->Reward->Currency.emplace_back(currencyId, quantity);
11242 ++currencyRewardCount;
11244 }
while (rewards->NextRow());
11247 if (
QueryResult rewards =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, FactionId, Quantity FROM playerchoice_response_reward_faction ORDER BY `Index` ASC"))
11253 int32 choiceId = fields.ChoiceId().GetInt32();
11254 int32 responseId = fields.ResponseId().GetInt32();
11255 uint32 factionId = fields.FactionId().GetUInt32();
11256 int32 quantity = fields.Quantity().GetInt32();
11261 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_faction` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11266 if (responseItr == choice->
Responses.end())
11268 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_faction` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11272 if (!responseItr->Reward)
11274 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_faction` references non-existing player choice reward for ChoiceId {}, ResponseId: {}, skipped",
11275 choiceId, responseId);
11281 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_faction` references non-existing faction {} for ChoiceId {}, ResponseId: {}, skipped",
11282 factionId, choiceId, responseId);
11286 responseItr->Reward->Faction.emplace_back(factionId, quantity);
11287 ++factionRewardCount;
11289 }
while (rewards->NextRow());
11292 if (
QueryResult rewards =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, ItemId, BonusListIDs, Quantity FROM playerchoice_response_reward_item_choice ORDER BY `Index` ASC"))
11298 int32 choiceId = fields.ChoiceId().GetInt32();
11299 int32 responseId = fields.ResponseId().GetInt32();
11300 uint32 itemId = fields.ItemId().GetUInt32();
11301 std::vector<int32> bonusListIds;
11302 for (std::string_view token :
Trinity::Tokenize(fields.BonusListIDs().GetStringView(),
' ',
false))
11304 bonusListIds.push_back(*bonusListID);
11305 int32 quantity = fields.Quantity().GetInt32();
11310 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item_choice` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11315 if (responseItr == choice->
Responses.end())
11317 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item_choice` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11321 if (!responseItr->Reward)
11323 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item_choice` references non-existing player choice reward for ChoiceId {}, ResponseId: {}, skipped",
11324 choiceId, responseId);
11328 if (!GetItemTemplate(itemId))
11330 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item_choice` references non-existing item {} for ChoiceId {}, ResponseId: {}, skipped",
11331 itemId, choiceId, responseId);
11335 responseItr->Reward->ItemChoices.emplace_back(itemId, std::move(bonusListIds), quantity);
11336 ++itemChoiceRewardCount;
11338 }
while (rewards->NextRow());
11341 if (
QueryResult mawPowersResult =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, TypeArtFileID, Rarity, SpellID, MaxStacks FROM playerchoice_response_maw_power"))
11347 int32 choiceId = fields.ChoiceId().GetInt32();
11348 int32 responseId = fields.ResponseId().GetInt32();
11353 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_maw_power` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11358 if (responseItr == choice->
Responses.end())
11360 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_maw_power` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11365 mawPower.
TypeArtFileID = fields.TypeArtFileID().GetInt32();
11366 mawPower.
Rarity = fields.Rarity().GetInt32OrNull();
11367 mawPower.
SpellID = fields.SpellID().GetInt32();
11368 mawPower.
MaxStacks = fields.MaxStacks().GetInt32();
11372 }
while (mawPowersResult->NextRow());
11375 TC_LOG_INFO(
"server.loading",
">> Loaded {} player choices, {} responses, {} rewards, {} item rewards, {} currency rewards, {} faction rewards, {} item choice rewards and {} maw powers in {} ms.",
11376 _playerChoices.size(), responseCount, rewardCount, itemRewardCount, currencyRewardCount, factionRewardCount, itemChoiceRewardCount, mawPowersCount,
GetMSTimeDiffToNow(oldMSTime));
11384 _playerChoiceLocales.clear();
11391 Field* fields = result->Fetch();
11396 if (!GetPlayerChoice(choiceId))
11398 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_locale` references non-existing ChoiceId: {} for locale {}, skipped", choiceId, localeName);
11407 AddLocaleString(fields[2].GetStringView(), locale, data.
Question);
11408 }
while (result->NextRow());
11410 TC_LOG_INFO(
"server.loading",
">> Loaded {} Player Choice locale strings in {} ms", _playerChoiceLocales.size(),
GetMSTimeDiffToNow(oldMSTime));
11416 if (
QueryResult result =
WorldDatabase.Query(
"SELECT ChoiceID, ResponseID, locale, Answer, Header, SubHeader, ButtonTooltip, Description, Confirmation FROM playerchoice_response_locale"))
11418 std::size_t count = 0;
11421 Field* fields = result->Fetch();
11427 auto itr = _playerChoiceLocales.find(choiceId);
11428 if (itr == _playerChoiceLocales.end())
11430 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_locale` references non-existing ChoiceId: {} for ResponseId {} locale {}, skipped",
11431 choiceId, responseId, localeName);
11438 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_locale` references non-existing ResponseId: {} for ChoiceId {} locale {}, skipped",
11439 responseId, choiceId, localeName);
11448 AddLocaleString(fields[3].GetStringView(), locale, data.
Answer);
11449 AddLocaleString(fields[4].GetStringView(), locale, data.
Header);
11450 AddLocaleString(fields[5].GetStringView(), locale, data.
SubHeader);
11451 AddLocaleString(fields[6].GetStringView(), locale, data.
ButtonTooltip);
11452 AddLocaleString(fields[7].GetStringView(), locale, data.
Description);
11453 AddLocaleString(fields[8].GetStringView(), locale, data.
Confirmation);
11455 }
while (result->NextRow());
11466 _uiMapQuestLinesStore.clear();
11473 TC_LOG_INFO(
"server.loading",
">> Loaded 0 questlines for UIMaps. DB table `ui_map_quest_line` is empty!");
11481 Field* fields = result->Fetch();
11488 TC_LOG_ERROR(
"sql.sql",
"Table `ui_map_quest_line` references non-existing UIMap {}, skipped", uiMapId);
11494 TC_LOG_ERROR(
"sql.sql",
"Table `ui_map_quest_line` references empty or non-existing questline {}, skipped", questLineId);
11498 _uiMapQuestLinesStore[uiMapId].push_back(questLineId);
11501 }
while (result->NextRow());
11516 _uiMapQuestsStore.clear();
11523 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quests for UIMaps. DB table `ui_map_quest` is empty!");
11531 Field* fields = result->Fetch();
11538 TC_LOG_ERROR(
"sql.sql",
"Table `ui_map_quest` references non-existing UIMap {}, skipped", uiMapId);
11542 if (!GetQuestTemplate(questId))
11544 TC_LOG_ERROR(
"sql.sql",
"Table `ui_map_quest` references non-existing quest {}, skipped", questId);
11548 _uiMapQuestsStore[uiMapId].push_back(questId);
11551 }
while (result->NextRow());
11566 _spawnTrackingDataStore.clear();
11569 QueryResult result =
WorldDatabase.Query(
"SELECT SpawnTrackingId, MapId, PhaseId, PhaseGroup, PhaseUseFlags FROM spawn_tracking_template");
11573 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spawn tracking templates. DB table `spawn_tracking_template` is empty!");
11579 Field* fields = result->Fetch();
11586 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_template` references non-existing map {}, skipped", mapId);
11592 data.
MapId = mapId;
11599 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_template` has spawn tracking (Id: {}) with `PhaseId` and `PhaseGroup` set, `PhaseGroup` set to 0", data.
SpawnTrackingId);
11607 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_template` has spawn tracking (Id: {}) referencing non-existing `PhaseId` {}, set to 0", data.
SpawnTrackingId, data.
PhaseId);
11623 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_template` has spawn tracking (Id: {}) referencing unknown `PhaseUseFlags`, removed unknown value.", data.
SpawnTrackingId);
11629 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_template` has spawn tracking (Id: {}) with `PhaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE,"
11634 }
while (result->NextRow());
11636 TC_LOG_INFO(
"server.loading",
">> Loaded {} spawn tracking templates in {} ms", _spawnTrackingDataStore.size(),
GetMSTimeDiffToNow(oldMSTime));
11657 _spawnTrackingQuestObjectiveStore.clear();
11660 QueryResult result =
WorldDatabase.Query(
"SELECT SpawnTrackingId, QuestObjectiveId FROM spawn_tracking_quest_objective");
11664 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spawn tracking quest objectives. DB table `spawn_tracking_quest_objective` is empty!");
11672 Field* fields = result->Fetch();
11677 if (!GetSpawnTrackingData(spawnTrackingId))
11679 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_quest_objective` has quest objective {} assigned to spawn tracking {}, but spawn tracking does not exist!", objectiveId, spawnTrackingId);
11683 QuestObjective const* questObjective = GetQuestObjective(objectiveId);
11684 if (!questObjective)
11686 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_quest_objective` has quest objective {} assigned to spawn tracking {}, but quest objective does not exist!", objectiveId, spawnTrackingId);
11690 _spawnTrackingQuestObjectiveStore[spawnTrackingId].push_back(questObjective);
11693 }
while (result->NextRow());
11703 _spawnTrackingMapStore.clear();
11706 QueryResult result =
WorldDatabase.Query(
"SELECT SpawnTrackingId, SpawnType, SpawnId, QuestObjectiveIds FROM spawn_tracking");
11710 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spawn tracking members. DB table `spawn_tracking` is empty!");
11718 Field* fields = result->Fetch();
11725 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking` has spawn data with invalid type {} listed for spawn tracking {}. Skipped.",
uint32(spawnType), spawnTrackingId);
11730 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking` has areatrigger spawn ({}) listed for spawn tracking {}. Skipped.",
uint32(spawnType), spawnTrackingId);
11734 SpawnMetadata const* data = GetSpawnMetadata(spawnType, spawnId);
11737 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking` has spawn ({},{}) not found, but is listed as a member of spawn tracking {}!",
uint32(spawnType), spawnId, spawnTrackingId);
11742 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking` has spawn ({},{}) is listed as a member of spawn tracking {}, but is already a member of spawn tracking {}. Skipped.",
11748 if (!spawnTrackingTemplateData)
11750 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking` has spawn tracking {} assigned to spawn ({},{}), but spawn tracking does not exist!", spawnTrackingId,
uint32(spawnType), spawnId);
11754 if (spawnTrackingTemplateData->
MapId != data->
mapId)
11756 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking` has spawn tracking {} (map {}) assigned to spawn ({},{}), but spawn has map {} - spawn NOT added to spawn tracking!",
11757 spawnTrackingId, spawnTrackingTemplateData->
MapId,
uint32(spawnType), spawnId, data->
mapId);
11764 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking` has spawn tracking {} with phase info (PhaseId: {}, PhaseGroup: {}, PhaseUseFlags: {}), ",
11765 "but spawn ({},{}) has different phase info (PhaseId: {}, PhaseGroup: {}, PhaseUseFlags: {}) - spawn NOT added to spawn tracking!",
11771 std::vector<uint32> objectiveList;
11774 for (std::string_view objectiveStr :
Trinity::Tokenize(*objectivesStr,
',',
false))
11780 if (!IsQuestObjectiveForSpawnTracking(spawnTrackingId, *objectiveId))
11782 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking` has spawn tracking {} assigned to spawn ({},{}), but spawn tracking is not linked to quest objective {}. Skipped.", spawnTrackingId,
uint32(spawnType), spawnId, objectiveId);
11786 objectiveList.push_back(*objectiveId);
11789 if (objectiveList.empty())
11791 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking` has spawn tracking {} assigned to spawn ({},{}), but spawn tracking is not linked to any quest objective - spawn NOT added to spawn tracking!", spawnTrackingId,
uint32(spawnType), spawnId);
11796 const_cast<SpawnMetadata*
>(data)->spawnTrackingData = spawnTrackingTemplateData;
11797 const_cast<SpawnMetadata*
>(data)->spawnTrackingQuestObjectives = std::move(objectiveList);
11798 _spawnTrackingMapStore.emplace(spawnTrackingId, data);
11801 }
while (result->NextRow());
11811 QueryResult result =
WorldDatabase.Query(
"SELECT SpawnType, SpawnId, State, Visible, StateSpellVisualId, StateAnimId, StateAnimKitId, StateWorldEffects FROM spawn_tracking_state");
11815 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spawn tracking states. DB table `spawn_tracking_state` is empty!");
11823 Field* fields = result->Fetch();
11830 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` has spawn data with invalid type {}. Skipped.",
uint32(spawnType));
11835 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` has areatrigger spawn ({}). Skipped.",
uint32(spawnType));
11839 SpawnMetadata const* data = GetSpawnMetadata(spawnType, spawnId);
11842 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` has spawn ({},{}) not found!",
uint32(spawnType), spawnId);
11847 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` has spawn ({},{}) with spawn tracking states, but is not part of a spawn tracking. Skipped.",
uint32(spawnType), spawnId);
11853 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` has spawn ({},{}) with invalid state type {}. Skipped.",
uint32(spawnType), spawnId,
uint8(state));
11865 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` references invalid StateSpellVisualId {} for spawn ({},{}), set to none.",
11872 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` references invalid StateAnimId {} for spawn ({},{}), set to none.",
11879 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` references invalid StateAnimKitId {} for spawn ({},{}), set to none.",
11886 for (std::string_view worldEffectStr :
Trinity::Tokenize(*worldEffectsStr,
',',
false))
11888 Optional<uint32> worldEffectId = Trinity::StringTo<uint32>(worldEffectStr);
11889 if (!worldEffectId)
11894 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` references invalid WorldEffectId {} for spawn ({},{}). Skipped.",
11895 *worldEffectId,
uint32(spawnType), spawnId);
11904 }
while (result->NextRow());
11914 _jumpChargeParams.clear();
11916 QueryResult result =
WorldDatabase.Query(
"SELECT id, speed, treatSpeedAsMoveTimeSeconds, minHeight, maxHeight, unlimitedSpeed, spellVisualId, progressCurveId, parabolicCurveId, triggerSpellId FROM jump_charge_params");
11923 (spellVisualId)(progressCurveId)(parabolicCurveId)(triggerSpellId)) fields { *result };
11927 int32 id = fields.id().GetInt32();
11930 params.TreatSpeedAsMoveTimeSeconds = fields.treatSpeedAsMoveTimeSeconds().GetBool();
11931 params.UnlimitedSpeed = fields.unlimitedSpeed().GetBool();
11932 params.MinHeight = fields.minHeight().GetFloatOrNull();
11933 params.MaxHeight = fields.maxHeight().GetFloatOrNull();
11934 params.SpellVisualId = fields.spellVisualId().GetInt32OrNull();
11935 params.ProgressCurveId = fields.progressCurveId().GetInt32OrNull();
11936 params.ParabolicCurveId = fields.parabolicCurveId().GetInt32OrNull();
11937 params.TriggerSpellId = fields.triggerSpellId().GetInt32OrNull();
11939 if (
params.Speed <= 0.0f)
11941 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` uses invalid speed {} for id {}, set to default charge speed {}.",
11948 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` uses invalid min height {} for id {}, set to none.",
11950 params.MinHeight.reset();
11955 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` uses invalid max height {} for id {}, set to none.",
11957 params.MaxHeight.reset();
11962 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` uses invalid max height {} (must be greated than min height {}) for id {}, set to none.",
11964 params.MaxHeight.reset();
11969 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` references non-existing SpellVisual: {} for id {}, ignored.",
11970 *
params.SpellVisualId,
id);
11971 params.SpellVisualId.reset();
11976 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` references non-existing progress Curve: {} for id {}, ignored.",
11977 *
params.ProgressCurveId,
id);
11978 params.ProgressCurveId.reset();
11983 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` references non-existing parabolic Curve: {} for id {}, ignored.",
11984 *
params.ParabolicCurveId,
id);
11985 params.ParabolicCurveId.reset();
11990 TC_LOG_DEBUG(
"sql.sql",
"Table `jump_charge_params` references non-existing trigger spell id: {} for id {}, ignored.",
11991 *
params.TriggerSpellId,
id);
11992 params.TriggerSpellId.reset();
11995 }
while (result->NextRow());
11997 TC_LOG_INFO(
"server.loading",
">> Loaded {} Player Choice locale strings in {} ms", _jumpChargeParams.size(),
GetMSTimeDiffToNow(oldMSTime));
12003 _phaseNameStore.clear();
12010 TC_LOG_INFO(
"server.loading",
">> Loaded 0 phase names. DB table `phase_name` is empty.");
12017 Field* fields = result->Fetch();
12020 std::string name = fields[1].
GetString();
12022 _phaseNameStore[phaseId] = name;
12025 }
while (result->NextRow());
12031 PhaseNameContainer::const_iterator iter = _phaseNameStore.find(phaseId);
12032 return iter != _phaseNameStore.end() ? iter->second :
"Unknown Name";
#define sAreaTriggerDataStore
@ CHAR_DEL_EMPTY_EXPIRED_MAIL
@ CHAR_SEL_EXPIRED_MAIL_ITEMS
@ CHAR_DEL_MAIL_ITEM_BY_ID
@ CHAR_UPD_MAIL_ITEM_RECEIVER
LocaleConstant GetLocaleByName(std::string_view name)
constexpr bool IsValidLocale(LocaleConstant locale)
const uint8 OLD_TOTAL_LOCALES
@ CONDITION_SOURCE_TYPE_PLAYER_CONDITION
@ CONDITION_SOURCE_TYPE_GRAVEYARD
#define sCreatureAIRegistry
@ CREATURE_FLAG_EXTRA_DB_ALLOWED
@ CREATURE_FLAG_EXTRA_TRIGGER
@ CREATURE_FLAG_EXTRA_INSTANCE_BIND
CreatureChaseMovementType
const uint8 MAX_KILL_CREDIT
@ CREATURE_STATIC_FLAG_5_INTERACT_WHILE_HOSTILE
@ CREATURE_STATIC_FLAG_CAN_SWIM
@ CREATURE_STATIC_FLAG_3_CANT_SWIM
@ CREATURE_STATIC_FLAG_3_ALLOW_INTERACTION_WHILE_IN_COMBAT
@ CREATURE_STATIC_FLAG_3_CANNOT_TURN
@ CREATURE_STATIC_FLAG_4_AI_WILL_ONLY_SWIM_IF_TARGET_SWIMS
CreatureRandomMovementType
const uint32 MAX_CREATURE_SPELLS
DB2Storage< PhaseEntry > sPhaseStore("Phase.db2", &PhaseLoadInfo::Instance)
DB2Storage< SkillRaceClassInfoEntry > sSkillRaceClassInfoStore("SkillRaceClassInfo.db2", &SkillRaceClassInfoLoadInfo::Instance)
DB2Storage< DifficultyEntry > sDifficultyStore("Difficulty.db2", &DifficultyLoadInfo::Instance)
DB2Storage< GameObjectDisplayInfoEntry > sGameObjectDisplayInfoStore("GameObjectDisplayInfo.db2", &GameobjectDisplayInfoLoadInfo::Instance)
DB2Storage< CharacterLoadoutEntry > sCharacterLoadoutStore("CharacterLoadout.db2", &CharacterLoadoutLoadInfo::Instance)
DB2Storage< SpellVisualEntry > sSpellVisualStore("SpellVisual.db2", &SpellVisualLoadInfo::Instance)
DB2Storage< ItemEntry > sItemStore("Item.db2", &ItemLoadInfo::Instance)
DB2Storage< SkillLineEntry > sSkillLineStore("SkillLine.db2", &SkillLineLoadInfo::Instance)
DB2Storage< AnimationDataEntry > sAnimationDataStore("AnimationData.db2", &AnimationDataLoadInfo::Instance)
DB2Storage< FriendshipReputationEntry > sFriendshipReputationStore("FriendshipReputation.db2", &FriendshipReputationLoadInfo::Instance)
DB2Storage< GameObjectsEntry > sGameObjectsStore("GameObjects.db2", &GameobjectsLoadInfo::Instance)
DB2Storage< AchievementEntry > sAchievementStore("Achievement.db2", &AchievementLoadInfo::Instance)
DB2Storage< CurveEntry > sCurveStore("Curve.db2", &CurveLoadInfo::Instance)
DB2Storage< MapEntry > sMapStore("Map.db2", &MapLoadInfo::Instance)
DB2Storage< TaxiNodesEntry > sTaxiNodesStore("TaxiNodes.db2", &TaxiNodesLoadInfo::Instance)
DB2Storage< CreatureModelDataEntry > sCreatureModelDataStore("CreatureModelData.db2", &CreatureModelDataLoadInfo::Instance)
DB2Storage< CreatureFamilyEntry > sCreatureFamilyStore("CreatureFamily.db2", &CreatureFamilyLoadInfo::Instance)
DB2Storage< CharacterLoadoutItemEntry > sCharacterLoadoutItemStore("CharacterLoadoutItem.db2", &CharacterLoadoutItemLoadInfo::Instance)
DB2Storage< AnimKitEntry > sAnimKitStore("AnimKit.db2", &AnimKitLoadInfo::Instance)
DB2Storage< MapDifficultyEntry > sMapDifficultyStore("MapDifficulty.db2", &MapDifficultyLoadInfo::Instance)
DB2Storage< CreatureTypeEntry > sCreatureTypeStore("CreatureType.db2", &CreatureTypeLoadInfo::Instance)
DB2Storage< CriteriaEntry > sCriteriaStore("Criteria.db2", &CriteriaLoadInfo::Instance)
TaxiPathNodesByPath sTaxiPathNodesByPath
DB2Storage< ItemXItemEffectEntry > sItemXItemEffectStore("ItemXItemEffect.db2", &ItemXItemEffectLoadInfo::Instance)
DB2Storage< ChrClassesEntry > sChrClassesStore("ChrClasses.db2", &ChrClassesLoadInfo::Instance)
DB2Storage< VehicleSeatEntry > sVehicleSeatStore("VehicleSeat.db2", &VehicleSeatLoadInfo::Instance)
DB2Storage< LockEntry > sLockStore("Lock.db2", &LockLoadInfo::Instance)
DB2Storage< CharTitlesEntry > sCharTitlesStore("CharTitles.db2", &CharTitlesLoadInfo::Instance)
DB2Storage< ChrSpecializationEntry > sChrSpecializationStore("ChrSpecialization.db2", &ChrSpecializationLoadInfo::Instance)
DB2Storage< Cfg_CategoriesEntry > sCfgCategoriesStore("Cfg_Categories.db2", &CfgCategoriesLoadInfo::Instance)
DB2Storage< GossipNPCOptionEntry > sGossipNPCOptionStore("GossipNPCOption.db2", &GossipNpcOptionLoadInfo::Instance)
DB2Storage< QuestSortEntry > sQuestSortStore("QuestSort.db2", &QuestSortLoadInfo::Instance)
DB2Storage< ItemEffectEntry > sItemEffectStore("ItemEffect.db2", &ItemEffectLoadInfo::Instance)
DB2Storage< CriteriaTreeEntry > sCriteriaTreeStore("CriteriaTree.db2", &CriteriaTreeLoadInfo::Instance)
DB2Storage< BattlePetSpeciesEntry > sBattlePetSpeciesStore("BattlePetSpecies.db2", &BattlePetSpeciesLoadInfo::Instance)
DB2Storage< AreaTriggerEntry > sAreaTriggerStore("AreaTrigger.db2", &AreaTriggerLoadInfo::Instance)
DB2Storage< MailTemplateEntry > sMailTemplateStore("MailTemplate.db2", &MailTemplateLoadInfo::Instance)
DB2Storage< EmotesEntry > sEmotesStore("Emotes.db2", &EmotesLoadInfo::Instance)
DB2Storage< UiMapEntry > sUiMapStore("UiMap.db2", &UiMapLoadInfo::Instance)
DB2Storage< LFGDungeonsEntry > sLFGDungeonsStore("LFGDungeons.db2", &LfgDungeonsLoadInfo::Instance)
DB2Storage< TaxiPathNodeEntry > sTaxiPathNodeStore("TaxiPathNode.db2", &TaxiPathNodeLoadInfo::Instance)
DB2Storage< SpellFocusObjectEntry > sSpellFocusObjectStore("SpellFocusObject.db2", &SpellFocusObjectLoadInfo::Instance)
DB2Storage< BroadcastTextEntry > sBroadcastTextStore("BroadcastText.db2", &BroadcastTextLoadInfo::Instance)
DB2Storage< GameObjectArtKitEntry > sGameObjectArtKitStore("GameObjectArtKit.db2", &GameobjectArtKitLoadInfo::Instance)
DB2Storage< ItemExtendedCostEntry > sItemExtendedCostStore("ItemExtendedCost.db2", &ItemExtendedCostLoadInfo::Instance)
DB2Storage< SpellEffectEntry > sSpellEffectStore("SpellEffect.db2", &SpellEffectLoadInfo::Instance)
DB2Storage< VignetteEntry > sVignetteStore("Vignette.db2", &VignetteLoadInfo::Instance)
DB2Storage< CurrencyTypesEntry > sCurrencyTypesStore("CurrencyTypes.db2", &CurrencyTypesLoadInfo::Instance)
DB2Storage< LanguagesEntry > sLanguagesStore("Languages.db2", &LanguagesLoadInfo::Instance)
DB2Storage< GemPropertiesEntry > sGemPropertiesStore("GemProperties.db2", &GemPropertiesLoadInfo::Instance)
DB2Storage< WorldEffectEntry > sWorldEffectStore("WorldEffect.db2", &WorldEffectLoadInfo::Instance)
DB2Storage< ChrRacesEntry > sChrRacesStore("ChrRaces.db2", &ChrRacesLoadInfo::Instance)
DB2Storage< ParagonReputationEntry > sParagonReputationStore("ParagonReputation.db2", &ParagonReputationLoadInfo::Instance)
DB2Storage< PlayerConditionEntry > sPlayerConditionStore("PlayerCondition.db2", &PlayerConditionLoadInfo::Instance)
DB2Storage< CreatureDisplayInfoEntry > sCreatureDisplayInfoStore("CreatureDisplayInfo.db2", &CreatureDisplayInfoLoadInfo::Instance)
DB2Storage< ContentTuningEntry > sContentTuningStore("ContentTuning.db2", &ContentTuningLoadInfo::Instance)
DB2Storage< MovieEntry > sMovieStore("Movie.db2", &MovieLoadInfo::Instance)
DB2Storage< ItemSparseEntry > sItemSparseStore("ItemSparse.db2", &ItemSparseLoadInfo::Instance)
DB2Storage< FactionTemplateEntry > sFactionTemplateStore("FactionTemplate.db2", &FactionTemplateLoadInfo::Instance)
DB2Storage< SoundKitEntry > sSoundKitStore("SoundKit.db2", &SoundKitLoadInfo::Instance)
DB2Storage< ItemSpecEntry > sItemSpecStore("ItemSpec.db2", &ItemSpecLoadInfo::Instance)
DB2Storage< AreaTableEntry > sAreaTableStore("AreaTable.db2", &AreaTableLoadInfo::Instance)
DB2Storage< FactionEntry > sFactionStore("Faction.db2", &FactionLoadInfo::Instance)
DB2Storage< VehicleEntry > sVehicleStore("Vehicle.db2", &VehicleLoadInfo::Instance)
@ ITEM_SPEC_STAT_TWO_HANDED_MACE
@ ITEM_SPEC_STAT_INTELLECT
@ ITEM_SPEC_STAT_RELIC_FROST
@ ITEM_SPEC_STAT_RELIC_BLOOD
@ ITEM_SPEC_STAT_STRENGTH
@ ITEM_SPEC_STAT_ONE_HANDED_AXE
@ ITEM_SPEC_STAT_BONUS_ARMOR
@ ITEM_SPEC_STAT_RELIC_HOLY
@ ITEM_SPEC_STAT_RELIC_WIND
@ ITEM_SPEC_STAT_RELIC_FIRE
@ ITEM_SPEC_STAT_FIST_WEAPON
@ ITEM_SPEC_STAT_TWO_HANDED_SWORD
@ ITEM_SPEC_STAT_RELIC_FEL
@ ITEM_SPEC_STAT_RELIC_WATER
@ ITEM_SPEC_STAT_ONE_HANDED_MACE
@ ITEM_SPEC_STAT_RELIC_SHADOW
@ ITEM_SPEC_STAT_WARGLAIVES
@ ITEM_SPEC_STAT_RELIC_LIFE
@ ITEM_SPEC_STAT_RELIC_ARCANE
@ ITEM_SPEC_STAT_CROSSBOW
@ ITEM_SPEC_STAT_TWO_HANDED_AXE
@ ITEM_SPEC_STAT_RELIC_IRON
@ ITEM_SPEC_STAT_ONE_HANDED_SWORD
@ PHASE_USE_FLAGS_ALWAYS_VISIBLE
@ PHASE_USE_FLAGS_INVERSE
#define MAX_ITEM_PROTO_STATS
@ AnyoneTriggerGameEventScenario
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
std::shared_ptr< ResultSet > QueryResult
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
std::unordered_set< uint32 > params[2]
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
std::chrono::seconds Seconds
Seconds shorthand typedef.
#define ASSERT_NOTNULL(pointer)
#define sGameObjectAIRegistry
#define MAX_NUMBER_OF_GRIDS
@ ITEM_VENDOR_TYPE_CURRENCY
@ ITEM_FLAG2_FACTION_HORDE
@ ITEM_FLAG2_FACTION_ALLIANCE
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
@ ITEM_SUBCLASS_WEAPON_GUN
@ ITEM_SUBCLASS_WEAPON_AXE2
@ ITEM_SUBCLASS_WEAPON_STAFF
@ ITEM_SUBCLASS_WEAPON_MACE
@ ITEM_SUBCLASS_WEAPON_WARGLAIVES
@ ITEM_SUBCLASS_WEAPON_MACE2
@ ITEM_SUBCLASS_WEAPON_DAGGER
@ ITEM_SUBCLASS_WEAPON_BOW
@ ITEM_SUBCLASS_WEAPON_SWORD
@ ITEM_SUBCLASS_WEAPON_AXE
@ ITEM_SUBCLASS_WEAPON_FIST_WEAPON
@ ITEM_SUBCLASS_WEAPON_WAND
@ ITEM_SUBCLASS_WEAPON_THROWN
@ ITEM_SUBCLASS_WEAPON_SWORD2
@ ITEM_SUBCLASS_WEAPON_POLEARM
@ ITEM_MOD_CRIT_SPELL_RATING
@ ITEM_MOD_CRIT_RANGED_RATING
@ ITEM_MOD_CRIT_MELEE_RATING
@ ITEM_SUBCLASS_ARMOR_MAIL
@ ITEM_SUBCLASS_ARMOR_CLOTH
@ ITEM_SUBCLASS_ARMOR_RELIC
@ ITEM_SUBCLASS_ARMOR_LEATHER
@ ITEM_SUBCLASS_ARMOR_SHIELD
@ ITEM_SUBCLASS_ARMOR_PLATE
@ SOCKET_COLOR_RELIC_WIND
@ SOCKET_COLOR_RELIC_FIRE
@ SOCKET_COLOR_RELIC_LIFE
@ SOCKET_COLOR_RELIC_ARCANE
@ SOCKET_COLOR_RELIC_SHADOW
@ SOCKET_COLOR_RELIC_FROST
@ SOCKET_COLOR_RELIC_IRON
@ SOCKET_COLOR_RELIC_WATER
@ SOCKET_COLOR_RELIC_HOLY
@ SOCKET_COLOR_RELIC_BLOOD
constexpr std::array< InventoryType, 10 > InventoryTypesEquipable
#define MAX_ITEM_SUBCLASS_WEAPON
@ ITEM_SUBCLASS_FOOD_DRINK
@ LANG_ITEM_ALREADY_IN_LIST
@ LANG_COMMAND_VENDORSELECTION
@ LANG_EXTENDED_COST_NOT_EXIST
#define TC_LOG_DEBUG(filterType__, message__,...)
#define TC_LOG_ERROR(filterType__, message__,...)
#define TC_LOG_INFO(filterType__, message__,...)
LootStore LootTemplates_Gameobject("gameobject_loot_template", "gameobject entry", true)
@ MAIL_CHECK_MASK_COD_PAYMENT
This mail is payable on delivery.
@ MAIL_CHECK_MASK_RETURNED
This mail was returned. Do not allow returning mail back again.
@ MAIL_CHECK_MASK_NOT_RETURNABLE
This mail cannot be returned even if mail was not returned before.
std::vector< MailItemInfo > MailItemInfoVec
#define MAX_NPC_TEXT_OPTIONS
#define DEFAULT_PLAYER_COMBAT_REACH
#define DEFAULT_VISIBILITY_DISTANCE
@ TEMPSUMMON_MANUAL_DESPAWN
#define INTERACTION_DISTANCE
#define DEFAULT_PLAYER_DISPLAY_SCALE
uint64 MAKE_PAIR64(uint32 l, uint32 h)
uint16 MAKE_PAIR16(uint8 l, uint8 h)
void CheckAndFixGOChairHeightId(GameObjectTemplate const *goInfo, uint32 &dataN, uint32 N)
static EnumFlag< CfgCategoriesCharsets > GetRealmLanguageType(bool create)
#define ChooseCreatureFlagSource(field)
void CheckGONoDamageImmuneId(GameObjectTemplate *goTemplate, uint32 dataN, uint32 N)
void CheckGOSpellId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
ScriptMapMap * GetScriptsMapByType(ScriptsType type)
std::string GetScriptCommandName(ScriptCommands command)
bool isValidString(const std::wstring &wstr, uint32 strictMask, bool numericOrSpace, bool create=false)
uint32 FillMaxDurability(uint32 itemClass, uint32 itemSubClass, uint32 inventoryType, uint32 quality, uint32 itemLevel)
ScriptMapMap sEventScripts
void CheckGOConsumable(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
void CheckGOLinkedTrapId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
void CheckGOLockId(GameObjectTemplate const *goInfo, uint32 dataN, uint32 N)
std::string GetScriptsTableNameByType(ScriptsType type)
ExtendedPlayerName ExtractExtendedPlayerName(std::string const &name)
bool normalizePlayerName(std::string &name)
std::vector< PlayerCreateInfoItem > PlayerCreateInfoItems
std::pair< GraveyardContainer::const_iterator, GraveyardContainer::const_iterator > GraveyardMapBounds
std::multimap< uint32, ScriptInfo > ScriptMap
SkillRangeType GetSkillRangeType(SkillRaceClassInfoEntry const *rcEntry)
std::pair< SpellScriptsContainer::iterator, SpellScriptsContainer::iterator > SpellScriptsBounds
ScriptMapMap * GetScriptsMapByType(ScriptsType type)
@ SCRIPT_COMMAND_CREATE_ITEM
@ SCRIPT_COMMAND_DESPAWN_SELF
@ SCRIPT_COMMAND_CLOSE_DOOR
@ SCRIPT_COMMAND_CAST_SPELL
@ SCRIPT_COMMAND_RESPAWN_GAMEOBJECT
@ SCRIPT_COMMAND_QUEST_EXPLORED
@ SCRIPT_COMMAND_ACTIVATE_OBJECT
@ SCRIPT_COMMAND_OPEN_DOOR
@ SCRIPT_COMMAND_PLAYMOVIE
@ SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT
@ SCRIPT_COMMAND_PLAY_ANIMKIT
@ SCRIPT_COMMAND_TELEPORT_TO
@ SCRIPT_COMMAND_FIELD_SET_DEPRECATED
@ SCRIPT_COMMAND_FLAG_REMOVE_DEPRECATED
@ SCRIPT_COMMAND_TEMP_SUMMON_CREATURE
@ SCRIPT_COMMAND_MOVEMENT
@ SCRIPT_COMMAND_KILL_CREDIT
@ SCRIPT_COMMAND_LOAD_PATH
@ SCRIPT_COMMAND_ORIENTATION
@ SCRIPT_COMMAND_PLAY_SOUND
@ SCRIPT_COMMAND_CLOSE_GOSSIP
@ SCRIPT_COMMAND_REMOVE_AURA
@ SCRIPT_COMMAND_FLAG_SET_DEPRECATED
std::string GetScriptCommandName(ScriptCommands command)
std::unordered_map< uint32, GridObjectGuids > GridObjectGuidsMap
#define SPAWNGROUP_MAP_UNSET
TC_GAME_API ScriptMapMap sEventScripts
std::pair< GossipMenusContainer::const_iterator, GossipMenusContainer::const_iterator > GossipMenusMapBounds
std::map< uint32, ScriptMap > ScriptMapMap
@ SUMMONER_TYPE_GAMEOBJECT
std::string GetScriptsTableNameByType(ScriptsType type)
std::multimap< uint32, uint32 > QuestRelationsReverse
std::multimap< uint32, uint32 > QuestRelations
std::optional< T > Optional
Optional helper class to wrap optional values within.
PlayerChoiceResponseFlags
#define DEFINE_FIELD_ACCESSOR_CACHE_ANONYMOUS(result_type, fields_list)
#define QUEST_ITEM_DROP_COUNT
#define QUEST_REWARD_ITEM_COUNT
#define QUEST_REWARD_REPUTATIONS_COUNT
@ QUEST_OBJECTIVE_DEFEATBATTLEPET
@ QUEST_OBJECTIVE_WINPVPPETBATTLES
@ QUEST_OBJECTIVE_INCREASE_REPUTATION
@ QUEST_OBJECTIVE_HAVE_CURRENCY
@ QUEST_OBJECTIVE_WINPETBATTLEAGAINSTNPC
@ QUEST_OBJECTIVE_MONSTER
@ QUEST_OBJECTIVE_KILL_WITH_LABEL
@ QUEST_OBJECTIVE_CRITERIA_TREE
@ QUEST_OBJECTIVE_OBTAIN_CURRENCY
@ QUEST_OBJECTIVE_PROGRESS_BAR
@ QUEST_OBJECTIVE_PLAYERKILLS
@ QUEST_OBJECTIVE_MAX_REPUTATION
@ QUEST_OBJECTIVE_AREA_TRIGGER_EXIT
@ QUEST_OBJECTIVE_AREATRIGGER
@ QUEST_OBJECTIVE_CURRENCY
@ QUEST_OBJECTIVE_LEARNSPELL
@ QUEST_OBJECTIVE_AREA_TRIGGER_ENTER
@ QUEST_OBJECTIVE_GAMEOBJECT
@ QUEST_OBJECTIVE_MIN_REPUTATION
#define QUEST_REWARD_CURRENCY_COUNT
@ QUEST_OBJECTIVE_FLAG_SEQUENCED
#define QUEST_REWARD_CHOICES_COUNT
@ QUEST_FLAGS_COMPLETION_AREA_TRIGGER
@ QUEST_FLAGS_COMPLETION_EVENT
@ QUEST_FLAGS_TRACKING_EVENT
@ QUEST_SPECIAL_FLAGS_SEQUENCED_OBJECTIVES
@ QUEST_SPECIAL_FLAGS_REPEATABLE
@ QUEST_SPECIAL_FLAGS_DB_ALLOWED
@ QUEST_SPECIAL_FLAGS_MONTHLY
constexpr Trinity::RaceMask< uint64 > RACEMASK_ALL_PLAYABLE
uint32 urand(uint32 min, uint32 max)
#define MAX_REPUTATION_RANK
#define CURRENT_EXPANSION
@ SPELL_EFFECT_SEND_EVENT
static constexpr uint8 MAX_UNIT_CLASSES
#define MAX_GO_STATE_TRANSPORT_STOP_FRAMES
@ SKILL_CATEGORY_LANGUAGES
@ GAMEOBJECT_TYPE_SPELL_FOCUS
@ GAMEOBJECT_TYPE_TRANSPORT
@ GAMEOBJECT_TYPE_GENERIC
@ GAMEOBJECT_TYPE_FISHINGHOLE
@ GAMEOBJECT_TYPE_FLAGDROP
@ GAMEOBJECT_TYPE_QUESTGIVER
@ GAMEOBJECT_TYPE_SPELLCASTER
@ GAMEOBJECT_TYPE_FLAGSTAND
@ GAMEOBJECT_TYPE_AREADAMAGE
@ GAMEOBJECT_TYPE_FISHINGNODE
@ GAMEOBJECT_TYPE_BARBER_CHAIR
@ GAMEOBJECT_TYPE_MAP_OBJ_TRANSPORT
@ GAMEOBJECT_TYPE_GARRISON_BUILDING
@ GAMEOBJECT_TYPE_GATHERING_NODE
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
constexpr uint32 GetMaxLevelForExpansion(uint32 expansion)
@ CHAR_NAME_THREE_CONSECUTIVE
@ CHAR_NAME_INVALID_CHARACTER
@ CHAR_NAME_MIXED_LANGUAGES
@ TOTAL_INVISIBILITY_TYPES
@ MAX_DB_ALLOWED_QUEST_TYPES
constexpr uint32 SkillByQuestSort(int32 QuestSort)
@ SPELL_CLICK_USER_FRIEND
#define MAX_GAMEOBJECT_DATA
#define CLASSMASK_ALL_PLAYABLE
@ PET_NAME_MIXED_LANGUAGES
#define CLASSMASK_ALL_CREATURES
@ EXPANSION_LEVEL_CURRENT
@ CHAT_MSG_RAID_BOSS_WHISPER
@ GO_STATE_TRANSPORT_ACTIVE
#define MAX_SPILLOVER_FACTIONS
@ SPAWNGROUP_FLAG_MANUAL_SPAWN
@ SPAWNGROUP_FLAG_COMPATIBILITY_MODE
@ LINKED_RESPAWN_CREATURE_TO_GO
@ LINKED_RESPAWN_GO_TO_GO
@ LINKED_RESPAWN_CREATURE_TO_CREATURE
@ LINKED_RESPAWN_GO_TO_CREATURE
@ SPELL_AURA_CONTROL_VEHICLE
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
@ UNIT_FLAG2_AI_WILL_ONLY_SWIM_IF_TARGET_SWIMS
@ UNIT_FLAG2_INTERACT_WHILE_HOSTILE
@ UNIT_STAND_STATE_SIT_HIGH_CHAIR
@ UNIT_STAND_STATE_SIT_LOW_CHAIR
#define MAX_DECLINED_NAME_CASES
@ UNIT_NPC_FLAG_QUESTGIVER
@ UNIT_NPC_FLAG_SPELLCLICK
@ UNIT_FLAG3_ALLOW_INTERACTION_WHILE_IN_COMBAT
#define MAX_EQUIPMENT_ITEMS
@ UNIT_FLAG_IMMUNE_TO_NPC
float DegToRad(float degrees)
std::wstring GetMainPartOfName(std::wstring const &wname, uint32 declension)
bool WStrToUtf8(wchar_t const *wstr, size_t size, std::string &utf8str)
void wstrToLower(std::wstring &str)
bool Utf8toWStr(char const *utf8str, size_t csize, wchar_t *wstr, size_t &wsize)
bool isKoreanString(std::wstring_view wstr, bool numericOrSpace)
bool isCyrillicString(std::wstring_view wstr, bool numericOrSpace)
bool isChineseString(std::wstring_view wstr, bool numericOrSpace)
bool isBasicLatinString(std::wstring_view wstr, bool numericOrSpace)
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
bool isExtendedLatinString(std::wstring_view wstr, bool numericOrSpace)
struct WcharToUpper wcharToUpper
std::vector< VehicleAccessory > VehicleAccessoryList
@ WORLD_INS_GRAVEYARD_ZONE
@ WORLD_SEL_NPC_VENDOR_REF
@ WORLD_REP_LINKED_RESPAWN
@ WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA
@ WORLD_UPD_CREATURE_ZONE_AREA_DATA
@ WORLD_DEL_LINKED_RESPAWN
@ WORLD_SEL_CREATURE_TEMPLATE
std::strong_ordering operator<=>(WowTime const &left, WowTime const &right)
static void DeleteFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
static void DeleteFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
ObjectGuid const & GetGUID() const
void PSendSysMessage(char const *fmt, Args &&... args)
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
bool HasFlag(CreatureStaticFlags flag) const
static float GetDamageMod(CreatureClassifications classification)
static char const * GetCreatureFamilyPetName(uint32 petfamily, LocaleConstant locale)
constexpr bool HasFlag(T flag) const
Class used to access individual fields of database query result.
float GetFloat() const noexcept
Optional< uint16 > GetUInt16OrNull() const noexcept
Optional< uint64 > GetUInt64OrNull() const noexcept
Optional< float > GetFloatOrNull() const noexcept
uint64 GetUInt64() const noexcept
int16 GetInt16() const noexcept
bool GetBool() const noexcept
uint32 GetUInt32() const noexcept
Optional< int32 > GetInt32OrNull() const noexcept
uint16 GetUInt16() const noexcept
std::string_view GetStringView() const noexcept
bool IsNull() const noexcept
uint8 GetUInt8() const noexcept
int32 GetInt32() const noexcept
Optional< uint32 > GetUInt32OrNull() const noexcept
std::string GetString() const noexcept
int8 GetInt8() const noexcept
int64 GetInt64() const noexcept
static void DeleteFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
bool HaveQuestLootFor(uint32 loot_id) const
static bool IsValidMapCoord(uint32 mapid, float x, float y)
static bool IsValidMAP(uint32 mapId)
void Set(ObjectGuid::LowType val)
std::unordered_set< std::string > GetAllDBScriptNames() const
void reserve(size_t capacity)
uint32 insert(std::string_view scriptName, bool isScriptNameBound=true)
NameMap::const_iterator find(size_t index) const
NameMap::const_iterator end() const
static void ChooseCreatureFlags(CreatureTemplate const *cInfo, uint64 *npcFlags, uint32 *unitFlags, uint32 *unitFlags2, uint32 *unitFlags3, CreatureStaticFlagsHolder const &staticFlags, CreatureData const *data=nullptr)
std::unordered_map< uint32, AreaTriggerPolygon > _areaTriggerPolygons
std::set< uint32 > EventContainer
CreatureMovementData const * GetCreatureMovementOverride(ObjectGuid::LowType spawnId) const
QuestOfferRewardLocaleContainer _questOfferRewardLocaleStore
uint32 LoadReferenceVendor(int32 vendor, int32 item_id, std::set< uint32 > *skip_vendors)
Trainer::Trainer const * GetTrainer(uint32 trainerId) const
std::unordered_set< std::string > GetAllDBScriptNames() const
AccessRequirement const * GetAccessRequirement(uint32 mapid, Difficulty difficulty) const
void LoadQuestRelationsHelper(QuestRelations &map, QuestRelationsReverse *reverseMap, std::string const &table)
EquipmentInfo const * GetEquipmentInfo(uint32 entry, int8 &id) const
TempSummonDataContainer _tempSummonDataStore
Stores temp summon data grouped by summoner's entry, summoner's type and group id.
QuestRelations _creatureQuestInvolvedRelations
PetLevelInfo const * GetPetLevelInfo(uint32 creature_id, uint8 level) const
void LoadCreatureTemplateResistances()
VehicleAccessoryList const * GetVehicleAccessoryList(Vehicle *veh) const
VehicleAccessoryContainer _vehicleAccessoryStore
int32 GetFishingBaseSkillLevel(AreaTableEntry const *areaEntry) const
bool HasPersonalSpawns(uint32 mapid, Difficulty spawnMode, uint32 phaseId) const
uint32 GetXPForLevel(uint8 level) const
void LoadCreatureTemplate(Field *fields)
GameObjectTemplateAddonContainer _gameObjectTemplateAddonStore
CreatureBaseStats const * GetCreatureBaseStats(uint8 level, uint8 unitClass)
void LoadCreatureTemplateSpells()
ObjectGuid::LowType GenerateGameObjectSpawnId()
InstanceTemplate const * GetInstanceTemplate(uint32 mapId) const
TrinityString const * GetTrinityString(uint32 entry) const
QuestObjectivesByIdContainer _questObjectives
MapPersonalObjectGuids _mapPersonalObjectGuidsStore
void LoadQuestTemplateLocale()
void LoadReputationOnKill()
std::vector< PhaseAreaInfo > const * GetPhasesForArea(uint32 areaId) const
void LoadGameObjectTemplate()
CreatureAddon const * GetCreatureTemplateAddon(uint32 entry) const
void LoadFactionChangeSpells()
void LoadFactionChangeItems()
void LoadAreaTriggerTeleports()
WorldSafeLocsEntry const * GetClosestGraveyardInZone(WorldLocation const &location, uint32 team, WorldObject *conditionObject, uint32 zoneId) const
QuestGreetingLocale const * GetQuestGreetingLocale(TypeID type, uint32 id) const
std::unordered_map< std::pair< Races, Classes >, std::unique_ptr< PlayerInfo > > _playerInfo
CreatureQuestCurrenciesMap _creatureQuestCurrenciesStore
void LoadPageTextLocales()
AreaTriggerTeleport const * GetGoBackTrigger(uint32 Map) const
HalfNameContainer _petHalfName1
void LoadVehicleTemplate()
void LoadInstanceTemplate()
CreatureTemplateSparringContainer _creatureTemplateSparringStore
void LoadItemScriptNames()
uint32 GetTaxiMountDisplayId(uint32 id, uint32 team, bool allowed_alt_team=false)
SpellScriptsContainer _spellScriptsStore
SpawnGroupDataContainer _spawnGroupDataStore
QuestPOIData const * GetQuestPOIData(int32 questId)
WorldSafeLocsEntry const * GetDefaultGraveyard(uint32 team) const
void RemoveSpawnDataFromGrid(SpawnData const *data)
void LoadQuestGreetingLocales()
CreatureDataContainer _creatureDataStore
void ValidateSpellScripts()
void LoadCreatureQuestEnders()
QuestRelations _goQuestRelations
void LoadSceneTemplates()
void LoadGameobjectQuestEnders()
void LoadCreatureMovementOverrides()
void LoadCreatureLocales()
void LoadDestructibleHitpoints()
TavernAreaTriggerContainer _tavernAreaTriggerStore
void LoadCreatureClassLevelStats()
PlayerInfo const * GetPlayerInfo(uint32 race, uint32 class_) const
void LoadCreatureTemplates()
GameObjectTemplateAddon const * GetGameObjectTemplateAddon(uint32 entry) const
CreatureStaticFlagsOverride const * GetCreatureStaticFlagsOverride(ObjectGuid::LowType spawnId, Difficulty difficultyId) const
Trinity::IteratorPair< std::unordered_map< uint32, WorldSafeLocsEntry >::const_iterator > GetWorldSafeLocs() const
PageTextLocaleContainer _pageTextLocaleStore
EquipmentInfoContainer _equipmentInfoStore
ObjectGuid::LowType _gameObjectSpawnId
void GetPlayerClassLevelInfo(uint32 class_, uint8 level, uint32 &baseMana) const
AccessRequirementContainer _accessRequirementStore
JumpChargeParams const * GetJumpChargeParams(int32 id) const
void LoadQuestAreaTriggers()
QuestGreetingLocaleContainer _questGreetingLocaleStore
SpawnData const * GetSpawnData(SpawnObjectType type, ObjectGuid::LowType spawnId) const
std::unordered_map< uint32, SkillTiersEntry > _skillTiers
CreatureTemplateContainer _creatureTemplateStore
bool AddGameTele(GameTele &data)
std::vector< uint32 > const * GetUiMapQuestLinesList(uint32 uiMapId) const
static bool CheckDeclinedNames(const std::wstring &w_ownname, DeclinedName const &names)
void LoadQuestOfferRewardLocale()
void LoadFactionChangeAchievements()
SpawnTrackingLinkContainer _spawnTrackingMapStore
static void AddLocaleString(std::string_view value, LocaleConstant localeConstant, std::vector< std::string > &data)
void LoadGameObjectOverrides()
SpellScriptsBounds GetSpellScriptsBounds(uint32 spellId)
void LoadGossipMenuAddon()
QuestRequestItemsLocaleContainer _questRequestItemsLocaleStore
std::map< HighGuid, ObjectGuidGenerator > _guidGenerators
PlayerChoice const * GetPlayerChoice(int32 choiceId) const
QuestGreetingContainer _questGreetingStore
SpawnGroupTemplateData const * GetLegacySpawnGroup() const
void LoadFactionChangeReputations()
void RemoveCreatureFromGrid(CreatureData const *data)
std::set< uint32 > _transportMaps
std::unordered_map< ObjectGuid::LowType, CreatureMovementData > _creatureMovementOverrides
GraveyardContainer GraveyardStore
std::string const & GetScriptName(uint32 id) const
GameObjectTemplateContainer _gameObjectTemplateStore
void LoadReputationSpilloverTemplate()
void LoadExplorationBaseXP()
void LoadFishingBaseSkillLevel()
InstanceSpawnGroupContainer _instanceSpawnGroupStore
uint32 GetScriptId(std::string_view name, bool isDatabaseBound=true)
void LoadQuestRequestItemsLocale()
EventScriptContainer _eventScriptStore
void LoadQuestObjectivesLocale()
void UnloadPhaseConditions()
void GetPlayerLevelInfo(uint32 race, uint32 class_, uint8 level, PlayerLevelInfo *info) const
std::vector< int32 > const * GetCreatureQuestCurrencyList(uint32 creatureId) const
PhaseInfoStruct const * GetPhaseInfo(uint32 phaseId) const
void LoadAreaTriggerPolygons()
CreatureAddon const * GetCreatureAddon(ObjectGuid::LowType lowguid) const
void LoadEquipmentTemplates()
GameObjectData const * GetGameObjectData(ObjectGuid::LowType spawnId) const
bool IsValidEvent(uint32 eventId) const
RaceUnlockRequirement const * GetRaceUnlockRequirement(uint8 raceId) const
NpcText const * GetNpcText(uint32 textID) const
void LoadCreatureStaticFlagsOverride()
QuestRelationsReverse _creatureQuestInvolvedRelationsReverse
ItemTemplateContainer _itemTemplateStore
void LoadQuestStartersAndEnders()
GameObjectOverride const * GetGameObjectOverride(ObjectGuid::LowType spawnId) const
static PetNameInvalidReason CheckPetName(std::string_view name)
GameObjectDataContainer _gameObjectDataStore
void LoadSpawnGroupTemplates()
AreaTriggerTeleport const * GetAreaTrigger(uint32 trigger) const
void LoadUiMapQuestLines()
void LoadGraveyardZones()
uint32 GeneratePetNumber()
CreatureSummonedData const * GetCreatureSummonedData(uint32 entryId) const
uint32 GetNearestTaxiNode(float x, float y, float z, uint32 mapid, uint32 team)
void LoadTerrainWorldMaps()
void LoadGossipMenuItemsLocales()
CreatureLocaleContainer _creatureLocaleStore
void CheckCreatureTemplate(CreatureTemplate const *cInfo)
std::atomic< uint32 > _hiPetNumber
bool IsReservedName(std::string_view name) const
void AddCreatureToGrid(CreatureData const *data)
std::unordered_map< uint32, std::vector< uint32 > > _spawnGroupsByMap
std::atomic< uint64 > _mailId
void RemoveGameobjectFromGrid(GameObjectData const *data)
GameTele const * GetGameTeleExactName(std::string_view name) const
void LoadCreatureSummonedData()
PointOfInterestLocaleContainer _pointOfInterestLocaleStore
InstanceTemplateContainer _instanceTemplateStore
void LoadTerrainSwapDefaults()
bool DeleteGameTele(std::string_view name)
ObjectGuid::LowType GenerateCreatureSpawnId()
QuestRelations _goQuestInvolvedRelations
void LoadCreatureQuestItems()
void LoadNPCSpellClickSpells()
QuestAreaTriggerContainer _questAreaTriggerStore
FishingBaseSkillContainer _fishingBaseForAreaStore
bool IsTransportMap(uint32 mapId) const
ObjectGuid::LowType _creatureSpawnId
AreaTriggerContainer _areaTriggerStore
GridObjectGuids const * GetCellPersonalObjectGuids(uint32 mapid, Difficulty spawnMode, uint32 phaseId, uint32 gridId) const
void LoadAccessRequirements()
MapObjectGuids _mapObjectGuidsStore
CreatureAddonContainer _creatureAddonStore
void LoadSpawnTrackingStates()
PetLevelInfoContainer _petInfoStore
static CreatureModel const * ChooseDisplayId(CreatureTemplate const *cinfo, CreatureData const *data=nullptr)
VehicleAccessoryTemplateContainer _vehicleTemplateAccessoryStore
static ObjectMgr * instance()
void LoadVehicleTemplateAccessories()
void DeleteGameObjectData(ObjectGuid::LowType spawnId)
void LoadJumpChargeParams()
WorldSafeLocsEntry const * GetWorldSafeLoc(uint32 id) const
TerrainSwapInfo const * GetTerrainSwapInfo(uint32 terrainSwapId) const
std::vector< uint32 > const * GetUiMapQuestsList(uint32 uiMapId) const
HalfNameContainer _petHalfName0
void LoadSpawnTrackings()
void LoadGameObjectLocales()
bool IsQuestObjectiveForSpawnTracking(uint32 spawnTrackingId, uint32 questObjectiveId) const
void LoadQuestGreetings()
NpcTextContainer _npcTextStore
QuestContainer _questTemplates
void PlayerCreateInfoAddItemHelper(uint32 race_, uint32 class_, uint32 itemId, int32 count)
CreatureModelInfo const * GetCreatureModelRandomGender(CreatureModel *model, CreatureTemplate const *creatureTemplate) const
PageText const * GetPageText(uint32 pageEntry)
void LoadCreatureTemplateAddons()
SpawnTrackingTemplateData const * GetSpawnTrackingData(uint32 spawnTrackingId) const
static ResponseCodes CheckPlayerName(std::string_view name, LocaleConstant locale, bool create=false)
uint32 GetCreatureTrainerForGossipOption(uint32 creatureId, uint32 gossipMenuId, uint32 gossipOptionId) const
bool RemoveVendorItem(uint32 entry, uint32 item, uint8 type, bool persist=true)
std::vector< Quest const * > _questTemplatesAutoPush
ObjectGuidGenerator & GetGuidSequenceGenerator(HighGuid high)
uint32 GetBaseXP(uint8 level)
CreatureTemplateAddonContainer _creatureTemplateAddonStore
static bool IsValidCharterName(std::string_view name)
std::unordered_map< uint32, VehicleTemplate > _vehicleTemplateStore
GameObjectTemplate const * GetGameObjectTemplate(uint32 entry) const
GridObjectGuids const * GetGridObjectGuids(uint32 mapid, Difficulty spawnMode, uint32 gridId)
GossipMenuItemsLocaleContainer _gossipMenuItemsLocaleStore
BaseXPContainer _baseXPTable
void LoadGameObjectTemplateAddons()
DestructibleHitpoint const * GetDestructibleHitpoint(uint32 entry) const
void LoadTavernAreaTriggers()
void LoadReputationRewardRate()
AreaTriggerPolygon const * GetAreaTriggerPolygon(uint32 areaTriggerId) const
AreaTriggerScriptContainer _areaTriggerScriptStore
void CheckCreatureMovement(char const *table, uint64 id, CreatureMovementData &creatureMovement)
QuestRelations _creatureQuestRelations
ClassAvailability const * GetClassExpansionRequirementFallback(uint8 classId) const
void AddSpawnDataToGrid(SpawnData const *data)
SceneTemplate const * GetSceneTemplate(uint32 sceneId) const
Quest const * GetQuestTemplate(uint32 quest_id) const
void LoadCreatureQuestCurrencies()
VehicleTemplate const * GetVehicleTemplate(Vehicle *veh) const
GameObjectAddon const * GetGameObjectAddon(ObjectGuid::LowType lowguid) const
void LoadGameobjectQuestStarters()
void LoadScripts(ScriptsType type)
RepOnKillContainer _repOnKillStore
void LoadGameObjectForQuests()
GridObjectGuidsMap const * GetMapObjectGuids(uint32 mapid, Difficulty spawnMode)
void LoadFactionChangeTitles()
uint32 GetAreaTriggerScriptId(uint32 trigger_id) const
SpawnGroupLinkContainer _spawnGroupMapStore
std::string GetPhaseName(uint32 phaseId) const
RepSpilloverTemplateContainer _repSpilloverTemplateStore
void LoadSpawnTrackingTemplates()
void LoadAreaTriggerScripts()
bool SetCreatureLinkedRespawn(ObjectGuid::LowType guid, ObjectGuid::LowType linkedGuid)
SpawnMetadata const * GetSpawnMetadata(SpawnObjectType type, ObjectGuid::LowType spawnId) const
void AddVendorItem(uint32 entry, VendorItem const &vItem, bool persist=true)
void ReturnOrDeleteOldMails(bool serverUp)
void LoadGameObjectAddons()
SpawnGroupTemplateData const * GetDefaultSpawnGroup() const
GameObjectData & NewOrExistGameObjectData(ObjectGuid::LowType spawnId)
CreatureModelInfo const * GetCreatureModelInfo(uint32 modelId) const
CreatureModelContainer _creatureModelStore
LinkedRespawnContainer _linkedRespawnStore
uint64 GenerateEquipmentSetGuid()
void GetTaxiPath(uint32 source, uint32 destination, uint32 &path, uint32 &cost)
void DeleteCreatureData(ObjectGuid::LowType spawnId)
void LoadCreatureTemplateSparring()
GameObjectLocaleContainer _gameObjectLocaleStore
GameObjectAddonContainer _gameObjectAddonStore
QuestObjectivesLocaleContainer _questObjectivesLocaleStore
void LoadCreatureQuestStarters()
bool IsScriptDatabaseBound(uint32 id) const
GameTele const * GetGameTele(uint32 id) const
void LoadInstanceSpawnGroups()
void LoadItemTemplateAddon()
PlayerXPperLevel _playerXPperLevel
QuestRelationsReverse _goQuestInvolvedRelationsReverse
void LoadSpellScriptNames()
CreatureTemplate const * GetCreatureTemplate(uint32 entry) const
void LoadMailLevelRewards()
void BuildPlayerLevelInfo(uint8 race, uint8 class_, uint8 level, PlayerLevelInfo *plinfo) const
CreatureData const * GetCreatureData(ObjectGuid::LowType spawnId) const
void AddGameobjectToGrid(GameObjectData const *data)
PointOfInterestContainer _pointsOfInterestStore
void LoadGameObjectQuestItems()
std::vector< Difficulty > ParseSpawnDifficulties(std::string_view difficultyString, std::string_view table, ObjectGuid::LowType spawnId, uint32 mapId, std::set< Difficulty > const &mapDifficulties)
void LoadPointsOfInterest()
void LoadFactionChangeQuests()
RepRewardRateContainer _repRewardRateStore
EventContainer _eventStore
uint32 GenerateAuctionID()
std::string GeneratePetName(uint32 entry)
void LoadCreatureTemplateGossip()
void LoadPointOfInterestLocales()
VehicleSeatAddonContainer _vehicleSeatAddonStore
QuestTemplateLocaleContainer _questTemplateLocaleStore
bool LoadTrinityStrings()
std::vector< float > const * GetCreatureTemplateSparringValues(uint32 entry) const
void LoadCreatureTemplateModels()
CreatureData & NewOrExistCreatureData(ObjectGuid::LowType spawnId)
std::vector< uint32 > const * GetCreatureQuestItemList(uint32 creatureEntry, Difficulty difficulty) const
PageTextContainer _pageTextStore
void LoadGossipMenuItems()
void LoadCreatureTrainers()
ExclusiveQuestGroups _exclusiveQuestGroups
void LoadVehicleAccessories()
void LoadCreatureModelInfo()
ClassAvailability const * GetClassExpansionRequirement(uint8 raceId, uint8 classId) const
void LoadVehicleSeatAddon()
GraveyardData const * FindGraveyardData(uint32 id, uint32 zone) const
uint32 GetEventScriptId(uint32 eventId) const
void LoadCreatureTemplateDifficulty()
void InitializeQueriesData(QueryDataGroup mask)
void LoadReservedPlayersNames()
CreatureQuestItemMap _creatureQuestItemStore
void LoadRaceAndClassExpansionRequirements()
AreaTriggerTeleport const * GetMapEntranceTrigger(uint32 Map) const
QuestPOIContainer _questPOIStore
void OnDeleteSpawnData(SpawnData const *data)
DestructibleHitpointContainer _destructibleHitpointStore
void LoadSpawnTrackingQuestObjectives()
SpellClickInfoContainer _spellClickInfoStore
void LoadPlayerChoicesLocale()
QuestGreeting const * GetQuestGreeting(TypeID type, uint32 id) const
std::unordered_map< uint32, WorldSafeLocsEntry > _worldSafeLocs
bool IsVendorItemValid(uint32 vendor_entry, VendorItem const &vItem, Player *player=nullptr, std::set< uint32 > *skip_vendors=nullptr, uint32 ORnpcflag=0) const
void LoadCreatureAddons()
bool AddGraveyardLink(uint32 id, uint32 zoneId, uint32 team, bool persist=true)
GameObjectOverrideContainer _gameObjectOverrideStore
std::unordered_map< uint32, CreatureSummonedData > _creatureSummonedDataStore
SkillTiersEntry const * GetSkillTier(uint32 skillTierId) const
ItemTemplate const * GetItemTemplate(uint32 entry) const
WorldSafeLocsEntry const * GetClosestGraveyard(WorldLocation const &location, uint32 team, WorldObject *conditionObject) const
bool HasVisibleMapId(uint32 visibleMapId) const
static bool IsPersonalPhase(uint32 phaseId)
static PhaseShift const & GetEmptyPhaseShift()
static void InitDbVisibleMapId(PhaseShift &phaseShift, int32 visibleMapId)
WorldSession * GetSession() const
void setUInt16(uint8 index, uint16 value)
void setString(uint8 index, std::string &&value)
void setUInt32(uint8 index, uint32 value)
void setInt64(uint8 index, int64 value)
void setFloat(uint8 index, float value)
void setUInt64(uint8 index, uint64 value)
void setUInt8(uint8 index, uint8 value)
std::array< int32, QUEST_REWARD_REPUTATIONS_COUNT > RewardFactionValue
uint32 _requiredSkillPoints
std::array< LootItemType, QUEST_REWARD_CHOICES_COUNT > RewardChoiceItemType
std::vector< uint32 > DependentBreadcrumbQuests
Trinity::RaceMask< int32, 2 > _allowableRaces
std::array< uint32, QUEST_REWARD_CURRENCY_COUNT > RewardCurrencyId
int32 _breadcrumbForQuestId
void LoadQuestDetails(Field *fields)
std::array< uint32, QUEST_REWARD_CHOICES_COUNT > RewardChoiceItemCount
bool HasQuestObjectiveType(QuestObjectiveType type) const
void LoadRewardDisplaySpell(Field *fields)
uint32 _sourceItemIdCount
static bool IsTakingQuestEnabled(uint32 questId)
void LoadConditionalConditionalRequestItemsText(Field *fields)
std::array< uint32, QUEST_REWARD_CHOICES_COUNT > RewardChoiceItemId
uint32 _rewardSkillPoints
void LoadQuestRequestItems(Field *fields)
uint32 _requiredMinRepFaction
std::array< uint32, QUEST_REWARD_ITEM_COUNT > RewardItemId
int32 _requiredMinRepValue
void LoadConditionalConditionalQuestDescription(Field *fields)
std::array< uint32, QUEST_REWARD_ITEM_COUNT > RewardItemCount
void LoadQuestMailSender(Field *fields)
void LoadQuestObjective(Field *fields)
int32 GetPrevQuestId() const
void LoadConditionalConditionalOfferRewardText(Field *fields)
int32 _requiredMaxRepValue
uint32 GetQuestType() const
uint32 _requiredMaxRepFaction
std::vector< uint32 > DependentPreviousQuests
uint32 GetQuestId() const
void LoadQuestOfferReward(Field *fields)
std::array< uint32, QUEST_ITEM_DROP_COUNT > ItemDropQuantity
int32 GetBreadcrumbForQuestId() const
void LoadRewardHouseDecor(Field *fields)
void SetSpecialFlag(QuestSpecialFlags flag)
std::array< int32, QUEST_REWARD_REPUTATIONS_COUNT > RewardFactionOverride
std::array< uint32, QUEST_REWARD_REPUTATIONS_COUNT > RewardFactionId
QuestObjectives const & GetObjectives() const
std::array< uint32, QUEST_REWARD_CURRENCY_COUNT > RewardCurrencyCount
uint32 _rewardMailSenderEntry
std::array< uint32, QUEST_ITEM_DROP_COUNT > ItemDrop
void LoadRewardHouseRoom(Field *fields)
void LoadConditionalConditionalQuestCompletionLog(Field *fields)
bool HasFlag(QuestFlags flag) const
uint32 _rewardMailTemplateId
void LoadRewardChoiceItems(Field *fields)
void LoadTreasurePickers(Field *fields)
void LoadQuestTemplateAddon(Field *fields)
static const int32 Reputation_Cap
SpellInfo const * GetFirstRankSpell() const
int32 GetDuration() const
SpellInfo const * GetNextRankSpell() const
bool HasAura(AuraType aura) const
static bool IsSpellValid(SpellInfo const *spellInfo, Player *player=nullptr, bool msg=true)
Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book,...
Unit * GetSummonerUnit() const
std::pair< iterator, bool > emplace(Args &&... args)
Utility class to enable range for loop syntax for multimap.equal_range uses.
constexpr end_iterator end() const
constexpr iterator begin() const
decltype(auto) PostWork(T &&work)
TempSummon * ToTempSummon()
bool IsInRaidWith(Unit const *unit) const
bool IsInPartyWith(Unit const *unit) const
static VMapManager * createOrGetVMapManager()
uint32 GetCreatureEntry() const
constexpr void WorldRelocate(WorldLocation const &loc)
constexpr uint32 GetMapId() const
PhaseShift & GetPhaseShift()
std::string const & GetName() const
bool IsFriendlyTo(WorldObject const *target) const
static void StopNow(uint8 exitcode)
@ CONFIG_STRICT_PET_NAMES
@ CONFIG_MAX_PLAYER_LEVEL
@ CONFIG_MIN_CHARTER_NAME
@ CONFIG_STRICT_CHARTER_NAMES
@ CONFIG_STRICT_PLAYER_NAMES
@ CONFIG_CREATURE_CHECK_INVALID_POSITION
@ CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA
@ CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA
@ CONFIG_CACHE_DATA_QUERIES
@ CONFIG_GAME_OBJECT_CHECK_INVALID_POSITION
static constexpr ObjectData creatureData[]
static constexpr uint32 Entry[5]
bool IsDisabledFor(DisableType type, uint32 entry, WorldObject const *ref, uint8 flags)
std::span< ItemBonusEntry const * > GetItemBonuses(uint32 bonusListId)
TC_GAME_API Player * FindConnectedPlayer(ObjectGuid const &)
TC_GAME_API std::span< QuestLineXQuestEntry const *const > GetQuestsForQuestLine(uint32 questLineId)
ItemModifiedAppearanceEntry const * GetDefaultItemModifiedAppearance(uint32 itemId)
ItemModifiedAppearanceEntry const * GetItemModifiedAppearance(uint32 itemId, uint32 appearanceModId)
auto MapGetValuePtr(M &map, typename M::key_type const &key)
constexpr bool Intersects(Iterator1 first1, Sentinel1 last1, Iterator2 first2, Sentinel2 last2)
TC_COMMON_API std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
bool IsValidMapCoord(float c)
std::string StringFormat(FormatString< Args... > fmt, Args &&... args) noexcept
Default TC string format function.
Optional< Result > StringTo(std::string_view str, Params &&... params)
constexpr GridCoord ComputeGridCoord(float x, float y)
struct advstd::ranges::Contains contains
std::string questFailedText
std::vector< Position > Vertices
uint8 MinActiveExpansionLevel
uint8 AccountExpansionLevel
uint8 ActiveExpansionLevel
std::weak_ptr< ConditionContainer > Conditions
bool Meets(WorldObject const *object) const
constexpr uint32 GetId() const
std::vector< uint32 > auras
VisibilityDistanceType visibilityDistanceType
Optional< uint32 > curHealthPct
Optional< uint64 > npcflag
Optional< CreatureModel > display
Optional< uint32 > unit_flags2
Optional< uint32 > unit_flags3
Optional< uint32 > unit_flags
CreatureStaticFlagsHolder StaticFlags
int32 CreatureDifficultyID
int32 HealthScalingExpansion
std::vector< std::string > Title
std::vector< std::string > Name
std::vector< std::string > TitleAlt
std::vector< std::string > NameAlt
uint32 displayId_other_gender
CreatureRandomMovementType Random
bool HoverInitiallyEnabled
CreatureChaseMovementType Chase
uint32 InteractionPauseTimer
Optional< CreatureStaticFlags > StaticFlags1
Optional< CreatureStaticFlags5 > StaticFlags5
Optional< CreatureStaticFlags7 > StaticFlags7
Optional< CreatureStaticFlags3 > StaticFlags3
Optional< CreatureStaticFlags2 > StaticFlags2
Optional< CreatureStaticFlags6 > StaticFlags6
Optional< CreatureStaticFlags8 > StaticFlags8
Optional< CreatureStaticFlags4 > StaticFlags4
Optional< uint32 > CreatureIDVisibleToSummoner
Optional< uint32 > GroundMountDisplayID
Optional< std::vector< uint32 > > DespawnOnQuestsRemoved
Optional< uint32 > FlyingMountDisplayID
CreatureModel const * GetRandomValidModel() const
CreatureClassifications Classification
CreatureModel const * GetFirstInvisibleModel() const
int32 CreatureImmunitiesId
uint32 spells[MAX_CREATURE_SPELLS]
int32 resistance[MAX_SPELL_SCHOOL]
std::vector< uint32 > GossipMenuIds
CreatureMovementData Movement
uint32 KillCredit[MAX_KILL_CREDIT]
int32 WidgetSetUnitConditionID
std::vector< CreatureModel > Models
std::string name[MAX_DECLINED_NAME_CASES]
int16 FallbackDifficultyID
EquipmentItem Items[MAX_EQUIPMENT_ITEMS]
bool CanHaveReputation() const
QuaternionData ParentRotation
InvisibilityType invisibilityType
std::vector< std::string > Name
std::vector< std::string > Unk1
std::vector< std::string > CastBarCaption
std::array< uint32, 5 > ArtKits
struct GameObjectTemplate::@199::@216 moTransport
uint32 data[MAX_GAMEOBJECT_DATA]
struct GameObjectTemplate::@199::@209 spellFocus
struct GameObjectTemplate::@199::@266 raw
struct GameObjectTemplate::@199::@239 garrisonBuilding
struct GameObjectTemplate::@199::@226 fishingHole
struct GameObjectTemplate::@199::@211 goober
struct GameObjectTemplate::@199::@207 trap
struct GameObjectTemplate::@199::@208 chair
bool IsDespawnAtAction() const
struct GameObjectTemplate::@199::@234 destructibleBuilding
struct GameObjectTemplate::@199::@203 questgiver
struct GameObjectTemplate::@199::@213 areaDamage
struct GameObjectTemplate::@199::@233 barberChair
struct GameObjectTemplate::@199::@223 spellCaster
struct GameObjectTemplate::@199::@227 flagDrop
std::string castBarCaption
struct GameObjectTemplate::@199::@202 button
struct GameObjectTemplate::@199::@251 gatheringNode
struct GameObjectTemplate::@199::@204 chest
struct GameObjectTemplate::@199::@225 flagStand
struct GameObjectTemplate::@199::@201 door
ConditionsReference Conditions
std::array< int32, MAX_ITEM_PROTO_STATS > StatModifierBonusStat
ItemSpecStats(ItemEntry const *item, ItemSparseEntry const *sparse)
void AddModStat(int32 itemStatType)
uint32 ItemSpecStatTypes[MAX_ITEM_PROTO_STATS]
void AddStat(ItemSpecStat statType)
std::bitset< MAX_CLASSES *MAX_SPECIALIZATIONS > Specializations[3]
ItemEntry const * BasicData
static std::size_t CalculateItemSpecBit(ChrSpecializationEntry const *spec)
ItemSparseEntry const * ExtendedData
uint32 RandomBonusListTemplateId
ObjectGuid::LowType item_guid
ObjectGuid::LowType receiver
ObjectGuid::LowType sender
std::vector< MailItemInfo > items
bool Instanceable() const
NpcTextData Data[MAX_NPC_TEXT_OPTIONS]
std::vector< std::string > Text
std::vector< PathPropertyEntry const * > Properties
std::vector< DBCPosition3D > Locations
std::unordered_set< uint32 > Areas
bool IsAllowedInArea(uint32 areaId) const
std::vector< std::string > Question
std::vector< std::string > Confirmation
std::vector< std::string > SubHeader
std::vector< std::string > Header
std::vector< std::string > Description
std::vector< std::string > Answer
std::vector< std::string > ButtonTooltip
std::string ButtonTooltip
uint32 UiTextureAtlasElementID
Optional< uint32 > RewardQuestID
EnumFlag< PlayerChoiceResponseFlags > Flags
bool ShowChoicesAsColumns
std::vector< PlayerChoiceResponse > Responses
Optional< uint32 > MaxResponses
std::string PendingChoiceText
PlayerChoiceResponse const * GetResponse(int32 responseId) const
std::unique_ptr< PlayerLevelInfo[]> levelInfo
PlayerCreateInfoItems item
std::vector< std::string > Name
constexpr float GetPositionX() const
constexpr float GetPositionY() const
constexpr float GetExactDist2dSq(const float x, const float y) const
constexpr void GetPosition(float &x, float &y) const
constexpr void Relocate(float x, float y)
constexpr float GetExactDistSq(float x, float y, float z) const
constexpr float GetOrientation() const
constexpr float GetPositionZ() const
static QuaternionData fromOrientation(float orientation)
std::vector< std::string > Greeting
std::vector< std::string > Description
std::vector< std::string > RewardText
void InitializeQueryData()
std::vector< QuestPOIBlobData > Blobs
QuestRelations::const_iterator _it
QuestRelations::const_iterator _end
bool HasQuest(uint32 questId) const
QuestRelations::const_iterator _end
QuestRelations::const_iterator _begin
std::vector< std::string > CompletionText
std::vector< std::string > PortraitTurnInText
std::vector< std::string > QuestCompletionLog
std::vector< std::string > LogTitle
std::vector< std::string > PortraitGiverName
std::vector< std::string > PortraitTurnInName
std::vector< std::string > QuestDescription
std::vector< std::string > LogDescription
std::vector< std::string > PortraitGiverText
std::vector< std::string > AreaDescription
std::vector< ClassAvailability > Classes
float questRepeatableRate
uint32 faction_rank[MAX_SPILLOVER_FACTIONS]
uint32 faction[MAX_SPILLOVER_FACTIONS]
float faction_rate[MAX_SPILLOVER_FACTIONS]
EnumFlag< SceneFlag > PlaybackFlags
struct ScriptInfo::@272::@275 Talk
struct ScriptInfo::@272::@289 CreateItem
struct ScriptInfo::@272::@284 TempSummonCreature
struct ScriptInfo::@272::@286 RemoveAura
struct ScriptInfo::@272::@282 KillCredit
struct ScriptInfo::@272::@280 TeleportTo
struct ScriptInfo::@272::@287 CastSpell
struct ScriptInfo::@272::@299 PlayAnimKit
struct ScriptInfo::@272::@276 Emote
struct ScriptInfo::@272::@274 Raw
struct ScriptInfo::@272::@285 ToggleDoor
struct ScriptInfo::@272::@283 RespawnGameobject
struct ScriptInfo::@272::@281 QuestExplored
std::string GetDebugInfo() const
uint32 GetValueForTierIndex(uint32 tierIndex) const
uint32 Value[MAX_SKILL_STEP]
std::vector< Difficulty > spawnDifficulties
Optional< uint16 > StateAnimKitId
Optional< uint32 > StateSpellVisualId
std::vector< uint32 > StateWorldEffects
Optional< uint16 > StateAnimId
bool IsFitToRequirements(Unit const *clicker, Unit const *clickee) const
SpellClickUserTypes userType
std::array< int32, 2 > MountCreatureID
Stores data for temp summons.
Milliseconds time
Despawn time, usable only with certain temp summon types.
TempSummonType type
Summon type, see TempSummonType for available types.
uint32 entry
Entry of summoned creature.
Position pos
Position, where should be creature spawned.
Key for storing temp summon data in TempSummonDataContainer.
uint32 SummonerEntry
Summoner's entry.
std::vector< uint32 > UiMapPhaseIDs
std::array< uint32, 3 > ReqAbility
std::vector< std::string > Content
std::array< T, N > RawValue
constexpr bool HasRace(uint32 raceId) const
constexpr bool IsEmpty() const
EnumFlag< VehicleCustomFlags > CustomFlags
Milliseconds DespawnDelay
VendorItem const * FindItemCostPair(uint32 item_id, uint32 extendedCost, uint8 type) const
void AddItem(VendorItem vItem)
std::vector< int32 > BonusListIDs
Optional< ObjectGuid::LowType > TransportSpawnId