aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorleak <leakzx@googlemail.com>2010-12-29 17:18:29 +0100
committerleak <leakzx@googlemail.com>2010-12-29 17:18:29 +0100
commit1c244cced512d069f748922055bb6b51ae7a85ee (patch)
tree8a7f45a8ab8a71f4286e7f0fcc3804678a7852ad /src
parent1f7e888465250cd339e2a784a643f66bb65ce3e1 (diff)
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
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp74
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h1
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuraEffects.cpp35
3 files changed, 73 insertions, 37 deletions
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<Player>
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);