From 4fe41fb33599b56867ba05fdf5b0b17b04d85f69 Mon Sep 17 00:00:00 2001 From: QAston Date: Tue, 4 Jan 2011 05:20:56 +0300 Subject: [PATCH] [10957] Implement auras SPELL_AURA_MOD_DISARM_OFFHAND (254) and SPELL_AURA_MOD_DISARM_RANGED (278). Thanks to Qsa prepare for mangos. Note: single unsure case: is block chance must be show or set to 0 in shield disarm time. Signed-off-by: VladimirMangos --- src/game/Player.cpp | 10 +++---- src/game/Player.h | 5 ---- src/game/SpellAuraDefines.h | 2 +- src/game/SpellAuras.cpp | 47 ++++++++++++++++++++++++-------- src/game/StatSystem.cpp | 9 +++--- src/game/Unit.cpp | 5 +++- src/game/Unit.h | 24 +++++++++++++++- src/game/UnitAuraProcHandler.cpp | 2 +- src/shared/revision_nr.h | 2 +- 9 files changed, 76 insertions(+), 30 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 822289054..80a370953 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -7282,14 +7282,14 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl ApplyFeralAPBonus(feral_bonus, apply); } // Druids get feral AP bonus from weapon dps (also use DPS from ScalingStatValue) - if(getClass() == CLASS_DRUID) + if (getClass() == CLASS_DRUID) { int32 feral_bonus = proto->getFeralBonus(extraDPS); if (feral_bonus > 0) ApplyFeralAPBonus(feral_bonus, apply); } - if(!IsUseEquippedWeapon(slot==EQUIPMENT_SLOT_MAINHAND)) + if (!IsUseEquipedWeapon(attType)) return; if (proto->Delay) @@ -9095,7 +9095,7 @@ Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool nonbroken, bo if (!item || item->GetProto()->Class != ITEM_CLASS_WEAPON) return NULL; - if (useable && !IsUseEquippedWeapon(attackType==BASE_ATTACK)) + if (useable && !IsUseEquipedWeapon(attackType)) return NULL; if (nonbroken && item->IsBroken()) @@ -9110,10 +9110,10 @@ Item* Player::GetShield(bool useable) const if (!item || item->GetProto()->Class != ITEM_CLASS_ARMOR) return NULL; - if(!useable) + if (!useable) return item; - if( item->IsBroken()) + if (item->IsBroken() || !IsUseEquipedWeapon(OFF_ATTACK)) return NULL; return item; diff --git a/src/game/Player.h b/src/game/Player.h index 2201fdb5c..ab43e7d10 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1338,11 +1338,6 @@ class MANGOS_DLL_SPEC Player : public Unit void AddArmorProficiency(uint32 newflag) { m_ArmorProficiency |= newflag; } uint32 GetWeaponProficiency() const { return m_WeaponProficiency; } uint32 GetArmorProficiency() const { return m_ArmorProficiency; } - bool IsUseEquippedWeapon( bool mainhand ) const - { - // disarm applied only to mainhand weapon - return !IsInFeralForm() && (!mainhand || !HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISARMED) ); - } bool IsTwoHandUsed() const { Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index a3f177f22..0271c904d 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -289,7 +289,7 @@ enum AuraType SPELL_AURA_MOD_ENEMY_DODGE = 251, SPELL_AURA_SLOW_ALL = 252, SPELL_AURA_MOD_BLOCK_CRIT_CHANCE = 253, - SPELL_AURA_MOD_DISARM_SHIELD = 254, + SPELL_AURA_MOD_DISARM_OFFHAND = 254, SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT = 255, SPELL_AURA_NO_REAGENT_USE = 256, SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS = 257, diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index a92a88954..f3823d1e5 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -304,7 +304,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleNULL, //251 SPELL_AURA_MOD_ENEMY_DODGE &Aura::HandleModCombatSpeedPct, //252 SPELL_AURA_SLOW_ALL &Aura::HandleNoImmediateEffect, //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE implemented in Unit::CalculateMeleeDamage - &Aura::HandleNULL, //254 SPELL_AURA_MOD_DISARM_SHIELD disarm Shield + &Aura::HandleAuraModDisarm, //254 SPELL_AURA_MOD_DISARM_OFFHAND also disarm shield &Aura::HandleNoImmediateEffect, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT implemented in Unit::SpellDamageBonusTaken &Aura::HandleNoReagentUseAura, //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select &Aura::HandleNULL, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select @@ -328,7 +328,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleNoImmediateEffect, //275 SPELL_AURA_MOD_IGNORE_SHAPESHIFT Use SpellClassMask for spell select &Aura::HandleNULL, //276 mod damage % mechanic? &Aura::HandleNoImmediateEffect, //277 SPELL_AURA_MOD_MAX_AFFECTED_TARGETS Use SpellClassMask for spell select - &Aura::HandleNULL, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon + &Aura::HandleAuraModDisarm, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon &Aura::HandleNULL, //279 visual effects? 58836 and 57507 &Aura::HandleModTargetArmorPct, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT &Aura::HandleNoImmediateEffect, //281 SPELL_AURA_MOD_HONOR_GAIN implemented in Player::RewardHonor @@ -3939,16 +3939,41 @@ void Aura::HandleAuraModDisarm(bool apply, bool Real) Unit *target = GetTarget(); - if(!apply && target->HasAuraType(SPELL_AURA_MOD_DISARM)) + if(!apply && target->HasAuraType(GetModifier()->m_auraname)) return; - // not sure for it's correctness - if(apply) - target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED); - else - target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED); + uint32 flags; + uint32 field; + WeaponAttackType attack_type; + + switch (GetModifier()->m_auraname) + { + default: + case SPELL_AURA_MOD_DISARM: + { + field = UNIT_FIELD_FLAGS; + flags = UNIT_FLAG_DISARMED; + attack_type = BASE_ATTACK; + break; + } + case SPELL_AURA_MOD_DISARM_OFFHAND: + { + field = UNIT_FIELD_FLAGS_2; + flags = UNIT_FLAG2_DISARM_OFFHAND; + attack_type = OFF_ATTACK; + break; + } + case SPELL_AURA_MOD_DISARM_RANGED: + { + field = UNIT_FIELD_FLAGS_2; + flags = UNIT_FLAG2_DISARM_RANGED; + attack_type = RANGED_ATTACK; + break; + } + } + + target->ApplyModFlag(field, flags, apply); - // only at real add/remove aura if (target->GetTypeId() != TYPEID_PLAYER) return; @@ -3957,11 +3982,11 @@ void Aura::HandleAuraModDisarm(bool apply, bool Real) return; if (apply) - target->SetAttackTime(BASE_ATTACK,BASE_ATTACK_TIME); + target->SetAttackTime(attack_type, BASE_ATTACK_TIME); else ((Player *)target)->SetRegularAttackTime(); - target->UpdateDamagePhysical(BASE_ATTACK); + target->UpdateDamagePhysical(attack_type); } void Aura::HandleAuraModStun(bool apply, bool Real) diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp index 75beb810b..2a4ea76b9 100644 --- a/src/game/StatSystem.cpp +++ b/src/game/StatSystem.cpp @@ -431,20 +431,21 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, fl 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 + if (IsInFeralForm()) // check if player is druid and in cat or bear forms, non main hand attacks not allowed for this mode so not check attack type { uint32 lvl = getLevel(); - if ( lvl > 60 ) lvl = 60; + if (lvl > 60) + lvl = 60; weapon_mindamage = lvl*0.85f*att_speed; weapon_maxdamage = lvl*1.25f*att_speed; } - else if (!IsUseEquippedWeapon(attType==BASE_ATTACK)) //check if player not in form but still can't use weapon (broken/etc) + else if (!IsUseEquipedWeapon(attType)) // check if player not in form but still can't use weapon (broken/etc) { weapon_mindamage = BASE_MINDAMAGE; weapon_maxdamage = 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; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 805172030..2f9bf9367 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -353,6 +353,9 @@ void Unit::Update( uint32 update_diff, uint32 p_time ) bool Unit::haveOffhandWeapon() const { + if (!IsUseEquipedWeapon(OFF_ATTACK)) + return false; + if(GetTypeId() == TYPEID_PLAYER) return ((Player*)this)->GetWeaponForAttack(OFF_ATTACK,true,true); else @@ -3327,7 +3330,7 @@ float Unit::GetUnitBlockChance() const if(GetTypeId() == TYPEID_PLAYER) { Player const* player = (Player const*)this; - if(player->CanBlock() ) + if(player->CanBlock() && player->IsUseEquipedWeapon(OFF_ATTACK)) { Item *tmpitem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); if(tmpitem && !tmpitem->IsBroken() && tmpitem->GetProto()->Block) diff --git a/src/game/Unit.h b/src/game/Unit.h index 35e1726c0..599f5917c 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -579,9 +579,15 @@ enum UnitFlags2 { UNIT_FLAG2_FEIGN_DEATH = 0x00000001, UNIT_FLAG2_UNK1 = 0x00000002, // Hides unit model (show only player equip) + UNIT_FLAG2_UNK2 = 0x00000004, UNIT_FLAG2_COMPREHEND_LANG = 0x00000008, + UNIT_FLAG2_UNK4 = 0x00000010, + UNIT_FLAG2_UNK5 = 0x00000020, UNIT_FLAG2_FORCE_MOVE = 0x00000040, - UNIT_FLAG2_DISARM = 0x00000400, // disarm or something + UNIT_FLAG2_DISARM_OFFHAND = 0x00000080, // also shield case + UNIT_FLAG2_UNK8 = 0x00000100, + UNIT_FLAG2_UNK9 = 0x00000200, + UNIT_FLAG2_DISARM_RANGED = 0x00000400, UNIT_FLAG2_REGENERATE_POWER = 0x00000800, }; @@ -1193,6 +1199,22 @@ class MANGOS_DLL_SPEC Unit : public WorldObject uint32 getAttackTimer(WeaponAttackType type) const { return m_attackTimer[type]; } bool isAttackReady(WeaponAttackType type = BASE_ATTACK) const { return m_attackTimer[type] == 0; } bool haveOffhandWeapon() const; + bool IsUseEquipedWeapon(WeaponAttackType attackType) const + { + if (IsInFeralForm()) + return false; + + switch(attackType) + { + default: + case BASE_ATTACK: + return !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED); + case OFF_ATTACK: + return !HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISARM_OFFHAND); + case RANGED_ATTACK: + return !HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISARM_RANGED); + } + } bool canReachWithAttack(Unit *pVictim) const; uint32 m_extraAttacks; diff --git a/src/game/UnitAuraProcHandler.cpp b/src/game/UnitAuraProcHandler.cpp index f80d7ccb2..feedea2b2 100644 --- a/src/game/UnitAuraProcHandler.cpp +++ b/src/game/UnitAuraProcHandler.cpp @@ -407,7 +407,7 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, SpellAuraHolder* holder, S { // Check if player is wearing shield Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); - if(!item || item->IsBroken() || item->GetProto()->Class != ITEM_CLASS_ARMOR || !((1<GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) + if(!item || item->IsBroken() || !IsUseEquipedWeapon(OFF_ATTACK) || item->GetProto()->Class != ITEM_CLASS_ARMOR || !((1<GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) return false; } } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 61b91019b..46fab83b0 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10956" + #define REVISION_NR "10957" #endif // __REVISION_NR_H__