--HG--
branch : trunk
This commit is contained in:
megamage
2009-02-03 15:05:04 -06:00
11 changed files with 231 additions and 119 deletions
+18 -13
View File
@@ -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;
+7 -6
View File
@@ -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);
+66
View File
@@ -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)
+1
View File
@@ -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();
+7 -7
View File
@@ -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,
+47 -32
View File
@@ -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)
if (!Real)
return;
AuraType type = GetModifier()->m_auraname;
if(!apply && m_target->HasAuraType(SPELL_AURA_MOD_DISARM))
//Prevent handling aura twice
if(apply && m_target->GetAurasByType(type).size()>1)
return;
// not sure for it's correctness
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())
Item *pItem = ((Player*)m_target)->GetItemByPos( INVENTORY_SLOT_BAG_0, slot );
if(!pItem )
return;
if (apply)
m_target->SetAttackTime(BASE_ATTACK,BASE_ATTACK_TIME);
else
((Player *)m_target)->SetRegularAttackTime();
((Player*)m_target)->_ApplyItemMods(pItem, slot, !apply);
}
else
{
// creature does not have equipment
if(apply && !((Creature*)m_target)->GetCurrentEquipmentId())
return;
}
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());
+1 -28
View File
@@ -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*/)
+2 -2
View File
@@ -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))
{
+9 -2
View File
@@ -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;
+60 -28
View File
@@ -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;
}
+13 -1
View File
@@ -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;