From 612341a61c04e7043f2059105892bff2e4a8cb4b Mon Sep 17 00:00:00 2001 From: iAmir Date: Tue, 23 Apr 2024 15:28:47 +0330 Subject: [PATCH] calculate estimated arrival time and use it to detect finish move --- Server/Components/NPCs/NPC/npc.cpp | 36 +++++++++++++++------------- Server/Components/NPCs/NPC/npc.hpp | 1 + Server/Components/NPCs/npcs_impl.hpp | 2 +- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/Server/Components/NPCs/NPC/npc.cpp b/Server/Components/NPCs/NPC/npc.cpp index 752cd16ad..e8a62c9f5 100644 --- a/Server/Components/NPCs/NPC/npc.cpp +++ b/Server/Components/NPCs/NPC/npc.cpp @@ -128,12 +128,6 @@ bool NPC::move(Vector3 pos, NPCMoveType moveType) // Set up everything to start moving in next tick auto position = getPosition(); float distance = glm::distance(position, pos); - Vector3 newVelocity; - - if (!(distance <= 0.0f)) - { - newVelocity = (pos - position) / distance; - } // Determine which speed to use based on moving type float speed = 0.0f; @@ -154,10 +148,6 @@ bool NPC::move(Vector3 pos, NPCMoveType moveType) footSync_.UpDown = static_cast(Key::ANALOG_UP); - // Calculate velocity to use on tick - newVelocity *= (speed / 100.0f); - velocity_ = newVelocity; - // Calculate front vector and player's facing angle: Vector3 front; if (!(std::fabs(distance) < DBL_EPSILON)) @@ -169,6 +159,18 @@ bool NPC::move(Vector3 pos, NPCMoveType moveType) rotation.z = utils::getAngleOfLine(front.x, front.y); footSync_.Rotation = rotation; // Do this directly, if you use NPC::setRotation it's going to cause recursion + // Calculate velocity to use on tick + velocity_ *= (speed / 100.0f); + + if (glm::length(velocity_) != 0.0f) + { + estimatedArrivalTimeNS_ = Time::now().time_since_epoch().count() + (static_cast(distance / glm::length(velocity_)) * ((npcComponent_->getFootSyncRate() * 10000) + 1000000)); + } + else + { + estimatedArrivalTimeNS_ = 0; + } + // Set internal variables moveSpeed_ = speed; targetPosition_ = pos; @@ -185,6 +187,7 @@ void NPC::stopMove() targetPosition_ = { 0.0f, 0.0f, 0.0f }; velocity_ = { 0.0f, 0.0f, 0.0f }; moveType_ = NPCMoveType_None; + estimatedArrivalTimeNS_ = 0; footSync_.Keys &= Key::SPRINT; footSync_.Keys &= Key::WALK; @@ -224,29 +227,28 @@ void NPC::sendFootSync() void NPC::advance(TimePoint now) { auto position = getPosition(); - Milliseconds difference = duration_cast(now.time_since_epoch()) - duration_cast(lastMove_.time_since_epoch()); - float remainingDistance = glm::distance(position, targetPosition_); - Vector3 travelled = velocity_ * static_cast(difference.count()); - if (glm::length(travelled) >= remainingDistance) + if (estimatedArrivalTimeNS_ <= Time::now().time_since_epoch().count()) { + footSync_.Position = targetPosition_; stopMove(); npcComponent_->getEventDispatcher_internal().dispatch(&NPCEventHandler::onNPCFinishMove, *this); } else { + Milliseconds difference = duration_cast(now.time_since_epoch()) - duration_cast(lastMove_.time_since_epoch()); + Vector3 travelled = velocity_ * static_cast(difference.count()); + position += travelled; footSync_.Velocity = velocity_; + footSync_.Position = position; // Do this directly, if you use NPC::setPosition it's going to cause recursion } lastMove_ = Time::now(); - footSync_.Position = position; // Do this directly, if you use NPC::setPosition it's going to cause recursion } void NPC::tick(Microseconds elapsed, TimePoint now) { - static auto footSyncRate = npcComponent_->getCore()->getConfig().getInt("network.on_foot_sync_rate"); - // Only process the NPC if it is spawned if (player_ && (player_->getState() == PlayerState_OnFoot || player_->getState() == PlayerState_Driver || player_->getState() == PlayerState_Passenger || player_->getState() == PlayerState_Spawned)) { diff --git a/Server/Components/NPCs/NPC/npc.hpp b/Server/Components/NPCs/NPC/npc.hpp index f4740e075..e707f2a3f 100644 --- a/Server/Components/NPCs/NPC/npc.hpp +++ b/Server/Components/NPCs/NPC/npc.hpp @@ -66,6 +66,7 @@ class NPC : public INPC, public PoolIDProvider, public NoCopy // Movements NPCMoveType moveType_; TimePoint lastMove_; + long long estimatedArrivalTimeNS_; TimePoint moveStart_; float moveSpeed_; Vector3 targetPosition_; diff --git a/Server/Components/NPCs/npcs_impl.hpp b/Server/Components/NPCs/npcs_impl.hpp index a3a865fd1..86a7b4f87 100644 --- a/Server/Components/NPCs/npcs_impl.hpp +++ b/Server/Components/NPCs/npcs_impl.hpp @@ -79,7 +79,7 @@ class NPCComponent final : public INPCComponent, public CoreEventHandler return eventDispatcher; } - int getFootSyncRate() const + int getFootSyncRate() const { return *footSyncRate; }