Пример #1
0
        void StoreCurrentTransform()
        {
            PlayerTransform snapshot = new PlayerTransform(Transform.Position, camera.Yaw, camera.Pitch);

            playerTransforms.Add(snapshot);

            if (playerTransforms.Count > MAX_STORED_TRANSFORMS)
            {
                playerTransforms.RemoveAt(0);
            }
        }
Пример #2
0
        public PlayerTransform RollbackTransform(int timeFrame, bool suppressLog = false)
        {
            PlayerTransform pt1 = null, pt2 = null;

            for (int i = 0; i < playerTransforms.Count; i++)
            {
                PlayerTransform pt      = playerTransforms[i];
                int             tickOff = Math.Abs(pt.Ticks - timeFrame);

                // Don't process anything more than a second off
                if (tickOff > 1000)
                {
                    continue;
                }

                if (pt1 == null || tickOff < Math.Abs(pt1.Ticks - timeFrame))
                {
                    pt1 = pt;
                }
            }

            for (int i = 0; i < playerTransforms.Count; i++)
            {
                PlayerTransform pt = playerTransforms[i];
                if (pt == pt1)
                {
                    continue;
                }

                int tickOff = Math.Abs(pt.Ticks - timeFrame);

                // Don't process anything more than a second off
                if (tickOff > 1000)
                {
                    continue;
                }

                if (pt2 == null || tickOff < Math.Abs(pt2.Ticks - timeFrame))
                {
                    pt2 = pt;
                }
            }

            if (pt1 != null && pt2 != null)
            {
                if (pt2.Ticks > pt1.Ticks)
                {
                    PlayerTransform temp = pt2;
                    pt2 = pt1;
                    pt1 = temp;
                }

                // Interpolate
                float timeI = pt1.Ticks == pt2.Ticks ? 0f : (float)(timeFrame - pt2.Ticks) / (pt1.Ticks - pt2.Ticks);
                //timeI = MathHelper.Clamp(timeI, 0f, 1f);

                if (DashCMD.GetCVar <bool>("sv_hitboxes") && !suppressLog)
                {
                    DashCMD.WriteImportant("[RB] Rolling back transform by {0}%. [timeFrame: {3}, pt2: {1}, pt1: {2}]",
                                           timeI * 100, pt2.Ticks, pt1.Ticks, timeFrame);
                }

                Vector3 position = Interpolation.Lerp(pt2.Position, pt1.Position, timeI);
                float   camPitch = Interpolation.LerpDegrees(pt2.CameraPitch, pt1.CameraPitch, timeI);
                float   camYaw   = Interpolation.LerpDegrees(pt2.CameraYaw, pt1.CameraYaw, timeI);

                return(new PlayerTransform(position, camYaw, camPitch, timeFrame));
            }
            else if (pt1 != null && pt2 == null)
            {
                // Take pt1
                return(pt1);
            }
            else
            {
                // Take current
                return(new PlayerTransform(Transform.Position, camera.Yaw, camera.Pitch, Environment.TickCount));
            }
        }
Пример #3
0
        public override PlayerRaycastResult RaycastPlayers(Ray ray, float maxDist = float.MaxValue, params Player[] ignore)
        {
            bool sv_impacts  = DashCMD.GetCVar <bool>("sv_impacts");
            bool sv_hitboxes = DashCMD.GetCVar <bool>("sv_hitboxes");

            ServerMPPlayer hitPlayer   = null;
            float?         hitPlayerAt = null;

            foreach (ServerMPPlayer otherPlayer in players.Values)
            {
                // Make sure we aren't ignoring this player
                if (ignore.Length == 0 || !Array.Exists(ignore, (x => x == otherPlayer)))
                {
                    Vector3 otherPlayerPosition;
                    float   otherPlayerCamYaw;
                    if (rollbackTime.HasValue)
                    {
                        // We are applying rollback, so find the players old transform
                        int otherPlayerPing = DashCMD.GetCVar <bool>("rp_usetargetping") ? otherPlayer.StateInfo.Owner.Stats.Ping : 0;
                        int rollbackFrame   = MathHelper.Clamp(otherPlayerPing + rollbackTime.Value, 0, 1000);

                        if (sv_hitboxes)
                        {
                            DashCMD.WriteLine("[RB] Rolling back bullet-player transform by {0}ms [target ping: {1}ms]",
                                              ConsoleColor.Green, rollbackTime, otherPlayerPing);
                        }

                        PlayerTransform otherPlayerTransform = otherPlayer.RollbackTransform(Environment.TickCount - rollbackFrame);
                        otherPlayerPosition = otherPlayerTransform.Position;
                        otherPlayerCamYaw   = otherPlayerTransform.CameraYaw;
                    }
                    else
                    {
                        // No rollback currently, use current transform
                        otherPlayerPosition = otherPlayer.Transform.Position;
                        otherPlayerCamYaw   = otherPlayer.GetCamera().Yaw;
                    }

                    if (sv_hitboxes)
                    {
                        channel.FireEventForAllConnections("Client_RolledBackServerPlayer",
                                                           otherPlayerPosition.X, otherPlayerPosition.Y,
                                                           otherPlayerPosition.Z, (byte)otherPlayer.Team);
                    }

                    Ray newRay = new Ray(ray.Origin - otherPlayerPosition, ray.Direction);

                    float?dist;
                    // Check for intersection
                    if (newRay.Intersects(otherPlayer.GetOrientatedBoundingBox(otherPlayerCamYaw), out dist))
                    {
                        // If the distance is out of bounds, ignore
                        if (dist.Value > maxDist)
                        {
                            continue;
                        }

                        // Only update the intersected player if it was closer than the last
                        if (!hitPlayerAt.HasValue || dist.Value < hitPlayerAt.Value)
                        {
                            hitPlayer   = otherPlayer;
                            hitPlayerAt = dist.Value;
                        }
                    }
                }
            }

            if (hitPlayer != null)
            {
                return(new PlayerRaycastResult(ray, true, ray.Origin + ray.Direction * hitPlayerAt.Value, hitPlayerAt, hitPlayer));
            }
            else
            {
                return(new PlayerRaycastResult(ray));
            }
        }