mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-21 07:22:02 -04:00
Core/Entities: correct creature damage, offhand damage should work too
* todo: some creatures need dmg_multiplier update in creature_template
This commit is contained in:
@@ -46,6 +46,43 @@ inline bool _ModifyUInt32(bool apply, uint32& baseValue, int32& amount)
|
||||
return apply;
|
||||
}
|
||||
|
||||
/*#######################################
|
||||
######## ########
|
||||
######## UNIT STAT SYSTEM ########
|
||||
######## ########
|
||||
#######################################*/
|
||||
|
||||
void Unit::UpdateAllResistances()
|
||||
{
|
||||
for (uint8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
|
||||
UpdateResistances(i);
|
||||
}
|
||||
|
||||
void Unit::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
{
|
||||
float minDamage = 0.0f;
|
||||
float maxDamage = 0.0f;
|
||||
|
||||
CalculateMinMaxDamage(attType, false, true, minDamage, maxDamage);
|
||||
|
||||
switch (attType)
|
||||
{
|
||||
case BASE_ATTACK:
|
||||
default:
|
||||
SetStatFloatValue(UNIT_FIELD_MINDAMAGE, minDamage);
|
||||
SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxDamage);
|
||||
break;
|
||||
case OFF_ATTACK:
|
||||
SetStatFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, minDamage);
|
||||
SetStatFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, maxDamage);
|
||||
break;
|
||||
case RANGED_ATTACK:
|
||||
SetStatFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, minDamage);
|
||||
SetStatFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, maxDamage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*#######################################
|
||||
######## ########
|
||||
######## PLAYERS STAT SYSTEM ########
|
||||
@@ -178,8 +215,7 @@ bool Player::UpdateAllStats()
|
||||
UpdateExpertise(BASE_ATTACK);
|
||||
UpdateExpertise(OFF_ATTACK);
|
||||
RecalculateRating(CR_ARMOR_PENETRATION);
|
||||
for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
|
||||
UpdateResistances(i);
|
||||
UpdateAllResistances();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -477,7 +513,7 @@ void Player::UpdateShieldBlockValue()
|
||||
SetUInt32Value(PLAYER_SHIELD_BLOCK, GetShieldBlockValue());
|
||||
}
|
||||
|
||||
void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& min_damage, float& max_damage)
|
||||
void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage)
|
||||
{
|
||||
UnitMods unitMod;
|
||||
|
||||
@@ -495,70 +531,45 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bo
|
||||
break;
|
||||
}
|
||||
|
||||
float att_speed = GetAPMultiplier(attType, normalized);
|
||||
float attackSpeedMod = GetAPMultiplier(attType, normalized);
|
||||
|
||||
float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed;
|
||||
float base_pct = GetModifierValue(unitMod, BASE_PCT);
|
||||
float total_value = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
float total_pct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f;
|
||||
float baseValue = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 14.0f * attackSpeedMod;
|
||||
float basePct = GetModifierValue(unitMod, BASE_PCT);
|
||||
float totalValue = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
float totalPct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f;
|
||||
|
||||
float weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE);
|
||||
float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE);
|
||||
float weaponMinDamage = GetWeaponDamageRange(attType, MINDAMAGE);
|
||||
float weaponMaxDamage = GetWeaponDamageRange(attType, MAXDAMAGE);
|
||||
|
||||
if (IsInFeralForm()) //check if player is druid and in cat or bear forms
|
||||
if (IsInFeralForm()) // check if player is druid and in cat or bear forms
|
||||
{
|
||||
uint8 lvl = getLevel();
|
||||
if (lvl > 60)
|
||||
lvl = 60;
|
||||
|
||||
weapon_mindamage = lvl*0.85f*att_speed;
|
||||
weapon_maxdamage = lvl*1.25f*att_speed;
|
||||
weaponMinDamage = lvl * 0.85f * attackSpeedMod;
|
||||
weaponMaxDamage = lvl * 1.25f * attackSpeedMod;
|
||||
}
|
||||
else if (!CanUseAttackType(attType)) //check if player not in form but still can't use (disarm case)
|
||||
else if (!CanUseAttackType(attType)) // check if player not in form but still can't use (disarm case)
|
||||
{
|
||||
//cannot use ranged/off attack, set values to 0
|
||||
// cannot use ranged/off attack, set values to 0
|
||||
if (attType != BASE_ATTACK)
|
||||
{
|
||||
min_damage = 0;
|
||||
max_damage = 0;
|
||||
minDamage = 0;
|
||||
maxDamage = 0;
|
||||
return;
|
||||
}
|
||||
weapon_mindamage = BASE_MINDAMAGE;
|
||||
weapon_maxdamage = BASE_MAXDAMAGE;
|
||||
weaponMinDamage = BASE_MINDAMAGE;
|
||||
weaponMaxDamage = BASE_MAXDAMAGE;
|
||||
}
|
||||
else if (attType == RANGED_ATTACK) //add ammo DPS to ranged damage
|
||||
else if (attType == RANGED_ATTACK) // add ammo DPS to ranged damage
|
||||
{
|
||||
weapon_mindamage += GetAmmoDPS() * att_speed;
|
||||
weapon_maxdamage += GetAmmoDPS() * att_speed;
|
||||
weaponMinDamage += GetAmmoDPS() * attackSpeedMod;
|
||||
weaponMaxDamage += GetAmmoDPS() * attackSpeedMod;
|
||||
}
|
||||
|
||||
min_damage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct;
|
||||
max_damage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct;
|
||||
}
|
||||
|
||||
void Player::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
{
|
||||
float mindamage;
|
||||
float maxdamage;
|
||||
|
||||
CalculateMinMaxDamage(attType, false, true, mindamage, maxdamage);
|
||||
|
||||
switch (attType)
|
||||
{
|
||||
case BASE_ATTACK:
|
||||
default:
|
||||
SetStatFloatValue(UNIT_FIELD_MINDAMAGE, mindamage);
|
||||
SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxdamage);
|
||||
break;
|
||||
case OFF_ATTACK:
|
||||
SetStatFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, mindamage);
|
||||
SetStatFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, maxdamage);
|
||||
break;
|
||||
case RANGED_ATTACK:
|
||||
SetStatFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, mindamage);
|
||||
SetStatFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, maxdamage);
|
||||
break;
|
||||
}
|
||||
minDamage = ((weaponMinDamage + baseValue) * basePct + totalValue) * totalPct;
|
||||
maxDamage = ((weaponMaxDamage + baseValue) * basePct + totalValue) * totalPct;
|
||||
}
|
||||
|
||||
void Player::UpdateDefenseBonusesMod()
|
||||
@@ -841,9 +852,14 @@ void Player::UpdateExpertise(WeaponAttackType attack)
|
||||
|
||||
switch (attack)
|
||||
{
|
||||
case BASE_ATTACK: SetUInt32Value(PLAYER_EXPERTISE, expertise); break;
|
||||
case OFF_ATTACK: SetUInt32Value(PLAYER_OFFHAND_EXPERTISE, expertise); break;
|
||||
default: break;
|
||||
case BASE_ATTACK:
|
||||
SetUInt32Value(PLAYER_EXPERTISE, expertise);
|
||||
break;
|
||||
case OFF_ATTACK:
|
||||
SetUInt32Value(PLAYER_OFFHAND_EXPERTISE, expertise);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -950,8 +966,7 @@ bool Creature::UpdateAllStats()
|
||||
for (uint8 i = POWER_MANA; i < MAX_POWERS; ++i)
|
||||
UpdateMaxPower(Powers(i));
|
||||
|
||||
for (int8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
|
||||
UpdateResistances(i);
|
||||
UpdateAllResistances();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -976,7 +991,7 @@ void Creature::UpdateArmor()
|
||||
void Creature::UpdateMaxHealth()
|
||||
{
|
||||
float value = GetTotalAuraModValue(UNIT_MOD_HEALTH);
|
||||
SetMaxHealth((uint32)value);
|
||||
SetMaxHealth(uint32(value));
|
||||
}
|
||||
|
||||
void Creature::UpdateMaxPower(Powers power)
|
||||
@@ -992,25 +1007,25 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged)
|
||||
UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER;
|
||||
|
||||
uint16 index = UNIT_FIELD_ATTACK_POWER;
|
||||
uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MODS;
|
||||
uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER;
|
||||
uint16 indexMod = UNIT_FIELD_ATTACK_POWER_MODS;
|
||||
uint16 indexMulti = UNIT_FIELD_ATTACK_POWER_MULTIPLIER;
|
||||
|
||||
if (ranged)
|
||||
{
|
||||
index = UNIT_FIELD_RANGED_ATTACK_POWER;
|
||||
index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS;
|
||||
index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER;
|
||||
indexMod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS;
|
||||
indexMulti = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER;
|
||||
}
|
||||
|
||||
float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
|
||||
float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
|
||||
float baseAttackPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
|
||||
float attackPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
float attackPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
|
||||
|
||||
SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field
|
||||
SetInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field
|
||||
SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field
|
||||
SetInt32Value(index, uint32(baseAttackPower)); // UNIT_FIELD_(RANGED)_ATTACK_POWER
|
||||
SetInt32Value(indexMod, uint32(attackPowerMod)); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS
|
||||
SetFloatValue(indexMulti, attackPowerMultiplier); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER
|
||||
|
||||
//automatically update weapon damage after attack power modification
|
||||
// automatically update weapon damage after attack power modification
|
||||
if (ranged)
|
||||
UpdateDamagePhysical(RANGED_ATTACK);
|
||||
else
|
||||
@@ -1020,7 +1035,7 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged)
|
||||
}
|
||||
}
|
||||
|
||||
void Creature::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage)
|
||||
{
|
||||
UnitMods unitMod;
|
||||
switch (attType)
|
||||
@@ -1037,44 +1052,32 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
break;
|
||||
}
|
||||
|
||||
//float att_speed = float(GetAttackTime(attType))/1000.0f;
|
||||
|
||||
float weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE);
|
||||
float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE);
|
||||
|
||||
/* difference in AP between current attack power and base value from DB */
|
||||
float att_pwr_change = GetTotalAttackPowerValue(attType) - GetCreatureTemplate()->attackpower;
|
||||
float base_value = GetModifierValue(unitMod, BASE_VALUE) + (att_pwr_change * GetAPMultiplier(attType, false) / 14.0f);
|
||||
float base_pct = GetModifierValue(unitMod, BASE_PCT);
|
||||
float total_value = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
float total_pct = GetModifierValue(unitMod, TOTAL_PCT);
|
||||
float dmg_multiplier = GetCreatureTemplate()->dmg_multiplier;
|
||||
|
||||
if (!CanUseAttackType(attType))
|
||||
if (attType == OFF_ATTACK && !haveOffhandWeapon())
|
||||
{
|
||||
weapon_mindamage = 0;
|
||||
weapon_maxdamage = 0;
|
||||
minDamage = 0.0f;
|
||||
maxDamage = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
float mindamage = ((base_value + weapon_mindamage) * dmg_multiplier * base_pct + total_value) * total_pct;
|
||||
float maxdamage = ((base_value + weapon_maxdamage) * dmg_multiplier * base_pct + total_value) * total_pct;
|
||||
float weaponMinDamage = GetWeaponDamageRange(attType, MINDAMAGE);
|
||||
float weaponMaxDamage = GetWeaponDamageRange(attType, MAXDAMAGE);
|
||||
|
||||
switch (attType)
|
||||
if (!CanUseAttackType(attType)) // disarm case
|
||||
{
|
||||
case BASE_ATTACK:
|
||||
default:
|
||||
SetStatFloatValue(UNIT_FIELD_MINDAMAGE, mindamage);
|
||||
SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxdamage);
|
||||
break;
|
||||
case OFF_ATTACK:
|
||||
SetStatFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, mindamage);
|
||||
SetStatFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, maxdamage);
|
||||
break;
|
||||
case RANGED_ATTACK:
|
||||
SetStatFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, mindamage);
|
||||
SetStatFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, maxdamage);
|
||||
break;
|
||||
weaponMinDamage = 0.0f;
|
||||
weaponMaxDamage = 0.0f;
|
||||
}
|
||||
|
||||
float attackPower = GetTotalAttackPowerValue(attType);
|
||||
float attackSpeedMulti = GetAPMultiplier(attType, normalized);
|
||||
float baseValue = GetModifierValue(unitMod, BASE_VALUE) + (attackPower / 14.0f);
|
||||
float basePct = GetModifierValue(unitMod, BASE_PCT) * attackSpeedMulti;
|
||||
float totalValue = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
float totalPct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f;
|
||||
float dmgMultiplier = GetCreatureTemplate()->dmg_multiplier; // = dmg_multiplier * _GetDamageMod(rank);
|
||||
|
||||
minDamage = ((weaponMinDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct;
|
||||
maxDamage = ((weaponMaxDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct;
|
||||
}
|
||||
|
||||
/*#######################################
|
||||
@@ -1197,8 +1200,7 @@ bool Guardian::UpdateAllStats()
|
||||
for (uint8 i = POWER_MANA; i < MAX_POWERS; ++i)
|
||||
UpdateMaxPower(Powers(i));
|
||||
|
||||
for (uint8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
|
||||
UpdateResistances(i);
|
||||
UpdateAllResistances();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1436,6 +1438,7 @@ void Guardian::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
}
|
||||
}
|
||||
|
||||
/// @todo: remove this
|
||||
Unit::AuraEffectList const& mDummy = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACKSPEED);
|
||||
for (Unit::AuraEffectList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user