Skip to content

Commit

Permalink
[Fix] Change SPA 193 Weapon Damage to allow values over 65,535 (#3138)
Browse files Browse the repository at this point in the history
  • Loading branch information
Aeadoin committed Mar 23, 2023
1 parent 2e2c4d6 commit dc45e0d
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 48 deletions.
6 changes: 3 additions & 3 deletions zone/mob.h
Expand Up @@ -1107,9 +1107,9 @@ class Mob : public Entity {
int64 ReduceAllDamage(int64 damage);

void DoSpecialAttackDamage(Mob *who, EQ::skills::SkillType skill, int base_damage, int min_damage = 0, int32 hate_override = -1, int ReuseTime = 10);
virtual void DoThrowingAttackDmg(Mob* other, const EQ::ItemInstance* RangeWeapon = nullptr, const EQ::ItemData* AmmoItem = nullptr, uint16 weapon_damage = 0, int16 chance_mod = 0, int16 focus = 0, int ReuseTime = 0, uint32 range_id = 0, int AmmoSlot = 0, float speed = 4.0f, bool DisableProcs = false);
void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, EQ::skills::SkillType skillinuse, int16 chance_mod = 0, int16 focus = 0, bool CanRiposte = false, int ReuseTime = 0);
virtual void DoArcheryAttackDmg(Mob* other, const EQ::ItemInstance* RangeWeapon = nullptr, const EQ::ItemInstance* Ammo = nullptr, uint16 weapon_damage = 0, int16 chance_mod = 0, int16 focus = 0, int ReuseTime = 0, uint32 range_id = 0, uint32 ammo_id = 0, const EQ::ItemData *AmmoItem = nullptr, int AmmoSlot = 0, float speed = 4.0f, bool DisableProcs = false);
void DoThrowingAttackDmg(Mob* other, const EQ::ItemInstance* RangeWeapon = nullptr, const EQ::ItemData* AmmoItem = nullptr, int32 weapon_damage = 0, int16 chance_mod = 0, int16 focus = 0, int ReuseTime = 0, uint32 range_id = 0, int AmmoSlot = 0, float speed = 4.0f, bool DisableProcs = false);
void DoMeleeSkillAttackDmg(Mob* other, int32 weapon_damage, EQ::skills::SkillType skillinuse, int16 chance_mod = 0, int16 focus = 0, bool CanRiposte = false, int ReuseTime = 0);
void DoArcheryAttackDmg(Mob* other, const EQ::ItemInstance* RangeWeapon = nullptr, const EQ::ItemInstance* Ammo = nullptr, int32 weapon_damage = 0, int16 chance_mod = 0, int16 focus = 0, int ReuseTime = 0, uint32 range_id = 0, uint32 ammo_id = 0, const EQ::ItemData *AmmoItem = nullptr, int AmmoSlot = 0, float speed = 4.0f, bool DisableProcs = false);
bool TryProjectileAttack(Mob* other, const EQ::ItemData *item, EQ::skills::SkillType skillInUse, uint64 weapon_dmg, const EQ::ItemInstance* RangeWeapon, const EQ::ItemInstance* Ammo, int AmmoSlot, float speed, bool DisableProcs = false);
void ProjectileAttack();
inline bool HasProjectileAttack() const { return ActiveProjectileATK; }
Expand Down
99 changes: 54 additions & 45 deletions zone/special_attacks.cpp
Expand Up @@ -747,11 +747,10 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
LogCombat("Shooting [{}] with bow [{}] ([{}]) and arrow [{}] ([{}])", other->GetName(), RangeItem->Name, RangeItem->ID, AmmoItem->Name, AmmoItem->ID);

//look for ammo in inventory if we only have 1 left...
if(Ammo->GetCharges() == 1) {
if (Ammo->GetCharges() == 1) {
//first look for quivers
int r;
bool found = false;
for (r = EQ::invslot::GENERAL_BEGIN; r <= EQ::invslot::GENERAL_END; r++) {
for (int r = EQ::invslot::GENERAL_BEGIN; r <= EQ::invslot::GENERAL_END; r++) {
const EQ::ItemInstance *pi = m_inv[r];
if (pi == nullptr || !pi->IsClassBag())
continue;
Expand All @@ -760,16 +759,17 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
continue;

//we found a quiver, look for the ammo in it
int i;
for (i = 0; i < bagitem->BagSlots; i++) {
EQ::ItemInstance* baginst = pi->GetItem(i);
if(!baginst)
continue; //empty
if(baginst->GetID() == Ammo->GetID()) {
for (int i = 0; i < bagitem->BagSlots; i++) {
const EQ::ItemInstance* baginst = pi->GetItem(i);
if (!baginst) {
continue;
}

if (baginst->GetID() == Ammo->GetID()) {
//we found it... use this stack
//the item wont change, but the instance does
Ammo = baginst;
ammo_slot = m_inv.CalcSlotId(r, i);
ammo_slot = EQ::InventoryProfile::CalcSlotId(r, i);
found = true;
LogCombat("Using ammo from quiver stack at slot [{}]. [{}] in stack", ammo_slot, Ammo->GetCharges());
break;
Expand All @@ -794,18 +794,17 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
float range = RangeItem->Range + AmmoItem->Range + GetRangeDistTargetSizeMod(GetTarget());
LogCombat("Calculated bow range to be [{}]", range);
range *= range;
float dist = DistanceSquared(m_Position, other->GetPosition());
if(dist > range) {
if (float dist = DistanceSquared(m_Position, other->GetPosition()); dist > range) {
LogCombat("Ranged attack out of range client should catch this. ([{}] > [{}]).\n", dist, range);
MessageString(Chat::Red,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase.
return;
}
else if(dist < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){
else if (dist < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){
MessageString(Chat::Yellow,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase.
return;
}

if(!IsAttackAllowed(other) ||
if (!IsAttackAllowed(other) ||
IsCasting() ||
IsSitting() ||
(DivineAura() && !GetGM()) ||
Expand Down Expand Up @@ -845,12 +844,12 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
}

void Mob::DoArcheryAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, const EQ::ItemInstance *Ammo,
uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime, uint32 range_id,
uint32 ammo_id, const EQ::ItemData *AmmoItem, int AmmoSlot, float speed, bool DisableProcs)
int32 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime, uint32 range_id,
uint32 ammo_id, const EQ::ItemData *AmmoItem, int AmmoSlot, float speed, bool DisableProcs)
{
if ((other == nullptr ||
((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead)) ||
HasDied() || (!IsAttackAllowed(other)) || (other->GetInvul() || other->GetSpecialAbility(IMMUNE_MELEE)))) {
((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead)) ||
HasDied() || (!IsAttackAllowed(other)) || (other->GetInvul() || other->GetSpecialAbility(IMMUNE_MELEE)))) {
return;
}

Expand Down Expand Up @@ -911,7 +910,7 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, co

if (LaunchProjectile) { // 1: Shoot the Projectile once we calculate weapon damage.
TryProjectileAttack(other, AmmoItem, EQ::skills::SkillArchery, (WDmg + ADmg), RangeWeapon,
Ammo, AmmoSlot, speed, DisableProcs);
Ammo, AmmoSlot, speed, DisableProcs);
return;
}

Expand All @@ -920,10 +919,14 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, co
}

if (WDmg > 0 || ADmg > 0) {
if (WDmg < 0)
if (WDmg < 0) {
WDmg = 0;
if (ADmg < 0)
}

if (ADmg < 0) {
ADmg = 0;
}

int MaxDmg = WDmg + ADmg;
hate = ((WDmg + ADmg));

Expand All @@ -934,10 +937,11 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, co
LogCombat("Bow DMG [{}], Arrow DMG [{}], Max Damage [{}]", WDmg, ADmg, MaxDmg);
}

if (MaxDmg == 0)
if (MaxDmg == 0) {
MaxDmg = 1;
}

DamageHitInfo my_hit;
DamageHitInfo my_hit {};
my_hit.base_damage = MaxDmg;
my_hit.min_damage = 0;
my_hit.damage_done = 1;
Expand All @@ -953,8 +957,9 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, co
TotalDmg = DMG_INVULNERABLE;
}

if (IsClient() && !CastToClient()->GetFeigned())
if (IsClient() && !CastToClient()->GetFeigned()) {
other->AddToHateList(this, hate, 0);
}

other->Damage(this, TotalDmg, SPELL_UNKNOWN, EQ::skills::SkillArchery);

Expand Down Expand Up @@ -1443,7 +1448,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
}

void Mob::DoThrowingAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, const EQ::ItemData *AmmoItem,
uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime, uint32 range_id,
int32 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime, uint32 range_id,
int AmmoSlot, float speed, bool DisableProcs)
{
if ((other == nullptr ||
Expand Down Expand Up @@ -1490,7 +1495,7 @@ void Mob::DoThrowingAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, c
int WDmg = 0;

if (!weapon_damage) {
if (IsClient() && RangeWeapon) {
if (IsOfClientBot() && RangeWeapon) {
WDmg = GetWeaponDamage(other, RangeWeapon);
}
else if (AmmoItem) {
Expand All @@ -1514,7 +1519,7 @@ void Mob::DoThrowingAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, c
int TotalDmg = 0;

if (WDmg > 0) {
DamageHitInfo my_hit;
DamageHitInfo my_hit {};
my_hit.base_damage = WDmg;
my_hit.min_damage = 0;
my_hit.damage_done = 1;
Expand All @@ -1533,8 +1538,9 @@ void Mob::DoThrowingAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, c
TotalDmg = DMG_INVULNERABLE;
}

if (IsClient() && !CastToClient()->GetFeigned())
if (IsClient() && !CastToClient()->GetFeigned()) {
other->AddToHateList(this, WDmg, 0);
}

other->Damage(this, TotalDmg, SPELL_UNKNOWN, EQ::skills::SkillThrowing);

Expand Down Expand Up @@ -2299,46 +2305,47 @@ int Mob::TryAssassinate(Mob *defender, EQ::skills::SkillType skillInUse)
return 0;
}

void Mob::DoMeleeSkillAttackDmg(Mob *other, uint16 weapon_damage, EQ::skills::SkillType skillinuse, int16 chance_mod,
void Mob::DoMeleeSkillAttackDmg(Mob *other, int32 weapon_damage, EQ::skills::SkillType skillinuse, int16 chance_mod,
int16 focus, bool CanRiposte, int ReuseTime)
{
if (!CanDoSpecialAttack(other))
if (!CanDoSpecialAttack(other)) {
return;
}

/*
For spells using skill value 98 (feral swipe ect) server sets this to 67 automatically.
Kayen: This is unlikely to be completely accurate but use OFFENSE skill value for these effects.
TODO: We need to stop moving skill 98, it's suppose to just be a dummy skill AFAIK
Spells using offense should use the skill of your primary, if you can use it, otherwise h2h
*/
if (skillinuse == EQ::skills::SkillBegging)
if (skillinuse == EQ::skills::SkillBegging) {
skillinuse = EQ::skills::SkillOffense;
}

int64 damage = 0;
int64 hate = 0;
if (hate == 0 && weapon_damage > 1)
if (hate == 0 && weapon_damage > 1) {
hate = weapon_damage;
}

if (weapon_damage > 0) {
if (focus) {
weapon_damage += weapon_damage * focus / 100;
}

if (skillinuse == EQ::skills::SkillBash) {
if (IsClient()) {
EQ::ItemInstance *item =
CastToClient()->GetInv().GetItem(EQ::invslot::slotSecondary);
if (item) {
if (item->GetItem()->ItemType == EQ::item::ItemTypeShield) {
hate += item->GetItem()->AC;
}
const EQ::ItemData *itm = item->GetItem();
hate = hate * (100 + GetFuriousBash(itm->Focus.Effect)) / 100;
if (skillinuse == EQ::skills::SkillBash && IsClient()) {
EQ::ItemInstance *item =
CastToClient()->GetInv().GetItem(EQ::invslot::slotSecondary);
if (item) {
if (item->GetItem()->ItemType == EQ::item::ItemTypeShield) {
hate += item->GetItem()->AC;
}
const EQ::ItemData *itm = item->GetItem();
hate = hate * (100 + GetFuriousBash(itm->Focus.Effect)) / 100;
}
}

DamageHitInfo my_hit;
DamageHitInfo my_hit {};
my_hit.base_damage = weapon_damage;
my_hit.min_damage = 0;
my_hit.damage_done = 1;
Expand All @@ -2349,8 +2356,9 @@ void Mob::DoMeleeSkillAttackDmg(Mob *other, uint16 weapon_damage, EQ::skills::Sk
// slot range exclude ripe etc ...
my_hit.hand = CanRiposte ? EQ::invslot::slotRange : EQ::invslot::slotPrimary;

if (IsNPC())
if (IsNPC()) {
my_hit.min_damage = CastToNPC()->GetMinDamage();
}

DoAttack(other, my_hit);
damage = my_hit.damage_done;
Expand All @@ -2365,8 +2373,9 @@ void Mob::DoMeleeSkillAttackDmg(Mob *other, uint16 weapon_damage, EQ::skills::Sk
other->AddToHateList(this, hate, 0);
other->Damage(this, damage, SPELL_UNKNOWN, skillinuse);

if (HasDied())
if (HasDied()) {
return;
}

TryCastOnSkillUse(other, skillinuse);
}
Expand Down

0 comments on commit dc45e0d

Please sign in to comment.