[8978] Fix wrongly apply weapon damage mods to broken weapon.

This commit is contained in:
VladimirMangos 2009-12-12 20:39:04 +03:00
parent f47492ad24
commit 1d608c482f
7 changed files with 42 additions and 38 deletions

View file

@ -5015,8 +5015,8 @@ void Player::SetRegularAttackTime()
{ {
for(int i = 0; i < MAX_ATTACK; ++i) for(int i = 0; i < MAX_ATTACK; ++i)
{ {
Item *tmpitem = GetWeaponForAttack(WeaponAttackType(i)); Item *tmpitem = GetWeaponForAttack(WeaponAttackType(i),true,false);
if(tmpitem && !tmpitem->IsBroken()) if (tmpitem)
{ {
ItemPrototype const *proto = tmpitem->GetProto(); ItemPrototype const *proto = tmpitem->GetProto();
if(proto->Delay) if(proto->Delay)
@ -5222,7 +5222,7 @@ void Player::UpdateWeaponSkill (WeaponAttackType attType)
{ {
case BASE_ATTACK: case BASE_ATTACK:
{ {
Item *tmpitem = GetWeaponForAttack(attType,true); Item *tmpitem = GetWeaponForAttack(attType,true,true);
if (!tmpitem) if (!tmpitem)
UpdateSkill(SKILL_UNARMED,weapon_skill_gain); UpdateSkill(SKILL_UNARMED,weapon_skill_gain);
@ -5233,7 +5233,7 @@ void Player::UpdateWeaponSkill (WeaponAttackType attType)
case OFF_ATTACK: case OFF_ATTACK:
case RANGED_ATTACK: case RANGED_ATTACK:
{ {
Item *tmpitem = GetWeaponForAttack(attType,true); Item *tmpitem = GetWeaponForAttack(attType,true,true);
if (tmpitem) if (tmpitem)
UpdateSkill(tmpitem->GetSkill(),weapon_skill_gain); UpdateSkill(tmpitem->GetSkill(),weapon_skill_gain);
break; break;
@ -6532,6 +6532,9 @@ void Player::_ApplyItemMods(Item *item, uint8 slot,bool apply)
if(slot >= INVENTORY_SLOT_BAG_END || !item) if(slot >= INVENTORY_SLOT_BAG_END || !item)
return; return;
UpdateExpertise(BASE_ATTACK);
UpdateArmorPenetration();
// not apply/remove mods for broken item // not apply/remove mods for broken item
if(item->IsBroken()) if(item->IsBroken())
return; return;
@ -7041,8 +7044,8 @@ void Player::UpdateEquipSpellsAtFormChange()
void Player::CastItemCombatSpell(Unit* Target, WeaponAttackType attType) void Player::CastItemCombatSpell(Unit* Target, WeaponAttackType attType)
{ {
Item *item = GetWeaponForAttack(attType, false); Item *item = GetWeaponForAttack(attType, true, false);
if(!item || item->IsBroken()) if(!item)
return; return;
ItemPrototype const *proto = item->GetProto(); ItemPrototype const *proto = item->GetProto();
@ -7362,8 +7365,8 @@ bool Player::CheckAmmoCompatibility(const ItemPrototype *ammo_proto) const
return false; return false;
// check ranged weapon // check ranged weapon
Item *weapon = GetWeaponForAttack( RANGED_ATTACK ); Item *weapon = GetWeaponForAttack( RANGED_ATTACK, true, false );
if(!weapon || weapon->IsBroken() ) if (!weapon)
return false; return false;
ItemPrototype const* weapon_proto = weapon->GetProto(); ItemPrototype const* weapon_proto = weapon->GetProto();
@ -8180,14 +8183,14 @@ void Player::SetSheath( SheathState sheathed )
break; break;
case SHEATH_STATE_MELEE: // prepared melee weapon case SHEATH_STATE_MELEE: // prepared melee weapon
{ {
SetVirtualItemSlot(0,GetWeaponForAttack(BASE_ATTACK,true)); SetVirtualItemSlot(0,GetWeaponForAttack(BASE_ATTACK,true,true));
SetVirtualItemSlot(1,GetWeaponForAttack(OFF_ATTACK,true)); SetVirtualItemSlot(1,GetWeaponForAttack(OFF_ATTACK,true,true));
SetVirtualItemSlot(2,NULL); SetVirtualItemSlot(2,NULL);
}; break; }; break;
case SHEATH_STATE_RANGED: // prepared ranged weapon case SHEATH_STATE_RANGED: // prepared ranged weapon
SetVirtualItemSlot(0,NULL); SetVirtualItemSlot(0,NULL);
SetVirtualItemSlot(1,NULL); SetVirtualItemSlot(1,NULL);
SetVirtualItemSlot(2,GetWeaponForAttack(RANGED_ATTACK,true)); SetVirtualItemSlot(2,GetWeaponForAttack(RANGED_ATTACK,true,true));
break; break;
default: default:
SetVirtualItemSlot(0,NULL); SetVirtualItemSlot(0,NULL);
@ -8558,7 +8561,7 @@ Item* Player::GetItemByPos( uint8 bag, uint8 slot ) const
return NULL; return NULL;
} }
Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool useable) const Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool nonbroken, bool useable) const
{ {
uint16 slot; uint16 slot;
switch (attackType) switch (attackType)
@ -8573,10 +8576,10 @@ Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool useable) cons
if (!item || item->GetProto()->Class != ITEM_CLASS_WEAPON) if (!item || item->GetProto()->Class != ITEM_CLASS_WEAPON)
return NULL; return NULL;
if(!useable) if (useable && !IsUseEquipedWeapon(attackType==BASE_ATTACK))
return item; return NULL;
if( item->IsBroken() || !IsUseEquipedWeapon(attackType==BASE_ATTACK) ) if (nonbroken && item->IsBroken())
return NULL; return NULL;
return item; return item;
@ -19644,7 +19647,7 @@ bool Player::IsAtGroupRewardDistance(WorldObject const* pRewardSource) const
uint32 Player::GetBaseWeaponSkillValue (WeaponAttackType attType) const uint32 Player::GetBaseWeaponSkillValue (WeaponAttackType attType) const
{ {
Item* item = GetWeaponForAttack(attType,true); Item* item = GetWeaponForAttack(attType,true,true);
// unarmed only with base attack // unarmed only with base attack
if(attType != BASE_ATTACK && !item) if(attType != BASE_ATTACK && !item)

View file

@ -1162,7 +1162,8 @@ class MANGOS_DLL_SPEC Player : public Unit
Item* GetItemByGuid( uint64 guid ) const; Item* GetItemByGuid( uint64 guid ) const;
Item* GetItemByPos( uint16 pos ) const; Item* GetItemByPos( uint16 pos ) const;
Item* GetItemByPos( uint8 bag, uint8 slot ) const; Item* GetItemByPos( uint8 bag, uint8 slot ) const;
Item* GetWeaponForAttack(WeaponAttackType attackType, bool useable = false) const; Item* GetWeaponForAttack(WeaponAttackType attackType) const { return GetWeaponForAttack(attackType,false,false); }
Item* GetWeaponForAttack(WeaponAttackType attackType, bool nonbroken, bool useable) const;
Item* GetShield(bool useable = false) const; Item* GetShield(bool useable = false) const;
static uint32 GetAttackBySlot( uint8 slot ); // MAX_ATTACK if not weapon slot static uint32 GetAttackBySlot( uint8 slot ); // MAX_ATTACK if not weapon slot
std::vector<Item *> &GetItemUpdateQueue() { return m_itemUpdateQueue; } std::vector<Item *> &GetItemUpdateQueue() { return m_itemUpdateQueue; }

View file

@ -5563,8 +5563,8 @@ SpellCastResult Spell::CheckItems()
if(m_caster->GetTypeId() != TYPEID_PLAYER) return SPELL_FAILED_TARGET_NOT_PLAYER; if(m_caster->GetTypeId() != TYPEID_PLAYER) return SPELL_FAILED_TARGET_NOT_PLAYER;
if( m_attackType != RANGED_ATTACK ) if( m_attackType != RANGED_ATTACK )
break; break;
Item *pItem = ((Player*)m_caster)->GetWeaponForAttack(m_attackType); Item *pItem = ((Player*)m_caster)->GetWeaponForAttack(m_attackType,true,false);
if(!pItem || pItem->IsBroken()) if (!pItem)
return SPELL_FAILED_EQUIPPED_ITEM; return SPELL_FAILED_EQUIPPED_ITEM;
switch(pItem->GetProto()->SubClass) switch(pItem->GetProto()->SubClass)

View file

@ -5295,7 +5295,7 @@ void Aura::HandleAuraModCritPercent(bool apply, bool Real)
if(Real) if(Real)
{ {
for(int i = 0; i < MAX_ATTACK; ++i) for(int i = 0; i < MAX_ATTACK; ++i)
if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i))) if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i),true,false))
((Player*)m_target)->_ApplyWeaponDependentAuraCritMod(pItem, WeaponAttackType(i), this, apply); ((Player*)m_target)->_ApplyWeaponDependentAuraCritMod(pItem, WeaponAttackType(i), this, apply);
} }
@ -5495,7 +5495,7 @@ void Aura::HandleModDamageDone(bool apply, bool Real)
if(Real && m_target->GetTypeId() == TYPEID_PLAYER) if(Real && m_target->GetTypeId() == TYPEID_PLAYER)
{ {
for(int i = 0; i < MAX_ATTACK; ++i) for(int i = 0; i < MAX_ATTACK; ++i)
if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i))) if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i),true,false))
((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem, WeaponAttackType(i), this, apply); ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem, WeaponAttackType(i), this, apply);
} }
@ -5578,7 +5578,7 @@ void Aura::HandleModDamagePercentDone(bool apply, bool Real)
if(Real && m_target->GetTypeId() == TYPEID_PLAYER) if(Real && m_target->GetTypeId() == TYPEID_PLAYER)
{ {
for(int i = 0; i < MAX_ATTACK; ++i) for(int i = 0; i < MAX_ATTACK; ++i)
if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i))) if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i),true,false))
((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem, WeaponAttackType(i), this, apply); ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem, WeaponAttackType(i), this, apply);
} }

View file

@ -2223,10 +2223,10 @@ void Spell::EffectTriggerSpell(uint32 effIndex)
// main hand weapon required // main hand weapon required
if (spellInfo->AttributesEx3 & SPELL_ATTR_EX3_MAIN_HAND) if (spellInfo->AttributesEx3 & SPELL_ATTR_EX3_MAIN_HAND)
{ {
Item* item = ((Player*)m_caster)->GetWeaponForAttack(BASE_ATTACK); Item* item = ((Player*)m_caster)->GetWeaponForAttack(BASE_ATTACK, true, false);
// skip spell if no weapon in slot or broken // skip spell if no weapon in slot or broken
if (!item || item->IsBroken() ) if (!item)
return; return;
// skip spell if weapon not fit to triggered spell // skip spell if weapon not fit to triggered spell
@ -2237,10 +2237,10 @@ void Spell::EffectTriggerSpell(uint32 effIndex)
// offhand hand weapon required // offhand hand weapon required
if (spellInfo->AttributesEx3 & SPELL_ATTR_EX3_REQ_OFFHAND) if (spellInfo->AttributesEx3 & SPELL_ATTR_EX3_REQ_OFFHAND)
{ {
Item* item = ((Player*)m_caster)->GetWeaponForAttack(OFF_ATTACK); Item* item = ((Player*)m_caster)->GetWeaponForAttack(OFF_ATTACK, true, false);
// skip spell if no weapon in slot or broken // skip spell if no weapon in slot or broken
if (!item || item->IsBroken() ) if (!item)
return; return;
// skip spell if weapon not fit to triggered spell // skip spell if weapon not fit to triggered spell
@ -4586,7 +4586,7 @@ void Spell::EffectWeaponDmg(uint32 i)
// Whirlwind, single only spell with 2 weapon white damage apply if have // Whirlwind, single only spell with 2 weapon white damage apply if have
if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x00000400000000))) if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x00000400000000)))
{ {
if(((Player*)m_caster)->GetWeaponForAttack(OFF_ATTACK,true)) if(((Player*)m_caster)->GetWeaponForAttack(OFF_ATTACK, true, true))
spell_bonus += m_caster->CalculateDamage (OFF_ATTACK, normalized); spell_bonus += m_caster->CalculateDamage (OFF_ATTACK, normalized);
} }
// Devastate bonus and sunder armor refresh // Devastate bonus and sunder armor refresh
@ -4646,7 +4646,7 @@ void Spell::EffectWeaponDmg(uint32 i)
// Fan of Knives // Fan of Knives
else if (m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0004000000000000))) else if (m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0004000000000000)))
{ {
Item* weapon = ((Player*)m_caster)->GetWeaponForAttack(m_attackType,true); Item* weapon = ((Player*)m_caster)->GetWeaponForAttack(m_attackType,true,true);
if (weapon && weapon->GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER) if (weapon && weapon->GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
totalDamagePercentMod *= 1.5f; // 150% to daggers totalDamagePercentMod *= 1.5f; // 150% to daggers
} }
@ -4821,13 +4821,13 @@ void Spell::EffectWeaponDmg(uint32 i)
// take ammo // take ammo
if(m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER) if(m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER)
{ {
Item *pItem = ((Player*)m_caster)->GetWeaponForAttack( RANGED_ATTACK ); Item *pItem = ((Player*)m_caster)->GetWeaponForAttack(RANGED_ATTACK, true, false);
// wands don't have ammo // wands don't have ammo
if(!pItem || pItem->IsBroken() || pItem->GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_WAND) if (!pItem || pItem->GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
return; return;
if( pItem->GetProto()->InventoryType == INVTYPE_THROWN ) if (pItem->GetProto()->InventoryType == INVTYPE_THROWN)
{ {
if(pItem->GetMaxStackCount()==1) if(pItem->GetMaxStackCount()==1)
{ {

View file

@ -246,7 +246,7 @@ void Unit::Update( uint32 p_time )
bool Unit::haveOffhandWeapon() const bool Unit::haveOffhandWeapon() const
{ {
if(GetTypeId() == TYPEID_PLAYER) if(GetTypeId() == TYPEID_PLAYER)
return ((Player*)this)->GetWeaponForAttack(OFF_ATTACK,true); return ((Player*)this)->GetWeaponForAttack(OFF_ATTACK,true,true);
else else
return false; return false;
} }
@ -2950,9 +2950,9 @@ float Unit::GetUnitParryChance() const
Player const* player = (Player const*)this; Player const* player = (Player const*)this;
if(player->CanParry() ) if(player->CanParry() )
{ {
Item *tmpitem = player->GetWeaponForAttack(BASE_ATTACK,true); Item *tmpitem = player->GetWeaponForAttack(BASE_ATTACK,true,true);
if(!tmpitem) if(!tmpitem)
tmpitem = player->GetWeaponForAttack(OFF_ATTACK,true); tmpitem = player->GetWeaponForAttack(OFF_ATTACK,true,true);
if(tmpitem) if(tmpitem)
chance = GetFloatValue(PLAYER_PARRY_PERCENTAGE); chance = GetFloatValue(PLAYER_PARRY_PERCENTAGE);
@ -3056,7 +3056,7 @@ uint32 Unit::GetWeaponSkillValue (WeaponAttackType attType, Unit const* target)
uint32 value = 0; uint32 value = 0;
if(GetTypeId() == TYPEID_PLAYER) if(GetTypeId() == TYPEID_PLAYER)
{ {
Item* item = ((Player*)this)->GetWeaponForAttack(attType,true); Item* item = ((Player*)this)->GetWeaponForAttack(attType,true,true);
// feral or unarmed skill only for base attack // feral or unarmed skill only for base attack
if(attType != BASE_ATTACK && !item ) if(attType != BASE_ATTACK && !item )
@ -9510,7 +9510,7 @@ uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType att
// differentiate for weapon damage based spells // differentiate for weapon damage based spells
bool isWeaponDamageBasedSpell = !(spellProto && (damagetype == DOT || IsSpellHaveEffect(spellProto, SPELL_EFFECT_SCHOOL_DAMAGE))); bool isWeaponDamageBasedSpell = !(spellProto && (damagetype == DOT || IsSpellHaveEffect(spellProto, SPELL_EFFECT_SCHOOL_DAMAGE)));
Item* pWeapon = GetTypeId() == TYPEID_PLAYER ? ((Player*)this)->GetWeaponForAttack(attType) : NULL; Item* pWeapon = GetTypeId() == TYPEID_PLAYER ? ((Player*)this)->GetWeaponForAttack(attType,true,false) : NULL;
uint32 creatureTypeMask = pVictim->GetCreatureTypeMask(); uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
uint32 schoolMask = spellProto ? spellProto->SchoolMask : GetMeleeDamageSchoolMask(); uint32 schoolMask = spellProto ? spellProto->SchoolMask : GetMeleeDamageSchoolMask();
uint32 mechanicMask = spellProto ? GetAllSpellMechanicMask(spellProto) : 0; uint32 mechanicMask = spellProto ? GetAllSpellMechanicMask(spellProto) : 0;
@ -12611,7 +12611,7 @@ float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized)
if (!normalized || GetTypeId() != TYPEID_PLAYER) if (!normalized || GetTypeId() != TYPEID_PLAYER)
return float(GetAttackTime(attType))/1000.0f; return float(GetAttackTime(attType))/1000.0f;
Item *Weapon = ((Player*)this)->GetWeaponForAttack(attType); Item *Weapon = ((Player*)this)->GetWeaponForAttack(attType, true, false);
if (!Weapon) if (!Weapon)
return 2.4; // fist attack return 2.4; // fist attack

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "8977" #define REVISION_NR "8978"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__