Core/Creatures: Fixed setting current health by spells/auras from creature_addon/creature_template_addon

This commit is contained in:
Shauren
2026-07-20 12:32:49 +02:00
parent 6a36858df6
commit 18fefeee44
4 changed files with 39 additions and 22 deletions
@@ -0,0 +1,3 @@
ALTER TABLE `creature` MODIFY COLUMN `curHealthPct` int UNSIGNED NULL DEFAULT NULL AFTER `currentwaypoint`;
UPDATE `creature` SET `curHealthPct` = NULL WHERE `curHealthPct` <= 0 OR `curHealthPct` >= 100;
+21 -16
View File
@@ -1478,24 +1478,21 @@ void Creature::SaveToDB(uint32 mapid, std::vector<Difficulty> const& spawnDiffic
// check if it's a custom model and if not, use 0 for displayId
CreatureTemplate const* cinfo = GetCreatureTemplate();
if (cinfo)
{
for (CreatureModel const& model : cinfo->Models)
if (displayId && displayId == model.CreatureDisplayID)
displayId = 0;
for (CreatureModel const& model : cinfo->Models)
if (displayId && displayId == model.CreatureDisplayID)
displayId = 0;
if (spawnNpcFlags != cinfo->npcflag)
npcflag = spawnNpcFlags;
if (spawnNpcFlags != cinfo->npcflag)
npcflag = spawnNpcFlags;
if (m_unitData->Flags != cinfo->unit_flags)
unitFlags = m_unitData->Flags;
if (m_unitData->Flags != cinfo->unit_flags)
unitFlags = m_unitData->Flags;
if (m_unitData->Flags2 != cinfo->unit_flags2)
unitFlags2 = m_unitData->Flags2;
if (m_unitData->Flags2 != cinfo->unit_flags2)
unitFlags2 = m_unitData->Flags2;
if (m_unitData->Flags3 != cinfo->unit_flags3)
unitFlags3 = m_unitData->Flags3;
}
if (m_unitData->Flags3 != cinfo->unit_flags3)
unitFlags3 = m_unitData->Flags3;
if (!data.spawnId)
data.spawnId = m_spawnId;
@@ -1520,7 +1517,9 @@ void Creature::SaveToDB(uint32 mapid, std::vector<Difficulty> const& spawnDiffic
// prevent add data integrity problems
data.wander_distance = GetDefaultMovementType() == IDLE_MOTION_TYPE ? 0.0f : m_wanderDistance;
data.currentwaypoint = 0;
data.curHealthPct = uint32(GetHealthPct());
if (!cinfo->RegenHealth)
data.curHealthPct = uint32(GetHealthPct());
// prevent add data integrity problems
data.movementType = !m_wanderDistance && GetDefaultMovementType() == RANDOM_MOTION_TYPE
? IDLE_MOTION_TYPE : GetDefaultMovementType();
@@ -1995,7 +1994,13 @@ void Creature::LoadEquipment(int8 id, bool force /*= true*/)
void Creature::SetSpawnHealth()
{
SetHealth(CountPctFromMaxHealth(m_creatureData ? m_creatureData->curHealthPct : 100));
// set health only if regenerating is not enabled (otherwise it would immediately go back to full health anyway)
if (!_regenerateHealth && m_creatureData && m_creatureData->curHealthPct)
SetHealth(CountPctFromMaxHealth(*m_creatureData->curHealthPct));
// or when creature respawns in legacy compatibility mode
else if (getDeathState() == JUST_RESPAWNED)
SetFullHealth();
SetInitialPowerValue(GetPowerType());
}
@@ -608,7 +608,7 @@ struct CreatureData : public SpawnData
int8 equipmentId = 0;
float wander_distance = 0.0f;
uint32 currentwaypoint = 0;
uint32 curHealthPct = 0;
Optional<uint32> curHealthPct;
uint8 movementType = 0;
Optional<uint64> npcflag;
Optional<uint32> unit_flags; // enum UnitFlags mask values
+14 -5
View File
@@ -2171,7 +2171,7 @@ void ObjectMgr::LoadCreatures()
data.spawntimesecs = fields[9].GetUInt32();
data.wander_distance = fields[10].GetFloat();
data.currentwaypoint = fields[11].GetUInt32();
data.curHealthPct = fields[12].GetUInt32();
data.curHealthPct = fields[12].GetUInt32OrNull();
data.movementType = fields[13].GetUInt8();
data.spawnDifficulties = ParseSpawnDifficulties(fields[14].GetStringView(), "creature", guid, data.mapId, spawnMasks[data.mapId]);
int16 gameEvent = fields[15].GetInt8();
@@ -2368,11 +2368,20 @@ void ObjectMgr::LoadCreatures()
}
}
uint32 healthPct = std::clamp<uint32>(data.curHealthPct, 1, 100);
if (data.curHealthPct != healthPct)
if (data.curHealthPct)
{
TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: {} Entry: {}) with invalid `curHealthPct` {}, set to {}.", guid, data.id, data.curHealthPct, healthPct);
data.curHealthPct = healthPct;
uint32 healthPct = std::clamp<uint32>(*data.curHealthPct, 1, 100);
if (*data.curHealthPct != healthPct)
{
TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: {} Entry: {}) with invalid `curHealthPct` {}, set to {}.", guid, data.id, *data.curHealthPct, healthPct);
data.curHealthPct = healthPct;
}
if (cInfo->RegenHealth)
{
TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: {} Entry: {}) with `curHealthPct` {}, but health regeneration is not disabled in `creature_template`, set to 100.", guid, data.id, *data.curHealthPct);
data.curHealthPct.reset();
}
}
if (sWorld->getBoolConfig(CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA))