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:
Michael Cook (mackal)
2018-02-15 18:20:16 -05:00
parent 91d3851d76
commit a32dedeb48
17 changed files with 169 additions and 162 deletions
+10 -4
View File
@@ -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;
+5 -5
View File
@@ -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));
+20 -37
View File
@@ -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)
+8 -11
View File
@@ -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]);
+31 -34
View File
@@ -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;
+3 -2
View File
@@ -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);
+2 -2
View File
@@ -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;
}
+6 -6
View File
@@ -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());
}
+25 -21
View File
@@ -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;
-21
View File
@@ -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;