Core/Creatures: Update creature scaling to use content tuning

Closes #22831
This commit is contained in:
funjoker
2020-05-02 22:37:28 +02:00
committed by Shauren
parent d7623adf0e
commit 314a35f0cd
10 changed files with 103 additions and 172 deletions
@@ -0,0 +1,7 @@
ALTER TABLE `creature_template_scaling`
ADD COLUMN `DifficultyID` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0' AFTER `Entry`,
ADD COLUMN `ContentTuningID` INT(10) NOT NULL DEFAULT '0' AFTER `LevelScalingDeltaMax`,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`Entry`, `DifficultyID`);
ALTER TABLE `creature_classlevelstats` DROP `basearmor`;
-20
View File
@@ -24,7 +24,6 @@
#include <fstream>
#include <sstream>
GameTable<GtArmorMitigationByLvlEntry> sArmorMitigationByLvlGameTable;
GameTable<GtArtifactKnowledgeMultiplierEntry> sArtifactKnowledgeMultiplierGameTable;
GameTable<GtArtifactLevelXPEntry> sArtifactLevelXPGameTable;
GameTable<GtBarberShopCostBaseEntry> sBarberShopCostBaseGameTable;
@@ -33,9 +32,7 @@ GameTable<GtCombatRatingsEntry> sCombatRatingsGameTable;
GameTable<GtCombatRatingsMultByILvl> sCombatRatingsMultByILvlGameTable;
GameTable<GtHpPerStaEntry> sHpPerStaGameTable;
GameTable<GtItemSocketCostPerLevelEntry> sItemSocketCostPerLevelGameTable;
GameTable<GtNpcDamageByClassEntry> sNpcDamageByClassGameTable[MAX_EXPANSIONS];
GameTable<GtNpcManaCostScalerEntry> sNpcManaCostScalerGameTable;
GameTable<GtNpcTotalHpEntry> sNpcTotalHpGameTable[MAX_EXPANSIONS];
GameTable<GtSpellScalingEntry> sSpellScalingGameTable;
GameTable<GtStaminaMultByILvl> sStaminaMultByILvlGameTable;
GameTable<GtXpEntry> sXpGameTable;
@@ -112,7 +109,6 @@ void LoadGameTables(std::string const& dataPath)
#define LOAD_GT(store, file) gameTableCount += LoadGameTable(bad_gt_files, store, gtPath / file); ++expectedGameTableCount;
LOAD_GT(sArmorMitigationByLvlGameTable, "ArmorMitigationByLvl.txt");
LOAD_GT(sArtifactKnowledgeMultiplierGameTable, "ArtifactKnowledgeMultiplier.txt");
LOAD_GT(sArtifactLevelXPGameTable, "ArtifactLevelXP.txt");
LOAD_GT(sBarberShopCostBaseGameTable, "BarberShopCostBase.txt");
@@ -121,23 +117,7 @@ void LoadGameTables(std::string const& dataPath)
LOAD_GT(sCombatRatingsMultByILvlGameTable, "CombatRatingsMultByILvl.txt");
LOAD_GT(sItemSocketCostPerLevelGameTable, "ItemSocketCostPerLevel.txt");
LOAD_GT(sHpPerStaGameTable, "HpPerSta.txt");
LOAD_GT(sNpcDamageByClassGameTable[0], "NpcDamageByClass.txt");
LOAD_GT(sNpcDamageByClassGameTable[1], "NpcDamageByClassExp1.txt");
LOAD_GT(sNpcDamageByClassGameTable[2], "NpcDamageByClassExp2.txt");
LOAD_GT(sNpcDamageByClassGameTable[3], "NpcDamageByClassExp3.txt");
LOAD_GT(sNpcDamageByClassGameTable[4], "NpcDamageByClassExp4.txt");
LOAD_GT(sNpcDamageByClassGameTable[5], "NpcDamageByClassExp5.txt");
LOAD_GT(sNpcDamageByClassGameTable[6], "NpcDamageByClassExp6.txt");
LOAD_GT(sNpcDamageByClassGameTable[7], "NpcDamageByClassExp7.txt");
LOAD_GT(sNpcManaCostScalerGameTable, "NPCManaCostScaler.txt");
LOAD_GT(sNpcTotalHpGameTable[0], "NpcTotalHp.txt");
LOAD_GT(sNpcTotalHpGameTable[1], "NpcTotalHpExp1.txt");
LOAD_GT(sNpcTotalHpGameTable[2], "NpcTotalHpExp2.txt");
LOAD_GT(sNpcTotalHpGameTable[3], "NpcTotalHpExp3.txt");
LOAD_GT(sNpcTotalHpGameTable[4], "NpcTotalHpExp4.txt");
LOAD_GT(sNpcTotalHpGameTable[5], "NpcTotalHpExp5.txt");
LOAD_GT(sNpcTotalHpGameTable[6], "NpcTotalHpExp6.txt");
LOAD_GT(sNpcTotalHpGameTable[7], "NpcTotalHpExp7.txt");
LOAD_GT(sSpellScalingGameTable, "SpellScaling.txt");
LOAD_GT(sStaminaMultByILvlGameTable, "StaminaMultByILvl.txt");
LOAD_GT(sXpGameTable, "xp.txt");
-40
View File
@@ -24,11 +24,6 @@
enum InventoryType : uint8;
struct GtArmorMitigationByLvlEntry
{
float Mitigation = 0.0f;
};
struct GtArtifactKnowledgeMultiplierEntry
{
float Multiplier = 0.0f;
@@ -115,43 +110,11 @@ struct GtItemSocketCostPerLevelEntry
float SocketCost = 0.0f;
};
struct GtNpcDamageByClassEntry
{
float Rogue = 0.0f;
float Druid = 0.0f;
float Hunter = 0.0f;
float Mage = 0.0f;
float Paladin = 0.0f;
float Priest = 0.0f;
float Shaman = 0.0f;
float Warlock = 0.0f;
float Warrior = 0.0f;
float DeathKnight = 0.0f;
float Monk = 0.0f;
float DemonHunter = 0.0f;
};
struct GtNpcManaCostScalerEntry
{
float Scaler = 0.0f;
};
struct GtNpcTotalHpEntry
{
float Rogue = 0.0f;
float Druid = 0.0f;
float Hunter = 0.0f;
float Mage = 0.0f;
float Paladin = 0.0f;
float Priest = 0.0f;
float Shaman = 0.0f;
float Warlock = 0.0f;
float Warrior = 0.0f;
float DeathKnight = 0.0f;
float Monk = 0.0f;
float DemonHunter = 0.0f;
};
struct GtSpellScalingEntry
{
float Rogue = 0.0f;
@@ -213,7 +176,6 @@ private:
std::vector<T> _data;
};
TC_GAME_API extern GameTable<GtArmorMitigationByLvlEntry> sArmorMitigationByLvlGameTable;
TC_GAME_API extern GameTable<GtArtifactKnowledgeMultiplierEntry> sArtifactKnowledgeMultiplierGameTable;
TC_GAME_API extern GameTable<GtArtifactLevelXPEntry> sArtifactLevelXPGameTable;
TC_GAME_API extern GameTable<GtBarberShopCostBaseEntry> sBarberShopCostBaseGameTable;
@@ -222,9 +184,7 @@ TC_GAME_API extern GameTable<GtCombatRatingsEntry> sCombatRatin
TC_GAME_API extern GameTable<GtCombatRatingsMultByILvl> sCombatRatingsMultByILvlGameTable;
TC_GAME_API extern GameTable<GtHpPerStaEntry> sHpPerStaGameTable;
TC_GAME_API extern GameTable<GtItemSocketCostPerLevelEntry> sItemSocketCostPerLevelGameTable;
TC_GAME_API extern GameTable<GtNpcDamageByClassEntry> sNpcDamageByClassGameTable[MAX_EXPANSIONS];
TC_GAME_API extern GameTable<GtNpcManaCostScalerEntry> sNpcManaCostScalerGameTable;
TC_GAME_API extern GameTable<GtNpcTotalHpEntry> sNpcTotalHpGameTable[MAX_EXPANSIONS];
TC_GAME_API extern GameTable<GtSpellScalingEntry> sSpellScalingGameTable;
TC_GAME_API extern GameTable<GtStaminaMultByILvl> sStaminaMultByILvlGameTable;
TC_GAME_API extern GameTable<GtXpEntry> sXpGameTable;
+47 -20
View File
@@ -24,6 +24,7 @@
#include "CreatureAISelector.h"
#include "CreatureGroups.h"
#include "DatabaseEnv.h"
#include "DB2Stores.h"
#include "Formulas.h"
#include "GameEventMgr.h"
#include "GameTime.h"
@@ -215,6 +216,27 @@ WorldPacket CreatureTemplate::BuildQueryData(LocaleConstant loc) const
return *queryTemp.Write();
}
CreatureLevelScaling const* CreatureTemplate::GetLevelScaling(Difficulty difficulty) const
{
auto it = scalingStore.find(difficulty);
if (it != scalingStore.end())
return &it->second;
struct DefaultCreatureLevelScaling : public CreatureLevelScaling
{
DefaultCreatureLevelScaling()
{
MinLevel = 0;
MaxLevel = 0;
DeltaLevelMin = 0;
DeltaLevelMax = 0;
ContentTuningID = 0;
}
};
static const DefaultCreatureLevelScaling defScaling;
return &defScaling;
}
bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{
if (Unit* victim = ObjectAccessor::GetUnit(m_owner, m_victim))
@@ -1372,17 +1394,17 @@ void Creature::SelectLevel()
uint8 level = minlevel == maxlevel ? minlevel : urand(minlevel, maxlevel);
SetLevel(level);
if (HasScalableLevels())
{
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ScalingLevelMin), cInfo->levelScaling->MinLevel);
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ScalingLevelMax), cInfo->levelScaling->MaxLevel);
CreatureLevelScaling const* scaling = cInfo->GetLevelScaling(GetMap()->GetDifficultyID());
int8 mindelta = std::min(cInfo->levelScaling->DeltaLevelMax, cInfo->levelScaling->DeltaLevelMin);
int8 maxdelta = std::max(cInfo->levelScaling->DeltaLevelMax, cInfo->levelScaling->DeltaLevelMin);
int8 delta = mindelta == maxdelta ? mindelta : irand(mindelta, maxdelta);
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ScalingLevelMin), scaling->MinLevel);
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ScalingLevelMax), scaling->MaxLevel);
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ScalingLevelDelta), delta);
}
int32 mindelta = std::min(scaling->DeltaLevelMax, scaling->DeltaLevelMin);
int32 maxdelta = std::max(scaling->DeltaLevelMax, scaling->DeltaLevelMin);
int32 delta = mindelta == maxdelta ? mindelta : irand(mindelta, maxdelta);
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ScalingLevelDelta), delta);
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ContentTuningID), scaling->ContentTuningID);
UpdateLevelDependantStats();
}
@@ -1391,12 +1413,13 @@ void Creature::UpdateLevelDependantStats()
{
CreatureTemplate const* cInfo = GetCreatureTemplate();
uint32 rank = IsPet() ? 0 : cInfo->rank;
CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(getLevel(), cInfo->unit_class);
uint8 level = getLevel();
CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(level, cInfo->unit_class);
// health
float healthmod = _GetHealthMod(rank);
uint32 basehp = stats->GenerateHealth(cInfo);
uint32 basehp = GetMaxHealthByLevel(level);
uint32 health = uint32(basehp * healthmod);
SetCreateHealth(health);
@@ -1422,7 +1445,7 @@ void Creature::UpdateLevelDependantStats()
SetStatFlatModifier(UNIT_MOD_HEALTH, BASE_VALUE, (float)health);
// damage
float basedamage = stats->GenerateBaseDamage(cInfo);
float basedamage = GetBaseDamageForLevel(level);
float weaponBaseMinDamage = basedamage;
float weaponBaseMaxDamage = basedamage * 1.5f;
@@ -1439,7 +1462,7 @@ void Creature::UpdateLevelDependantStats()
SetStatFlatModifier(UNIT_MOD_ATTACK_POWER, BASE_VALUE, stats->AttackPower);
SetStatFlatModifier(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, stats->RangedAttackPower);
float armor = (float)stats->GenerateArmor(cInfo); /// @todo Why is this treated as uint32 when it's a float?
float armor = GetBaseArmorForLevel(level); /// @todo Why is this treated as uint32 when it's a float?
SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, armor);
}
@@ -2670,14 +2693,17 @@ void Creature::AllLootRemovedFromCorpse()
bool Creature::HasScalableLevels() const
{
CreatureTemplate const* cinfo = GetCreatureTemplate();
return cinfo->levelScaling.is_initialized();
CreatureLevelScaling const* scaling = cinfo->GetLevelScaling(GetMap()->GetDifficultyID());
return (scaling->MinLevel != 0 && scaling->MaxLevel != 0);
}
uint64 Creature::GetMaxHealthByLevel(uint8 level) const
{
CreatureTemplate const* cInfo = GetCreatureTemplate();
CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(level, cInfo->unit_class);
return stats->GenerateHealth(cInfo);
CreatureLevelScaling const* scaling = cInfo->GetLevelScaling(GetMap()->GetDifficultyID());
float baseHealth = sDB2Manager.EvaluateExpectedStat(ExpectedStatType::CreatureHealth, level, cInfo->HealthScalingExpansion, scaling->ContentTuningID, Classes(cInfo->unit_class));
return baseHealth * cInfo->ModHealth * cInfo->ModHealthExtra;
}
float Creature::GetHealthMultiplierForTarget(WorldObject const* target) const
@@ -2695,8 +2721,8 @@ float Creature::GetHealthMultiplierForTarget(WorldObject const* target) const
float Creature::GetBaseDamageForLevel(uint8 level) const
{
CreatureTemplate const* cInfo = GetCreatureTemplate();
CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(level, cInfo->unit_class);
return stats->GenerateBaseDamage(cInfo);
CreatureLevelScaling const* scaling = cInfo->GetLevelScaling(GetMap()->GetDifficultyID());
return sDB2Manager.EvaluateExpectedStat(ExpectedStatType::CreatureAutoAttackDps, level, cInfo->HealthScalingExpansion, scaling->ContentTuningID, Classes(cInfo->unit_class));
}
float Creature::GetDamageMultiplierForTarget(WorldObject const* target) const
@@ -2712,8 +2738,9 @@ float Creature::GetDamageMultiplierForTarget(WorldObject const* target) const
float Creature::GetBaseArmorForLevel(uint8 level) const
{
CreatureTemplate const* cInfo = GetCreatureTemplate();
CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(level, cInfo->unit_class);
return stats->GenerateArmor(cInfo);
CreatureLevelScaling const* scaling = cInfo->GetLevelScaling(GetMap()->GetDifficultyID());
float baseArmor = sDB2Manager.EvaluateExpectedStat(ExpectedStatType::CreatureArmor, level, cInfo->HealthScalingExpansion, scaling->ContentTuningID, Classes(cInfo->unit_class));
return baseArmor * cInfo->ModArmor;
}
float Creature::GetArmorMultiplierForTarget(WorldObject const* target) const
@@ -288,7 +288,7 @@ enum CreatureFlagsExtra : uint32
CREATURE_FLAG_EXTRA_DUNGEON_BOSS = 0x10000000, // creature is a dungeon boss (SET DYNAMICALLY, DO NOT ADD IN DB)
CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING = 0x20000000, // creature ignore pathfinding
CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK = 0x40000000, // creature is immune to knockback effects
CREATURE_FLAG_EXTRA_UNUSED_31 = 0x80000000,
CREATURE_FLAG_EXTRA_UNUSED_31 = 0x80000000,
// Masks
CREATURE_FLAG_EXTRA_UNUSED = (CREATURE_FLAG_EXTRA_UNUSED_11 | CREATURE_FLAG_EXTRA_UNUSED_12 | CREATURE_FLAG_EXTRA_UNUSED_13 |
@@ -309,14 +309,6 @@ const uint32 MAX_CREATURE_NAMES = 4;
const uint32 MAX_CREATURE_SPELLS = 8;
const uint32 MAX_CREATURE_DIFFICULTIES = 3;
struct CreatureLevelScaling
{
uint16 MinLevel;
uint16 MaxLevel;
int16 DeltaLevelMin;
int16 DeltaLevelMax;
};
struct CreatureModel
{
static CreatureModel const DefaultInvisibleModel;
@@ -333,6 +325,15 @@ struct CreatureModel
float Probability;
};
struct CreatureLevelScaling
{
uint16 MinLevel;
uint16 MaxLevel;
int16 DeltaLevelMin;
int16 DeltaLevelMax;
int32 ContentTuningID;
};
// from `creature_template` table
struct TC_GAME_API CreatureTemplate
{
@@ -348,7 +349,7 @@ struct TC_GAME_API CreatureTemplate
uint32 GossipMenuId;
int16 minlevel;
int16 maxlevel;
Optional<CreatureLevelScaling> levelScaling;
std::unordered_map<Difficulty, CreatureLevelScaling> scalingStore;
int32 HealthScalingExpansion;
uint32 RequiredExpansion;
uint32 VignetteID; /// @todo Read Vignette.db2
@@ -408,6 +409,7 @@ struct TC_GAME_API CreatureTemplate
CreatureModel const* GetModelWithDisplayId(uint32 displayId) const;
CreatureModel const* GetFirstInvisibleModel() const;
CreatureModel const* GetFirstVisibleModel() const;
CreatureLevelScaling const* GetLevelScaling(Difficulty difficulty) const;
// helpers
SkillType GetRequiredLootSkill() const
@@ -477,20 +479,11 @@ struct TC_GAME_API CreatureTemplate
// Defines base stats for creatures (used to calculate HP/mana/armor/attackpower/rangedattackpower/all damage).
struct TC_GAME_API CreatureBaseStats
{
uint32 BaseHealth[MAX_EXPANSIONS];
uint32 BaseMana;
uint32 BaseArmor;
uint32 AttackPower;
uint32 RangedAttackPower;
float BaseDamage[MAX_EXPANSIONS];
// Helpers
uint32 GenerateHealth(CreatureTemplate const* info) const
{
return uint32(ceil(BaseHealth[info->HealthScalingExpansion] * info->ModHealth * info->ModHealthExtra));
}
uint32 GenerateMana(CreatureTemplate const* info) const
{
// Mana can be 0.
@@ -500,16 +493,6 @@ struct TC_GAME_API CreatureBaseStats
return uint32(ceil(BaseMana * info->ModMana * info->ModManaExtra));
}
uint32 GenerateArmor(CreatureTemplate const* info) const
{
return uint32(ceil(BaseArmor * info->ModArmor));
}
float GenerateBaseDamage(CreatureTemplate const* info) const
{
return BaseDamage[info->HealthScalingExpansion];
}
static CreatureBaseStats const* GetBaseStats(uint8 level, uint8 unitClass);
};
+3 -1
View File
@@ -840,7 +840,9 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
{
// remove elite bonuses included in DB values
CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(petlevel, cinfo->unit_class);
SetCreateHealth(stats->BaseHealth[cinfo->HealthScalingExpansion]);
CreatureLevelScaling const* scaling = cinfo->GetLevelScaling(GetMap()->GetDifficultyID());
SetCreateHealth(sDB2Manager.EvaluateExpectedStat(ExpectedStatType::CreatureHealth, petlevel, cinfo->HealthScalingExpansion, scaling->ContentTuningID, Classes(cinfo->unit_class)) * cinfo->ModHealth * cinfo->ModHealthExtra);
SetCreateMana(stats->BaseMana);
SetCreateStat(STAT_STRENGTH, 22);
+4 -5
View File
@@ -1640,14 +1640,13 @@ uint32 Unit::CalcArmorReducedDamage(Unit* attacker, Unit* victim, const uint32 d
return damage;
uint8 attackerLevel = attacker->GetLevelForTarget(victim);
if (attackerLevel > sArmorMitigationByLvlGameTable.GetTableRowCount())
attackerLevel = sArmorMitigationByLvlGameTable.GetTableRowCount();
// Expansion and ContentTuningID necessary? Does Player get a ContentTuningID too ?
float armorConstant = sDB2Manager.EvaluateExpectedStat(ExpectedStatType::ArmorConstant, attackerLevel, -2, 0, Classes(attacker->getClass()));
GtArmorMitigationByLvlEntry const* ambl = sArmorMitigationByLvlGameTable.GetRow(attackerLevel);
if (!ambl)
if (!armorConstant)
return damage;
float mitigation = std::min(armor / (armor + ambl->Mitigation), 0.85f);
float mitigation = std::min(armor / (armor + armorConstant), 0.85f);
return std::max<uint32>(damage * (1.0f - mitigation), 1);
}
+18 -31
View File
@@ -704,8 +704,8 @@ void ObjectMgr::LoadCreatureScalingData()
{
uint32 oldMSTime = getMSTime();
// 0 1 2 3 4
QueryResult result = WorldDatabase.Query("SELECT Entry, LevelScalingMin, LevelScalingMax, LevelScalingDeltaMin, LevelScalingDeltaMax FROM creature_template_scaling");
// 0 1 2 3 4 5 6
QueryResult result = WorldDatabase.Query("SELECT Entry, DifficultyID, LevelScalingMin, LevelScalingMax, LevelScalingDeltaMin, LevelScalingDeltaMax, ContentTuningID FROM creature_template_scaling ORDER BY Entry");
if (!result)
{
@@ -719,8 +719,9 @@ void ObjectMgr::LoadCreatureScalingData()
Field* fields = result->Fetch();
uint32 entry = fields[0].GetUInt32();
Difficulty difficulty = Difficulty(fields[1].GetUInt8());
CreatureTemplateContainer::iterator itr = _creatureTemplateStore.find(entry);
auto itr = _creatureTemplateStore.find(entry);
if (itr == _creatureTemplateStore.end())
{
TC_LOG_ERROR("sql.sql", "Creature template (Entry: %u) does not exist but has a record in `creature_template_scaling`", entry);
@@ -728,11 +729,13 @@ void ObjectMgr::LoadCreatureScalingData()
}
CreatureLevelScaling creatureLevelScaling;
creatureLevelScaling.MinLevel = fields[1].GetUInt16();
creatureLevelScaling.MaxLevel = fields[2].GetUInt16();
creatureLevelScaling.DeltaLevelMin = fields[3].GetInt16();
creatureLevelScaling.DeltaLevelMax = fields[4].GetInt16();
itr->second.levelScaling = creatureLevelScaling;
creatureLevelScaling.MinLevel = fields[2].GetUInt16();
creatureLevelScaling.MaxLevel = fields[3].GetUInt16();
creatureLevelScaling.DeltaLevelMin = fields[4].GetInt16();
creatureLevelScaling.DeltaLevelMax = fields[5].GetInt16();
creatureLevelScaling.ContentTuningID = fields[6].GetInt32();
itr->second.scalingStore[difficulty] = creatureLevelScaling;
++count;
} while (result->NextRow());
@@ -2232,6 +2235,8 @@ ObjectGuid::LowType ObjectMgr::AddCreatureData(uint32 entry, uint32 mapId, float
if (!map)
return UI64LIT(0);
CreatureLevelScaling const* scaling = cInfo->GetLevelScaling(map->GetDifficultyID());
ObjectGuid::LowType guid = GenerateCreatureSpawnId();
CreatureData& data = NewOrExistCreatureData(guid);
data.id = entry;
@@ -2245,7 +2250,7 @@ ObjectGuid::LowType ObjectMgr::AddCreatureData(uint32 entry, uint32 mapId, float
data.spawntimesecs = spawntimedelay;
data.spawndist = 0;
data.currentwaypoint = 0;
data.curhealth = stats->GenerateHealth(cInfo);
data.curhealth = sDB2Manager.EvaluateExpectedStat(ExpectedStatType::CreatureHealth, level, cInfo->HealthScalingExpansion, scaling->ContentTuningID, Classes(cInfo->unit_class)) * cInfo->ModHealth * cInfo->ModHealthExtra;
data.curmana = stats->GenerateMana(cInfo);
data.movementType = cInfo->MovementType;
data.spawnDifficulties.push_back(DIFFICULTY_NONE);
@@ -9222,12 +9227,6 @@ CreatureBaseStats const* ObjectMgr::GetCreatureBaseStats(uint8 level, uint8 unit
{
DefaultCreatureBaseStats()
{
BaseArmor = 1;
for (uint8 j = 0; j < MAX_EXPANSIONS; ++j)
{
BaseHealth[j] = 1;
BaseDamage[j] = 0.0f;
}
BaseMana = 0;
AttackPower = 0;
RangedAttackPower = 0;
@@ -9240,8 +9239,8 @@ CreatureBaseStats const* ObjectMgr::GetCreatureBaseStats(uint8 level, uint8 unit
void ObjectMgr::LoadCreatureClassLevelStats()
{
uint32 oldMSTime = getMSTime();
// 0 1 2 3 4 5
QueryResult result = WorldDatabase.Query("SELECT level, class, basemana, basearmor, attackpower, rangedattackpower FROM creature_classlevelstats");
// 0 1 2 3 4
QueryResult result = WorldDatabase.Query("SELECT level, class, basemana, attackpower, rangedattackpower FROM creature_classlevelstats");
if (!result)
{
@@ -9262,22 +9261,10 @@ void ObjectMgr::LoadCreatureClassLevelStats()
CreatureBaseStats stats;
for (uint8 i = 0; i < MAX_EXPANSIONS; ++i)
{
stats.BaseHealth[i] = GetGameTableColumnForClass(sNpcTotalHpGameTable[i].GetRow(Level), Class);
stats.BaseDamage[i] = GetGameTableColumnForClass(sNpcDamageByClassGameTable[i].GetRow(Level), Class);
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);
stats.BaseDamage[i] = 0.0f;
}
}
stats.BaseMana = fields[2].GetUInt32();
stats.BaseArmor = fields[3].GetUInt32();
stats.AttackPower = fields[4].GetUInt16();
stats.RangedAttackPower = fields[5].GetUInt16();
stats.AttackPower = fields[3].GetUInt16();
stats.RangedAttackPower = fields[4].GetUInt16();
_creatureBaseStatsStore[MAKE_PAIR16(Level, Class)] = stats;
@@ -64,6 +64,7 @@ namespace WorldPackets
bool ContentTuningParams::GenerateDataForUnits<Creature, Player>(Creature* attacker, Player* target)
{
CreatureTemplate const* creatureTemplate = attacker->GetCreatureTemplate();
CreatureLevelScaling const* creatureScaling = creatureTemplate->GetLevelScaling(attacker->GetMap()->GetDifficultyID());
Type = TYPE_CREATURE_TO_PLAYER_DAMAGE;
PlayerLevelDelta = target->m_activePlayerData->ScalingPlayerLevelDelta;
@@ -71,9 +72,9 @@ namespace WorldPackets
TargetItemLevel = 0;
ScalingHealthItemLevelCurveID = target->m_unitData->ScalingHealthItemLevelCurveID;
TargetLevel = target->getLevel();
Expansion = creatureTemplate->RequiredExpansion;
TargetMinScalingLevel = uint8(creatureTemplate->levelScaling->MinLevel);
TargetMaxScalingLevel = uint8(creatureTemplate->levelScaling->MaxLevel);
Expansion = creatureTemplate->HealthScalingExpansion;
TargetMinScalingLevel = uint8(creatureScaling->MinLevel);
TargetMaxScalingLevel = uint8(creatureScaling->MaxLevel);
TargetScalingLevelDelta = int8(attacker->m_unitData->ScalingLevelDelta);
return true;
}
@@ -82,6 +83,7 @@ namespace WorldPackets
bool ContentTuningParams::GenerateDataForUnits<Player, Creature>(Player* attacker, Creature* target)
{
CreatureTemplate const* creatureTemplate = target->GetCreatureTemplate();
CreatureLevelScaling const* creatureScaling = creatureTemplate->GetLevelScaling(target->GetMap()->GetDifficultyID());
Type = TYPE_PLAYER_TO_CREATURE_DAMAGE;
PlayerLevelDelta = attacker->m_activePlayerData->ScalingPlayerLevelDelta;
@@ -89,9 +91,9 @@ namespace WorldPackets
TargetItemLevel = 0;
ScalingHealthItemLevelCurveID = target->m_unitData->ScalingHealthItemLevelCurveID;
TargetLevel = target->getLevel();
Expansion = creatureTemplate->RequiredExpansion;
TargetMinScalingLevel = uint8(creatureTemplate->levelScaling->MinLevel);
TargetMaxScalingLevel = uint8(creatureTemplate->levelScaling->MaxLevel);
Expansion = creatureTemplate->HealthScalingExpansion;
TargetMinScalingLevel = uint8(creatureScaling->MinLevel);
TargetMaxScalingLevel = uint8(creatureScaling->MaxLevel);
TargetScalingLevelDelta = int8(target->m_unitData->ScalingLevelDelta);
return true;
}
@@ -101,14 +103,15 @@ namespace WorldPackets
{
Creature* accessor = target->HasScalableLevels() ? target : attacker;
CreatureTemplate const* creatureTemplate = accessor->GetCreatureTemplate();
CreatureLevelScaling const* creatureScaling = creatureTemplate->GetLevelScaling(accessor->GetMap()->GetDifficultyID());
Type = TYPE_CREATURE_TO_CREATURE_DAMAGE;
PlayerLevelDelta = 0;
PlayerItemLevel = 0;
TargetLevel = target->getLevel();
Expansion = creatureTemplate->RequiredExpansion;
TargetMinScalingLevel = uint8(creatureTemplate->levelScaling->MinLevel);
TargetMaxScalingLevel = uint8(creatureTemplate->levelScaling->MaxLevel);
Expansion = creatureTemplate->HealthScalingExpansion;
TargetMinScalingLevel = uint8(creatureScaling->MinLevel);
TargetMaxScalingLevel = uint8(creatureScaling->MaxLevel);
TargetScalingLevelDelta = int8(accessor->m_unitData->ScalingLevelDelta);
return true;
}
-17
View File
@@ -1356,7 +1356,6 @@ void ExtractGameTables()
DB2FileInfo GameTables[] =
{
{ 1385707, "ArmorMitigationByLvl.txt" },
{ 1582086, "ArtifactKnowledgeMultiplier.txt" },
{ 1391662, "ArtifactLevelXP.txt" },
{ 1892815, "AzeriteBaseExperiencePerLevel.txt" },
@@ -1375,23 +1374,7 @@ void ExtractGameTables()
{ 2012881, "ItemLevelByLevel.txt" },
{ 1726830, "ItemLevelSquish.txt" },
{ 1391643, "ItemSocketCostPerLevel.txt" },
{ 1391644, "NpcDamageByClass.txt" },
{ 1391645, "NpcDamageByClassExp1.txt" },
{ 1391646, "NpcDamageByClassExp2.txt" },
{ 1391647, "NpcDamageByClassExp3.txt" },
{ 1391648, "NpcDamageByClassExp4.txt" },
{ 1391649, "NpcDamageByClassExp5.txt" },
{ 1391650, "NpcDamageByClassExp6.txt" },
{ 1536195, "NpcDamageByClassExp7.txt" },
{ 1391651, "NPCManaCostScaler.txt" },
{ 1391652, "NpcTotalHp.txt" },
{ 1391653, "NpcTotalHpExp1.txt" },
{ 1391654, "NpcTotalHpExp2.txt" },
{ 1391655, "NpcTotalHpExp3.txt" },
{ 1391656, "NpcTotalHpExp4.txt" },
{ 1391657, "NpcTotalHpExp5.txt" },
{ 1391658, "NpcTotalHpExp6.txt" },
{ 1536196, "NpcTotalHpExp7.txt" },
{ 1391659, "SandboxScaling.txt" },
{ 1391660, "SpellScaling.txt" },
{ 1980632, "StaminaMultByILvl.txt" },