Index: src/game/Player.h =================================================================== --- src/game/Player.h (revision 5136) +++ src/game/Player.h (working copy) @@ -1317,7 +1317,7 @@ int32 GetTotalFlatMods(uint32 spellId, uint8 op); int32 GetTotalPctMods(uint32 spellId, uint8 op); bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod); - template T ApplySpellMod(uint32 spellId, uint8 op, T &basevalue, unsigned int only_type = 0); + template T ApplySpellMod(uint32 spellId, uint8 op, T &basevalue); void RemoveSpellMods(uint32 spellId); bool HasSpellCooldown(uint32 spell_id) const @@ -2053,7 +2053,7 @@ void RemoveItemsSetItem(Player*player,ItemPrototype const *proto); // "the bodies of template functions must be made available in a header file" -template T Player::ApplySpellMod(uint32 spellId, uint8 op, T &basevalue, unsigned int only_type) +template T Player::ApplySpellMod(uint32 spellId, uint8 op, T &basevalue) { SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); if (!spellInfo) return 0; @@ -2063,10 +2063,6 @@ { SpellModifier *mod = *itr; - // skip other mod types - if(only_type && (unsigned int)mod->type != only_type) - continue; - if(!IsAffectedBySpellmod(spellInfo,mod)) continue; if (mod->type == SPELLMOD_FLAT) Index: src/game/SpellEffects.cpp =================================================================== --- src/game/SpellEffects.cpp (revision 5136) +++ src/game/SpellEffects.cpp (working copy) @@ -3184,9 +3184,24 @@ //if miss/parry, no eff=0 automatically by func DoAttackDamage //if crit eff = (bonus + weapon) * 2 //In a word, bonus + weapon will be calculated together in cases of miss, armor reduce, crit, etc. - uint32 eff_damage = 0; - m_caster->DoAttackDamage(unitTarget, bonus, damagePercentMod, &eff_damage, &cleanDamage, &blocked_dmg, damageType, &hitInfo, &victimState, &absorbed_dmg, &resisted_dmg, attType, m_spellInfo, m_IsTriggeredSpell); + bonus += m_caster->CalculateDamage (attType); + // Whirlwind, single only spell with 2 weapon white damage apply if have + if(m_caster->GetTypeId()==TYPEID_PLAYER && m_spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && (m_spellInfo->SpellFamilyFlags & 0x00000400000000LL)) + { + Item* item = ((Player*)m_caster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); + if (item && item->GetProto()->Class == ITEM_CLASS_WEAPON && !item->IsBroken() && ((Player*)m_caster)->IsUseEquipedWeapon(false)) + bonus += m_caster->CalculateDamage (OFF_ATTACK); + } + + // percent mod applied + bonus = int32(bonus *damagePercentMod); + + // prevent negative damage + uint32 eff_damage = uint32(bonus > 0 ? bonus : 0); + + m_caster->DoAttackDamage(unitTarget, &eff_damage, &cleanDamage, &blocked_dmg, damageType, &hitInfo, &victimState, &absorbed_dmg, &resisted_dmg, attType, m_spellInfo, m_IsTriggeredSpell); + if ((hitInfo & nohitMask) && attType != RANGED_ATTACK) // not send ranged miss/etc m_caster->SendAttackStateUpdate(hitInfo & nohitMask, unitTarget, 1, SpellSchools(m_spellInfo->School), eff_damage, absorbed_dmg, resisted_dmg, VICTIMSTATE_NORMAL, blocked_dmg); Index: src/game/Unit.cpp =================================================================== --- src/game/Unit.cpp (revision 5136) +++ src/game/Unit.cpp (working copy) @@ -1879,7 +1879,7 @@ *absorb = damage - RemainingDamage - *resist; } -void Unit::DoAttackDamage (Unit *pVictim, int32 init_damage, float damagePercentMod, uint32 *damage, CleanDamage *cleanDamage, uint32 *blocked_amount, SpellSchools damageType, uint32 *hitInfo, VictimState *victimState, uint32 *absorbDamage, uint32 *resistDamage, WeaponAttackType attType, SpellEntry const *spellCasted, bool isTriggeredSpell) +void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDamage, uint32 *blocked_amount, SpellSchools damageType, uint32 *hitInfo, VictimState *victimState, uint32 *absorbDamage, uint32 *resistDamage, WeaponAttackType attType, SpellEntry const *spellCasted, bool isTriggeredSpell) { bool unavoidable = spellCasted && (spellCasted->Attributes & 0x200000); @@ -1935,41 +1935,6 @@ CastSpell(pVictim, 1604, true); } - int32 white_damage = CalculateDamage (attType); - - if(spellCasted) - { - // single only spell with 2 weapon white damage apply if have - if(GetTypeId()==TYPEID_PLAYER && spellCasted->SpellFamilyName == SPELLFAMILY_WARRIOR && (spellCasted->SpellFamilyFlags & 0x00000400000000LL)) - { - Item* item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); - if (item && item->GetProto()->Class == ITEM_CLASS_WEAPON && !item->IsBroken() && ((Player*)this)->IsUseEquipedWeapon(false)) - white_damage += CalculateDamage (OFF_ATTACK); - } - - //apply spellmod also to the weapon damage, *damage already have applied mod - if(Player* modOwner = GetSpellModOwner()) - { - // SPELLMOD_FLAT already applied in Spell::EffectWeaponDmg - modOwner->ApplySpellMod(spellCasted->Id, SPELLMOD_DAMAGE, white_damage, SPELLMOD_PCT); - } - } - - // calculate full damage (init_damage can be negative) - { - // full original damage - int32 temp_damage = init_damage + white_damage; - - // percent mod applied - temp_damage = int32(temp_damage *damagePercentMod); - - // prevent negative damage - if(temp_damage < 0) - temp_damage = 0; - - *damage = uint32(temp_damage); - } - //Calculate the damage after armor mitigation if SPELL_SCHOOL_NORMAL if (damageType == SPELL_SCHOOL_NORMAL) { @@ -2239,7 +2204,7 @@ // apply melee damage bonus and absorb only if base damage not fully blocked to prevent negative damage or damage with full block if(*victimState != VICTIMSTATE_BLOCKS) { - MeleeDamageBonus(pVictim, damage,attType); + MeleeDamageBonus(pVictim, damage,attType,spellCasted); CalcAbsorbResist(pVictim, damageType, DIRECT_DAMAGE, *damage-*blocked_amount, absorbDamage, resistDamage); } @@ -2369,7 +2334,6 @@ VictimState victimState = VICTIMSTATE_NORMAL; - uint32 damage = 0; CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL ); uint32 blocked_dmg = 0; uint32 absorbed_dmg = 0; @@ -2383,8 +2347,10 @@ return; } - DoAttackDamage (pVictim, 0, 1.0f, &damage, &cleanDamage, &blocked_dmg, meleeSchool, &hitInfo, &victimState, &absorbed_dmg, &resisted_dmg, attType); + uint32 damage = CalculateDamage (attType); + DoAttackDamage (pVictim, &damage, &cleanDamage, &blocked_dmg, meleeSchool, &hitInfo, &victimState, &absorbed_dmg, &resisted_dmg, attType); + if (hitInfo & HITINFO_MISS) //send miss SendAttackStateUpdate (hitInfo, pVictim, 1, meleeSchool, damage, absorbed_dmg, resisted_dmg, victimState, blocked_dmg); @@ -5945,6 +5911,11 @@ float TakenActualBenefit = TakenAdvertisedBenefit * (CastingTime / 3500.0f) * (100.0f - LvlPenalty) * LvlFactor * DotFactor / 100.0f; float tmpDamage = (float(pdamage)+DoneActualBenefit)*DoneTotalMod; + + // apply spellmod to Done damage + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, tmpDamage); + tmpDamage = (tmpDamage+TakenActualBenefit)*TakenTotalMod; if( GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet() ) @@ -6126,6 +6097,10 @@ for(AuraList::const_iterator i = mHealingDonePct.begin();i != mHealingDonePct.end(); ++i) heal *= (100.0f + (*i)->GetModifier()->m_amount) / 100.0f; + // apply spellmod to Done amount + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, heal); + // Healing taken percent AuraList const& mHealingPct = pVictim->GetAurasByType(SPELL_AURA_MOD_HEALING_PCT); for(AuraList::const_iterator i = mHealingPct.begin();i != mHealingPct.end(); ++i) @@ -6237,7 +6212,7 @@ return false; } -void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attType) +void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attType, SpellEntry const *spellProto) { if(!pVictim) return; @@ -6347,8 +6322,17 @@ TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; } - float tmpDamage = ((int32(*pdamage) + DoneFlatBenefit) + TakenFlatBenefit)*TakenTotalMod; + float tmpDamage = float(int32(*pdamage) + DoneFlatBenefit); + // apply spellmod to Done damage + if(spellProto) + { + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, tmpDamage); + } + + tmpDamage = (tmpDamage + TakenFlatBenefit)*TakenTotalMod; + // bonus result can be negative *pdamage = tmpDamage > 0 ? uint32(tmpDamage) : 0; } @@ -7295,8 +7279,6 @@ spellProto->EffectApplyAuraName[effect_index] == SPELL_AURA_PERIODIC_HEAL || spellProto->EffectApplyAuraName[effect_index] == SPELL_AURA_PERIODIC_LEECH) ) modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DOT, value); - - modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, value); } return value; @@ -8463,4 +8445,4 @@ ApplyPercentModFloatValue(UNIT_MOD_CAST_SPEED,val,!apply); else ApplyPercentModFloatValue(UNIT_MOD_CAST_SPEED,-val,apply); -} \ No newline at end of file +} Index: src/game/Unit.h =================================================================== --- src/game/Unit.h (revision 5136) +++ src/game/Unit.h (working copy) @@ -674,7 +674,7 @@ uint16 GetMaxSkillValueForLevel() const { return getLevel()*5; } void DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchools damageSchool, SpellEntry const *spellProto, bool durabilityLoss); void DealDamageBySchool(Unit *pVictim, SpellEntry const *spellInfo, uint32 *damage, CleanDamage *cleanDamage, bool *crit = false, bool isTriggeredSpell = false); - void DoAttackDamage(Unit *pVictim, int32 init_damage, float damagePercentMod, uint32 *damage, CleanDamage *cleanDamage, uint32 *blocked_amount, SpellSchools damageType, uint32 *hitInfo, VictimState *victimState, uint32 *absorbDamage, uint32 *resistDamage, WeaponAttackType attType, SpellEntry const *spellCasted = NULL, bool isTriggeredSpell = false); + void DoAttackDamage(Unit *pVictim, uint32 *damage, CleanDamage *cleanDamage, uint32 *blocked_amount, SpellSchools damageType, uint32 *hitInfo, VictimState *victimState, uint32 *absorbDamage, uint32 *resistDamage, WeaponAttackType attType, SpellEntry const *spellCasted = NULL, bool isTriggeredSpell = false); void CastMeleeProcDamageAndSpell(Unit* pVictim, uint32 damage, WeaponAttackType attType, MeleeHitOutcome outcome, SpellEntry const *spellCasted = NULL, bool isTriggeredSpell = false); void ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 damage = 0, SpellEntry const *procSpell = NULL, bool isTriggeredSpell = false, WeaponAttackType attType = BASE_ATTACK); @@ -956,7 +956,7 @@ uint32 SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 damage, DamageEffectType damagetype); uint32 SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, Unit *pVictim); bool SpellCriticalBonus(SpellEntry const *spellProto, uint32 *damage, Unit *pVictim); - void MeleeDamageBonus(Unit *pVictim, uint32 *damage, WeaponAttackType attType); + void MeleeDamageBonus(Unit *pVictim, uint32 *damage, WeaponAttackType attType, SpellEntry const *spellProto = NULL); void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply); virtual bool IsImmunedToSpell(SpellEntry const* spellInfo) const; // redefined in Creature