[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 <vladimir@getmangos.com>
This commit is contained in:
QAston 2011-01-04 05:20:56 +03:00 committed by VladimirMangos
parent 883e88fad5
commit 4fe41fb335
9 changed files with 76 additions and 30 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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,

View file

@ -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)

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
if(!item || item->IsBroken() || !IsUseEquipedWeapon(OFF_ATTACK) || item->GetProto()->Class != ITEM_CLASS_ARMOR || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
return false;
}
}

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "10956"
#define REVISION_NR "10957"
#endif // __REVISION_NR_H__