Implement 220 SPELL_AURA_MOD_RATING_FROM_STAT aura

Recalculate Melee/Ranged/Spell Hit Chances (not apply/remove) for players

Signed-off-by: DiSlord <dislord@nomail.com>
This commit is contained in:
DiSlord 2008-12-21 05:07:16 +03:00
parent d1a776f41a
commit 18eeaa85dd
5 changed files with 92 additions and 18 deletions

View file

@ -411,6 +411,9 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this)
m_auraBaseMod[i][PCT_MOD] = 1.0f;
}
for (int i = 0; i < MAX_COMBAT_RATING; i++)
m_baseRatingValue[i] = 0;
// Honor System
m_lastHonorUpdateTime = time(NULL);
@ -4541,7 +4544,18 @@ float Player::OCTRegenMPPerSpirit()
void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply)
{
ApplyModUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, value, apply);
m_baseRatingValue[cr]+=(apply ? value : -value);
int32 amount = uint32(m_baseRatingValue[cr]);
// Apply bonus from SPELL_AURA_MOD_RATING_FROM_STAT
// stat used stored in miscValueB for this aura
AuraList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT);
for(AuraList::const_iterator i = modRatingFromStat.begin();i != modRatingFromStat.end(); ++i)
if ((*i)->GetMiscValue() & (1<<cr))
amount += GetStat(Stats((*i)->GetMiscBValue())) * (*i)->GetModifier()->m_amount / 100.0f;
if (amount < 0)
amount = 0;
SetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, uint32(amount));
float RatingCoeffecient = GetRatingCoefficient(cr);
float RatingChange = 0.0f;
@ -4564,16 +4578,13 @@ void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply)
UpdateBlockPercentage();
break;
case CR_HIT_MELEE:
RatingChange = value / RatingCoeffecient;
m_modMeleeHitChance += apply ? RatingChange : -RatingChange;
UpdateMeleeHitChances();
break;
case CR_HIT_RANGED:
RatingChange = value / RatingCoeffecient;
m_modRangedHitChance += apply ? RatingChange : -RatingChange;
UpdateRangedHitChances();
break;
case CR_HIT_SPELL:
RatingChange = value / RatingCoeffecient;
m_modSpellHitChance += apply ? RatingChange : -RatingChange;
UpdateSpellHitChances();
break;
case CR_CRIT_MELEE:
if(affectStats)

View file

@ -1650,6 +1650,10 @@ class MANGOS_DLL_SPEC Player : public Unit
void UpdateAllCritPercentages();
void UpdateParryPercentage();
void UpdateDodgePercentage();
void UpdateMeleeHitChances();
void UpdateRangedHitChances();
void UpdateSpellHitChances();
void UpdateAllSpellCritChances();
void UpdateSpellCritChance(uint32 school);
void UpdateExpertise(WeaponAttackType attType);
@ -2287,6 +2291,7 @@ class MANGOS_DLL_SPEC Player : public Unit
ActionButtonList m_actionButtons;
float m_auraBaseMod[BASEMOD_END][MOD_END];
int16 m_baseRatingValue[MAX_COMBAT_RATING];
SpellModList m_spellMods[MAX_SPELLMOD];
int32 m_SpellModRemoveCount;

View file

@ -270,7 +270,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleUnused, //217 unused
&Aura::HandleAuraModRangedHaste, //218 SPELL_AURA_HASTE_RANGED
&Aura::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT
&Aura::HandleNULL, //220 SPELL_AURA_MOD_RATING_FROM_STAT
&Aura::HandleModRatingFromStat, //220 SPELL_AURA_MOD_RATING_FROM_STAT
&Aura::HandleNULL, //221 ignored
&Aura::HandleUnused, //222 unused
&Aura::HandleNULL, //223 Cold Stare
@ -4883,13 +4883,28 @@ void Aura::HandleAuraModCritPercent(bool apply, bool Real)
void Aura::HandleModHitChance(bool apply, bool Real)
{
m_target->m_modMeleeHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount);
m_target->m_modRangedHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount);
if(m_target->GetTypeId() == TYPEID_PLAYER)
{
((Player*)m_target)->UpdateMeleeHitChances();
((Player*)m_target)->UpdateRangedHitChances();
}
else
{
m_target->m_modMeleeHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount);
m_target->m_modRangedHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount);
}
}
void Aura::HandleModSpellHitChance(bool apply, bool Real)
{
m_target->m_modSpellHitChance += apply ? m_modifier.m_amount: (-m_modifier.m_amount);
if(m_target->GetTypeId() == TYPEID_PLAYER)
{
((Player*)m_target)->UpdateSpellHitChances();
}
else
{
m_target->m_modSpellHitChance += apply ? m_modifier.m_amount: (-m_modifier.m_amount);
}
}
void Aura::HandleModSpellCritChance(bool apply, bool Real)
@ -5455,6 +5470,20 @@ void Aura::HandleModRating(bool apply, bool Real)
((Player*)m_target)->ApplyRatingMod(CombatRating(rating), m_modifier.m_amount, apply);
}
void Aura::HandleModRatingFromStat(bool apply, bool Real)
{
// spells required only Real aura add/remove
if(!Real)
return;
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
// Just recalculate ratings
for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
if (m_modifier.m_miscvalue & (1 << rating))
((Player*)m_target)->ApplyRatingMod(CombatRating(rating), 0, apply);
}
void Aura::HandleForceMoveForward(bool apply, bool Real)
{
if(!Real || m_target->GetTypeId() != TYPEID_PLAYER)

View file

@ -183,6 +183,7 @@ class MANGOS_DLL_SPEC Aura
void HandleAuraGhost(bool Apply, bool Real);
void HandleAuraAllowFlight(bool Apply, bool Real);
void HandleModRating(bool apply, bool Real);
void HandleModRatingFromStat(bool apply, bool Real);
void HandleModTargetResistance(bool apply, bool Real);
void HandleAuraModAttackPowerPercent(bool apply, bool Real);
void HandleAuraModRangedAttackPowerPercent(bool apply, bool Real);

View file

@ -49,24 +49,17 @@ bool Player::UpdateStats(Stats stat)
switch(stat)
{
case STAT_STRENGTH:
UpdateAttackPowerAndDamage();
UpdateShieldBlockValue();
break;
case STAT_AGILITY:
UpdateArmor();
UpdateAttackPowerAndDamage(true);
if(getClass() == CLASS_ROGUE || getClass() == CLASS_HUNTER || getClass() == CLASS_DRUID && m_form==FORM_CAT)
UpdateAttackPowerAndDamage();
UpdateAllCritPercentages();
UpdateDodgePercentage();
break;
case STAT_STAMINA: UpdateMaxHealth(); break;
case STAT_INTELLECT:
UpdateMaxPower(POWER_MANA);
UpdateAllSpellCritChances();
UpdateAttackPowerAndDamage(true); //SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT, only intelect currently
UpdateArmor(); //SPELL_AURA_MOD_RESISTANCE_OF_INTELLECT_PERCENT, only armor currently
break;
@ -76,8 +69,25 @@ bool Player::UpdateStats(Stats stat)
default:
break;
}
// Need update (exist AP from stat auras)
UpdateAttackPowerAndDamage();
UpdateAttackPowerAndDamage(true);
UpdateSpellDamageAndHealingBonus();
UpdateManaRegen();
// Update ratings in exist SPELL_AURA_MOD_RATING_FROM_STAT and only depends from stat
uint32 mask = 0;
AuraList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT);
for(AuraList::const_iterator i = modRatingFromStat.begin();i != modRatingFromStat.end(); ++i)
if (Stats((*i)->GetMiscBValue()) == stat)
mask |= (*i)->GetMiscValue();
if (mask)
{
for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
if (mask & (1 << rating))
ApplyRatingMod(CombatRating(rating), 0, true);
}
return true;
}
@ -560,6 +570,24 @@ void Player::UpdateSpellCritChance(uint32 school)
SetFloatValue(PLAYER_SPELL_CRIT_PERCENTAGE1 + school, crit);
}
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++)