80#include <G3D/g3dmath.h>
113 std::string res =
"";
182 size_t pos = name.find(
'-');
183 if (pos != std::string::npos)
195 Unit const* summoner =
nullptr;
226 _equipmentSetGuid(1),
230 _gameObjectSpawnId(1),
247 if (data.size() <=
size_t(localeConstant))
250 data.resize(localeConstant + 1);
253 data[localeConstant] = value.empty() ?
"" : value;
263 QueryResult result =
WorldDatabase.Query(
"SELECT entry, locale, Name, NameAlt, Title, TitleAlt FROM creature_template_locale");
269 Field* fields = result->Fetch();
284 }
while (result->NextRow());
296 QueryResult result =
WorldDatabase.Query(
"SELECT MenuID, OptionID, Locale, OptionText, BoxText FROM gossip_menu_option_locale");
303 Field* fields = result->Fetch();
316 }
while (result->NextRow());
334 Field* fields = result->Fetch();
345 }
while (result->NextRow());
380 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template definitions. DB table `creature_template` is empty.");
387 Field* fields = result->Fetch();
389 }
while (result->NextRow());
409 creatureTemplate.
Entry = entry;
438 creatureTemplate.
type =
uint32(fields[27].GetUInt8());
444 creatureTemplate.
spells[i] = 0;
450 if (!fields[31].IsNull())
483 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template gossip definitions. DB table `creature_template_gossip` is empty.");
491 Field* fields = result->Fetch();
499 TC_LOG_ERROR(
"sql.sql",
"creature_template_gossip has gossip definitions for creature {} but this creature doesn't exist", creatureID);
504 if (menuBounds.first == menuBounds.second)
506 TC_LOG_ERROR(
"sql.sql",
"creature_template_gossip has gossip definitions for menu id {} but this menu doesn't exist", menuID);
515 }
while (result->NextRow());
525 QueryResult result =
WorldDatabase.Query(
"SELECT CreatureID, School, Resistance FROM creature_template_resistance");
529 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template resistance definitions. DB table `creature_template_resistance` is empty.");
537 Field* fields = result->Fetch();
544 TC_LOG_ERROR(
"sql.sql",
"creature_template_resistance has resistance definitions for creature {} but this school {} doesn't exist", creatureID, school);
551 TC_LOG_ERROR(
"sql.sql",
"creature_template_resistance has resistance definitions for creature {} but this creature doesn't exist", creatureID);
560 }
while (result->NextRow());
574 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template spell definitions. DB table `creature_template_spell` is empty.");
582 Field* fields = result->Fetch();
589 TC_LOG_ERROR(
"sql.sql",
"creature_template_spell has spell definitions for creature {} with a incorrect index {}", creatureID, index);
596 TC_LOG_ERROR(
"sql.sql",
"creature_template_spell has spell definitions for creature {} but this creature doesn't exist", creatureID);
605 }
while (result->NextRow());
615 QueryResult result =
WorldDatabase.Query(
"SELECT CreatureID, CreatureDisplayID, DisplayScale, Probability FROM creature_template_model ORDER BY Idx ASC");
619 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template model definitions. DB table `creature_template_model` is empty.");
626 Field* fields = result->Fetch();
630 float displayScale = fields[2].
GetFloat();
631 float probability = fields[3].
GetFloat();
636 TC_LOG_ERROR(
"sql.sql",
"Creature template (Entry: {}) does not exist but has a record in `creature_template_model`", creatureId);
643 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) lists non-existing CreatureDisplayID id ({}), this can crash the client.", creatureId, creatureDisplayId);
649 TC_LOG_ERROR(
"sql.sql",
"No model data exist for `CreatureDisplayID` = {} listed by creature (Entry: {}).", creatureDisplayId, creatureId);
651 if (displayScale <= 0.0f)
658 while (result->NextRow());
668 QueryResult result =
WorldDatabase.Query(
"SELECT CreatureID, CreatureIDVisibleToSummoner, GroundMountDisplayID, FlyingMountDisplayID, DespawnOnQuestsRemoved FROM creature_summoned_data");
672 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature summoned data definitions. DB table `creature_summoned_data` is empty.");
678 Field* fields = result->Fetch();
683 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summoned_data` references non-existing creature {}, skipped", creatureId);
694 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summoned_data` references non-existing creature {} in CreatureIDVisibleToSummoner for creature {}, set to 0",
701 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summoned_data` references non-existing display id {} in GroundMountDisplayID for creature {}, set to 0",
708 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summoned_data` references non-existing display id {} in FlyingMountDisplayID for creature {}, set to 0",
716 for (std::string_view questStr :
Trinity::Tokenize(*despawnOnQuestsRemoved,
',',
false))
725 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summoned_data` references non-existing quest {} in DespawnOnQuestsRemoved for creature {}, skipping",
726 *questId, creatureId);
737 }
while (result->NextRow());
747 QueryResult result =
WorldDatabase.Query(
"SELECT entry, PathId, mount, StandState, AnimTier, VisFlags, SheathState, PvPFlags, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_template_addon");
751 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template addon definitions. DB table `creature_template_addon` is empty.");
758 Field* fields = result->Fetch();
764 TC_LOG_ERROR(
"sql.sql",
"Creature template (Entry: {}) does not exist but has a record in `creature_template_addon`", entry);
783 for (std::string_view aura :
Trinity::Tokenize(fields[13].GetStringView(),
' ',
false))
791 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has wrong spell '{}' defined in `auras` field in `creature_template_addon`.", entry, std::string(aura));
796 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has SPELL_AURA_CONTROL_VEHICLE aura {} defined in `auras` field in `creature_template_addon`.", entry, spellInfo->
Id);
798 if (std::find(creatureAddon.
auras.begin(), creatureAddon.
auras.end(), spellInfo->
Id) != creatureAddon.
auras.end())
800 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has duplicate aura (spell {}) in `auras` field in `creature_template_addon`.", entry, spellInfo->
Id);
806 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has temporary aura (spell {}) in `auras` field in `creature_template_addon`.", entry, spellInfo->
Id);
810 creatureAddon.
auras.push_back(spellInfo->
Id);
813 if (creatureAddon.
mount)
817 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid displayInfoId ({}) for mount defined in `creature_template_addon`", entry, creatureAddon.
mount);
818 creatureAddon.
mount = 0;
824 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid unit stand state ({}) defined in `creature_template_addon`. Truncated to 0.", entry, creatureAddon.
standState);
830 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid animation tier ({}) defined in `creature_template_addon`. Truncated to 0.", entry, creatureAddon.
animTier);
836 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid sheath state ({}) defined in `creature_template_addon`. Truncated to 0.", entry, creatureAddon.
sheathState);
844 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid emote ({}) defined in `creature_template_addon`.", entry, creatureAddon.
emote);
845 creatureAddon.
emote = 0;
850 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid aiAnimKit ({}) defined in `creature_template_addon`.", entry, creatureAddon.
aiAnimKit);
856 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid movementAnimKit ({}) defined in `creature_template_addon`.", entry, creatureAddon.
movementAnimKit);
862 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid meleeAnimKit ({}) defined in `creature_template_addon`.", entry, creatureAddon.
meleeAnimKit);
868 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid visibilityDistanceType ({}) defined in `creature_template_addon`.",
875 while (result->NextRow());
885 QueryResult result =
WorldDatabase.Query(
"SELECT Entry, NoNPCDamageBelowHealthPct FROM creature_template_sparring");
889 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template sparring definitions. DB table `creature_template_sparring` is empty.");
896 Field* fields = result->Fetch();
899 float noNPCDamageBelowHealthPct = fields[1].
GetFloat();
903 TC_LOG_ERROR(
"sql.sql",
"Creature template (Entry: {}) does not exist but has a record in `creature_template_sparring`", entry);
907 if (noNPCDamageBelowHealthPct <= 0 || noNPCDamageBelowHealthPct > 100)
909 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid NoNPCDamageBelowHealthPct ({}) defined in `creature_template_sparring`. Skipping",
910 entry, noNPCDamageBelowHealthPct);
916 }
while (result->NextRow());
926 QueryResult result =
WorldDatabase.Query(
"SELECT Entry, DifficultyID, LevelScalingDeltaMin, LevelScalingDeltaMax, ContentTuningID, HealthScalingExpansion, "
928 "HealthModifier, ManaModifier, ArmorModifier, DamageModifier, CreatureDifficultyID, TypeFlags, TypeFlags2, TypeFlags3, "
930 "LootID, PickPocketLootID, SkinLootID, GoldMin, GoldMax,"
932 "StaticFlags1, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, StaticFlags6, StaticFlags7, StaticFlags8 "
933 "FROM creature_template_difficulty ORDER BY Entry");
937 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template difficulty definitions. DB table `creature_template_difficulty` is empty.");
944 Field* fields = result->Fetch();
952 TC_LOG_ERROR(
"sql.sql",
"Creature template (Entry: {}) does not exist but has a record in `creature_template_difficulty`", entry);
956 CreatureDifficulty& creatureDifficulty = itr->second.difficultyStore.try_emplace(difficulty).first->second;
983 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template_difficulty` lists creature (ID: {}) with invalid `HealthScalingExpansion` {}. Ignored and set to 0.",
990 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template_difficulty` lists creature (ID: {}) with `GoldMin` {} greater than `GoldMax` {}, setting `GoldMax` to {}.",
996 }
while (result->NextRow());
1006 if (!cInfo->
AIName.empty())
1011 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has non-registered `AIName` '{}' set, removing", cInfo->
Entry, cInfo->
AIName);
1019 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has not-allowed `AIName` '{}' set, removing", cInfo->
Entry, cInfo->
AIName);
1026 if (!factionTemplate)
1028 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);
1038 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) lists non-existing creature entry {} in `KillCredit{}`.", cInfo->
Entry, cInfo->
KillCredit[k], k + 1);
1044 if (cInfo->
Models.empty())
1045 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) does not have any existing display id in creature_template_model.", cInfo->
Entry);
1049 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);
1055 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid spell school value ({}) in `dmgschool`.", cInfo->
Entry, cInfo->
dmgschool);
1073 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has wrong value ({}) in speed_run, set to 1.14286.", cInfo->
Entry, cInfo->
speed_run);
1079 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid creature type ({}) in `type`.", cInfo->
Entry, cInfo->
type);
1085 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid creature family ({}) in `family`.", cInfo->
Entry, cInfo->
family);
1096 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has a non-existing VehicleId ({}). This *WILL* cause the client to freeze!", cInfo->
Entry, cInfo->
VehicleId);
1105 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has non-existing Spell{} ({}), set to 0.", cInfo->
Entry, j+1, cInfo->
spells[j]);
1112 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has wrong movement generator type ({}), ignored and set to IDLE.", cInfo->
Entry, cInfo->
MovementType);
1118 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template` lists creature (Entry: {}) with `RequiredExpansion` {}. Ignored and set to 0.", cInfo->
Entry, cInfo->
RequiredExpansion);
1124 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template` lists creature (Entry: {}) with disallowed `flags_extra` {}, removing incorrect flag.", cInfo->
Entry, badFlags);
1130 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template` lists creature (Entry: {}) with disallowed `unit_flags` {}, removing incorrect flag.", cInfo->
Entry, disallowedUnitFlags);
1136 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template` lists creature (Entry: {}) with disallowed `unit_flags2` {}, removing incorrect flag.", cInfo->
Entry, disallowedUnitFlags2);
1142 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template` lists creature (Entry: {}) with disallowed `unit_flags3` {}, removing incorrect flag.", cInfo->
Entry, disallowedUnitFlags3);
1147 TC_LOG_INFO(
"sql.sql",
"Creature (Entry: {}) has assigned gossip menu, but npcflag does not include UNIT_NPC_FLAG_GOSSIP.", cInfo->
Entry);
1149 TC_LOG_INFO(
"sql.sql",
"Creature (Entry: {}) has npcflag UNIT_NPC_FLAG_GOSSIP, but gossip menu is unassigned.", cInfo->
Entry);
1162 TC_LOG_ERROR(
"sql.sql",
"`{}`.`Chase` wrong value ({}) for Id {}, setting to Run.",
1169 TC_LOG_ERROR(
"sql.sql",
"`{}`.`Random` wrong value ({}) for Id {}, setting to Walk.",
1180 QueryResult result =
WorldDatabase.Query(
"SELECT guid, PathId, mount, StandState, AnimTier, VisFlags, SheathState, PvPFlags, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_addon");
1184 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature addon definitions. DB table `creature_addon` is empty.");
1191 Field* fields = result->Fetch();
1198 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) does not exist but has a record in `creature_addon`", guid);
1208 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID {}) has movement type set to WAYPOINT_MOTION_TYPE but no path assigned", guid);
1223 for (std::string_view aura :
Trinity::Tokenize(fields[13].GetStringView(),
' ',
false))
1231 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has wrong spell '{}' defined in `auras` field in `creature_addon`.", guid, std::string(aura));
1236 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has SPELL_AURA_CONTROL_VEHICLE aura {} defined in `auras` field in `creature_addon`.", guid, spellInfo->
Id);
1238 if (std::find(creatureAddon.
auras.begin(), creatureAddon.
auras.end(), spellInfo->
Id) != creatureAddon.
auras.end())
1240 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has duplicate aura (spell {}) in `auras` field in `creature_addon`.", guid, spellInfo->
Id);
1246 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has temporary aura (spell {}) in `auras` field in `creature_addon`.", guid, spellInfo->
Id);
1250 creatureAddon.
auras.push_back(spellInfo->
Id);
1253 if (creatureAddon.
mount)
1257 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid displayInfoId ({}) for mount defined in `creature_addon`", guid, creatureAddon.
mount);
1258 creatureAddon.
mount = 0;
1264 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid unit stand state ({}) defined in `creature_addon`. Truncated to 0.", guid, creatureAddon.
standState);
1270 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid animation tier ({}) defined in `creature_addon`. Truncated to 0.", guid, creatureAddon.
animTier);
1276 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid sheath state ({}) defined in `creature_addon`. Truncated to 0.", guid, creatureAddon.
sheathState);
1284 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid emote ({}) defined in `creature_addon`.", guid, creatureAddon.
emote);
1285 creatureAddon.
emote = 0;
1290 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid aiAnimKit ({}) defined in `creature_addon`.", guid, creatureAddon.
aiAnimKit);
1296 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid movementAnimKit ({}) defined in `creature_addon`.", guid, creatureAddon.
movementAnimKit);
1302 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid meleeAnimKit ({}) defined in `creature_addon`.", guid, creatureAddon.
meleeAnimKit);
1308 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid visibilityDistanceType ({}) defined in `creature_addon`.",
1315 while (result->NextRow());
1325 QueryResult result =
WorldDatabase.Query(
"SELECT guid, parent_rotation0, parent_rotation1, parent_rotation2, parent_rotation3, invisibilityType, invisibilityValue, WorldEffectID, AIAnimKitID FROM gameobject_addon");
1329 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject addon definitions. DB table `gameobject_addon` is empty.");
1336 Field* fields = result->Fetch();
1343 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) does not exist but has a record in `gameobject_addon`", guid);
1348 gameObjectAddon.
ParentRotation =
QuaternionData(fields[1].GetFloat(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat());
1356 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) has invalid InvisibilityType in `gameobject_addon`, disabled invisibility", guid);
1363 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) has InvisibilityType set but has no InvisibilityValue in `gameobject_addon`, set to 1", guid);
1369 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) has invalid parent rotation in `gameobject_addon`, set to default", guid);
1375 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) has invalid WorldEffectID ({}) in `gameobject_addon`, set to 0.", guid, gameObjectAddon.
WorldEffectID);
1381 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) has invalid AIAnimKitID ({}) in `gameobject_addon`, set to 0.", guid, gameObjectAddon.
AIAnimKitID);
1387 while (result->NextRow());
1396 return &(itr->second);
1405 return &(itr->second);
1414 return &(itr->second);
1435 if (itr->second.empty())
1440 EquipmentInfoContainerInternal::const_iterator ritr = itr->second.begin();
1441 std::advance(ritr,
urand(0u, itr->second.size() - 1));
1442 id = std::distance(itr->second.begin(), ritr) + 1;
1443 return &ritr->second;
1447 EquipmentInfoContainerInternal::const_iterator itr2 = itr->second.find(
id);
1448 if (itr2 != itr->second.end())
1449 return &itr2->second;
1462 "ItemID2, AppearanceModID2, ItemVisual2, "
1464 "ItemID3, AppearanceModID3, ItemVisual3 "
1465 "FROM creature_equip_template");
1469 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature equipment templates. DB table `creature_equip_template` is empty!");
1476 Field* fields = result->Fetch();
1482 TC_LOG_ERROR(
"sql.sql",
"Creature template (CreatureID: {}) does not exist but has a record in `creature_equip_template`", entry);
1489 TC_LOG_ERROR(
"sql.sql",
"Creature equipment template with id 0 found for creature {}, skipped.", entry);
1506 TC_LOG_ERROR(
"sql.sql",
"Unknown item (ID={}) in creature_equip_template.ItemID{} for CreatureID = {} and ID={}, forced to 0.",
1515 TC_LOG_ERROR(
"sql.sql",
"Unknown item appearance for (ID={}, AppearanceModID={}) pair in creature_equip_template.ItemID{} creature_equip_template.AppearanceModID{} "
1516 "for CreatureID = {} and ID={}, forced to default.",
1527 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.",
1535 while (result->NextRow());
1548 "SELECT cmo.SpawnId,"
1549 "COALESCE(cmo.HoverInitiallyEnabled, ctm.HoverInitiallyEnabled),"
1550 "COALESCE(cmo.Chase, ctm.Chase),"
1551 "COALESCE(cmo.Random, ctm.Random),"
1552 "COALESCE(cmo.InteractionPauseTimer, ctm.InteractionPauseTimer) "
1553 "FROM creature_movement_override AS cmo "
1554 "LEFT JOIN creature AS c ON c.guid = cmo.SpawnId "
1555 "LEFT JOIN creature_template_movement AS ctm ON ctm.CreatureId = c.id");
1559 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature movement overrides. DB table `creature_movement_override` is empty!");
1565 Field* fields = result->Fetch();
1569 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) does not exist but has a record in `creature_movement_override`", spawnId);
1574 if (!fields[1].IsNull())
1585 while (result->NextRow());
1594 return &(itr->second);
1620#define ChooseCreatureFlagSource(field) ((data && data->field.has_value()) ? *data->field : cInfo->field)
1655#undef ChooseCreatureFlagSource
1674 if (creatureTemplate)
1676 auto itr = std::find_if(creatureTemplate->
Models.begin(), creatureTemplate->
Models.end(), [&](
CreatureModel const& templateModel)
1678 return templateModel.CreatureDisplayID == modelInfo->displayId_other_gender;
1680 if (itr != creatureTemplate->
Models.end())
1694 QueryResult result =
WorldDatabase.Query(
"SELECT DisplayID, BoundingRadius, CombatReach, DisplayID_Other_Gender FROM creature_model_info");
1698 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature model definitions. DB table `creature_model_info` is empty.");
1706 uint32 trigggerCreatureModelFileID[5] = { 124640, 124641, 124642, 343863, 439302 };
1710 Field* fields = result->Fetch();
1715 if (!creatureDisplay)
1717 TC_LOG_ERROR(
"sql.sql",
"Table `creature_model_info` has a non-existent DisplayID (ID: {}). Skipped.", displayId);
1741 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);
1750 for (
uint32 i = 0; i < 5; ++i)
1752 if (modelData->FileDataID == trigggerCreatureModelFileID[i])
1762 while (result->NextRow());
1773 QueryResult result =
WorldDatabase.Query(
"SELECT guid, linkedGuid, linkType FROM linked_respawn ORDER BY guid ASC");
1777 TC_LOG_INFO(
"server.loading",
">> Loaded 0 linked respawns. DB table `linked_respawn` is empty.");
1783 Field* fields = result->Fetch();
1798 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature (guid) '{}' not found in creature table", guidLow);
1806 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature (linkedGuid) '{}' not found in creature table", linkedGuidLow);
1814 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature '{}' linking to Creature '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1822 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature '{}' linking to Creature '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1827 guid = ObjectGuid::Create<HighGuid::Creature>(slave->
mapId, slave->
id, guidLow);
1828 linkedGuid = ObjectGuid::Create<HighGuid::Creature>(master->
mapId, master->
id, linkedGuidLow);
1836 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature (guid) '{}' not found in creature table", guidLow);
1844 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject (linkedGuid) '{}' not found in gameobject table", linkedGuidLow);
1852 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature '{}' linking to Gameobject '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1860 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature '{}' linking to Gameobject '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1865 guid = ObjectGuid::Create<HighGuid::Creature>(slave->
mapId, slave->
id, guidLow);
1866 linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->
mapId, master->
id, linkedGuidLow);
1874 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject (guid) '{}' not found in gameobject table", guidLow);
1882 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject (linkedGuid) '{}' not found in gameobject table", linkedGuidLow);
1890 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject '{}' linking to Gameobject '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1898 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject '{}' linking to Gameobject '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1903 guid = ObjectGuid::Create<HighGuid::GameObject>(slave->
mapId, slave->
id, guidLow);
1904 linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->
mapId, master->
id, linkedGuidLow);
1912 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject (guid) '{}' not found in gameobject table", guidLow);
1920 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature (linkedGuid) '{}' not found in creature table", linkedGuidLow);
1928 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject '{}' linking to Creature '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1936 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject '{}' linking to Creature '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1941 guid = ObjectGuid::Create<HighGuid::GameObject>(slave->
mapId, slave->
id, guidLow);
1942 linkedGuid = ObjectGuid::Create<HighGuid::Creature>(master->
mapId, master->
id, linkedGuidLow);
1950 while (result->NextRow());
1962 ObjectGuid guid = ObjectGuid::Create<HighGuid::Creature>(master->
mapId, master->
id, guidLow);
1977 TC_LOG_ERROR(
"sql.sql",
"Creature '{}' linking to non-existent creature '{}'.", guidLow, linkedGuidLow);
1984 TC_LOG_ERROR(
"sql.sql",
"Creature '{}' linking to '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1991 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature '{}' linking to '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1995 ObjectGuid linkedGuid = ObjectGuid::Create<HighGuid::Creature>(slave->
mapId, slave->
id, linkedGuidLow);
2013 QueryResult result =
WorldDatabase.Query(
"SELECT summonerId, summonerType, groupId, entry, position_x, position_y, position_z, orientation, summonType, summonTime FROM creature_summon_groups");
2017 TC_LOG_INFO(
"server.loading",
">> Loaded 0 temp summons. DB table `creature_summon_groups` is empty.");
2024 Field* fields = result->Fetch();
2030 switch (summonerType)
2035 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summon_groups` has summoner with non existing entry {} for creature summoner type, skipped.", summonerId);
2042 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summon_groups` has summoner with non existing entry {} for gameobject summoner type, skipped.", summonerId);
2049 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summon_groups` has summoner with non existing entry {} for map summoner type, skipped.", summonerId);
2054 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summon_groups` has unhandled summoner type {} for summoner {}, skipped.", summonerType, summonerId);
2063 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);
2070 float orientation = fields[7].
GetFloat();
2078 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);
2089 }
while (result->NextRow());
2095 std::set<Difficulty>
const& mapDifficulties)
2097 std::vector<Difficulty> difficulties;
2098 bool isTransportMap =
sObjectMgr->IsTransportMap(mapId);
2104 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has {} (GUID: {}) with non invalid difficulty id {}, skipped.",
2105 table, table, spawnId,
uint32(difficultyId));
2109 if (!isTransportMap && mapDifficulties.find(difficultyId) == mapDifficulties.end())
2111 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has {} (GUID: {}) has unsupported difficulty {} for map (Id: {}).",
2112 table, table, spawnId,
uint32(difficultyId), mapId);
2116 difficulties.push_back(difficultyId);
2119 std::sort(difficulties.begin(), difficulties.end());
2120 return difficulties;
2128 QueryResult result =
WorldDatabase.Query(
"SELECT creature.guid, id, map, position_x, position_y, position_z, orientation, modelid, equipment_id, spawntimesecs, wander_distance, "
2130 "currentwaypoint, curHealthPct, MovementType, spawnDifficulties, eventEntry, poolSpawnId, creature.npcflag, creature.unit_flags, creature.unit_flags2, creature.unit_flags3, "
2132 "creature.phaseUseFlags, creature.phaseid, creature.phasegroup, creature.terrainSwapMap, creature.ScriptName, creature.StringId "
2134 "LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid "
2135 "LEFT OUTER JOIN pool_members ON pool_members.type = 0 AND creature.guid = pool_members.spawnId");
2139 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creatures. DB table `creature` is empty.");
2144 std::unordered_map<uint32, std::set<Difficulty>> spawnMasks;
2146 spawnMasks[mapDifficulty->MapID].insert(
Difficulty(mapDifficulty->DifficultyID));
2154 Field* fields = result->Fetch();
2162 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {}) with non existing creature entry {}, skipped.", guid, entry);
2170 data.
spawnPoint.
Relocate(fields[3].GetFloat(), fields[4].GetFloat(), fields[5].GetFloat(), fields[6].GetFloat());
2171 if (
uint32 displayId = fields[7].GetUInt32())
2197 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {}) that spawned at nonexistent map (Id: {}), skipped.", guid, data.
mapId);
2213 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {} MapID: {}) spawned on a possible invalid position ({})",
2221 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {}) that is not spawned in any difficulty, skipped.", guid);
2229 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with invalid `modelid` {}, ignoring.", guid, data.
id, data.
display->CreatureDisplayID);
2239 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);
2247 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);
2252 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);
2258 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with `wander_distance`< 0, set to 0.", guid, data.
id);
2263 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);
2270 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);
2278 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);
2285 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.
id);
2291 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE,"
2292 " removing PHASE_USE_FLAGS_INVERSE.", guid, data.
id);
2298 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.
id);
2306 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) with `phaseid` {} does not exist, set to 0", guid, data.
id, data.
phaseId);
2315 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) with `phasegroup` {} does not exist, set to 0", guid, data.
id, data.
phaseGroup);
2323 if (!terrainSwapEntry)
2325 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) with `terrainSwapMap` {} does not exist, set to -1", guid, data.
id, data.
terrainSwapMap);
2330 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);
2339 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with disallowed `unit_flags` {}, removing incorrect flag.", guid, data.
id, disallowedUnitFlags);
2348 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with disallowed `unit_flags2` {}, removing incorrect flag.", guid, data.
id, disallowedUnitFlags2);
2354 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);
2363 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with disallowed `unit_flags3` {}, removing incorrect flag.", guid, data.
id, disallowedUnitFlags3);
2369 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);
2377 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with invalid `curHealthPct` {}, set to {}.", guid, data.
id, data.
curHealthPct, healthPct);
2401 while (result->NextRow());
2432template<CellGu
idSet CellObjectGu
ids::*gu
ids>
2437 if (!isPersonalPhase)
2449template<CellGu
idSet CellObjectGu
ids::*gu
ids>
2454 if (!isPersonalPhase)
2468 AddSpawnDataToGrid<&CellObjectGuids::creatures>(data);
2473 RemoveSpawnDataFromGrid<&CellObjectGuids::creatures>(data);
2481 QueryResult result =
WorldDatabase.Query(
"SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
2483 "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnDifficulties, eventEntry, poolSpawnId, "
2485 "phaseUseFlags, phaseid, phasegroup, terrainSwapMap, ScriptName, StringId "
2486 "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid "
2487 "LEFT OUTER JOIN pool_members ON pool_members.type = 1 AND gameobject.guid = pool_members.spawnId");
2491 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobjects. DB table `gameobject` is empty.");
2496 std::unordered_map<uint32, std::set<Difficulty>> spawnMasks;
2498 spawnMasks[mapDifficulty->MapID].insert(
Difficulty(mapDifficulty->DifficultyID));
2506 Field* fields = result->Fetch();
2514 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {}) with non existing gameobject entry {}, skipped.", guid, entry);
2520 switch (gInfo->
type)
2526 TC_LOG_ERROR(
"sql.sql",
"Gameobject (GUID: {} Entry {} GoType: {}) doesn't have a displayId ({}), not loaded.", guid, entry, gInfo->
type, gInfo->
displayId);
2533 TC_LOG_ERROR(
"sql.sql",
"Gameobject (GUID: {} Entry {} GoType: {}) has an invalid displayId ({}), not loaded.", guid, entry, gInfo->
type, gInfo->
displayId);
2542 data.
spawnPoint.
Relocate(fields[3].GetFloat(), fields[4].GetFloat(), fields[5].GetFloat(), fields[6].GetFloat());
2553 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) spawned on a non-existed map (Id: {}), skip", guid, data.
id, data.
mapId);
2569 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {} MapID: {}) spawned on a possible invalid position ({})",
2577 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);
2588 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid `state` ({}) value, skip", guid, data.
id, go_state);
2597 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {}) that is not spawned in any difficulty, skipped.", guid);
2609 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.
id);
2615 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE,"
2616 " removing PHASE_USE_FLAGS_INVERSE.", guid, data.
id);
2622 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.
id);
2630 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) with `phaseid` {} does not exist, set to 0", guid, data.
id, data.
phaseId);
2639 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) with `phaseGroup` {} does not exist, set to 0", guid, data.
id, data.
phaseGroup);
2648 if (!terrainSwapEntry)
2650 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) with `terrainSwapMap` {} does not exist, set to -1", guid, data.
id, data.
terrainSwapMap);
2655 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);
2665 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationX ({}) value, skip", guid, data.
id, data.
rotation.
x);
2671 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationY ({}) value, skip", guid, data.
id, data.
rotation.
y);
2677 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationZ ({}) value, skip", guid, data.
id, data.
rotation.
z);
2683 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationW ({}) value, skip", guid, data.
id, data.
rotation.
w);
2689 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid coordinates, skip", guid, data.
id);
2695 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);
2718 while (result->NextRow());
2734 Field* fields = result->Fetch();
2748 flags &= ~SPAWNGROUP_FLAG_MANUAL_SPAWN;
2749 TC_LOG_ERROR(
"sql.sql",
"System spawn group {} ({}) has invalid manual spawn flag. Ignored.", groupId, group.
name);
2752 }
while (result->NextRow());
2757 TC_LOG_ERROR(
"sql.sql",
"Default spawn group (index 0) is missing from DB! Manually inserted.");
2760 data.
name =
"Default Group";
2766 TC_LOG_ERROR(
"sql.sql",
"Default legacy spawn group (index 1) is missing from DB! Manually inserted.");
2769 data.
name =
"Legacy Group";
2777 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spawn group templates. DB table `spawn_group_template` is empty.");
2791 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spawn group members. DB table `spawn_group` is empty.");
2798 Field* fields = result->Fetch();
2803 TC_LOG_ERROR(
"sql.sql",
"Spawn data with invalid type {} listed for spawn group {}. Skipped.",
uint32(spawnType), groupId);
2811 TC_LOG_ERROR(
"sql.sql",
"Spawn data with ID ({},{}) not found, but is listed as a member of spawn group {}!",
uint32(spawnType), spawnId, groupId);
2816 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);
2822 TC_LOG_ERROR(
"sql.sql",
"Spawn group {} assigned to spawn ID ({},{}), but group is found!", groupId,
uint32(spawnType), spawnId);
2835 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);
2838 const_cast<SpawnMetadata*
>(data)->spawnGroupData = &groupTemplate;
2843 }
while (result->NextRow());
2853 QueryResult result =
WorldDatabase.Query(
"SELECT instanceMapId, bossStateId, bossStates, spawnGroupId, flags FROM instance_spawn_groups");
2857 TC_LOG_INFO(
"server.loading",
">> Loaded 0 instance spawn groups. DB table `instance_spawn_groups` is empty.");
2864 Field* fields = result->Fetch();
2869 TC_LOG_ERROR(
"sql.sql",
"Invalid spawn group {} specified for instance {}. Skipped.", spawnGroupId, fields[0].GetUInt16());
2874 if (it->second.mapId != instanceMapId)
2876 TC_LOG_ERROR(
"sql.sql",
"Instance spawn group {} specified for instance {} has spawns on a different map {}. Skipped.",
2877 spawnGroupId, instanceMapId, it->second.mapId);
2887 if (states & ~ALL_STATES)
2890 TC_LOG_ERROR(
"sql.sql",
"Instance spawn group ({},{}) had invalid boss state mask {} - truncated to {}.", instanceMapId, spawnGroupId, states, info.
BossStates);
2899 TC_LOG_ERROR(
"sql.sql",
"Instance spawn group ({},{}) had invalid flags {} - truncated to {}.", instanceMapId, spawnGroupId,
flags, info.
Flags);
2907 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);
2911 }
while (result->NextRow());
2942 bool erased =
false;
2943 for (
auto it = pair.first; it != pair.second; ++it)
2945 if (it->second != data)
2961 for (
auto it = pair.first; it != pair.second; ++it)
2963 if (it->second != data)
2973 AddSpawnDataToGrid<&CellObjectGuids::gameobjects>(data);
2978 RemoveSpawnDataFromGrid<&CellObjectGuids::gameobjects>(data);
2988 0.92f, 0.92f, 0.92f, 1.11f, 1.32f, 1.61f, 0.0f, 0.0f
2991 static float const armorMultipliers[
MAX_INVTYPE] =
3055 float levelPenalty = 1.0f;
3056 if (itemLevel <= 28)
3057 levelPenalty = 0.966f - float(28u - itemLevel) / 54.0f;
3064 return 5 *
uint32(round(25.0f * qualityMultipliers[quality] * armorMultipliers[inventoryType] * levelPenalty));
3067 return 5 *
uint32(round(18.0f * qualityMultipliers[quality] * weaponMultipliers[itemSubClass] * levelPenalty));
3227 switch (itemStatType)
3306 if (std::vector<ItemSpecOverrideEntry const*>
const* itemSpecOverrides =
sDB2Manager.GetItemSpecOverrides(sparse->ID))
3325 if (itemSpecStats.
ItemType != itemSpec->ItemType)
3335 hasSecondary =
true;
3338 if (!hasPrimary || !hasSecondary)
3343 if ((1 << (specialization->ClassID - 1)) & sparse->AllowableClass)
3348 if (itemSpec->MaxLevel > 40)
3350 if (itemSpec->MaxLevel >= 110)
3359 if (specs.count() == 0)
3371 item->Effects.insert(itr, effect);
3384 QueryResult result =
WorldDatabase.Query(
"SELECT Id, FlagsCu, FoodType, MinMoneyLoot, MaxMoneyLoot, SpellPPMChance, RandomBonusListTemplateId, QuestLogItemId FROM item_template_addon");
3389 Field* fields = result->Fetch();
3394 TC_LOG_ERROR(
"sql.sql",
"Item {} specified in `item_template_addon` does not exist, skipped.", itemId);
3400 if (minMoneyLoot > maxMoneyLoot)
3402 TC_LOG_ERROR(
"sql.sql",
"Minimum money loot specified in `item_template_addon` for item {} was greater than maximum amount, swapping.", itemId);
3403 std::swap(minMoneyLoot, maxMoneyLoot);
3413 }
while (result->NextRow());
3428 Field* fields = result->Fetch();
3433 TC_LOG_ERROR(
"sql.sql",
"Item {} specified in `item_script_names` does not exist, skipped.", itemId);
3439 }
while (result->NextRow());
3459 QueryResult result =
WorldDatabase.Query(
"SELECT `entry`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer`, `RideSpellID` FROM `vehicle_template_accessory`");
3463 TC_LOG_INFO(
"server.loading",
">> Loaded 0 vehicle template accessories. DB table `vehicle_template_accessory` is empty.");
3469 Field* fields = result->Fetch();
3474 bool isMinion = fields[3].
GetBool();
3481 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template_accessory`: rideSpellId {} does not exist for entry {}.", *rideSpellId, entry);
3487 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template_accessory`: creature template entry {} does not exist.", entry);
3493 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template_accessory`: Accessory {} does not exist.", accessory);
3499 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template_accessory`: creature template entry {} has no data in npc_spellclick_spells", entry);
3507 while (result->NextRow());
3519 QueryResult result =
WorldDatabase.Query(
"SELECT creatureId, despawnDelayMs, Pitch, CustomFlags FROM vehicle_template");
3523 TC_LOG_INFO(
"server.loading",
">> Loaded 0 vehicle template. DB table `vehicle_template` is empty.");
3529 Field* fields = result->Fetch();
3536 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template`: Creature (Entry: {}) does not exist.", creatureId);
3542 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template`: Creature (Entry: {}) is not a vehicle.", creatureId);
3553 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template`: Creature (Entry: {}) has negative despawnDelayMs ({}).`. Ignoring",
3560 if (vehicleTemplate.
Pitch)
3564 if (*vehicleTemplate.
Pitch < vehicle->PitchMin || *vehicleTemplate.
Pitch > vehicle->PitchMax)
3566 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template`: Creature (Entry: {}) has invalid Pitch ({}).`. Ignoring",
3567 creatureId, *vehicleTemplate.
Pitch);
3568 vehicleTemplate.
Pitch.reset();
3573 }
while (result->NextRow());
3587 QueryResult result =
WorldDatabase.Query(
"SELECT `guid`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer`, `RideSpellID` FROM `vehicle_accessory`");
3591 TC_LOG_INFO(
"server.loading",
">> Loaded 0 vehicle accessories. DB table `vehicle_accessory` is empty.");
3597 Field* fields = result->Fetch();
3601 int8 uiSeat =
int8(fields[2].GetInt16());
3602 bool bMinion = fields[3].
GetBool();
3609 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_accessory`: rideSpellId {} does not exist for guid {}.", *rideSpellId, uiGUID);
3615 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_accessory`: Accessory {} does not exist.", uiAccessory);
3623 while (result->NextRow());
3637 QueryResult result =
WorldDatabase.Query(
"SELECT `SeatEntry`, `SeatOrientation`, `ExitParamX`, `ExitParamY`, `ExitParamZ`, `ExitParamO`, `ExitParamValue` FROM `vehicle_seat_addon`");
3641 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 vehicle seat addons. DB table `vehicle_seat_addon` is empty.");
3647 Field* fields = result->Fetch();
3650 float orientation = fields[1].
GetFloat();
3651 float exitX = fields[2].
GetFloat();
3652 float exitY = fields[3].
GetFloat();
3653 float exitZ = fields[4].
GetFloat();
3654 float exitO = fields[5].
GetFloat();
3659 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_seat_addon`: SeatID: {} does not exist in VehicleSeat.dbc. Skipping entry.", seatID);
3664 if (orientation >
float(
M_PI * 2))
3666 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_seat_addon`: SeatID: {} is using invalid angle offset value ({}). Set Value to 0.", seatID, orientation);
3672 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_seat_addon`: SeatID: {} is using invalid exit parameter value ({}). Setting to 0 (none).", seatID, exitParam);
3679 }
while (result->NextRow());
3689 QueryResult result =
WorldDatabase.Query(
"SELECT creature_entry, level, hp, mana, str, agi, sta, inte, spi, armor FROM pet_levelstats");
3693 TC_LOG_INFO(
"server.loading",
">> Loaded 0 level pet stats definitions. DB table `pet_levelstats` is empty.");
3701 Field* fields = result->Fetch();
3706 TC_LOG_ERROR(
"sql.sql",
"Wrong creature id {} in `pet_levelstats` table, ignoring.", creature_id);
3717 TC_LOG_INFO(
"misc",
"Unused (> MaxPlayerLevel in worldserver.conf) level {} in `pet_levelstats` table, ignoring.", current_level);
3722 else if (current_level < 1)
3724 TC_LOG_ERROR(
"sql.sql",
"Wrong (<1) level {} in `pet_levelstats` table, ignoring.", current_level);
3733 PetLevelInfo* pLevelInfo = &pInfoMapEntry[current_level - 1];
3744 while (result->NextRow());
3749 auto& pInfo = itr->second;
3752 if (!pInfo || pInfo[0].health == 0)
3754 TC_LOG_ERROR(
"sql.sql",
"Creature {} does not have pet stats data for Level 1!", itr->first);
3761 if (pInfo[level].health == 0)
3763 TC_LOG_ERROR(
"sql.sql",
"Creature {} has no data for Level {} pet stats data, using data of Level {}.", itr->first, level + 1, level);
3764 pInfo[level] = pInfo[level - 1];
3781 return &itr->second[level - 1];
3791 playerInfo->
item.emplace_back(itemId, count);
3795 TC_LOG_ERROR(
"sql.sql",
"Invalid count {} specified on item {} be removed from original player create info (use -1)!", count, itemId);
3799 auto erased = std::remove_if(items.begin(), items.end(), [itemId](
PlayerCreateInfoItem const& item) { return item.item_id == itemId; });
3800 if (erased == items.end())
3802 TC_LOG_ERROR(
"sql.sql",
"Item {} specified to be removed from original create info not found in db2!", itemId);
3806 items.erase(erased, items.end());
3816 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");
3820 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 player create definitions. DB table `playercreateinfo` is empty.");
3829 Field* fields = result->Fetch();
3834 float positionX = fields[3].
GetFloat();
3835 float positionY = fields[4].
GetFloat();
3836 float positionZ = fields[5].
GetFloat();
3837 float orientation = fields[6].
GetFloat();
3841 TC_LOG_ERROR(
"sql.sql",
"Wrong race {} in `playercreateinfo` table, ignoring.", current_race);
3847 TC_LOG_ERROR(
"sql.sql",
"Wrong class {} in `playercreateinfo` table, ignoring.", current_class);
3854 TC_LOG_ERROR(
"sql.sql",
"Wrong home position for class {} race {} pair in `playercreateinfo` table, ignoring.", current_class, current_race);
3858 if (
sMapStore.LookupEntry(mapId)->Instanceable())
3860 TC_LOG_ERROR(
"sql.sql",
"Home position in instanceable map for class {} race {} pair in `playercreateinfo` table, ignoring.", current_class, current_race);
3866 TC_LOG_ERROR(
"sql.sql",
"Missing male model for race {}, ignoring.", current_race);
3872 TC_LOG_ERROR(
"sql.sql",
"Missing female model for race {}, ignoring.", current_race);
3876 std::unique_ptr<PlayerInfo> info = std::make_unique<PlayerInfo>();
3877 info->createPosition.Loc.WorldRelocate(mapId, positionX, positionY, positionZ, orientation);
3879 if (std::none_of(fields + 7, fields + 12, [](
Field const& field) {
return field.
IsNull(); }))
3881 info->createPositionNPE.emplace();
3883 info->createPositionNPE->Loc.WorldRelocate(fields[7].GetUInt32(), fields[8].GetFloat(), fields[9].GetFloat(), fields[10].GetFloat(), fields[11].GetFloat());
3884 info->createPositionNPE->TransportGuid = fields[12].
GetUInt64OrNull();
3886 if (!
sMapStore.LookupEntry(info->createPositionNPE->Loc.GetMapId()))
3888 TC_LOG_ERROR(
"sql.sql",
"Invalid NPE map id {} for class {} race {} pair in `playercreateinfo` table, ignoring.",
3889 info->createPositionNPE->Loc.GetMapId(), current_class, current_race);
3890 info->createPositionNPE.reset();
3893 if (info->createPositionNPE && info->createPositionNPE->TransportGuid && !
sTransportMgr->GetTransportSpawn(*info->createPositionNPE->TransportGuid))
3895 TC_LOG_ERROR(
"sql.sql",
"Invalid NPE transport spawn id {} for class {} race {} pair in `playercreateinfo` table, ignoring.",
3896 *info->createPositionNPE->TransportGuid, current_class, current_race);
3897 info->createPositionNPE.reset();
3902 if (info->introMovieId && !
sMovieStore.LookupEntry(*info->introMovieId))
3904 TC_LOG_ERROR(
"sql.sql",
"Invalid intro movie id {} for class {} race {} pair in `playercreateinfo` table, ignoring.",
3905 *info->introMovieId, current_class, current_race);
3906 info->introMovieId.reset();
3912 TC_LOG_ERROR(
"sql.sql",
"Invalid intro scene id {} for class {} race {} pair in `playercreateinfo` table, ignoring.",
3913 *info->introSceneId, current_class, current_race);
3914 info->introSceneId.reset();
3920 TC_LOG_ERROR(
"sql.sql",
"Invalid NPE intro scene id {} for class {} race {} pair in `playercreateinfo` table, ignoring.",
3921 *info->introSceneIdNPE, current_class, current_race);
3922 info->introSceneIdNPE.reset();
3929 while (result->NextRow());
3936 TC_LOG_INFO(
"server.loading",
"Loading Player Create Items Data...");
3938 std::unordered_map<uint32, std::vector<ItemTemplate const*>> itemsByCharacterLoadout;
3941 itemsByCharacterLoadout[characterLoadoutItem->CharacterLoadoutID].push_back(itemTemplate);
3945 if (!characterLoadout->IsForNewCharacter())
3954 if (!characterLoadout->RaceMask.HasRace(race->ID))
3959 playerInfo->itemContext =
ItemContext(characterLoadout->ItemContext);
3964 uint32 count = itemTemplate->GetBuyCount();
3969 if (!itemTemplate->Effects.empty())
3971 switch (itemTemplate->Effects[0]->SpellCategoryID)
3981 if (itemTemplate->GetMaxStackSize() < count)
3982 count = itemTemplate->GetMaxStackSize();
3985 playerInfo->item.emplace_back(itemTemplate->GetId(), count);
3992 TC_LOG_INFO(
"server.loading",
"Loading Player Create Items Override Data...");
4000 TC_LOG_INFO(
"server.loading",
">> Loaded 0 custom player create items. DB table `playercreateinfo_item` is empty.");
4008 Field* fields = result->Fetch();
4013 TC_LOG_ERROR(
"sql.sql",
"Wrong race {} in `playercreateinfo_item` table, ignoring.", current_race);
4020 TC_LOG_ERROR(
"sql.sql",
"Wrong class {} in `playercreateinfo_item` table, ignoring.", current_class);
4028 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);
4036 TC_LOG_ERROR(
"sql.sql",
"Item id {} (class {} race {}) have amount == 0 in `playercreateinfo_item` table, ignoring.", item_id, current_race, current_class);
4040 if (!current_race || !current_class)
4042 uint32 min_race = current_race ? current_race : 1;
4044 uint32 min_class = current_class ? current_class : 1;
4046 for (
uint32 r = min_race; r < max_race; ++r)
4047 for (
uint32 c = min_class; c < max_class; ++c)
4055 while (result->NextRow());
4062 TC_LOG_INFO(
"server.loading",
"Loading Player Create Skill Data...");
4067 if (rcInfo->Availability == 1)
4069 if (rcInfo->RaceMask.IsEmpty() || rcInfo->RaceMask.HasRace(race->ID))
4071 if (rcInfo->ClassMask == -1 || rcInfo->ClassMask == 0 || ((1 << (classIndex - 1)) & rcInfo->ClassMask))
4073 playerInfo->skills.push_back(rcInfo);
4079 TC_LOG_INFO(
"server.loading",
"Loading Player Create Custom Spell Data...");
4087 TC_LOG_INFO(
"server.loading",
">> Loaded 0 player create custom spells. DB table `playercreateinfo_spell_custom` is empty.");
4095 Field* fields = result->Fetch();
4102 TC_LOG_ERROR(
"sql.sql",
"Wrong race mask {} in `playercreateinfo_spell_custom` table, ignoring.", raceMask.
RawValue);
4108 TC_LOG_ERROR(
"sql.sql",
"Wrong class mask {} in `playercreateinfo_spell_custom` table, ignoring.", classMask);
4118 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
4122 playerInfo->customSpells.push_back(spellId);
4134 while (result->NextRow());
4141 TC_LOG_INFO(
"server.loading",
"Loading Player Create Cast Spell Data...");
4145 QueryResult result =
WorldDatabase.PQuery(
"SELECT raceMask, classMask, spell, createMode FROM playercreateinfo_cast_spell");
4148 TC_LOG_INFO(
"server.loading",
">> Loaded 0 player create cast spells. DB table `playercreateinfo_cast_spell` is empty.");
4155 Field* fields = result->Fetch();
4163 TC_LOG_ERROR(
"sql.sql",
"Wrong race mask {} in `playercreateinfo_cast_spell` table, ignoring.", raceMask.
RawValue);
4169 TC_LOG_ERROR(
"sql.sql",
"Wrong class mask {} in `playercreateinfo_cast_spell` table, ignoring.", classMask);
4175 TC_LOG_ERROR(
"sql.sql",
"Uses invalid createMode {} in `playercreateinfo_cast_spell` table, ignoring.", playerCreateMode);
4185 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
4189 playerInfo->castSpells[playerCreateMode].push_back(spellId);
4196 }
while (result->NextRow());
4203 TC_LOG_INFO(
"server.loading",
"Loading Player Create Action Data...");
4212 TC_LOG_INFO(
"server.loading",
">> Loaded 0 player create actions. DB table `playercreateinfo_action` is empty.");
4220 Field* fields = result->Fetch();
4225 TC_LOG_ERROR(
"sql.sql",
"Wrong race {} in `playercreateinfo_action` table, ignoring.", current_race);
4232 TC_LOG_ERROR(
"sql.sql",
"Wrong class {} in `playercreateinfo_action` table, ignoring.", current_class);
4241 while (result->NextRow());
4248 TC_LOG_INFO(
"server.loading",
"Loading Player Create Level Stats Data...");
4253 std::array<int16, MAX_STATS> StatModifier = { };
4255 explicit RaceStats(
Races race) :
Race(race) { }
4256 std::strong_ordering
operator<=>(RaceStats
const& right)
const {
return Race <=> right.Race; }
4257 bool operator==(RaceStats
const& right)
const {
return Race == right.Race; }
4266 if (!raceStatsResult)
4268 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 race stats definitions. DB table `player_racestats` is empty.");
4274 Field* fields = raceStatsResult->Fetch();
4279 TC_LOG_ERROR(
"sql.sql",
"Wrong race {} in `player_racestats` table, ignoring.", current_race);
4283 RaceStats& stats = *raceStatModifiers.
emplace(
Races(current_race)).first;
4285 stats.StatModifier[i] = fields[i + 1].
GetInt16();
4287 }
while (raceStatsResult->NextRow());
4290 QueryResult result =
WorldDatabase.Query(
"SELECT class, level, str, agi, sta, inte, spi FROM player_classlevelstats");
4294 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 level stats definitions. DB table `player_classlevelstats` is empty.");
4302 Field* fields = result->Fetch();
4307 TC_LOG_ERROR(
"sql.sql",
"Wrong class {} in `player_classlevelstats` table, ignoring.", current_class);
4317 TC_LOG_INFO(
"misc",
"Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_classlevelstats` table, ignoring.", current_level);
4322 for (RaceStats
const& raceStats : raceStatModifiers)
4326 if (!playerInfo->levelInfo)
4329 PlayerLevelInfo& levelInfo = playerInfo->levelInfo[current_level - 1];
4331 levelInfo.
stats[i] = fields[i + 2].
GetInt32() + raceStats.StatModifier[i];
4337 while (result->NextRow());
4340 for (
auto const& [raceClass, playerInfo] :
_playerInfo)
4342 auto [race, class_] = raceClass;
4345 if (!playerInfo->levelInfo || playerInfo->levelInfo[0].stats[0] == 0)
4347 TC_LOG_ERROR(
"sql.sql",
"Race {} Class {} Level 1 does not have stats data!", race, class_);
4354 if (playerInfo->levelInfo[level].stats[0] == 0)
4356 TC_LOG_ERROR(
"sql.sql",
"Race {} Class {} Level {} does not have stats data. Using stats data of level {}.", race, class_, level + 1, level);
4357 playerInfo->levelInfo[level] = playerInfo->levelInfo[level - 1];
4366 TC_LOG_INFO(
"server.loading",
"Loading Player Create XP Data...");
4386 Field* fields = result->Fetch();
4397 TC_LOG_INFO(
"misc",
"Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_xp_for_level` table, ignoring.", current_level);
4405 }
while (result->NextRow());
4413 TC_LOG_ERROR(
"sql.sql",
"Level {} does not have XP for level data. Using data of level [{}] + 12000.", level + 1, level);
4433 TC_LOG_ERROR(
"misc",
"Tried to get non-existant Class-Level combination data for base hp/mp. Class {} Level {}", class_, level);
4551 "ID, QuestType, QuestPackageID, ContentTuningID, QuestSortID, QuestInfoID, SuggestedGroupNum, RewardNextQuest, RewardXPDifficulty, RewardXPMultiplier, "
4552 "RewardMoneyDifficulty, RewardMoneyMultiplier, RewardBonusMoney, RewardSpell, RewardHonor, RewardKillHonor, RewardFavor, StartItem, "
4553 "RewardArtifactXPDifficulty, RewardArtifactXPMultiplier, RewardArtifactCategoryID, Flags, FlagsEx, FlagsEx2, FlagsEx3, "
4554 "RewardItem1, RewardAmount1, ItemDrop1, ItemDropQuantity1, RewardItem2, RewardAmount2, ItemDrop2, ItemDropQuantity2, "
4555 "RewardItem3, RewardAmount3, ItemDrop3, ItemDropQuantity3, RewardItem4, RewardAmount4, ItemDrop4, ItemDropQuantity4, "
4556 "RewardChoiceItemID1, RewardChoiceItemQuantity1, RewardChoiceItemDisplayID1, RewardChoiceItemID2, RewardChoiceItemQuantity2, RewardChoiceItemDisplayID2, "
4557 "RewardChoiceItemID3, RewardChoiceItemQuantity3, RewardChoiceItemDisplayID3, RewardChoiceItemID4, RewardChoiceItemQuantity4, RewardChoiceItemDisplayID4, "
4558 "RewardChoiceItemID5, RewardChoiceItemQuantity5, RewardChoiceItemDisplayID5, RewardChoiceItemID6, RewardChoiceItemQuantity6, RewardChoiceItemDisplayID6, "
4559 "POIContinent, POIx, POIy, POIPriority, RewardTitle, RewardArenaPoints, RewardSkillLineID, RewardNumSkillUps, "
4560 "PortraitGiver, PortraitGiverMount, PortraitGiverModelSceneID, PortraitTurnIn, "
4561 "RewardFactionID1, RewardFactionValue1, RewardFactionOverride1, RewardFactionCapIn1, RewardFactionID2, RewardFactionValue2, RewardFactionOverride2, RewardFactionCapIn2, "
4562 "RewardFactionID3, RewardFactionValue3, RewardFactionOverride3, RewardFactionCapIn3, RewardFactionID4, RewardFactionValue4, RewardFactionOverride4, RewardFactionCapIn4, "
4563 "RewardFactionID5, RewardFactionValue5, RewardFactionOverride5, RewardFactionCapIn5, RewardFactionFlags, "
4564 "RewardCurrencyID1, RewardCurrencyQty1, RewardCurrencyID2, RewardCurrencyQty2, RewardCurrencyID3, RewardCurrencyQty3, RewardCurrencyID4, RewardCurrencyQty4, "
4565 "AcceptedSoundKitID, CompleteSoundKitID, AreaGroupID, TimeAllowed, AllowableRaces, ResetByScheduler, Expansion, ManagedWorldStateID, QuestSessionBonus, "
4566 "LogTitle, LogDescription, QuestDescription, AreaDescription, PortraitGiverText, PortraitGiverName, PortraitTurnInText, PortraitTurnInName, QuestCompletionLog "
4567 "FROM quest_template");
4570 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quests definitions. DB table `quest_template` is empty.");
4581 Field* fields = result->Fetch();
4584 auto itr =
_questTemplates.emplace(std::piecewise_construct, std::forward_as_tuple(questId), std::forward_as_tuple(
new Quest(result))).first;
4585 itr->second->_weakRef = itr->second;
4586 if (itr->second->IsAutoPush())
4588 }
while (result->NextRow());
4590 struct QuestLoaderHelper
4592 typedef void(
Quest::* QuestLoaderFunction)(
Field* fields);
4594 char const* QueryFields;
4595 char const* TableName;
4596 char const* QueryExtra;
4597 char const* TableDesc;
4598 QuestLoaderFunction LoaderFunction;
4602 QuestLoaderHelper
const QuestLoaderHelpers[] =
4605 {
"QuestID, Type1, Type2, Type3, Type4, Type5, Type6",
"quest_reward_choice_items",
"",
"reward choice items", &
Quest::LoadRewardChoiceItems },
4608 {
"QuestID, SpellID, PlayerConditionID, Type",
"quest_reward_display_spell",
"ORDER BY QuestID ASC, Idx ASC",
"reward display spells", &
Quest::LoadRewardDisplaySpell },
4611 {
"ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4",
"quest_details",
"",
"details", &
Quest::LoadQuestDetails },
4614 {
"ID, EmoteOnComplete, EmoteOnIncomplete, EmoteOnCompleteDelay, EmoteOnIncompleteDelay, CompletionText",
"quest_request_items",
"",
"request items", &
Quest::LoadQuestRequestItems },
4617 {
"ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4, RewardText",
"quest_offer_reward",
"",
"reward emotes", &
Quest::LoadQuestOfferReward },
4620 {
"ID, MaxLevel, AllowableClasses, SourceSpellID, PrevQuestID, NextQuestID, ExclusiveGroup, BreadcrumbForQuestId, RewardMailTemplateID, RewardMailDelay,"
4622 " RequiredSkillID, RequiredSkillPoints, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, ProvidedItemCount, SpecialFlags,"
4630 {
"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, "
4632 "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 },
4647 {
"QuestID, TreasurePickerID",
"quest_treasure_pickers",
"ORDER BY OrderIndex",
"treasure pickers", &
Quest::LoadTreasurePickers },
4650 {
"QuestID, HouseRoomID",
"quest_reward_house_room",
"ORDER BY OrderIndex",
"house room rewards", &
Quest::LoadRewardHouseRoom },
4653 {
"QuestID, HouseDecorID",
"quest_reward_house_decor",
"ORDER BY OrderIndex",
"house decor rewards", &
Quest::LoadRewardHouseDecor }
4656 for (QuestLoaderHelper
const& loader : QuestLoaderHelpers)
4658 result =
WorldDatabase.PQuery(
"SELECT {} FROM {} {}", loader.QueryFields, loader.TableName, loader.QueryExtra);
4661 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quest {}. DB table `{}` is empty.", loader.TableDesc, loader.TableName);
4666 Field* fields = result->Fetch();
4671 (itr->second.get()->*loader.LoaderFunction)(fields);
4673 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has data for quest {} but such quest does not exist", loader.TableName, questId);
4674 }
while (result->NextRow());
4680 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");
4683 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quest visual effects. DB table `quest_visual_effect` is empty.");
4688 Field* fields = result->Fetch();
4694 TC_LOG_ERROR(
"sql.sql",
"Table `quest_visual_effect` has visual effect for null objective id");
4701 TC_LOG_ERROR(
"sql.sql",
"Table `quest_visual_effect` has visual effect for objective {} but such objective does not exist.", vID);
4710 itr->second->LoadQuestObjectiveVisualEffect(fields);
4711 }
while (result->NextRow());
4714 std::map<uint32, uint32> usedMailTemplates;
4723 Quest* qinfo = questPair.second.get();
4732 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SpecialFlags` = {} > max allowed value. Correct `SpecialFlags` to value <= {}",
4739 TC_LOG_ERROR(
"sql.sql",
"Weekly Quest {} is marked as daily quest in `Flags`, removed daily flag.", qinfo->
GetQuestId());
4740 qinfo->
_flags &= ~QUEST_FLAGS_DAILY;
4747 TC_LOG_DEBUG(
"sql.sql",
"Daily Quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->
GetQuestId());
4756 TC_LOG_DEBUG(
"sql.sql",
"Weekly Quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->
GetQuestId());
4765 TC_LOG_DEBUG(
"sql.sql",
"Monthly quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->
GetQuestId());
4777 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemId{}` = {} but item from `RewardChoiceItemId{}` can't be rewarded with quest flag QUEST_FLAGS_TRACKING.",
4786 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `ContentTuningID` = {} but content tuning with this id does not exist.",
4795 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `QuestSortID` = {} (zone case) but zone with this id does not exist.",
4806 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `QuestSortID` = {} (sort case) but quest sort with this id does not exist.",
4815 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `QuestSortID` = {} but `RequiredSkillId` does not have a corresponding value ({}).",
4836 TC_LOG_ERROR(
"sql.sql",
"Quest {} does not contain any playable races in `AllowableRaces` (0x{:X}{:08X}), value set to -1 (all races).",
4846 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredSkillId` = {} but this skill does not exist",
4855 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredSkillPoints` = {} but max possible skill is {}, quest can't be done.",
4864 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMinRepFaction` = {} but faction template {} does not exist, quest can't be done.",
4871 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMaxRepFaction` = {} but faction template {} does not exist, quest can't be done.",
4878 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMinRepValue` = {} but max reputation is {}, quest can't be done.",
4885 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMaxRepValue` = {} and `RequiredMinRepValue` = {}, quest can't be done.",
4892 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMinRepValue` = {} but `RequiredMinRepFaction` is 0, value has no effect",
4899 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMaxRepValue` = {} but `RequiredMaxRepFaction` is 0, value has no effect",
4906 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardTitleId` = {} but CharTitle Id {} does not exist, quest can't be rewarded with title.",
4916 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SourceItemId` = {} but item with entry {} does not exist, quest can't be done.",
4922 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `StartItem` = {} but `ProvidedItemCount` = 0, set to 1 but need fix in DB.",
4929 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SourceItemId` = 0 but `SourceItemIdCount` = {}, useless value.",
4939 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SourceSpellid` = {} but spell {} doesn't exist, quest can't be done.",
4945 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SourceSpellid` = {} but spell {} is broken, quest can't be done.",
4957 if (obj.IsStoringValue() && obj.StorageIndex < 0)
4958 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has invalid StorageIndex = {} for objective type {}", qinfo->
GetQuestId(), obj.ID, obj.StorageIndex, obj.Type);
4964 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing item entry {}, quest can't be done.",
4969 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing creature entry {}, quest can't be done.",
4974 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing gameobject entry {}, quest can't be done.",
4979 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing creature entry {}, quest can't be done.",
4986 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing faction id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
4989 if (obj.Amount <= 0)
4990 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has invalid player kills count {}", qinfo->
GetQuestId(), obj.ID, obj.Amount);
4996 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing currency {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
4997 if (obj.Amount <= 0)
4998 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has invalid currency amount {}", qinfo->
GetQuestId(), obj.ID, obj.Amount);
5002 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing spell id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
5006 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing creature entry {}, quest can't be done.",
5011 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing battlepet species id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
5015 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing criteria tree id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
5019 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing AreaTrigger.db2 id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
5024 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing areatrigger id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
5032 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has unhandled type {}", qinfo->
GetQuestId(), obj.ID, obj.Type);
5047 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `ItemDrop{}` = {} but item with entry {} does not exist, quest can't be done.",
5056 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `ItemDrop{}` = 0 but `ItemDropQuantity{}` = {}.",
5072 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemId{}` = {} but item with entry {} does not exist, quest will not reward this item.",
5080 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemId{}` = {} but currency with id {} does not exist, quest will not reward this currency.",
5086 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemType{}` = {} but it is not a valid item type, reward removed.",
5094 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemId{}` = {} but `RewardChoiceItemCount{}` = 0.",
5100 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemId{}` = 0 but `RewardChoiceItemCount{}` = {}.",
5113 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardItemId{}` = {} but item with entry {} does not exist, quest will not reward this item.",
5120 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardItemId{}` = {} but `RewardItemCount{}` = 0, quest will not reward this item.",
5127 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardItemId{}` = 0 but `RewardItemCount{}` = {}.",
5150 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardFactionId{}` = 0 but `RewardFactionValueIdOverride{}` = {}.",
5162 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSpellCast` = {} but spell {} does not exist, quest will not have a spell reward.",
5169 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSpellCast` = {} but spell {} is broken, quest will not have a spell reward.",
5179 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardMailTemplateId` = {} but mail template {} does not exist, quest will not have a mail reward.",
5188 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardMailTemplateId` = {} but mail template {} already used for quest {}, quest will not have a mail reward.",
5202 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `NextQuestInChain` = {} but quest {} does not exist, quest chain will not work.",
5214 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardCurrencyId{}` = {} but `RewardCurrencyCount{}` = 0, quest can't be done.",
5221 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardCurrencyId{}` = {} but currency with entry {} does not exist, quest can't be done.",
5228 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardCurrencyId{}` = 0 but `RewardCurrencyCount{}` = {}, quest can't be done.",
5238 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SoundAccept` = {} but sound {} does not exist, set to 0.",
5248 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SoundTurnIn` = {} but sound {} does not exist, set to 0.",
5258 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSkillId` = {} but this skill does not exist",
5263 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSkillId` = {} but `RewardSkillPoints` is 0",
5272 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSkillPoints` = {} but max possible skill is {}, quest can't be done.",
5278 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSkillPoints` = {} but `RewardSkillId` is 0",
5289 else if (prevQuestItr->second->_breadcrumbForQuestId)
5290 TC_LOG_ERROR(
"sql.sql",
"Quest {} should not be unlocked by breadcrumb quest {}", qinfo->
_id, prevQuestId);
5301 nextQuestItr->second->DependentPreviousQuests.push_back(qinfo->
GetQuestId());
5308 TC_LOG_ERROR(
"sql.sql",
"Quest {} is a breadcrumb for quest {}, but no such quest exists", qinfo->
_id, breadcrumbForQuestId);
5326 Quest* qinfo = questPair.second.get();
5329 std::set<uint32> questSet;
5331 while(breadcrumbForQuestId)
5335 if (!questSet.insert(qinfo->
_id).second)
5337 TC_LOG_ERROR(
"sql.sql",
"Breadcrumb quests {} and {} are in a loop", qid, breadcrumbForQuestId);
5363 TC_LOG_INFO(
"server.loading",
"Loading GO Start Quest Data...");
5365 TC_LOG_INFO(
"server.loading",
"Loading GO End Quest Data...");
5367 TC_LOG_INFO(
"server.loading",
"Loading Creature Start Quest Data...");
5369 TC_LOG_INFO(
"server.loading",
"Loading Creature End Quest Data...");
5381 "LogTitle, LogDescription, QuestDescription, AreaDescription, PortraitGiverText, PortraitGiverName, PortraitTurnInText, PortraitTurnInName, QuestCompletionLog"
5382 " FROM quest_template_locale");
5388 Field* fields = result->Fetch();
5407 }
while (result->NextRow());
5424 Field* fields = result->Fetch();
5436 while (result->NextRow());
5456 Field* fields = result->Fetch();
5465 TC_LOG_ERROR(
"sql.sql",
"Table `quest_greeting_locale`: creature template entry {} does not exist.",
id);
5472 TC_LOG_ERROR(
"sql.sql",
"Table `quest_greeting_locale`: gameobject template entry {} does not exist.",
id);
5490 while (result->NextRow());
5507 Field* fields = result->Fetch();
5518 }
while (result->NextRow());
5535 Field* fields = result->Fetch();
5546 }
while (result->NextRow());
5560 if (tableName.empty())
5563 if (
sMapMgr->IsScriptScheduled())
5566 TC_LOG_INFO(
"server.loading",
"Loading {}...", tableName);
5572 QueryResult result =
WorldDatabase.PQuery(
"SELECT id, delay, command, datalong, datalong2, dataint, x, y, z, o{} FROM {}", isSpellScriptTable ?
", effIndex" :
"", tableName);
5576 TC_LOG_INFO(
"server.loading",
">> Loaded 0 script definitions. DB table `{}` is empty!", tableName);
5584 Field* fields = result->Fetch();
5588 if (isSpellScriptTable)
5607 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid talk type (datalong = {}) in SCRIPT_COMMAND_TALK for script id {}",
5613 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid talk text id (dataint = {}) in SCRIPT_COMMAND_TALK for script id {}",
5625 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid emote id (datalong = {}) in SCRIPT_COMMAND_EMOTE for script id {}",
5636 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid map (Id: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
5643 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
5655 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid quest (ID: {}) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id {}",
5662 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.",
5669 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 {}",
5676 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",
5683 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",
5695 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_KILL_CREDIT for script id {}",
5707 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid gameobject (GUID: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5715 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5726 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has gameobject type ({}) unsupported by command SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5727 tableName, info->
entry, tmp.
id);
5737 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
5744 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
5757 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid gameobject (GUID: {}) in {} for script id {}",
5765 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in {} for script id {}",
5772 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has gameobject type ({}) unsupported by command {} for script id {}",
5784 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
5790 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using unknown flags in datalong2 ({}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
5801 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5807 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using unknown target in datalong2 ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5813 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using unknown flags in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5819 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using invalid creature entry in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5830 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has nonexistent item (entry: {}) in SCRIPT_COMMAND_CREATE_ITEM for script id {}",
5836 TC_LOG_ERROR(
"sql.sql",
"Table `{}` SCRIPT_COMMAND_CREATE_ITEM but amount is {} for script id {}",
5846 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid AnimKid id (datalong = {}) in SCRIPT_COMMAND_PLAY_ANIMKIT for script id {}",
5863 if (scripts->find(tmp.
id) == scripts->end())
5866 (*scripts)[tmp.
id] = emptyMap;
5868 (*scripts)[tmp.
id].insert(std::pair<uint32, ScriptInfo>(tmp.
delay, tmp));
5872 while (result->NextRow());
5889 TC_LOG_ERROR(
"sql.sql",
"Table `spell_scripts` has not existing spell (Id: {}) as script id", spellId);
5896 TC_LOG_ERROR(
"sql.sql",
"Table `spell_scripts` has too high effect index {} for spell (Id: {}) as script id",
uint32(i), spellId);
5902 TC_LOG_ERROR(
"sql.sql",
"Table `spell_scripts` - spell {} effect {} is not SPELL_EFFECT_SCRIPT_EFFECT or SPELL_EFFECT_DUMMY", spellId,
uint32(i));
5913 EventContainer eventSet = gameObjectTemplatePair.second.GetEventScriptSet();
5914 _eventStore.insert(eventSet.begin(), eventSet.end());
5920 _eventStore.insert(spellEffect->EffectMiscValue[0]);
5925 if (node->ArrivalEventID)
5928 if (node->DepartureEventID)
5933 auto addCriteriaEventsToStore = [&](
CriteriaList const& criteriaList)
5935 for (
Criteria const* criteria : criteriaList)
5936 if (criteria->Entry->Asset.EventID)
5937 _eventStore.insert(criteria->Entry->Asset.EventID);
5943 addCriteriaEventsToStore(
sCriteriaMgr->GetPlayerCriteriaByType(criteriaType, 0));
5944 addCriteriaEventsToStore(
sCriteriaMgr->GetGuildCriteriaByType(criteriaType));
5945 addCriteriaEventsToStore(
sCriteriaMgr->GetQuestObjectiveCriteriaByType(criteriaType));
5950 addCriteriaEventsToStore(
sCriteriaMgr->GetScenarioCriteriaByTypeAndScenario(criteriaType, scenario->ID));
5973 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 {}",
5984 TC_LOG_INFO(
"server.loading",
">> Loaded 0 event scripts. DB table `event_script_names` is empty.");
5990 Field* fields = result->Fetch();
5997 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 {}",
6002 }
while (result->NextRow());
6017 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spell script names. DB table `spell_script_names` is empty!");
6026 Field* fields = result->Fetch();
6031 bool allRanks =
false;
6041 TC_LOG_ERROR(
"sql.sql",
"Scriptname: `{}` spell (Id: {}) does not exist.", scriptName, fields[0].GetInt32());
6048 TC_LOG_ERROR(
"sql.sql",
"Scriptname: `{}` spell (Id: {}) has no ranks of spell.", scriptName, fields[0].GetInt32());
6052 TC_LOG_ERROR(
"sql.sql",
"Scriptname: `{}` spell (Id: {}) is not first rank of spell.", scriptName, fields[0].GetInt32());
6065 TC_LOG_ERROR(
"sql.sql",
"Scriptname: `{}` spell (Id: {}) is ranked spell. Perhaps not all ranks are assigned to this script.", scriptName, spellId);
6072 while (result->NextRow());
6083 TC_LOG_INFO(
"server.loading",
">> Validated 0 scripts.");
6097 std::unique_ptr<SpellScript> spellScript(spellScriptLoader->GetSpellScript());
6098 std::unique_ptr<AuraScript> auraScript(spellScriptLoader->GetAuraScript());
6100 if (!spellScript && !auraScript)
6102 TC_LOG_ERROR(
"scripts",
"Functions GetSpellScript() and GetAuraScript() of script `{}` do not return objects - script skipped",
GetScriptName(spell.second.first));
6104 spell.second.second =
false;
6110 spellScript->_Init(spellScriptLoader->GetName(), spellEntry->
Id);
6111 spellScript->_Register();
6113 if (!spellScript->_Validate(spellEntry))
6115 spell.second.second =
false;
6122 auraScript->_Init(spellScriptLoader->GetName(), spellEntry->
Id);
6123 auraScript->_Register();
6125 if (!auraScript->_Validate(spellEntry))
6127 spell.second.second =
false;
6133 spell.second.second =
true;
6136 spell.second.second =
false;
6147 QueryResult result =
WorldDatabase.Query(
"SELECT ID, `Text`, NextPageID, PlayerConditionID, Flags FROM page_text");
6150 TC_LOG_INFO(
"server.loading",
">> Loaded 0 page texts. DB table `page_text` is empty!");
6157 Field* fields = result->Fetch();
6169 while (result->NextRow());
6172 if (itr->second.NextPageID)
6174 TC_LOG_ERROR(
"sql.sql",
"Page text (ID: {}) has non-existing `NextPageID` ({})", itr->first, itr->second.NextPageID);
6181 PageTextContainer::const_iterator itr =
_pageTextStore.find(pageEntry);
6183 return &(itr->second);
6201 Field* fields = result->Fetch();
6212 }
while (result->NextRow());
6226 TC_LOG_INFO(
"server.loading",
">> Loaded 0 instance templates. DB table `page_text` is empty!");
6233 Field* fields = result->Fetch();
6239 TC_LOG_ERROR(
"sql.sql",
"ObjectMgr::LoadInstanceTemplate: bad mapid {} for template!", mapID);
6245 instanceTemplate.
Parent =
uint32(fields[1].GetUInt16());
6252 while (result->NextRow());
6261 return &(itr->second);
6268 NpcTextContainer::const_iterator itr =
_npcTextStore.find(Text_ID);
6270 return &itr->second;
6279 "Probability0, Probability1, Probability2, Probability3, Probability4, Probability5, Probability6, Probability7, "
6280 "BroadcastTextID0, BroadcastTextID1, BroadcastTextID2, BroadcastTextID3, BroadcastTextID4, BroadcastTextID5, BroadcastTextID6, BroadcastTextID7"
6284 TC_LOG_INFO(
"server.loading",
">> Loaded 0 npc texts, table is empty!");
6292 Field* fields = result->Fetch();
6297 TC_LOG_ERROR(
"sql.sql",
"Table `npc_text` has record with reserved id 0, ignore.");
6326 TC_LOG_ERROR(
"sql.sql",
"NPCText (ID: {}) has a probability (Index: {}) set, but no BroadcastTextID to go with it", textID, i);
6331 float probabilitySum = std::accumulate(std::begin(npcText.
Data), std::end(npcText.
Data), 0.0f, [](
float sum,
NpcTextData const& data) { return sum + data.Probability; });
6332 if (probabilitySum <= 0.0f)
6334 TC_LOG_ERROR(
"sql.sql",
"NPCText (ID: {}) has a probability sum 0, no text can be selected from it, skipped.", textID);
6340 while (result->NextRow());
6352 localtime_r(&curTime, <);
6353 TC_LOG_INFO(
"misc",
"Returning mails current time: hour: {}, minute: {}, second: {} ", lt.tm_hour, lt.tm_min, lt.tm_sec);
6367 TC_LOG_INFO(
"server.loading",
">> No expired mails found.");
6379 Field* fields = items->Fetch();
6383 itemsCache[mailId].push_back(item);
6384 }
while (items->NextRow());
6388 uint32 returnedCount = 0;
6391 Field* fields = result->Fetch();
6401 bool has_items = fields[4].
GetBool();
6419 for (MailItemInfoVec::iterator itr2 = m->
items.begin(); itr2 != m->
items.end(); ++itr2)
6441 for (MailItemInfoVec::iterator itr2 = m->
items.begin(); itr2 != m->
items.end(); ++itr2)
6466 while (result->NextRow());
6468 TC_LOG_INFO(
"server.loading",
">> Processed {} expired mails: {} deleted and {} returned in {} ms", deletedCount + returnedCount, deletedCount, returnedCount,
GetMSTimeDiffToNow(oldMSTime));
6481 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quest trigger points. DB table `areatrigger_involvedrelation` is empty.");
6491 Field* fields = result->Fetch();
6499 TC_LOG_ERROR(
"sql.sql",
"Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", trigger_ID);
6507 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger_involvedrelation` has record (id: {}) for not existing quest {}", trigger_ID, quest_ID);
6513 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);
6519 }
while (result->NextRow());
6565 QueryResult result =
WorldDatabase.Query(
"SELECT ID, type, GreetEmoteType, GreetEmoteDelay, Greeting FROM quest_greeting");
6568 TC_LOG_INFO(
"server.loading",
">> Loaded 0 npc texts, table is empty!");
6575 Field* fields = result->Fetch();
6584 TC_LOG_ERROR(
"sql.sql",
"Table `quest_greeting`: creature template entry {} does not exist.",
id);
6591 TC_LOG_ERROR(
"sql.sql",
"Table `quest_greeting`: gameobject template entry {} does not exist.",
id);
6601 std::string greeting = fields[4].
GetString();
6603 _questGreetingStore[type].emplace(std::piecewise_construct, std::forward_as_tuple(
id), std::forward_as_tuple(greetEmoteType, greetEmoteDelay, std::move(greeting)));
6606 while (result->NextRow());
6621 TC_LOG_INFO(
"server.loading",
">> Loaded 0 tavern triggers. DB table `areatrigger_tavern` is empty.");
6631 Field* fields = result->Fetch();
6638 TC_LOG_ERROR(
"sql.sql",
"Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
6643 }
while (result->NextRow());
6657 TC_LOG_INFO(
"server.loading",
">> Loaded 0 areatrigger scripts. DB table `areatrigger_scripts` is empty.");
6663 Field* fields = result->Fetch();
6671 TC_LOG_ERROR(
"sql.sql",
"AreaTrigger (ID: {}) does not exist in `AreaTrigger.dbc`.", triggerId);
6676 while (result->NextRow());
6710 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);
6735 path = taxiPath->
ID;
6736 cost = taxiPath->
Cost;
6762 if (mount_entry == 0 && allowed_alt_team)
6774 TC_LOG_ERROR(
"sql.sql",
"No displayid found for the taxi mount with the entry {}! Can't load it!", mount_entry);
6777 mountModel = *model;
6809 TC_LOG_INFO(
"server.loading",
">> Loaded 0 graveyard-zone links. DB table `graveyard_zone` is empty.");
6819 Field* fields = result->Fetch();
6827 TC_LOG_ERROR(
"sql.sql",
"Table `graveyard_zone` has a record for non-existing graveyard (WorldSafeLocsID: {}), skipped.", safeLocId);
6834 TC_LOG_ERROR(
"sql.sql",
"Table `graveyard_zone` has a record for non-existing Zone (ID: {}), skipped.", zoneId);
6839 TC_LOG_ERROR(
"sql.sql",
"Table `graveyard_zone` has a duplicate record for Graveyard (ID: {}) and Zone (ID: {}), skipped.", safeLocId, zoneId);
6840 }
while (result->NextRow());
6847 enum DefaultGraveyard
6849 HORDE_GRAVEYARD = 10,
6850 ALLIANCE_GRAVEYARD = 4
6857 else return nullptr;
6873 TC_LOG_ERROR(
"misc",
"ZoneId not found for map {} coords ({}, {}, {})", MapId, x, y, z);
6882 while (!graveyard && parentEntry)
6888 parentEntry =
nullptr;
6891 if (!graveyard && !
sMapStore.LookupEntry(MapId)->IsBattlegroundOrArena())
6894 TC_LOG_ERROR(
"sql.sql",
"Table `graveyard_zone` incomplete: Zone {} Team {} does not have a linked graveyard.", zoneId, team);
6929 for (; range.first != range.second; ++range.first)
6935 if (conditionObject)
6945 bool teamConditionMet =
true;
6948 for (
Condition const& cond : *conditions)
6953 if (cond.ConditionValue1 == team)
6956 teamConditionMet =
false;
6960 if (!teamConditionMet)
6980 if (!distEntr || dist2 < *distEntr)
6990 if (!distNear || dist2 < *distNear)
7010 for (; range.first != range.second; ++range.first)
7024 if (
QueryResult result =
WorldDatabase.Query(
"SELECT ID, MapID, LocX, LocY, LocZ, Facing, TransportSpawnId FROM world_safe_locs"))
7028 Field* fields = result->Fetch();
7030 WorldLocation loc(fields[1].GetUInt32(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat(),
DegToRad(fields[5].GetFloat()));
7033 TC_LOG_ERROR(
"sql.sql",
"World location (ID: {}) has a invalid position {}, skipped",
id, loc);
7038 if (transportSpawnId && !
sTransportMgr->GetTransportSpawn(*transportSpawnId))
7040 TC_LOG_ERROR(
"sql.sql",
"World location (ID: {}) has a invalid transportSpawnID {}, skipped.",
id, *transportSpawnId);
7045 worldSafeLocs.
ID = id;
7049 }
while (result->NextRow());
7054 TC_LOG_INFO(
"server.loading",
">> Loaded 0 world locations. DB table `world_safe_locs` is empty.");
7086 GraveyardStore.insert(GraveyardContainer::value_type(zoneId, data));
7139 TC_LOG_INFO(
"server.loading",
">> Loaded 0 area trigger teleport definitions. DB table `areatrigger_teleport` is empty.");
7147 Field* fields = result->Fetch();
7157 TC_LOG_ERROR(
"sql.sql",
"Area Trigger (ID: {}) does not exist in AreaTrigger.dbc.", Trigger_ID);
7164 TC_LOG_ERROR(
"sql.sql",
"Area Trigger (ID: {}) has a non-existing Port Loc (ID: {}) in WorldSafeLocs.dbc, skipped", Trigger_ID, PortLocID);
7170 }
while (result->NextRow());
7183 if (!path || path->
Locations.size() < 4)
7190 return Position(pos.X, pos.Y, pos.Z);
7195 polygon.
Height = pathProperty->Value * 0.001f + 0.02f;
7206 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");
7210 TC_LOG_INFO(
"server.loading",
">> Loaded 0 access requirement definitions. DB table `access_requirement` is empty.");
7218 Field* fields = result->Fetch();
7223 TC_LOG_ERROR(
"sql.sql",
"Map {} referenced in `access_requirement` does not exist, skipped.", mapid);
7228 if (!
sDB2Manager.GetMapDifficultyData(mapid, difficulty))
7230 TC_LOG_ERROR(
"sql.sql",
"Map {} referenced in `access_requirement` does not have difficulty {}, skipped", mapid, difficulty);
7251 TC_LOG_ERROR(
"sql.sql",
"Key item {} does not exist for map {} difficulty {}, removing key requirement.", ar->
item, mapid, difficulty);
7261 TC_LOG_ERROR(
"sql.sql",
"Second item {} does not exist for map {} difficulty {}, removing key requirement.", ar->
item2, mapid, difficulty);
7270 TC_LOG_ERROR(
"sql.sql",
"Required Alliance Quest {} not exist for map {} difficulty {}, remove quest done requirement.", ar->
quest_A, mapid, difficulty);
7279 TC_LOG_ERROR(
"sql.sql",
"Required Horde Quest {} not exist for map {} difficulty {}, remove quest done requirement.", ar->
quest_H, mapid, difficulty);
7288 TC_LOG_ERROR(
"sql.sql",
"Required Achievement {} not exist for map {} difficulty {}, remove quest done requirement.", ar->
achievement, mapid, difficulty);
7294 }
while (result->NextRow());
7311 parentId = iTemplate->Parent;
7316 if (itr->second->Loc.GetMapId() == entrance_map)
7333 if (itr->second->Loc.GetMapId() ==
Map)
7350 GetGenerator<HighGuid::Item>().Set((*result)[0].GetUInt64() + 1);
7353 CharacterDatabase.PExecute(
"DELETE FROM character_inventory WHERE item >= '{}'", GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed());
7354 CharacterDatabase.PExecute(
"DELETE FROM mail_items WHERE item_guid >= '{}'", GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed());
7355 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 >= '{}'",
7356 GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed());
7357 CharacterDatabase.PExecute(
"DELETE FROM guild_bank_item WHERE item_guid >= '{}'", GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed());
7359 result =
WorldDatabase.Query(
"SELECT MAX(guid) FROM transports");
7369 _mailId = (*result)[0].GetUInt64()+1;
7373 sArenaTeamMgr->SetNextArenaTeamId((*result)[0].GetUInt32()+1);
7375 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");
7381 sGuildMgr->SetNextGuildId((*result)[0].GetUInt64()+1);
7385 sGroupMgr->SetGroupDbStoreSize((*result)[0].GetUInt32()+1);
7387 result =
WorldDatabase.Query(
"SELECT MAX(guid) FROM creature");
7391 result =
WorldDatabase.Query(
"SELECT MAX(guid) FROM gameobject");
7405 TC_LOG_ERROR(
"misc",
"Auctions ids overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7415 TC_LOG_ERROR(
"misc",
"EquipmentSet guid overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7425 TC_LOG_ERROR(
"misc",
"Mail ids overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7435 TC_LOG_ERROR(
"misc",
"_hiPetNumber Id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info.");
7445 TC_LOG_ERROR(
"misc",
"Creature spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info.");
7455 TC_LOG_ERROR(
"misc",
"GameObject spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7468 QueryResult result =
WorldDatabase.Query(
"SELECT entry, locale, name, castBarCaption, unk1 FROM gameobject_template_locale");
7474 Field* fields = result->Fetch();
7488 }
while (result->NextRow());
7506 Field* fields = result->Fetch();
7515 }
while (result->NextRow());
7525 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but lock (Id: {}) not found.",
7526 goInfo->
entry, goInfo->
type, N, dataN, dataN);
7534 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but GO (Entry {}) have not GAMEOBJECT_TYPE_TRAP ({}) type.",
7544 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but Spell (Entry {}) not exist.",
7545 goInfo->
entry, goInfo->
type, N, dataN, dataN);
7553 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but correct chair height in range 0..{}.",
7566 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but expected boolean (0/1) noDamageImmune field value.", goTemplate->
entry, goTemplate->
type, N, dataN);
7575 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but expected boolean (0/1) consumable field value.",
7586 go.
entry = db2go->ID;
7587 go.
type = db2go->TypeID;
7589 go.
name = db2go->Name[
sWorld->GetDefaultDbcLocale()];
7590 go.
size = db2go->Scale;
7592 std::ranges::copy(db2go->PropValue, std::begin(go.
raw.
data));
7599 QueryResult result =
WorldDatabase.Query(
"SELECT entry, type, displayId, name, IconName, castBarCaption, unk1, size, "
7601 "Data0, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11, Data12, "
7603 "Data13, Data14, Data15, Data16, Data17, Data18, Data19, Data20, Data21, Data22, Data23, Data24, Data25, Data26, Data27, Data28, "
7605 "Data29, Data30, Data31, Data32, Data33, Data34, ContentTuningId, RequiredLevel, AIName, ScriptName, StringId "
7606 "FROM gameobject_template");
7610 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject definitions. DB table `gameobject_template` is empty.");
7617 Field* fields = result->Fetch();
7643 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {}) has non-registered `AIName` '{}' set, removing", got.
entry, got.
AIName);
7693 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {} GoType: {}) have data0={} but SpellFocus (Id: {}) not exist.",
7711 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {} GoType: {}) have data7={} but PageText (Entry {}) not exist.",
7736 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {} GoType: {}) have data0={} but TaxiPath (Id: {}) not exist.",
7776 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {} GoType: {}) have data2 = {} but AnimKit.dbc (Id: {}) not exist, set to 0.",
7796 }
while (result->NextRow());
7806 QueryResult result =
WorldDatabase.Query(
"SELECT entry, faction, flags, mingold, maxgold, artkit0, artkit1, artkit2, artkit3, artkit4, WorldEffectID, AIAnimKitID FROM gameobject_template_addon");
7810 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject template addon definitions. DB table `gameobject_template_addon` is empty.");
7817 Field* fields = result->Fetch();
7824 TC_LOG_ERROR(
"sql.sql",
"GameObject template (Entry: {}) does not exist but has a record in `gameobject_template_addon`", entry);
7844 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {}) has invalid `artkit{}` ({}) defined, set to zero instead.", entry, i, artKitID);
7848 gameObjectAddon.
ArtKits[i] = artKitID;
7853 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {}) has invalid faction ({}) defined in `gameobject_template_addon`.", entry, gameObjectAddon.
Faction);
7855 if (gameObjectAddon.
Maxgold > 0)
7863 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry {} GoType: {}) cannot be looted but has maxgold set in `gameobject_template_addon`.", entry, got->
type);
7870 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {}) has invalid WorldEffectID ({}) defined in `gameobject_template_addon`, set to 0.", entry, gameObjectAddon.
WorldEffectID);
7876 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {}) has invalid AIAnimKitID ({}) defined in `gameobject_template_addon`, set to 0.", entry, gameObjectAddon.
AIAnimKitID);
7882 while (result->NextRow());
7895 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject faction and flags overrides. DB table `gameobject_overrides` is empty.");
7902 Field* fields = result->Fetch();
7908 TC_LOG_ERROR(
"sql.sql",
"GameObject (SpawnId: {}) does not exist but has a record in `gameobject_overrides`", spawnId);
7917 TC_LOG_ERROR(
"sql.sql",
"GameObject (SpawnId: {}) has invalid faction ({}) defined in `gameobject_overrides`.", spawnId, gameObjectOverride.
Faction);
7920 }
while (result->NextRow());
7933 TC_LOG_INFO(
"server.loading",
">> Loaded 0 BaseXP definitions. DB table `exploration_basexp` is empty.");
7941 Field* fields = result->Fetch();
7947 while (result->NextRow());
7978 TC_LOG_ERROR(
"sql.sql",
"Fishable areaId {} is not properly defined in `skill_fishing_base_level`.", areaEntry->
ID);
7986 return itr !=
_skillTiers.end() ? &itr->second :
nullptr;
7994 while (
Value[tierIndex] == 0 && tierIndex > 0)
7997 return Value[tierIndex];
8008 TC_LOG_INFO(
"server.loading",
">> Loaded 0 pet name parts. DB table `pet_name_generation` is empty!");
8016 Field* fields = result->Fetch();
8017 std::string word = fields[0].
GetString();
8019 bool half = fields[2].
GetBool();
8026 while (result->NextRow());
8038 Field* fields = result->Fetch();
8050 if (list0.empty() || list1.empty())
8054 return std::string();
8058 return std::string(petname);
8063 return *(list0.begin()+
urand(0, list0.size()-1)) + *(list1.begin()+
urand(0, list1.size()-1));
8073 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");
8076 TC_LOG_INFO(
"server.loading",
">> Loaded `reputation_reward_rate`, table is empty!");
8082 Field* fields = result->Fetch();
8099 TC_LOG_ERROR(
"sql.sql",
"Faction (faction.dbc) {} does not exist but is used in `reputation_reward_rate`", factionId);
8105 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has quest_rate with invalid rate {}, skipping data for faction {}", repRate.
questRate, factionId);
8111 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has quest_daily_rate with invalid rate {}, skipping data for faction {}", repRate.
questDailyRate, factionId);
8117 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has quest_weekly_rate with invalid rate {}, skipping data for faction {}", repRate.
questWeeklyRate, factionId);
8123 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has quest_monthly_rate with invalid rate {}, skipping data for faction {}", repRate.
questMonthlyRate, factionId);
8129 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has quest_repeatable_rate with invalid rate {}, skipping data for faction {}", repRate.
questRepeatableRate, factionId);
8135 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has creature_rate with invalid rate {}, skipping data for faction {}", repRate.
creatureRate, factionId);
8141 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has spell_rate with invalid rate {}, skipping data for faction {}", repRate.
spellRate, factionId);
8149 while (result->NextRow());
8166 "IsTeamAward1, MaxStanding1, RewOnKillRepValue1, IsTeamAward2, MaxStanding2, RewOnKillRepValue2, TeamDependent "
8167 "FROM creature_onkill_reputation");
8171 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature award reputation definitions. DB table `creature_onkill_reputation` is empty.");
8177 Field* fields = result->Fetch();
8194 TC_LOG_ERROR(
"sql.sql",
"Table `creature_onkill_reputation` has data for nonexistent creature entry ({}), skipped", creature_id);
8203 TC_LOG_ERROR(
"sql.sql",
"Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.
RepFaction1);
8213 TC_LOG_ERROR(
"sql.sql",
"Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.
RepFaction2);
8221 }
while (result->NextRow());
8233 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");
8237 TC_LOG_INFO(
"server.loading",
">> Loaded `reputation_spillover_template`, table is empty.");
8243 Field* fields = result->Fetch();
8269 TC_LOG_ERROR(
"sql.sql",
"Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", factionId);
8275 TC_LOG_ERROR(
"sql.sql",
"Faction (faction.dbc) {} in `reputation_spillover_template` does not belong to any team, skipping", factionId);
8279 bool invalidSpilloverFaction =
false;
8286 if (!factionSpillover)
8288 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);
8289 invalidSpilloverFaction =
true;
8295 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);
8296 invalidSpilloverFaction =
true;
8302 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]);
8303 invalidSpilloverFaction =
true;
8309 if (invalidSpilloverFaction)
8316 while (result->NextRow());
8330 QueryResult result =
WorldDatabase.Query(
"SELECT ID, PositionX, PositionY, PositionZ, Icon, Flags, Importance, Name, WMOGroupID FROM points_of_interest");
8334 TC_LOG_INFO(
"server.loading",
">> Loaded 0 Points of Interest definitions. DB table `points_of_interest` is empty.");
8340 Field* fields = result->Fetch();
8345 pointOfInterest.
ID = id;
8346 pointOfInterest.
Pos.
Relocate(fields[1].GetFloat(), fields[2].GetFloat(), fields[3].GetFloat());
8355 TC_LOG_ERROR(
"sql.sql",
"Table `points_of_interest` (ID: {}) have invalid coordinates (PositionX: {} PositionY: {}, PositionZ: {}), ignored.",
8363 }
while (result->NextRow());
8375 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");
8378 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty.");
8383 QueryResult pointsResult =
WorldDatabase.Query(
"SELECT QuestID, Idx1, X, Y, Z FROM quest_poi_points ORDER BY QuestID DESC, Idx1, Idx2");
8385 std::unordered_map<int32, std::map<int32, std::vector<QuestPOIBlobPoint>>> allPoints;
8391 Field* fields = pointsResult->Fetch();
8399 allPoints[QuestID][Idx1].emplace_back(x, y, z);
8400 }
while (pointsResult->NextRow());
8405 Field* fields = result->Fetch();
8421 bool alwaysAllowMergingBlobs = fields[14].
GetBool();
8424 TC_LOG_ERROR(
"sql.sql",
"`quest_poi` quest id ({}) Idx1 ({}) does not exist in `quest_template`", questID, idx1);
8432 poiData.
Blobs.emplace_back(blobIndex, objectiveIndex, questObjectiveID, questObjectID, mapID, uiMapID, priority,
flags,
8433 worldEffectID, playerConditionID, navigationPlayerConditionID, spawnTrackingID, std::move(*points), alwaysAllowMergingBlobs);
8438 TC_LOG_ERROR(
"sql.sql",
"Table quest_poi references unknown quest points for quest {} POI id {}", questID, blobIndex);
8440 }
while (result->NextRow());
8451 QueryResult result =
WorldDatabase.Query(
"SELECT npc_entry, spell_id, cast_flags, user_type FROM npc_spellclick_spells");
8455 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spellclick spells. DB table `npc_spellclick_spells` is empty.");
8463 Field* fields = result->Fetch();
8469 TC_LOG_ERROR(
"sql.sql",
"Table npc_spellclick_spells references unknown creature_template {}. Skipping entry.", npc_entry);
8477 TC_LOG_ERROR(
"sql.sql",
"Table npc_spellclick_spells creature: {} references unknown spellid {}. Skipping entry.", npc_entry, spellid);
8483 TC_LOG_ERROR(
"sql.sql",
"Table npc_spellclick_spells creature: {} references unknown user type {}. Skipping entry.", npc_entry,
uint32(userType));
8494 while (result->NextRow());
8502 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);
8503 creatureTemplatePair.second.npcflag &= ~UNIT_NPC_FLAG_SPELLCLICK;
8558 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quest relations from `{}`, table is empty.", table);
8564 uint32 id = result->Fetch()[0].GetUInt32();
8565 uint32 quest = result->Fetch()[1].GetUInt32();
8569 TC_LOG_ERROR(
"sql.sql",
"Table `{}`: Quest {} listed for entry {} does not exist.", table, quest,
id);
8573 map.insert(QuestRelations::value_type(
id, quest));
8575 reverseMap->insert(QuestRelationsReverse::value_type(quest,
id));
8577 }
while (result->NextRow());
8590 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject_queststarter` has data for nonexistent gameobject entry ({}) and existed quest {}", itr->first, itr->second);
8592 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);
8604 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject_questender` has data for nonexistent gameobject entry ({}) and existed quest {}", itr->first, itr->second);
8606 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);
8618 TC_LOG_ERROR(
"sql.sql",
"Table `creature_queststarter` has data for nonexistent creature entry ({}) and existed quest {}", itr->first, itr->second);
8620 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);
8632 TC_LOG_ERROR(
"sql.sql",
"Table `creature_questender` has data for nonexistent creature entry ({}) and existed quest {}", itr->first, itr->second);
8634 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);
8653 _reservedNamesStore.clear();
8659 TC_LOG_INFO(
"server.loading",
">> Loaded 0 reserved player names. DB table `reserved_name` is empty!");
8668 fields = result->Fetch();
8669 std::string name= fields[0].
GetString();
8674 TC_LOG_ERROR(
"misc",
"Table `reserved_name` has invalid name: {}", name);
8680 _reservedNamesStore.insert(wstr);
8683 while (result->NextRow());
8696 return _reservedNamesStore.find(wstr) != _reservedNamesStore.end();
8701 if (std::shared_ptr<Realm const> currentRealm =
sRealmList->GetCurrentRealm())
8703 return create ? category->GetCreateCharsetMask() : category->GetExistingCharsetMask();
8710 if (strictMask == 0)
8723 if (strictMask & 0x2)
8740 if (strictMask & 0x1)
8759 if (wname.size() < minName)
8767 for (
size_t i = 2; i < wname.size(); ++i)
8768 if (wname[i] == wname[i-1] && wname[i] == wname[i-2])
8784 if (wname.size() < minName)
8802 if (wname.size() < minName)
8816 _gameObjectForQuestStore.clear();
8818 if (_gameObjectTemplateStore.empty())
8820 TC_LOG_INFO(
"server.loading",
">> Loaded 0 GameObjects for quests");
8827 for (
auto const& gameObjectTemplatePair : _gameObjectTemplateStore)
8829 switch (gameObjectTemplatePair.second.type)
8837 if (gameObjectTemplatePair.second.chest.questID
8846 if (gameObjectTemplatePair.second.generic.questID > 0)
8852 if (gameObjectTemplatePair.second.spellFocus.questID > 0)
8858 if (gameObjectTemplatePair.second.goober.questID > 0)
8874 _gameObjectForQuestStore.insert(gameObjectTemplatePair.first);
8878 for (
auto [questObjectiveId, objective] : _questObjectives)
8883 _gameObjectForQuestStore.insert(objective->ObjectID);
8894 _trinityStringStore.clear();
8896 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");
8899 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.");
8905 Field* fields = result->Fetch();
8916 while (result->NextRow());
8926 if (ts->Content.size() >
size_t(locale) && !ts->Content[locale].empty())
8927 return ts->
Content[locale].c_str();
8931 TC_LOG_ERROR(
"sql.sql",
"Trinity string entry {} not found in DB.", entry);
8939 _fishingBaseForAreaStore.clear();
8945 TC_LOG_INFO(
"server.loading",
">> Loaded 0 areas for fishing base skill level. DB table `skill_fishing_base_level` is empty.");
8953 Field* fields = result->Fetch();
8960 TC_LOG_ERROR(
"sql.sql",
"AreaId {} defined in `skill_fishing_base_level` does not exist", entry);
8964 _fishingBaseForAreaStore[entry] = skill;
8967 while (result->NextRow());
8976 QueryResult result =
WorldDatabase.Query(
"SELECT ID, Value1, Value2, Value3, Value4, Value5, Value6, Value7, Value8, Value9, Value10, "
8977 " Value11, Value12, Value13, Value14, Value15, Value16 FROM skill_tiers");
8981 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 skill max values. DB table `skill_tiers` is empty.");
8987 Field* fields = result->Fetch();
8993 }
while (result->NextRow());
9016 if (w_ownname != wname)
9024 AreaTriggerScriptContainer::const_iterator i = _areaTriggerScriptStore.find(trigger_id);
9025 if (i!= _areaTriggerScriptStore.end())
9037 EventScriptContainer::const_iterator i = _eventScriptStore.find(eventId);
9038 if (i != _eventScriptStore.end())
9049 uint32 classMask = 1 << (playerClass - 1);
9051 for (
uint8 i = 0; i < 4; ++i)
9090 _gameTeleStore.clear();
9093 QueryResult result =
WorldDatabase.Query(
"SELECT id, position_x, position_y, position_z, orientation, map, name FROM game_tele");
9097 TC_LOG_INFO(
"server.loading",
">> Loaded 0 GameTeleports. DB table `game_tele` is empty!");
9105 Field* fields = result->Fetch();
9120 TC_LOG_ERROR(
"sql.sql",
"Wrong position for id {} (name: {}) in `game_tele` table, ignoring.",
id, gt.
name);
9126 TC_LOG_ERROR(
"sql.sql",
"Wrong UTF8 name for id {} in `game_tele` table, ignoring.",
id);
9132 _gameTeleStore[id] = gt;
9136 while (result->NextRow());
9153 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9155 if (itr->second.wnameLow == wname)
9156 return &itr->second;
9157 else if (!alt && itr->second.
wnameLow.find(wname) != std::wstring::npos)
9174 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9176 if (itr->second.wnameLow == wname)
9177 return &itr->second;
9187 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9188 if (itr->first > new_id)
9189 new_id = itr->first;
9199 _gameTeleStore[new_id] = tele;
9226 for (GameTeleContainer::iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9228 if (itr->second.wnameLow == wname)
9236 _gameTeleStore.erase(itr);
9248 _mailLevelRewardStore.clear();
9251 QueryResult result =
WorldDatabase.Query(
"SELECT level, raceMask, mailTemplateId, senderEntry FROM mail_level_reward");
9255 TC_LOG_INFO(
"server.loading",
">> Loaded 0 level dependent mail rewards. DB table `mail_level_reward` is empty.");
9263 Field* fields = result->Fetch();
9272 TC_LOG_ERROR(
"sql.sql",
"Table `mail_level_reward` has data for level {} that more supported by client ({}), ignoring.", level,
MAX_LEVEL);
9278 TC_LOG_ERROR(
"sql.sql",
"Table `mail_level_reward` has raceMask ({}) for level {} that not include any player races, ignoring.", raceMask.
RawValue, level);
9284 TC_LOG_ERROR(
"sql.sql",
"Table `mail_level_reward` has invalid mailTemplateId ({}) for level {} that invalid not include any player races, ignoring.", mailTemplateId, level);
9288 if (!GetCreatureTemplate(senderEntry))
9290 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);
9294 _mailLevelRewardStore[level].emplace_back(raceMask, mailTemplateId, senderEntry);
9298 while (result->NextRow());
9310 std::unordered_map<int32, std::vector<Trainer::Spell>> spellsByTrainer;
9311 if (
QueryResult trainerSpellsResult =
WorldDatabase.Query(
"SELECT TrainerId, SpellId, MoneyCost, ReqSkillLine, ReqSkillRank, ReqAbility1, ReqAbility2, ReqAbility3, ReqLevel FROM trainer_spell"))
9315 Field* fields = trainerSpellsResult->Fetch();
9331 TC_LOG_ERROR(
"sql.sql",
"Table `trainer_spell` references non-existing spell (SpellId: {}) for TrainerId {}, ignoring", spell.
SpellId, trainerId);
9337 TC_LOG_ERROR(
"sql.sql",
"Table `trainer_spell` references non-existing skill (ReqSkillLine: {}) for TrainerId {} and SpellId {}, ignoring",
9342 bool allReqValid =
true;
9343 for (std::size_t i = 0; i < spell.
ReqAbility.size(); ++i)
9348 TC_LOG_ERROR(
"sql.sql",
"Table `trainer_spell` references non-existing spell (ReqAbility{}: {}) for TrainerId {} and SpellId {}, ignoring",
9349 i + 1, requiredSpell, trainerId, spell.
SpellId);
9350 allReqValid =
false;
9357 spellsByTrainer[trainerId].push_back(spell);
9359 }
while (trainerSpellsResult->NextRow());
9366 Field* fields = trainersResult->Fetch();
9370 std::vector<Trainer::Spell> spells;
9371 auto spellsItr = spellsByTrainer.find(trainerId);
9372 if (spellsItr != spellsByTrainer.end())
9374 spells = std::move(spellsItr->second);
9375 spellsByTrainer.erase(spellsItr);
9378 _trainers.emplace(std::piecewise_construct, std::forward_as_tuple(trainerId), std::forward_as_tuple(trainerId, trainerType, greeting, std::move(spells)));
9380 }
while (trainersResult->NextRow());
9383 for (
auto const& unusedSpells : spellsByTrainer)
9387 TC_LOG_ERROR(
"sql.sql",
"Table `trainer_spell` references non-existing trainer (TrainerId: {}) for SpellId {}, ignoring", unusedSpells.first, unusedSpell.SpellId);
9391 if (
QueryResult trainerLocalesResult =
WorldDatabase.Query(
"SELECT Id, locale, Greeting_lang FROM trainer_locale"))
9395 Field* fields = trainerLocalesResult->Fetch();
9397 std::string localeName = fields[1].
GetString();
9404 trainer->AddGreetingLocale(locale, fields[2].GetString());
9406 TC_LOG_ERROR(
"sql.sql",
"Table `trainer_locale` references non-existing trainer (TrainerId: {}) for locale {}, ignoring",
9407 trainerId, localeName);
9409 }
while (trainerLocalesResult->NextRow());
9419 _creatureDefaultTrainers.clear();
9421 if (
QueryResult result =
WorldDatabase.Query(
"SELECT CreatureID, TrainerID, MenuID, OptionID FROM creature_trainer"))
9425 Field* fields = result->Fetch();
9431 if (!GetCreatureTemplate(creatureId))
9433 TC_LOG_ERROR(
"sql.sql",
"Table `creature_trainer` references non-existing creature template (CreatureID: {}), ignoring", creatureId);
9437 if (!GetTrainer(trainerId))
9439 TC_LOG_ERROR(
"sql.sql",
"Table `creature_trainer` references non-existing trainer (TrainerID: {}) for CreatureID {} MenuID {} OptionID {}, ignoring",
9440 trainerId, creatureId, gossipMenuId, gossipOptionId);
9444 if (gossipMenuId || gossipOptionId)
9447 auto gossipOptionItr = std::find_if(gossipMenuItems.
begin(), gossipMenuItems.
end(), [gossipOptionId](std::pair<uint32 const, GossipMenuItems>
const& entry)
9449 return entry.second.OrderIndex == gossipOptionId;
9451 if (gossipOptionItr == gossipMenuItems.
end())
9453 TC_LOG_ERROR(
"sql.sql",
"Table `creature_trainer` references non-existing gossip menu option (MenuID {} OptionID {}) for CreatureID {} and TrainerID {}, ignoring",
9454 gossipMenuId, gossipOptionId, creatureId, trainerId);
9459 _creatureDefaultTrainers[std::make_tuple(creatureId, gossipMenuId, gossipOptionId)] = trainerId;
9460 }
while (result->NextRow());
9479 Field* fields = result->Fetch();
9485 count += LoadReferenceVendor(vendor, -item_id, skip_vendors);
9489 vItem.
item = item_id;
9497 for (std::string_view token :
Trinity::Tokenize(fields[5].GetStringView(),
' ',
false))
9501 if (!IsVendorItemValid(vendor, vItem,
nullptr, skip_vendors))
9505 vList.
AddItem(std::move(vItem));
9508 }
while (result->NextRow());
9518 for (CacheVendorItemContainer::iterator itr = _cacheVendorItemStore.begin(); itr != _cacheVendorItemStore.end(); ++itr)
9519 itr->second.Clear();
9520 _cacheVendorItemStore.clear();
9522 std::set<uint32> skip_vendors;
9524 QueryResult result =
WorldDatabase.Query(
"SELECT entry, item, maxcount, incrtime, ExtendedCost, type, BonusListIDs, PlayerConditionID, IgnoreFiltering FROM npc_vendor ORDER BY entry, slot ASC");
9527 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 Vendors. DB table `npc_vendor` is empty!");
9535 Field* fields = result->Fetch();
9542 count += LoadReferenceVendor(entry, -item_id, &skip_vendors);
9546 vItem.
item = item_id;
9554 for (std::string_view token :
Trinity::Tokenize(fields[6].GetStringView(),
' ',
false))
9558 if (!IsVendorItemValid(entry, vItem,
nullptr, &skip_vendors))
9562 vList.
AddItem(std::move(vItem));
9566 while (result->NextRow());
9575 _gossipMenusStore.clear();
9582 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gossip_menu IDs. DB table `gossip_menu` is empty!");
9588 Field* fields = result->Fetch();
9595 if (!GetNpcText(gMenu.
TextID))
9601 _gossipMenusStore.insert(GossipMenusContainer::value_type(gMenu.
MenuID, gMenu));
9602 }
while (result->NextRow());
9611 _gossipMenuItemsStore.clear();
9615 "SELECT MenuID, GossipOptionID, OptionID, OptionNpc, OptionText, OptionBroadcastTextID, Language, Flags, ActionMenuID, ActionPoiID, GossipNpcOptionID, "
9617 "BoxCoded, BoxMoney, BoxText, BoxBroadcastTextID, SpellID, OverrideIconID "
9618 "FROM gossip_menu_option ORDER BY MenuID, OptionID");
9622 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gossip_menu_option IDs. DB table `gossip_menu_option` is empty!");
9626 std::unordered_map<int32, int32> optionToNpcOption;
9628 optionToNpcOption[npcOption->GossipOptionID] = npcOption->ID;
9632 Field* fields = result->Fetch();
9677 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);
9685 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);
9688 else if (!GetPointOfInterest(gMenuItem.
ActionPoiID))
9699 TC_LOG_ERROR(
"sql.sql",
"Table `gossip_menu_option` for menu {}, id {} use non-existing GossipNPCOption {}, ignoring",
9720 TC_LOG_ERROR(
"sql.sql",
"Table `gossip_menu_option` for menu {}, id {} use non-existing Spell {}, ignoring",
9726 _gossipMenuItemsStore.insert(GossipMenuItemsContainer::value_type(gMenuItem.
MenuID, gMenuItem));
9727 }
while (result->NextRow());
9729 TC_LOG_INFO(
"server.loading",
">> Loaded {} gossip_menu_option entries in {} ms", _gossipMenuItemsStore.size(),
GetMSTimeDiffToNow(oldMSTime));
9736 _gossipMenuAddonStore.clear();
9739 QueryResult result =
WorldDatabase.Query(
"SELECT MenuID, FriendshipFactionID, LfgDungeonsID FROM gossip_menu_addon");
9743 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gossip_menu_addon IDs. DB table `gossip_menu_addon` is empty!");
9749 Field* fields = result->Fetch();
9762 TC_LOG_ERROR(
"sql.sql",
"Table gossip_menu_addon: ID {} is using FriendshipFactionID {} referencing non-existing FriendshipRepID {}",
9776 TC_LOG_ERROR(
"sql.sql",
"Table gossip_menu_addon: ID {} is using non-existing LfgDungeonsID {}", menuID, addon.
LfgDungeonsID);
9780 }
while (result->NextRow());
9792 auto itr = _creatureDefaultTrainers.find(std::make_tuple(creatureId, gossipMenuId, gossipOptionId));
9793 if (itr != _creatureDefaultTrainers.end())
9821 CacheVendorItemContainer::iterator iter = _cacheVendorItemStore.find(entry);
9822 if (iter == _cacheVendorItemStore.end())
9825 if (!iter->second.RemoveItem(item, type))
9850 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` has data for nonexistent creature template (Entry: {}), ignore", vendor_entry);
9856 if (!skip_vendors || skip_vendors->count(vendor_entry) == 0)
9861 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` has data for creature template (Entry: {}) without vendor flag, ignore", vendor_entry);
9864 skip_vendors->insert(vendor_entry);
9875 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);
9883 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);
9893 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);
9904 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);
9912 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);
9920 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` have Item (Entry: {}) with invalid bonus {} for vendor ({}), ignore", vItem.
item, bonusListId, vendor_entry);
9926 VendorItemData const* vItems = GetNpcVendorItemList(vendor_entry);
9935 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);
9941 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);
9952 [[maybe_unused]]
uint32 const id = insert(
"",
false);
9959 IndexToName.reserve(capacity);
9964 auto result = NameToIndex.lower_bound(scriptName);
9965 if (result == NameToIndex.end() || NameToIndex.key_comp()(scriptName, result->first))
9967 ASSERT(NameToIndex.size() <= std::numeric_limits<uint32>::max());
9968 result = NameToIndex.emplace_hint(result, scriptName,
Entry(
static_cast<uint32>(NameToIndex.size()), isScriptNameBound));
9969 IndexToName.emplace_back(result);
9972 return result->second.Id;
9977 return IndexToName.size();
9982 return index < IndexToName.size() ? IndexToName[index] :
end();
9991 return NameToIndex.find(name);
9996 return NameToIndex.end();
10001 std::unordered_set<std::string> scriptNames;
10003 for (std::pair<std::string const, Entry>
const& entry : NameToIndex)
10005 if (entry.second.IsScriptDatabaseBound)
10007 scriptNames.insert(entry.first);
10011 return scriptNames;
10016 return _scriptNamesStore.GetAllDBScriptNames();
10021 auto const itr = _scriptNamesStore.find(
id);
10022 if (itr != _scriptNamesStore.end())
10028 static std::string
const empty;
10035 auto const itr = _scriptNamesStore.find(
id);
10036 if (itr != _scriptNamesStore.end())
10038 return itr->second.IsScriptDatabaseBound;
10048 return _scriptNamesStore.insert(name, isDatabaseBound);
10053 CreatureBaseStatsContainer::const_iterator it = _creatureBaseStatsStore.find(
MAKE_PAIR16(level, unitClass));
10055 if (it != _creatureBaseStatsStore.end())
10056 return &(it->second);
10062 .RangedAttackPower = 0
10071 QueryResult result =
WorldDatabase.Query(
"SELECT level, class, basemana, attackpower, rangedattackpower FROM creature_classlevelstats");
10075 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature base stats. DB table `creature_classlevelstats` is empty.");
10082 Field* fields = result->Fetch();
10101 while (result->NextRow());
10104 for (
uint8 unitLevel = 1; unitLevel <= maxLevel + 3; ++unitLevel)
10108 uint8 unitClassMask = 1 << (unitClass - 1);
10109 if (!_creatureBaseStatsStore.count(
MAKE_PAIR16(unitLevel, unitClassMask)))
10110 TC_LOG_ERROR(
"sql.sql",
"Missing base stats for creature class {} level {}", unitClassMask, unitLevel);
10125 TC_LOG_INFO(
"server.loading",
">> Loaded 0 faction change achievement pairs. DB table `player_factionchange_achievement` is empty.");
10133 Field* fields = result->Fetch();
10139 TC_LOG_ERROR(
"sql.sql",
"Achievement {} (alliance_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", alliance);
10141 TC_LOG_ERROR(
"sql.sql",
"Achievement {} (horde_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", horde);
10143 FactionChangeAchievements[alliance] = horde;
10147 while (result->NextRow());
10157 for (std::pair<uint32 const, ItemTemplate>
const& itemPair : _itemTemplateStore)
10159 if (!itemPair.second.GetOtherFactionItemId())
10163 FactionChangeItemsHordeToAlliance[itemPair.first] = itemPair.second.GetOtherFactionItemId();
10166 FactionChangeItemsAllianceToHorde[itemPair.first] = itemPair.second.GetOtherFactionItemId();
10182 TC_LOG_INFO(
"server.loading",
">> Loaded 0 faction change quest pairs. DB table `player_factionchange_quests` is empty.");
10190 Field* fields = result->Fetch();
10195 if (!GetQuestTemplate(alliance))
10196 TC_LOG_ERROR(
"sql.sql",
"Quest {} (alliance_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", alliance);
10197 else if (!GetQuestTemplate(horde))
10198 TC_LOG_ERROR(
"sql.sql",
"Quest {} (horde_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", horde);
10200 FactionChangeQuests[alliance] = horde;
10204 while (result->NextRow());
10217 TC_LOG_INFO(
"server.loading",
">> Loaded 0 faction change reputation pairs. DB table `player_factionchange_reputations` is empty.");
10225 Field* fields = result->Fetch();
10231 TC_LOG_ERROR(
"sql.sql",
"Reputation {} (alliance_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", alliance);
10233 TC_LOG_ERROR(
"sql.sql",
"Reputation {} (horde_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", horde);
10235 FactionChangeReputation[alliance] = horde;
10239 while (result->NextRow());
10252 TC_LOG_INFO(
"server.loading",
">> Loaded 0 faction change spell pairs. DB table `player_factionchange_spells` is empty.");
10260 Field* fields = result->Fetch();
10266 TC_LOG_ERROR(
"sql.sql",
"Spell {} (alliance_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", alliance);
10268 TC_LOG_ERROR(
"sql.sql",
"Spell {} (horde_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", horde);
10270 FactionChangeSpells[alliance] = horde;
10274 while (result->NextRow());
10287 TC_LOG_INFO(
"server.loading",
">> Loaded 0 faction change title pairs. DB table `player_factionchange_title` is empty.");
10295 Field* fields = result->Fetch();
10301 TC_LOG_ERROR(
"sql.sql",
"Title {} (alliance_id) referenced in `player_factionchange_title` does not exist, pair skipped!", alliance);
10303 TC_LOG_ERROR(
"sql.sql",
"Title {} (horde_id) referenced in `player_factionchange_title` does not exist, pair skipped!", horde);
10305 FactionChangeTitles[alliance] = horde;
10309 while (result->NextRow());
10317 _phaseInfoById.emplace(std::make_pair(phase->ID,
PhaseInfoStruct{ phase->ID, std::unordered_set<uint32>{} }));
10320 if (map->ParentMapID != -1)
10323 TC_LOG_INFO(
"server.loading",
"Loading Terrain World Map definitions...");
10324 LoadTerrainWorldMaps();
10326 TC_LOG_INFO(
"server.loading",
"Loading Terrain Swap Default definitions...");
10327 LoadTerrainSwapDefaults();
10329 TC_LOG_INFO(
"server.loading",
"Loading Phase Area definitions...");
10335 for (
auto itr = _phaseInfoByArea.begin(); itr != _phaseInfoByArea.end(); ++itr)
10337 phase.Conditions.clear();
10349 TC_LOG_INFO(
"server.loading",
">> Loaded 0 terrain world maps. DB table `terrain_worldmap` is empty.");
10356 Field* fields = result->Fetch();
10363 TC_LOG_ERROR(
"sql.sql",
"TerrainSwapMap {} defined in `terrain_worldmap` does not exist, skipped.", mapId);
10369 TC_LOG_ERROR(
"sql.sql",
"Phase {} defined in `terrain_worldmap` is not a valid terrain swap phase, skipped.", uiMapPhaseId);
10374 terrainSwapInfo->
Id = mapId;
10378 }
while (result->NextRow());
10392 TC_LOG_INFO(
"server.loading",
">> Loaded 0 terrain swap defaults. DB table `terrain_swap_defaults` is empty.");
10399 Field* fields = result->Fetch();
10405 TC_LOG_ERROR(
"sql.sql",
"Map {} defined in `terrain_swap_defaults` does not exist, skipped.", mapId);
10411 if (!
sMapStore.LookupEntry(terrainSwap))
10413 TC_LOG_ERROR(
"sql.sql",
"TerrainSwapMap {} defined in `terrain_swap_defaults` does not exist, skipped.", terrainSwap);
10417 TerrainSwapInfo* terrainSwapInfo = &_terrainSwapInfoById[terrainSwap];
10418 terrainSwapInfo->
Id = terrainSwap;
10419 _terrainSwapInfoByMap[mapId].push_back(terrainSwapInfo);
10422 }
while (result->NextRow());
10436 TC_LOG_INFO(
"server.loading",
">> Loaded 0 phase areas. DB table `phase_area` is empty.");
10440 auto getOrCreatePhaseIfMissing = [
this](
uint32 phaseId)
10443 phaseInfo->
Id = phaseId;
10450 Field* fields = result->Fetch();
10455 TC_LOG_ERROR(
"sql.sql",
"Area {} defined in `phase_area` does not exist, skipped.", area);
10461 TC_LOG_ERROR(
"sql.sql",
"Phase {} defined in `phase_area` does not exist, skipped.", phaseId);
10466 phase->
Areas.insert(area);
10467 _phaseInfoByArea[area].emplace_back(phase);
10470 }
while (result->NextRow());
10472 for (
auto itr = _phaseInfoByArea.begin(); itr != _phaseInfoByArea.end(); ++itr)
10476 uint32 parentAreaId = itr->first;
10489 if (parentAreaPhase.PhaseInfo->Id == phase.PhaseInfo->Id)
10490 parentAreaPhase.SubAreaExclusions.insert(itr->first);
10501 return std::any_of(
Areas.begin(),
Areas.end(), [areaId](
uint32 areaToCheck)
10503 return DB2Manager::IsInArea(areaId, areaToCheck);
10534 auto itr = _gameObjectTemplateAddonStore.find(entry);
10535 if (itr != _gameObjectTemplateAddonStore.end())
10536 return &itr->second;
10566 VehicleAccessoryContainer::const_iterator itr = _vehicleAccessoryStore.find(cre->GetSpawnId());
10567 if (itr != _vehicleAccessoryStore.end())
10568 return &itr->second;
10572 VehicleAccessoryTemplateContainer::const_iterator itr = _vehicleTemplateAccessoryStore.find(veh->
GetCreatureEntry());
10573 if (itr != _vehicleTemplateAccessoryStore.end())
10574 return &itr->second;
10586 _raceUnlockRequirementStore.clear();
10589 QueryResult result =
WorldDatabase.Query(
"SELECT raceID, expansion, achievementId FROM `race_unlock_requirement`");
10595 Field* fields = result->Fetch();
10604 TC_LOG_ERROR(
"sql.sql",
"Race {} defined in `race_unlock_requirement` does not exists, skipped.", raceID);
10610 TC_LOG_ERROR(
"sql.sql",
"Race {} defined in `race_unlock_requirement` has incorrect expansion {}, skipped.", raceID, expansion);
10616 TC_LOG_ERROR(
"sql.sql",
"Race {} defined in `race_unlock_requirement` has incorrect achievement {}, skipped.", raceID, achievementId);
10621 raceUnlockRequirement.
Expansion = expansion;
10624 while (result->NextRow());
10625 TC_LOG_INFO(
"server.loading",
">> Loaded {} race expansion requirements in {} ms.", _raceUnlockRequirementStore.size(),
GetMSTimeDiffToNow(oldMSTime));
10628 TC_LOG_INFO(
"server.loading",
">> Loaded 0 race expansion requirements. DB table `race_expansion_requirement` is empty.");
10631 _classExpansionRequirementStore.clear();
10634 result =
WorldDatabase.Query(
"SELECT ClassID, RaceID, ActiveExpansionLevel, AccountExpansionLevel FROM `class_expansion_requirement`");
10638 std::map<uint8, std::map<uint8, std::pair<uint8, uint8>>> temp;
10639 std::array<uint8, MAX_CLASSES> minRequirementForClass = { };
10644 Field* fields = result->Fetch();
10654 TC_LOG_ERROR(
"sql.sql",
"Class {} (race {}) defined in `class_expansion_requirement` does not exists, skipped.",
10662 TC_LOG_ERROR(
"sql.sql",
"Race {} (class {}) defined in `class_expansion_requirement` does not exists, skipped.",
10669 TC_LOG_ERROR(
"sql.sql",
"Class {} Race {} defined in `class_expansion_requirement` has incorrect ActiveExpansionLevel {}, skipped.",
10670 uint32(classID),
uint32(raceID), activeExpansionLevel);
10676 TC_LOG_ERROR(
"sql.sql",
"Class {} Race {} defined in `class_expansion_requirement` has incorrect AccountExpansionLevel {}, skipped.",
10677 uint32(classID),
uint32(raceID), accountExpansionLevel);
10681 temp[raceID][classID] = { activeExpansionLevel, accountExpansionLevel };
10682 minRequirementForClass[classID] = std::min(minRequirementForClass[classID], activeExpansionLevel);
10686 while (result->NextRow());
10688 for (
auto&& race : temp)
10692 raceClassAvailability.
RaceID = race.first;
10694 for (
auto&& class_ : race.second)
10698 classAvailability.
ClassID = class_.first;
10708 TC_LOG_INFO(
"server.loading",
">> Loaded 0 class expansion requirements. DB table `class_expansion_requirement` is empty.");
10713 auto raceItr = std::find_if(_classExpansionRequirementStore.begin(), _classExpansionRequirementStore.end(), [raceId](
RaceClassAvailability const& raceClass)
10715 return raceClass.RaceID == raceId;
10717 if (raceItr == _classExpansionRequirementStore.end())
10720 auto classItr = std::find_if(raceItr->Classes.begin(), raceItr->Classes.end(), [classId](
ClassAvailability const& classAvailability)
10722 return classAvailability.ClassID == classId;
10724 if (classItr == raceItr->Classes.end())
10727 return &(*classItr);
10733 for (
ClassAvailability const& classAvailability : raceClassAvailability.Classes)
10734 if (classAvailability.ClassID == classId)
10735 return &classAvailability;
10753 if (staticFlagsOverride)
10754 return staticFlagsOverride;
10758 if (difficultyEntry)
10769 QueryResult result =
WorldDatabase.Query(
"SELECT GameObjectEntry, ItemId, Idx FROM gameobject_questitem ORDER BY Idx ASC");
10773 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject quest items. DB table `gameobject_questitem` is empty.");
10780 Field* fields = result->Fetch();
10789 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject_questitem` has data for nonexistent gameobject (entry: {}, idx: {}), skipped", entry, idx);
10796 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject_questitem` has nonexistent item (ID: {}) in gameobject (entry: {}, idx: {}), skipped", item, entry, idx);
10800 _gameObjectQuestItemStore[entry].push_back(item);
10804 while (result->NextRow());
10814 QueryResult result =
WorldDatabase.Query(
"SELECT CreatureEntry, DifficultyID, ItemId, Idx FROM creature_questitem ORDER BY Idx ASC");
10818 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature quest items. DB table `creature_questitem` is empty.");
10825 Field* fields = result->Fetch();
10835 TC_LOG_ERROR(
"sql.sql",
"Table `creature_questitem` has data for nonexistent creature (entry: {}, difficulty: {}, idx: {}), skipped", entry, difficulty, idx);
10842 TC_LOG_ERROR(
"sql.sql",
"Table `creature_questitem` has nonexistent item (ID: {}) in creature (entry: {}, difficulty: {}, idx: {}), skipped", item, entry, difficulty, idx);
10846 _creatureQuestItemStore[std::make_pair(entry, difficulty)].push_back(item);
10850 while (result->NextRow());
10860 QueryResult result =
WorldDatabase.Query(
"SELECT CreatureId, CurrencyId FROM creature_quest_currency ORDER BY CreatureId, CurrencyId ASC");
10864 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature quest currencies. DB table `creature_quest_currency` is empty.");
10871 Field* fields = result->Fetch();
10876 if (!GetCreatureTemplate(entry))
10878 TC_LOG_ERROR(
"sql.sql",
"Table `creature_quest_currency` has data for nonexistent creature (entry: {}, currency: {}), skipped", entry, currency);
10884 TC_LOG_ERROR(
"sql.sql",
"Table `creature_quest_currency` has nonexistent currency (ID: {}) in creature (entry: {}, currency: {}), skipped", currency, entry, currency);
10888 _creatureQuestCurrenciesStore[entry].push_back(currency);
10892 while (result->NextRow());
10900 _creatureStaticFlagsOverrideStore.clear();
10905 QueryResult result =
WorldDatabase.Query(
"SELECT SpawnId, DifficultyId, StaticFlags1, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, StaticFlags6, StaticFlags7, StaticFlags8 FROM creature_static_flags_override");
10909 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature static flag overrides. DB table `creature_static_flags_override` is empty.");
10916 Field* fields = result->Fetch();
10924 TC_LOG_ERROR(
"sql.sql",
"Table `creature_static_flags_override` has data for nonexistent creature (SpawnId: {}), skipped", spawnId);
10933 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);
10939 if (!fields[2].IsNull())
10941 if (!fields[3].IsNull())
10943 if (!fields[4].IsNull())
10945 if (!fields[5].IsNull())
10947 if (!fields[6].IsNull())
10949 if (!fields[7].IsNull())
10951 if (!fields[8].IsNull())
10953 if (!fields[9].IsNull())
10957 }
while (result->NextRow());
10969 TC_LOG_INFO(
"server.loading",
">> Query data caching is disabled. Skipped initialization.");
10977 for (
auto& creatureTemplatePair : _creatureTemplateStore)
10978 pool.
PostWork([creature = &creatureTemplatePair.second]() { creature->InitializeQueryData(); });
10982 for (
auto& gameObjectTemplatePair : _gameObjectTemplateStore)
10983 pool.
PostWork([gobj = &gameObjectTemplatePair.second]() { gobj->InitializeQueryData(); });
10987 for (
auto& questTemplatePair : _questTemplates)
10988 pool.
PostWork([quest = questTemplatePair.second.get()]() { quest->InitializeQueryData(); });
10992 for (
auto& poiWrapperPair : _questPOIStore)
10993 pool.
PostWork([poi = &poiWrapperPair.second]() { poi->InitializeQueryData(); });
11003 tempBuffer << *
this;
11006 QueryDataBuffer = std::move(tempBuffer).Release();
11012 _sceneTemplateStore.clear();
11014 QueryResult templates =
WorldDatabase.Query(
"SELECT SceneId, Flags, ScriptPackageID, Encrypted, ScriptName FROM scene_template");
11018 TC_LOG_INFO(
"server.loading",
">> Loaded 0 scene templates. DB table `scene_template` is empty.");
11024 Field* fields = templates->Fetch();
11027 SceneTemplate& sceneTemplate = _sceneTemplateStore[sceneId];
11028 sceneTemplate.
SceneId = sceneId;
11032 sceneTemplate.
ScriptId = GetScriptId(fields[4].GetStringView());
11034 }
while (templates->NextRow());
11042 _playerChoices.clear();
11044 QueryResult choices =
WorldDatabase.Query(
"SELECT ChoiceId, UiTextureKitId, SoundKitId, CloseSoundKitId, Duration, Question, PendingChoiceText, "
11045 "InfiniteRange, HideWarboardHeader, KeepOpenAfterChoice, ShowChoicesAsList, ForceDontShowChoicesAsList, RequiresSelection, MaxResponses, ScriptName FROM playerchoice");
11048 TC_LOG_INFO(
"server.loading",
">> Loaded 0 player choices. DB table `playerchoice` is empty.");
11052 uint32 responseCount = 0;
11054 uint32 itemRewardCount = 0;
11055 uint32 currencyRewardCount = 0;
11056 uint32 factionRewardCount = 0;
11057 uint32 itemChoiceRewardCount = 0;
11058 uint32 mawPowersCount = 0;
11064 (InfiniteRange)(HideWarboardHeader)(KeepOpenAfterChoice)(ShowChoicesAsList)(ForceDontShowChoicesAsList)(RequiresSelection)(MaxResponses)(ScriptName)) fields { *choices };
11066 int32 choiceId = fields.ChoiceId().GetInt32();
11071 choice.
SoundKitId = fields.SoundKitId().GetUInt32();
11073 if (!fields.Duration().IsNull())
11075 choice.
Question = fields.Question().GetStringView();
11083 choice.
MaxResponses = fields.MaxResponses().GetUInt32OrNull();
11084 choice.
ScriptId = GetScriptId(fields.ScriptName().GetStringView());
11086 }
while (choices->NextRow());
11089 if (
QueryResult responses =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, NULL, ChoiceArtFileId, Flags, WidgetSetID, "
11090 "UiTextureAtlasElementID, SoundKitID, GroupID, UiTextureKitID, Answer, Header, SubHeader, ButtonTooltip, Description, Confirmation, RewardQuestID "
11091 "FROM playerchoice_response ORDER BY `Index` ASC"))
11096 (GroupID)(UiTextureKitID)(Answer)(
Header)(SubHeader)(ButtonTooltip)(
Description)(Confirmation)(RewardQuestID)) fields{ *responses };
11098 int32 choiceId = fields.ChoiceId().GetInt32();
11099 int32 responseId = fields.ResponseId().GetInt32();
11104 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11114 response.
WidgetSetID = fields.WidgetSetID().GetUInt32();
11116 response.
SoundKitID = fields.SoundKitID().GetUInt32();
11117 response.
GroupID = fields.GroupID().GetUInt8();
11119 response.
Answer = fields.Answer().GetStringView();
11120 response.
Header = fields.Header().GetStringView();
11121 response.
SubHeader = fields.SubHeader().GetStringView();
11122 response.
ButtonTooltip = fields.ButtonTooltip().GetStringView();
11123 response.
Description = fields.Description().GetStringView();
11124 response.
Confirmation = fields.Confirmation().GetStringView();
11125 response.
RewardQuestID = fields.RewardQuestID().GetUInt32OrNull();
11129 }
while (responses->NextRow());
11132 if (
QueryResult rewards =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, TitleId, PackageId, SkillLineId, SkillPointCount, ArenaPointCount, HonorPointCount, Money, Xp FROM playerchoice_response_reward"))
11137 (SkillPointCount)(ArenaPointCount)(HonorPointCount)(
Money)(Xp)) fields{ *rewards };
11139 int32 choiceId = fields.ChoiceId().GetInt32();
11140 int32 responseId = fields.ResponseId().GetInt32();
11145 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11150 if (responseItr == choice->
Responses.end())
11152 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11157 reward->
TitleId = fields.TitleId().GetInt32();
11158 reward->
PackageId = fields.PackageId().GetInt32();
11159 reward->
SkillLineId = fields.SkillLineId().GetInt32();
11163 reward->
Money = fields.Money().GetUInt64();
11164 reward->
Xp = fields.Xp().GetUInt32();
11169 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward` references non-existing Title {} for ChoiceId {}, ResponseId: {}, set to 0",
11170 reward->
TitleId, choiceId, responseId);
11176 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward` references non-existing QuestPackage {} for ChoiceId {}, ResponseId: {}, set to 0",
11177 reward->
TitleId, choiceId, responseId);
11183 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward` references non-existing SkillLine {} for ChoiceId {}, ResponseId: {}, set to 0",
11184 reward->
TitleId, choiceId, responseId);
11189 }
while (rewards->NextRow());
11192 if (
QueryResult rewards =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, ItemId, BonusListIDs, Quantity FROM playerchoice_response_reward_item ORDER BY `Index` ASC"))
11198 int32 choiceId = fields.ChoiceId().GetInt32();
11199 int32 responseId = fields.ResponseId().GetInt32();
11200 uint32 itemId = fields.ItemId().GetUInt32();
11201 std::vector<int32> bonusListIds;
11202 for (std::string_view token :
Trinity::Tokenize(fields.BonusListIDs().GetStringView(),
' ',
false))
11204 bonusListIds.push_back(*bonusListID);
11205 int32 quantity = fields.Quantity().GetInt32();
11210 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11215 if (responseItr == choice->
Responses.end())
11217 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11221 if (!responseItr->Reward)
11223 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item` references non-existing player choice reward for ChoiceId {}, ResponseId: {}, skipped",
11224 choiceId, responseId);
11228 if (!GetItemTemplate(itemId))
11230 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item` references non-existing item {} for ChoiceId {}, ResponseId: {}, skipped",
11231 itemId, choiceId, responseId);
11235 responseItr->Reward->Items.emplace_back(itemId, std::move(bonusListIds), quantity);
11238 }
while (rewards->NextRow());
11241 if (
QueryResult rewards =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, CurrencyId, Quantity FROM playerchoice_response_reward_currency ORDER BY `Index` ASC"))
11247 int32 choiceId = fields.ChoiceId().GetInt32();
11248 int32 responseId = fields.ResponseId().GetInt32();
11249 uint32 currencyId = fields.CurrencyId().GetUInt32();
11250 int32 quantity = fields.Quantity().GetInt32();
11255 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_currency` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11260 if (responseItr == choice->
Responses.end())
11262 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_currency` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11266 if (!responseItr->Reward)
11268 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_currency` references non-existing player choice reward for ChoiceId {}, ResponseId: {}, skipped",
11269 choiceId, responseId);
11275 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_currency` references non-existing currency {} for ChoiceId {}, ResponseId: {}, skipped",
11276 currencyId, choiceId, responseId);
11280 responseItr->Reward->Currency.emplace_back(currencyId, quantity);
11281 ++currencyRewardCount;
11283 }
while (rewards->NextRow());
11286 if (
QueryResult rewards =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, FactionId, Quantity FROM playerchoice_response_reward_faction ORDER BY `Index` ASC"))
11292 int32 choiceId = fields.ChoiceId().GetInt32();
11293 int32 responseId = fields.ResponseId().GetInt32();
11294 uint32 factionId = fields.FactionId().GetUInt32();
11295 int32 quantity = fields.Quantity().GetInt32();
11300 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_faction` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11305 if (responseItr == choice->
Responses.end())
11307 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_faction` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11311 if (!responseItr->Reward)
11313 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_faction` references non-existing player choice reward for ChoiceId {}, ResponseId: {}, skipped",
11314 choiceId, responseId);
11320 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_faction` references non-existing faction {} for ChoiceId {}, ResponseId: {}, skipped",
11321 factionId, choiceId, responseId);
11325 responseItr->Reward->Faction.emplace_back(factionId, quantity);
11326 ++factionRewardCount;
11328 }
while (rewards->NextRow());
11331 if (
QueryResult rewards =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, ItemId, BonusListIDs, Quantity FROM playerchoice_response_reward_item_choice ORDER BY `Index` ASC"))
11337 int32 choiceId = fields.ChoiceId().GetInt32();
11338 int32 responseId = fields.ResponseId().GetInt32();
11339 uint32 itemId = fields.ItemId().GetUInt32();
11340 std::vector<int32> bonusListIds;
11341 for (std::string_view token :
Trinity::Tokenize(fields.BonusListIDs().GetStringView(),
' ',
false))
11343 bonusListIds.push_back(*bonusListID);
11344 int32 quantity = fields.Quantity().GetInt32();
11349 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item_choice` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11354 if (responseItr == choice->
Responses.end())
11356 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item_choice` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11360 if (!responseItr->Reward)
11362 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item_choice` references non-existing player choice reward for ChoiceId {}, ResponseId: {}, skipped",
11363 choiceId, responseId);
11367 if (!GetItemTemplate(itemId))
11369 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item_choice` references non-existing item {} for ChoiceId {}, ResponseId: {}, skipped",
11370 itemId, choiceId, responseId);
11374 responseItr->Reward->ItemChoices.emplace_back(itemId, std::move(bonusListIds), quantity);
11375 ++itemChoiceRewardCount;
11377 }
while (rewards->NextRow());
11380 if (
QueryResult mawPowersResult =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, TypeArtFileID, Rarity, SpellID, MaxStacks FROM playerchoice_response_maw_power"))
11386 int32 choiceId = fields.ChoiceId().GetInt32();
11387 int32 responseId = fields.ResponseId().GetInt32();
11392 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_maw_power` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11397 if (responseItr == choice->
Responses.end())
11399 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_maw_power` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11404 mawPower.
TypeArtFileID = fields.TypeArtFileID().GetInt32();
11405 mawPower.
Rarity = fields.Rarity().GetInt32OrNull();
11406 mawPower.
SpellID = fields.SpellID().GetInt32();
11407 mawPower.
MaxStacks = fields.MaxStacks().GetInt32();
11411 }
while (mawPowersResult->NextRow());
11414 TC_LOG_INFO(
"server.loading",
">> Loaded {} player choices, {} responses, {} rewards, {} item rewards, {} currency rewards, {} faction rewards, {} item choice rewards and {} maw powers in {} ms.",
11415 _playerChoices.size(), responseCount, rewardCount, itemRewardCount, currencyRewardCount, factionRewardCount, itemChoiceRewardCount, mawPowersCount,
GetMSTimeDiffToNow(oldMSTime));
11423 _playerChoiceLocales.clear();
11430 Field* fields = result->Fetch();
11435 if (!GetPlayerChoice(choiceId))
11437 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_locale` references non-existing ChoiceId: {} for locale {}, skipped", choiceId, localeName);
11446 AddLocaleString(fields[2].GetStringView(), locale, data.
Question);
11447 }
while (result->NextRow());
11449 TC_LOG_INFO(
"server.loading",
">> Loaded {} Player Choice locale strings in {} ms", _playerChoiceLocales.size(),
GetMSTimeDiffToNow(oldMSTime));
11455 if (
QueryResult result =
WorldDatabase.Query(
"SELECT ChoiceID, ResponseID, locale, Answer, Header, SubHeader, ButtonTooltip, Description, Confirmation FROM playerchoice_response_locale"))
11457 std::size_t count = 0;
11460 Field* fields = result->Fetch();
11466 auto itr = _playerChoiceLocales.find(choiceId);
11467 if (itr == _playerChoiceLocales.end())
11469 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_locale` references non-existing ChoiceId: {} for ResponseId {} locale {}, skipped",
11470 choiceId, responseId, localeName);
11477 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_locale` references non-existing ResponseId: {} for ChoiceId {} locale {}, skipped",
11478 responseId, choiceId, localeName);
11487 AddLocaleString(fields[3].GetStringView(), locale, data.
Answer);
11488 AddLocaleString(fields[4].GetStringView(), locale, data.
Header);
11489 AddLocaleString(fields[5].GetStringView(), locale, data.
SubHeader);
11490 AddLocaleString(fields[6].GetStringView(), locale, data.
ButtonTooltip);
11491 AddLocaleString(fields[7].GetStringView(), locale, data.
Description);
11492 AddLocaleString(fields[8].GetStringView(), locale, data.
Confirmation);
11494 }
while (result->NextRow());
11505 _uiMapQuestLinesStore.clear();
11512 TC_LOG_INFO(
"server.loading",
">> Loaded 0 questlines for UIMaps. DB table `ui_map_quest_line` is empty!");
11520 Field* fields = result->Fetch();
11527 TC_LOG_ERROR(
"sql.sql",
"Table `ui_map_quest_line` references non-existing UIMap {}, skipped", uiMapId);
11533 TC_LOG_ERROR(
"sql.sql",
"Table `ui_map_quest_line` references empty or non-existing questline {}, skipped", questLineId);
11537 _uiMapQuestLinesStore[uiMapId].push_back(questLineId);
11540 }
while (result->NextRow());
11555 _uiMapQuestsStore.clear();
11562 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quests for UIMaps. DB table `ui_map_quest` is empty!");
11570 Field* fields = result->Fetch();
11577 TC_LOG_ERROR(
"sql.sql",
"Table `ui_map_quest` references non-existing UIMap {}, skipped", uiMapId);
11581 if (!GetQuestTemplate(questId))
11583 TC_LOG_ERROR(
"sql.sql",
"Table `ui_map_quest` references non-existing quest {}, skipped", questId);
11587 _uiMapQuestsStore[uiMapId].push_back(questId);
11590 }
while (result->NextRow());
11605 _spawnTrackingDataStore.clear();
11608 QueryResult result =
WorldDatabase.Query(
"SELECT SpawnTrackingId, MapId, PhaseId, PhaseGroup, PhaseUseFlags FROM spawn_tracking_template");
11612 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spawn tracking templates. DB table `spawn_tracking_template` is empty!");
11618 Field* fields = result->Fetch();
11625 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_template` references non-existing map {}, skipped", mapId);
11631 data.
MapId = mapId;
11638 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_template` has spawn tracking (Id: {}) with `PhaseId` and `PhaseGroup` set, `PhaseGroup` set to 0", data.
SpawnTrackingId);
11646 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_template` has spawn tracking (Id: {}) referencing non-existing `PhaseId` {}, set to 0", data.
SpawnTrackingId, data.
PhaseId);
11662 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_template` has spawn tracking (Id: {}) referencing unknown `PhaseUseFlags`, removed unknown value.", data.
SpawnTrackingId);
11668 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,"
11673 }
while (result->NextRow());
11675 TC_LOG_INFO(
"server.loading",
">> Loaded {} spawn tracking templates in {} ms", _spawnTrackingDataStore.size(),
GetMSTimeDiffToNow(oldMSTime));
11696 _spawnTrackingQuestObjectiveStore.clear();
11699 QueryResult result =
WorldDatabase.Query(
"SELECT SpawnTrackingId, QuestObjectiveId FROM spawn_tracking_quest_objective");
11703 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spawn tracking quest objectives. DB table `spawn_tracking_quest_objective` is empty!");
11711 Field* fields = result->Fetch();
11716 if (!GetSpawnTrackingData(spawnTrackingId))
11718 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);
11722 QuestObjective const* questObjective = GetQuestObjective(objectiveId);
11723 if (!questObjective)
11725 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);
11729 _spawnTrackingQuestObjectiveStore[spawnTrackingId].push_back(questObjective);
11732 }
while (result->NextRow());
11742 _spawnTrackingMapStore.clear();
11745 QueryResult result =
WorldDatabase.Query(
"SELECT SpawnTrackingId, SpawnType, SpawnId, QuestObjectiveIds FROM spawn_tracking");
11749 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spawn tracking members. DB table `spawn_tracking` is empty!");
11757 Field* fields = result->Fetch();
11764 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking` has spawn data with invalid type {} listed for spawn tracking {}. Skipped.",
uint32(spawnType), spawnTrackingId);
11769 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking` has areatrigger spawn ({}) listed for spawn tracking {}. Skipped.",
uint32(spawnType), spawnTrackingId);
11773 SpawnMetadata const* data = GetSpawnMetadata(spawnType, spawnId);
11776 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);
11781 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.",
11787 if (!spawnTrackingTemplateData)
11789 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking` has spawn tracking {} assigned to spawn ({},{}), but spawn tracking does not exist!", spawnTrackingId,
uint32(spawnType), spawnId);
11793 if (spawnTrackingTemplateData->
MapId != data->
mapId)
11795 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!",
11796 spawnTrackingId, spawnTrackingTemplateData->
MapId,
uint32(spawnType), spawnId, data->
mapId);
11803 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking` has spawn tracking {} with phase info (PhaseId: {}, PhaseGroup: {}, PhaseUseFlags: {}), ",
11804 "but spawn ({},{}) has different phase info (PhaseId: {}, PhaseGroup: {}, PhaseUseFlags: {}) - spawn NOT added to spawn tracking!",
11810 std::vector<uint32> objectiveList;
11813 for (std::string_view objectiveStr :
Trinity::Tokenize(*objectivesStr,
',',
false))
11819 if (!IsQuestObjectiveForSpawnTracking(spawnTrackingId, *objectiveId))
11821 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);
11825 objectiveList.push_back(*objectiveId);
11828 if (objectiveList.empty())
11830 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);
11835 const_cast<SpawnMetadata*
>(data)->spawnTrackingData = spawnTrackingTemplateData;
11836 const_cast<SpawnMetadata*
>(data)->spawnTrackingQuestObjectives = std::move(objectiveList);
11837 _spawnTrackingMapStore.emplace(spawnTrackingId, data);
11840 }
while (result->NextRow());
11850 QueryResult result =
WorldDatabase.Query(
"SELECT SpawnType, SpawnId, State, Visible, StateSpellVisualId, StateAnimId, StateAnimKitId, StateWorldEffects FROM spawn_tracking_state");
11854 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spawn tracking states. DB table `spawn_tracking_state` is empty!");
11862 Field* fields = result->Fetch();
11869 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` has spawn data with invalid type {}. Skipped.",
uint32(spawnType));
11874 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` has areatrigger spawn ({}). Skipped.",
uint32(spawnType));
11878 SpawnMetadata const* data = GetSpawnMetadata(spawnType, spawnId);
11881 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` has spawn ({},{}) not found!",
uint32(spawnType), spawnId);
11886 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);
11892 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` has spawn ({},{}) with invalid state type {}. Skipped.",
uint32(spawnType), spawnId,
uint8(state));
11904 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` references invalid StateSpellVisualId {} for spawn ({},{}), set to none.",
11911 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` references invalid StateAnimId {} for spawn ({},{}), set to none.",
11918 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` references invalid StateAnimKitId {} for spawn ({},{}), set to none.",
11925 for (std::string_view worldEffectStr :
Trinity::Tokenize(*worldEffectsStr,
',',
false))
11927 Optional<uint32> worldEffectId = Trinity::StringTo<uint32>(worldEffectStr);
11928 if (!worldEffectId)
11933 TC_LOG_ERROR(
"sql.sql",
"Table `spawn_tracking_state` references invalid WorldEffectId {} for spawn ({},{}). Skipped.",
11934 *worldEffectId,
uint32(spawnType), spawnId);
11943 }
while (result->NextRow());
11953 _jumpChargeParams.clear();
11955 QueryResult result =
WorldDatabase.Query(
"SELECT id, speed, treatSpeedAsMoveTimeSeconds, minHeight, maxHeight, unlimitedSpeed, spellVisualId, progressCurveId, parabolicCurveId, triggerSpellId FROM jump_charge_params");
11962 (spellVisualId)(progressCurveId)(parabolicCurveId)(triggerSpellId)) fields { *result };
11966 int32 id = fields.id().GetInt32();
11969 params.TreatSpeedAsMoveTimeSeconds = fields.treatSpeedAsMoveTimeSeconds().GetBool();
11970 params.UnlimitedSpeed = fields.unlimitedSpeed().GetBool();
11971 params.MinHeight = fields.minHeight().GetFloatOrNull();
11972 params.MaxHeight = fields.maxHeight().GetFloatOrNull();
11973 params.SpellVisualId = fields.spellVisualId().GetInt32OrNull();
11974 params.ProgressCurveId = fields.progressCurveId().GetInt32OrNull();
11975 params.ParabolicCurveId = fields.parabolicCurveId().GetInt32OrNull();
11976 params.TriggerSpellId = fields.triggerSpellId().GetInt32OrNull();
11978 if (
params.Speed <= 0.0f)
11980 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` uses invalid speed {} for id {}, set to default charge speed {}.",
11987 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` uses invalid min height {} for id {}, set to none.",
11989 params.MinHeight.reset();
11994 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` uses invalid max height {} for id {}, set to none.",
11996 params.MaxHeight.reset();
12001 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` uses invalid max height {} (must be greated than min height {}) for id {}, set to none.",
12003 params.MaxHeight.reset();
12008 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` references non-existing SpellVisual: {} for id {}, ignored.",
12009 *
params.SpellVisualId,
id);
12010 params.SpellVisualId.reset();
12015 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` references non-existing progress Curve: {} for id {}, ignored.",
12016 *
params.ProgressCurveId,
id);
12017 params.ProgressCurveId.reset();
12022 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` references non-existing parabolic Curve: {} for id {}, ignored.",
12023 *
params.ParabolicCurveId,
id);
12024 params.ParabolicCurveId.reset();
12029 TC_LOG_DEBUG(
"sql.sql",
"Table `jump_charge_params` references non-existing trigger spell id: {} for id {}, ignored.",
12030 *
params.TriggerSpellId,
id);
12031 params.TriggerSpellId.reset();
12034 }
while (result->NextRow());
12036 TC_LOG_INFO(
"server.loading",
">> Loaded {} Player Choice locale strings in {} ms", _jumpChargeParams.size(),
GetMSTimeDiffToNow(oldMSTime));
12042 _phaseNameStore.clear();
12049 TC_LOG_INFO(
"server.loading",
">> Loaded 0 phase names. DB table `phase_name` is empty.");
12056 Field* fields = result->Fetch();
12059 std::string name = fields[1].
GetString();
12061 _phaseNameStore[phaseId] = name;
12064 }
while (result->NextRow());
12070 PhaseNameContainer::const_iterator iter = _phaseNameStore.find(phaseId);
12071 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
std::vector< Criteria const * > CriteriaList
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)
TaxiPathNodesByPath sTaxiPathNodesByPath
DB2Storage< ItemXItemEffectEntry > sItemXItemEffectStore("ItemXItemEffect.db2", &ItemXItemEffectLoadInfo::Instance)
DB2Storage< ScenarioEntry > sScenarioStore("Scenario.db2", &ScenarioLoadInfo::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 was copied. Do not allow making a copy of items in mail.
@ MAIL_CHECK_MASK_RETURNED
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)
ScriptMapMap sSpellScripts
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, CellObjectGuids > CellObjectGuidsMap
#define SPAWNGROUP_MAP_UNSET
TC_GAME_API ScriptMapMap sEventScripts
std::pair< GossipMenusContainer::const_iterator, GossipMenusContainer::const_iterator > GossipMenusMapBounds
TC_GAME_API ScriptMapMap sSpellScripts
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
constexpr Trinity::RaceMask< T > RACEMASK_ALL_PLAYABLE_v
constexpr Trinity::RaceMask< T > RACEMASK_ALL_v
uint32 urand(uint32 min, uint32 max)
#define MAX_REPUTATION_RANK
#define CURRENT_EXPANSION
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
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_SEND_EVENT
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)
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
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
int32 GetBaseReputationOf(FactionEntry const *factionEntry, uint8 race, uint8 playerClass) 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
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
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()
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()
CellObjectGuids const * GetCellPersonalObjectGuids(uint32 mapid, Difficulty spawnMode, uint32 phaseId, uint32 cell_id) const
CellObjectGuidsMap const * GetMapObjectGuids(uint32 mapid, Difficulty spawnMode)
GameObjectLocaleContainer _gameObjectLocaleStore
CellObjectGuids const * GetCellObjectGuids(uint32 mapid, Difficulty spawnMode, uint32 cell_id)
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
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)
Trinity::RaceMask< std::array< int32, 2 > > _allowableRaces
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
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
std::vector< SpellEffectInfo > const & GetEffects() 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()
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[]
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.
GridCoord ComputeGridCoord(float x, float y)
Optional< Result > StringTo(std::string_view str, Params &&... params)
CellCoord ComputeCellCoord(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
std::vector< uint32 > auras
VisibilityDistanceType visibilityDistanceType
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]
std::array< int32, 4 > ReputationBase
std::array< int16, 4 > ReputationClassMask
bool CanHaveReputation() const
std::array< Trinity::RaceMask< int64 >, 4 > ReputationRaceMask
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::@197::@201 questgiver
struct GameObjectTemplate::@197::@231 barberChair
uint32 data[MAX_GAMEOBJECT_DATA]
struct GameObjectTemplate::@197::@211 areaDamage
struct GameObjectTemplate::@197::@264 raw
struct GameObjectTemplate::@197::@207 spellFocus
struct GameObjectTemplate::@197::@232 destructibleBuilding
struct GameObjectTemplate::@197::@223 flagStand
struct GameObjectTemplate::@197::@206 chair
struct GameObjectTemplate::@197::@209 goober
bool IsDespawnAtAction() const
struct GameObjectTemplate::@197::@224 fishingHole
struct GameObjectTemplate::@197::@199 door
struct GameObjectTemplate::@197::@249 gatheringNode
struct GameObjectTemplate::@197::@205 trap
struct GameObjectTemplate::@197::@200 button
struct GameObjectTemplate::@197::@225 flagDrop
struct GameObjectTemplate::@197::@214 moTransport
struct GameObjectTemplate::@197::@221 spellCaster
std::string castBarCaption
struct GameObjectTemplate::@197::@202 chest
struct GameObjectTemplate::@197::@237 garrisonBuilding
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 ForceDontShowChoicesAsList
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 fromEulerAnglesZYX(float Z, float Y, float X)
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::@270::@273 Talk
struct ScriptInfo::@270::@280 KillCredit
struct ScriptInfo::@270::@287 CreateItem
struct ScriptInfo::@270::@278 TeleportTo
struct ScriptInfo::@270::@285 CastSpell
struct ScriptInfo::@270::@272 Raw
struct ScriptInfo::@270::@284 RemoveAura
struct ScriptInfo::@270::@282 TempSummonCreature
struct ScriptInfo::@270::@297 PlayAnimKit
std::string GetDebugInfo() const
struct ScriptInfo::@270::@279 QuestExplored
struct ScriptInfo::@270::@283 ToggleDoor
struct ScriptInfo::@270::@281 RespawnGameobject
struct ScriptInfo::@270::@274 Emote
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
constexpr bool IsEmpty() const
constexpr bool HasRace(uint32 raceId) 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