mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-29 13:22:48 +01:00
*Backed out changeset 3be01fb200a5
--HG-- branch : trunk
This commit is contained in:
@@ -17,30 +17,37 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Unit.h"
|
||||
#include "Player.h"
|
||||
#include "Pet.h"
|
||||
#include "Creature.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "SpellAuras.h"
|
||||
|
||||
/*#######################################
|
||||
######## ########
|
||||
######## PLAYERS STAT SYSTEM ########
|
||||
######## ########
|
||||
#######################################*/
|
||||
|
||||
bool Player::UpdateStats(Stats stat)
|
||||
{
|
||||
if(stat > STAT_SPIRIT)
|
||||
return false;
|
||||
|
||||
// value = ((base_value * base_pct) + total_value) * total_pct
|
||||
float value = GetTotalStatValue(stat);
|
||||
|
||||
SetStat(stat, int32(value));
|
||||
|
||||
if(stat == STAT_STAMINA || stat == STAT_INTELLECT)
|
||||
{
|
||||
Pet *pet = GetPet();
|
||||
if(pet)
|
||||
pet->UpdateStats(stat);
|
||||
}
|
||||
|
||||
switch(stat)
|
||||
{
|
||||
case STAT_STRENGTH:
|
||||
@@ -57,11 +64,14 @@ bool Player::UpdateStats(Stats stat)
|
||||
UpdateAllSpellCritChances();
|
||||
UpdateArmor(); //SPELL_AURA_MOD_RESISTANCE_OF_INTELLECT_PERCENT, only armor currently
|
||||
break;
|
||||
|
||||
case STAT_SPIRIT:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (stat == STAT_STRENGTH)
|
||||
{
|
||||
UpdateAttackPowerAndDamage(false);
|
||||
@@ -81,8 +91,10 @@ bool Player::UpdateStats(Stats stat)
|
||||
if (HasAuraTypeWithMiscvalue(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT, stat))
|
||||
UpdateAttackPowerAndDamage(true);
|
||||
}
|
||||
|
||||
UpdateSpellDamageAndHealingBonus();
|
||||
UpdateManaRegen();
|
||||
|
||||
// Update ratings in exist SPELL_AURA_MOD_RATING_FROM_STAT and only depends from stat
|
||||
uint32 mask = 0;
|
||||
AuraEffectList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT);
|
||||
@@ -97,14 +109,17 @@ bool Player::UpdateStats(Stats stat)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Player::ApplySpellPowerBonus(int32 amount, bool apply)
|
||||
{
|
||||
m_baseSpellPower+=apply?amount:-amount;
|
||||
|
||||
// For speed just update for client
|
||||
ApplyModUInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, amount, apply);
|
||||
for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
|
||||
ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, amount, apply);;
|
||||
}
|
||||
|
||||
void Player::UpdateSpellDamageAndHealingBonus()
|
||||
{
|
||||
// Magic damage modifiers implemented in Unit::SpellDamageBonus
|
||||
@@ -115,6 +130,7 @@ void Player::UpdateSpellDamageAndHealingBonus()
|
||||
for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
|
||||
SetStatInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, SpellBaseDamageBonus(SpellSchoolMask(1 << i)));
|
||||
}
|
||||
|
||||
bool Player::UpdateAllStats()
|
||||
{
|
||||
for (int i = STAT_STRENGTH; i < MAX_STATS; ++i)
|
||||
@@ -122,12 +138,15 @@ bool Player::UpdateAllStats()
|
||||
float value = GetTotalStatValue(Stats(i));
|
||||
SetStat(Stats(i), (int32)value);
|
||||
}
|
||||
|
||||
UpdateArmor();
|
||||
// calls UpdateAttackPowerAndDamage() in UpdateArmor for SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR
|
||||
UpdateAttackPowerAndDamage(true);
|
||||
UpdateMaxHealth();
|
||||
|
||||
for(int i = POWER_MANA; i < MAX_POWERS; ++i)
|
||||
UpdateMaxPower(Powers(i));
|
||||
|
||||
UpdateAllCritPercentages();
|
||||
UpdateAllSpellCritChances();
|
||||
UpdateDefenseBonusesMod();
|
||||
@@ -139,14 +158,17 @@ bool Player::UpdateAllStats()
|
||||
RecalculateRating(CR_ARMOR_PENETRATION);
|
||||
for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
|
||||
UpdateResistances(i);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Player::UpdateResistances(uint32 school)
|
||||
{
|
||||
if(school > SPELL_SCHOOL_NORMAL)
|
||||
{
|
||||
float value = GetTotalAuraModValue(UnitMods(UNIT_MOD_RESISTANCE_START + school));
|
||||
SetResistance(SpellSchools(school), int32(value));
|
||||
|
||||
Pet *pet = GetPet();
|
||||
if(pet)
|
||||
pet->UpdateResistances(school);
|
||||
@@ -154,14 +176,17 @@ void Player::UpdateResistances(uint32 school)
|
||||
else
|
||||
UpdateArmor();
|
||||
}
|
||||
|
||||
void Player::UpdateArmor()
|
||||
{
|
||||
float value = 0.0f;
|
||||
UnitMods unitMod = UNIT_MOD_ARMOR;
|
||||
|
||||
value = GetModifierValue(unitMod, BASE_VALUE); // base armor (from items)
|
||||
value *= GetModifierValue(unitMod, BASE_PCT); // armor percent from items
|
||||
value += GetStat(STAT_AGILITY) * 2.0f; // armor bonus from stats
|
||||
value += GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
|
||||
//add dynamic flat mods
|
||||
AuraEffectList const& mResbyIntellect = GetAurasByType(SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT);
|
||||
for(AuraEffectList::const_iterator i = mResbyIntellect.begin();i != mResbyIntellect.end(); ++i)
|
||||
@@ -169,64 +194,87 @@ void Player::UpdateArmor()
|
||||
if((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
|
||||
value += int32(GetStat(Stats((*i)->GetMiscBValue())) * (*i)->GetAmount() / 100.0f);
|
||||
}
|
||||
|
||||
value *= GetModifierValue(unitMod, TOTAL_PCT);
|
||||
|
||||
SetArmor(int32(value));
|
||||
|
||||
Pet *pet = GetPet();
|
||||
if(pet)
|
||||
pet->UpdateArmor();
|
||||
|
||||
UpdateAttackPowerAndDamage(); // armor dependent auras update for SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR
|
||||
}
|
||||
|
||||
float Player::GetHealthBonusFromStamina()
|
||||
{
|
||||
float stamina = GetStat(STAT_STAMINA);
|
||||
|
||||
float baseStam = stamina < 20 ? stamina : 20;
|
||||
float moreStam = stamina - baseStam;
|
||||
|
||||
return baseStam + (moreStam*10.0f);
|
||||
}
|
||||
|
||||
float Player::GetManaBonusFromIntellect()
|
||||
{
|
||||
float intellect = GetStat(STAT_INTELLECT);
|
||||
|
||||
float baseInt = intellect < 20 ? intellect : 20;
|
||||
float moreInt = intellect - baseInt;
|
||||
|
||||
return baseInt + (moreInt*15.0f);
|
||||
}
|
||||
|
||||
void Player::UpdateMaxHealth()
|
||||
{
|
||||
UnitMods unitMod = UNIT_MOD_HEALTH;
|
||||
|
||||
float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreateHealth();
|
||||
value *= GetModifierValue(unitMod, BASE_PCT);
|
||||
value += GetModifierValue(unitMod, TOTAL_VALUE) + GetHealthBonusFromStamina();
|
||||
value *= GetModifierValue(unitMod, TOTAL_PCT);
|
||||
|
||||
SetMaxHealth((uint32)value);
|
||||
}
|
||||
|
||||
void Player::UpdateMaxPower(Powers power)
|
||||
{
|
||||
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power);
|
||||
|
||||
float bonusPower = (power == POWER_MANA) ? GetManaBonusFromIntellect() : 0;
|
||||
|
||||
float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power);
|
||||
value *= GetModifierValue(unitMod, BASE_PCT);
|
||||
value += GetModifierValue(unitMod, TOTAL_VALUE) + bonusPower;
|
||||
value *= GetModifierValue(unitMod, TOTAL_PCT);
|
||||
|
||||
SetMaxPower(power, uint32(value));
|
||||
}
|
||||
|
||||
void Player::ApplyFeralAPBonus(int32 amount, bool apply)
|
||||
{
|
||||
m_baseFeralAP+= apply ? amount:-amount;
|
||||
UpdateAttackPowerAndDamage();
|
||||
}
|
||||
|
||||
void Player::UpdateAttackPowerAndDamage(bool ranged )
|
||||
{
|
||||
float val2 = 0.0f;
|
||||
float level = float(getLevel());
|
||||
|
||||
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;
|
||||
|
||||
if(ranged)
|
||||
{
|
||||
index = UNIT_FIELD_RANGED_ATTACK_POWER;
|
||||
index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS;
|
||||
index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER;
|
||||
|
||||
switch(getClass())
|
||||
{
|
||||
case CLASS_HUNTER: val2 = level * 2.0f + GetStat(STAT_AGILITY) - 10.0f; break;
|
||||
@@ -281,6 +329,7 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch(m_form)
|
||||
{
|
||||
case FORM_CAT:
|
||||
@@ -300,9 +349,12 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
|
||||
case CLASS_WARLOCK: val2 = GetStat(STAT_STRENGTH) - 10.0f; break;
|
||||
}
|
||||
}
|
||||
|
||||
SetModifierValue(unitMod, BASE_VALUE, val2);
|
||||
|
||||
float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
|
||||
float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
|
||||
//add dynamic flat mods
|
||||
if( ranged )
|
||||
{
|
||||
@@ -318,15 +370,19 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
|
||||
AuraEffectList const& mAPbyStat = GetAurasByType(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT);
|
||||
for(AuraEffectList::const_iterator i = mAPbyStat.begin();i != mAPbyStat.end(); ++i)
|
||||
attPowerMod += int32(GetStat(Stats((*i)->GetMiscValue())) * (*i)->GetAmount() / 100.0f);
|
||||
|
||||
AuraEffectList const& mAPbyArmor = GetAurasByType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR);
|
||||
for(AuraEffectList::const_iterator iter = mAPbyArmor.begin(); iter != mAPbyArmor.end(); ++iter)
|
||||
// always: ((*i)->GetModifier()->m_miscvalue == 1 == SPELL_SCHOOL_MASK_NORMAL)
|
||||
attPowerMod += int32(GetArmor() / (*iter)->GetAmount());
|
||||
}
|
||||
|
||||
float attPowerMultiplier = 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
|
||||
|
||||
Pet *pet = GetPet(); //update pet's AP
|
||||
//automatically update weapon damage after attack power modification
|
||||
if(ranged)
|
||||
@@ -342,18 +398,22 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
|
||||
UpdateDamagePhysical(OFF_ATTACK);
|
||||
if(getClass() == CLASS_SHAMAN) // mental quickness
|
||||
UpdateSpellDamageAndHealingBonus();
|
||||
|
||||
if(pet && pet->IsPetGhoul()) // At ranged attack change for hunter pet
|
||||
pet->UpdateAttackPowerAndDamage();
|
||||
}
|
||||
}
|
||||
|
||||
void Player::UpdateShieldBlockValue()
|
||||
{
|
||||
SetUInt32Value(PLAYER_SHIELD_BLOCK, GetShieldBlockValue());
|
||||
}
|
||||
|
||||
void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& min_damage, float& max_damage)
|
||||
{
|
||||
UnitMods unitMod;
|
||||
UnitMods attPower;
|
||||
|
||||
switch(attType)
|
||||
{
|
||||
case BASE_ATTACK:
|
||||
@@ -370,17 +430,22 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bo
|
||||
attPower = UNIT_MOD_ATTACK_POWER_RANGED;
|
||||
break;
|
||||
}
|
||||
|
||||
float att_speed = 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 weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE);
|
||||
float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE);
|
||||
|
||||
if (IsInFeralForm()) //check if player is druid and in cat or bear forms
|
||||
{
|
||||
uint32 lvl = getLevel();
|
||||
if ( lvl > 60 ) lvl = 60;
|
||||
|
||||
weapon_mindamage = lvl*0.85*att_speed;
|
||||
weapon_maxdamage = lvl*1.25*att_speed;
|
||||
}
|
||||
@@ -401,14 +466,18 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bo
|
||||
weapon_mindamage += GetAmmoDPS() * att_speed;
|
||||
weapon_maxdamage += GetAmmoDPS() * att_speed;
|
||||
}
|
||||
|
||||
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:
|
||||
@@ -426,12 +495,14 @@ void Player::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Player::UpdateDefenseBonusesMod()
|
||||
{
|
||||
UpdateBlockPercentage();
|
||||
UpdateParryPercentage();
|
||||
UpdateDodgePercentage();
|
||||
}
|
||||
|
||||
void Player::UpdateBlockPercentage()
|
||||
{
|
||||
// No block
|
||||
@@ -450,11 +521,13 @@ void Player::UpdateBlockPercentage()
|
||||
}
|
||||
SetStatFloatValue(PLAYER_BLOCK_PERCENTAGE, value);
|
||||
}
|
||||
|
||||
void Player::UpdateCritPercentage(WeaponAttackType attType)
|
||||
{
|
||||
BaseModGroup modGroup;
|
||||
uint16 index;
|
||||
CombatRating cr;
|
||||
|
||||
switch(attType)
|
||||
{
|
||||
case OFF_ATTACK:
|
||||
@@ -474,22 +547,27 @@ void Player::UpdateCritPercentage(WeaponAttackType attType)
|
||||
cr = CR_CRIT_MELEE;
|
||||
break;
|
||||
}
|
||||
|
||||
float value = GetTotalPercentageModValue(modGroup) + GetRatingBonusValue(cr);
|
||||
// Modify crit from weapon skill and maximized defense skill of same level victim difference
|
||||
value += (int32(GetWeaponSkillValue(attType)) - int32(GetMaxSkillValueForLevel())) * 0.04f;
|
||||
value = value < 0.0f ? 0.0f : value;
|
||||
SetStatFloatValue(index, value);
|
||||
}
|
||||
|
||||
void Player::UpdateAllCritPercentages()
|
||||
{
|
||||
float value = GetMeleeCritFromAgility();
|
||||
|
||||
SetBaseModValue(CRIT_PERCENTAGE, PCT_MOD, value);
|
||||
SetBaseModValue(OFFHAND_CRIT_PERCENTAGE, PCT_MOD, value);
|
||||
SetBaseModValue(RANGED_CRIT_PERCENTAGE, PCT_MOD, value);
|
||||
|
||||
UpdateCritPercentage(BASE_ATTACK);
|
||||
UpdateCritPercentage(OFF_ATTACK);
|
||||
UpdateCritPercentage(RANGED_ATTACK);
|
||||
}
|
||||
|
||||
void Player::UpdateParryPercentage()
|
||||
{
|
||||
// No parry
|
||||
@@ -508,6 +586,7 @@ void Player::UpdateParryPercentage()
|
||||
}
|
||||
SetStatFloatValue(PLAYER_PARRY_PERCENTAGE, value);
|
||||
}
|
||||
|
||||
void Player::UpdateDodgePercentage()
|
||||
{
|
||||
// Dodge from agility
|
||||
@@ -521,6 +600,7 @@ void Player::UpdateDodgePercentage()
|
||||
value = value < 0.0f ? 0.0f : value;
|
||||
SetStatFloatValue(PLAYER_DODGE_PERCENTAGE, value);
|
||||
}
|
||||
|
||||
void Player::UpdateSpellCritChance(uint32 school)
|
||||
{
|
||||
// For normal school set zero crit chance
|
||||
@@ -541,40 +621,50 @@ void Player::UpdateSpellCritChance(uint32 school)
|
||||
crit += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, 1<<school);
|
||||
// Increase crit from spell crit ratings
|
||||
crit += GetRatingBonusValue(CR_CRIT_SPELL);
|
||||
|
||||
// Store crit value
|
||||
SetFloatValue(PLAYER_SPELL_CRIT_PERCENTAGE1 + school, crit);
|
||||
}
|
||||
|
||||
void Player::UpdateArmorPenetration(int32 amount)
|
||||
{
|
||||
// Store Rating Value
|
||||
SetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + CR_ARMOR_PENETRATION, amount);
|
||||
}
|
||||
|
||||
void Player::UpdateMeleeHitChances()
|
||||
{
|
||||
m_modMeleeHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
|
||||
m_modMeleeHitChance+= GetRatingBonusValue(CR_HIT_MELEE);
|
||||
}
|
||||
|
||||
void Player::UpdateRangedHitChances()
|
||||
{
|
||||
m_modRangedHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
|
||||
m_modRangedHitChance+= GetRatingBonusValue(CR_HIT_RANGED);
|
||||
}
|
||||
|
||||
void Player::UpdateSpellHitChances()
|
||||
{
|
||||
m_modSpellHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
|
||||
m_modSpellHitChance+= GetRatingBonusValue(CR_HIT_SPELL);
|
||||
}
|
||||
|
||||
void Player::UpdateAllSpellCritChances()
|
||||
{
|
||||
for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
|
||||
UpdateSpellCritChance(i);
|
||||
}
|
||||
|
||||
void Player::UpdateExpertise(WeaponAttackType attack)
|
||||
{
|
||||
if(attack==RANGED_ATTACK)
|
||||
return;
|
||||
|
||||
int32 expertise = int32(GetRatingBonusValue(CR_EXPERTISE));
|
||||
|
||||
Item *weapon = GetWeaponForAttack(attack);
|
||||
|
||||
AuraEffectList const& expAuras = GetAurasByType(SPELL_AURA_MOD_EXPERTISE);
|
||||
for(AuraEffectList::const_iterator itr = expAuras.begin(); itr != expAuras.end(); ++itr)
|
||||
{
|
||||
@@ -585,8 +675,10 @@ void Player::UpdateExpertise(WeaponAttackType attack)
|
||||
else if(weapon && weapon->IsFitToSpellRequirements((*itr)->GetSpellProto()))
|
||||
expertise += (*itr)->GetAmount();
|
||||
}
|
||||
|
||||
if(expertise < 0)
|
||||
expertise = 0;
|
||||
|
||||
switch(attack)
|
||||
{
|
||||
case BASE_ATTACK: SetUInt32Value(PLAYER_EXPERTISE, expertise); break;
|
||||
@@ -594,11 +686,13 @@ void Player::UpdateExpertise(WeaponAttackType attack)
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void Player::ApplyManaRegenBonus(int32 amount, bool apply)
|
||||
{
|
||||
m_baseManaRegen+= apply ? amount : -amount;
|
||||
UpdateManaRegen();
|
||||
}
|
||||
|
||||
void Player::UpdateManaRegen()
|
||||
{
|
||||
float Intellect = GetStat(STAT_INTELLECT);
|
||||
@@ -606,57 +700,76 @@ void Player::UpdateManaRegen()
|
||||
float power_regen = sqrt(Intellect) * OCTRegenMPPerSpirit();
|
||||
// Apply PCT bonus from SPELL_AURA_MOD_POWER_REGEN_PERCENT aura on spirit base regen
|
||||
power_regen *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, POWER_MANA);
|
||||
|
||||
// Mana regen from SPELL_AURA_MOD_POWER_REGEN aura
|
||||
float power_regen_mp5 = (GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) + m_baseManaRegen) / 5.0f;
|
||||
|
||||
// Get bonus from SPELL_AURA_MOD_MANA_REGEN_FROM_STAT aura
|
||||
AuraEffectList const& regenAura = GetAurasByType(SPELL_AURA_MOD_MANA_REGEN_FROM_STAT);
|
||||
for(AuraEffectList::const_iterator i = regenAura.begin();i != regenAura.end(); ++i)
|
||||
{
|
||||
power_regen_mp5 += GetStat(Stats((*i)->GetMiscValue())) * (*i)->GetAmount() / 500.0f;
|
||||
}
|
||||
|
||||
// Set regen rate in cast state apply only on spirit based regen
|
||||
int32 modManaRegenInterrupt = GetTotalAuraModifier(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT);
|
||||
if (modManaRegenInterrupt > 100)
|
||||
modManaRegenInterrupt = 100;
|
||||
SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER, power_regen_mp5 + power_regen * modManaRegenInterrupt / 100.0f);
|
||||
|
||||
SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER, power_regen_mp5 + power_regen);
|
||||
}
|
||||
|
||||
void Player::_ApplyAllStatBonuses()
|
||||
{
|
||||
SetCanModifyStats(false);
|
||||
|
||||
_ApplyAllAuraMods();
|
||||
_ApplyAllItemMods();
|
||||
|
||||
SetCanModifyStats(true);
|
||||
|
||||
UpdateAllStats();
|
||||
}
|
||||
|
||||
void Player::_RemoveAllStatBonuses()
|
||||
{
|
||||
SetCanModifyStats(false);
|
||||
|
||||
_RemoveAllItemMods();
|
||||
_RemoveAllAuraMods();
|
||||
|
||||
SetCanModifyStats(true);
|
||||
|
||||
UpdateAllStats();
|
||||
}
|
||||
|
||||
/*#######################################
|
||||
######## ########
|
||||
######## MOBS STAT SYSTEM ########
|
||||
######## ########
|
||||
#######################################*/
|
||||
|
||||
bool Creature::UpdateStats(Stats /*stat*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Creature::UpdateAllStats()
|
||||
{
|
||||
UpdateMaxHealth();
|
||||
UpdateAttackPowerAndDamage();
|
||||
UpdateAttackPowerAndDamage(true);
|
||||
|
||||
for(int i = POWER_MANA; i < MAX_POWERS; ++i)
|
||||
UpdateMaxPower(Powers(i));
|
||||
|
||||
for(int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
|
||||
UpdateResistances(i);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Creature::UpdateResistances(uint32 school)
|
||||
{
|
||||
if(school > SPELL_SCHOOL_NORMAL)
|
||||
@@ -667,40 +780,50 @@ void Creature::UpdateResistances(uint32 school)
|
||||
else
|
||||
UpdateArmor();
|
||||
}
|
||||
|
||||
void Creature::UpdateArmor()
|
||||
{
|
||||
float value = GetTotalAuraModValue(UNIT_MOD_ARMOR);
|
||||
SetArmor(int32(value));
|
||||
}
|
||||
|
||||
void Creature::UpdateMaxHealth()
|
||||
{
|
||||
float value = GetTotalAuraModValue(UNIT_MOD_HEALTH);
|
||||
SetMaxHealth((uint32)value);
|
||||
}
|
||||
|
||||
void Creature::UpdateMaxPower(Powers power)
|
||||
{
|
||||
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power);
|
||||
|
||||
float value = GetTotalAuraModValue(unitMod);
|
||||
SetMaxPower(power, uint32(value));
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if(ranged)
|
||||
{
|
||||
index = UNIT_FIELD_RANGED_ATTACK_POWER;
|
||||
index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS;
|
||||
index_mult = 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;
|
||||
|
||||
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
|
||||
|
||||
//automatically update weapon damage after attack power modification
|
||||
if(ranged)
|
||||
UpdateDamagePhysical(RANGED_ATTACK);
|
||||
@@ -710,6 +833,7 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged)
|
||||
UpdateDamagePhysical(OFF_ATTACK);
|
||||
}
|
||||
}
|
||||
|
||||
void Creature::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
{
|
||||
UnitMods unitMod;
|
||||
@@ -726,9 +850,12 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
unitMod = UNIT_MOD_DAMAGE_RANGED;
|
||||
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) - GetCreatureInfo()->attackpower;
|
||||
float base_value = GetModifierValue(unitMod, BASE_VALUE) + (att_pwr_change * GetAPMultiplier(attType, false) / 14.0f);
|
||||
@@ -736,13 +863,16 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
float total_value = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
float total_pct = GetModifierValue(unitMod, TOTAL_PCT);
|
||||
float dmg_multiplier = GetCreatureInfo()->dmg_multiplier;
|
||||
|
||||
if(!CanUseAttackType(attType))
|
||||
{
|
||||
weapon_mindamage = 0;
|
||||
weapon_maxdamage = 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
switch(attType)
|
||||
{
|
||||
case BASE_ATTACK:
|
||||
@@ -760,11 +890,13 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*#######################################
|
||||
######## ########
|
||||
######## PETS STAT SYSTEM ########
|
||||
######## ########
|
||||
#######################################*/
|
||||
|
||||
#define ENTRY_IMP 416
|
||||
#define ENTRY_VOIDWALKER 1860
|
||||
#define ENTRY_SUCCUBUS 1863
|
||||
@@ -773,12 +905,15 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
#define ENTRY_WATER_ELEMENTAL 510
|
||||
#define ENTRY_TREANT 1964
|
||||
#define ENTRY_FIRE_ELEMENTAL 15438
|
||||
|
||||
bool Guardian::UpdateStats(Stats stat)
|
||||
{
|
||||
if(stat > STAT_SPIRIT)
|
||||
return false;
|
||||
|
||||
// value = ((base_value * base_pct) + total_value) * total_pct
|
||||
float value = GetTotalStatValue(stat);
|
||||
|
||||
Unit *owner = GetOwner();
|
||||
if ( stat == STAT_STAMINA )
|
||||
{
|
||||
@@ -798,7 +933,9 @@ bool Guardian::UpdateStats(Stats stat)
|
||||
if (IsPetGhoul())
|
||||
value += float(owner->GetStat(stat)) * 0.3f;
|
||||
}
|
||||
|
||||
SetStat(stat, int32(value));
|
||||
|
||||
switch(stat)
|
||||
{
|
||||
case STAT_STRENGTH: UpdateAttackPowerAndDamage(); break;
|
||||
@@ -809,50 +946,64 @@ bool Guardian::UpdateStats(Stats stat)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Guardian::UpdateAllStats()
|
||||
{
|
||||
for (int i = STAT_STRENGTH; i < MAX_STATS; ++i)
|
||||
UpdateStats(Stats(i));
|
||||
|
||||
for(int i = POWER_MANA; i < MAX_POWERS; ++i)
|
||||
UpdateMaxPower(Powers(i));
|
||||
|
||||
for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
|
||||
UpdateResistances(i);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Guardian::UpdateResistances(uint32 school)
|
||||
{
|
||||
if(school > SPELL_SCHOOL_NORMAL)
|
||||
{
|
||||
float value = GetTotalAuraModValue(UnitMods(UNIT_MOD_RESISTANCE_START + school));
|
||||
|
||||
// hunter and warlock pets gain 40% of owner's resistance
|
||||
if(isPet())
|
||||
value += float(m_owner->GetResistance(SpellSchools(school))) * 0.4f;
|
||||
|
||||
SetResistance(SpellSchools(school), int32(value));
|
||||
}
|
||||
else
|
||||
UpdateArmor();
|
||||
}
|
||||
|
||||
void Guardian::UpdateArmor()
|
||||
{
|
||||
float value = 0.0f;
|
||||
float bonus_armor = 0.0f;
|
||||
UnitMods unitMod = UNIT_MOD_ARMOR;
|
||||
|
||||
// hunter and warlock pets gain 35% of owner's armor value
|
||||
if(isPet())
|
||||
bonus_armor = 0.35f * float(m_owner->GetArmor());
|
||||
|
||||
value = GetModifierValue(unitMod, BASE_VALUE);
|
||||
value *= GetModifierValue(unitMod, BASE_PCT);
|
||||
value += GetStat(STAT_AGILITY) * 2.0f;
|
||||
value += GetModifierValue(unitMod, TOTAL_VALUE) + bonus_armor;
|
||||
value *= GetModifierValue(unitMod, TOTAL_PCT);
|
||||
|
||||
SetArmor(int32(value));
|
||||
}
|
||||
|
||||
void Guardian::UpdateMaxHealth()
|
||||
{
|
||||
UnitMods unitMod = UNIT_MOD_HEALTH;
|
||||
float stamina = GetStat(STAT_STAMINA) - GetCreateStat(STAT_STAMINA);
|
||||
|
||||
float multiplicator;
|
||||
switch(GetEntry())
|
||||
{
|
||||
@@ -863,17 +1014,22 @@ void Guardian::UpdateMaxHealth()
|
||||
case ENTRY_FELGUARD: multiplicator = 11.0f; break;
|
||||
default: multiplicator = 10.0f; break;
|
||||
}
|
||||
|
||||
float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreateHealth();
|
||||
value *= GetModifierValue(unitMod, BASE_PCT);
|
||||
value += GetModifierValue(unitMod, TOTAL_VALUE) + stamina * multiplicator;
|
||||
value *= GetModifierValue(unitMod, TOTAL_PCT);
|
||||
|
||||
SetMaxHealth((uint32)value);
|
||||
}
|
||||
|
||||
void Guardian::UpdateMaxPower(Powers power)
|
||||
{
|
||||
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power);
|
||||
|
||||
float addValue = (power == POWER_MANA) ? GetStat(STAT_INTELLECT) - GetCreateStat(STAT_INTELLECT) : 0.0f;
|
||||
float multiplicator = 15.0f;
|
||||
|
||||
switch(GetEntry())
|
||||
{
|
||||
case ENTRY_IMP: multiplicator = 4.95f; break;
|
||||
@@ -883,23 +1039,29 @@ void Guardian::UpdateMaxPower(Powers power)
|
||||
case ENTRY_FELGUARD: multiplicator = 11.5f; break;
|
||||
default: multiplicator = 15.0f; break;
|
||||
}
|
||||
|
||||
float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power);
|
||||
value *= GetModifierValue(unitMod, BASE_PCT);
|
||||
value += GetModifierValue(unitMod, TOTAL_VALUE) + addValue * multiplicator;
|
||||
value *= GetModifierValue(unitMod, TOTAL_PCT);
|
||||
|
||||
SetMaxPower(power, uint32(value));
|
||||
}
|
||||
|
||||
void Guardian::UpdateAttackPowerAndDamage(bool ranged)
|
||||
{
|
||||
if(ranged)
|
||||
return;
|
||||
|
||||
float val = 0.0f;
|
||||
float bonusAP = 0.0f;
|
||||
UnitMods unitMod = UNIT_MOD_ATTACK_POWER;
|
||||
|
||||
if(GetEntry() == ENTRY_IMP) // imp's attack power
|
||||
val = GetStat(STAT_STRENGTH) - 10.0f;
|
||||
else
|
||||
val = 2 * GetStat(STAT_STRENGTH) - 20.0f;
|
||||
|
||||
Unit* owner = GetOwner();
|
||||
if( owner && owner->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
@@ -933,24 +1095,30 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged)
|
||||
SetBonusDamage( int32(frost * 0.4f));
|
||||
}
|
||||
}
|
||||
|
||||
SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, val + bonusAP);
|
||||
|
||||
//in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB
|
||||
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;
|
||||
|
||||
//UNIT_FIELD_(RANGED)_ATTACK_POWER field
|
||||
SetInt32Value(UNIT_FIELD_ATTACK_POWER, (int32)base_attPower);
|
||||
//UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field
|
||||
SetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, (int32)attPowerMod);
|
||||
//UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field
|
||||
SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, attPowerMultiplier);
|
||||
|
||||
//automatically update weapon damage after attack power modification
|
||||
UpdateDamagePhysical(BASE_ATTACK);
|
||||
}
|
||||
|
||||
void Guardian::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
{
|
||||
if(attType > BASE_ATTACK)
|
||||
return;
|
||||
|
||||
float bonusDamage = 0.0f;
|
||||
if(m_owner->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
@@ -969,16 +1137,22 @@ void Guardian::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
bonusDamage = spellDmg * 0.4f;
|
||||
}
|
||||
}
|
||||
|
||||
UnitMods unitMod = UNIT_MOD_DAMAGE_MAINHAND;
|
||||
|
||||
float att_speed = float(GetAttackTime(BASE_ATTACK))/1000.0f;
|
||||
|
||||
float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed + bonusDamage;
|
||||
float base_pct = GetModifierValue(unitMod, BASE_PCT);
|
||||
float total_value = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
float total_pct = GetModifierValue(unitMod, TOTAL_PCT);
|
||||
|
||||
float weapon_mindamage = GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE);
|
||||
float weapon_maxdamage = GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE);
|
||||
|
||||
float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct;
|
||||
float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct;
|
||||
|
||||
// Pet's base damage changes depending on happiness
|
||||
if (isHunterPet() && attType == BASE_ATTACK)
|
||||
{
|
||||
@@ -999,6 +1173,7 @@ void Guardian::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SetStatFloatValue(UNIT_FIELD_MINDAMAGE, mindamage);
|
||||
SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxdamage);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user