@@ -128,12 +128,6 @@ bool NPC::move(Vector3 pos, NPCMoveType moveType)
128
128
// Set up everything to start moving in next tick
129
129
auto position = getPosition ();
130
130
float distance = glm::distance (position, pos);
131
- Vector3 newVelocity;
132
-
133
- if (!(distance <= 0 .0f ))
134
- {
135
- newVelocity = (pos - position) / distance;
136
- }
137
131
138
132
// Determine which speed to use based on moving type
139
133
float speed = 0 .0f ;
@@ -154,10 +148,6 @@ bool NPC::move(Vector3 pos, NPCMoveType moveType)
154
148
155
149
footSync_.UpDown = static_cast <uint16_t >(Key::ANALOG_UP);
156
150
157
- // Calculate velocity to use on tick
158
- newVelocity *= (speed / 100 .0f );
159
- velocity_ = newVelocity;
160
-
161
151
// Calculate front vector and player's facing angle:
162
152
Vector3 front;
163
153
if (!(std::fabs (distance) < DBL_EPSILON))
@@ -169,6 +159,18 @@ bool NPC::move(Vector3 pos, NPCMoveType moveType)
169
159
rotation.z = utils::getAngleOfLine (front.x , front.y );
170
160
footSync_.Rotation = rotation; // Do this directly, if you use NPC::setRotation it's going to cause recursion
171
161
162
+ // Calculate velocity to use on tick
163
+ velocity_ *= (speed / 100 .0f );
164
+
165
+ if (glm::length (velocity_) != 0 .0f )
166
+ {
167
+ estimatedArrivalTimeNS_ = Time::now ().time_since_epoch ().count () + (static_cast <long long >(distance / glm::length (velocity_)) * ((npcComponent_->getFootSyncRate () * 10000 ) + 1000000 ));
168
+ }
169
+ else
170
+ {
171
+ estimatedArrivalTimeNS_ = 0 ;
172
+ }
173
+
172
174
// Set internal variables
173
175
moveSpeed_ = speed;
174
176
targetPosition_ = pos;
@@ -185,6 +187,7 @@ void NPC::stopMove()
185
187
targetPosition_ = { 0 .0f , 0 .0f , 0 .0f };
186
188
velocity_ = { 0 .0f , 0 .0f , 0 .0f };
187
189
moveType_ = NPCMoveType_None;
190
+ estimatedArrivalTimeNS_ = 0 ;
188
191
189
192
footSync_.Keys &= Key::SPRINT;
190
193
footSync_.Keys &= Key::WALK;
@@ -224,29 +227,28 @@ void NPC::sendFootSync()
224
227
void NPC::advance (TimePoint now)
225
228
{
226
229
auto position = getPosition ();
227
- Milliseconds difference = duration_cast<Milliseconds>(now.time_since_epoch ()) - duration_cast<Milliseconds>(lastMove_.time_since_epoch ());
228
- float remainingDistance = glm::distance (position, targetPosition_);
229
- Vector3 travelled = velocity_ * static_cast <float >(difference.count ());
230
230
231
- if (glm::length (travelled) >= remainingDistance )
231
+ if (estimatedArrivalTimeNS_ <= Time::now (). time_since_epoch (). count () )
232
232
{
233
+ footSync_.Position = targetPosition_;
233
234
stopMove ();
234
235
npcComponent_->getEventDispatcher_internal ().dispatch (&NPCEventHandler::onNPCFinishMove, *this );
235
236
}
236
237
else
237
238
{
239
+ Milliseconds difference = duration_cast<Milliseconds>(now.time_since_epoch ()) - duration_cast<Milliseconds>(lastMove_.time_since_epoch ());
240
+ Vector3 travelled = velocity_ * static_cast <float >(difference.count ());
241
+
238
242
position += travelled;
239
243
footSync_.Velocity = velocity_;
244
+ footSync_.Position = position; // Do this directly, if you use NPC::setPosition it's going to cause recursion
240
245
}
241
246
242
247
lastMove_ = Time::now ();
243
- footSync_.Position = position; // Do this directly, if you use NPC::setPosition it's going to cause recursion
244
248
}
245
249
246
250
void NPC::tick (Microseconds elapsed, TimePoint now)
247
251
{
248
- static auto footSyncRate = npcComponent_->getCore ()->getConfig ().getInt (" network.on_foot_sync_rate" );
249
-
250
252
// Only process the NPC if it is spawned
251
253
if (player_ && (player_->getState () == PlayerState_OnFoot || player_->getState () == PlayerState_Driver || player_->getState () == PlayerState_Passenger || player_->getState () == PlayerState_Spawned))
252
254
{
0 commit comments