Core/DataStores: ported NpcTotalHp game tables from Cata Classic and use them to calculate npc health values
This commit is contained in:
1 parent
94f1ac8498
commit
77efec36ee
8 files changed
+685
-51
No files matched your search
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GAMETABLE_H
|
||||
#define __GAMETABLE_H
|
||||
|
||||
#include "Define.h"
|
||||
|
||||
enum UnitClass : uint8;
|
||||
|
||||
class GameTable
|
||||
{
|
||||
public:
|
||||
static float GetSpellScalingValue(uint8 level, UnitClass unitClass);
|
||||
};
|
||||
|
||||
#endif // __GAMETABLE_H
|
||||
+12
-2
@@ -15,11 +15,13 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GameTable.h"
|
||||
#include "GameTables.h"
|
||||
#include "DBCStores.h"
|
||||
#include "DBCStructure.h"
|
||||
|
||||
/*static*/ float GameTable::GetSpellScalingValue(uint8 level, UnitClass unitClass)
|
||||
GameTable<GtNpcTotalHpEntry> sNpcTotalHpGameTable[MAX_EXPANSIONS];
|
||||
|
||||
/*static*/ float GameTables::GetSpellScalingValue(uint8 level, UnitClass unitClass)
|
||||
{
|
||||
if (level > GT_MAX_LEVEL)
|
||||
return 0.0f;
|
||||
@@ -30,3 +32,11 @@
|
||||
|
||||
return gt->value;
|
||||
}
|
||||
|
||||
/*float*/ float GameTables::GetNpcTotalHpValue(uint8 level, UnitClass unitClass, Expansions expansion)
|
||||
{
|
||||
if (level > GT_MAX_LEVEL || expansion >= MAX_EXPANSIONS)
|
||||
return 0.0f;
|
||||
|
||||
return GetGameTableColumnForClass(sNpcTotalHpGameTable[expansion].GetRow(level), unitClass);
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GAMETABLES_H
|
||||
#define __GAMETABLES_H
|
||||
|
||||
#include "Define.h"
|
||||
|
||||
enum UnitClass : uint8;
|
||||
|
||||
struct GtNpcTotalHpEntry
|
||||
{
|
||||
float Warrior = 0.0f;
|
||||
float Paladin = 0.0f;
|
||||
float Hunter = 0.0f;
|
||||
float Rogue = 0.0f;
|
||||
float Priest = 0.0f;
|
||||
float DeathKnight = 0.0f;
|
||||
float Shaman = 0.0f;
|
||||
float Mage = 0.0f;
|
||||
float Warlock = 0.0f;
|
||||
float Monk = 0.0f;
|
||||
float Druid = 0.0f;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class GameTable
|
||||
{
|
||||
public:
|
||||
T const* GetRow(uint32 row) const
|
||||
{
|
||||
if (row >= _data.size())
|
||||
return nullptr;
|
||||
|
||||
return &_data[row];
|
||||
}
|
||||
|
||||
std::size_t GetTableRowCount() const { return _data.size(); }
|
||||
|
||||
void SetData(std::vector<T> data) { _data = std::move(data); }
|
||||
|
||||
private:
|
||||
std::vector<T> _data;
|
||||
};
|
||||
|
||||
class GameTables
|
||||
{
|
||||
public:
|
||||
// Helper Methods
|
||||
static float GetSpellScalingValue(uint8 level, UnitClass unitClass);
|
||||
static float GetNpcTotalHpValue(uint8 level, UnitClass unitClass, Expansions expansion);
|
||||
};
|
||||
|
||||
TC_GAME_API extern GameTable<GtNpcTotalHpEntry> sNpcTotalHpGameTable[MAX_EXPANSIONS];
|
||||
|
||||
template<class T>
|
||||
inline float GetGameTableColumnForClass(T const* row, int32 class_)
|
||||
{
|
||||
switch (class_)
|
||||
{
|
||||
case CLASS_WARRIOR:
|
||||
return row->Warrior;
|
||||
case CLASS_PALADIN:
|
||||
return row->Paladin;
|
||||
case CLASS_HUNTER:
|
||||
return row->Hunter;
|
||||
case CLASS_ROGUE:
|
||||
return row->Rogue;
|
||||
case CLASS_PRIEST:
|
||||
return row->Priest;
|
||||
case CLASS_DEATH_KNIGHT:
|
||||
return row->DeathKnight;
|
||||
case CLASS_SHAMAN:
|
||||
return row->Shaman;
|
||||
case CLASS_MAGE:
|
||||
return row->Mage;
|
||||
case CLASS_WARLOCK:
|
||||
return row->Warlock;
|
||||
//case CLASS_MONK:
|
||||
// return row->Monk;
|
||||
case CLASS_DRUID:
|
||||
return row->Druid;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
#endif // __GAMETABLES_H
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "DB2Structure.h"
|
||||
#include "DB2Stores.h"
|
||||
#include "DisableMgr.h"
|
||||
#include "GameTables.h"
|
||||
#include "GameTime.h"
|
||||
#include "GameObject.h"
|
||||
#include "GameObjectAIFactory.h"
|
||||
@@ -9554,8 +9555,8 @@ CreatureBaseStats const* ObjectMgr::GetCreatureBaseStats(uint8 level, uint8 unit
|
||||
void ObjectMgr::LoadCreatureClassLevelStats()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13
|
||||
QueryResult result = WorldDatabase.Query("SELECT level, class, basehp0, basehp1, basehp2, basehp3, basemana, basearmor, attackpower, rangedattackpower, damage_base, damage_exp1, damage_exp2, damage_exp3 FROM creature_classlevelstats");
|
||||
// 0 1 2 3 4 5 6 7 8 9
|
||||
QueryResult result = WorldDatabase.Query("SELECT level, class, basemana, basearmor, attackpower, rangedattackpower, damage_base, damage_exp1, damage_exp2, damage_exp3 FROM creature_classlevelstats");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
@@ -9578,15 +9579,9 @@ void ObjectMgr::LoadCreatureClassLevelStats()
|
||||
|
||||
for (uint8 i = 0; i < MAX_EXPANSIONS; ++i)
|
||||
{
|
||||
stats.BaseHealth[i] = fields[2 + i].GetUInt32();
|
||||
stats.BaseHealth[i] = GetGameTableColumnForClass(sNpcTotalHpGameTable[i].GetRow(Level), Class);
|
||||
|
||||
if (stats.BaseHealth[i] == 0)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Creature base stats for class %u, level %u has invalid zero base HP[%u] - set to 1", Class, Level, i);
|
||||
stats.BaseHealth[i] = 1;
|
||||
}
|
||||
|
||||
stats.BaseDamage[i] = fields[10 + i].GetFloat();
|
||||
stats.BaseDamage[i] = fields[6 + i].GetFloat();
|
||||
if (stats.BaseDamage[i] < 0.0f)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Creature base stats for class %u, level %u has invalid negative base damage[%u] - set to 0.0", Class, Level, i);
|
||||
@@ -9594,11 +9589,11 @@ void ObjectMgr::LoadCreatureClassLevelStats()
|
||||
}
|
||||
}
|
||||
|
||||
stats.BaseMana = fields[6].GetUInt16();
|
||||
stats.BaseArmor = fields[7].GetUInt16();
|
||||
stats.BaseMana = fields[2].GetUInt16();
|
||||
stats.BaseArmor = fields[3].GetUInt16();
|
||||
|
||||
stats.AttackPower = fields[8].GetUInt16();
|
||||
stats.RangedAttackPower = fields[9].GetUInt16();
|
||||
stats.AttackPower = fields[4].GetUInt16();
|
||||
stats.RangedAttackPower = fields[5].GetUInt16();
|
||||
|
||||
_creatureBaseStatsStore[MAKE_PAIR16(Level, Class)] = stats;
|
||||
|
||||
@@ -10098,6 +10093,81 @@ CreatureStaticFlagsOverride const* ObjectMgr::GetCreatureStaticFlagsOverride(Obj
|
||||
return Trinity::Containers::MapGetValuePtr(_creatureStaticFlagsOverrideStore, std::make_pair(spawnId, difficultyId));
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadDatabaseGameTables()
|
||||
{
|
||||
LoadNpcTotalHpGameTables();
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadNpcTotalHpGameTables()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
QueryResult result = WorldDatabase.Query("SELECT exp0.Level, exp0.Warrior, exp1.Warrior, exp2.Warrior, exp3.Warrior, "
|
||||
"exp0.Paladin, exp1.Paladin, exp2.Paladin, exp3.Paladin, "
|
||||
"exp0.Hunter, exp1.Hunter, exp2.Hunter, exp3.Hunter, "
|
||||
"exp0.Rogue, exp1.Rogue, exp2.Rogue, exp3.Rogue, "
|
||||
"exp0.Priest, exp1.Priest, exp2.Priest, exp3.Priest, "
|
||||
"exp0.DeathKnight, exp1.DeathKnight, exp2.DeathKnight, exp3.DeathKnight, "
|
||||
"exp0.Shaman, exp1.Shaman, exp2.Shaman, exp3.Shaman, "
|
||||
"exp0.Mage, exp1.Mage, exp2.Mage, exp3.Mage, "
|
||||
"exp0.Warlock, exp1.Warlock, exp2.Warlock, exp3.Warlock, "
|
||||
"exp0.Monk, exp1.Monk, exp2.Monk, exp3.Monk, "
|
||||
"exp0.Druid, exp1.Druid, exp2.Druid, exp3.Druid "
|
||||
"FROM gt_npc_total_hp AS exp0 "
|
||||
"INNER JOIN gt_npc_total_hp_exp1 AS exp1 ON exp0.Level = exp1.Level "
|
||||
"INNER JOIN gt_npc_total_hp_exp2 AS exp2 ON exp0.Level = exp2.Level "
|
||||
"INNER JOIN gt_npc_total_hp_exp3 AS exp3 ON exp0.Level = exp3.Level "
|
||||
"ORDER BY Level ASC");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_INFO("server.loading", ">> Loaded 0 npc total health game table entries. DB table `gt_npc_total_hp` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
// Initialize the storages with one extra entry for level 0
|
||||
std::vector<GtNpcTotalHpEntry> npcTotalHpExp0(result->GetRowCount() + 1);
|
||||
std::vector<GtNpcTotalHpEntry> npcTotalHpExp1(result->GetRowCount() + 1);
|
||||
std::vector<GtNpcTotalHpEntry> npcTotalHpExp2(result->GetRowCount() + 1);
|
||||
std::vector<GtNpcTotalHpEntry> npcTotalHpExp3(result->GetRowCount() + 1);
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
uint8 level = fields[0].GetUInt8();
|
||||
uint8 expansion = 0;
|
||||
for (std::vector<GtNpcTotalHpEntry>* storage : { &npcTotalHpExp0, &npcTotalHpExp1, &npcTotalHpExp2, &npcTotalHpExp3 })
|
||||
{
|
||||
std::vector<GtNpcTotalHpEntry>& npcTotalHp = *storage;
|
||||
|
||||
npcTotalHp[level].Warrior = fields[1 + expansion].GetFloat();
|
||||
npcTotalHp[level].Paladin = fields[5 + expansion].GetFloat();
|
||||
npcTotalHp[level].Hunter = fields[9 + expansion].GetFloat();
|
||||
npcTotalHp[level].Rogue = fields[13 + expansion].GetFloat();
|
||||
npcTotalHp[level].Priest = fields[17 + expansion].GetFloat();
|
||||
npcTotalHp[level].DeathKnight = fields[21 + expansion].GetFloat();
|
||||
npcTotalHp[level].Shaman = fields[25 + expansion].GetFloat();
|
||||
npcTotalHp[level].Mage = fields[29 + expansion].GetFloat();
|
||||
npcTotalHp[level].Warlock = fields[33 + expansion].GetFloat();
|
||||
npcTotalHp[level].Monk = fields[37 + expansion].GetFloat();
|
||||
npcTotalHp[level].Druid = fields[41 + expansion].GetFloat();
|
||||
|
||||
++expansion;
|
||||
}
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
sNpcTotalHpGameTable[EXPANSION_CLASSIC].SetData(npcTotalHpExp0);
|
||||
sNpcTotalHpGameTable[EXPANSION_THE_BURNING_CRUSADE].SetData(npcTotalHpExp1);
|
||||
sNpcTotalHpGameTable[EXPANSION_WRATH_OF_THE_LICH_KING].SetData(npcTotalHpExp2);
|
||||
sNpcTotalHpGameTable[EXPANSION_CATACLYSM].SetData(npcTotalHpExp3);
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u npc total health game table entries in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadGameObjectQuestItems()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
@@ -1611,6 +1611,9 @@ class TC_GAME_API ObjectMgr
|
||||
|
||||
CreatureStaticFlagsOverride const* GetCreatureStaticFlagsOverride(ObjectGuid::LowType spawnId, Difficulty difficultyId) const;
|
||||
|
||||
void LoadDatabaseGameTables();
|
||||
void LoadNpcTotalHpGameTables();
|
||||
|
||||
private:
|
||||
// first free id for selected id type
|
||||
uint32 _auctionId;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "Creature.h"
|
||||
#include "DBCStores.h"
|
||||
#include "GameClient.h"
|
||||
#include "GameTable.h"
|
||||
#include "GameTables.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Item.h"
|
||||
#include "ItemTemplate.h"
|
||||
@@ -518,7 +518,7 @@ int32 SpellEffectInfo::CalcBaseValue(WorldObject const* caster, Unit const* targ
|
||||
if (!_spellInfo->Scaling.Class)
|
||||
return 0;
|
||||
|
||||
value = GameTable::GetSpellScalingValue(level, static_cast<UnitClass>(_spellInfo->Scaling.Class > 0 ? _spellInfo->Scaling.Class: (MAX_CLASSES - 1 /*last class*/) - _spellInfo->Scaling.Class));
|
||||
value = GameTables::GetSpellScalingValue(level, static_cast<UnitClass>(_spellInfo->Scaling.Class > 0 ? _spellInfo->Scaling.Class: (MAX_CLASSES - 1 /*last class*/) - _spellInfo->Scaling.Class));
|
||||
value *= _spellInfo->GetSpellScalingMultiplier(level, false);
|
||||
}
|
||||
|
||||
@@ -550,7 +550,7 @@ double SpellEffectInfo::CalcPointsPerResource(WorldObject const* caster) const
|
||||
if (scalingClass < 0)
|
||||
scalingClass = (MAX_CLASSES - 1 /*last class*/) - scalingClass;
|
||||
|
||||
float scaledAmount = GameTable::GetSpellScalingValue(caster->ToUnit()->getLevel(), static_cast<UnitClass>(scalingClass));
|
||||
float scaledAmount = GameTables::GetSpellScalingValue(caster->ToUnit()->getLevel(), static_cast<UnitClass>(scalingClass));
|
||||
scaledAmount *= _spellInfo->GetSpellScalingMultiplier(caster->ToUnit()->getLevel(), false) * Scaling.ComboPointsCoefficient;
|
||||
value = scaledAmount;
|
||||
}
|
||||
|
||||
@@ -1901,7 +1901,10 @@ void World::SetInitialWorldSettings()
|
||||
TC_LOG_INFO("server.loading", "Loading Points Of Interest Data...");
|
||||
sObjectMgr->LoadPointsOfInterest();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading Creature Base Stats...");
|
||||
TC_LOG_INFO("server.loading", "Loading Database Game Tables...");
|
||||
sObjectMgr->LoadDatabaseGameTables();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading Creature Base Stats..."); // must be after LoadDatabaseGameTables
|
||||
sObjectMgr->LoadCreatureClassLevelStats();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading Spawn Group Templates...");
|
||||
|
||||
Reference in new issue
Block a user