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
This commit is contained in:
@@ -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,34 +7646,12 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl
|
||||
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)
|
||||
{
|
||||
extraDPS = ssv->getDPSMod(proto->ScalingStatValue);
|
||||
if (extraDPS)
|
||||
{
|
||||
float average = extraDPS * proto->Delay / 1000.0f;
|
||||
minDamage = 0.7f * average;
|
||||
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(CanUseAttackType(attType))
|
||||
_ApplyWeaponDamage(slot, proto, ssv, apply);
|
||||
|
||||
if (maxDamage > 0)
|
||||
{
|
||||
damage = apply ? maxDamage : BASE_MAXDAMAGE;
|
||||
SetBaseWeaponDamage(attType, MAXDAMAGE, damage);
|
||||
}
|
||||
int32 extraDPS = ssv->getDPSMod(proto->ScalingStatValue);
|
||||
|
||||
// Apply feral bonus from ScalingStatValue if set
|
||||
// Apply feral bonus from ScalingStatValue if set
|
||||
if (ssv)
|
||||
{
|
||||
if (int32 feral_bonus = ssv->getFeralBonus(proto->ScalingStatValue))
|
||||
@@ -7691,10 +7665,53 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl
|
||||
ApplyFeralAPBonus(feral_bonus, apply);
|
||||
}
|
||||
|
||||
if (IsInFeralForm() || !CanUseAttackType(attType))
|
||||
return;
|
||||
}
|
||||
|
||||
if (proto->Delay)
|
||||
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)
|
||||
{
|
||||
extraDPS = ssv->getDPSMod(proto->ScalingStatValue);
|
||||
if (extraDPS)
|
||||
{
|
||||
float average = extraDPS * proto->Delay / 1000.0f;
|
||||
minDamage = 0.7f * average;
|
||||
maxDamage = 1.3f * average;
|
||||
}
|
||||
}
|
||||
|
||||
if (minDamage > 0)
|
||||
{
|
||||
damage = apply ? minDamage : BASE_MINDAMAGE;
|
||||
SetBaseWeaponDamage(attType, MINDAMAGE, damage);
|
||||
}
|
||||
|
||||
if (maxDamage > 0)
|
||||
{
|
||||
damage = apply ? maxDamage : BASE_MAXDAMAGE;
|
||||
SetBaseWeaponDamage(attType, MAXDAMAGE, damage);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,21 +3575,26 @@ void AuraEffect::HandleAuraModDisarm(AuraApplication const * aurApp, uint8 mode,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(apply))
|
||||
if (!apply)
|
||||
target->RemoveFlag(field, flag);
|
||||
|
||||
if (target->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
if (apply)
|
||||
target->SetFlag(field, flag);
|
||||
|
||||
// Handle damage modifcation, shapeshifted druids are not affected
|
||||
if (target->GetTypeId() == TYPEID_PLAYER && !target->IsInFeralForm())
|
||||
{
|
||||
if (Item *pItem = target->ToPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
|
||||
{
|
||||
uint8 attacktype = Player::GetAttackBySlot(slot);
|
||||
|
||||
if (attacktype < MAX_ATTACK)
|
||||
target->ToPlayer()->_ApplyWeaponDamage(slot, pItem->GetProto(), NULL, !apply);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->GetCurrentEquipmentId())
|
||||
target->UpdateDamagePhysical(attType);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user