Merge branch 'master' of github.com:azerothcore/azerothcore-wotlk into Playerbot

This commit is contained in:
Yunfan Li
2023-09-23 22:44:15 +08:00
154 changed files with 7913 additions and 4858 deletions
+65 -120
View File
@@ -2863,47 +2863,43 @@ void ObjectMgr::LoadItemTemplates()
if (dbcitem)
{
if (itemTemplate.Class != dbcitem->ClassID)
if (enforceDBCAttributes)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Class value ({}), must be ({}).", entry, itemTemplate.Class, dbcitem->ClassID);
if (enforceDBCAttributes)
if (itemTemplate.Class != dbcitem->ClassID)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Class value ({}), must be ({}).", entry, itemTemplate.Class, dbcitem->ClassID);
itemTemplate.Class = dbcitem->ClassID;
}
if (itemTemplate.SubClass != dbcitem->SubclassID)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Subclass value ({}) for class {}, must be ({}).", entry, itemTemplate.SubClass, itemTemplate.Class, dbcitem->SubclassID);
if (enforceDBCAttributes)
}
if (itemTemplate.SubClass != dbcitem->SubclassID)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Subclass value ({}) for class {}, must be ({}).", entry, itemTemplate.SubClass, itemTemplate.Class, dbcitem->SubclassID);
itemTemplate.SubClass = dbcitem->SubclassID;
}
if (itemTemplate.SoundOverrideSubclass != dbcitem->SoundOverrideSubclassID)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct SoundOverrideSubclass ({}), must be {}.", entry, itemTemplate.SoundOverrideSubclass);
if (enforceDBCAttributes)
}
if (itemTemplate.SoundOverrideSubclass != dbcitem->SoundOverrideSubclassID)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct SoundOverrideSubclass ({}), must be {}.", entry, itemTemplate.SoundOverrideSubclass, dbcitem->SoundOverrideSubclassID);
itemTemplate.SoundOverrideSubclass = dbcitem->SoundOverrideSubclassID;
}
if (itemTemplate.Material != dbcitem->Material)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct material ({}), must be {}.", entry, itemTemplate.Material, dbcitem->Material);
if (enforceDBCAttributes)
}
if (itemTemplate.Material != dbcitem->Material)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct material ({}), must be {}.", entry, itemTemplate.Material, dbcitem->Material);
itemTemplate.Material = dbcitem->Material;
}
if (itemTemplate.InventoryType != dbcitem->InventoryType)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong InventoryType value ({}), must be {}.", entry, itemTemplate.InventoryType, dbcitem->InventoryType);
if (enforceDBCAttributes)
}
if (itemTemplate.InventoryType != dbcitem->InventoryType)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong InventoryType value ({}), must be {}.", entry, itemTemplate.InventoryType, dbcitem->InventoryType);
itemTemplate.InventoryType = dbcitem->InventoryType;
}
if (itemTemplate.DisplayInfoID != dbcitem->DisplayInfoID)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct display id ({}), must be {}.", entry, itemTemplate.DisplayInfoID, dbcitem->DisplayInfoID);
if (enforceDBCAttributes)
}
if (itemTemplate.DisplayInfoID != dbcitem->DisplayInfoID)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct display id ({}), must be {}.", entry, itemTemplate.DisplayInfoID, dbcitem->DisplayInfoID);
itemTemplate.DisplayInfoID = dbcitem->DisplayInfoID;
}
if (itemTemplate.Sheath != dbcitem->SheatheType)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Sheath ({}), must be {}.", entry, itemTemplate.Sheath, dbcitem->SheatheType);
if (enforceDBCAttributes)
}
if (itemTemplate.Sheath != dbcitem->SheatheType)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Sheath ({}), must be {}.", entry, itemTemplate.Sheath, dbcitem->SheatheType);
itemTemplate.Sheath = dbcitem->SheatheType;
}
}
}
else
@@ -4062,88 +4058,6 @@ void ObjectMgr::LoadPlayerInfo()
}
}
// Loading levels data (class only dependent)
LOG_INFO("server.loading", "Loading Player Create Level HP/Mana Data...");
{
uint32 oldMSTime = getMSTime();
// 0 1 2 3
QueryResult result = WorldDatabase.Query("SELECT class, level, basehp, basemana FROM player_classlevelstats");
if (!result)
{
LOG_FATAL("server.loading", ">> Loaded 0 level health/mana definitions. DB table `player_classlevelstats` is empty.");
exit(1);
}
uint32 count = 0;
do
{
Field* fields = result->Fetch();
uint32 current_class = fields[0].Get<uint8>();
if (current_class >= MAX_CLASSES)
{
LOG_ERROR("sql.sql", "Wrong class {} in `player_classlevelstats` table, ignoring.", current_class);
continue;
}
uint8 current_level = fields[1].Get<uint8>(); // Can't be > than STRONG_MAX_LEVEL (hardcoded level maximum) due to var type
if (current_level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
{
LOG_INFO("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_classlevelstats` table, ignoring.", current_level);
++count; // make result loading percent "expected" correct in case disabled detail mode for example.
continue;
}
PlayerClassInfo* info = _playerClassInfo[current_class];
if (!info)
{
info = new PlayerClassInfo();
info->levelInfo = new PlayerClassLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)];
_playerClassInfo[current_class] = info;
}
PlayerClassLevelInfo& levelInfo = info->levelInfo[current_level - 1];
levelInfo.basehealth = fields[2].Get<uint32>();
levelInfo.basemana = fields[3].Get<uint32>();
++count;
} while (result->NextRow());
// Fill gaps and check integrity
for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
{
// skip non existed classes
if (!sChrClassesStore.LookupEntry(class_))
continue;
PlayerClassInfo* pClassInfo = _playerClassInfo[class_];
// fatal error if no initial level data
if (!pClassInfo->levelInfo || (pClassInfo->levelInfo[sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL) - 1].basehealth == 0 && class_ != CLASS_DEATH_KNIGHT) || (pClassInfo->levelInfo[sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL) - 1].basehealth == 0 && class_ == CLASS_DEATH_KNIGHT))
{
LOG_ERROR("sql.sql", "Class {} initial level does not have health/mana data!", class_);
exit(1);
}
// fill level gaps
for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
{
if ((pClassInfo->levelInfo[level].basehealth == 0 && class_ != CLASS_DEATH_KNIGHT) || (level >= sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL) && pClassInfo->levelInfo[level].basehealth == 0 && class_ == CLASS_DEATH_KNIGHT))
{
LOG_ERROR("sql.sql", "Class {} level {} does not have health/mana data. Using stats data of level {}.", class_, level + 1, level);
pClassInfo->levelInfo[level] = pClassInfo->levelInfo[level - 1];
}
}
}
LOG_INFO("server.loading", ">> Loaded {} Level Health/Mana Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
LOG_INFO("server.loading", " ");
}
// Loading levels data (class/race dependent)
LOG_INFO("server.loading", "Loading Player Create Level Stats Data...");
{
@@ -4182,8 +4096,8 @@ void ObjectMgr::LoadPlayerInfo()
} while (raceStatsResult->NextRow());
// 0 1 2 3 4 5 6
QueryResult result = WorldDatabase.Query("SELECT Class, Level, Strength, Agility, Stamina, Intellect, Spirit FROM player_class_stats");
// 0 1 2 3 4 5 6 7 8
QueryResult result = WorldDatabase.Query("SELECT Class, Level, Strength, Agility, Stamina, Intellect, Spirit, BaseHP, BaseMana FROM player_class_stats");
if (!result)
{
@@ -4207,7 +4121,7 @@ void ObjectMgr::LoadPlayerInfo()
uint32 current_level = fields[1].Get<uint8>();
if (current_level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
{
if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
LOG_ERROR("sql.sql", "Wrong (> {}) level {} in `player_class_stats` table, ignoring.", STRONG_MAX_LEVEL, current_level);
else
LOG_DEBUG("sql.sql", "Unused (> MaxPlayerLevel in worldserver.conf) level {} in `player_class_stats` table, ignoring.", current_level);
@@ -4228,6 +4142,19 @@ void ObjectMgr::LoadPlayerInfo()
}
}
PlayerClassInfo* info = _playerClassInfo[current_class];
if (!info)
{
info = new PlayerClassInfo();
info->levelInfo = new PlayerClassLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)];
_playerClassInfo[current_class] = info;
}
PlayerClassLevelInfo& levelInfo = info->levelInfo[current_level - 1];
levelInfo.basehealth = fields[7].Get<uint32>();
levelInfo.basemana = fields[8].Get<uint32>();
++count;
} while (result->NextRow());
@@ -4244,6 +4171,7 @@ void ObjectMgr::LoadPlayerInfo()
if (!sChrClassesStore.LookupEntry(class_))
continue;
PlayerClassInfo* pClassInfo = _playerClassInfo[class_];
PlayerInfo* info = _playerInfo[race][class_];
if (!info)
continue;
@@ -4256,14 +4184,21 @@ void ObjectMgr::LoadPlayerInfo()
if (sWorld->getIntConfig(CONFIG_EXPANSION) < EXPANSION_WRATH_OF_THE_LICH_KING && class_ == CLASS_DEATH_KNIGHT)
continue;
// fatal error if no initial level data
// fatal error if no initial stats data
if (!info->levelInfo || (info->levelInfo[sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL) - 1].stats[0] == 0 && class_ != CLASS_DEATH_KNIGHT) || (info->levelInfo[sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL) - 1].stats[0] == 0 && class_ == CLASS_DEATH_KNIGHT))
{
LOG_ERROR("sql.sql", "Race {} class {} initial level does not have stats data!", race, class_);
exit(1);
}
// fill level gaps
// fatal error if no initial health/mana data
if (!pClassInfo->levelInfo || (pClassInfo->levelInfo[sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL) - 1].basehealth == 0 && class_ != CLASS_DEATH_KNIGHT) || (pClassInfo->levelInfo[sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL) - 1].basehealth == 0 && class_ == CLASS_DEATH_KNIGHT))
{
LOG_ERROR("sql.sql", "Class {} initial level does not have health/mana data!", class_);
exit(1);
}
// fill level gaps for stats
for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
{
if ((info->levelInfo[level].stats[0] == 0 && class_ != CLASS_DEATH_KNIGHT) || (level >= sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL) && info->levelInfo[level].stats[0] == 0 && class_ == CLASS_DEATH_KNIGHT))
@@ -4272,6 +4207,16 @@ void ObjectMgr::LoadPlayerInfo()
info->levelInfo[level] = info->levelInfo[level - 1];
}
}
// fill level gaps for health/mana
for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
{
if ((pClassInfo->levelInfo[level].basehealth == 0 && class_ != CLASS_DEATH_KNIGHT) || (level >= sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL) && pClassInfo->levelInfo[level].basehealth == 0 && class_ == CLASS_DEATH_KNIGHT))
{
LOG_ERROR("sql.sql", "Class {} level {} does not have health/mana data. Using stats data of level {}.", class_, level + 1, level);
pClassInfo->levelInfo[level] = pClassInfo->levelInfo[level - 1];
}
}
}
}