public void PacketFromServer(double gtt, int ID, Location pos, Location vel, bool _pup) { CurrentRemoteGTT = gtt; ServerLocation = pos; if (ServerFlags.HasFlag(YourStatusFlags.INSECURE_MOVEMENT)) { return; } if (InVehicle) { return; } Location cur_pos = GetPosition(); Location cur_vel = GetVelocity(); Location old_pos = Positions[ID]; Location old_vel = Velocities[ID]; Location off_pos = pos - old_pos; Location off_vel = vel - old_vel; double off_gtt = MathHelper.Clamp(gtt - GTTs[ID], 0.001, 0.3) * 2.0; if ((cur_pos - pos).LengthSquared() > 20.0 * 20.0) { SetPosition(pos); SetVelocity(vel); } else { SetPosition(cur_pos + off_pos * off_gtt); SetVelocity(cur_vel + off_vel * off_gtt); } GTTs[ID] = -1.0; // TODO: match this movement logic for vehicles too (pos + vel + direction) }
public void UpdateForPacketFromServer(double gtt, long ID, Location pos, Location vel, bool _pup) { ServerLocation = pos; if (ServerFlags.HasFlag(YourStatusFlags.INSECURE_MOVEMENT)) { return; } if (InVehicle) { return; } // TODO: big solid entities! double now = TheRegion.GlobalTickTimeLocal; if (TheClient.CVars.n_movemode.ValueI == 2) { // TODO: Remove outsider chunks! for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { for (int z = -1; z <= 1; z++) { Vector3i ch = TheRegion.ChunkLocFor(pos) + new Vector3i(x, y, z); Chunk chunk = TheRegion.GetChunk(ch); if (chunk == null) { continue; } if (!NMTWOMeshes.ContainsKey(ch)) { if (chunk.FCO != null) { FullChunkObject im = new FullChunkObject(chunk.FCO.Position, chunk.FCO.ChunkShape); NMTWOWorld.Add(im); NMTWOMeshes[ch] = im; } } } } } AddUIS(); int xf = 0; double jumpback = gtt - lGTT; if (jumpback < 0) { return; } double target = TheRegion.GlobalTickTimeLocal - jumpback; UserInputSet past = null; while (xf < Input.Length) { UserInputSet uis = Input[xf]; if (uis.GlobalTimeLocal < target) { past = uis; Input.Pop(); continue; } else if (xf == 0) { double mult = Math.Max(Math.Min(jumpback / TheClient.CVars.n_movement_adjustment.ValueD, 1.0), 0.01); NMTWOSetPosition(uis.Position + (pos - uis.Position) * mult); NMTWOSetVelocity(uis.Velocity + (vel - uis.Velocity) * mult); } xf++; double delta; if (xf < 2) { if (past == null) { continue; } delta = uis.GlobalTimeLocal - target; SetBodyMovement(NMTWOCBody, past); } else { UserInputSet prev = Input[xf - 2]; delta = uis.GlobalTimeLocal - prev.GlobalTimeLocal; SetBodyMovement(NMTWOCBody, prev); } SetMoveSpeed(NMTWOCBody, uis); if (!_pup) { NMTWOTryToJump(uis); } lPT = uis.GlobalTimeLocal; NMTWOWorld.Update((float)delta); FlyForth(NMTWOCBody, uis, delta); // TODO: Entirely disregard NWTWOWorld if flying? } AddUIS(); SetPosition(NMTWOGetPosition()); SetVelocity(new Location(NMTWOCBody.Body.LinearVelocity)); pup = _pup; lGTT = gtt; } else { double delta = lPT - now; Location dir = pos - TheClient.Player.GetPosition(); if (dir.LengthSquared() < TheClient.CVars.n_movement_maxdistance.ValueF * TheClient.CVars.n_movement_maxdistance.ValueF) { SetPosition(GetPosition() + dir / Math.Max(TheClient.CVars.n_movement_adjustment.ValueF / delta, 1)); Location veldir = vel - GetVelocity(); SetVelocity(GetVelocity() + veldir / Math.Max(TheClient.CVars.n_movement_adjustment.ValueF / delta, 1)); } else { TheClient.Player.SetPosition(pos); TheClient.Player.SetVelocity(vel); } lPT = now; } }