Core/Units: ported rage generation refactors from Classic

This commit is contained in:
Ovahlord committed 2025-06-19 23:30:04 +02:00
1 parent 4539f848ac
commit e8c928fc74
2 files changed
+34 -37

No files matched your search

+32 -37
View File
@@ -929,7 +929,7 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) cons
// Rage from damage received
if (attacker != victim && victim->GetPowerType() == POWER_RAGE)
{
uint32 rageBaseReward = std::max(damage, unmitigatedDamage);
uint32 rageBaseReward = CalcDamageTakenRageGain(victim, std::max(damage, unmitigatedDamage));
victim->RewardRage(rageBaseReward, false);
}
@@ -1150,6 +1150,37 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss)
Unit::DealDamage(this, victim, damageInfo->damage, damageInfo->unmitigatedDamage, SPELL_DIRECT_DAMAGE, SpellSchoolMask(damageInfo->schoolMask), spellProto, durabilityLoss);
}
/*static*/ uint32 Unit::CalcMeleeAttackRageGain(Unit const* attacker, Unit const* victim, WeaponAttackType attType)
{
if (!attacker || !victim || (attType != BASE_ATTACK && attType != OFF_ATTACK))
return 0;
uint32 rage = uint32(attacker->GetBaseAttackTime(attType) / 1000.f * 6.5f);
if (attType == OFF_ATTACK)
rage /= 2;
// Players below level 10 start with a 50% rage gain reduction that slowly diminishes
if (attacker->IsPlayer() && attacker->getLevel() < 10)
rage -= (rage / 2.f) * (1.0f - (attacker->getLevel() / 10.f));
return uint32(rage * 10);
}
// The minimum amount a damaging hit should award
constexpr uint32 MIN_RAGE_AMOUNT = 10;
/*static*/ uint32 Unit::CalcDamageTakenRageGain(Unit const* victim, uint32 damage)
{
if (!victim || damage == 0)
return 0;
double multiplier = static_cast<double>(damage) / victim->GetMaxHealth();
// This formula is based on sampling multiple sniff data at multiple level ranges
// There has never been any leak and the only info we have is that the amount is based on max HP and damage taken and that there is a hidden constant
return std::max<uint32>(MIN_RAGE_AMOUNT, std::ceil(400 * multiplier));
}
/// @todo for melee need create structure as in
void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, WeaponAttackType attackType /*= BASE_ATTACK*/)
{
@@ -1922,42 +1953,6 @@ static float GetArmorReduction(float armor, uint8 attackerLevel)
healInfo.AbsorbHeal(absorbAmount);
}
// Calculates the normalized rage amount per weapon swing
inline static uint32 CalcMeleeAttackRageGain(Unit const* attacker, Unit const* victim, WeaponAttackType attType)
{
float attackDelay = [&]()
{
if (Player const* playerAttacker = attacker->ToPlayer())
{
if (!playerAttacker->IsInFeralForm())
{
Item const* weapon = playerAttacker->GetWeaponForAttack(attType);
if (weapon)
return static_cast<float>(weapon->GetTemplate()->GetDelay());
}
else if (SpellShapeshiftFormEntry const* shapeShiftFormEntry = sSpellShapeshiftFormStore.LookupEntry(playerAttacker->GetShapeshiftForm()))
return static_cast<float>(shapeShiftFormEntry->CombatRoundTime);
}
else if (Creature const* creature = attacker->ToCreature())
return static_cast<float>(creature->GetCreatureTemplate()->BaseAttackTime);
return 0.f;
}();
uint32 rageAmount = attackDelay / 1000 * 6.5f;
// Sentinel
if (victim->GetVictim() && victim->GetVictim() != attacker)
if (AuraEffect* aurEff = attacker->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_GENERIC, 1916, EFFECT_1))
rageAmount += CalculatePct(rageAmount, aurEff->GetAmount());
if (attType == OFF_ATTACK)
rageAmount *= 0.5f;
return rageAmount;
}
void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extra)
{
if (HasUnitState(UNIT_STATE_CANNOT_AUTOATTACK) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))
+2
View File
@@ -888,6 +888,8 @@ class TC_GAME_API Unit : public WorldObject
void HandleEmoteCommand(uint32 emoteId);
void AttackerStateUpdate(Unit* victim, WeaponAttackType attType = BASE_ATTACK, bool extra = false);
static uint32 CalcMeleeAttackRageGain(Unit const* attacker, Unit const* victim, WeaponAttackType attType);
static uint32 CalcDamageTakenRageGain(Unit const* victim, uint32 damage);
void CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, WeaponAttackType attackType = BASE_ATTACK);
void DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss);
void HandleProcExtraAttackFor(Unit* victim);