From eb33e8ae111a35fa5e345b74996f20b646f2ba3c Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Mon, 5 May 2014 15:29:29 -0400 Subject: [PATCH] Melee 'facing' code updated to client derived function These new functions are derived from the client The need was because the old function sometimes didn't line up with the client generated messages. --- zone/client_packet.cpp | 2 +- zone/client_process.cpp | 6 ++--- zone/mob.cpp | 49 +++++++++++++++++++++++++++++++++++++++++ zone/mob.h | 2 ++ 4 files changed, 55 insertions(+), 4 deletions(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 1a9420dd7..cc5414ac4 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1328,7 +1328,7 @@ void Client::Handle_OP_AutoAttack(const EQApplicationPacket *app) aa_los_them.y = aa_los_them_mob->GetY(); aa_los_them.z = aa_los_them_mob->GetZ(); los_status = CheckLosFN(aa_los_them_mob); - los_status_facing = aa_los_them_mob->InFrontMob(this, aa_los_them.x, aa_los_them.y); + los_status_facing = IsFacingMob(aa_los_them_mob); } else { diff --git a/zone/client_process.cpp b/zone/client_process.cpp index c28affd28..f245c1d44 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -361,13 +361,13 @@ bool Client::Process() { aa_los_them.z = aa_los_them_mob->GetZ(); los_status = CheckLosFN(auto_attack_target); aa_los_me_heading = GetHeading(); - los_status_facing = aa_los_them_mob->InFrontMob(this, aa_los_them.x, aa_los_them.y); + los_status_facing = IsFacingMob(aa_los_them_mob); } // If only our heading changes, we can skip the CheckLosFN call // but above we still need to update los_status_facing if (aa_los_me_heading != GetHeading()) { aa_los_me_heading = GetHeading(); - los_status_facing = aa_los_them_mob->InFrontMob(this, aa_los_them.x, aa_los_them.y); + los_status_facing = IsFacingMob(aa_los_them_mob); } } else @@ -381,7 +381,7 @@ bool Client::Process() { aa_los_them.y = aa_los_them_mob->GetY(); aa_los_them.z = aa_los_them_mob->GetZ(); los_status = CheckLosFN(auto_attack_target); - los_status_facing = aa_los_them_mob->InFrontMob(this, aa_los_them.x, aa_los_them.y); + los_status_facing = IsFacingMob(aa_los_them_mob); } if (!CombatRange(auto_attack_target)) diff --git a/zone/mob.cpp b/zone/mob.cpp index 6d5907014..cef5bd605 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -5046,3 +5046,52 @@ void Mob::ProcessSpecialAbilities(const std::string str) { } } } + +// derived from client to keep these functions more consistent +// if anything seems weird, blame SoE +bool Mob::IsFacingMob(Mob *other) +{ + float angle = HeadingAngleToMob(other); + // what the client uses appears to be 2x our internal heading + float heading = GetHeading() * 2.0; + + if (angle > 472.0 && heading < 40.0) + angle = heading; + if (angle < 40.0 && heading > 472.0) + angle = heading; + + if (fabs(angle - heading) <= 80.0) + return true; + + return false; +} + +// All numbers derived from the client +float Mob::HeadingAngleToMob(Mob *other) +{ + float mob_x = other->GetX(); + float mob_y = other->GetY(); + float this_x = GetX(); + float this_y = GetY(); + + float y_diff = fabs(this_y - mob_y); + float x_diff = fabs(this_x - mob_x); + if (y_diff < 0.0000009999999974752427) + y_diff = 0.0000009999999974752427; + + float angle = atan2(x_diff, y_diff) * 180.0 * 0.3183099014828645; // angle, nice "pi" + + // return the right thing based on relative quadrant + // I'm sure this could be improved for readability, but whatever + if (this_y >= mob_y) { + if (mob_x >= this_x) + return (90.0 - angle + 90.0) * 511.5 * 0.0027777778; + if (mob_x <= this_x) + return (angle + 180.0) * 511.5 * 0.0027777778; + } + if (this_y > mob_y || mob_x > this_x) + return angle * 511.5 * 0.0027777778; + else + return (90.0 - angle + 270.0) * 511.5 * 0.0027777778; +} + diff --git a/zone/mob.h b/zone/mob.h index 92b999d9d..1df559d16 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -125,6 +125,8 @@ public: // less than 56 is in front, greater than 56 is usually where the client generates the messages inline bool InFrontMob(Mob *other = 0, float ourx = 0.0f, float oury = 0.0f) const { return (!other || other == this) ? true : MobAngle(other, ourx, oury) < 56.0f; } + bool IsFacingMob(Mob *other); // kind of does the same as InFrontMob, but derived from client + float HeadingAngleToMob(Mob *other); // to keep consistent with client generated messages virtual void RangedAttack(Mob* other) { } virtual void ThrowingAttack(Mob* other) { } uint16 GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg);