refactor(DB/Player): Unify two player stat tables. (#17188)

* Init.

Change query table names, move data to existing table.

* Combine two player stat loading functions.
This commit is contained in:
Benjamin Jackson
2023-09-14 20:35:26 -04:00
committed by GitHub
parent ef8f8bf712
commit 358a1e71e0
2 changed files with 45 additions and 87 deletions

View File

@@ -0,0 +1,9 @@
ALTER TABLE `player_class_stats`
ADD COLUMN `BaseHP` int unsigned NOT NULL DEFAULT '1' AFTER `Level`,
ADD COLUMN `BaseMana` int unsigned NOT NULL DEFAULT '1' AFTER `BaseHP`;
UPDATE player_class_stats AS noo
JOIN player_classlevelstats AS ole ON noo.Class = ole.class AND noo.Level = ole.level
SET noo.BaseHP = ole.basehp, noo.BaseMana = ole.basemana;
DROP TABLE IF EXISTS `player_classlevelstats`;

View File

@@ -4062,88 +4062,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 +4100,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 +4125,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 +4146,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 +4175,7 @@ void ObjectMgr::LoadPlayerInfo()
if (!sChrClassesStore.LookupEntry(class_))
continue;
PlayerClassInfo* pClassInfo = _playerClassInfo[class_];
PlayerInfo* info = _playerInfo[race][class_];
if (!info)
continue;
@@ -4256,14 +4188,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 +4211,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];
}
}
}
}