Core/Creatures: renamed exp column to HealthScalingExpansion and implement support for negative expansion level (-1 means current expansion - often used in battlegrounds)

This commit is contained in:
Ovahlord committed 2025-06-18 00:36:43 +02:00
1 parent 49da5d33e1
commit f26684b407
7 files changed
+26 -16

No files matched your search

@@ -0,0 +1,2 @@
ALTER TABLE `creature_template`
CHANGE `exp` `HealthScalingExpansion` INT NOT NULL DEFAULT 0;
@@ -76,7 +76,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID, "SELECT id FROM waypoint_scripts WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_DEL_CREATURE, "DELETE FROM creature WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, permission, help FROM command", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, ctm.HoverInitiallyEnabled, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, StaticFlags, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, ScriptName FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId WHERE entry = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, HealthScalingExpansion, exp_unk, faction, npcflag, speed_walk, speed_run, scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, ctm.HoverInitiallyEnabled, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, StaticFlags, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, ScriptName FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId WHERE entry = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_GAMEOBJECT_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM gameobject WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_", CONNECTION_SYNCH);
@@ -1875,7 +1875,7 @@ float Creature::GetAttackDistance(Unit const* player) const
float maxRadius = (45.0f * sWorld->getRate(RATE_CREATURE_AGGRO));
float minRadius = (5.0f * sWorld->getRate(RATE_CREATURE_AGGRO));
float aggroRate = sWorld->getRate(RATE_CREATURE_AGGRO);
uint8 expansionMaxLevel = uint8(DBCManager::GetMaxLevelForExpansion(GetCreatureTemplate()->expansion));
uint8 expansionMaxLevel = uint8(DBCManager::GetMaxLevelForExpansion(GetCreatureTemplate()->GetHealthScalingExpansion()));
uint32 playerLevel = player->getLevel();
uint32 creatureLevel = getLevel();
@@ -366,7 +366,7 @@ struct TC_GAME_API CreatureTemplate
uint32 GossipMenuId;
uint8 minlevel;
uint8 maxlevel;
uint32 expansion;
int32 HealthScalingExpansion;
uint32 expansionUnknown; // either 0 or 3, sent to the client / wdb
uint32 faction;
uint32 npcflag;
@@ -450,6 +450,12 @@ struct TC_GAME_API CreatureTemplate
return canTameExotic || !IsExotic();
}
// Helpers
int32 GetHealthScalingExpansion() const
{
return HealthScalingExpansion == EXPANSION_LEVEL_CURRENT ? CURRENT_EXPANSION : HealthScalingExpansion;
}
void InitializeQueryData();
WorldPacket BuildQueryData(LocaleConstant loc) const;
};
@@ -467,10 +473,9 @@ struct TC_GAME_API CreatureBaseStats
float BaseDamage[MAX_EXPANSIONS];
// Helpers
uint32 GenerateHealth(CreatureTemplate const* info) const
{
return uint32(ceil(BaseHealth[info->expansion] * info->ModHealth * info->ModHealthExtra));
return uint32(ceil(BaseHealth[info->GetHealthScalingExpansion()] * info->ModHealth * info->ModHealthExtra));
}
uint32 GenerateArmor(CreatureTemplate const* info) const
@@ -480,7 +485,7 @@ struct TC_GAME_API CreatureBaseStats
float GenerateBaseDamage(CreatureTemplate const* info) const
{
return BaseDamage[info->expansion];
return BaseDamage[info->GetHealthScalingExpansion()];
}
static CreatureBaseStats const* GetBaseStats(uint8 level, uint8 unitClass);
+9 -9
View File
@@ -426,8 +426,8 @@ void ObjectMgr::LoadCreatureTemplates()
// 0 1 2 3 4 5 6 7 8
QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, "
// 9 10 11 12 13 14 15 16 17 18 19 20 21 22
"modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, "
// 9 10 11 12 13 14 15 16 17 18 19 20 21 22
"modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, HealthScalingExpansion, exp_unk, faction, npcflag, speed_walk, speed_run, "
// 23 24 25 26 27 28 29 30 31 32
"scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, "
// 33 34 35 36 37 38 39 40 41 42 43 44 45 46
@@ -490,7 +490,7 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields)
creatureTemplate.GossipMenuId = fields[14].GetUInt32();
creatureTemplate.minlevel = fields[15].GetUInt8();
creatureTemplate.maxlevel = fields[16].GetUInt8();
creatureTemplate.expansion = uint32(fields[17].GetInt16());
creatureTemplate.HealthScalingExpansion = fields[17].GetInt32();
creatureTemplate.expansionUnknown = uint32(fields[18].GetUInt16());
creatureTemplate.faction = uint32(fields[19].GetUInt16());
creatureTemplate.npcflag = fields[20].GetUInt32();
@@ -838,10 +838,10 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
if (!ok2)
continue;
if (cInfo->expansion > difficultyInfo->expansion)
if (cInfo->HealthScalingExpansion >= 0 && cInfo->HealthScalingExpansion > difficultyInfo->HealthScalingExpansion)
{
TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, exp: %u) has different `exp` in difficulty %u mode (Entry: %u, exp: %u).",
cInfo->Entry, cInfo->expansion, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->expansion);
TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, exp: %u) has different `HealthScalingExpansion` in difficulty %u mode (Entry: %u, exp: %u).",
cInfo->Entry, cInfo->HealthScalingExpansion, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->HealthScalingExpansion);
}
if (cInfo->minlevel > difficultyInfo->minlevel)
@@ -1097,10 +1097,10 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
const_cast<CreatureTemplate*>(cInfo)->MovementType = IDLE_MOTION_TYPE;
}
if (cInfo->expansion > (MAX_EXPANSIONS - 1))
if (cInfo->HealthScalingExpansion > (MAX_EXPANSIONS - 1))
{
TC_LOG_ERROR("sql.sql", "Table `creature_template` lists creature (Entry: %u) with expansion %u. Ignored and set to 0.", cInfo->Entry, cInfo->expansion);
const_cast<CreatureTemplate*>(cInfo)->expansion = 0;
TC_LOG_ERROR("sql.sql", "Table `creature_template` lists creature (Entry: %u) with `HealthScalingExpansion` %u. Ignored and set to 0.", cInfo->Entry, cInfo->HealthScalingExpansion);
const_cast<CreatureTemplate*>(cInfo)->HealthScalingExpansion = 0;
}
if (cInfo->expansionUnknown > MAX_EXPANSIONS)
@@ -54,6 +54,7 @@ enum LootModes
enum Expansions
{
EXPANSION_LEVEL_CURRENT = -1,
EXPANSION_CLASSIC = 0,
EXPANSION_THE_BURNING_CRUSADE = 1,
EXPANSION_WRATH_OF_THE_LICH_KING = 2,
@@ -61,6 +62,8 @@ enum Expansions
MAX_EXPANSIONS = 4
};
constexpr uint8 CURRENT_EXPANSION = EXPANSION_CATACLYSM;
enum Gender
{
GENDER_MALE = 0,
+1 -1
View File
@@ -581,7 +581,7 @@ int32 SpellEffectInfo::CalcBaseValue(WorldObject const* caster, Unit const* targ
if (Creature const* creatureCaster = Object::ToCreature(caster))
{
uint8 casterClass = creatureCaster->getClass();
uint8 expansion = creatureCaster->GetCreatureTemplate()->expansion;
uint8 expansion = creatureCaster->GetCreatureTemplate()->GetHealthScalingExpansion();
float spellDamage = GetGameTableColumnForClass(sNpcDamageByClassGameTable[expansion].GetRow(_spellInfo->SpellLevel), casterClass);
float creatureDamage = GetGameTableColumnForClass(sNpcDamageByClassGameTable[expansion].GetRow(creatureCaster->getLevel()), casterClass);