From 1c244cced512d069f748922055bb6b51ae7a85ee Mon Sep 17 00:00:00 2001 From: leak Date: Wed, 29 Dec 2010 17:18:29 +0100 Subject: Core/Entities: Fixed disarming and related exploits - Disarm shouldn't deduct stats other than weapon damage - Ferals shouldn't be affected by disarm - Fixed meta gem stacking exploit --- src/server/game/Entities/Player/Player.cpp | 74 ++++++++++++++--------- src/server/game/Entities/Player/Player.h | 1 + src/server/game/Spells/Auras/SpellAuraEffects.cpp | 35 ++++++++--- 3 files changed, 73 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index ca41e0ca7cc..de2f5d16a3f 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -5730,9 +5730,9 @@ void Player::SetRegularAttackTime() ItemPrototype const *proto = tmpitem->GetProto(); if (proto->Delay) SetAttackTime(WeaponAttackType(i), proto->Delay); - else - SetAttackTime(WeaponAttackType(i), BASE_ATTACK_TIME); } + else + SetAttackTime(WeaponAttackType(i), BASE_ATTACK_TIME); // If there is no weapon reset attack time to base (might have been changed from forms) } } @@ -7368,10 +7368,6 @@ void Player::_ApplyItemMods(Item *item, uint8 slot,bool apply) uint8 attacktype = Player::GetAttackBySlot(slot); - // check disarm only on mod apply to allow remove item mods - if (!CanUseAttackType(attacktype)) - return; - if (proto->Socket[0].Color) //only (un)equipping of items with sockets can influence metagems, so no need to waste time with normal items CorrectMetaGemEnchants(slot, apply); @@ -7650,9 +7646,47 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl attType = OFF_ATTACK; } + if(CanUseAttackType(attType)) + _ApplyWeaponDamage(slot, proto, ssv, apply); + + int32 extraDPS = ssv->getDPSMod(proto->ScalingStatValue); + + // Apply feral bonus from ScalingStatValue if set + if (ssv) + { + if (int32 feral_bonus = ssv->getFeralBonus(proto->ScalingStatValue)) + ApplyFeralAPBonus(feral_bonus, apply); + } + // Druids get feral AP bonus from weapon dps (lso use DPS from ScalingStatValue) + if (getClass() == CLASS_DRUID) + { + int32 feral_bonus = proto->getFeralBonus(extraDPS); + if (feral_bonus > 0) + ApplyFeralAPBonus(feral_bonus, apply); + } + + } + +void Player::_ApplyWeaponDamage(uint8 slot, ItemPrototype const *proto, ScalingStatValuesEntry const *ssv, bool apply) +{ + WeaponAttackType attType = BASE_ATTACK; + float damage = 0.0f; + + if (slot == EQUIPMENT_SLOT_RANGED && ( + proto->InventoryType == INVTYPE_RANGED || proto->InventoryType == INVTYPE_THROWN || + proto->InventoryType == INVTYPE_RANGEDRIGHT)) + { + attType = RANGED_ATTACK; + } + else if (slot == EQUIPMENT_SLOT_OFFHAND) + { + attType = OFF_ATTACK; + } + float minDamage = proto->Damage[0].DamageMin; float maxDamage = proto->Damage[0].DamageMax; int32 extraDPS = 0; + // If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage if (ssv) { @@ -7664,11 +7698,11 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl maxDamage = 1.3f * average; } } + if (minDamage > 0) { damage = apply ? minDamage : BASE_MINDAMAGE; SetBaseWeaponDamage(attType, MINDAMAGE, damage); - //sLog->outError("applying mindam: assigning %f to weapon mindamage, now is: %f", damage, GetWeaponDamageRange(attType, MINDAMAGE)); } if (maxDamage > 0) @@ -7677,24 +7711,7 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl SetBaseWeaponDamage(attType, MAXDAMAGE, damage); } - // Apply feral bonus from ScalingStatValue if set - if (ssv) - { - if (int32 feral_bonus = ssv->getFeralBonus(proto->ScalingStatValue)) - ApplyFeralAPBonus(feral_bonus, apply); - } - // Druids get feral AP bonus from weapon dps (lso use DPS from ScalingStatValue) - if (getClass() == CLASS_DRUID) - { - int32 feral_bonus = proto->getFeralBonus(extraDPS); - if (feral_bonus > 0) - ApplyFeralAPBonus(feral_bonus, apply); - } - - if (IsInFeralForm() || !CanUseAttackType(attType)) - return; - - if (proto->Delay) + if (proto->Delay && !IsInFeralForm()) { if (slot == EQUIPMENT_SLOT_RANGED) SetAttackTime(RANGED_ATTACK, apply ? proto->Delay: BASE_ATTACK_TIME); @@ -7704,6 +7721,10 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl SetAttackTime(OFF_ATTACK, apply ? proto->Delay: BASE_ATTACK_TIME); } + // No need to modify any physical damage for ferals as it is calculated from stats only + if (IsInFeralForm()) + return; + if (CanModifyStats() && (damage || proto->Delay)) UpdateDamagePhysical(attType); } @@ -13168,9 +13189,6 @@ void Player::ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool if (!item || !item->IsEquipped()) return; - if (!CanUseAttackType(Player::GetAttackBySlot(item->GetSlot()))) - return; - if (slot >= MAX_ENCHANTMENT_SLOT) return; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index de4b62eed8d..d1f217d7a3e 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2012,6 +2012,7 @@ class Player : public Unit, public GridObject void _ApplyAllItemMods(); void _ApplyAllLevelScaleItemMods(bool apply); void _ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply, bool only_level_scale = false); + void _ApplyWeaponDamage(uint8 slot, ItemPrototype const *proto, ScalingStatValuesEntry const *ssv, bool apply); void _ApplyAmmoBonuses(); bool EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot); void ToggleMetaGemsActive(uint8 exceptslot, bool apply); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 87a951b7938..3afd452044b 100755 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -3200,8 +3200,20 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const * aurApp, uint8 m { // Dash if (AuraEffect * aurEff =target->GetAuraEffect(SPELL_AURA_MOD_INCREASE_SPEED, SPELLFAMILY_DRUID, 0, 0, 0x8)) - aurEff->RecalculateAmount(); + aurEff->RecalculateAmount(); + + // Disarm handling + // If druid shifts while being disarmed we need to deal with that since forms aren't affected by disarm + // and also HandleAuraModDisarm is not triggered + if(!target->CanUseAttackType(BASE_ATTACK)) + { + if (Item *pItem = target->ToPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND)) + { + target->ToPlayer()->_ApplyWeaponDamage(EQUIPMENT_SLOT_MAINHAND, pItem->GetProto(), NULL, apply); + } + } } + if (target->GetTypeId() == TYPEID_PLAYER) { SpellShapeshiftEntry const *shapeInfo = sSpellShapeshiftStore.LookupEntry(form); @@ -3563,20 +3575,25 @@ void AuraEffect::HandleAuraModDisarm(AuraApplication const * aurApp, uint8 mode, return; } - if (!(apply)) + if (!apply) target->RemoveFlag(field, flag); - if (target->GetTypeId() == TYPEID_PLAYER) + if (apply) + target->SetFlag(field, flag); + + // Handle damage modifcation, shapeshifted druids are not affected + if (target->GetTypeId() == TYPEID_PLAYER && !target->IsInFeralForm()) { - // This is between the two because there is a check in _ApplyItemMods - // we must make sure that flag is always removed when call that function - // refer to DurabilityPointsLoss if (Item *pItem = target->ToPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) - target->ToPlayer()->_ApplyItemMods(pItem, slot, !apply); + { + uint8 attacktype = Player::GetAttackBySlot(slot); + + if (attacktype < MAX_ATTACK) + target->ToPlayer()->_ApplyWeaponDamage(slot, pItem->GetProto(), NULL, !apply); + } } - if (apply) - target->SetFlag(field, flag); + if (target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->GetCurrentEquipmentId()) target->UpdateDamagePhysical(attType); -- cgit v1.2.3