diff --git a/zone/bot.cpp b/zone/bot.cpp index 23163d1de..2336b8c8d 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -1827,7 +1827,6 @@ bool Bot::Process() { if(tic_timer.Check()) { //6 seconds, or whatever the rule is set to has passed, send this position to everyone to avoid ghosting if(!IsMoving() && !IsEngaged()) { - SendPosition(); if(IsSitting()) { if(!rest_timer.Enabled()) rest_timer.Start(RuleI(Character, RestRegenTimeToActivate) * 1000); @@ -2717,8 +2716,6 @@ void Bot::AI_Process() { else { if (IsMoving()) StopMoving(); - else - SendPosition(); return; } @@ -2743,8 +2740,6 @@ void Bot::AI_Process() { } // end not in combat range if (!IsMoving() && !spellend_timer.Enabled()) { // This may actually need work... - SendPosition(); - if (GetBotStance() == BotStancePassive) return; @@ -3028,8 +3023,7 @@ void Bot::PetAIProcess() { if(moved) { moved = false; StopNavigation(); - botPet->SendPosition(); - botPet->SetMoving(false); + botPet->StopNavigation(); } } } @@ -3056,8 +3050,7 @@ void Bot::PetAIProcess() { if(moved) { moved = false; StopNavigation(); - botPet->SendPosition(); - botPet->SetMoving(false); + botPet->StopNavigation(); } } break; @@ -3119,7 +3112,7 @@ bool Bot::Spawn(Client* botCharacterOwner) { entity_list.AddBot(this, true, true); // Load pet LoadPet(); - this->SendPosition(); + SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0); // there is something askew with spawn struct appearance fields... // I re-enabled this until I can sort it out uint32 itemID = 0; diff --git a/zone/client.cpp b/zone/client.cpp index 462c9c679..45ce6791c 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -6116,7 +6116,7 @@ void Client::LocateCorpse() SetHeading(CalculateHeadingToTarget(ClosestCorpse->GetX(), ClosestCorpse->GetY())); SetTarget(ClosestCorpse); SendTargetCommand(ClosestCorpse->GetID()); - SendPositionUpdate(true); + SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0, true); } else if(!GetTarget()) Message_StringID(clientMessageError, SENSE_CORPSE_NONE); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 8d6ec0328..16691e370 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -10030,7 +10030,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsNPC()) { mypet->SayTo_StringID(this, MT_PetResponse, PET_GUARDINGLIFE); mypet->SetPetOrder(SPO_Guard); - mypet->CastToNPC()->SaveGuardSpot(); + mypet->CastToNPC()->SaveGuardSpot(mypet->GetPosition()); if (!mypet->GetTarget()) // want them to not twitch if they're chasing something down mypet->StopNavigation(); if (mypet->IsPetStop()) { diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 87c6d8a49..12c9a91be 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -122,7 +122,7 @@ bool Client::Process() { /* I haven't naturally updated my position in 10 seconds, updating manually */ if (!is_client_moving && position_update_timer.Check()) { - SendPositionUpdate(); + SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0); } if (mana_timer.Check()) diff --git a/zone/command.cpp b/zone/command.cpp index b0bdc35be..9c2008afb 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -1022,7 +1022,7 @@ void command_summon(Client *c, const Seperator *sep) { // npc target c->Message(0, "Summoning NPC %s to %1.1f, %1.1f, %1.1f", t->GetName(), c->GetX(), c->GetY(), c->GetZ()); t->CastToNPC()->GMMove(c->GetX(), c->GetY(), c->GetZ(), c->GetHeading()); - t->CastToNPC()->SaveGuardSpot(true); + t->CastToNPC()->SaveGuardSpot(glm::vec4(0.0f)); } else if (t->IsCorpse()) { // corpse target @@ -1842,7 +1842,7 @@ void command_ai(Client *c, const Seperator *sep) } else if (strcasecmp(sep->arg[1], "guard") == 0) { if (target && target->IsNPC()) - target->CastToNPC()->SaveGuardSpot(); + target->CastToNPC()->SaveGuardSpot(target->GetPosition()); else c->Message(0, "Usage: (targeted) #ai guard - sets npc to guard the current location (use #summon to move)"); } @@ -8473,9 +8473,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep) } c->Message(0, "Updating coordinates successful."); - target->CastToNPC()->GMMove(c->GetX(), c->GetY(), c->GetZ(), c->GetHeading()); - target->CastToNPC()->SaveGuardSpot(true); - target->SendPosition(); + target->GMMove(c->GetX(), c->GetY(), c->GetZ(), c->GetHeading()); return; } diff --git a/zone/lua_npc.cpp b/zone/lua_npc.cpp index a16d78361..88def208a 100644 --- a/zone/lua_npc.cpp +++ b/zone/lua_npc.cpp @@ -308,14 +308,9 @@ void Lua_NPC::NextGuardPosition() { self->NextGuardPosition(); } -void Lua_NPC::SaveGuardSpot() { +void Lua_NPC::SaveGuardSpot(float x, float y, float z, float heading) { Lua_Safe_Call_Void(); - self->SaveGuardSpot(); -} - -void Lua_NPC::SaveGuardSpot(bool clear) { - Lua_Safe_Call_Void(); - self->SaveGuardSpot(clear); + self->SaveGuardSpot(glm::vec4(x, y, z, heading)); } bool Lua_NPC::IsGuarding() { @@ -567,8 +562,7 @@ luabind::scope lua_register_npc() { .def("PauseWandering", (void(Lua_NPC::*)(int))&Lua_NPC::PauseWandering) .def("MoveTo", (void(Lua_NPC::*)(float,float,float,float,bool))&Lua_NPC::MoveTo) .def("NextGuardPosition", (void(Lua_NPC::*)(void))&Lua_NPC::NextGuardPosition) - .def("SaveGuardSpot", (void(Lua_NPC::*)(void))&Lua_NPC::SaveGuardSpot) - .def("SaveGuardSpot", (void(Lua_NPC::*)(bool))&Lua_NPC::SaveGuardSpot) + .def("SaveGuardSpot", (void(Lua_NPC::*)(float,float,float,float))&Lua_NPC::SaveGuardSpot) .def("IsGuarding", (bool(Lua_NPC::*)(void))&Lua_NPC::IsGuarding) .def("AI_SetRoambox", (void(Lua_NPC::*)(float,float,float,float,float))&Lua_NPC::AI_SetRoambox) .def("AI_SetRoambox", (void(Lua_NPC::*)(float,float,float,float,float,uint32,uint32))&Lua_NPC::AI_SetRoambox) diff --git a/zone/lua_npc.h b/zone/lua_npc.h index 972adee90..5edb7b68a 100644 --- a/zone/lua_npc.h +++ b/zone/lua_npc.h @@ -87,8 +87,7 @@ public: void PauseWandering(int pause_time); void MoveTo(float x, float y, float z, float h, bool save); void NextGuardPosition(); - void SaveGuardSpot(); - void SaveGuardSpot(bool clear); + void SaveGuardSpot(float x, float y, float z, float heading); bool IsGuarding(); void AI_SetRoambox(float dist, float max_x, float min_x, float max_y, float min_y); void AI_SetRoambox(float dist, float max_x, float min_x, float max_y, float min_y, uint32 delay, uint32 mindelay); diff --git a/zone/merc.cpp b/zone/merc.cpp index c7bd12765..f8d4469de 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -1271,7 +1271,7 @@ bool Merc::Process() //6 seconds, or whatever the rule is set to has passed, send this position to everyone to avoid ghosting if(!IsMoving() && !IsEngaged()) { - SendPosition(); + SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0); if(IsSitting()) { if(!rest_timer.Enabled()) { rest_timer.Start(RuleI(Character, RestRegenTimeToActivate) * 1000); @@ -1568,10 +1568,10 @@ void Merc::AI_Process() { } } - if (IsMoving()) - SendPositionUpdate(); - else - SendPosition(); + //if (IsMoving()) + // SendPositionUpdate(); + //else + // SendPosition(); } if(!IsMercCaster() && GetTarget() && !IsStunned() && !IsMezzed() && (GetAppearance() != eaDead)) @@ -1693,10 +1693,10 @@ void Merc::AI_Process() { return; } - if(IsMoving()) - SendPositionUpdate(); - else - SendPosition(); + //if(IsMoving()) + // SendPositionUpdate(); + //else + // SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0); } } // end not in combat range @@ -1791,7 +1791,7 @@ void Merc::AI_Start(int32 iMoveDelay) { } SendTo(GetX(), GetY(), GetZ()); - SaveGuardSpot(); + SaveGuardSpot(GetPosition()); } void Merc::AI_Stop() { @@ -1990,7 +1990,7 @@ bool Merc::AIDoSpellCast(uint16 spellid, Mob* tar, int32 mana_cost, uint32* oDon || dist2 <= GetActSpellRange(spellid, spells[spellid].range)*GetActSpellRange(spellid, spells[spellid].range)) && (mana_cost <= GetMana() || GetMana() == GetMaxMana())) { SetRunAnimSpeed(0); - SendPosition(); + SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0); SetMoving(false); result = CastSpell(spellid, tar->GetID(), EQEmu::CastingSlot::Gem2, -1, mana_cost, oDontDoAgainBefore, -1, -1, 0, 0); @@ -4360,7 +4360,7 @@ void Merc::Sit() { if(IsMoving()) { moved = false; // SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY())); - SendPosition(); + SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0); SetMoving(false); } @@ -5128,7 +5128,7 @@ bool Merc::Spawn(Client *owner) { entity_list.AddMerc(this, true, true); - SendPosition(); + SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0); Log(Logs::General, Logs::Mercenaries, "Spawn Mercenary %s.", GetName()); diff --git a/zone/mob.cpp b/zone/mob.cpp index 71f805d86..b9c6f1af3 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -159,7 +159,7 @@ Mob::Mob(const char* in_name, if (runspeed < 0 || runspeed > 20) runspeed = 1.25f; base_runspeed = (int)((float)runspeed * 40.0f); - // clients + // clients -- todo movement this doesn't take into account gm speed we need to fix that. if (runspeed == 0.7f) { base_runspeed = 28; walkspeed = 0.3f; @@ -1475,14 +1475,24 @@ void Mob::StopMoving(float new_heading) { moved = false; } -/* Used for mobs standing still - this does not send a delta */ -void Mob::SendPosition() { - //mMovementManager->SendPosition(this); -} +void Mob::SentPositionPacket(float dx, float dy, float dz, float dh, int anim, bool send_to_self) +{ + EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); + PlayerPositionUpdateServer_Struct *spu = (PlayerPositionUpdateServer_Struct*)outapp.pBuffer; -/* Position updates for mobs on the move */ -void Mob::SendPositionUpdate(bool iSendToSelf) { - //mMovementManager->SendPositionUpdate(this, iSendToSelf); + memset(spu, 0x00, sizeof(PlayerPositionUpdateServer_Struct)); + spu->spawn_id = GetID(); + spu->x_pos = FloatToEQ19(GetX()); + spu->y_pos = FloatToEQ19(GetY()); + spu->z_pos = FloatToEQ19(GetZ()); + spu->heading = FloatToEQ12(GetHeading()); + spu->delta_x = FloatToEQ13(dx); + spu->delta_y = FloatToEQ13(dy); + spu->delta_z = FloatToEQ13(dz); + spu->delta_heading = FloatToEQ10(dh); + spu->animation = anim; + + entity_list.QueueClients(this, &outapp, send_to_self == false, false); } // this is for SendPosition() @@ -1646,19 +1656,11 @@ void Mob::ShowBuffList(Client* client) { } void Mob::GMMove(float x, float y, float z, float heading, bool SendUpdate) { - if(IsNPC()) { - entity_list.ProcessMove(CastToNPC(), x, y, z); - } + Teleport(glm::vec4(x, y, z, heading)); - m_Position.x = x; - m_Position.y = y; - m_Position.z = z; - if (m_Position.w != 0.01) - this->m_Position.w = heading; - if(IsNPC()) - CastToNPC()->SaveGuardSpot(true); - if(SendUpdate) - SendPosition(); + if (IsNPC()) { + CastToNPC()->SaveGuardSpot(glm::vec4(x, y, z, heading)); + } } void Mob::SendIllusionPacket(uint16 in_race, uint8 in_gender, uint8 in_texture, uint8 in_helmtexture, uint8 in_haircolor, uint8 in_beardcolor, uint8 in_eyecolor1, uint8 in_eyecolor2, uint8 in_hairstyle, uint8 in_luclinface, uint8 in_beard, uint8 in_aa_title, uint32 in_drakkin_heritage, uint32 in_drakkin_tattoo, uint32 in_drakkin_details, float in_size) { diff --git a/zone/mob.h b/zone/mob.h index cd8cc4185..0a56bbd84 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -557,10 +557,9 @@ public: void SetRunning(bool val) { m_is_running = val; } virtual void GMMove(float x, float y, float z, float heading = 0.01, bool SendUpdate = true); void SetDelta(const glm::vec4& delta); - void SendPositionUpdate(bool iSendToSelf = false); void MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct* spu); void MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu); - void SendPosition(); + void SentPositionPacket(float dx, float dy, float dz, float dh, int anim, bool send_to_self = false); void StopMoving(); void StopMoving(float new_heading); void SetSpawned() { spawned = true; }; diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 19c418f10..e7cccf320 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -555,7 +555,7 @@ void NPC::AI_Start(uint32 iMoveDelay) { } SendTo(GetX(), GetY(), GetZ()); - SaveGuardSpot(); + SaveGuardSpot(GetPosition()); } void Mob::AI_Stop() { @@ -910,7 +910,6 @@ void Client::AI_Process() float dist = DistanceSquared(m_Position, owner->GetPosition()); if (dist >= 202500) { // >= 450 distance Teleport(owner->GetPosition()); - SendPositionUpdate(); // this shouldn't happen a lot (and hard to make it) so lets not rate limit } else if (dist >= 400) { // >=20 if (AI_movement_timer->Check()) { if (dist >= 1225) { @@ -929,86 +928,86 @@ void Client::AI_Process() void Mob::ProcessForcedMovement() { - //// we are being pushed, we will hijack this movement timer - //// this also needs to be done before casting to have a chance to interrupt - //// this flag won't be set if the mob can't be pushed (rooted etc) - //if (AI_movement_timer->Check()) { - // bool bPassed = true; - // glm::vec3 normal; - // - // // no zone map = fucked - // if (zone->HasMap()) { - // // in front - // m_CollisionBox[0].x = m_Position.x + 3.0f * g_Math.FastSin(0.0f); - // m_CollisionBox[0].y = m_Position.y + 3.0f * g_Math.FastCos(0.0f); - // m_CollisionBox[0].z = m_Position.z; - // - // // 45 right front - // m_CollisionBox[1].x = m_Position.x + 3.0f * g_Math.FastSin(64.0f); - // m_CollisionBox[1].y = m_Position.y + 3.0f * g_Math.FastCos(64.0f); - // m_CollisionBox[1].z = m_Position.z; - // - // // to right - // m_CollisionBox[2].x = m_Position.x + 3.0f * g_Math.FastSin(128.0f); - // m_CollisionBox[2].y = m_Position.y + 3.0f * g_Math.FastCos(128.0f); - // m_CollisionBox[2].z = m_Position.z; - // - // // 45 right back - // m_CollisionBox[3].x = m_Position.x + 3.0f * g_Math.FastSin(192.0f); - // m_CollisionBox[3].y = m_Position.y + 3.0f * g_Math.FastCos(192.0f); - // m_CollisionBox[3].z = m_Position.z; - // - // // behind - // m_CollisionBox[4].x = m_Position.x + 3.0f * g_Math.FastSin(256.0f); - // m_CollisionBox[4].y = m_Position.y + 3.0f * g_Math.FastCos(256.0f); - // m_CollisionBox[4].z = m_Position.z; - // - // // 45 left back - // m_CollisionBox[5].x = m_Position.x + 3.0f * g_Math.FastSin(320.0f); - // m_CollisionBox[5].y = m_Position.y + 3.0f * g_Math.FastCos(320.0f); - // m_CollisionBox[5].z = m_Position.z; - // - // // to left - // m_CollisionBox[6].x = m_Position.x + 3.0f * g_Math.FastSin(384.0f); - // m_CollisionBox[6].y = m_Position.y + 3.0f * g_Math.FastCos(384.0f); - // m_CollisionBox[6].z = m_Position.z; - // - // // 45 left front - // m_CollisionBox[7].x = m_Position.x + 3.0f * g_Math.FastSin(448.0f); - // m_CollisionBox[7].y = m_Position.y + 3.0f * g_Math.FastCos(448.0f); - // m_CollisionBox[7].z = m_Position.z; - // - // // collision happened, need to move along the wall - // float distance = 0.0f, shortest = std::numeric_limits::infinity(); - // glm::vec3 tmp_nrm; - // for (auto &vec : m_CollisionBox) { - // if (zone->zonemap->DoCollisionCheck(vec, vec + m_Delta, tmp_nrm, distance)) { - // bPassed = false; // lets try with new projection next pass - // if (distance < shortest) { - // normal = tmp_nrm; - // shortest = distance; - // } - // } - // } - // } - // - // if (bPassed) { - // ForcedMovement = 0; - // Teleport(m_Position + m_Delta); - // m_Delta = glm::vec4(); - // SendPositionUpdate(); - // FixZ(); // so we teleport to the ground locally, we want the client to interpolate falling etc - // } else if (--ForcedMovement) { - // if (normal.z < -0.15f) // prevent too much wall climbing. ex. OMM's room in anguish - // normal.z = 0.0f; - // auto proj = glm::proj(static_cast(m_Delta), normal); - // m_Delta.x -= proj.x; - // m_Delta.y -= proj.y; - // m_Delta.z -= proj.z; - // } else { - // m_Delta = glm::vec4(); // well, we failed to find a spot to be forced to, lets give up - // } - //} + // we are being pushed, we will hijack this movement timer + // this also needs to be done before casting to have a chance to interrupt + // this flag won't be set if the mob can't be pushed (rooted etc) + if (AI_movement_timer->Check()) { + bool bPassed = true; + glm::vec3 normal; + + // no zone map = fucked + if (zone->HasMap()) { + // in front + m_CollisionBox[0].x = m_Position.x + 3.0f * g_Math.FastSin(0.0f); + m_CollisionBox[0].y = m_Position.y + 3.0f * g_Math.FastCos(0.0f); + m_CollisionBox[0].z = m_Position.z; + + // 45 right front + m_CollisionBox[1].x = m_Position.x + 3.0f * g_Math.FastSin(64.0f); + m_CollisionBox[1].y = m_Position.y + 3.0f * g_Math.FastCos(64.0f); + m_CollisionBox[1].z = m_Position.z; + + // to right + m_CollisionBox[2].x = m_Position.x + 3.0f * g_Math.FastSin(128.0f); + m_CollisionBox[2].y = m_Position.y + 3.0f * g_Math.FastCos(128.0f); + m_CollisionBox[2].z = m_Position.z; + + // 45 right back + m_CollisionBox[3].x = m_Position.x + 3.0f * g_Math.FastSin(192.0f); + m_CollisionBox[3].y = m_Position.y + 3.0f * g_Math.FastCos(192.0f); + m_CollisionBox[3].z = m_Position.z; + + // behind + m_CollisionBox[4].x = m_Position.x + 3.0f * g_Math.FastSin(256.0f); + m_CollisionBox[4].y = m_Position.y + 3.0f * g_Math.FastCos(256.0f); + m_CollisionBox[4].z = m_Position.z; + + // 45 left back + m_CollisionBox[5].x = m_Position.x + 3.0f * g_Math.FastSin(320.0f); + m_CollisionBox[5].y = m_Position.y + 3.0f * g_Math.FastCos(320.0f); + m_CollisionBox[5].z = m_Position.z; + + // to left + m_CollisionBox[6].x = m_Position.x + 3.0f * g_Math.FastSin(384.0f); + m_CollisionBox[6].y = m_Position.y + 3.0f * g_Math.FastCos(384.0f); + m_CollisionBox[6].z = m_Position.z; + + // 45 left front + m_CollisionBox[7].x = m_Position.x + 3.0f * g_Math.FastSin(448.0f); + m_CollisionBox[7].y = m_Position.y + 3.0f * g_Math.FastCos(448.0f); + m_CollisionBox[7].z = m_Position.z; + + // collision happened, need to move along the wall + float distance = 0.0f, shortest = std::numeric_limits::infinity(); + glm::vec3 tmp_nrm; + for (auto &vec : m_CollisionBox) { + if (zone->zonemap->DoCollisionCheck(vec, vec + m_Delta, tmp_nrm, distance)) { + bPassed = false; // lets try with new projection next pass + if (distance < shortest) { + normal = tmp_nrm; + shortest = distance; + } + } + } + } + + if (bPassed) { + ForcedMovement = 0; + Teleport(m_Position + m_Delta); + m_Delta = glm::vec4(); + SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0, true); + FixZ(); // so we teleport to the ground locally, we want the client to interpolate falling etc + } else if (--ForcedMovement) { + if (normal.z < -0.15f) // prevent too much wall climbing. ex. OMM's room in anguish + normal.z = 0.0f; + auto proj = glm::proj(static_cast(m_Delta), normal); + m_Delta.x -= proj.x; + m_Delta.y -= proj.y; + m_Delta.z -= proj.z; + } else { + m_Delta = glm::vec4(); // well, we failed to find a spot to be forced to, lets give up + } + } } void Mob::AI_Process() { @@ -1108,16 +1107,12 @@ void Mob::AI_Process() { if (this->GetTarget()) { /* If we are engaged, moving and following client, let's look for best Z more often */ float target_distance = DistanceNoZ(this->GetPosition(), this->GetTarget()->GetPosition()); - this->FixZ(); + FixZ(); if (target_distance <= 15 && !this->CheckLosFN(this->GetTarget())) { Mob *target = this->GetTarget(); - m_Position.x = target->GetX(); - m_Position.y = target->GetY(); - m_Position.z = target->GetZ(); - m_Position.w = target->GetHeading(); - SendPosition(); + Teleport(target->GetPosition()); } } } diff --git a/zone/mob_movement_manager.cpp b/zone/mob_movement_manager.cpp index 2b53c3f06..50aad279f 100644 --- a/zone/mob_movement_manager.cpp +++ b/zone/mob_movement_manager.cpp @@ -247,6 +247,11 @@ public: m->SetPosition(m_teleport_to_x, m_teleport_to_y, m_teleport_to_z); m->SetHeading(mgr->FixHeading(m_teleport_to_heading)); mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny); + + if (m->IsNPC()) { + entity_list.ProcessMove(m->CastToNPC(), m_teleport_to_x, m_teleport_to_y, m_teleport_to_z); + } + return true; } @@ -326,7 +331,7 @@ struct NavigateTo struct MobMovementEntry { std::deque> Commands; - NavigateTo NavigateTo; + NavigateTo NavTo; }; void AdjustRoute(std::list &nodes, int flymode, float offset) { @@ -433,7 +438,7 @@ void MobMovementManager::NavigateTo(Mob *who, float x, float y, float z, MobMove { auto iter = _impl->Entries.find(who); auto &ent = (*iter); - auto &nav = ent.second.NavigateTo; + auto &nav = ent.second.NavTo; double current_time = static_cast(Timer::GetCurrentTime()) / 1000.0; if ((current_time - nav.last_set_time) > 0.5) { @@ -502,7 +507,7 @@ void MobMovementManager::SendCommandToClients(Mob *m, float dx, float dy, float _impl->Stats.TotalSentPosition++; } - c->QueuePacket(&outapp); + c->QueuePacket(&outapp, false); } } else { @@ -541,7 +546,7 @@ void MobMovementManager::SendCommandToClients(Mob *m, float dx, float dy, float _impl->Stats.TotalSentPosition++; } - c->QueuePacket(&outapp); + c->QueuePacket(&outapp, false); } } } diff --git a/zone/npc.h b/zone/npc.h index 7d2c5a9c8..2300217a5 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -305,7 +305,7 @@ public: int32 GetEquipmentMaterial(uint8 material_slot) const; void NextGuardPosition(); - void SaveGuardSpot(bool iClearGuardSpot = false); + void SaveGuardSpot(const glm::vec4 &pos); inline bool IsGuarding() const { return(m_GuardPoint.w != 0); } void SaveGuardSpotCharm(); diff --git a/zone/perl_npc.cpp b/zone/perl_npc.cpp index 1eaddf3a2..8c68af734 100644 --- a/zone/perl_npc.cpp +++ b/zone/perl_npc.cpp @@ -1341,11 +1341,14 @@ XS(XS_NPC_NextGuardPosition) { XS(XS_NPC_SaveGuardSpot); /* prototype to pass -Wmissing-prototypes */ XS(XS_NPC_SaveGuardSpot) { dXSARGS; - if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: NPC::SaveGuardSpot(THIS, [bool clear_guard_spot = false])"); + if (items != 5) + Perl_croak(aTHX_ "Usage: NPC::SaveGuardSpot(THIS, x, y, z, heading)"); { NPC *THIS; - bool iClearGuardSpot; + float x = (float)SvNV(ST(1)); + float y = (float)SvNV(ST(2)); + float z = (float)SvNV(ST(3)); + float heading = (float)SvNV(ST(4)); if (sv_derived_from(ST(0), "NPC")) { IV tmp = SvIV((SV *) SvRV(ST(0))); @@ -1355,13 +1358,7 @@ XS(XS_NPC_SaveGuardSpot) { if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - if (items < 2) - iClearGuardSpot = false; - else { - iClearGuardSpot = (bool) SvTRUE(ST(1)); - } - - THIS->SaveGuardSpot(iClearGuardSpot); + THIS->SaveGuardSpot(glm::vec4(x, y, z, heading)); } XSRETURN_EMPTY; } @@ -2449,7 +2446,7 @@ XS(boot_NPC) { newXSproto(strcpy(buf, "PauseWandering"), XS_NPC_PauseWandering, file, "$$"); newXSproto(strcpy(buf, "MoveTo"), XS_NPC_MoveTo, file, "$$$$"); newXSproto(strcpy(buf, "NextGuardPosition"), XS_NPC_NextGuardPosition, file, "$"); - newXSproto(strcpy(buf, "SaveGuardSpot"), XS_NPC_SaveGuardSpot, file, "$;$"); + newXSproto(strcpy(buf, "SaveGuardSpot"), XS_NPC_SaveGuardSpot, file, "$$$$$"); newXSproto(strcpy(buf, "IsGuarding"), XS_NPC_IsGuarding, file, "$"); newXSproto(strcpy(buf, "AI_SetRoambox"), XS_NPC_AI_SetRoambox, file, "$$$$$$;$$"); newXSproto(strcpy(buf, "GetNPCSpellsID"), XS_NPC_GetNPCSpellsID, file, "$"); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index adcef8c76..0f239fe6f 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -851,7 +851,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove SetHeading(CalculateHeadingToTarget(ClosestMob->GetX(), ClosestMob->GetY())); SetTarget(ClosestMob); CastToClient()->SendTargetCommand(ClosestMob->GetID()); - SendPositionUpdate(true); + SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0, true); } else Message_StringID(clientMessageError, SENSE_NOTHING); diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 8e5402895..e137b605a 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -412,18 +412,13 @@ void NPC::SetWaypointPause() } } -void NPC::SaveGuardSpot(bool iClearGuardSpot) { - if (iClearGuardSpot) { - Log(Logs::Detail, Logs::AI, "Clearing guard order."); - m_GuardPoint = glm::vec4(); - } - else { - m_GuardPoint = m_Position; +void NPC::SaveGuardSpot(const glm::vec4 &pos) +{ + m_GuardPoint = pos; - if (m_GuardPoint.w == 0) - m_GuardPoint.w = 0.0001; //hack to make IsGuarding simpler - Log(Logs::Detail, Logs::AI, "Setting guard position to %s", to_string(static_cast(m_GuardPoint)).c_str()); - } + if (m_GuardPoint.w == 0) + m_GuardPoint.w = 0.0001; //hack to make IsGuarding simpler + LogF(Logs::Detail, Logs::AI, "Setting guard position to {0}", to_string(static_cast(m_GuardPoint))); } void NPC::NextGuardPosition() { @@ -819,8 +814,6 @@ void Mob::TryMoveAlong(float distance, float angle, bool send) new_pos.z = GetFixedZ(new_pos); Teleport(new_pos); - if (send) - SendPositionUpdate(); } int ZoneDatabase::GetHighestGrid(uint32 zoneid) { diff --git a/zone/zoning.cpp b/zone/zoning.cpp index 1ca418eb8..3d98f9ad6 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -664,7 +664,7 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z m_Proximity = glm::vec3(m_Position); //send out updates to people in zone. - SendPosition(); + SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0); } auto outapp =