74#include <G3D/g3dmath.h>
107 std::string res =
"";
176 size_t pos = name.find(
'-');
177 if (pos != std::string::npos)
189 Unit const* summoner =
nullptr;
220 _equipmentSetGuid(1),
224 _gameObjectSpawnId(1),
242 if (data.size() <=
size_t(localeConstant))
245 data.resize(localeConstant + 1);
248 data[localeConstant] = value.empty() ?
"" : value;
258 QueryResult result =
WorldDatabase.Query(
"SELECT entry, locale, Name, NameAlt, Title, TitleAlt FROM creature_template_locale");
264 Field* fields = result->Fetch();
279 }
while (result->NextRow());
291 QueryResult result =
WorldDatabase.Query(
"SELECT MenuID, OptionID, Locale, OptionText, BoxText FROM gossip_menu_option_locale");
298 Field* fields = result->Fetch();
311 }
while (result->NextRow());
329 Field* fields = result->Fetch();
340 }
while (result->NextRow());
375 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template definitions. DB table `creature_template` is empty.");
382 Field* fields = result->Fetch();
384 }
while (result->NextRow());
404 creatureTemplate.
Entry = entry;
433 creatureTemplate.
type =
uint32(fields[27].GetUInt8());
439 creatureTemplate.
spells[i] = 0;
445 if (!fields[31].IsNull())
448 if (!fields[32].IsNull())
451 if (!fields[33].IsNull())
454 if (!fields[34].IsNull())
478 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template gossip definitions. DB table `creature_template_gossip` is empty.");
486 Field* fields = result->Fetch();
494 TC_LOG_ERROR(
"sql.sql",
"creature_template_gossip has gossip definitions for creature {} but this creature doesn't exist", creatureID);
499 if (menuBounds.first == menuBounds.second)
501 TC_LOG_ERROR(
"sql.sql",
"creature_template_gossip has gossip definitions for menu id {} but this menu doesn't exist", menuID);
510 }
while (result->NextRow());
520 QueryResult result =
WorldDatabase.Query(
"SELECT CreatureID, School, Resistance FROM creature_template_resistance");
524 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template resistance definitions. DB table `creature_template_resistance` is empty.");
532 Field* fields = result->Fetch();
539 TC_LOG_ERROR(
"sql.sql",
"creature_template_resistance has resistance definitions for creature {} but this school {} doesn't exist", creatureID, school);
546 TC_LOG_ERROR(
"sql.sql",
"creature_template_resistance has resistance definitions for creature {} but this creature doesn't exist", creatureID);
555 }
while (result->NextRow());
569 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template spell definitions. DB table `creature_template_spell` is empty.");
577 Field* fields = result->Fetch();
584 TC_LOG_ERROR(
"sql.sql",
"creature_template_spell has spell definitions for creature {} with a incorrect index {}", creatureID, index);
591 TC_LOG_ERROR(
"sql.sql",
"creature_template_spell has spell definitions for creature {} but this creature doesn't exist", creatureID);
600 }
while (result->NextRow());
610 QueryResult result =
WorldDatabase.Query(
"SELECT CreatureID, CreatureDisplayID, DisplayScale, Probability FROM creature_template_model ORDER BY Idx ASC");
614 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template model definitions. DB table `creature_template_model` is empty.");
621 Field* fields = result->Fetch();
625 float displayScale = fields[2].
GetFloat();
626 float probability = fields[3].
GetFloat();
631 TC_LOG_ERROR(
"sql.sql",
"Creature template (Entry: {}) does not exist but has a record in `creature_template_model`", creatureId);
638 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) lists non-existing CreatureDisplayID id ({}), this can crash the client.", creatureId, creatureDisplayId);
644 TC_LOG_ERROR(
"sql.sql",
"No model data exist for `CreatureDisplayID` = {} listed by creature (Entry: {}).", creatureDisplayId, creatureId);
646 if (displayScale <= 0.0f)
653 while (result->NextRow());
663 QueryResult result =
WorldDatabase.Query(
"SELECT CreatureID, CreatureIDVisibleToSummoner, GroundMountDisplayID, FlyingMountDisplayID, DespawnOnQuestsRemoved FROM creature_summoned_data");
667 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature summoned data definitions. DB table `creature_summoned_data` is empty.");
673 Field* fields = result->Fetch();
678 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summoned_data` references non-existing creature {}, skipped", creatureId);
684 if (!fields[1].IsNull())
689 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summoned_data` references non-existing creature {} in CreatureIDVisibleToSummoner for creature {}, set to 0",
695 if (!fields[2].IsNull())
700 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summoned_data` references non-existing display id {} in GroundMountDisplayID for creature {}, set to 0",
706 if (!fields[3].IsNull())
711 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summoned_data` references non-existing display id {} in FlyingMountDisplayID for creature {}, set to 0",
717 if (!fields[4].IsNull())
719 std::vector<uint32> questList;
720 for (std::string_view questStr :
Trinity::Tokenize(fields[4].GetStringView(),
',',
false))
729 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summoned_data` references non-existing quest {} in DespawnOnQuestsRemoved for creature {}, skipping",
730 *questId, creatureId);
734 questList.push_back(*questId);
737 if (!questList.empty())
741 }
while (result->NextRow());
751 QueryResult result =
WorldDatabase.Query(
"SELECT entry, PathId, mount, StandState, AnimTier, VisFlags, SheathState, PvPFlags, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_template_addon");
755 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template addon definitions. DB table `creature_template_addon` is empty.");
762 Field* fields = result->Fetch();
768 TC_LOG_ERROR(
"sql.sql",
"Creature template (Entry: {}) does not exist but has a record in `creature_template_addon`", entry);
787 for (std::string_view aura :
Trinity::Tokenize(fields[13].GetStringView(),
' ',
false))
795 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has wrong spell '{}' defined in `auras` field in `creature_template_addon`.", entry, std::string(aura));
800 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has SPELL_AURA_CONTROL_VEHICLE aura {} defined in `auras` field in `creature_template_addon`.", entry, spellInfo->
Id);
802 if (std::find(creatureAddon.
auras.begin(), creatureAddon.
auras.end(), spellInfo->
Id) != creatureAddon.
auras.end())
804 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has duplicate aura (spell {}) in `auras` field in `creature_template_addon`.", entry, spellInfo->
Id);
810 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has temporary aura (spell {}) in `auras` field in `creature_template_addon`.", entry, spellInfo->
Id);
814 creatureAddon.
auras.push_back(spellInfo->
Id);
817 if (creatureAddon.
mount)
821 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid displayInfoId ({}) for mount defined in `creature_template_addon`", entry, creatureAddon.
mount);
822 creatureAddon.
mount = 0;
828 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid unit stand state ({}) defined in `creature_template_addon`. Truncated to 0.", entry, creatureAddon.
standState);
834 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid animation tier ({}) defined in `creature_template_addon`. Truncated to 0.", entry, creatureAddon.
animTier);
840 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid sheath state ({}) defined in `creature_template_addon`. Truncated to 0.", entry, creatureAddon.
sheathState);
848 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid emote ({}) defined in `creature_template_addon`.", entry, creatureAddon.
emote);
849 creatureAddon.
emote = 0;
854 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid aiAnimKit ({}) defined in `creature_template_addon`.", entry, creatureAddon.
aiAnimKit);
860 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid movementAnimKit ({}) defined in `creature_template_addon`.", entry, creatureAddon.
movementAnimKit);
866 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid meleeAnimKit ({}) defined in `creature_template_addon`.", entry, creatureAddon.
meleeAnimKit);
872 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid visibilityDistanceType ({}) defined in `creature_template_addon`.",
879 while (result->NextRow());
889 QueryResult result =
WorldDatabase.Query(
"SELECT Entry, NoNPCDamageBelowHealthPct FROM creature_template_sparring");
893 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template sparring definitions. DB table `creature_template_sparring` is empty.");
900 Field* fields = result->Fetch();
903 float noNPCDamageBelowHealthPct = fields[1].
GetFloat();
907 TC_LOG_ERROR(
"sql.sql",
"Creature template (Entry: {}) does not exist but has a record in `creature_template_sparring`", entry);
911 if (noNPCDamageBelowHealthPct <= 0 || noNPCDamageBelowHealthPct > 100)
913 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid NoNPCDamageBelowHealthPct ({}) defined in `creature_template_sparring`. Skipping",
914 entry, noNPCDamageBelowHealthPct);
920 }
while (result->NextRow());
930 QueryResult result =
WorldDatabase.Query(
"SELECT Entry, DifficultyID, LevelScalingDeltaMin, LevelScalingDeltaMax, ContentTuningID, HealthScalingExpansion, "
932 "HealthModifier, ManaModifier, ArmorModifier, DamageModifier, CreatureDifficultyID, TypeFlags, TypeFlags2, "
934 "LootID, PickPocketLootID, SkinLootID, GoldMin, GoldMax,"
936 "StaticFlags1, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, StaticFlags6, StaticFlags7, StaticFlags8 "
937 "FROM creature_template_difficulty ORDER BY Entry");
941 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature template difficulty definitions. DB table `creature_template_difficulty` is empty.");
948 Field* fields = result->Fetch();
956 TC_LOG_ERROR(
"sql.sql",
"Creature template (Entry: {}) does not exist but has a record in `creature_template_difficulty`", entry);
986 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template_difficulty` lists creature (ID: {}) with invalid `HealthScalingExpansion` {}. Ignored and set to 0.",
993 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template_difficulty` lists creature (ID: {}) with `GoldMin` {} greater than `GoldMax` {}, setting `GoldMax` to {}.",
998 itr->second.difficultyStore[difficulty] = creatureDifficulty;
1001 }
while (result->NextRow());
1011 if (!cInfo->
AIName.empty())
1016 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has non-registered `AIName` '{}' set, removing", cInfo->
Entry, cInfo->
AIName);
1024 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has not-allowed `AIName` '{}' set, removing", cInfo->
Entry, cInfo->
AIName);
1031 if (!factionTemplate)
1033 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);
1043 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) lists non-existing creature entry {} in `KillCredit{}`.", cInfo->
Entry, cInfo->
KillCredit[k], k + 1);
1049 if (cInfo->
Models.empty())
1050 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) does not have any existing display id in creature_template_model.", cInfo->
Entry);
1054 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);
1060 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid spell school value ({}) in `dmgschool`.", cInfo->
Entry, cInfo->
dmgschool);
1078 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has wrong value ({}) in speed_run, set to 1.14286.", cInfo->
Entry, cInfo->
speed_run);
1084 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid creature type ({}) in `type`.", cInfo->
Entry, cInfo->
type);
1090 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has invalid creature family ({}) in `family`.", cInfo->
Entry, cInfo->
family);
1101 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has a non-existing VehicleId ({}). This *WILL* cause the client to freeze!", cInfo->
Entry, cInfo->
VehicleId);
1110 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has non-existing Spell{} ({}), set to 0.", cInfo->
Entry, j+1, cInfo->
spells[j]);
1117 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) has wrong movement generator type ({}), ignored and set to IDLE.", cInfo->
Entry, cInfo->
MovementType);
1123 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template` lists creature (Entry: {}) with `RequiredExpansion` {}. Ignored and set to 0.", cInfo->
Entry, cInfo->
RequiredExpansion);
1129 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template` lists creature (Entry: {}) with disallowed `flags_extra` {}, removing incorrect flag.", cInfo->
Entry, badFlags);
1135 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template` lists creature (Entry: {}) with disallowed `unit_flags` {}, removing incorrect flag.", cInfo->
Entry, disallowedUnitFlags);
1141 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template` lists creature (Entry: {}) with disallowed `unit_flags2` {}, removing incorrect flag.", cInfo->
Entry, disallowedUnitFlags2);
1147 TC_LOG_ERROR(
"sql.sql",
"Table `creature_template` lists creature (Entry: {}) with disallowed `unit_flags3` {}, removing incorrect flag.", cInfo->
Entry, disallowedUnitFlags3);
1152 TC_LOG_INFO(
"sql.sql",
"Creature (Entry: {}) has assigned gossip menu, but npcflag does not include UNIT_NPC_FLAG_GOSSIP.", cInfo->
Entry);
1154 TC_LOG_INFO(
"sql.sql",
"Creature (Entry: {}) has npcflag UNIT_NPC_FLAG_GOSSIP, but gossip menu is unassigned.", cInfo->
Entry);
1167 TC_LOG_ERROR(
"sql.sql",
"`{}`.`Chase` wrong value ({}) for Id {}, setting to Run.",
1174 TC_LOG_ERROR(
"sql.sql",
"`{}`.`Random` wrong value ({}) for Id {}, setting to Walk.",
1185 QueryResult result =
WorldDatabase.Query(
"SELECT guid, PathId, mount, StandState, AnimTier, VisFlags, SheathState, PvPFlags, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_addon");
1189 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature addon definitions. DB table `creature_addon` is empty.");
1196 Field* fields = result->Fetch();
1203 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) does not exist but has a record in `creature_addon`", guid);
1213 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID {}) has movement type set to WAYPOINT_MOTION_TYPE but no path assigned", guid);
1228 for (std::string_view aura :
Trinity::Tokenize(fields[13].GetStringView(),
' ',
false))
1236 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has wrong spell '{}' defined in `auras` field in `creature_addon`.", guid, std::string(aura));
1241 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has SPELL_AURA_CONTROL_VEHICLE aura {} defined in `auras` field in `creature_addon`.", guid, spellInfo->
Id);
1243 if (std::find(creatureAddon.
auras.begin(), creatureAddon.
auras.end(), spellInfo->
Id) != creatureAddon.
auras.end())
1245 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has duplicate aura (spell {}) in `auras` field in `creature_addon`.", guid, spellInfo->
Id);
1251 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has temporary aura (spell {}) in `auras` field in `creature_addon`.", guid, spellInfo->
Id);
1255 creatureAddon.
auras.push_back(spellInfo->
Id);
1258 if (creatureAddon.
mount)
1262 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid displayInfoId ({}) for mount defined in `creature_addon`", guid, creatureAddon.
mount);
1263 creatureAddon.
mount = 0;
1269 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid unit stand state ({}) defined in `creature_addon`. Truncated to 0.", guid, creatureAddon.
standState);
1275 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid animation tier ({}) defined in `creature_addon`. Truncated to 0.", guid, creatureAddon.
animTier);
1281 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid sheath state ({}) defined in `creature_addon`. Truncated to 0.", guid, creatureAddon.
sheathState);
1289 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid emote ({}) defined in `creature_addon`.", guid, creatureAddon.
emote);
1290 creatureAddon.
emote = 0;
1295 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid aiAnimKit ({}) defined in `creature_addon`.", guid, creatureAddon.
aiAnimKit);
1301 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid movementAnimKit ({}) defined in `creature_addon`.", guid, creatureAddon.
movementAnimKit);
1307 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid meleeAnimKit ({}) defined in `creature_addon`.", guid, creatureAddon.
meleeAnimKit);
1313 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) has invalid visibilityDistanceType ({}) defined in `creature_addon`.",
1320 while (result->NextRow());
1330 QueryResult result =
WorldDatabase.Query(
"SELECT guid, parent_rotation0, parent_rotation1, parent_rotation2, parent_rotation3, invisibilityType, invisibilityValue, WorldEffectID, AIAnimKitID FROM gameobject_addon");
1334 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject addon definitions. DB table `gameobject_addon` is empty.");
1341 Field* fields = result->Fetch();
1348 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) does not exist but has a record in `gameobject_addon`", guid);
1353 gameObjectAddon.
ParentRotation =
QuaternionData(fields[1].GetFloat(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat());
1361 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) has invalid InvisibilityType in `gameobject_addon`, disabled invisibility", guid);
1368 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) has InvisibilityType set but has no InvisibilityValue in `gameobject_addon`, set to 1", guid);
1374 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) has invalid parent rotation in `gameobject_addon`, set to default", guid);
1380 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) has invalid WorldEffectID ({}) in `gameobject_addon`, set to 0.", guid, gameObjectAddon.
WorldEffectID);
1386 TC_LOG_ERROR(
"sql.sql",
"GameObject (GUID: {}) has invalid AIAnimKitID ({}) in `gameobject_addon`, set to 0.", guid, gameObjectAddon.
AIAnimKitID);
1392 while (result->NextRow());
1401 return &(itr->second);
1410 return &(itr->second);
1419 return &(itr->second);
1440 if (itr->second.empty())
1445 EquipmentInfoContainerInternal::const_iterator ritr = itr->second.begin();
1446 std::advance(ritr,
urand(0u, itr->second.size() - 1));
1447 id = std::distance(itr->second.begin(), ritr) + 1;
1448 return &ritr->second;
1452 EquipmentInfoContainerInternal::const_iterator itr2 = itr->second.find(
id);
1453 if (itr2 != itr->second.end())
1454 return &itr2->second;
1467 "ItemID2, AppearanceModID2, ItemVisual2, "
1469 "ItemID3, AppearanceModID3, ItemVisual3 "
1470 "FROM creature_equip_template");
1474 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature equipment templates. DB table `creature_equip_template` is empty!");
1481 Field* fields = result->Fetch();
1487 TC_LOG_ERROR(
"sql.sql",
"Creature template (CreatureID: {}) does not exist but has a record in `creature_equip_template`", entry);
1494 TC_LOG_ERROR(
"sql.sql",
"Creature equipment template with id 0 found for creature {}, skipped.", entry);
1511 TC_LOG_ERROR(
"sql.sql",
"Unknown item (ID={}) in creature_equip_template.ItemID{} for CreatureID = {} and ID={}, forced to 0.",
1519 TC_LOG_ERROR(
"sql.sql",
"Unknown item appearance for (ID={}, AppearanceModID={}) pair in creature_equip_template.ItemID{} creature_equip_template.AppearanceModID{} "
1520 "for CreatureID = {} and ID={}, forced to default.",
1539 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.",
1547 while (result->NextRow());
1560 "SELECT cmo.SpawnId,"
1561 "COALESCE(cmo.HoverInitiallyEnabled, ctm.HoverInitiallyEnabled),"
1562 "COALESCE(cmo.Chase, ctm.Chase),"
1563 "COALESCE(cmo.Random, ctm.Random),"
1564 "COALESCE(cmo.InteractionPauseTimer, ctm.InteractionPauseTimer) "
1565 "FROM creature_movement_override AS cmo "
1566 "LEFT JOIN creature AS c ON c.guid = cmo.SpawnId "
1567 "LEFT JOIN creature_template_movement AS ctm ON ctm.CreatureId = c.id");
1571 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature movement overrides. DB table `creature_movement_override` is empty!");
1577 Field* fields = result->Fetch();
1581 TC_LOG_ERROR(
"sql.sql",
"Creature (GUID: {}) does not exist but has a record in `creature_movement_override`", spawnId);
1586 if (!fields[1].IsNull())
1588 if (!fields[2].IsNull())
1590 if (!fields[3].IsNull())
1592 if (!fields[4].IsNull())
1597 while (result->NextRow());
1606 return &(itr->second);
1632#define ChooseCreatureFlagSource(field) ((data && data->field.has_value()) ? *data->field : cInfo->field)
1664#undef ChooseCreatureFlagSource
1683 if (creatureTemplate)
1685 auto itr = std::find_if(creatureTemplate->
Models.begin(), creatureTemplate->
Models.end(), [&](
CreatureModel const& templateModel)
1687 return templateModel.CreatureDisplayID == modelInfo->displayId_other_gender;
1689 if (itr != creatureTemplate->
Models.end())
1703 QueryResult result =
WorldDatabase.Query(
"SELECT DisplayID, BoundingRadius, CombatReach, DisplayID_Other_Gender FROM creature_model_info");
1707 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature model definitions. DB table `creature_model_info` is empty.");
1715 uint32 trigggerCreatureModelFileID[5] = { 124640, 124641, 124642, 343863, 439302 };
1719 Field* fields = result->Fetch();
1724 if (!creatureDisplay)
1726 TC_LOG_ERROR(
"sql.sql",
"Table `creature_model_info` has a non-existent DisplayID (ID: {}). Skipped.", displayId);
1750 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);
1759 for (
uint32 i = 0; i < 5; ++i)
1761 if (modelData->FileDataID == trigggerCreatureModelFileID[i])
1771 while (result->NextRow());
1782 QueryResult result =
WorldDatabase.Query(
"SELECT guid, linkedGuid, linkType FROM linked_respawn ORDER BY guid ASC");
1786 TC_LOG_INFO(
"server.loading",
">> Loaded 0 linked respawns. DB table `linked_respawn` is empty.");
1792 Field* fields = result->Fetch();
1807 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature (guid) '{}' not found in creature table", guidLow);
1815 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature (linkedGuid) '{}' not found in creature table", linkedGuidLow);
1823 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature '{}' linking to Creature '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1831 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature '{}' linking to Creature '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1836 guid = ObjectGuid::Create<HighGuid::Creature>(slave->
mapId, slave->
id, guidLow);
1837 linkedGuid = ObjectGuid::Create<HighGuid::Creature>(master->
mapId, master->
id, linkedGuidLow);
1845 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature (guid) '{}' not found in creature table", guidLow);
1853 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject (linkedGuid) '{}' not found in gameobject table", linkedGuidLow);
1861 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature '{}' linking to Gameobject '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1869 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature '{}' linking to Gameobject '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1874 guid = ObjectGuid::Create<HighGuid::Creature>(slave->
mapId, slave->
id, guidLow);
1875 linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->
mapId, master->
id, linkedGuidLow);
1883 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject (guid) '{}' not found in gameobject table", guidLow);
1891 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject (linkedGuid) '{}' not found in gameobject table", linkedGuidLow);
1899 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject '{}' linking to Gameobject '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1907 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject '{}' linking to Gameobject '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1912 guid = ObjectGuid::Create<HighGuid::GameObject>(slave->
mapId, slave->
id, guidLow);
1913 linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->
mapId, master->
id, linkedGuidLow);
1921 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject (guid) '{}' not found in gameobject table", guidLow);
1929 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature (linkedGuid) '{}' not found in creature table", linkedGuidLow);
1937 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject '{}' linking to Creature '{}' on an unpermitted map.", guidLow, linkedGuidLow);
1945 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Gameobject '{}' linking to Creature '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
1950 guid = ObjectGuid::Create<HighGuid::GameObject>(slave->
mapId, slave->
id, guidLow);
1951 linkedGuid = ObjectGuid::Create<HighGuid::Creature>(master->
mapId, master->
id, linkedGuidLow);
1959 while (result->NextRow());
1971 ObjectGuid guid = ObjectGuid::Create<HighGuid::Creature>(master->
mapId, master->
id, guidLow);
1986 TC_LOG_ERROR(
"sql.sql",
"Creature '{}' linking to non-existent creature '{}'.", guidLow, linkedGuidLow);
1993 TC_LOG_ERROR(
"sql.sql",
"Creature '{}' linking to '{}' on an unpermitted map.", guidLow, linkedGuidLow);
2000 TC_LOG_ERROR(
"sql.sql",
"LinkedRespawn: Creature '{}' linking to '{}' with not corresponding spawnMask", guidLow, linkedGuidLow);
2004 ObjectGuid linkedGuid = ObjectGuid::Create<HighGuid::Creature>(slave->
mapId, slave->
id, linkedGuidLow);
2022 QueryResult result =
WorldDatabase.Query(
"SELECT summonerId, summonerType, groupId, entry, position_x, position_y, position_z, orientation, summonType, summonTime FROM creature_summon_groups");
2026 TC_LOG_INFO(
"server.loading",
">> Loaded 0 temp summons. DB table `creature_summon_groups` is empty.");
2033 Field* fields = result->Fetch();
2039 switch (summonerType)
2044 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summon_groups` has summoner with non existing entry {} for creature summoner type, skipped.", summonerId);
2051 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summon_groups` has summoner with non existing entry {} for gameobject summoner type, skipped.", summonerId);
2058 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summon_groups` has summoner with non existing entry {} for map summoner type, skipped.", summonerId);
2063 TC_LOG_ERROR(
"sql.sql",
"Table `creature_summon_groups` has unhandled summoner type {} for summoner {}, skipped.", summonerType, summonerId);
2072 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);
2079 float orientation = fields[7].
GetFloat();
2087 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);
2098 }
while (result->NextRow());
2104 std::set<Difficulty>
const& mapDifficulties)
2106 std::vector<Difficulty> difficulties;
2107 bool isTransportMap =
sObjectMgr->IsTransportMap(mapId);
2113 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has {} (GUID: {}) with non invalid difficulty id {}, skipped.",
2114 table, table, spawnId,
uint32(difficultyId));
2118 if (!isTransportMap && mapDifficulties.find(difficultyId) == mapDifficulties.end())
2120 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has {} (GUID: {}) has unsupported difficulty {} for map (Id: {}).",
2121 table, table, spawnId,
uint32(difficultyId), mapId);
2125 difficulties.push_back(difficultyId);
2128 std::sort(difficulties.begin(), difficulties.end());
2129 return difficulties;
2137 QueryResult result =
WorldDatabase.Query(
"SELECT creature.guid, id, map, position_x, position_y, position_z, orientation, modelid, equipment_id, spawntimesecs, wander_distance, "
2139 "currentwaypoint, curhealth, curmana, MovementType, spawnDifficulties, eventEntry, poolSpawnId, creature.npcflag, creature.unit_flags, creature.unit_flags2, creature.unit_flags3, "
2141 "creature.phaseUseFlags, creature.phaseid, creature.phasegroup, creature.terrainSwapMap, creature.ScriptName, creature.StringId "
2143 "LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid "
2144 "LEFT OUTER JOIN pool_members ON pool_members.type = 0 AND creature.guid = pool_members.spawnId");
2148 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creatures. DB table `creature` is empty.");
2153 std::unordered_map<uint32, std::set<Difficulty>> spawnMasks;
2155 spawnMasks[mapDifficulty->MapID].insert(
Difficulty(mapDifficulty->DifficultyID));
2163 Field* fields = result->Fetch();
2171 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {}) with non existing creature entry {}, skipped.", guid, entry);
2179 data.
spawnPoint.
Relocate(fields[3].GetFloat(), fields[4].GetFloat(), fields[5].GetFloat(), fields[6].GetFloat());
2180 if (
uint32 displayId = fields[7].GetUInt32())
2192 if (!fields[18].IsNull())
2194 if (!fields[19].IsNull())
2196 if (!fields[20].IsNull())
2198 if (!fields[21].IsNull())
2211 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {}) that spawned at nonexistent map (Id: {}), skipped.", guid, data.
mapId);
2227 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {} MapID: {}) spawned on a possible invalid position ({})",
2235 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {}) that is not spawned in any difficulty, skipped.", guid);
2244 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);
2252 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);
2257 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);
2263 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with `wander_distance`< 0, set to 0.", guid, data.
id);
2268 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);
2275 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);
2283 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);
2290 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.
id);
2296 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE,"
2297 " removing PHASE_USE_FLAGS_INVERSE.", guid, data.
id);
2303 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.
id);
2311 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) with `phaseid` {} does not exist, set to 0", guid, data.
id, data.
phaseId);
2320 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) with `phasegroup` {} does not exist, set to 0", guid, data.
id, data.
phaseGroup);
2328 if (!terrainSwapEntry)
2330 TC_LOG_ERROR(
"sql.sql",
"Table `creature` have creature (GUID: {} Entry: {}) with `terrainSwapMap` {} does not exist, set to -1", guid, data.
id, data.
terrainSwapMap);
2335 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);
2344 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with disallowed `unit_flags` {}, removing incorrect flag.", guid, data.
id, disallowedUnitFlags);
2353 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with disallowed `unit_flags2` {}, removing incorrect flag.", guid, data.
id, disallowedUnitFlags2);
2362 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {} Entry: {}) with disallowed `unit_flags3` {}, removing incorrect flag.", guid, data.
id, disallowedUnitFlags3);
2387 while (result->NextRow());
2418template<CellGu
idSet CellObjectGu
ids::*gu
ids>
2423 if (!isPersonalPhase)
2435template<CellGu
idSet CellObjectGu
ids::*gu
ids>
2440 if (!isPersonalPhase)
2454 AddSpawnDataToGrid<&CellObjectGuids::creatures>(data);
2459 RemoveSpawnDataFromGrid<&CellObjectGuids::creatures>(data);
2467 QueryResult result =
WorldDatabase.Query(
"SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
2469 "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnDifficulties, eventEntry, poolSpawnId, "
2471 "phaseUseFlags, phaseid, phasegroup, terrainSwapMap, ScriptName, StringId "
2472 "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid "
2473 "LEFT OUTER JOIN pool_members ON pool_members.type = 1 AND gameobject.guid = pool_members.spawnId");
2477 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobjects. DB table `gameobject` is empty.");
2482 std::unordered_map<uint32, std::set<Difficulty>> spawnMasks;
2484 spawnMasks[mapDifficulty->MapID].insert(
Difficulty(mapDifficulty->DifficultyID));
2492 Field* fields = result->Fetch();
2500 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {}) with non existing gameobject entry {}, skipped.", guid, entry);
2506 switch (gInfo->
type)
2512 TC_LOG_ERROR(
"sql.sql",
"Gameobject (GUID: {} Entry {} GoType: {}) doesn't have a displayId ({}), not loaded.", guid, entry, gInfo->
type, gInfo->
displayId);
2519 TC_LOG_ERROR(
"sql.sql",
"Gameobject (GUID: {} Entry {} GoType: {}) has an invalid displayId ({}), not loaded.", guid, entry, gInfo->
type, gInfo->
displayId);
2528 data.
spawnPoint.
Relocate(fields[3].GetFloat(), fields[4].GetFloat(), fields[5].GetFloat(), fields[6].GetFloat());
2539 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) spawned on a non-existed map (Id: {}), skip", guid, data.
id, data.
mapId);
2555 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {} MapID: {}) spawned on a possible invalid position ({})",
2563 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);
2574 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid `state` ({}) value, skip", guid, data.
id, go_state);
2583 TC_LOG_ERROR(
"sql.sql",
"Table `creature` has creature (GUID: {}) that is not spawned in any difficulty, skipped.", guid);
2595 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.
id);
2601 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE,"
2602 " removing PHASE_USE_FLAGS_INVERSE.", guid, data.
id);
2608 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.
id);
2616 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) with `phaseid` {} does not exist, set to 0", guid, data.
id, data.
phaseId);
2625 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) with `phaseGroup` {} does not exist, set to 0", guid, data.
id, data.
phaseGroup);
2634 if (!terrainSwapEntry)
2636 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` have gameobject (GUID: {} Entry: {}) with `terrainSwapMap` {} does not exist, set to -1", guid, data.
id, data.
terrainSwapMap);
2641 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);
2651 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationX ({}) value, skip", guid, data.
id, data.
rotation.
x);
2657 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationY ({}) value, skip", guid, data.
id, data.
rotation.
y);
2663 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationZ ({}) value, skip", guid, data.
id, data.
rotation.
z);
2669 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid rotationW ({}) value, skip", guid, data.
id, data.
rotation.
w);
2675 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject` has gameobject (GUID: {} Entry: {}) with invalid coordinates, skip", guid, data.
id);
2681 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);
2704 while (result->NextRow());
2720 Field* fields = result->Fetch();
2734 flags &= ~SPAWNGROUP_FLAG_MANUAL_SPAWN;
2735 TC_LOG_ERROR(
"sql.sql",
"System spawn group {} ({}) has invalid manual spawn flag. Ignored.", groupId, group.
name);
2738 }
while (result->NextRow());
2743 TC_LOG_ERROR(
"sql.sql",
"Default spawn group (index 0) is missing from DB! Manually inserted.");
2746 data.
name =
"Default Group";
2752 TC_LOG_ERROR(
"sql.sql",
"Default legacy spawn group (index 1) is missing from DB! Manually inserted.");
2755 data.
name =
"Legacy Group";
2763 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spawn group templates. DB table `spawn_group_template` is empty.");
2777 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spawn group members. DB table `spawn_group` is empty.");
2784 Field* fields = result->Fetch();
2789 TC_LOG_ERROR(
"sql.sql",
"Spawn data with invalid type {} listed for spawn group {}. Skipped.",
uint32(spawnType), groupId);
2797 TC_LOG_ERROR(
"sql.sql",
"Spawn data with ID ({},{}) not found, but is listed as a member of spawn group {}!",
uint32(spawnType), spawnId, groupId);
2802 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);
2808 TC_LOG_ERROR(
"sql.sql",
"Spawn group {} assigned to spawn ID ({},{}), but group is found!", groupId,
uint32(spawnType), spawnId);
2821 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);
2824 const_cast<SpawnMetadata*
>(data)->spawnGroupData = &groupTemplate;
2829 }
while (result->NextRow());
2839 QueryResult result =
WorldDatabase.Query(
"SELECT instanceMapId, bossStateId, bossStates, spawnGroupId, flags FROM instance_spawn_groups");
2843 TC_LOG_INFO(
"server.loading",
">> Loaded 0 instance spawn groups. DB table `instance_spawn_groups` is empty.");
2850 Field* fields = result->Fetch();
2855 TC_LOG_ERROR(
"sql.sql",
"Invalid spawn group {} specified for instance {}. Skipped.", spawnGroupId, fields[0].GetUInt16());
2860 if (it->second.mapId != instanceMapId)
2862 TC_LOG_ERROR(
"sql.sql",
"Instance spawn group {} specified for instance {} has spawns on a different map {}. Skipped.",
2863 spawnGroupId, instanceMapId, it->second.mapId);
2873 if (states & ~ALL_STATES)
2876 TC_LOG_ERROR(
"sql.sql",
"Instance spawn group ({},{}) had invalid boss state mask {} - truncated to {}.", instanceMapId, spawnGroupId, states, info.
BossStates);
2885 TC_LOG_ERROR(
"sql.sql",
"Instance spawn group ({},{}) had invalid flags {} - truncated to {}.", instanceMapId, spawnGroupId,
flags, info.
Flags);
2893 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);
2897 }
while (result->NextRow());
2928 for (
auto it = pair.first; it != pair.second; ++it)
2930 if (it->second != data)
2940 AddSpawnDataToGrid<&CellObjectGuids::gameobjects>(data);
2945 RemoveSpawnDataFromGrid<&CellObjectGuids::gameobjects>(data);
2955 0.92f, 0.92f, 0.92f, 1.11f, 1.32f, 1.61f, 0.0f, 0.0f
2958 static float const armorMultipliers[
MAX_INVTYPE] =
3022 float levelPenalty = 1.0f;
3023 if (itemLevel <= 28)
3024 levelPenalty = 0.966f - float(28u - itemLevel) / 54.0f;
3031 return 5 *
uint32(round(25.0f * qualityMultipliers[quality] * armorMultipliers[inventoryType] * levelPenalty));
3034 return 5 *
uint32(round(18.0f * qualityMultipliers[quality] * weaponMultipliers[itemSubClass] * levelPenalty));
3194 switch (itemStatType)
3273 if (std::vector<ItemSpecOverrideEntry const*>
const* itemSpecOverrides =
sDB2Manager.GetItemSpecOverrides(sparse->ID))
3292 if (itemSpecStats.
ItemType != itemSpec->ItemType)
3302 hasSecondary =
true;
3305 if (!hasPrimary || !hasSecondary)
3310 if ((1 << (specialization->ClassID - 1)) & sparse->AllowableClass)
3315 if (itemSpec->MaxLevel > 40)
3317 if (itemSpec->MaxLevel >= 110)
3326 if (specs.count() == 0)
3334 item->Effects.push_back(effect);
3344 QueryResult result =
WorldDatabase.Query(
"SELECT Id, FlagsCu, FoodType, MinMoneyLoot, MaxMoneyLoot, SpellPPMChance, RandomBonusListTemplateId, QuestLogItemId FROM item_template_addon");
3349 Field* fields = result->Fetch();
3354 TC_LOG_ERROR(
"sql.sql",
"Item {} specified in `item_template_addon` does not exist, skipped.", itemId);
3360 if (minMoneyLoot > maxMoneyLoot)
3362 TC_LOG_ERROR(
"sql.sql",
"Minimum money loot specified in `item_template_addon` for item {} was greater than maximum amount, swapping.", itemId);
3363 std::swap(minMoneyLoot, maxMoneyLoot);
3373 }
while (result->NextRow());
3388 Field* fields = result->Fetch();
3393 TC_LOG_ERROR(
"sql.sql",
"Item {} specified in `item_script_names` does not exist, skipped.", itemId);
3399 }
while (result->NextRow());
3419 QueryResult result =
WorldDatabase.Query(
"SELECT `entry`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer` FROM `vehicle_template_accessory`");
3423 TC_LOG_INFO(
"server.loading",
">> Loaded 0 vehicle template accessories. DB table `vehicle_template_accessory` is empty.");
3429 Field* fields = result->Fetch();
3434 bool isMinion = fields[3].
GetBool();
3440 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template_accessory`: creature template entry {} does not exist.", entry);
3446 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template_accessory`: Accessory {} does not exist.", accessory);
3452 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template_accessory`: creature template entry {} has no data in npc_spellclick_spells", entry);
3460 while (result->NextRow());
3476 TC_LOG_INFO(
"server.loading",
">> Loaded 0 vehicle template. DB table `vehicle_template` is empty.");
3482 Field* fields = result->Fetch();
3488 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_template`: Vehicle {} does not exist.", creatureId);
3495 }
while (result->NextRow());
3509 QueryResult result =
WorldDatabase.Query(
"SELECT `guid`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer` FROM `vehicle_accessory`");
3519 Field* fields = result->Fetch();
3523 int8 uiSeat =
int8(fields[2].GetInt16());
3524 bool bMinion = fields[3].
GetBool();
3530 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_accessory`: Accessory {} does not exist.", uiAccessory);
3538 while (result->NextRow());
3552 QueryResult result =
WorldDatabase.Query(
"SELECT `SeatEntry`, `SeatOrientation`, `ExitParamX`, `ExitParamY`, `ExitParamZ`, `ExitParamO`, `ExitParamValue` FROM `vehicle_seat_addon`");
3556 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 vehicle seat addons. DB table `vehicle_seat_addon` is empty.");
3562 Field* fields = result->Fetch();
3565 float orientation = fields[1].
GetFloat();
3566 float exitX = fields[2].
GetFloat();
3567 float exitY = fields[3].
GetFloat();
3568 float exitZ = fields[4].
GetFloat();
3569 float exitO = fields[5].
GetFloat();
3574 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_seat_addon`: SeatID: {} does not exist in VehicleSeat.dbc. Skipping entry.", seatID);
3579 if (orientation >
float(
M_PI * 2))
3581 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_seat_addon`: SeatID: {} is using invalid angle offset value ({}). Set Value to 0.", seatID, orientation);
3587 TC_LOG_ERROR(
"sql.sql",
"Table `vehicle_seat_addon`: SeatID: {} is using invalid exit parameter value ({}). Setting to 0 (none).", seatID, exitParam);
3594 }
while (result->NextRow());
3604 QueryResult result =
WorldDatabase.Query(
"SELECT creature_entry, level, hp, mana, str, agi, sta, inte, spi, armor FROM pet_levelstats");
3608 TC_LOG_INFO(
"server.loading",
">> Loaded 0 level pet stats definitions. DB table `pet_levelstats` is empty.");
3616 Field* fields = result->Fetch();
3621 TC_LOG_ERROR(
"sql.sql",
"Wrong creature id {} in `pet_levelstats` table, ignoring.", creature_id);
3632 TC_LOG_INFO(
"misc",
"Unused (> MaxPlayerLevel in worldserver.conf) level {} in `pet_levelstats` table, ignoring.", current_level);
3637 else if (current_level < 1)
3639 TC_LOG_ERROR(
"sql.sql",
"Wrong (<1) level {} in `pet_levelstats` table, ignoring.", current_level);
3648 PetLevelInfo* pLevelInfo = &pInfoMapEntry[current_level - 1];
3659 while (result->NextRow());
3664 auto& pInfo = itr->second;
3667 if (!pInfo || pInfo[0].health == 0)
3669 TC_LOG_ERROR(
"sql.sql",
"Creature {} does not have pet stats data for Level 1!", itr->first);
3676 if (pInfo[level].health == 0)
3678 TC_LOG_ERROR(
"sql.sql",
"Creature {} has no data for Level {} pet stats data, using data of Level {}.", itr->first, level + 1, level);
3679 pInfo[level] = pInfo[level - 1];
3696 return &itr->second[level - 1];
3706 playerInfo->get()->item.emplace_back(itemId, count);
3710 TC_LOG_ERROR(
"sql.sql",
"Invalid count {} specified on item {} be removed from original player create info (use -1)!", count, itemId);
3714 auto erased = std::remove_if(items.begin(), items.end(), [itemId](
PlayerCreateInfoItem const& item) { return item.item_id == itemId; });
3715 if (erased == items.end())
3717 TC_LOG_ERROR(
"sql.sql",
"Item {} specified to be removed from original create info not found in db2!", itemId);
3721 items.erase(erased, items.end());
3731 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");
3735 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 player create definitions. DB table `playercreateinfo` is empty.");
3744 Field* fields = result->Fetch();
3749 float positionX = fields[3].
GetFloat();
3750 float positionY = fields[4].
GetFloat();
3751 float positionZ = fields[5].
GetFloat();
3752 float orientation = fields[6].
GetFloat();
3756 TC_LOG_ERROR(
"sql.sql",
"Wrong race {} in `playercreateinfo` table, ignoring.", current_race);
3762 TC_LOG_ERROR(
"sql.sql",
"Wrong class {} in `playercreateinfo` table, ignoring.", current_class);
3769 TC_LOG_ERROR(
"sql.sql",
"Wrong home position for class {} race {} pair in `playercreateinfo` table, ignoring.", current_class, current_race);
3773 if (
sMapStore.LookupEntry(mapId)->Instanceable())
3775 TC_LOG_ERROR(
"sql.sql",
"Home position in instanceable map for class {} race {} pair in `playercreateinfo` table, ignoring.", current_class, current_race);
3781 TC_LOG_ERROR(
"sql.sql",
"Missing male model for race {}, ignoring.", current_race);
3787 TC_LOG_ERROR(
"sql.sql",
"Missing female model for race {}, ignoring.", current_race);
3791 std::unique_ptr<PlayerInfo> info = std::make_unique<PlayerInfo>();
3792 info->createPosition.Loc.WorldRelocate(mapId, positionX, positionY, positionZ, orientation);
3794 if (std::none_of(fields + 7, fields + 12, [](
Field const& field) {
return field.
IsNull(); }))
3796 info->createPositionNPE.emplace();
3798 info->createPositionNPE->Loc.WorldRelocate(fields[7].GetUInt32(), fields[8].GetFloat(), fields[9].GetFloat(), fields[10].GetFloat(), fields[11].GetFloat());
3799 if (!fields[12].IsNull())
3800 info->createPositionNPE->TransportGuid = fields[12].
GetUInt64();
3802 if (!
sMapStore.LookupEntry(info->createPositionNPE->Loc.GetMapId()))
3804 TC_LOG_ERROR(
"sql.sql",
"Invalid NPE map id {} for class {} race {} pair in `playercreateinfo` table, ignoring.",
3805 info->createPositionNPE->Loc.GetMapId(), current_class, current_race);
3806 info->createPositionNPE.reset();
3809 if (info->createPositionNPE && info->createPositionNPE->TransportGuid && !
sTransportMgr->GetTransportSpawn(*info->createPositionNPE->TransportGuid))
3811 TC_LOG_ERROR(
"sql.sql",
"Invalid NPE transport spawn id {} for class {} race {} pair in `playercreateinfo` table, ignoring.",
3812 *info->createPositionNPE->TransportGuid, current_class, current_race);
3813 info->createPositionNPE.reset();
3817 if (!fields[13].IsNull())
3821 info->introMovieId = introMovieId;
3823 TC_LOG_ERROR(
"sql.sql",
"Invalid intro movie id {} for class {} race {} pair in `playercreateinfo` table, ignoring.",
3824 introMovieId, current_class, current_race);
3827 if (!fields[14].IsNull())
3831 info->introSceneId = introSceneId;
3833 TC_LOG_ERROR(
"sql.sql",
"Invalid intro scene id {} for class {} race {} pair in `playercreateinfo` table, ignoring.",
3834 introSceneId, current_class, current_race);
3837 if (!fields[15].IsNull())
3841 info->introSceneIdNPE = introSceneId;
3843 TC_LOG_ERROR(
"sql.sql",
"Invalid NPE intro scene id {} for class {} race {} pair in `playercreateinfo` table, ignoring.",
3844 introSceneId, current_class, current_race);
3851 while (result->NextRow());
3858 TC_LOG_INFO(
"server.loading",
"Loading Player Create Items Data...");
3860 std::unordered_map<uint32, std::vector<ItemTemplate const*>> itemsByCharacterLoadout;
3863 itemsByCharacterLoadout[characterLoadoutItem->CharacterLoadoutID].push_back(itemTemplate);
3867 if (!characterLoadout->IsForNewCharacter())
3876 if (!characterLoadout->RaceMask.HasRace(raceIndex))
3881 playerInfo->get()->itemContext =
ItemContext(characterLoadout->ItemContext);
3886 uint32 count = itemTemplate->GetBuyCount();
3891 if (!itemTemplate->Effects.empty())
3893 switch (itemTemplate->Effects[0]->SpellCategoryID)
3903 if (itemTemplate->GetMaxStackSize() < count)
3904 count = itemTemplate->GetMaxStackSize();
3907 playerInfo->get()->item.emplace_back(itemTemplate->GetId(), count);
3914 TC_LOG_INFO(
"server.loading",
"Loading Player Create Items Override Data...");
3922 TC_LOG_INFO(
"server.loading",
">> Loaded 0 custom player create items. DB table `playercreateinfo_item` is empty.");
3930 Field* fields = result->Fetch();
3935 TC_LOG_ERROR(
"sql.sql",
"Wrong race {} in `playercreateinfo_item` table, ignoring.", current_race);
3942 TC_LOG_ERROR(
"sql.sql",
"Wrong class {} in `playercreateinfo_item` table, ignoring.", current_class);
3950 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);
3958 TC_LOG_ERROR(
"sql.sql",
"Item id {} (class {} race {}) have amount == 0 in `playercreateinfo_item` table, ignoring.", item_id, current_race, current_class);
3962 if (!current_race || !current_class)
3964 uint32 min_race = current_race ? current_race : 1;
3966 uint32 min_class = current_class ? current_class : 1;
3968 for (
uint32 r = min_race; r < max_race; ++r)
3969 for (
uint32 c = min_class; c < max_class; ++c)
3977 while (result->NextRow());
3984 TC_LOG_INFO(
"server.loading",
"Loading Player Create Skill Data...");
3989 if (rcInfo->Availability == 1)
3991 if (rcInfo->RaceMask.IsEmpty() || rcInfo->RaceMask.HasRace(raceIndex))
3993 if (rcInfo->ClassMask == -1 || rcInfo->ClassMask == 0 || ((1 << (classIndex - 1)) & rcInfo->ClassMask))
3995 playerInfo->get()->skills.push_back(rcInfo);
4001 TC_LOG_INFO(
"server.loading",
"Loading Player Create Custom Spell Data...");
4009 TC_LOG_INFO(
"server.loading",
">> Loaded 0 player create custom spells. DB table `playercreateinfo_spell_custom` is empty.");
4017 Field* fields = result->Fetch();
4024 TC_LOG_ERROR(
"sql.sql",
"Wrong race mask {} in `playercreateinfo_spell_custom` table, ignoring.", raceMask.
RawValue);
4030 TC_LOG_ERROR(
"sql.sql",
"Wrong class mask {} in `playercreateinfo_spell_custom` table, ignoring.", classMask);
4040 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
4044 playerInfo->get()->customSpells.push_back(spellId);
4056 while (result->NextRow());
4063 TC_LOG_INFO(
"server.loading",
"Loading Player Create Cast Spell Data...");
4067 QueryResult result =
WorldDatabase.PQuery(
"SELECT raceMask, classMask, spell, createMode FROM playercreateinfo_cast_spell");
4070 TC_LOG_INFO(
"server.loading",
">> Loaded 0 player create cast spells. DB table `playercreateinfo_cast_spell` is empty.");
4077 Field* fields = result->Fetch();
4085 TC_LOG_ERROR(
"sql.sql",
"Wrong race mask {} in `playercreateinfo_cast_spell` table, ignoring.", raceMask.
RawValue);
4091 TC_LOG_ERROR(
"sql.sql",
"Wrong class mask {} in `playercreateinfo_cast_spell` table, ignoring.", classMask);
4097 TC_LOG_ERROR(
"sql.sql",
"Uses invalid createMode {} in `playercreateinfo_cast_spell` table, ignoring.", playerCreateMode);
4107 if (classMask == 0 || ((1 << (classIndex - 1)) & classMask))
4111 playerInfo->get()->castSpells[playerCreateMode].push_back(spellId);
4118 }
while (result->NextRow());
4125 TC_LOG_INFO(
"server.loading",
"Loading Player Create Action Data...");
4134 TC_LOG_INFO(
"server.loading",
">> Loaded 0 player create actions. DB table `playercreateinfo_action` is empty.");
4142 Field* fields = result->Fetch();
4147 TC_LOG_ERROR(
"sql.sql",
"Wrong race {} in `playercreateinfo_action` table, ignoring.", current_race);
4154 TC_LOG_ERROR(
"sql.sql",
"Wrong class {} in `playercreateinfo_action` table, ignoring.", current_class);
4163 while (result->NextRow());
4170 TC_LOG_INFO(
"server.loading",
"Loading Player Create Level Stats Data...");
4174 std::array<int16, MAX_STATS> StatModifier = { };
4177 std::array<RaceStats, MAX_RACES> raceStatModifiers = { };
4183 if (!raceStatsResult)
4185 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 race stats definitions. DB table `player_racestats` is empty.");
4191 Field* fields = raceStatsResult->Fetch();
4196 TC_LOG_ERROR(
"sql.sql",
"Wrong race {} in `player_racestats` table, ignoring.", current_race);
4201 raceStatModifiers[current_race].StatModifier[i] = fields[i + 1].GetInt16();
4203 }
while (raceStatsResult->NextRow());
4210 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 level stats definitions. DB table `player_classlevelstats` is empty.");
4218 Field* fields = result->Fetch();
4223 TC_LOG_ERROR(
"sql.sql",
"Wrong class {} in `player_classlevelstats` table, ignoring.", current_class);
4233 TC_LOG_INFO(
"misc",
"Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_classlevelstats` table, ignoring.", current_level);
4238 for (std::size_t race = 0; race < raceStatModifiers.size(); ++race)
4242 if (!playerInfo->get()->levelInfo)
4245 PlayerLevelInfo& levelInfo = playerInfo->get()->levelInfo[current_level - 1];
4247 levelInfo.
stats[i] = fields[i + 2].
GetUInt16() + raceStatModifiers[race].StatModifier[i];
4253 while (result->NextRow());
4294 if (!playerInfo->get()->levelInfo || playerInfo->get()->levelInfo[0].stats[0] == 0)
4296 TC_LOG_ERROR(
"sql.sql",
"Race {} Class {} Level 1 does not have stats data!", race, class_);
4303 if (playerInfo->get()->levelInfo[level].stats[0] == 0)
4305 TC_LOG_ERROR(
"sql.sql",
"Race {} Class {} Level {} does not have stats data. Using stats data of level {}.", race, class_, level + 1, level);
4306 playerInfo->get()->levelInfo[level] = playerInfo->get()->levelInfo[level - 1];
4316 TC_LOG_INFO(
"server.loading",
"Loading Player Create XP Data...");
4336 Field* fields = result->Fetch();
4347 TC_LOG_INFO(
"misc",
"Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_xp_for_level` table, ignoring.", current_level);
4355 }
while (result->NextRow());
4363 TC_LOG_ERROR(
"sql.sql",
"Level {} does not have XP for level data. Using data of level [{}] + 12000.", level + 1, level);
4383 TC_LOG_ERROR(
"misc",
"Tried to get non-existant Class-Level combination data for base hp/mp. Class {} Level {}", class_, level);
4400 *info = pInfo->get()->levelInfo[level - 1];
4502 "ID, QuestType, QuestPackageID, ContentTuningID, QuestSortID, QuestInfoID, SuggestedGroupNum, RewardNextQuest, RewardXPDifficulty, RewardXPMultiplier, "
4504 "RewardMoneyDifficulty, RewardMoneyMultiplier, RewardBonusMoney, RewardSpell, RewardHonor, RewardKillHonor, StartItem, "
4506 "RewardArtifactXPDifficulty, RewardArtifactXPMultiplier, RewardArtifactCategoryID, Flags, FlagsEx, FlagsEx2, "
4508 "RewardItem1, RewardAmount1, ItemDrop1, ItemDropQuantity1, RewardItem2, RewardAmount2, ItemDrop2, ItemDropQuantity2, "
4510 "RewardItem3, RewardAmount3, ItemDrop3, ItemDropQuantity3, RewardItem4, RewardAmount4, ItemDrop4, ItemDropQuantity4, "
4512 "RewardChoiceItemID1, RewardChoiceItemQuantity1, RewardChoiceItemDisplayID1, RewardChoiceItemID2, RewardChoiceItemQuantity2, RewardChoiceItemDisplayID2, "
4514 "RewardChoiceItemID3, RewardChoiceItemQuantity3, RewardChoiceItemDisplayID3, RewardChoiceItemID4, RewardChoiceItemQuantity4, RewardChoiceItemDisplayID4, "
4516 "RewardChoiceItemID5, RewardChoiceItemQuantity5, RewardChoiceItemDisplayID5, RewardChoiceItemID6, RewardChoiceItemQuantity6, RewardChoiceItemDisplayID6, "
4518 "POIContinent, POIx, POIy, POIPriority, RewardTitle, RewardArenaPoints, RewardSkillLineID, RewardNumSkillUps, "
4520 "PortraitGiver, PortraitGiverMount, PortraitGiverModelSceneID, PortraitTurnIn, "
4522 "RewardFactionID1, RewardFactionValue1, RewardFactionOverride1, RewardFactionCapIn1, RewardFactionID2, RewardFactionValue2, RewardFactionOverride2, RewardFactionCapIn2, "
4524 "RewardFactionID3, RewardFactionValue3, RewardFactionOverride3, RewardFactionCapIn3, RewardFactionID4, RewardFactionValue4, RewardFactionOverride4, RewardFactionCapIn4, "
4526 "RewardFactionID5, RewardFactionValue5, RewardFactionOverride5, RewardFactionCapIn5, RewardFactionFlags, "
4528 "RewardCurrencyID1, RewardCurrencyQty1, RewardCurrencyID2, RewardCurrencyQty2, RewardCurrencyID3, RewardCurrencyQty3, RewardCurrencyID4, RewardCurrencyQty4, "
4530 "AcceptedSoundKitID, CompleteSoundKitID, AreaGroupID, TimeAllowed, AllowableRaces, TreasurePickerID, Expansion, ManagedWorldStateID, QuestSessionBonus, "
4532 "LogTitle, LogDescription, QuestDescription, AreaDescription, PortraitGiverText, PortraitGiverName, PortraitTurnInText, PortraitTurnInName, QuestCompletionLog "
4533 "FROM quest_template");
4536 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quests definitions. DB table `quest_template` is empty.");
4547 Field* fields = result->Fetch();
4550 auto itr =
_questTemplates.emplace(std::piecewise_construct, std::forward_as_tuple(questId), std::forward_as_tuple(
new Quest(fields))).first;
4551 itr->second->_weakRef = itr->second;
4552 if (itr->second->IsAutoPush())
4554 }
while (result->NextRow());
4556 struct QuestLoaderHelper
4558 typedef void(
Quest::* QuestLoaderFunction)(
Field* fields);
4560 char const* QueryFields;
4561 char const* TableName;
4562 char const* QueryExtra;
4563 char const* TableDesc;
4564 QuestLoaderFunction LoaderFunction;
4568 QuestLoaderHelper
const QuestLoaderHelpers[] =
4571 {
"QuestID, Type1, Type2, Type3, Type4, Type5, Type6",
"quest_reward_choice_items",
"",
"reward choice items", &
Quest::LoadRewardChoiceItems },
4574 {
"QuestID, SpellID, PlayerConditionID, Type",
"quest_reward_display_spell",
"ORDER BY QuestID ASC, Idx ASC",
"reward display spells", &
Quest::LoadRewardDisplaySpell },
4577 {
"ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4",
"quest_details",
"",
"details", &
Quest::LoadQuestDetails },
4580 {
"ID, EmoteOnComplete, EmoteOnIncomplete, EmoteOnCompleteDelay, EmoteOnIncompleteDelay, CompletionText",
"quest_request_items",
"",
"request items", &
Quest::LoadQuestRequestItems },
4583 {
"ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4, RewardText",
"quest_offer_reward",
"",
"reward emotes", &
Quest::LoadQuestOfferReward },
4586 {
"ID, MaxLevel, AllowableClasses, SourceSpellID, PrevQuestID, NextQuestID, ExclusiveGroup, BreadcrumbForQuestId, RewardMailTemplateID, RewardMailDelay,"
4588 " RequiredSkillID, RequiredSkillPoints, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, ProvidedItemCount, SpecialFlags,"
4596 {
"qo.QuestID, qo.ID, qo.Type, qo.StorageIndex, qo.ObjectID, qo.Amount, qo.Flags, qo.Flags2, qo.ProgressBarWeight, qo.Description, "
4598 "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 },
4613 for (QuestLoaderHelper
const& loader : QuestLoaderHelpers)
4615 result =
WorldDatabase.PQuery(
"SELECT {} FROM {} {}", loader.QueryFields, loader.TableName, loader.QueryExtra);
4618 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quest {}. DB table `{}` is empty.", loader.TableDesc, loader.TableName);
4623 Field* fields = result->Fetch();
4628 (itr->second.get()->*loader.LoaderFunction)(fields);
4630 TC_LOG_ERROR(
"server.loading",
"Table `{}` has data for quest {} but such quest does not exist", loader.TableName, questId);
4631 }
while (result->NextRow());
4637 result =
WorldDatabase.Query(
"SELECT v.ID, o.ID, 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");
4641 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 quest visual effects. DB table `quest_visual_effect` is empty.");
4647 Field* fields = result->Fetch();
4653 TC_LOG_ERROR(
"server.loading",
"Table `quest_visual_effect` has visual effect for null objective id");
4660 TC_LOG_ERROR(
"server.loading",
"Table `quest_visual_effect` has visual effect for objective {} but such objective does not exist.", vID);
4669 itr->second->LoadQuestObjectiveVisualEffect(fields);
4670 }
while (result->NextRow());
4673 std::map<uint32, uint32> usedMailTemplates;
4682 Quest* qinfo = questPair.second.get();
4691 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SpecialFlags` = {} > max allowed value. Correct `SpecialFlags` to value <= {}",
4698 TC_LOG_ERROR(
"sql.sql",
"Weekly Quest {} is marked as daily quest in `Flags`, removed daily flag.", qinfo->
GetQuestId());
4699 qinfo->
_flags &= ~QUEST_FLAGS_DAILY;
4706 TC_LOG_DEBUG(
"sql.sql",
"Daily Quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->
GetQuestId());
4715 TC_LOG_DEBUG(
"sql.sql",
"Weekly Quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->
GetQuestId());
4724 TC_LOG_DEBUG(
"sql.sql",
"Monthly quest {} not marked as repeatable in `SpecialFlags`, added.", qinfo->
GetQuestId());
4736 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemId{}` = {} but item from `RewardChoiceItemId{}` can't be rewarded with quest flag QUEST_FLAGS_TRACKING.",
4745 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `ContentTuningID` = {} but content tuning with this id does not exist.",
4754 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `QuestSortID` = {} (zone case) but zone with this id does not exist.",
4765 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `QuestSortID` = {} (sort case) but quest sort with this id does not exist.",
4774 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `QuestSortID` = {} but `RequiredSkillId` does not have a corresponding value ({}).",
4804 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredSkillId` = {} but this skill does not exist",
4813 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredSkillPoints` = {} but max possible skill is {}, quest can't be done.",
4822 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMinRepFaction` = {} but faction template {} does not exist, quest can't be done.",
4829 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMaxRepFaction` = {} but faction template {} does not exist, quest can't be done.",
4836 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMinRepValue` = {} but max reputation is {}, quest can't be done.",
4843 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMaxRepValue` = {} and `RequiredMinRepValue` = {}, quest can't be done.",
4850 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMinRepValue` = {} but `RequiredMinRepFaction` is 0, value has no effect",
4857 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RequiredMaxRepValue` = {} but `RequiredMaxRepFaction` is 0, value has no effect",
4864 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardTitleId` = {} but CharTitle Id {} does not exist, quest can't be rewarded with title.",
4874 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SourceItemId` = {} but item with entry {} does not exist, quest can't be done.",
4880 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `StartItem` = {} but `ProvidedItemCount` = 0, set to 1 but need fix in DB.",
4887 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SourceItemId` = 0 but `SourceItemIdCount` = {}, useless value.",
4897 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SourceSpellid` = {} but spell {} doesn't exist, quest can't be done.",
4903 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SourceSpellid` = {} but spell {} is broken, quest can't be done.",
4915 if (obj.StorageIndex < 0)
4927 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has invalid StorageIndex = {} for objective type {}", qinfo->
GetQuestId(), obj.ID, obj.StorageIndex, obj.Type);
4938 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing item entry {}, quest can't be done.",
4943 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing creature entry {}, quest can't be done.",
4948 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing gameobject entry {}, quest can't be done.",
4953 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing creature entry {}, quest can't be done.",
4960 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing faction id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
4963 if (obj.Amount <= 0)
4964 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has invalid player kills count {}", qinfo->
GetQuestId(), obj.ID, obj.Amount);
4970 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing currency {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
4971 if (obj.Amount <= 0)
4972 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has invalid currency amount {}", qinfo->
GetQuestId(), obj.ID, obj.Amount);
4976 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing spell id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
4980 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing creature entry {}, quest can't be done.",
4985 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing battlepet species id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
4989 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing criteria tree id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
4993 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing AreaTrigger.db2 id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
4998 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has non existing areatrigger id {}", qinfo->
GetQuestId(), obj.ID, obj.ObjectID);
5005 TC_LOG_ERROR(
"sql.sql",
"Quest {} objective {} has unhandled type {}", qinfo->
GetQuestId(), obj.ID, obj.Type);
5020 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `ItemDrop{}` = {} but item with entry {} does not exist, quest can't be done.",
5029 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `ItemDrop{}` = 0 but `ItemDropQuantity{}` = {}.",
5045 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemId{}` = {} but item with entry {} does not exist, quest will not reward this item.",
5053 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemId{}` = {} but currency with id {} does not exist, quest will not reward this currency.",
5059 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemType{}` = {} but it is not a valid item type, reward removed.",
5067 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemId{}` = {} but `RewardChoiceItemCount{}` = 0.",
5073 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardChoiceItemId{}` = 0 but `RewardChoiceItemCount{}` = {}.",
5086 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardItemId{}` = {} but item with entry {} does not exist, quest will not reward this item.",
5093 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardItemId{}` = {} but `RewardItemCount{}` = 0, quest will not reward this item.",
5100 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardItemId{}` = 0 but `RewardItemCount{}` = {}.",
5123 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardFactionId{}` = 0 but `RewardFactionValueIdOverride{}` = {}.",
5135 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSpellCast` = {} but spell {} does not exist, quest will not have a spell reward.",
5142 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSpellCast` = {} but spell {} is broken, quest will not have a spell reward.",
5152 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardMailTemplateId` = {} but mail template {} does not exist, quest will not have a mail reward.",
5161 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardMailTemplateId` = {} but mail template {} already used for quest {}, quest will not have a mail reward.",
5175 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `NextQuestInChain` = {} but quest {} does not exist, quest chain will not work.",
5187 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardCurrencyId{}` = {} but `RewardCurrencyCount{}` = 0, quest can't be done.",
5194 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardCurrencyId{}` = {} but currency with entry {} does not exist, quest can't be done.",
5201 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardCurrencyId{}` = 0 but `RewardCurrencyCount{}` = {}, quest can't be done.",
5211 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SoundAccept` = {} but sound {} does not exist, set to 0.",
5221 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `SoundTurnIn` = {} but sound {} does not exist, set to 0.",
5231 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSkillId` = {} but this skill does not exist",
5236 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSkillId` = {} but `RewardSkillPoints` is 0",
5245 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSkillPoints` = {} but max possible skill is {}, quest can't be done.",
5251 TC_LOG_ERROR(
"sql.sql",
"Quest {} has `RewardSkillPoints` = {} but `RewardSkillId` is 0",
5262 else if (prevQuestItr->second->_breadcrumbForQuestId)
5263 TC_LOG_ERROR(
"sql.sql",
"Quest {} should not be unlocked by breadcrumb quest {}", qinfo->
_id, prevQuestId);
5274 nextQuestItr->second->DependentPreviousQuests.push_back(qinfo->
GetQuestId());
5281 TC_LOG_ERROR(
"sql.sql",
"Quest {} is a breadcrumb for quest {}, but no such quest exists", qinfo->
_id, breadcrumbForQuestId);
5299 Quest* qinfo = questPair.second.get();
5302 std::set<uint32> questSet;
5304 while(breadcrumbForQuestId)
5308 if (!questSet.insert(qinfo->
_id).second)
5310 TC_LOG_ERROR(
"sql.sql",
"Breadcrumb quests {} and {} are in a loop", qid, breadcrumbForQuestId);
5336 TC_LOG_INFO(
"server.loading",
"Loading GO Start Quest Data...");
5338 TC_LOG_INFO(
"server.loading",
"Loading GO End Quest Data...");
5340 TC_LOG_INFO(
"server.loading",
"Loading Creature Start Quest Data...");
5342 TC_LOG_INFO(
"server.loading",
"Loading Creature End Quest Data...");
5354 "LogTitle, LogDescription, QuestDescription, AreaDescription, PortraitGiverText, PortraitGiverName, PortraitTurnInText, PortraitTurnInName, QuestCompletionLog"
5355 " FROM quest_template_locale");
5361 Field* fields = result->Fetch();
5380 }
while (result->NextRow());
5397 Field* fields = result->Fetch();
5409 while (result->NextRow());
5429 Field* fields = result->Fetch();
5438 TC_LOG_ERROR(
"sql.sql",
"Table `quest_greeting_locale`: creature template entry {} does not exist.",
id);
5445 TC_LOG_ERROR(
"sql.sql",
"Table `quest_greeting_locale`: gameobject template entry {} does not exist.",
id);
5463 while (result->NextRow());
5480 Field* fields = result->Fetch();
5491 }
while (result->NextRow());
5508 Field* fields = result->Fetch();
5519 }
while (result->NextRow());
5533 if (tableName.empty())
5536 if (
sMapMgr->IsScriptScheduled())
5539 TC_LOG_INFO(
"server.loading",
"Loading {}...", tableName);
5545 QueryResult result =
WorldDatabase.PQuery(
"SELECT id, delay, command, datalong, datalong2, dataint, x, y, z, o{} FROM {}", isSpellScriptTable ?
", effIndex" :
"", tableName);
5549 TC_LOG_INFO(
"server.loading",
">> Loaded 0 script definitions. DB table `{}` is empty!", tableName);
5557 Field* fields = result->Fetch();
5561 if (isSpellScriptTable)
5580 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid talk type (datalong = {}) in SCRIPT_COMMAND_TALK for script id {}",
5586 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid talk text id (dataint = {}) in SCRIPT_COMMAND_TALK for script id {}",
5598 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid emote id (datalong = {}) in SCRIPT_COMMAND_EMOTE for script id {}",
5609 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid map (Id: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
5616 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TELEPORT_TO for script id {}",
5628 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid quest (ID: {}) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id {}",
5635 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.",
5642 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 {}",
5649 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",
5656 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",
5668 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_KILL_CREDIT for script id {}",
5680 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid gameobject (GUID: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5688 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5699 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has gameobject type ({}) unsupported by command SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id {}",
5700 tableName, info->
entry, tmp.
id);
5710 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid coordinates (X: {} Y: {} Z: {} O: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
5717 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid creature (Entry: {}) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id {}",
5730 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid gameobject (GUID: {}) in {} for script id {}",
5738 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has gameobject with invalid entry (GUID: {} Entry: {}) in {} for script id {}",
5745 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has gameobject type ({}) unsupported by command {} for script id {}",
5757 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
5763 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using unknown flags in datalong2 ({}) in SCRIPT_COMMAND_REMOVE_AURA for script id {}",
5774 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using non-existent spell (id: {}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5780 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using unknown target in datalong2 ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5786 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using unknown flags in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5792 TC_LOG_ERROR(
"sql.sql",
"Table `{}` using invalid creature entry in dataint ({}) in SCRIPT_COMMAND_CAST_SPELL for script id {}",
5803 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has nonexistent item (entry: {}) in SCRIPT_COMMAND_CREATE_ITEM for script id {}",
5809 TC_LOG_ERROR(
"sql.sql",
"Table `{}` SCRIPT_COMMAND_CREATE_ITEM but amount is {} for script id {}",
5819 TC_LOG_ERROR(
"sql.sql",
"Table `{}` has invalid AnimKid id (datalong = {}) in SCRIPT_COMMAND_PLAY_ANIMKIT for script id {}",
5836 if (scripts->find(tmp.
id) == scripts->end())
5839 (*scripts)[tmp.
id] = emptyMap;
5841 (*scripts)[tmp.
id].insert(std::pair<uint32, ScriptInfo>(tmp.
delay, tmp));
5845 while (result->NextRow());
5862 TC_LOG_ERROR(
"sql.sql",
"Table `spell_scripts` has not existing spell (Id: {}) as script id", spellId);
5869 TC_LOG_ERROR(
"sql.sql",
"Table `spell_scripts` has too high effect index {} for spell (Id: {}) as script id",
uint32(i), spellId);
5875 TC_LOG_ERROR(
"sql.sql",
"Table `spell_scripts` - spell {} effect {} is not SPELL_EFFECT_SCRIPT_EFFECT or SPELL_EFFECT_DUMMY", spellId,
uint32(i));
5886 EventContainer eventSet = gameObjectTemplatePair.second.GetEventScriptSet();
5887 _eventStore.insert(eventSet.begin(), eventSet.end());
5893 _eventStore.insert(spellEffect->EffectMiscValue[0]);
5898 if (node->ArrivalEventID)
5901 if (node->DepartureEventID)
5906 auto addCriteriaEventsToStore = [&](
CriteriaList const& criteriaList)
5908 for (
Criteria const* criteria : criteriaList)
5909 if (criteria->Entry->Asset.EventID)
5910 _eventStore.insert(criteria->Entry->Asset.EventID);
5916 addCriteriaEventsToStore(
sCriteriaMgr->GetPlayerCriteriaByType(criteriaType, 0));
5917 addCriteriaEventsToStore(
sCriteriaMgr->GetGuildCriteriaByType(criteriaType));
5918 addCriteriaEventsToStore(
sCriteriaMgr->GetQuestObjectiveCriteriaByType(criteriaType));
5923 addCriteriaEventsToStore(
sCriteriaMgr->GetScenarioCriteriaByTypeAndScenario(criteriaType, scenario->ID));
5946 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 {}",
5957 TC_LOG_INFO(
"server.loading",
">> Loaded 0 event scripts. DB table `event_script_names` is empty.");
5963 Field* fields = result->Fetch();
5966 std::string
const scriptName = fields[1].
GetString();
5970 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 {}",
5975 }
while (result->NextRow());
5990 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spell script names. DB table `spell_script_names` is empty!");
5999 Field* fields = result->Fetch();
6002 std::string
const scriptName = fields[1].
GetString();
6004 bool allRanks =
false;
6014 TC_LOG_ERROR(
"sql.sql",
"Scriptname: `{}` spell (Id: {}) does not exist.", scriptName, fields[0].GetInt32());
6021 TC_LOG_ERROR(
"sql.sql",
"Scriptname: `{}` spell (Id: {}) has no ranks of spell.", scriptName, fields[0].GetInt32());
6025 TC_LOG_ERROR(
"sql.sql",
"Scriptname: `{}` spell (Id: {}) is not first rank of spell.", scriptName, fields[0].GetInt32());
6037 TC_LOG_ERROR(
"sql.sql",
"Scriptname: `{}` spell (Id: {}) is ranked spell. Perhaps not all ranks are assigned to this script.", scriptName, spellId);
6044 while (result->NextRow());
6055 TC_LOG_INFO(
"server.loading",
">> Validated 0 scripts.");
6069 std::unique_ptr<SpellScript> spellScript(spellScriptLoader->GetSpellScript());
6070 std::unique_ptr<AuraScript> auraScript(spellScriptLoader->GetAuraScript());
6072 if (!spellScript && !auraScript)
6074 TC_LOG_ERROR(
"scripts",
"Functions GetSpellScript() and GetAuraScript() of script `{}` do not return objects - script skipped",
GetScriptName(spell.second.first));
6076 spell.second.second =
false;
6082 spellScript->_Init(spellScriptLoader->GetName(), spellEntry->
Id);
6083 spellScript->_Register();
6085 if (!spellScript->_Validate(spellEntry))
6087 spell.second.second =
false;
6094 auraScript->_Init(spellScriptLoader->GetName(), spellEntry->
Id);
6095 auraScript->_Register();
6097 if (!auraScript->_Validate(spellEntry))
6099 spell.second.second =
false;
6105 spell.second.second =
true;
6108 spell.second.second =
false;
6119 QueryResult result =
WorldDatabase.Query(
"SELECT ID, `Text`, NextPageID, PlayerConditionID, Flags FROM page_text");
6122 TC_LOG_INFO(
"server.loading",
">> Loaded 0 page texts. DB table `page_text` is empty!");
6129 Field* fields = result->Fetch();
6141 while (result->NextRow());
6144 if (itr->second.NextPageID)
6146 TC_LOG_ERROR(
"sql.sql",
"Page text (ID: {}) has non-existing `NextPageID` ({})", itr->first, itr->second.NextPageID);
6153 PageTextContainer::const_iterator itr =
_pageTextStore.find(pageEntry);
6155 return &(itr->second);
6173 Field* fields = result->Fetch();
6184 }
while (result->NextRow());
6198 TC_LOG_INFO(
"server.loading",
">> Loaded 0 instance templates. DB table `page_text` is empty!");
6205 Field* fields = result->Fetch();
6211 TC_LOG_ERROR(
"sql.sql",
"ObjectMgr::LoadInstanceTemplate: bad mapid {} for template!", mapID);
6217 instanceTemplate.
Parent =
uint32(fields[1].GetUInt16());
6224 while (result->NextRow());
6233 return &(itr->second);
6240 NpcTextContainer::const_iterator itr =
_npcTextStore.find(Text_ID);
6242 return &itr->second;
6251 "Probability0, Probability1, Probability2, Probability3, Probability4, Probability5, Probability6, Probability7, "
6252 "BroadcastTextID0, BroadcastTextID1, BroadcastTextID2, BroadcastTextID3, BroadcastTextID4, BroadcastTextID5, BroadcastTextID6, BroadcastTextID7"
6256 TC_LOG_INFO(
"server.loading",
">> Loaded 0 npc texts, table is empty!");
6264 Field* fields = result->Fetch();
6269 TC_LOG_ERROR(
"sql.sql",
"Table `npc_text` has record with reserved id 0, ignore.");
6298 TC_LOG_ERROR(
"sql.sql",
"NPCText (ID: {}) has a probability (Index: {}) set, but no BroadcastTextID to go with it", textID, i);
6303 float probabilitySum = std::accumulate(std::begin(npcText.
Data), std::end(npcText.
Data), 0.0f, [](
float sum,
NpcTextData const& data) { return sum + data.Probability; });
6304 if (probabilitySum <= 0.0f)
6306 TC_LOG_ERROR(
"sql.sql",
"NPCText (ID: {}) has a probability sum 0, no text can be selected from it, skipped.", textID);
6312 while (result->NextRow());
6324 localtime_r(&curTime, <);
6325 TC_LOG_INFO(
"misc",
"Returning mails current time: hour: {}, minute: {}, second: {} ", lt.tm_hour, lt.tm_min, lt.tm_sec);
6339 TC_LOG_INFO(
"server.loading",
">> No expired mails found.");
6351 Field* fields = items->Fetch();
6355 itemsCache[mailId].push_back(item);
6356 }
while (items->NextRow());
6360 uint32 returnedCount = 0;
6363 Field* fields = result->Fetch();
6373 bool has_items = fields[4].
GetBool();
6391 for (MailItemInfoVec::iterator itr2 = m->
items.begin(); itr2 != m->
items.end(); ++itr2)
6413 for (MailItemInfoVec::iterator itr2 = m->
items.begin(); itr2 != m->
items.end(); ++itr2)
6438 while (result->NextRow());
6440 TC_LOG_INFO(
"server.loading",
">> Processed {} expired mails: {} deleted and {} returned in {} ms", deletedCount + returnedCount, deletedCount, returnedCount,
GetMSTimeDiffToNow(oldMSTime));
6453 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quest trigger points. DB table `areatrigger_involvedrelation` is empty.");
6463 Field* fields = result->Fetch();
6471 TC_LOG_ERROR(
"sql.sql",
"Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", trigger_ID);
6479 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger_involvedrelation` has record (id: {}) for not existing quest {}", trigger_ID, quest_ID);
6485 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);
6491 }
while (result->NextRow());
6537 QueryResult result =
WorldDatabase.Query(
"SELECT ID, type, GreetEmoteType, GreetEmoteDelay, Greeting FROM quest_greeting");
6540 TC_LOG_INFO(
"server.loading",
">> Loaded 0 npc texts, table is empty!");
6547 Field* fields = result->Fetch();
6556 TC_LOG_ERROR(
"sql.sql",
"Table `quest_greeting`: creature template entry {} does not exist.",
id);
6563 TC_LOG_ERROR(
"sql.sql",
"Table `quest_greeting`: gameobject template entry {} does not exist.",
id);
6573 std::string greeting = fields[4].
GetString();
6575 _questGreetingStore[type].emplace(std::piecewise_construct, std::forward_as_tuple(
id), std::forward_as_tuple(greetEmoteType, greetEmoteDelay, std::move(greeting)));
6578 while (result->NextRow());
6593 TC_LOG_INFO(
"server.loading",
">> Loaded 0 tavern triggers. DB table `areatrigger_tavern` is empty.");
6603 Field* fields = result->Fetch();
6610 TC_LOG_ERROR(
"sql.sql",
"Area trigger (ID:{}) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
6615 }
while (result->NextRow());
6629 TC_LOG_INFO(
"server.loading",
">> Loaded 0 areatrigger scripts. DB table `areatrigger_scripts` is empty.");
6635 Field* fields = result->Fetch();
6638 std::string
const scriptName = fields[1].
GetString();
6643 TC_LOG_ERROR(
"sql.sql",
"AreaTrigger (ID: {}) does not exist in `AreaTrigger.dbc`.", triggerId);
6648 while (result->NextRow());
6666 uint32 submask = 1 << ((node->ID - 1) % 8);
6672 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);
6697 path = taxiPath->
ID;
6698 cost = taxiPath->
Cost;
6724 if (mount_entry == 0 && allowed_alt_team)
6736 TC_LOG_ERROR(
"sql.sql",
"No displayid found for the taxi mount with the entry {}! Can't load it!", mount_entry);
6739 mountModel = *model;
6766 TC_LOG_INFO(
"server.loading",
">> Loaded 0 graveyard-zone links. DB table `graveyard_zone` is empty.");
6776 Field* fields = result->Fetch();
6784 TC_LOG_ERROR(
"sql.sql",
"Table `graveyard_zone` has a record for non-existing graveyard (WorldSafeLocsID: {}), skipped.", safeLocId);
6791 TC_LOG_ERROR(
"sql.sql",
"Table `graveyard_zone` has a record for non-existing Zone (ID: {}), skipped.", zoneId);
6796 TC_LOG_ERROR(
"sql.sql",
"Table `graveyard_zone` has a duplicate record for Graveyard (ID: {}) and Zone (ID: {}), skipped.", safeLocId, zoneId);
6797 }
while (result->NextRow());
6804 enum DefaultGraveyard
6806 HORDE_GRAVEYARD = 10,
6807 ALLIANCE_GRAVEYARD = 4
6814 else return nullptr;
6830 TC_LOG_ERROR(
"misc",
"ZoneId not found for map {} coords ({}, {}, {})", MapId, x, y, z);
6839 while (!graveyard && parentEntry)
6845 parentEntry =
nullptr;
6871 TC_LOG_ERROR(
"sql.sql",
"Table `game_graveyard_zone` incomplete: Zone {} Team {} does not have a linked graveyard.", zoneId, team);
6876 bool foundNear =
false;
6877 float distNear = 10000;
6881 bool foundEntr =
false;
6882 float distEntr = 10000;
6890 for (; range.first != range.second; ++range.first)
6896 if (conditionObject)
6906 bool teamConditionMet =
true;
6909 for (
Condition const& cond : *conditions)
6914 if (cond.ConditionValue1 == team)
6917 teamConditionMet =
false;
6921 if (!teamConditionMet)
6944 if (dist2 < distEntr)
6965 if (dist2 < distNear)
6992 for (; range.first != range.second; ++range.first)
7010 Field* fields = result->Fetch();
7012 WorldLocation loc(fields[1].GetUInt32(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat(),
DegToRad(fields[5].GetFloat()));
7020 worldSafeLocs.
ID = id;
7023 }
while (result->NextRow());
7028 TC_LOG_INFO(
"server.loading",
">> Loaded 0 world locations. DB table `world_safe_locs` is empty.");
7045 return &itr->second;
7063 GraveyardStore.insert(GraveyardContainer::value_type(zoneId, data));
7116 TC_LOG_INFO(
"server.loading",
">> Loaded 0 area trigger teleport definitions. DB table `areatrigger_teleport` is empty.");
7124 Field* fields = result->Fetch();
7134 TC_LOG_ERROR(
"sql.sql",
"Area Trigger (ID: {}) has a non-existing Port Loc (ID: {}) in WorldSafeLocs.dbc, skipped", Trigger_ID, PortLocID);
7149 TC_LOG_ERROR(
"sql.sql",
"Area Trigger (ID: {}) does not exist in AreaTrigger.dbc.", Trigger_ID);
7155 }
while (result->NextRow());
7167 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");
7171 TC_LOG_INFO(
"server.loading",
">> Loaded 0 access requirement definitions. DB table `access_requirement` is empty.");
7179 Field* fields = result->Fetch();
7184 TC_LOG_ERROR(
"sql.sql",
"Map {} referenced in `access_requirement` does not exist, skipped.", mapid);
7191 TC_LOG_ERROR(
"sql.sql",
"Map {} referenced in `access_requirement` does not have difficulty {}, skipped", mapid, difficulty);
7212 TC_LOG_ERROR(
"sql.sql",
"Key item {} does not exist for map {} difficulty {}, removing key requirement.", ar->
item, mapid, difficulty);
7222 TC_LOG_ERROR(
"sql.sql",
"Second item {} does not exist for map {} difficulty {}, removing key requirement.", ar->
item2, mapid, difficulty);
7231 TC_LOG_ERROR(
"sql.sql",
"Required Alliance Quest {} not exist for map {} difficulty {}, remove quest done requirement.", ar->
quest_A, mapid, difficulty);
7240 TC_LOG_ERROR(
"sql.sql",
"Required Horde Quest {} not exist for map {} difficulty {}, remove quest done requirement.", ar->
quest_H, mapid, difficulty);
7249 TC_LOG_ERROR(
"sql.sql",
"Required Achievement {} not exist for map {} difficulty {}, remove quest done requirement.", ar->
achievement, mapid, difficulty);
7255 }
while (result->NextRow());
7272 parentId = iTemplate->Parent;
7277 if (itr->second.target_mapId == entrance_map)
7281 return &itr->second;
7294 if (itr->second.target_mapId ==
Map)
7298 return &itr->second;
7317 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 >= '{}'",
7321 result =
WorldDatabase.Query(
"SELECT MAX(guid) FROM transports");
7331 _mailId = (*result)[0].GetUInt64()+1;
7335 sArenaTeamMgr->SetNextArenaTeamId((*result)[0].GetUInt32()+1);
7337 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");
7343 sGuildMgr->SetNextGuildId((*result)[0].GetUInt64()+1);
7347 sGroupMgr->SetGroupDbStoreSize((*result)[0].GetUInt32()+1);
7349 result =
CharacterDatabase.Query(
"SELECT MAX(itemId) from character_void_storage");
7353 result =
WorldDatabase.Query(
"SELECT MAX(guid) FROM creature");
7357 result =
WorldDatabase.Query(
"SELECT MAX(guid) FROM gameobject");
7366 itr =
_guidGenerators.insert(std::make_pair(high, std::make_unique<ObjectGuidGenerator>(high))).first;
7368 return *itr->second;
7375 TC_LOG_ERROR(
"misc",
"Auctions ids overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7385 TC_LOG_ERROR(
"misc",
"EquipmentSet guid overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7395 TC_LOG_ERROR(
"misc",
"Mail ids overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7405 TC_LOG_ERROR(
"misc",
"_hiPetNumber Id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info.");
7415 TC_LOG_ERROR(
"misc",
"_voidItemId overflow!! Can't continue, shutting down server. ");
7425 TC_LOG_ERROR(
"misc",
"Creature spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info.");
7435 TC_LOG_ERROR(
"misc",
"GameObject spawn id overflow!! Can't continue, shutting down server. Search on forum for TCE00007 for more info. ");
7448 QueryResult result =
WorldDatabase.Query(
"SELECT entry, locale, name, castBarCaption, unk1 FROM gameobject_template_locale");
7454 Field* fields = result->Fetch();
7468 }
while (result->NextRow());
7478 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but lock (Id: {}) not found.",
7479 goInfo->
entry, goInfo->
type, N, dataN, dataN);
7487 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but GO (Entry {}) have not GAMEOBJECT_TYPE_TRAP ({}) type.",
7497 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but Spell (Entry {}) not exist.",
7498 goInfo->
entry, goInfo->
type, N, dataN, dataN);
7506 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but correct chair height in range 0..{}.",
7519 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but expected boolean (0/1) noDamageImmune field value.", goTemplate->
entry, goTemplate->
type, N, dataN);
7528 TC_LOG_ERROR(
"sql.sql",
"Gameobject (Entry: {} GoType: {}) have data{}={} but expected boolean (0/1) consumable field value.",
7539 go.
entry = db2go->ID;
7540 go.
type = db2go->TypeID;
7542 go.
name = db2go->Name[
sWorld->GetDefaultDbcLocale()];
7543 go.
size = db2go->Scale;
7545 std::copy(db2go->PropValue.begin(), db2go->PropValue.end(), std::begin(go.
raw.
data));
7551 QueryResult result =
WorldDatabase.Query(
"SELECT entry, type, displayId, name, IconName, castBarCaption, unk1, size, "
7553 "Data0, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11, Data12, "
7555 "Data13, Data14, Data15, Data16, Data17, Data18, Data19, Data20, Data21, Data22, Data23, Data24, Data25, Data26, Data27, Data28, "
7557 "Data29, Data30, Data31, Data32, Data33, Data34, ContentTuningId, AIName, ScriptName, StringId "
7558 "FROM gameobject_template");
7562 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject definitions. DB table `gameobject_template` is empty.");
7569 Field* fields = result->Fetch();
7594 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {}) has non-registered `AIName` '{}' set, removing", got.
entry, got.
AIName);
7646 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {} GoType: {}) have data0={} but SpellFocus (Id: {}) not exist.",
7664 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {} GoType: {}) have data7={} but PageText (Entry {}) not exist.",
7689 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {} GoType: {}) have data0={} but TaxiPath (Id: {}) not exist.",
7729 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {} GoType: {}) have data2 = {} but AnimKit.dbc (Id: {}) not exist, set to 0.",
7745 }
while (result->NextRow());
7755 QueryResult result =
WorldDatabase.Query(
"SELECT entry, faction, flags, mingold, maxgold, artkit0, artkit1, artkit2, artkit3, artkit4, WorldEffectID, AIAnimKitID FROM gameobject_template_addon");
7759 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject template addon definitions. DB table `gameobject_template_addon` is empty.");
7766 Field* fields = result->Fetch();
7773 TC_LOG_ERROR(
"sql.sql",
"GameObject template (Entry: {}) does not exist but has a record in `gameobject_template_addon`", entry);
7793 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {}) has invalid `artkit{}` ({}) defined, set to zero instead.", entry, i, artKitID);
7797 gameObjectAddon.
ArtKits[i] = artKitID;
7802 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {}) has invalid faction ({}) defined in `gameobject_template_addon`.", entry, gameObjectAddon.
Faction);
7804 if (gameObjectAddon.
Maxgold > 0)
7812 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry {} GoType: {}) cannot be looted but has maxgold set in `gameobject_template_addon`.", entry, got->
type);
7819 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {}) has invalid WorldEffectID ({}) defined in `gameobject_template_addon`, set to 0.", entry, gameObjectAddon.
WorldEffectID);
7825 TC_LOG_ERROR(
"sql.sql",
"GameObject (Entry: {}) has invalid AIAnimKitID ({}) defined in `gameobject_template_addon`, set to 0.", entry, gameObjectAddon.
AIAnimKitID);
7831 while (result->NextRow());
7844 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject faction and flags overrides. DB table `gameobject_overrides` is empty.");
7851 Field* fields = result->Fetch();
7857 TC_LOG_ERROR(
"sql.sql",
"GameObject (SpawnId: {}) does not exist but has a record in `gameobject_overrides`", spawnId);
7866 TC_LOG_ERROR(
"sql.sql",
"GameObject (SpawnId: {}) has invalid faction ({}) defined in `gameobject_overrides`.", spawnId, gameObjectOverride.
Faction);
7869 }
while (result->NextRow());
7882 TC_LOG_INFO(
"server.loading",
">> Loaded 0 BaseXP definitions. DB table `exploration_basexp` is empty.");
7890 Field* fields = result->Fetch();
7896 while (result->NextRow());
7927 TC_LOG_ERROR(
"sql.sql",
"Fishable areaId {} is not properly defined in `skill_fishing_base_level`.", areaEntry->
ID);
7935 return itr !=
_skillTiers.end() ? &itr->second :
nullptr;
7943 while (
Value[tierIndex] == 0 && tierIndex > 0)
7946 return Value[tierIndex];
7957 TC_LOG_INFO(
"server.loading",
">> Loaded 0 pet name parts. DB table `pet_name_generation` is empty!");
7965 Field* fields = result->Fetch();
7966 std::string word = fields[0].
GetString();
7968 bool half = fields[2].
GetBool();
7975 while (result->NextRow());
7987 Field* fields = result->Fetch();
7999 if (list0.empty() || list1.empty())
8003 return std::string();
8007 return std::string(petname);
8012 return *(list0.begin()+
urand(0, list0.size()-1)) + *(list1.begin()+
urand(0, list1.size()-1));
8022 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");
8025 TC_LOG_INFO(
"server.loading",
">> Loaded `reputation_reward_rate`, table is empty!");
8031 Field* fields = result->Fetch();
8048 TC_LOG_ERROR(
"sql.sql",
"Faction (faction.dbc) {} does not exist but is used in `reputation_reward_rate`", factionId);
8054 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has quest_rate with invalid rate {}, skipping data for faction {}", repRate.
questRate, factionId);
8060 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has quest_daily_rate with invalid rate {}, skipping data for faction {}", repRate.
questDailyRate, factionId);
8066 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has quest_weekly_rate with invalid rate {}, skipping data for faction {}", repRate.
questWeeklyRate, factionId);
8072 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has quest_monthly_rate with invalid rate {}, skipping data for faction {}", repRate.
questMonthlyRate, factionId);
8078 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has quest_repeatable_rate with invalid rate {}, skipping data for faction {}", repRate.
questRepeatableRate, factionId);
8084 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has creature_rate with invalid rate {}, skipping data for faction {}", repRate.
creatureRate, factionId);
8090 TC_LOG_ERROR(
"sql.sql",
"Table reputation_reward_rate has spell_rate with invalid rate {}, skipping data for faction {}", repRate.
spellRate, factionId);
8098 while (result->NextRow());
8115 "IsTeamAward1, MaxStanding1, RewOnKillRepValue1, IsTeamAward2, MaxStanding2, RewOnKillRepValue2, TeamDependent "
8116 "FROM creature_onkill_reputation");
8120 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature award reputation definitions. DB table `creature_onkill_reputation` is empty.");
8126 Field* fields = result->Fetch();
8143 TC_LOG_ERROR(
"sql.sql",
"Table `creature_onkill_reputation` has data for nonexistent creature entry ({}), skipped", creature_id);
8152 TC_LOG_ERROR(
"sql.sql",
"Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.
RepFaction1);
8162 TC_LOG_ERROR(
"sql.sql",
"Faction (faction.dbc) {} does not exist but is used in `creature_onkill_reputation`", repOnKill.
RepFaction2);
8170 }
while (result->NextRow());
8182 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");
8186 TC_LOG_INFO(
"server.loading",
">> Loaded `reputation_spillover_template`, table is empty.");
8192 Field* fields = result->Fetch();
8218 TC_LOG_ERROR(
"sql.sql",
"Faction (faction.dbc) {} does not exist but is used in `reputation_spillover_template`", factionId);
8224 TC_LOG_ERROR(
"sql.sql",
"Faction (faction.dbc) {} in `reputation_spillover_template` does not belong to any team, skipping", factionId);
8228 bool invalidSpilloverFaction =
false;
8235 if (!factionSpillover)
8237 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);
8238 invalidSpilloverFaction =
true;
8244 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);
8245 invalidSpilloverFaction =
true;
8251 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]);
8252 invalidSpilloverFaction =
true;
8258 if (invalidSpilloverFaction)
8265 while (result->NextRow());
8279 QueryResult result =
WorldDatabase.Query(
"SELECT ID, PositionX, PositionY, PositionZ, Icon, Flags, Importance, Name, WMOGroupID FROM points_of_interest");
8283 TC_LOG_INFO(
"server.loading",
">> Loaded 0 Points of Interest definitions. DB table `points_of_interest` is empty.");
8289 Field* fields = result->Fetch();
8294 pointOfInterest.
ID = id;
8295 pointOfInterest.
Pos.
Relocate(fields[1].GetFloat(), fields[2].GetFloat(), fields[3].GetFloat());
8304 TC_LOG_ERROR(
"sql.sql",
"Table `points_of_interest` (ID: {}) have invalid coordinates (PositionX: {} PositionY: {}, PositionZ: {}), ignored.",
8312 }
while (result->NextRow());
8324 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");
8327 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty.");
8332 QueryResult pointsResult =
WorldDatabase.Query(
"SELECT QuestID, Idx1, X, Y, Z FROM quest_poi_points ORDER BY QuestID DESC, Idx1, Idx2");
8334 std::unordered_map<int32, std::map<int32, std::vector<QuestPOIBlobPoint>>> allPoints;
8340 Field* fields = pointsResult->Fetch();
8348 allPoints[QuestID][Idx1].emplace_back(x, y, z);
8349 }
while (pointsResult->NextRow());
8354 Field* fields = result->Fetch();
8370 bool alwaysAllowMergingBlobs = fields[14].
GetBool();
8373 TC_LOG_ERROR(
"sql.sql",
"`quest_poi` quest id ({}) Idx1 ({}) does not exist in `quest_template`", questID, idx1);
8381 poiData.
Blobs.emplace_back(blobIndex, objectiveIndex, questObjectiveID, questObjectID, mapID, uiMapID, priority,
flags,
8382 worldEffectID, playerConditionID, navigationPlayerConditionID, spawnTrackingID, std::move(*points), alwaysAllowMergingBlobs);
8387 TC_LOG_ERROR(
"sql.sql",
"Table quest_poi references unknown quest points for quest {} POI id {}", questID, blobIndex);
8389 }
while (result->NextRow());
8400 QueryResult result =
WorldDatabase.Query(
"SELECT npc_entry, spell_id, cast_flags, user_type FROM npc_spellclick_spells");
8404 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spellclick spells. DB table `npc_spellclick_spells` is empty.");
8412 Field* fields = result->Fetch();
8418 TC_LOG_ERROR(
"sql.sql",
"Table npc_spellclick_spells references unknown creature_template {}. Skipping entry.", npc_entry);
8426 TC_LOG_ERROR(
"sql.sql",
"Table npc_spellclick_spells creature: {} references unknown spellid {}. Skipping entry.", npc_entry, spellid);
8432 TC_LOG_ERROR(
"sql.sql",
"Table npc_spellclick_spells creature: {} references unknown user type {}. Skipping entry.", npc_entry,
uint32(userType));
8443 while (result->NextRow());
8451 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);
8452 creatureTemplatePair.second.npcflag &= ~UNIT_NPC_FLAG_SPELLCLICK;
8497 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quest relations from `{}`, table is empty.", table);
8503 uint32 id = result->Fetch()[0].GetUInt32();
8504 uint32 quest = result->Fetch()[1].GetUInt32();
8508 TC_LOG_ERROR(
"sql.sql",
"Table `{}`: Quest {} listed for entry {} does not exist.", table, quest,
id);
8512 map.insert(QuestRelations::value_type(
id, quest));
8514 reverseMap->insert(QuestRelationsReverse::value_type(quest,
id));
8516 }
while (result->NextRow());
8529 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject_queststarter` has data for nonexistent gameobject entry ({}) and existed quest {}", itr->first, itr->second);
8531 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);
8543 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject_questender` has data for nonexistent gameobject entry ({}) and existed quest {}", itr->first, itr->second);
8545 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);
8557 TC_LOG_ERROR(
"sql.sql",
"Table `creature_queststarter` has data for nonexistent creature entry ({}) and existed quest {}", itr->first, itr->second);
8559 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);
8571 TC_LOG_ERROR(
"sql.sql",
"Table `creature_questender` has data for nonexistent creature entry ({}) and existed quest {}", itr->first, itr->second);
8573 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);
8592 _reservedNamesStore.clear();
8598 TC_LOG_INFO(
"server.loading",
">> Loaded 0 reserved player names. DB table `reserved_name` is empty!");
8607 fields = result->Fetch();
8608 std::string name= fields[0].
GetString();
8613 TC_LOG_ERROR(
"misc",
"Table `reserved_name` has invalid name: {}", name);
8619 _reservedNamesStore.insert(wstr);
8622 while (result->NextRow());
8635 return _reservedNamesStore.find(wstr) != _reservedNamesStore.end();
8641 return create ? category->GetCreateCharsetMask() : category->GetExistingCharsetMask();
8648 if (strictMask == 0)
8661 if (strictMask & 0x2)
8678 if (strictMask & 0x1)
8697 if (wname.size() < minName)
8705 for (
size_t i = 2; i < wname.size(); ++i)
8706 if (wname[i] == wname[i-1] && wname[i] == wname[i-2])
8722 if (wname.size() < minName)
8740 if (wname.size() < minName)
8754 _gameObjectForQuestStore.clear();
8756 if (_gameObjectTemplateStore.empty())
8758 TC_LOG_INFO(
"server.loading",
">> Loaded 0 GameObjects for quests");
8765 for (
auto const& gameObjectTemplatePair : _gameObjectTemplateStore)
8767 switch (gameObjectTemplatePair.second.type)
8775 if (gameObjectTemplatePair.second.chest.questID
8784 if (gameObjectTemplatePair.second.generic.questID > 0)
8790 if (gameObjectTemplatePair.second.goober.questID > 0)
8806 _gameObjectForQuestStore.insert(gameObjectTemplatePair.first);
8817 _trinityStringStore.clear();
8819 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");
8822 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.");
8828 Field* fields = result->Fetch();
8839 while (result->NextRow());
8849 if (ts->Content.size() >
size_t(locale) && !ts->Content[locale].empty())
8850 return ts->
Content[locale].c_str();
8854 TC_LOG_ERROR(
"sql.sql",
"Trinity string entry {} not found in DB.", entry);
8862 _fishingBaseForAreaStore.clear();
8868 TC_LOG_INFO(
"server.loading",
">> Loaded 0 areas for fishing base skill level. DB table `skill_fishing_base_level` is empty.");
8876 Field* fields = result->Fetch();
8883 TC_LOG_ERROR(
"sql.sql",
"AreaId {} defined in `skill_fishing_base_level` does not exist", entry);
8887 _fishingBaseForAreaStore[entry] = skill;
8890 while (result->NextRow());
8899 QueryResult result =
WorldDatabase.Query(
"SELECT ID, Value1, Value2, Value3, Value4, Value5, Value6, Value7, Value8, Value9, Value10, "
8900 " Value11, Value12, Value13, Value14, Value15, Value16 FROM skill_tiers");
8904 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 skill max values. DB table `skill_tiers` is empty.");
8910 Field* fields = result->Fetch();
8916 }
while (result->NextRow());
8939 if (w_ownname != wname)
8947 AreaTriggerScriptContainer::const_iterator i = _areaTriggerScriptStore.find(trigger_id);
8948 if (i!= _areaTriggerScriptStore.end())
8960 EventScriptContainer::const_iterator i = _eventScriptStore.find(eventId);
8961 if (i != _eventScriptStore.end())
8972 uint32 classMask = 1 << (playerClass - 1);
8974 for (
uint8 i = 0; i < 4; ++i)
9013 _gameTeleStore.clear();
9016 QueryResult result =
WorldDatabase.Query(
"SELECT id, position_x, position_y, position_z, orientation, map, name FROM game_tele");
9020 TC_LOG_INFO(
"server.loading",
">> Loaded 0 GameTeleports. DB table `game_tele` is empty!");
9028 Field* fields = result->Fetch();
9043 TC_LOG_ERROR(
"sql.sql",
"Wrong position for id {} (name: {}) in `game_tele` table, ignoring.",
id, gt.
name);
9049 TC_LOG_ERROR(
"sql.sql",
"Wrong UTF8 name for id {} in `game_tele` table, ignoring.",
id);
9055 _gameTeleStore[id] = gt;
9059 while (result->NextRow());
9076 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9078 if (itr->second.wnameLow == wname)
9079 return &itr->second;
9080 else if (!alt && itr->second.
wnameLow.find(wname) != std::wstring::npos)
9097 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9099 if (itr->second.wnameLow == wname)
9100 return &itr->second;
9110 for (GameTeleContainer::const_iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9111 if (itr->first > new_id)
9112 new_id = itr->first;
9122 _gameTeleStore[new_id] = tele;
9149 for (GameTeleContainer::iterator itr = _gameTeleStore.begin(); itr != _gameTeleStore.end(); ++itr)
9151 if (itr->second.wnameLow == wname)
9159 _gameTeleStore.erase(itr);
9171 _mailLevelRewardStore.clear();
9174 QueryResult result =
WorldDatabase.Query(
"SELECT level, raceMask, mailTemplateId, senderEntry FROM mail_level_reward");
9178 TC_LOG_INFO(
"server.loading",
">> Loaded 0 level dependent mail rewards. DB table `mail_level_reward` is empty.");
9186 Field* fields = result->Fetch();
9195 TC_LOG_ERROR(
"sql.sql",
"Table `mail_level_reward` has data for level {} that more supported by client ({}), ignoring.", level,
MAX_LEVEL);
9201 TC_LOG_ERROR(
"sql.sql",
"Table `mail_level_reward` has raceMask ({}) for level {} that not include any player races, ignoring.", raceMask.
RawValue, level);
9207 TC_LOG_ERROR(
"sql.sql",
"Table `mail_level_reward` has invalid mailTemplateId ({}) for level {} that invalid not include any player races, ignoring.", mailTemplateId, level);
9211 if (!GetCreatureTemplate(senderEntry))
9213 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);
9217 _mailLevelRewardStore[level].emplace_back(raceMask, mailTemplateId, senderEntry);
9221 while (result->NextRow());
9233 std::unordered_map<int32, std::vector<Trainer::Spell>> spellsByTrainer;
9234 if (
QueryResult trainerSpellsResult =
WorldDatabase.Query(
"SELECT TrainerId, SpellId, MoneyCost, ReqSkillLine, ReqSkillRank, ReqAbility1, ReqAbility2, ReqAbility3, ReqLevel FROM trainer_spell"))
9238 Field* fields = trainerSpellsResult->Fetch();
9254 TC_LOG_ERROR(
"sql.sql",
"Table `trainer_spell` references non-existing spell (SpellId: {}) for TrainerId {}, ignoring", spell.
SpellId, trainerId);
9260 TC_LOG_ERROR(
"sql.sql",
"Table `trainer_spell` references non-existing skill (ReqSkillLine: {}) for TrainerId {} and SpellId {}, ignoring",
9265 bool allReqValid =
true;
9266 for (std::size_t i = 0; i < spell.
ReqAbility.size(); ++i)
9271 TC_LOG_ERROR(
"sql.sql",
"Table `trainer_spell` references non-existing spell (ReqAbility{}: {}) for TrainerId {} and SpellId {}, ignoring",
9272 i + 1, requiredSpell, trainerId, spell.
SpellId);
9273 allReqValid =
false;
9280 spellsByTrainer[trainerId].push_back(spell);
9282 }
while (trainerSpellsResult->NextRow());
9289 Field* fields = trainersResult->Fetch();
9293 std::vector<Trainer::Spell> spells;
9294 auto spellsItr = spellsByTrainer.find(trainerId);
9295 if (spellsItr != spellsByTrainer.end())
9297 spells = std::move(spellsItr->second);
9298 spellsByTrainer.erase(spellsItr);
9301 _trainers.emplace(std::piecewise_construct, std::forward_as_tuple(trainerId), std::forward_as_tuple(trainerId, trainerType, greeting, std::move(spells)));
9303 }
while (trainersResult->NextRow());
9306 for (
auto const& unusedSpells : spellsByTrainer)
9310 TC_LOG_ERROR(
"sql.sql",
"Table `trainer_spell` references non-existing trainer (TrainerId: {}) for SpellId {}, ignoring", unusedSpells.first, unusedSpell.
SpellId);
9314 if (
QueryResult trainerLocalesResult =
WorldDatabase.Query(
"SELECT Id, locale, Greeting_lang FROM trainer_locale"))
9318 Field* fields = trainerLocalesResult->Fetch();
9320 std::string localeName = fields[1].
GetString();
9327 trainer->AddGreetingLocale(locale, fields[2].GetString());
9329 TC_LOG_ERROR(
"sql.sql",
"Table `trainer_locale` references non-existing trainer (TrainerId: {}) for locale {}, ignoring",
9330 trainerId, localeName);
9332 }
while (trainerLocalesResult->NextRow());
9342 _creatureDefaultTrainers.clear();
9344 if (
QueryResult result =
WorldDatabase.Query(
"SELECT CreatureID, TrainerID, MenuID, OptionID FROM creature_trainer"))
9348 Field* fields = result->Fetch();
9354 if (!GetCreatureTemplate(creatureId))
9356 TC_LOG_ERROR(
"sql.sql",
"Table `creature_trainer` references non-existing creature template (CreatureID: {}), ignoring", creatureId);
9360 if (!GetTrainer(trainerId))
9362 TC_LOG_ERROR(
"sql.sql",
"Table `creature_trainer` references non-existing trainer (TrainerID: {}) for CreatureID {} MenuID {} OptionID {}, ignoring",
9363 trainerId, creatureId, gossipMenuId, gossipOptionId);
9367 if (gossipMenuId || gossipOptionId)
9370 auto gossipOptionItr = std::find_if(gossipMenuItems.
begin(), gossipMenuItems.
end(), [gossipOptionId](std::pair<uint32 const, GossipMenuItems>
const& entry)
9372 return entry.second.OrderIndex == gossipOptionId;
9374 if (gossipOptionItr == gossipMenuItems.
end())
9376 TC_LOG_ERROR(
"sql.sql",
"Table `creature_trainer` references non-existing gossip menu option (MenuID {} OptionID {}) for CreatureID {} and TrainerID {}, ignoring",
9377 gossipMenuId, gossipOptionId, creatureId, trainerId);
9382 _creatureDefaultTrainers[std::make_tuple(creatureId, gossipMenuId, gossipOptionId)] = trainerId;
9383 }
while (result->NextRow());
9402 Field* fields = result->Fetch();
9408 count += LoadReferenceVendor(vendor, -item_id, skip_vendors);
9412 vItem.
item = item_id;
9420 for (std::string_view token :
Trinity::Tokenize(fields[5].GetStringView(),
' ',
false))
9424 if (!IsVendorItemValid(vendor, vItem,
nullptr, skip_vendors))
9428 vList.
AddItem(std::move(vItem));
9431 }
while (result->NextRow());
9441 for (CacheVendorItemContainer::iterator itr = _cacheVendorItemStore.begin(); itr != _cacheVendorItemStore.end(); ++itr)
9442 itr->second.Clear();
9443 _cacheVendorItemStore.clear();
9445 std::set<uint32> skip_vendors;
9447 QueryResult result =
WorldDatabase.Query(
"SELECT entry, item, maxcount, incrtime, ExtendedCost, type, BonusListIDs, PlayerConditionID, IgnoreFiltering FROM npc_vendor ORDER BY entry, slot ASC");
9450 TC_LOG_ERROR(
"server.loading",
">> Loaded 0 Vendors. DB table `npc_vendor` is empty!");
9458 Field* fields = result->Fetch();
9465 count += LoadReferenceVendor(entry, -item_id, &skip_vendors);
9469 vItem.
item = item_id;
9477 for (std::string_view token :
Trinity::Tokenize(fields[6].GetStringView(),
' ',
false))
9481 if (!IsVendorItemValid(entry, vItem,
nullptr, &skip_vendors))
9485 vList.
AddItem(std::move(vItem));
9489 while (result->NextRow());
9498 _gossipMenusStore.clear();
9505 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gossip_menu IDs. DB table `gossip_menu` is empty!");
9511 Field* fields = result->Fetch();
9518 if (!GetNpcText(gMenu.
TextID))
9524 _gossipMenusStore.insert(GossipMenusContainer::value_type(gMenu.
MenuID, gMenu));
9525 }
while (result->NextRow());
9534 _gossipMenuItemsStore.clear();
9538 "SELECT MenuID, GossipOptionID, OptionID, OptionNpc, OptionText, OptionBroadcastTextID, Language, Flags, ActionMenuID, ActionPoiID, GossipNpcOptionID, "
9540 "BoxCoded, BoxMoney, BoxText, BoxBroadcastTextID, SpellID, OverrideIconID "
9541 "FROM gossip_menu_option ORDER BY MenuID, OptionID");
9545 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gossip_menu_option IDs. DB table `gossip_menu_option` is empty!");
9549 std::unordered_map<int32, int32> optionToNpcOption;
9551 optionToNpcOption[npcOption->GossipOptionID] = npcOption->ID;
9555 Field* fields = result->Fetch();
9569 if (!fields[10].IsNull())
9576 if (!fields[15].IsNull())
9579 if (!fields[16].IsNull())
9605 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);
9613 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);
9616 else if (!GetPointOfInterest(gMenuItem.
ActionPoiID))
9627 TC_LOG_ERROR(
"sql.sql",
"Table `gossip_menu_option` for menu {}, id {} use non-existing GossipNPCOption {}, ignoring",
9648 TC_LOG_ERROR(
"sql.sql",
"Table `gossip_menu_option` for menu {}, id {} use non-existing Spell {}, ignoring",
9654 _gossipMenuItemsStore.insert(GossipMenuItemsContainer::value_type(gMenuItem.
MenuID, gMenuItem));
9655 }
while (result->NextRow());
9657 TC_LOG_INFO(
"server.loading",
">> Loaded {} gossip_menu_option entries in {} ms", _gossipMenuItemsStore.size(),
GetMSTimeDiffToNow(oldMSTime));
9664 _gossipMenuAddonStore.clear();
9671 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gossip_menu_addon IDs. DB table `gossip_menu_addon` is empty!");
9677 Field* fields = result->Fetch();
9687 TC_LOG_ERROR(
"sql.sql",
"Table gossip_menu_addon: ID {} is using FriendshipFactionID {} referencing non-existing FriendshipRepID {}",
9698 }
while (result->NextRow());
9710 auto itr = _creatureDefaultTrainers.find(std::make_tuple(creatureId, gossipMenuId, gossipOptionId));
9711 if (itr != _creatureDefaultTrainers.end())
9739 CacheVendorItemContainer::iterator iter = _cacheVendorItemStore.find(entry);
9740 if (iter == _cacheVendorItemStore.end())
9743 if (!iter->second.RemoveItem(item, type))
9768 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` has data for nonexistent creature template (Entry: {}), ignore", vendor_entry);
9774 if (!skip_vendors || skip_vendors->count(vendor_entry) == 0)
9779 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` has data for creature template (Entry: {}) without vendor flag, ignore", vendor_entry);
9782 skip_vendors->insert(vendor_entry);
9793 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);
9799 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` has Item (Entry: {}) with invalid PlayerConditionId ({}) for vendor ({}), ignore", vItem.
item, vItem.
PlayerConditionId, vendor_entry);
9808 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);
9819 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);
9827 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);
9835 TC_LOG_ERROR(
"sql.sql",
"Table `(game_event_)npc_vendor` have Item (Entry: {}) with invalid bonus {} for vendor ({}), ignore", vItem.
item, bonusListId, vendor_entry);
9841 VendorItemData const* vItems = GetNpcVendorItemList(vendor_entry);
9850 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);
9856 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);
9867 [[maybe_unused]]
uint32 const id = insert(
"",
false);
9874 IndexToName.reserve(capacity);
9879 auto result = NameToIndex.try_emplace(scriptName,
static_cast<uint32>(NameToIndex.size()), isScriptNameBound);
9882 ASSERT(NameToIndex.size() <= std::numeric_limits<uint32>::max());
9883 IndexToName.emplace_back(result.first);
9886 return result.first->second.Id;
9891 return IndexToName.size();
9896 return index < IndexToName.size() ? IndexToName[index] :
end();
9905 return NameToIndex.find(name);
9910 return NameToIndex.end();
9915 std::unordered_set<std::string> scriptNames;
9917 for (std::pair<std::string const, Entry>
const& entry : NameToIndex)
9919 if (entry.second.IsScriptDatabaseBound)
9921 scriptNames.insert(entry.first);
9930 return _scriptNamesStore.GetAllDBScriptNames();
9935 auto const itr = _scriptNamesStore.find(
id);
9936 if (itr != _scriptNamesStore.end())
9942 static std::string
const empty;
9949 auto const itr = _scriptNamesStore.find(
id);
9950 if (itr != _scriptNamesStore.end())
9952 return itr->second.IsScriptDatabaseBound;
9962 return _scriptNamesStore.insert(name, isDatabaseBound);
9967 CreatureBaseStatsContainer::const_iterator it = _creatureBaseStatsStore.find(
MAKE_PAIR16(level, unitClass));
9969 if (it != _creatureBaseStatsStore.end())
9970 return &(it->second);
9974 DefaultCreatureBaseStats()
9978 RangedAttackPower = 0;
9981 static const DefaultCreatureBaseStats defStats;
9989 QueryResult result =
WorldDatabase.Query(
"SELECT level, class, basemana, attackpower, rangedattackpower FROM creature_classlevelstats");
9993 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature base stats. DB table `creature_classlevelstats` is empty.");
10000 Field* fields = result->Fetch();
10019 while (result->NextRow());
10025 uint8 unitClassMask = 1 << (unitClass - 1);
10026 if (!_creatureBaseStatsStore.count(
MAKE_PAIR16(unitLevel, unitClassMask)))
10027 TC_LOG_ERROR(
"sql.sql",
"Missing base stats for creature class {} level {}", unitClassMask, unitLevel);
10042 TC_LOG_INFO(
"server.loading",
">> Loaded 0 faction change achievement pairs. DB table `player_factionchange_achievement` is empty.");
10050 Field* fields = result->Fetch();
10056 TC_LOG_ERROR(
"sql.sql",
"Achievement {} (alliance_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", alliance);
10058 TC_LOG_ERROR(
"sql.sql",
"Achievement {} (horde_id) referenced in `player_factionchange_achievement` does not exist, pair skipped!", horde);
10060 FactionChangeAchievements[alliance] = horde;
10064 while (result->NextRow());
10074 for (std::pair<uint32 const, ItemTemplate>
const& itemPair : _itemTemplateStore)
10076 if (!itemPair.second.GetOtherFactionItemId())
10080 FactionChangeItemsHordeToAlliance[itemPair.first] = itemPair.second.GetOtherFactionItemId();
10083 FactionChangeItemsAllianceToHorde[itemPair.first] = itemPair.second.GetOtherFactionItemId();
10099 TC_LOG_INFO(
"server.loading",
">> Loaded 0 faction change quest pairs. DB table `player_factionchange_quests` is empty.");
10107 Field* fields = result->Fetch();
10112 if (!GetQuestTemplate(alliance))
10113 TC_LOG_ERROR(
"sql.sql",
"Quest {} (alliance_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", alliance);
10114 else if (!GetQuestTemplate(horde))
10115 TC_LOG_ERROR(
"sql.sql",
"Quest {} (horde_id) referenced in `player_factionchange_quests` does not exist, pair skipped!", horde);
10117 FactionChangeQuests[alliance] = horde;
10121 while (result->NextRow());
10134 TC_LOG_INFO(
"server.loading",
">> Loaded 0 faction change reputation pairs. DB table `player_factionchange_reputations` is empty.");
10142 Field* fields = result->Fetch();
10148 TC_LOG_ERROR(
"sql.sql",
"Reputation {} (alliance_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", alliance);
10150 TC_LOG_ERROR(
"sql.sql",
"Reputation {} (horde_id) referenced in `player_factionchange_reputations` does not exist, pair skipped!", horde);
10152 FactionChangeReputation[alliance] = horde;
10156 while (result->NextRow());
10169 TC_LOG_INFO(
"server.loading",
">> Loaded 0 faction change spell pairs. DB table `player_factionchange_spells` is empty.");
10177 Field* fields = result->Fetch();
10183 TC_LOG_ERROR(
"sql.sql",
"Spell {} (alliance_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", alliance);
10185 TC_LOG_ERROR(
"sql.sql",
"Spell {} (horde_id) referenced in `player_factionchange_spells` does not exist, pair skipped!", horde);
10187 FactionChangeSpells[alliance] = horde;
10191 while (result->NextRow());
10204 TC_LOG_INFO(
"server.loading",
">> Loaded 0 faction change title pairs. DB table `player_factionchange_title` is empty.");
10212 Field* fields = result->Fetch();
10218 TC_LOG_ERROR(
"sql.sql",
"Title {} (alliance_id) referenced in `player_factionchange_title` does not exist, pair skipped!", alliance);
10220 TC_LOG_ERROR(
"sql.sql",
"Title {} (horde_id) referenced in `player_factionchange_title` does not exist, pair skipped!", horde);
10222 FactionChangeTitles[alliance] = horde;
10226 while (result->NextRow());
10234 _phaseInfoById.emplace(std::make_pair(phase->ID,
PhaseInfoStruct{ phase->ID, std::unordered_set<uint32>{} }));
10237 if (map->ParentMapID != -1)
10238 _terrainSwapInfoById.emplace(std::make_pair(map->ID,
TerrainSwapInfo{ map->ID, std::vector<uint32>{} }));
10240 TC_LOG_INFO(
"server.loading",
"Loading Terrain World Map definitions...");
10241 LoadTerrainWorldMaps();
10243 TC_LOG_INFO(
"server.loading",
"Loading Terrain Swap Default definitions...");
10244 LoadTerrainSwapDefaults();
10246 TC_LOG_INFO(
"server.loading",
"Loading Phase Area definitions...");
10252 for (
auto itr = _phaseInfoByArea.begin(); itr != _phaseInfoByArea.end(); ++itr)
10266 TC_LOG_INFO(
"server.loading",
">> Loaded 0 terrain world maps. DB table `terrain_worldmap` is empty.");
10273 Field* fields = result->Fetch();
10280 TC_LOG_ERROR(
"sql.sql",
"TerrainSwapMap {} defined in `terrain_worldmap` does not exist, skipped.", mapId);
10286 TC_LOG_ERROR(
"sql.sql",
"Phase {} defined in `terrain_worldmap` is not a valid terrain swap phase, skipped.", uiMapPhaseId);
10291 terrainSwapInfo->
Id = mapId;
10295 }
while (result->NextRow());
10309 TC_LOG_INFO(
"server.loading",
">> Loaded 0 terrain swap defaults. DB table `terrain_swap_defaults` is empty.");
10316 Field* fields = result->Fetch();
10322 TC_LOG_ERROR(
"sql.sql",
"Map {} defined in `terrain_swap_defaults` does not exist, skipped.", mapId);
10328 if (!
sMapStore.LookupEntry(terrainSwap))
10330 TC_LOG_ERROR(
"sql.sql",
"TerrainSwapMap {} defined in `terrain_swap_defaults` does not exist, skipped.", terrainSwap);
10334 TerrainSwapInfo* terrainSwapInfo = &_terrainSwapInfoById[terrainSwap];
10335 terrainSwapInfo->
Id = terrainSwap;
10336 _terrainSwapInfoByMap[mapId].push_back(terrainSwapInfo);
10339 }
while (result->NextRow());
10353 TC_LOG_INFO(
"server.loading",
">> Loaded 0 phase areas. DB table `phase_area` is empty.");
10357 auto getOrCreatePhaseIfMissing = [
this](
uint32 phaseId)
10360 phaseInfo->
Id = phaseId;
10367 Field* fields = result->Fetch();
10372 TC_LOG_ERROR(
"sql.sql",
"Area {} defined in `phase_area` does not exist, skipped.", area);
10378 TC_LOG_ERROR(
"sql.sql",
"Phase {} defined in `phase_area` does not exist, skipped.", phaseId);
10383 phase->
Areas.insert(area);
10384 _phaseInfoByArea[area].emplace_back(phase);
10387 }
while (result->NextRow());
10389 for (
auto itr = _phaseInfoByArea.begin(); itr != _phaseInfoByArea.end(); ++itr)
10393 uint32 parentAreaId = itr->first;
10406 if (parentAreaPhase.PhaseInfo->Id == phase.
PhaseInfo->
Id)
10407 parentAreaPhase.SubAreaExclusions.insert(itr->first);
10418 return std::any_of(
Areas.begin(),
Areas.end(), [areaId](
uint32 areaToCheck)
10420 return DB2Manager::IsInArea(areaId, areaToCheck);
10446 auto itr = _gameObjectTemplateAddonStore.find(entry);
10447 if (itr != _gameObjectTemplateAddonStore.end())
10448 return &itr->second;
10478 VehicleAccessoryContainer::const_iterator itr = _vehicleAccessoryStore.find(cre->GetSpawnId());
10479 if (itr != _vehicleAccessoryStore.end())
10480 return &itr->second;
10484 VehicleAccessoryTemplateContainer::const_iterator itr = _vehicleTemplateAccessoryStore.find(veh->
GetCreatureEntry());
10485 if (itr != _vehicleTemplateAccessoryStore.end())
10486 return &itr->second;
10499 return info->get();
10505 _raceUnlockRequirementStore.clear();
10508 QueryResult result =
WorldDatabase.Query(
"SELECT raceID, expansion, achievementId FROM `race_unlock_requirement`");
10514 Field* fields = result->Fetch();
10523 TC_LOG_ERROR(
"sql.sql",
"Race {} defined in `race_unlock_requirement` does not exists, skipped.", raceID);
10529 TC_LOG_ERROR(
"sql.sql",
"Race {} defined in `race_unlock_requirement` has incorrect expansion {}, skipped.", raceID, expansion);
10535 TC_LOG_ERROR(
"sql.sql",
"Race {} defined in `race_unlock_requirement` has incorrect achievement {}, skipped.", raceID, achievementId);
10540 raceUnlockRequirement.
Expansion = expansion;
10543 while (result->NextRow());
10544 TC_LOG_INFO(
"server.loading",
">> Loaded {} race expansion requirements in {} ms.", _raceUnlockRequirementStore.size(),
GetMSTimeDiffToNow(oldMSTime));
10547 TC_LOG_INFO(
"server.loading",
">> Loaded 0 race expansion requirements. DB table `race_expansion_requirement` is empty.");
10550 _classExpansionRequirementStore.clear();
10553 result =
WorldDatabase.Query(
"SELECT ClassID, RaceID, ActiveExpansionLevel, AccountExpansionLevel FROM `class_expansion_requirement`");
10557 std::map<uint8, std::map<uint8, std::pair<uint8, uint8>>> temp;
10558 std::array<uint8, MAX_CLASSES> minRequirementForClass = { };
10563 Field* fields = result->Fetch();
10573 TC_LOG_ERROR(
"sql.sql",
"Class {} (race {}) defined in `class_expansion_requirement` does not exists, skipped.",
10581 TC_LOG_ERROR(
"sql.sql",
"Race {} (class {}) defined in `class_expansion_requirement` does not exists, skipped.",
10588 TC_LOG_ERROR(
"sql.sql",
"Class {} Race {} defined in `class_expansion_requirement` has incorrect ActiveExpansionLevel {}, skipped.",
10589 uint32(classID),
uint32(raceID), activeExpansionLevel);
10595 TC_LOG_ERROR(
"sql.sql",
"Class {} Race {} defined in `class_expansion_requirement` has incorrect AccountExpansionLevel {}, skipped.",
10596 uint32(classID),
uint32(raceID), accountExpansionLevel);
10600 temp[raceID][classID] = { activeExpansionLevel, accountExpansionLevel };
10601 minRequirementForClass[classID] = std::min(minRequirementForClass[classID], activeExpansionLevel);
10605 while (result->NextRow());
10607 for (
auto&& race : temp)
10611 raceClassAvailability.
RaceID = race.first;
10613 for (
auto&& class_ : race.second)
10617 classAvailability.
ClassID = class_.first;
10627 TC_LOG_INFO(
"server.loading",
">> Loaded 0 class expansion requirements. DB table `class_expansion_requirement` is empty.");
10632 auto raceItr = std::find_if(_classExpansionRequirementStore.begin(), _classExpansionRequirementStore.end(), [raceId](
RaceClassAvailability const& raceClass)
10634 return raceClass.RaceID == raceId;
10636 if (raceItr == _classExpansionRequirementStore.end())
10639 auto classItr = std::find_if(raceItr->Classes.begin(), raceItr->Classes.end(), [classId](
ClassAvailability const& classAvailability)
10641 return classAvailability.ClassID == classId;
10643 if (classItr == raceItr->Classes.end())
10646 return &(*classItr);
10652 for (
ClassAvailability const& classAvailability : raceClassAvailability.Classes)
10653 if (classAvailability.
ClassID == classId)
10654 return &classAvailability;
10674 QueryResult result =
WorldDatabase.Query(
"SELECT GameObjectEntry, ItemId, Idx FROM gameobject_questitem ORDER BY Idx ASC");
10678 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject quest items. DB table `gameobject_questitem` is empty.");
10685 Field* fields = result->Fetch();
10694 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject_questitem` has data for nonexistent gameobject (entry: {}, idx: {}), skipped", entry, idx);
10701 TC_LOG_ERROR(
"sql.sql",
"Table `gameobject_questitem` has nonexistent item (ID: {}) in gameobject (entry: {}, idx: {}), skipped", item, entry, idx);
10705 _gameObjectQuestItemStore[entry].push_back(item);
10709 while (result->NextRow());
10719 QueryResult result =
WorldDatabase.Query(
"SELECT CreatureEntry, DifficultyID, ItemId, Idx FROM creature_questitem ORDER BY Idx ASC");
10723 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature quest items. DB table `creature_questitem` is empty.");
10730 Field* fields = result->Fetch();
10740 TC_LOG_ERROR(
"sql.sql",
"Table `creature_questitem` has data for nonexistent creature (entry: {}, difficulty: {}, idx: {}), skipped", entry, difficulty, idx);
10747 TC_LOG_ERROR(
"sql.sql",
"Table `creature_questitem` has nonexistent item (ID: {}) in creature (entry: {}, difficulty: {}, idx: {}), skipped", item, entry, difficulty, idx);
10751 _creatureQuestItemStore[std::make_pair(entry, difficulty)].push_back(item);
10755 while (result->NextRow());
10765 QueryResult result =
WorldDatabase.Query(
"SELECT CreatureId, CurrencyId FROM creature_quest_currency ORDER BY CreatureId, CurrencyId ASC");
10769 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature quest currencies. DB table `creature_quest_currency` is empty.");
10776 Field* fields = result->Fetch();
10781 if (!GetCreatureTemplate(entry))
10783 TC_LOG_ERROR(
"sql.sql",
"Table `creature_quest_currency` has data for nonexistent creature (entry: {}, currency: {}), skipped", entry, currency);
10789 TC_LOG_ERROR(
"sql.sql",
"Table `creature_quest_currency` has nonexistent currency (ID: {}) in creature (entry: {}, currency: {}), skipped", currency, entry, currency);
10793 _creatureQuestCurrenciesStore[entry].push_back(currency);
10797 while (result->NextRow());
10809 TC_LOG_INFO(
"server.loading",
">> Query data caching is disabled. Skipped initialization.");
10817 for (
auto& creatureTemplatePair : _creatureTemplateStore)
10818 pool.
PostWork([creature = &creatureTemplatePair.second]() { creature->InitializeQueryData(); });
10822 for (
auto& gameObjectTemplatePair : _gameObjectTemplateStore)
10823 pool.
PostWork([gobj = &gameObjectTemplatePair.second]() { gobj->InitializeQueryData(); });
10827 for (
auto& questTemplatePair : _questTemplates)
10828 pool.
PostWork([quest = questTemplatePair.second.get()]() { quest->InitializeQueryData(); });
10832 for (
auto& poiWrapperPair : _questPOIStore)
10833 pool.
PostWork([poi = &poiWrapperPair.second]() { poi->InitializeQueryData(); });
10842 QueryDataBuffer << *
this;
10843 QueryDataBuffer.shrink_to_fit();
10849 _sceneTemplateStore.clear();
10851 QueryResult templates =
WorldDatabase.Query(
"SELECT SceneId, Flags, ScriptPackageID, Encrypted, ScriptName FROM scene_template");
10855 TC_LOG_INFO(
"server.loading",
">> Loaded 0 scene templates. DB table `scene_template` is empty.");
10863 Field* fields = templates->Fetch();
10866 SceneTemplate& sceneTemplate = _sceneTemplateStore[sceneId];
10867 sceneTemplate.
SceneId = sceneId;
10871 sceneTemplate.
ScriptId = GetScriptId(fields[4].GetCString());
10873 }
while (templates->NextRow());
10881 _playerChoices.clear();
10884 QueryResult choices =
WorldDatabase.Query(
"SELECT ChoiceId, UiTextureKitId, SoundKitId, CloseSoundKitId, Duration, Question, PendingChoiceText, HideWarboardHeader, KeepOpenAfterChoice FROM playerchoice");
10888 TC_LOG_INFO(
"server.loading",
">> Loaded 0 player choices. DB table `playerchoice` is empty.");
10892 uint32 responseCount = 0;
10894 uint32 itemRewardCount = 0;
10895 uint32 currencyRewardCount = 0;
10896 uint32 factionRewardCount = 0;
10897 uint32 itemChoiceRewardCount = 0;
10898 uint32 mawPowersCount = 0;
10902 Field* fields = choices->Fetch();
10917 }
while (choices->NextRow());
10920 if (
QueryResult responses =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, ResponseIdentifier, ChoiceArtFileId, Flags, WidgetSetID, "
10922 "UiTextureAtlasElementID, SoundKitID, GroupID, UiTextureKitID, Answer, Header, SubHeader, ButtonTooltip, Description, Confirmation, RewardQuestID "
10923 "FROM playerchoice_response ORDER BY `Index` ASC"))
10927 Field* fields = responses->Fetch();
10935 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
10957 if (!fields[16].IsNull())
10962 }
while (responses->NextRow());
10965 if (
QueryResult rewards =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, TitleId, PackageId, SkillLineId, SkillPointCount, ArenaPointCount, HonorPointCount, Money, Xp FROM playerchoice_response_reward"))
10969 Field* fields = rewards->Fetch();
10977 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
10982 [responseId](
PlayerChoiceResponse const& playerChoiceResponse) { return playerChoiceResponse.ResponseId == responseId; });
10983 if (responseItr == choice->
Responses.end())
10985 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11002 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward` references non-existing Title {} for ChoiceId {}, ResponseId: {}, set to 0",
11003 reward->
TitleId, choiceId, responseId);
11009 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward` references non-existing QuestPackage {} for ChoiceId {}, ResponseId: {}, set to 0",
11010 reward->
TitleId, choiceId, responseId);
11016 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward` references non-existing SkillLine {} for ChoiceId {}, ResponseId: {}, set to 0",
11017 reward->
TitleId, choiceId, responseId);
11022 }
while (rewards->NextRow());
11025 if (
QueryResult rewards =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, ItemId, BonusListIDs, Quantity FROM playerchoice_response_reward_item ORDER BY `Index` ASC"))
11029 Field* fields = rewards->Fetch();
11034 std::vector<int32> bonusListIds;
11035 for (std::string_view token :
Trinity::Tokenize(fields[3].GetStringView(),
' ',
false))
11037 bonusListIds.push_back(*bonusListID);
11043 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11048 [responseId](
PlayerChoiceResponse const& playerChoiceResponse) { return playerChoiceResponse.ResponseId == responseId; });
11049 if (responseItr == choice->
Responses.end())
11051 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11055 if (!responseItr->Reward)
11057 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item` references non-existing player choice reward for ChoiceId {}, ResponseId: {}, skipped",
11058 choiceId, responseId);
11062 if (!GetItemTemplate(itemId))
11064 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item` references non-existing item {} for ChoiceId {}, ResponseId: {}, skipped",
11065 itemId, choiceId, responseId);
11069 responseItr->Reward->Items.emplace_back(itemId, std::move(bonusListIds), quantity);
11072 }
while (rewards->NextRow());
11075 if (
QueryResult rewards =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, CurrencyId, Quantity FROM playerchoice_response_reward_currency ORDER BY `Index` ASC"))
11079 Field* fields = rewards->Fetch();
11089 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_currency` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11094 [responseId](
PlayerChoiceResponse const& playerChoiceResponse) { return playerChoiceResponse.ResponseId == responseId; });
11095 if (responseItr == choice->
Responses.end())
11097 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_currency` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11101 if (!responseItr->Reward)
11103 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_currency` references non-existing player choice reward for ChoiceId {}, ResponseId: {}, skipped",
11104 choiceId, responseId);
11110 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_currency` references non-existing currency {} for ChoiceId {}, ResponseId: {}, skipped",
11111 currencyId, choiceId, responseId);
11115 responseItr->Reward->Currency.emplace_back(currencyId, quantity);
11116 ++currencyRewardCount;
11118 }
while (rewards->NextRow());
11121 if (
QueryResult rewards =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, FactionId, Quantity FROM playerchoice_response_reward_faction ORDER BY `Index` ASC"))
11125 Field* fields = rewards->Fetch();
11135 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_faction` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11140 [responseId](
PlayerChoiceResponse const& playerChoiceResponse) { return playerChoiceResponse.ResponseId == responseId; });
11141 if (responseItr == choice->
Responses.end())
11143 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_faction` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11147 if (!responseItr->Reward)
11149 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_faction` references non-existing player choice reward for ChoiceId {}, ResponseId: {}, skipped",
11150 choiceId, responseId);
11156 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_faction` references non-existing faction {} for ChoiceId {}, ResponseId: {}, skipped",
11157 factionId, choiceId, responseId);
11161 responseItr->Reward->Faction.emplace_back(factionId, quantity);
11162 ++factionRewardCount;
11164 }
while (rewards->NextRow());
11167 if (
QueryResult rewards =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, ItemId, BonusListIDs, Quantity FROM playerchoice_response_reward_item_choice ORDER BY `Index` ASC"))
11171 Field* fields = rewards->Fetch();
11176 std::vector<int32> bonusListIds;
11177 for (std::string_view token :
Trinity::Tokenize(fields[3].GetStringView(),
' ',
false))
11179 bonusListIds.push_back(*bonusListID);
11185 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item_choice` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11190 [responseId](
PlayerChoiceResponse const& playerChoiceResponse) { return playerChoiceResponse.ResponseId == responseId; });
11191 if (responseItr == choice->
Responses.end())
11193 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item_choice` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11197 if (!responseItr->Reward)
11199 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item_choice` references non-existing player choice reward for ChoiceId {}, ResponseId: {}, skipped",
11200 choiceId, responseId);
11204 if (!GetItemTemplate(itemId))
11206 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_reward_item_choice` references non-existing item {} for ChoiceId {}, ResponseId: {}, skipped",
11207 itemId, choiceId, responseId);
11211 responseItr->Reward->ItemChoices.emplace_back(itemId, std::move(bonusListIds), quantity);
11212 ++itemChoiceRewardCount;
11214 }
while (rewards->NextRow());
11217 if (
QueryResult mawPowersResult =
WorldDatabase.Query(
"SELECT ChoiceId, ResponseId, TypeArtFileID, Rarity, RarityColor, SpellID, MaxStacks FROM playerchoice_response_maw_power"))
11221 Field* fields = mawPowersResult->Fetch();
11228 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_maw_power` references non-existing ChoiceId: {} (ResponseId: {}), skipped", choiceId, responseId);
11235 return playerChoiceResponse.ResponseId == responseId;
11237 if (responseItr == choice->
Responses.end())
11239 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_response_maw_power` references non-existing ResponseId: {} for ChoiceId {}, skipped", responseId, choiceId);
11245 if (!fields[3].IsNull())
11247 if (!fields[4].IsNull())
11254 }
while (mawPowersResult->NextRow());
11257 TC_LOG_INFO(
"server.loading",
">> Loaded {} player choices, {} responses, {} rewards, {} item rewards, {} currency rewards, {} faction rewards, {} item choice rewards and {} maw powers in {} ms.",
11258 _playerChoices.size(), responseCount, rewardCount, itemRewardCount, currencyRewardCount, factionRewardCount, itemChoiceRewardCount, mawPowersCount,
GetMSTimeDiffToNow(oldMSTime));
11266 _playerChoiceLocales.clear();
11273 Field* fields = result->Fetch();
11278 if (!GetPlayerChoice(choiceId))
11280 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_locale` references non-existing ChoiceId: {} for locale {}, skipped", choiceId, localeName);
11289 AddLocaleString(fields[2].GetStringView(), locale, data.
Question);
11290 }
while (result->NextRow());
11292 TC_LOG_INFO(
"server.loading",
">> Loaded {} Player Choice locale strings in {} ms", _playerChoiceLocales.size(),
GetMSTimeDiffToNow(oldMSTime));
11298 if (
QueryResult result =
WorldDatabase.Query(
"SELECT ChoiceID, ResponseID, locale, Answer, Header, SubHeader, ButtonTooltip, Description, Confirmation FROM playerchoice_response_locale"))
11300 std::size_t count = 0;
11303 Field* fields = result->Fetch();
11309 auto itr = _playerChoiceLocales.find(choiceId);
11310 if (itr == _playerChoiceLocales.end())
11312 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_locale` references non-existing ChoiceId: {} for ResponseId {} locale {}, skipped",
11313 choiceId, responseId, localeName);
11320 TC_LOG_ERROR(
"sql.sql",
"Table `playerchoice_locale` references non-existing ResponseId: {} for ChoiceId {} locale {}, skipped",
11321 responseId, choiceId, localeName);
11330 AddLocaleString(fields[3].GetStringView(), locale, data.
Answer);
11331 AddLocaleString(fields[4].GetStringView(), locale, data.
Header);
11332 AddLocaleString(fields[5].GetStringView(), locale, data.
SubHeader);
11333 AddLocaleString(fields[6].GetStringView(), locale, data.
ButtonTooltip);
11334 AddLocaleString(fields[7].GetStringView(), locale, data.
Description);
11335 AddLocaleString(fields[8].GetStringView(), locale, data.
Confirmation);
11337 }
while (result->NextRow());
11348 _jumpChargeParams.clear();
11351 QueryResult result =
WorldDatabase.Query(
"SELECT id, speed, treatSpeedAsMoveTimeSeconds, jumpGravity, spellVisualId, progressCurveId, parabolicCurveId FROM jump_charge_params");
11359 Field* fields = result->Fetch();
11362 float speed = fields[1].
GetFloat();
11363 bool treatSpeedAsMoveTimeSeconds = fields[2].
GetBool();
11364 float jumpGravity = fields[3].
GetFloat();
11371 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` uses invalid speed {} for id {}, set to default charge speed {}.",
11376 if (jumpGravity <= 0.0f)
11378 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` uses invalid jump gravity {} for id {}, set to default {}.",
11383 if (!fields[4].IsNull())
11386 spellVisualId = fields[4].
GetInt32();
11388 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` references non-existing SpellVisual: {} for id {}, ignored.",
11389 fields[4].GetInt32(),
id);
11392 if (!fields[5].IsNull())
11395 progressCurveId = fields[5].
GetInt32();
11397 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` references non-existing progress Curve: {} for id {}, ignored.",
11398 fields[4].GetInt32(),
id);
11401 if (!fields[6].IsNull())
11404 parabolicCurveId = fields[6].
GetInt32();
11406 TC_LOG_ERROR(
"sql.sql",
"Table `jump_charge_params` references non-existing parabolic Curve: {} for id {}, ignored.",
11407 fields[6].GetInt32(),
id);
11412 params.TreatSpeedAsMoveTimeSeconds = treatSpeedAsMoveTimeSeconds;
11413 params.JumpGravity = jumpGravity;
11414 params.SpellVisualId = spellVisualId;
11415 params.ProgressCurveId = progressCurveId;
11416 params.ParabolicCurveId = parabolicCurveId;
11418 }
while (result->NextRow());
11420 TC_LOG_INFO(
"server.loading",
">> Loaded {} Player Choice locale strings in {} ms", _jumpChargeParams.size(),
GetMSTimeDiffToNow(oldMSTime));
11426 _phaseNameStore.clear();
11433 TC_LOG_INFO(
"server.loading",
">> Loaded 0 phase names. DB table `phase_name` is empty.");
11440 Field* fields = result->Fetch();
11443 std::string name = fields[1].
GetString();
11445 _phaseNameStore[phaseId] = name;
11448 }
while (result->NextRow());
11454 PhaseNameContainer::const_iterator iter = _phaseNameStore.find(phaseId);
11455 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_GRAVEYARD
#define sCreatureAIRegistry
@ CREATURE_FLAG_EXTRA_DB_ALLOWED
@ CREATURE_FLAG_EXTRA_TRIGGER
@ CREATURE_FLAG_EXTRA_INSTANCE_BIND
@ CREATURE_STATIC_FLAG_CAN_SWIM
CreatureChaseMovementType
const uint8 MAX_KILL_CREDIT
@ CREATURE_STATIC_FLAG_5_INTERACT_WHILE_HOSTILE
CreatureRandomMovementType
@ CREATURE_STATIC_FLAG_3_ALLOW_INTERACTION_WHILE_IN_COMBAT
@ CREATURE_STATIC_FLAG_3_CANNOT_TURN
@ CREATURE_STATIC_FLAG_3_CANNOT_SWIM
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< 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< 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.
#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
#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__,...)
#define TC_LOG_ERROR(filterType__,...)
#define TC_LOG_INFO(filterType__,...)
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)
SkillRangeType GetSkillRangeType(SkillRaceClassInfoEntry const *rcEntry)
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
std::pair< SpellScriptsContainer::iterator, SpellScriptsContainer::iterator > SpellScriptsBounds
@ 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::unordered_map< uint32, CellObjectGuids > CellObjectGuidsMap
#define SPAWNGROUP_MAP_UNSET
std::pair< GossipMenusContainer::const_iterator, GossipMenusContainer::const_iterator > GossipMenusMapBounds
std::map< uint32, ScriptMap > ScriptMapMap
@ SUMMONER_TYPE_GAMEOBJECT
std::multimap< uint32, uint32 > QuestRelationsReverse
std::multimap< uint32, uint32 > QuestRelations
std::optional< T > Optional
Optional helper class to wrap optional values within.
#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_CRITERIA_TREE
@ QUEST_OBJECTIVE_OBTAIN_CURRENCY
@ QUEST_OBJECTIVE_PROGRESS_BAR
@ QUEST_OBJECTIVE_PLAYERKILLS
@ QUEST_OBJECTIVE_MAX_REPUTATION
@ QUEST_OBJECTIVE_AREA_TRIGGER_EXIT
@ QUEST_OBJECTIVE_AREATRIGGER
@ QUEST_OBJECTIVE_CURRENCY
@ QUEST_OBJECTIVE_LEARNSPELL
@ QUEST_OBJECTIVE_AREA_TRIGGER_ENTER
@ QUEST_OBJECTIVE_GAMEOBJECT
@ QUEST_OBJECTIVE_MIN_REPUTATION
#define QUEST_REWARD_CURRENCY_COUNT
@ QUEST_OBJECTIVE_FLAG_SEQUENCED
#define QUEST_REWARD_CHOICES_COUNT
@ QUEST_FLAGS_COMPLETION_AREA_TRIGGER
@ QUEST_FLAGS_COMPLETION_EVENT
@ QUEST_FLAGS_TRACKING_EVENT
@ QUEST_SPECIAL_FLAGS_SEQUENCED_OBJECTIVES
@ QUEST_SPECIAL_FLAGS_REPEATABLE
@ QUEST_SPECIAL_FLAGS_DB_ALLOWED
@ QUEST_SPECIAL_FLAGS_MONTHLY
constexpr Trinity::RaceMask< uint64 > RACEMASK_ALL_PLAYABLE
uint32 urand(uint32 min, uint32 max)
#define MAX_REPUTATION_RANK
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
@ 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_THE_BURNING_CRUSADE
@ EXPANSION_LEVEL_CURRENT
@ EXPANSION_MISTS_OF_PANDARIA
@ EXPANSION_WRATH_OF_THE_LICH_KING
@ 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_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
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)
wchar_t wcharToUpper(wchar_t wchar)
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
bool isExtendedLatinString(std::wstring_view wstr, bool numericOrSpace)
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
static void DeleteFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
static void DeleteFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
void PSendSysMessage(const char *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.
std::string GetString() const
std::string_view GetStringView() const
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)
NameMap::const_iterator find(size_t index) const
uint32 insert(std::string const &scriptName, bool isScriptNameBound=true)
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::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
AreaTriggerStruct const * GetAreaTrigger(uint32 trigger) const
void LoadPageTextLocales()
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()
TavernAreaTriggerContainer _tavernAreaTriggerStore
void LoadCreatureClassLevelStats()
PlayerInfo const * GetPlayerInfo(uint32 race, uint32 class_) const
void LoadCreatureTemplates()
GameObjectTemplateAddon const * GetGameObjectTemplateAddon(uint32 entry) 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)
static bool CheckDeclinedNames(const std::wstring &w_ownname, DeclinedName const &names)
void LoadQuestOfferRewardLocale()
void LoadFactionChangeAchievements()
static void AddLocaleString(std::string_view value, LocaleConstant localeConstant, std::vector< std::string > &data)
void LoadGameObjectOverrides()
SpellScriptsBounds GetSpellScriptsBounds(uint32 spellId)
void LoadGossipMenuAddon()
QuestRequestItemsLocaleContainer _questRequestItemsLocaleStore
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
void LoadQuestRequestItemsLocale()
EventScriptContainer _eventScriptStore
uint64 GenerateVoidStorageItemId()
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
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
QuestRelationsReverse _creatureQuestInvolvedRelationsReverse
ItemTemplateContainer _itemTemplateStore
void LoadQuestStartersAndEnders()
GameObjectOverride const * GetGameObjectOverride(ObjectGuid::LowType spawnId) const
static PetNameInvalidReason CheckPetName(std::string_view name)
GameObjectDataContainer _gameObjectDataStore
void LoadSpawnGroupTemplates()
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
PetLevelInfoContainer _petInfoStore
static CreatureModel const * ChooseDisplayId(CreatureTemplate const *cinfo, CreatureData const *data=nullptr)
VehicleAccessoryTemplateContainer _vehicleTemplateAccessoryStore
AreaTriggerStruct const * GetGoBackTrigger(uint32 Map) const
static ObjectMgr * instance()
void LoadVehicleTemplateAccessories()
void DeleteGameObjectData(ObjectGuid::LowType spawnId)
void LoadJumpChargeParams()
WorldSafeLocsEntry const * GetWorldSafeLoc(uint32 id) const
TerrainSwapInfo const * GetTerrainSwapInfo(uint32 terrainSwapId) const
HalfNameContainer _petHalfName0
void LoadGameObjectLocales()
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()
static ResponseCodes CheckPlayerName(std::string_view name, LocaleConstant locale, bool create=false)
uint32 GetCreatureTrainerForGossipOption(uint32 creatureId, uint32 gossipMenuId, uint32 gossipOptionId) const
std::map< HighGuid, std::unique_ptr< ObjectGuidGenerator > > _guidGenerators
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()
void LoadTavernAreaTriggers()
void LoadReputationRewardRate()
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()
AreaTriggerStruct const * GetMapEntranceTrigger(uint32 Map) const
void LoadFactionChangeTitles()
uint32 GetAreaTriggerScriptId(uint32 trigger_id) const
SpawnGroupLinkContainer _spawnGroupMapStore
std::string GetPhaseName(uint32 phaseId) const
RepSpilloverTemplateContainer _repSpilloverTemplateStore
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()
uint32 GetScriptId(std::string const &name, bool isDatabaseBound=true)
SpawnGroupTemplateData const * GetDefaultSpawnGroup() const
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()
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()
QuestPOIContainer _questPOIStore
void OnDeleteSpawnData(SpawnData const *data)
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
static Creature * ToCreature(Object *o)
static Player * ToPlayer(Object *o)
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 setFloat(const uint8 index, const float value)
void setUInt8(const uint8 index, const uint8 value)
void setInt64(const uint8 index, const int64 value)
void setUInt32(const uint8 index, const uint32 value)
void setUInt16(const uint8 index, const uint16 value)
void setString(const uint8 index, const std::string &value)
void setUInt64(const uint8 index, const uint64 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
Trinity::RaceMask< uint64 > _allowableRaces
static bool IsTakingQuestEnabled(uint32 questId)
void LoadConditionalConditionalRequestItemsText(Field *fields)
std::array< uint32, QUEST_REWARD_CHOICES_COUNT > RewardChoiceItemId
uint32 _rewardSkillPoints
void LoadQuestRequestItems(Field *fields)
uint32 _requiredMinRepFaction
std::array< uint32, QUEST_REWARD_ITEM_COUNT > RewardItemId
int32 _requiredMinRepValue
void LoadConditionalConditionalQuestDescription(Field *fields)
std::array< uint32, QUEST_REWARD_ITEM_COUNT > RewardItemCount
void LoadQuestMailSender(Field *fields)
void LoadQuestObjective(Field *fields)
int32 GetPrevQuestId() const
void LoadConditionalConditionalOfferRewardText(Field *fields)
int32 _requiredMaxRepValue
uint32 GetQuestType() const
uint32 _requiredMaxRepFaction
std::vector< uint32 > DependentPreviousQuests
uint32 GetQuestId() const
void LoadQuestOfferReward(Field *fields)
std::array< uint32, QUEST_ITEM_DROP_COUNT > ItemDropQuantity
int32 GetBreadcrumbForQuestId() const
void 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 LoadConditionalConditionalQuestCompletionLog(Field *fields)
bool HasFlag(QuestFlags flag) const
uint32 _rewardMailTemplateId
void LoadRewardChoiceItems(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
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 VMapManager2 * 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
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 &)
auto MapGetValuePtr(M &map, typename M::key_type const &key)
bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
TC_GAME_API char const * GetTrinityString(ChatHandler const *handler, TrinityStrings which)
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)
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)
std::string questFailedText
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< 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]
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::@213::@239 flagStand
struct GameObjectTemplate::@213::@278 raw
uint32 data[MAX_GAMEOBJECT_DATA]
struct GameObjectTemplate::@213::@227 areaDamage
struct GameObjectTemplate::@213::@241 flagDrop
struct GameObjectTemplate::@213::@218 chest
struct GameObjectTemplate::@213::@237 spellCaster
struct GameObjectTemplate::@213::@216 button
struct GameObjectTemplate::@213::@215 door
struct GameObjectTemplate::@213::@265 gatheringNode
bool IsDespawnAtAction() const
struct GameObjectTemplate::@213::@223 spellFocus
struct GameObjectTemplate::@213::@230 moTransport
struct GameObjectTemplate::@213::@247 barberChair
std::string castBarCaption
struct GameObjectTemplate::@213::@217 questgiver
struct GameObjectTemplate::@213::@225 goober
struct GameObjectTemplate::@213::@240 fishingHole
struct GameObjectTemplate::@213::@222 chair
struct GameObjectTemplate::@213::@253 garrisonBuilding
struct GameObjectTemplate::@213::@221 trap
ConditionsReference Conditions
std::array< int8, 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 IsBattlegroundOrArena() const
bool Instanceable() const
NpcTextData Data[MAX_NPC_TEXT_OPTIONS]
std::vector< std::string > Text
ConditionContainer Conditions
PhaseInfoStruct const * PhaseInfo
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
Optional< uint32 > RarityColor
uint16 ResponseIdentifier
std::string ButtonTooltip
uint32 UiTextureAtlasElementID
Optional< uint32 > RewardQuestID
std::vector< PlayerChoiceResponse > Responses
std::string PendingChoiceText
PlayerChoiceResponse const * GetResponse(int32 responseId) const
std::vector< std::string > Name
constexpr float GetPositionX() const
constexpr float GetPositionY() const
std::string ToString() const
constexpr void GetPosition(float &x, float &y) const
constexpr void Relocate(float x, float y)
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::@284::@296 TempSummonCreature
struct ScriptInfo::@284::@311 PlayAnimKit
struct ScriptInfo::@284::@295 RespawnGameobject
struct ScriptInfo::@284::@292 TeleportTo
struct ScriptInfo::@284::@297 ToggleDoor
struct ScriptInfo::@284::@286 Raw
struct ScriptInfo::@284::@301 CreateItem
struct ScriptInfo::@284::@288 Emote
struct ScriptInfo::@284::@294 KillCredit
struct ScriptInfo::@284::@299 CastSpell
std::string GetDebugInfo() const
struct ScriptInfo::@284::@287 Talk
struct ScriptInfo::@284::@293 QuestExplored
struct ScriptInfo::@284::@298 RemoveAura
uint32 GetValueForTierIndex(uint32 tierIndex) const
uint32 Value[MAX_SKILL_STEP]
std::vector< Difficulty > spawnDifficulties
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.
std::vector< uint32 > UiMapPhaseIDs
std::array< uint32, 3 > ReqAbility
std::vector< std::string > Content
constexpr bool HasRace(uint8 raceId) const
constexpr bool IsEmpty() const
Milliseconds DespawnDelay
VendorItem const * FindItemCostPair(uint32 item_id, uint32 extendedCost, uint8 type) const
void AddItem(VendorItem vItem)
std::vector< int32 > BonusListIDs