mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-14 15:41:30 +00:00
Fix issue with heading being incorrectly handled
So we've been doing heading wrong all these years. You will need to run a script to fix your quests and required SQL to fix DB. This fixes a ton of random issues with headings and as gives us a better resolution on headings :P
This commit is contained in:
parent
91d3851d76
commit
a32dedeb48
@ -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
|
||||
|
||||
|
||||
@ -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<float>(d) / 64.0f;
|
||||
}
|
||||
|
||||
float EQ19toFloat(int d)
|
||||
{
|
||||
return ( float(d)/float(1<<3));
|
||||
return static_cast<float>(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<int>(d * 64.0f);
|
||||
}
|
||||
|
||||
int FloatToEQ19(float d)
|
||||
{
|
||||
return int(d*float(1<<3));
|
||||
return static_cast<int>(d * 8.0f);
|
||||
}
|
||||
|
||||
float EQ12toFloat(int d)
|
||||
{
|
||||
return static_cast<float>(d) / 4.0f;
|
||||
}
|
||||
|
||||
int FloatToEQ12(float d)
|
||||
{
|
||||
return static_cast<int>((d + 2048.0f) * 4.0f) % 2048;
|
||||
}
|
||||
|
||||
float EQ10toFloat(int d)
|
||||
{
|
||||
return static_cast<float>(d) / 20.0f;
|
||||
}
|
||||
|
||||
int FloatToEQ10(float d)
|
||||
{
|
||||
return static_cast<int>(d * 20.0f);
|
||||
}
|
||||
|
||||
float EQSpeedRunToFloat(int d)
|
||||
{
|
||||
return static_cast<float>(d) / 40.0f;
|
||||
}
|
||||
|
||||
int FloatToEQSpeedRun(float d)
|
||||
{
|
||||
return static_cast<int>(d * 40.0f);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
3
utils/sql/git/required/2018_02_13_Heading.sql
Normal file
3
utils/sql/git/required/2018_02_13_Heading.sql
Normal file
@ -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
|
||||
@ -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;
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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]);
|
||||
|
||||
65
zone/mob.cpp
65
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<float>(new_x));
|
||||
spu->delta_y = NewFloatToEQ13(static_cast<float>(new_y));
|
||||
spu->delta_z = NewFloatToEQ13(static_cast<float>(pushup));
|
||||
spu->heading = FloatToEQ19(GetHeading());
|
||||
spu->delta_x = FloatToEQ13(static_cast<float>(new_x));
|
||||
spu->delta_y = FloatToEQ13(static_cast<float>(new_y));
|
||||
spu->delta_z = FloatToEQ13(static_cast<float>(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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user