aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormegamage <none@none>2009-02-03 15:05:04 -0600
committermegamage <none@none>2009-02-03 15:05:04 -0600
commit3b8bce566ec9d3e56e35ebc3c3a0e9136faabdc6 (patch)
treed6c99472398f57257198200f1599952d000619bf
parent7fdb40ec5cfe99ad97d8c0768538d7a7b60016d8 (diff)
parent516cb0c6da103f2e5297beab80a19dfc88ffb4af (diff)
*Merge.
--HG-- branch : trunk
-rw-r--r--src/game/Player.cpp31
-rw-r--r--src/game/Player.h13
-rw-r--r--src/game/Spell.cpp66
-rw-r--r--src/game/Spell.h1
-rw-r--r--src/game/SpellAuraDefines.h14
-rw-r--r--src/game/SpellAuras.cpp83
-rw-r--r--src/game/SpellEffects.cpp29
-rw-r--r--src/game/SpellHandler.cpp4
-rw-r--r--src/game/StatSystem.cpp11
-rw-r--r--src/game/Unit.cpp88
-rw-r--r--src/game/Unit.h14
11 files changed, 233 insertions, 121 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 9366907c9b1..985865cb812 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -6742,7 +6742,12 @@ void Player::_ApplyItemMods(Item *item, uint8 slot,bool apply)
sLog.outDetail("applying mods for item %u ",item->GetGUIDLow());
- uint32 attacktype = Player::GetAttackBySlot(slot);
+ uint8 attacktype = Player::GetAttackBySlot(slot);
+
+ //check disarm only on mod apply to allow remove item mods
+ if (apply && !CanUseAttackType(attacktype) )
+ return;
+
if(attacktype < MAX_ATTACK)
_ApplyWeaponDependentAuraMods(item,WeaponAttackType(attacktype),apply);
@@ -6993,7 +6998,7 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl
SetBaseWeaponDamage(attType, MAXDAMAGE, damage);
}
- if(!IsUseEquipedWeapon(slot==EQUIPMENT_SLOT_MAINHAND))
+ if(IsInFeralForm())
return;
if (proto->Delay)
@@ -8883,14 +8888,14 @@ Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool useable) cons
default: return NULL;
}
- Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, slot);
+ Item* item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, slot);
if (!item || item->GetProto()->Class != ITEM_CLASS_WEAPON)
return NULL;
if(!useable)
return item;
- if( item->IsBroken() || !IsUseEquipedWeapon(attackType==BASE_ATTACK) )
+ if( item->IsBroken() || IsInFeralForm())
return NULL;
return item;
@@ -8898,7 +8903,7 @@ Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool useable) cons
Item* Player::GetShield(bool useable) const
{
- Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ Item* item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
if (!item || item->GetProto()->Class != ITEM_CLASS_ARMOR)
return NULL;
@@ -8911,7 +8916,7 @@ Item* Player::GetShield(bool useable) const
return item;
}
-uint32 Player::GetAttackBySlot( uint8 slot )
+uint8 Player::GetAttackBySlot( uint8 slot )
{
switch(slot)
{
@@ -9177,13 +9182,13 @@ bool Player::HasItemTotemCategory( uint32 TotemCategory ) const
Item *pItem;
for(uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i)
{
- pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+ pItem = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory ))
return true;
}
for(uint8 i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; ++i)
{
- pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+ pItem = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory ))
return true;
}
@@ -9193,7 +9198,7 @@ bool Player::HasItemTotemCategory( uint32 TotemCategory ) const
{
for(uint32 j = 0; j < pBag->GetBagSize(); ++j)
{
- pItem = GetItemByPos( i, j );
+ pItem = GetUseableItemByPos( i, j );
if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory ))
return true;
}
@@ -19154,7 +19159,7 @@ bool Player::HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item cons
case ITEM_CLASS_WEAPON:
{
for(int i= EQUIPMENT_SLOT_MAINHAND; i < EQUIPMENT_SLOT_TABARD; ++i)
- if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
+ if(Item *item = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, i ))
if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo))
return true;
break;
@@ -19163,17 +19168,17 @@ bool Player::HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item cons
{
// tabard not have dependent spells
for(int i= EQUIPMENT_SLOT_START; i< EQUIPMENT_SLOT_MAINHAND; ++i)
- if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
+ if(Item *item = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, i ))
if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo))
return true;
// shields can be equipped to offhand slot
- if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
+ if(Item *item = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo))
return true;
// ranged slot can have some armor subclasses
- if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED))
+ if(Item *item = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED))
if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo))
return true;
diff --git a/src/game/Player.h b/src/game/Player.h
index d27137c7cc9..f7858f3419b 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -1061,9 +1061,15 @@ class TRINITY_DLL_SPEC Player : public Unit
Item* GetItemByGuid( uint64 guid ) const;
Item* GetItemByPos( uint16 pos ) const;
Item* GetItemByPos( uint8 bag, uint8 slot ) const;
+ inline Item* Player::GetUseableItemByPos( uint8 bag, uint8 slot ) const //Does additional check for disarmed weapons
+ {
+ if (!CanUseAttackType(GetAttackBySlot(slot)))
+ return NULL;
+ return GetItemByPos(bag, slot);
+ }
Item* GetWeaponForAttack(WeaponAttackType attackType, bool useable = false) const;
Item* GetShield(bool useable = false) const;
- static uint32 GetAttackBySlot( uint8 slot ); // MAX_ATTACK if not weapon slot
+ static uint8 GetAttackBySlot( uint8 slot ); // MAX_ATTACK if not weapon slot
std::vector<Item *> &GetItemUpdateQueue() { return m_itemUpdateQueue; }
static bool IsInventoryPos( uint16 pos ) { return IsInventoryPos(pos >> 8,pos & 255); }
static bool IsInventoryPos( uint8 bag, uint8 slot );
@@ -1153,11 +1159,6 @@ class TRINITY_DLL_SPEC Player : public Unit
uint32 GetWeaponProficiency() const { return m_WeaponProficiency; }
uint32 GetArmorProficiency() const { return m_ArmorProficiency; }
bool IsInFeralForm() const { return m_form == FORM_CAT || m_form == FORM_BEAR || m_form == FORM_DIREBEAR; }
- bool IsUseEquipedWeapon( 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/Spell.cpp b/src/game/Spell.cpp
index ddac7d5c970..36766c67011 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -1442,6 +1442,13 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[i];
uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets;
+ Unit::AuraList const& Auras = m_caster->GetAurasByType(SPELL_AURA_MOD_ABILITY_AFFECTED_TARGETS);
+ for(Unit::AuraList::const_iterator j = Auras.begin();j != Auras.end(); ++j)
+ {
+ if((*j)->isAffectedOnSpell(m_spellInfo))
+ unMaxTargets+=(*j)->GetModifier()->m_amount;
+ }
+
if(m_originalCaster)
{
if(Player* modOwner = m_originalCaster->GetSpellModOwner())
@@ -3294,6 +3301,35 @@ void Spell::TakePower()
m_caster->SetLastManaUse(getMSTime());
}
+void Spell::TakeAmmo()
+{
+ if(m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ Item *pItem = ((Player*)m_caster)->GetWeaponForAttack( RANGED_ATTACK );
+
+ // wands don't have ammo
+ if(!pItem || pItem->IsBroken() || pItem->GetProto()->SubClass==ITEM_SUBCLASS_WEAPON_WAND)
+ return;
+
+ if( pItem->GetProto()->InventoryType == INVTYPE_THROWN )
+ {
+ if(pItem->GetMaxStackCount()==1)
+ {
+ // decrease durability for non-stackable throw weapon
+ ((Player*)m_caster)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_RANGED);
+ }
+ else
+ {
+ // decrease items amount for stackable throw weapon
+ uint32 count = 1;
+ ((Player*)m_caster)->DestroyItemCount( pItem, count, true);
+ }
+ }
+ else if(uint32 ammo = ((Player*)m_caster)->GetUInt32Value(PLAYER_AMMO_ID))
+ ((Player*)m_caster)->DestroyItemCount(ammo, 1, true);
+ }
+}
+
uint8 Spell::CheckRuneCost(uint32 runeCostID)
{
if(m_caster->GetTypeId() != TYPEID_PLAYER)
@@ -5618,6 +5654,14 @@ void Spell::CalculateDamageDoneForAllTargets()
}
}
+ bool usesAmmo=true;
+ Unit::AuraList const& Auras = m_caster->GetAurasByType(SPELL_AURA_ABILITY_CONSUME_NO_AMMO);
+ for(Unit::AuraList::const_iterator j = Auras.begin();j != Auras.end(); ++j)
+ {
+ if((*j)->isAffectedOnSpell(m_spellInfo))
+ usesAmmo=false;
+ }
+
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
TargetInfo &target = *ihit;
@@ -5630,6 +5674,28 @@ void Spell::CalculateDamageDoneForAllTargets()
if (!unit)
continue;
+ if (usesAmmo)
+ {
+ bool ammoTaken=false;
+ for (uint8 i=0;i<3;i++)
+ {
+ if (!(mask & 1<<i))
+ continue;
+ switch (m_spellInfo->Effect[i])
+ {
+ case SPELL_EFFECT_SCHOOL_DAMAGE:
+ case SPELL_EFFECT_WEAPON_DAMAGE:
+ case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
+ case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
+ case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
+ ammoTaken=true;
+ TakeAmmo();
+ }
+ if (ammoTaken)
+ break;
+ }
+ }
+
if (target.missCondition==SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
target.damage += CalculateDamageDone(unit, mask, multiplier);
else if (target.missCondition == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
diff --git a/src/game/Spell.h b/src/game/Spell.h
index ac7f8c8c7ea..38345525b65 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -360,6 +360,7 @@ class Spell
void cast(bool skipCheck = false);
void finish(bool ok = true);
void TakePower();
+ void TakeAmmo();
uint8 CheckRuneCost(uint32 runeCostID);
void TakeRunePower();
void TakeReagents();
diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h
index abe3438aa43..77270d20c7f 100644
--- a/src/game/SpellAuraDefines.h
+++ b/src/game/SpellAuraDefines.h
@@ -238,8 +238,8 @@ enum AuraType
SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED = 191,
SPELL_AURA_HASTE_MELEE = 192,
SPELL_AURA_MELEE_SLOW = 193,
- SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL = 194,
- SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL = 195,
+ SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL = 194,
+ SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL = 195,
SPELL_AURA_MOD_COOLDOWN = 196, // only 24818 Noxious Breath
SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE = 197,
SPELL_AURA_MOD_ALL_WEAPON_SKILLS = 198,
@@ -298,7 +298,7 @@ enum AuraType
SPELL_AURA_MOD_ENEMY_DODGE = 251,
SPELL_AURA_252 = 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,
@@ -313,15 +313,15 @@ enum AuraType
SPELL_AURA_266 = 266,
SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL = 267,
SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT = 268,
- SPELL_AURA_269 = 269,
- SPELL_AURA_MOD_IGNORE_TARGET_RESIST = 270, // Possibly need swap vs 195 aura used only in 1 spell Chaos Bolt Passive
+ SPELL_AURA_MOD_IGNORE_TARGET_RESIST = 269,
+ SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST = 270, // Possibly need swap vs 195 aura used only in 1 spell Chaos Bolt Passive
SPELL_AURA_MOD_DAMAGE_FROM_CASTER = 271,
SPELL_AURA_272 = 272,
SPELL_AURA_273 = 273,
- SPELL_AURA_274 = 274,
+ SPELL_AURA_ABILITY_CONSUME_NO_AMMO = 274,
SPELL_AURA_MOD_IGNORE_SHAPESHIFT = 275,
SPELL_AURA_276 = 276, // Only "Test Mod Damage % Mechanic" spell, possible mod damage done
- SPELL_AURA_MOD_MAX_AFFECTED_TARGETS = 277,
+ SPELL_AURA_MOD_ABILITY_AFFECTED_TARGETS = 277,
SPELL_AURA_MOD_DISARM_RANGED = 278,
SPELL_AURA_279 = 279,
SPELL_AURA_MOD_WEAPONTYPE_IGNORE_TARGET_RESISTANCE = 280,
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index f831dc2d045..58d1b6253d4 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -248,8 +248,8 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
&Aura::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE
&Aura::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
- &Aura::HandleUnused, //194 SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL
- &Aura::HandleNoImmediateEffect, //195 SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL implement in Unit::CalculateSpellDamage
+ &Aura::HandleNoImmediateEffect, //194 SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist
+ &Aura::HandleNoImmediateEffect, //195 SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist
&Aura::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN
&Aura::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
&Aura::HandleUnused, //198 SPELL_AURA_MOD_ALL_WEAPON_SKILLS
@@ -308,7 +308,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleNULL, //251 SPELL_AURA_MOD_ENEMY_DODGE
&Aura::HandleNULL, //252 haste all?
&Aura::HandleNULL, //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE
- &Aura::HandleNULL, //254 SPELL_AURA_MOD_DISARM_SHIELD disarm Shield
+ &Aura::HandleAuraModDisarm, //254 SPELL_AURA_MOD_DISARM_OFFHAND
&Aura::HandleNoImmediateEffect, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT implemented in Unit::SpellDamageBonus
&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
@@ -323,16 +323,16 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleNULL, //266 unused
&Aura::HandleNoImmediateEffect, //267 SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL implemented in Unit::IsImmunedToSpellEffect
&Aura::HandleAuraModAttackPowerOfStatPercent, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT
- &Aura::HandleNULL, //269 ignore DR effects?
- &Aura::HandleNULL, //270 SPELL_AURA_MOD_IGNORE_TARGET_RESIST
+ &Aura::HandleNoImmediateEffect, //269 SPELL_AURA_MOD_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
+ &Aura::HandleNoImmediateEffect, //270 SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
&Aura::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus
&Aura::HandleNULL, //272 reduce spell cast time?
- &Aura::HandleNULL, //273
- &Aura::HandleNULL, //274 proc free shot?
+ &Aura::HandleUnused, //273 clientside
+ &Aura::HandleNoImmediateEffect, //274 SPELL_AURA_CONSUME_NO_AMMO implemented in spell::CalculateDamageDoneForAllTargets
&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::HandleNoImmediateEffect, //277 SPELL_AURA_MOD_ABILITY_AFFECTED_TARGETS implemented in spell::settargetmap
+ &Aura::HandleAuraModDisarm, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon
&Aura::HandleNULL, //279
&Aura::HandleNULL, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT
&Aura::HandleNoImmediateEffect, //281 SPELL_AURA_MOD_HONOR_GAIN_PCT implemented in Player::RewardHonor
@@ -3223,37 +3223,52 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
void Aura::HandleAuraModDisarm(bool apply, bool Real)
{
- if(!Real)
- return;
-
- if(!apply && m_target->HasAuraType(SPELL_AURA_MOD_DISARM))
+ if (!Real)
return;
-
- // not sure for it's correctness
+ AuraType type = GetModifier()->m_auraname;
+
+ //Prevent handling aura twice
+ if(apply && m_target->GetAurasByType(type).size()>1)
+ return;
+ if(!apply && m_target->HasAuraType(type))
+ return;
+ uint32 field, flag, slot;
+ WeaponAttackType attType;
+ switch (type)
+ {
+ case SPELL_AURA_MOD_DISARM:
+ field=UNIT_FIELD_FLAGS;
+ flag=UNIT_FLAG_DISARMED;
+ slot=EQUIPMENT_SLOT_MAINHAND;
+ attType=BASE_ATTACK;
+ break;
+ case SPELL_AURA_MOD_DISARM_OFFHAND:
+ field=UNIT_FIELD_FLAGS_2;
+ flag=UNIT_FLAG2_DISARM_OFFHAND;
+ slot=EQUIPMENT_SLOT_OFFHAND;
+ attType=OFF_ATTACK;
+ break;
+ case SPELL_AURA_MOD_DISARM_RANGED:
+ field=UNIT_FIELD_FLAGS_2;
+ flag=UNIT_FLAG2_DISARM_RANGED;
+ slot=EQUIPMENT_SLOT_RANGED;
+ attType=RANGED_ATTACK;
+ break;
+ }
if(apply)
- m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
+ m_target->SetFlag(field, flag);
else
- m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
+ m_target->RemoveFlag(field, flag);
if (m_target->GetTypeId() == TYPEID_PLAYER)
{
- // main-hand attack speed already set to special value for feral form already and don't must change and reset at remove.
- if (((Player *)m_target)->IsInFeralForm())
- return;
-
- if (apply)
- m_target->SetAttackTime(BASE_ATTACK,BASE_ATTACK_TIME);
- else
- ((Player *)m_target)->SetRegularAttackTime();
- }
- else
- {
- // creature does not have equipment
- if(apply && !((Creature*)m_target)->GetCurrentEquipmentId())
+ Item *pItem = ((Player*)m_target)->GetItemByPos( INVENTORY_SLOT_BAG_0, slot );
+ if(!pItem )
return;
+ ((Player*)m_target)->_ApplyItemMods(pItem, slot, !apply);
}
-
- m_target->UpdateDamagePhysical(BASE_ATTACK);
+ else if (((Creature*)m_target)->GetCurrentEquipmentId())
+ m_target->UpdateDamagePhysical(attType);
}
void Aura::HandleAuraModStun(bool apply, bool Real)
@@ -5478,7 +5493,7 @@ void Aura::PeriodicTick()
if (m_target->GetTypeId()==TYPEID_PLAYER)
pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage);
- pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
+ pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist, m_spellProto);
sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
@@ -5549,7 +5564,7 @@ void Aura::PeriodicTick()
if (m_target->GetTypeId()==TYPEID_PLAYER)
pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage);
- pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
+ pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist, m_spellProto);
if(m_target->GetHealth() < pdamage)
pdamage = uint32(m_target->GetHealth());
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 2ef4a3827c4..0fec6925203 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -300,7 +300,7 @@ void Spell::EffectEnvirinmentalDMG(uint32 i)
// currently each enemy selected explicitly and self cast damage, we prevent apply self casted spell bonuses/etc
damage = m_spellInfo->EffectBasePoints[i]+m_spellInfo->EffectBaseDice[i];
- m_caster->CalcAbsorbResist(m_caster,GetSpellSchoolMask(m_spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
+ m_caster->CalcAbsorbResist(m_caster,GetSpellSchoolMask(m_spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist, m_spellInfo);
m_caster->SendSpellNonMeleeDamageLog(m_caster, m_spellInfo->Id, damage, GetSpellSchoolMask(m_spellInfo), absorb, resist, false, 0, false);
if(m_caster->GetTypeId() == TYPEID_PLAYER)
@@ -4575,33 +4575,6 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
// Add melee damage bonuses (also check for negative)
m_caster->MeleeDamageBonus(unitTarget, &eff_damage, m_attackType, m_spellInfo);
m_damage+= eff_damage;
-
- // take ammo
- if(m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER)
- {
- Item *pItem = ((Player*)m_caster)->GetWeaponForAttack( RANGED_ATTACK );
-
- // wands don't have ammo
- if(!pItem || pItem->IsBroken() || pItem->GetProto()->SubClass==ITEM_SUBCLASS_WEAPON_WAND)
- return;
-
- if( pItem->GetProto()->InventoryType == INVTYPE_THROWN )
- {
- if(pItem->GetMaxStackCount()==1)
- {
- // decrease durability for non-stackable throw weapon
- ((Player*)m_caster)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_RANGED);
- }
- else
- {
- // decrease items amount for stackable throw weapon
- uint32 count = 1;
- ((Player*)m_caster)->DestroyItemCount( pItem, count, true);
- }
- }
- else if(uint32 ammo = ((Player*)m_caster)->GetUInt32Value(PLAYER_AMMO_ID))
- ((Player*)m_caster)->DestroyItemCount(ammo, 1, true);
- }
}
void Spell::EffectThreat(uint32 /*i*/)
diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp
index 4186336fe18..7323bed1915 100644
--- a/src/game/SpellHandler.cpp
+++ b/src/game/SpellHandler.cpp
@@ -50,7 +50,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
recvPacket >> bagIndex >> slot >> cast_count >> spellid >> item_guid >> glyphIndex >> unk_flags;
- Item *pItem = pUser->GetItemByPos(bagIndex, slot);
+ Item *pItem = pUser->GetUseableItemByPos(bagIndex, slot);
if(!pItem)
{
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
@@ -349,7 +349,7 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
}
}
-
+
// channeled spell case (it currently casted then)
if(IsChanneledSpell(spellInfo))
{
diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp
index 5473206e8bd..8f520125986 100644
--- a/src/game/StatSystem.cpp
+++ b/src/game/StatSystem.cpp
@@ -427,8 +427,15 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, fl
weapon_mindamage = lvl*0.85*att_speed;
weapon_maxdamage = lvl*1.25*att_speed;
}
- else if(!IsUseEquipedWeapon(attType==BASE_ATTACK)) //check if player not in form but still can't use weapon (broken/etc)
+ else if(!CanUseAttackType(attType)) //check if player not in form but still can't use (disarm case)
{
+ //cannot use ranged/off attack, set values to 0
+ if (attType != BASE_ATTACK)
+ {
+ min_damage=0;
+ max_damage=0;
+ return;
+ }
weapon_mindamage = BASE_MINDAMAGE;
weapon_maxdamage = BASE_MAXDAMAGE;
}
@@ -820,7 +827,7 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType)
float total_value = GetModifierValue(unitMod, TOTAL_VALUE);
float total_pct = GetModifierValue(unitMod, TOTAL_PCT);
- if(attType == BASE_ATTACK && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED))
+ if(!CanUseAttackType(attType))
{
weapon_mindamage = 0;
weapon_maxdamage = 0;
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 0c79a7d2bd3..a576abc0360 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -1267,21 +1267,8 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 dama
// Calculate absorb resist
if(damage > 0)
{
- // lookup absorb/resist ignore auras on caster for spell
- bool ignore = false;
- Unit::AuraList const& ignoreAbsorb = GetAurasByType(SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL);
- for(Unit::AuraList::const_iterator i = ignoreAbsorb.begin(); i != ignoreAbsorb.end(); ++i)
- if ((*i)->isAffectedOnSpell(spellInfo))
- {
- ignore = true;
- break;
- }
-
- if (!ignore)
- {
- CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, damage, &damageInfo->absorb, &damageInfo->resist);
- damage-= damageInfo->absorb + damageInfo->resist;
- }
+ CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, damage, &damageInfo->absorb, &damageInfo->resist, spellInfo);
+ damage-= damageInfo->absorb + damageInfo->resist;
}
else
damage = 0;
@@ -1293,15 +1280,15 @@ int32 Unit::GetIgnoredArmorMultiplier(SpellEntry const *spellInfo, WeaponAttackT
if (GetTypeId() != TYPEID_PLAYER)
return 0;
//check if spell uses weapon
- if (spellInfo && spellInfo->EquippedItemClass!=ITEM_CLASS_WEAPON)
+ if (!spellInfo || spellInfo->EquippedItemClass!=ITEM_CLASS_WEAPON)
return 0;
Item *item = NULL;
if(attackType == BASE_ATTACK)
- item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
else if (attackType == OFF_ATTACK)
- item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
else if (attackType == RANGED_ATTACK)
- item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
if (!item)
return 0;
@@ -1657,7 +1644,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
if(GetTypeId() == TYPEID_PLAYER && pVictim->isAlive())
{
for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++)
- ((Player*)this)->CastItemCombatSpell(((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0,i), pVictim, damageInfo->attackType);
+ ((Player*)this)->CastItemCombatSpell(((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0,i), pVictim, damageInfo->attackType);
}
// victim's damage shield
@@ -1722,6 +1709,21 @@ uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEnt
if(Player *modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_IGNORE_ARMOR, armor);
+ AuraList const& ResIgnoreAurasAb = GetAurasByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
+ for(AuraList::const_iterator j = ResIgnoreAurasAb.begin();j != ResIgnoreAurasAb.end(); ++j)
+ {
+ if( (*j)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL
+ && (*j)->isAffectedOnSpell(spellInfo))
+ armor= float(armor) * (float(100-(*j)->GetModifier()->m_amount)/100.0f);
+ }
+
+ AuraList const& ResIgnoreAuras = GetAurasByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ for(AuraList::const_iterator j = ResIgnoreAuras.begin();j != ResIgnoreAuras.end(); ++j)
+ {
+ if( (*j)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL)
+ armor= float(armor) * (float(100-(*j)->GetModifier()->m_amount)/100.0f);
+ }
+
// Apply Player CR_ARMOR_PENETRATION rating
if (GetTypeId()==TYPEID_PLAYER)
armor *= 1.0f - ((Player*)this)->GetRatingBonusValue(CR_ARMOR_PENETRATION) / 100.0f;
@@ -1744,7 +1746,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEnt
return (newdamage > 1) ? newdamage : 1;
}
-void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist)
+void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, SpellEntry const *spellInfo)
{
if(!pVictim || !pVictim->isAlive() || !damage)
return;
@@ -1780,6 +1782,21 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
*resist += uint32(damage * m / 4);
if(*resist > damage)
*resist = damage;
+
+ AuraList const& ResIgnoreAurasAb = GetAurasByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
+ for(AuraList::const_iterator j = ResIgnoreAurasAb.begin();j != ResIgnoreAurasAb.end(); ++j)
+ {
+ if( (*j)->GetModifier()->m_miscvalue & schoolMask
+ && (*j)->isAffectedOnSpell(spellInfo))
+ *resist= float(*resist) * (float(100-(*j)->GetModifier()->m_amount)/100.0f);
+ }
+
+ AuraList const& ResIgnoreAuras = GetAurasByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ for(AuraList::const_iterator j = ResIgnoreAuras.begin();j != ResIgnoreAuras.end(); ++j)
+ {
+ if( (*j)->GetModifier()->m_miscvalue & schoolMask)
+ *resist= float(*resist) * (float(100-(*j)->GetModifier()->m_amount)/100.0f);
+ }
}
else
*resist = 0;
@@ -1990,6 +2007,21 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
if (RemainingDamage < currentAbsorb)
currentAbsorb = RemainingDamage;
+ AuraList const& AbsIgnoreAurasAb = GetAurasByType(SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL);
+ for(AuraList::const_iterator j = AbsIgnoreAurasAb.begin();j != AbsIgnoreAurasAb.end(); ++j)
+ {
+ if( (*j)->GetModifier()->m_miscvalue & (*i)->GetModifier()->m_miscvalue
+ && (*j)->isAffectedOnSpell(spellInfo))
+ currentAbsorb= float(currentAbsorb) * (float(100-(*j)->GetModifier()->m_amount)/100.0f);
+ }
+
+ AuraList const& AbsIgnoreAuras = GetAurasByType(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL);
+ for(AuraList::const_iterator j = AbsIgnoreAuras.begin();j != AbsIgnoreAuras.end(); ++j)
+ {
+ if( (*j)->GetModifier()->m_miscvalue & (*i)->GetModifier()->m_miscvalue)
+ currentAbsorb= float(currentAbsorb) * (float(100-(*j)->GetModifier()->m_amount)/100.0f);
+ }
+
RemainingDamage -= currentAbsorb;
// Reduce shield amount
@@ -2919,7 +2951,7 @@ float Unit::GetUnitBlockChance() const
Player const* player = (Player const*)this;
if(player->CanBlock() )
{
- Item *tmpitem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ Item *tmpitem = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
if(tmpitem && !tmpitem->IsBroken() && tmpitem->GetProto()->Block)
return GetFloatValue(PLAYER_BLOCK_PERCENTAGE);
}
@@ -8595,7 +8627,7 @@ uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint
AuraList const& mHealingGet= pVictim->GetAurasByType(SPELL_AURA_MOD_HEALING_RECEIVED);
for(AuraList::const_iterator i = mHealingGet.begin(); i != mHealingGet.end(); ++i)
- if ((*i)->isAffectedOnSpell(spellProto))
+ if (GetGUID()==(*i)->GetCasterGUID() && (*i)->isAffectedOnSpell(spellProto) )
TakenTotalMod *= ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f;
heal = (heal + TakenTotal) * TakenTotalMod;
@@ -11686,13 +11718,13 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry con
{
Item *item = NULL;
if(attType == BASE_ATTACK)
- item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
else if (attType == OFF_ATTACK)
- item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
else
- item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
- if (!((Player*)this)->IsUseEquipedWeapon(attType==BASE_ATTACK))
+ if (((Player*)this)->IsInFeralForm())
return false;
if(!item || item->IsBroken() || item->GetProto()->Class != ITEM_CLASS_WEAPON || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
@@ -11701,7 +11733,7 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry con
else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR)
{
// Check if player is wearing shield
- Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ Item *item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
if(!item || item->IsBroken() || item->GetProto()->Class != ITEM_CLASS_ARMOR || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
return false;
}
diff --git a/src/game/Unit.h b/src/game/Unit.h
index aa038ab1fb4..00ee9b90e58 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -544,6 +544,8 @@ enum UnitFlags2
UNIT_FLAG2_UNK1 = 0x00000002, // Hide unit model (show only player equip)
UNIT_FLAG2_COMPREHEND_LANG = 0x00000008,
UNIT_FLAG2_FORCE_MOVE = 0x00000040,
+ UNIT_FLAG2_DISARM_OFFHAND = 0x00000080,
+ UNIT_FLAG2_DISARM_RANGED = 0x00000400, //this does not disable ranged weapon display (maybe additional flag needed?)
UNIT_FLAG2_REGENERATE_POWER = 0x00000800
};
@@ -1005,6 +1007,16 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
float GetUnitParryChance() const;
float GetUnitBlockChance() const;
float GetUnitCriticalChance(WeaponAttackType attackType, const Unit *pVictim) const;
+ bool CanUseAttackType( uint8 attacktype ) const
+ {
+ switch(attacktype)
+ {
+ 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);
+ }
+ return true;
+ }
virtual uint32 GetShieldBlockValue() const =0;
uint32 GetUnitMeleeSkill(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
@@ -1414,7 +1426,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
// redefined in Creature
uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType=MAX_ATTACK);
- void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist);
+ void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, SpellEntry const *spellInfo = NULL);
void UpdateSpeed(UnitMoveType mtype, bool forced);
float GetSpeed( UnitMoveType mtype ) const;