diff --git a/changelog.txt b/changelog.txt index a700ded31..8daf85938 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,12 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 02/14/2018 == +mackal: Fix Heading -- Quests broken + +Please report any other issues with heading, most things were tested and worked + +Run akkadius' script to fix your quests + == 02/10/2018 == mackal: Add Global Loot system diff --git a/common/misc_functions.cpp b/common/misc_functions.cpp index dcdbad561..aaa20f3d4 100644 --- a/common/misc_functions.cpp +++ b/common/misc_functions.cpp @@ -194,32 +194,52 @@ uint32 rnd_hash( time_t t, clock_t c ) float EQ13toFloat(int d) { - return ( float(d)/float(1<<2)); -} - -float NewEQ13toFloat(int d) -{ - return ( float(d)/float(1<<6)); + return static_cast(d) / 64.0f; } float EQ19toFloat(int d) { - return ( float(d)/float(1<<3)); + return static_cast(d) / 8.0f; } int FloatToEQ13(float d) { - return int(d*float(1<<2)); -} - -int NewFloatToEQ13(float d) -{ - return int(d*float(1<<6)); + return static_cast(d * 64.0f); } int FloatToEQ19(float d) { - return int(d*float(1<<3)); + return static_cast(d * 8.0f); +} + +float EQ12toFloat(int d) +{ + return static_cast(d) / 4.0f; +} + +int FloatToEQ12(float d) +{ + return static_cast((d + 2048.0f) * 4.0f) % 2048; +} + +float EQ10toFloat(int d) +{ + return static_cast(d) / 20.0f; +} + +int FloatToEQ10(float d) +{ + return static_cast(d * 20.0f); +} + +float EQSpeedRunToFloat(int d) +{ + return static_cast(d) / 40.0f; +} + +int FloatToEQSpeedRun(float d) +{ + return static_cast(d * 40.0f); } /* diff --git a/common/misc_functions.h b/common/misc_functions.h index 501244fda..9ecb08378 100644 --- a/common/misc_functions.h +++ b/common/misc_functions.h @@ -50,13 +50,22 @@ uint32 ResolveIP(const char* hostname, char* errbuf = 0); bool ParseAddress(const char* iAddress, uint32* oIP, uint16* oPort, char* errbuf = 0); void CoutTimestamp(bool ms = true); float EQ13toFloat(int d); -float NewEQ13toFloat(int d); float EQ19toFloat(int d); float EQHtoFloat(int d); int FloatToEQ13(float d); -int NewFloatToEQ13(float d); int FloatToEQ19(float d); int FloatToEQH(float d); + +float EQ12toFloat(int d); +int FloatToEQ12(float d); + +float EQ10toFloat(int d); +int FloatToEQ10(float d); + +// this is also a 10 bit float +float EQSpeedRunToFloat(int d); +int FloatToEQSpeedRun(float d); + uint32 SwapBits21and22(uint32 mask); uint32 Catch22(uint32 mask); diff --git a/common/patches/rof2_structs.h b/common/patches/rof2_structs.h index 5aa11977f..5d42d9046 100644 --- a/common/patches/rof2_structs.h +++ b/common/patches/rof2_structs.h @@ -400,7 +400,7 @@ struct Spawn_Struct_Position struct Spawn_Struct_Position { - signed padding0000:12; + signed angle:12; // pitch of camera? signed y:19; signed padding0001:1; @@ -416,7 +416,7 @@ struct Spawn_Struct_Position signed z:19; signed padding0020:3; - signed animation:10; // animation + signed animation:10; // SpeedRun signed deltaY:13; signed padding0023:9; }; diff --git a/common/version.h b/common/version.h index 928592a4a..412223b8c 100644 --- a/common/version.h +++ b/common/version.h @@ -30,7 +30,7 @@ Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9119 +#define CURRENT_BINARY_DATABASE_VERSION 9120 #ifdef BOTS #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9018 #else diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 188db2162..4de5f3d8f 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -373,6 +373,7 @@ 9117|2018_02_01_NPC_Spells_Min_Max_HP.sql|SHOW COLUMNS FROM `npc_spells_entries` LIKE 'min_hp'|empty| 9118|2018_02_04_Charm_Stats.sql|SHOW COLUMNS FROM `npc_types` LIKE 'charm_ac'|empty| 9119|2018_02_10_GlobalLoot.sql|SHOW TABLES LIKE 'global_loot'|empty| +9120|2018_02_13_Heading.sql|SELECT value FROM variables WHERE varname = 'fixed_heading'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/required/2018_02_13_Heading.sql b/utils/sql/git/required/2018_02_13_Heading.sql new file mode 100644 index 000000000..4f4736625 --- /dev/null +++ b/utils/sql/git/required/2018_02_13_Heading.sql @@ -0,0 +1,3 @@ +UPDATE spawn2 SET heading = heading * 8.0 / 4.0; +UPDATE grid_entries SET heading = heading * 8.0 / 4.0 WHERE heading <> -1; +INSERT INTO variables (varname, value) VALUES ('fixed_heading', 1); -- hack diff --git a/zone/attack.cpp b/zone/attack.cpp index ce96675a0..58e1510ff 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -358,7 +358,7 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit) Mob *attacker = other; Mob *defender = this; - bool InFront = attacker->InFrontMob(this, attacker->GetX(), attacker->GetY()); + bool InFront = !attacker->BehindMob(this, attacker->GetX(), attacker->GetY()); /* This special ability adds a negative modifer to the defenders riposte/block/parry/chance @@ -3611,13 +3611,13 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const a->special = 2; else a->special = 0; - a->meleepush_xy = attacker ? attacker->GetHeading() * 2.0f : 0.0f; + a->meleepush_xy = attacker ? attacker->GetHeading() : 0.0f; if (RuleB(Combat, MeleePush) && damage > 0 && !IsRooted() && (IsClient() || zone->random.Roll(RuleI(Combat, MeleePushChance)))) { a->force = EQEmu::skills::GetSkillMeleePushForce(skill_used); // update NPC stuff - auto new_pos = glm::vec3(m_Position.x + (a->force * std::sin(a->meleepush_xy) + m_Delta.x), - m_Position.y + (a->force * std::cos(a->meleepush_xy) + m_Delta.y), m_Position.z); + auto new_pos = glm::vec3(m_Position.x + (a->force * std::cos(a->meleepush_xy) + m_Delta.x), + m_Position.y + (a->force * std::sin(a->meleepush_xy) + m_Delta.y), m_Position.z); if (zone->zonemap && zone->zonemap->CheckLoS(glm::vec3(m_Position), new_pos)) { // If we have LoS on the new loc it should be reachable. if (IsNPC()) { // Is this adequate? @@ -4445,6 +4445,12 @@ void Mob::DoRiposte(Mob *defender) if (!defender) return; + // so ahhh the angle you can riposte is larger than the angle you can hit :P + if (!defender->IsFacingMob(this)) { + defender->Message_StringID(MT_TooFarAway, CANT_SEE_TARGET); + return; + } + defender->Attack(this, EQEmu::inventory::slotPrimary, true); if (HasDied()) return; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 42a78cdaa..2de71acc8 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4402,7 +4402,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) return; } - auto boat_delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, ppu->delta_heading); + auto boat_delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, EQ10toFloat(ppu->delta_heading)); boat->SetDelta(boat_delta); auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); @@ -4412,7 +4412,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) safe_delete(outapp); /* Update the boat's position on the server, without sending an update */ - boat->GMMove(ppu->x_pos, ppu->y_pos, ppu->z_pos, EQ19toFloat(ppu->heading), false); + boat->GMMove(ppu->x_pos, ppu->y_pos, ppu->z_pos, EQ12toFloat(ppu->heading), false); return; } else return; @@ -4557,7 +4557,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) } /* Update internal state */ - m_Delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, ppu->delta_heading); + m_Delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, EQ10toFloat(ppu->delta_heading)); if (IsTracking() && ((m_Position.x != ppu->x_pos) || (m_Position.y != ppu->y_pos))) { if (zone->random.Real(0, 100) < 70)//should be good @@ -4610,7 +4610,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) } } - float new_heading = EQ19toFloat(ppu->heading); + float new_heading = EQ12toFloat(ppu->heading); int32 new_animation = ppu->animation; /* Update internal server position from what the client has sent */ @@ -4629,7 +4629,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) if (is_client_moving || new_heading != m_Position.w || new_animation != animation) { animation = ppu->animation; - m_Position.w = EQ19toFloat(ppu->heading); + m_Position.w = EQ12toFloat(ppu->heading); /* Broadcast update to other clients */ auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 21863dbd3..c5801044f 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -1960,57 +1960,40 @@ void Client::CalcRestState() { void Client::DoTracking() { - if(TrackingID == 0) + if (TrackingID == 0) return; Mob *m = entity_list.GetMob(TrackingID); - if(!m || m->IsCorpse()) - { + if (!m || m->IsCorpse()) { Message_StringID(MT_Skills, TRACK_LOST_TARGET); - TrackingID = 0; - return; } float RelativeHeading = GetHeading() - CalculateHeadingToTarget(m->GetX(), m->GetY()); - if(RelativeHeading < 0) - RelativeHeading += 256; + if (RelativeHeading < 0) + RelativeHeading += 512; - if((RelativeHeading <= 16) || (RelativeHeading >= 240)) - { + if (RelativeHeading > 480) Message_StringID(MT_Skills, TRACK_STRAIGHT_AHEAD, m->GetCleanName()); - } - else if((RelativeHeading > 16) && (RelativeHeading <= 48)) - { - Message_StringID(MT_Skills, TRACK_AHEAD_AND_TO, m->GetCleanName(), "right"); - } - else if((RelativeHeading > 48) && (RelativeHeading <= 80)) - { - Message_StringID(MT_Skills, TRACK_TO_THE, m->GetCleanName(), "right"); - } - else if((RelativeHeading > 80) && (RelativeHeading <= 112)) - { - Message_StringID(MT_Skills, TRACK_BEHIND_AND_TO, m->GetCleanName(), "right"); - } - else if((RelativeHeading > 112) && (RelativeHeading <= 144)) - { - Message_StringID(MT_Skills, TRACK_BEHIND_YOU, m->GetCleanName()); - } - else if((RelativeHeading > 144) && (RelativeHeading <= 176)) - { - Message_StringID(MT_Skills, TRACK_BEHIND_AND_TO, m->GetCleanName(), "left"); - } - else if((RelativeHeading > 176) && (RelativeHeading <= 208)) - { - Message_StringID(MT_Skills, TRACK_TO_THE, m->GetCleanName(), "left"); - } - else if((RelativeHeading > 208) && (RelativeHeading < 240)) - { + else if (RelativeHeading > 416) Message_StringID(MT_Skills, TRACK_AHEAD_AND_TO, m->GetCleanName(), "left"); - } + else if (RelativeHeading > 352) + Message_StringID(MT_Skills, TRACK_TO_THE, m->GetCleanName(), "left"); + else if (RelativeHeading > 288) + Message_StringID(MT_Skills, TRACK_BEHIND_AND_TO, m->GetCleanName(), "left"); + else if (RelativeHeading > 224) + Message_StringID(MT_Skills, TRACK_BEHIND_YOU, m->GetCleanName()); + else if (RelativeHeading > 160) + Message_StringID(MT_Skills, TRACK_BEHIND_AND_TO, m->GetCleanName(), "right"); + else if (RelativeHeading > 96) + Message_StringID(MT_Skills, TRACK_TO_THE, m->GetCleanName(), "right"); + else if (RelativeHeading > 32) + Message_StringID(MT_Skills, TRACK_AHEAD_AND_TO, m->GetCleanName(), "right"); + else if (RelativeHeading >= 0) + Message_StringID(MT_Skills, TRACK_STRAIGHT_AHEAD, m->GetCleanName()); } void Client::HandleRespawnFromHover(uint32 Option) diff --git a/zone/command.cpp b/zone/command.cpp index 7a4366a4f..179a37ded 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -8759,7 +8759,7 @@ void command_object(Client *c, const Seperator *sep) od.x = c->GetX(); od.y = c->GetY(); od.z = c->GetZ() - (c->GetSize() * 0.625f); - od.heading = c->GetHeading() * 2.0f; // GetHeading() is half of actual. Compensate by doubling. + od.heading = c->GetHeading(); std::string query; if (id) { @@ -8864,11 +8864,9 @@ void command_object(Client *c, const Seperator *sep) // Bump player back to avoid getting stuck inside new object - // GetHeading() returns half of the actual heading, for some reason, so we'll double it here for - // computation - x2 = 10.0f * sin(c->GetHeading() * 2.0f / 256.0f * 3.14159265f); - y2 = 10.0f * cos(c->GetHeading() * 2.0f / 256.0f * 3.14159265f); - c->MovePC(c->GetX() - x2, c->GetY() - y2, c->GetZ(), c->GetHeading() * 2); + x2 = 10.0f * sin(c->GetHeading() / 256.0f * 3.14159265f); + y2 = 10.0f * cos(c->GetHeading() / 256.0f * 3.14159265f); + c->MovePC(c->GetX() - x2, c->GetY() - y2, c->GetZ(), c->GetHeading()); c->Message(0, "Spawning object with tentative id %u at location (%.1f, %.1f, %.1f heading %.1f). Use " "'#object Save' to save to database when satisfied with placement.", @@ -9186,14 +9184,13 @@ void command_object(Client *c, const Seperator *sep) (c->GetSize() * 0.625f); // Compensate for #loc bumping up Z coordinate by 62.5% of character's size. - o->SetHeading(c->GetHeading() * 2.0f); // Compensate for GetHeading() returning half of actual + o->SetHeading(c->GetHeading()); // Bump player back to avoid getting stuck inside object - // GetHeading() returns half of the actual heading, for some reason - x2 = 10.0f * sin(c->GetHeading() * 2.0f / 256.0f * 3.14159265f); - y2 = 10.0f * cos(c->GetHeading() * 2.0f / 256.0f * 3.14159265f); - c->MovePC(c->GetX() - x2, c->GetY() - y2, c->GetZ(), c->GetHeading() * 2.0f); + x2 = 10.0f * std::sin(c->GetHeading() / 256.0f * 3.14159265f); + y2 = 10.0f * std::cos(c->GetHeading() / 256.0f * 3.14159265f); + c->MovePC(c->GetX() - x2, c->GetY() - y2, c->GetZ(), c->GetHeading()); } // Move to x, y, z [h] else { od.x = atof(sep->arg[3]); diff --git a/zone/mob.cpp b/zone/mob.cpp index 0c0e20d81..3e9aff746 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -1109,7 +1109,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName)); } - ns->spawn.heading = FloatToEQ19(m_Position.w); + ns->spawn.heading = FloatToEQ12(m_Position.w); ns->spawn.x = FloatToEQ19(m_Position.x);//((int32)x_pos)<<3; ns->spawn.y = FloatToEQ19(m_Position.y);//((int32)y_pos)<<3; ns->spawn.z = FloatToEQ19(m_Position.z);//((int32)z_pos)<<3; @@ -1515,12 +1515,12 @@ void Mob::MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct *spu) { spu->x_pos = FloatToEQ19(m_Position.x); spu->y_pos = FloatToEQ19(m_Position.y); spu->z_pos = FloatToEQ19(m_Position.z); - spu->delta_x = NewFloatToEQ13(0); - spu->delta_y = NewFloatToEQ13(0); - spu->delta_z = NewFloatToEQ13(0); - spu->heading = FloatToEQ19(m_Position.w); + spu->delta_x = FloatToEQ13(0); + spu->delta_y = FloatToEQ13(0); + spu->delta_z = FloatToEQ13(0); + spu->heading = FloatToEQ12(m_Position.w); spu->animation = 0; - spu->delta_heading = NewFloatToEQ13(0); + spu->delta_heading = FloatToEQ10(0); spu->padding0002 = 0; spu->padding0006 = 7; spu->padding0014 = 0x7f; @@ -1534,10 +1534,10 @@ void Mob::MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu) { spu->x_pos = FloatToEQ19(m_Position.x); spu->y_pos = FloatToEQ19(m_Position.y); spu->z_pos = FloatToEQ19(m_Position.z); - spu->delta_x = NewFloatToEQ13(m_Delta.x); - spu->delta_y = NewFloatToEQ13(m_Delta.y); - spu->delta_z = NewFloatToEQ13(m_Delta.z); - spu->heading = FloatToEQ19(m_Position.w); + spu->delta_x = FloatToEQ13(m_Delta.x); + spu->delta_y = FloatToEQ13(m_Delta.y); + spu->delta_z = FloatToEQ13(m_Delta.z); + spu->heading = FloatToEQ12(m_Position.w); spu->padding0002 = 0; spu->padding0006 = 7; spu->padding0014 = 0x7f; @@ -1551,7 +1551,7 @@ void Mob::MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu) { else spu->animation = pRunAnimSpeed;//animation; - spu->delta_heading = NewFloatToEQ13(m_Delta.w); + spu->delta_heading = FloatToEQ10(m_Delta.w); } void Mob::ShowStats(Client* client) @@ -2438,18 +2438,18 @@ float Mob::MobAngle(Mob *other, float ourx, float oury) const { float mobx = -(other->GetX()); // mob xloc (inverse because eq) float moby = other->GetY(); // mob yloc float heading = other->GetHeading(); // mob heading - heading = (heading * 360.0f) / 256.0f; // convert to degrees + heading = (heading * 360.0f) / 512.0f; // convert to degrees if (heading < 270) heading += 90; else heading -= 270; heading = heading * 3.1415f / 180.0f; // convert to radians - vectorx = mobx + (10.0f * cosf(heading)); // create a vector based on heading - vectory = moby + (10.0f * sinf(heading)); // of mob length 10 + vectorx = mobx + (10.0f * std::cos(heading)); // create a vector based on heading + vectory = moby + (10.0f * std::sin(heading)); // of mob length 10 // length of mob to player vector - lengthb = (float) sqrtf(((-ourx - mobx) * (-ourx - mobx)) + ((oury - moby) * (oury - moby))); + lengthb = (float) std::sqrt(((-ourx - mobx) * (-ourx - mobx)) + ((oury - moby) * (oury - moby))); // calculate dot product to get angle // Handle acos domain errors due to floating point rounding errors @@ -2462,7 +2462,7 @@ float Mob::MobAngle(Mob *other, float ourx, float oury) const { else if (dotp < -1) return 180.0f; - angle = acosf(dotp); + angle = std::acos(dotp); angle = angle * 180.0f / 3.1415f; return angle; @@ -2631,7 +2631,7 @@ bool Mob::PlotPositionAroundTarget(Mob* target, float &x_dest, float &y_dest, fl look_heading = target->GetHeading(); // Convert to sony heading to radians - look_heading = (look_heading / 256.0f) * 6.283184f; + look_heading = (look_heading / 512.0f) * 6.283184f; float tempX = 0; float tempY = 0; @@ -4676,16 +4676,16 @@ void Mob::DoKnockback(Mob *caster, uint32 pushback, uint32 pushup) spu->x_pos = FloatToEQ19(GetX()); spu->y_pos = FloatToEQ19(GetY()); spu->z_pos = FloatToEQ19(GetZ()); - spu->delta_x = NewFloatToEQ13(static_cast(new_x)); - spu->delta_y = NewFloatToEQ13(static_cast(new_y)); - spu->delta_z = NewFloatToEQ13(static_cast(pushup)); - spu->heading = FloatToEQ19(GetHeading()); + spu->delta_x = FloatToEQ13(static_cast(new_x)); + spu->delta_y = FloatToEQ13(static_cast(new_y)); + spu->delta_z = FloatToEQ13(static_cast(pushup)); + spu->heading = FloatToEQ12(GetHeading()); spu->padding0002 =0; spu->padding0006 =7; spu->padding0014 =0x7f; spu->padding0018 =0x5df27; spu->animation = 0; - spu->delta_heading = NewFloatToEQ13(0); + spu->delta_heading = FloatToEQ10(0); outapp_push->priority = 6; entity_list.QueueClients(this, outapp_push, true); CastToClient()->FastQueuePacket(&outapp_push); @@ -5003,7 +5003,7 @@ void Mob::DoGravityEffect() } if(IsClient()) - this->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), cur_x, cur_y, new_ground, GetHeading()*2); // I know the heading thing is weird(chance of movepc to halve the heading value, too lazy to figure out why atm) + this->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), cur_x, cur_y, new_ground, GetHeading()); else this->GMMove(cur_x, cur_y, new_ground, GetHeading()); } @@ -5640,8 +5640,7 @@ bool Mob::IsFacingMob(Mob *other) if (!other) return false; float angle = HeadingAngleToMob(other); - // what the client uses appears to be 2x our internal heading - float heading = GetHeading() * 2.0f; + float heading = GetHeading(); if (angle > 472.0 && heading < 40.0) angle = heading; @@ -5655,15 +5654,13 @@ bool Mob::IsFacingMob(Mob *other) } // All numbers derived from the client -float Mob::HeadingAngleToMob(Mob *other) +float Mob::HeadingAngleToMob(float other_x, float other_y) { - float mob_x = other->GetX(); - float mob_y = other->GetY(); float this_x = GetX(); float this_y = GetY(); - float y_diff = std::abs(this_y - mob_y); - float x_diff = std::abs(this_x - mob_x); + float y_diff = std::abs(this_y - other_y); + float x_diff = std::abs(this_x - other_x); if (y_diff < 0.0000009999999974752427) y_diff = 0.0000009999999974752427; @@ -5671,13 +5668,13 @@ float Mob::HeadingAngleToMob(Mob *other) // 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) + if (this_y >= other_y) { + if (other_x >= this_x) return (90.0f - angle + 90.0f) * 511.5f * 0.0027777778f; - if (mob_x <= this_x) + if (other_x <= this_x) return (angle + 180.0f) * 511.5f * 0.0027777778f; } - if (this_y > mob_y || mob_x > this_x) + if (this_y > other_y || other_x > this_x) return angle * 511.5f * 0.0027777778f; else return (90.0f - angle + 270.0f) * 511.5f * 0.0027777778f; diff --git a/zone/mob.h b/zone/mob.h index c223a45b4..23c0004df 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -177,7 +177,8 @@ public: 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 + float HeadingAngleToMob(Mob *other) { return HeadingAngleToMob(other->GetX(), other->GetY()); } + float HeadingAngleToMob(float other_x, float other_y); // to keep consistent with client generated messages virtual void RangedAttack(Mob* other) { } virtual void ThrowingAttack(Mob* other) { } // 13 = Primary (default), 14 = secondary @@ -970,7 +971,7 @@ public: inline bool IsBlind() { return spellbonuses.IsBlind; } inline bool CheckAggro(Mob* other) {return hate_list.IsEntOnHateList(other);} - float CalculateHeadingToTarget(float in_x, float in_y); + float CalculateHeadingToTarget(float in_x, float in_y) {return HeadingAngleToMob(in_x, in_y); } bool CalculateNewPosition(float x, float y, float z, int speed, bool checkZ = false, bool calcHeading = true); virtual bool CalculateNewPosition2(float x, float y, float z, int speed, bool checkZ = true, bool calcHeading = true); float CalculateDistance(float x, float y, float z); diff --git a/zone/position.cpp b/zone/position.cpp index 798ff145c..22885b4b1 100644 --- a/zone/position.cpp +++ b/zone/position.cpp @@ -150,13 +150,13 @@ float GetReciprocalHeading(const float heading) float result = 0; // Convert to radians - float h = (heading / 256.0f) * 6.283184f; + float h = (heading / 512.0f) * 6.283184f; // Calculate the reciprocal heading in radians result = h + 3.141592f; // Convert back to eq heading from radians - result = (result / 6.283184f) * 256.0f; + result = (result / 6.283184f) * 512.0f; return result; } diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 5f0305f3a..480479b2f 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -2115,16 +2115,16 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove spu->x_pos = FloatToEQ19(GetX()); spu->y_pos = FloatToEQ19(GetY()); spu->z_pos = FloatToEQ19(GetZ()); - spu->delta_x = NewFloatToEQ13(new_x); - spu->delta_y = NewFloatToEQ13(new_y); - spu->delta_z = NewFloatToEQ13(toss_amt); - spu->heading = FloatToEQ19(GetHeading()); + spu->delta_x = FloatToEQ13(new_x); + spu->delta_y = FloatToEQ13(new_y); + spu->delta_z = FloatToEQ13(toss_amt); + spu->heading = FloatToEQ12(GetHeading()); spu->padding0002 =0; spu->padding0006 =7; spu->padding0014 =0x7f; spu->padding0018 =0x5df27; spu->animation = 0; - spu->delta_heading = NewFloatToEQ13(0); + spu->delta_heading = FloatToEQ10(0); outapp_push->priority = 5; entity_list.QueueClients(this, outapp_push, true); if(IsClient()) @@ -2654,7 +2654,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove float new_ground = GetGroundZ(my_x, my_y); if(caster->IsClient()) - caster->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), my_x, my_y, new_ground, GetHeading()*2); + caster->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), my_x, my_y, new_ground, GetHeading()); else caster->GMMove(my_x, my_y, new_ground, GetHeading()); } diff --git a/zone/spells.cpp b/zone/spells.cpp index 8117a8018..78ef657aa 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -2646,7 +2646,7 @@ void Mob::BardPulse(uint16 spell_id, Mob *caster) { action->source = caster->GetID(); action->target = GetID(); action->spell = spell_id; - action->sequence = (uint32) (GetHeading() * 2); // just some random number + action->sequence = (uint32) (GetHeading()); // just some random number action->instrument_mod = caster->GetInstrumentMod(spell_id); action->buff_unknown = 0; action->level = buffs[buffs_i].casterlevel; @@ -2686,16 +2686,16 @@ void Mob::BardPulse(uint16 spell_id, Mob *caster) { spu->x_pos = FloatToEQ19(GetX()); spu->y_pos = FloatToEQ19(GetY()); spu->z_pos = FloatToEQ19(GetZ()); - spu->delta_x = NewFloatToEQ13(new_x); - spu->delta_y = NewFloatToEQ13(new_y); - spu->delta_z = NewFloatToEQ13(spells[spell_id].pushup); - spu->heading = FloatToEQ19(GetHeading()); + spu->delta_x = FloatToEQ13(new_x); + spu->delta_y = FloatToEQ13(new_y); + spu->delta_z = FloatToEQ13(spells[spell_id].pushup); + spu->heading = FloatToEQ12(GetHeading()); spu->padding0002 =0; spu->padding0006 =7; spu->padding0014 =0x7f; spu->padding0018 =0x5df27; spu->animation = 0; - spu->delta_heading = NewFloatToEQ13(0); + spu->delta_heading = FloatToEQ10(0); outapp_push->priority = 6; entity_list.QueueClients(this, outapp_push, true); CastToClient()->FastQueuePacket(&outapp_push); @@ -3530,7 +3530,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r action->level = caster_level; // caster level, for animation only action->type = 231; // 231 means a spell action->spell = spell_id; - action->sequence = (uint32) (GetHeading() * 2); // just some random number + action->sequence = (uint32) (GetHeading()); // just some random number action->instrument_mod = GetInstrumentMod(spell_id); action->buff_unknown = 0; @@ -3992,16 +3992,16 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r spu->x_pos = FloatToEQ19(spelltar->GetX()); spu->y_pos = FloatToEQ19(spelltar->GetY()); spu->z_pos = FloatToEQ19(spelltar->GetZ()); - spu->delta_x = NewFloatToEQ13(new_x); - spu->delta_y = NewFloatToEQ13(new_y); - spu->delta_z = NewFloatToEQ13(spells[spell_id].pushup); - spu->heading = FloatToEQ19(spelltar->GetHeading()); + spu->delta_x = FloatToEQ13(new_x); + spu->delta_y = FloatToEQ13(new_y); + spu->delta_z = FloatToEQ13(spells[spell_id].pushup); + spu->heading = FloatToEQ12(spelltar->GetHeading()); spu->padding0002 =0; spu->padding0006 =7; spu->padding0014 =0x7f; spu->padding0018 =0x5df27; spu->animation = 0; - spu->delta_heading = NewFloatToEQ13(0); + spu->delta_heading = FloatToEQ10(0); outapp_push->priority = 6; entity_list.QueueClients(this, outapp_push, true); spelltar->CastToClient()->FastQueuePacket(&outapp_push); @@ -5727,8 +5727,8 @@ void Mob::CalcDestFromHeading(float heading, float distance, float MaxZDiff, flo if (!distance) { return; } if (!MaxZDiff) { MaxZDiff = 5; } - float ReverseHeading = 256 - heading; - float ConvertAngle = ReverseHeading * 1.40625f; + float ReverseHeading = 512 - heading; + float ConvertAngle = ReverseHeading * 360.0f / 512.0f; if (ConvertAngle <= 270) ConvertAngle = ConvertAngle + 90; else @@ -5736,8 +5736,8 @@ void Mob::CalcDestFromHeading(float heading, float distance, float MaxZDiff, flo float Radian = ConvertAngle * (3.1415927f / 180.0f); - float CircleX = distance * cos(Radian); - float CircleY = distance * sin(Radian); + float CircleX = distance * std::cos(Radian); + float CircleY = distance * std::sin(Radian); dX = CircleX + StartX; dY = CircleY + StartY; dZ = FindGroundZ(dX, dY, MaxZDiff); @@ -5802,7 +5802,8 @@ void Mob::BeamDirectional(uint16 spell_id, int16 resist_adjust) maxtarget_count++; } - if (maxtarget_count >= spells[spell_id].aemaxtargets) + // not sure if we need this check, but probably do, need to check if it should be default limited or not + if (spells[spell_id].aemaxtargets && maxtarget_count >= spells[spell_id].aemaxtargets) return; } ++iter; @@ -5817,8 +5818,10 @@ void Mob::ConeDirectional(uint16 spell_id, int16 resist_adjust) if (IsBeneficialSpell(spell_id) && IsClient()) beneficial_targets = true; - float angle_start = spells[spell_id].directional_start + (GetHeading() * 360.0f / 256.0f); - float angle_end = spells[spell_id].directional_end + (GetHeading() * 360.0f / 256.0f); + float heading = GetHeading() * 360.0f / 512.0f; // convert to degrees + + float angle_start = spells[spell_id].directional_start + heading; + float angle_end = spells[spell_id].directional_end + heading; while (angle_start > 360.0f) angle_start -= 360.0f; @@ -5839,7 +5842,7 @@ void Mob::ConeDirectional(uint16 spell_id, int16 resist_adjust) } float heading_to_target = - (CalculateHeadingToTarget((*iter)->GetX(), (*iter)->GetY()) * 360.0f / 256.0f); + (CalculateHeadingToTarget((*iter)->GetX(), (*iter)->GetY()) * 360.0f / 512.0f); while (heading_to_target < 0.0f) heading_to_target += 360.0f; @@ -5883,7 +5886,8 @@ void Mob::ConeDirectional(uint16 spell_id, int16 resist_adjust) } } - if (maxtarget_count >= spells[spell_id].aemaxtargets) + // my SHM breath could hit all 5 dummies I could summon in arena + if (spells[spell_id].aemaxtargets && maxtarget_count >= spells[spell_id].aemaxtargets) return; ++iter; diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 8f9c902bb..45d199277 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -435,27 +435,6 @@ float Mob::CalculateDistance(float x, float y, float z) { return (float)sqrtf(((m_Position.x - x)*(m_Position.x - x)) + ((m_Position.y - y)*(m_Position.y - y)) + ((m_Position.z - z)*(m_Position.z - z))); } -float Mob::CalculateHeadingToTarget(float in_x, float in_y) { - float angle; - - if (in_x - m_Position.x > 0) - angle = -90 + atan((float)(in_y - m_Position.y) / (float)(in_x - m_Position.x)) * 180 / M_PI; - else if (in_x - m_Position.x < 0) - angle = +90 + atan((float)(in_y - m_Position.y) / (float)(in_x - m_Position.x)) * 180 / M_PI; - else // Added? - { - if (in_y - m_Position.y > 0) - angle = 0; - else - angle = 180; - } - if (angle < 0) - angle += 360; - if (angle > 360) - angle -= 360; - return (256 * (360 - angle) / 360.0f); -} - bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, bool checkZ, bool calcHeading) { if (GetID() == 0) return true;