示例#1
0
        private void TargetClosestNode(Vector3 pos)
        {
            OpponentPathNode curNode = _targetNode;

            TargetNode(OpponentController.GetClosestNode(pos));
            _currentPath = null;

            if (curNode == _targetNode) //if the closest node is the one we've failed to get to
            {
                // if we've failed to get to the target twice we're really stuck, teleport straight to node :)
                Teleport(_targetNode);
                return;
            }
            GameConsole.WriteEvent("ClosestNode");
            _nbrFails++;
        }
示例#2
0
        //public static OpponentPathNode GetClosestRaceNode(Vector3 currentPosition)
        //{
        //    float leastDistance = int.MaxValue;
        //    OpponentPathNode leastDistantNode = null;

        //    foreach (OpponentPathNode node in Nodes)
        //    {
        //        float thisDistance = Vector3.Distance(currentPosition, node.Position);
        //        if (thisDistance < leastDistance)
        //        {
        //            if (node.Paths.Exists(a => a.Type == PathType.Race))
        //            {
        //                leastDistance = thisDistance;
        //                leastDistantNode = node;
        //            }
        //        }
        //    }

        //    return leastDistantNode;
        //}

        public static OpponentPath GetClosestPath(Vector3 point)
        {
            float        closestDist = float.MaxValue;
            OpponentPath closestPath = null;

            foreach (OpponentPathNode node in Nodes)
            {
                foreach (OpponentPath path in node.Paths)
                {
                    Vector3 closestPoint = Helpers.GetClosestPointOnLine(path.Start.Position, path.End.Position, point);
                    float   dist         = Vector3.Distance(point, closestPoint);
                    if (dist < closestDist)
                    {
                        closestPath = path;
                        closestDist = dist;
                    }
                }
            }

            return(closestPath);
        }
示例#3
0
        private void TargetClosestNode(Vector3 pos)
        {
            OpponentPathNode curNode = _targetNode;
            TargetNode(OpponentController.GetClosestNode(pos));
            _currentPath = null;

            if (curNode == _targetNode) //if the closest node is the one we've failed to get to
            {
                // if we've failed to get to the target twice we're really stuck, teleport straight to node :)
                Teleport(_targetNode);
                return;
            }
            GameConsole.WriteEvent("ClosestNode");
            _nbrFails++;
        }
示例#4
0
        public virtual void Update()
        {
            if (!_raceStarted) return;
            Vector3 pos = Vehicle.Position;
            bool isBraking = false;

            if (IsDead || _state == CpuDriverState.Sleeping)
            {
                Vehicle.Chassis.Brake(0);
                Vehicle.Chassis.Steer(0);
                return;
            }

            if (DistanceFromPlayer > _catchupDistance)
            {
                _catchupDistance = Engine.Random.Next(MIN_CATCHUP_DISTANCE, MAX_CATCHUP_DISTANCE);
                Teleport(OpponentController.GetNodeCloseToPlayer());
            }

            // check position
            if (Helpers.HasTimePassed(1.5f, _lastPositionTime))
            {
                float distFromLastPosition = Vector3.Distance(_lastPosition, pos);
                if (distFromLastPosition < 2 && Vehicle.Chassis.Speed < 3)
                {
                    Escape(); //were stuck, try and escape
                }
                LogPosition(pos);
            }
            if (Vehicle.Chassis.Actor.GlobalPose.Up.Y < 0.002f && Vehicle.Chassis.Speed < 5 && !InPlayersView)
            {
                Vehicle.Chassis.Reset();
                return;
            }

            // check for state change
            if (_nextDirectionChangeTime < Engine.TotalSeconds)
            {
                if (_isReversing)
                {
                    _isReversing = false;
                    LogPosition(pos);
                }
            }

            float distanceFromNode=0;
            if (_state == CpuDriverState.Racing) distanceFromNode = Vector3.Distance(pos, _targetNode.Position);
            else if (_state == CpuDriverState.ReturningToTrack) distanceFromNode = Vector3.Distance(pos, _closestPointOnPath);

            // if we've been trying to get to the same target for 20 seconds, get a new one
            if (_state != CpuDriverState.Attacking && Helpers.HasTimePassed(20, _lastTargetChangeTime))
            {
                if (_lastDistance <= distanceFromNode) //only get another node if were not getting closer
                {
                    TargetClosestNode(pos);
                    return;
                }
            }

            if (_state == CpuDriverState.Racing)
            {
                //if (_currentPath != null)
                //{
                //    GameConsole.WriteLine("Limits " + _currentPath.Number + ", " + _currentPath.MinSpeedAtEnd + ", " + _maxSpeedAtEndOfPath);
                //}

                if (_currentPath != null && Vehicle.Chassis.Speed > _maxSpeedAtEndOfPath)
                {
                    float distToBrake = Vehicle.Chassis.Speed * 0.45f + ((Vehicle.Chassis.Speed - _maxSpeedAtEndOfPath) * 1.4f);
                    //GameConsole.WriteLine("brake: " + (int)distToBrake + ", " + (int)distanceFromNode);
                    //Matrix mat = Matrix.CreateTranslation(0, 0, distToBrake) * Vehicle.Chassis.Actor.GlobalPose;

                    if (distToBrake >= distanceFromNode)
                    {
                        Vehicle.Chassis.Brake(1);
                        isBraking = true;
                    }
                }
                if (_currentPath != null)
                {
                    _closestPointOnPath = Helpers.GetClosestPointOnLine(_currentPath.Start.Position, _currentPath.End.Position, pos);
                    _closestPointOnPath.Y = pos.Y; //ignore Y
                    if (Vector3.Distance(_closestPointOnPath, pos) > _currentPath.Width)
                    {
                        SetState(CpuDriverState.ReturningToTrack);
                    }
                }

                // now see if we're at the target ignoring height (if we jump over it for example)
                distanceFromNode = Vector2.Distance(new Vector2(pos.X, pos.Z), new Vector2(_targetNode.Position.X, _targetNode.Position.Z));
                if (distanceFromNode < 11 && pos.Y >= _targetNode.Position.Y)
                {
                    _nbrFails = 0; //reset fail counter

                    if (_currentPath != null)
                    {
                        if (Vehicle.Chassis.Speed < _currentPath.MinSpeedAtEnd)
                        {
                            Vehicle.Chassis.Boost();
                        }
                    }
                    _currentPath = _nextPath;

                    if (_currentPath != null && _currentPath.Type == PathType.Cheat)
                    {
                        Teleport(_currentPath.End);
                        SetState(CpuDriverState.Racing);
                        return;
                    }

                    if (_nextPath == null)  // the node didnt have any start paths
                    {
                        TargetClosestNode(pos);
                    }
                    else
                    {
                        TargetNode(_currentPath.End);
                    }

                    if (_currentPath == null && _nextPath == null)
                    {
                        Teleport(); //if the node we've just got to doesnt have any outgoing paths, teleport randomly
                    }
                }
            }
            else if (_state == CpuDriverState.ReturningToTrack)
            {
                _closestPointOnPath = Helpers.GetClosestPointOnLine(_currentPath.Start.Position, _currentPath.End.Position, pos);

                GameConsole.WriteLine("dist from track", Vector3.Distance(_closestPointOnPath, pos));
                if (Vector3.Distance(_closestPointOnPath, pos) > GIVEUP_DISTANCE_FROM_TRACK)
                {
                    TargetClosestNode(pos);
                    return;
                }

                _closestPointOnPath.Y = pos.Y; //ignore Y

                float dist = Vector3.Distance(_closestPointOnPath, pos);
                if (dist < _currentPath.Width)
                {
                    _state = CpuDriverState.Racing;
                }
                else if (dist < _currentPath.Width * 1.5f)
                {
                    _closestPointOnPath = Vector3.Lerp(_currentPath.End.Position, _closestPointOnPath, dist / (_currentPath.Width * 1.5f));
                }
                //Engine.DebugRenderer.AddCube(Matrix.CreateTranslation(_closestPointOnPath), Color.Blue);
            }
            else if (_state == CpuDriverState.Attacking)
            {
                if (DistanceFromPlayer > GIVEUP_ATTACK_DISTANCE)
                    TargetClosestNode(pos);
            }

            Vector3 towardsNode = Vector3.Zero;
            if (_state == CpuDriverState.Racing)
            {
                towardsNode = _targetNode.Position - pos;
            }
            else if (_state == CpuDriverState.Attacking)
            {
                towardsNode = Race.Current.PlayerVehicle.Position - pos;
            }
            else if (_state == CpuDriverState.ReturningToTrack)
            {
                towardsNode = _closestPointOnPath - pos;
            }

            GameConsole.WriteLine("state: " + _state);

            float angle = Helpers.GetSignedAngleBetweenVectors(Vehicle.Chassis.Actor.GlobalOrientation.Forward, towardsNode, true);
            angle *= 1.5f;
            if (angle > 1) angle = 1;
            else if (angle < -1) angle = -1;

            if (Math.Abs(angle) > 0.003f) Vehicle.Chassis.Steer(angle);

            if (!isBraking)
            {
                if (_state == CpuDriverState.ReturningToTrack)
                {
                    if (Math.Abs(angle) > 0.3f)
                    {
                        float speed = 20; // 20 + ((1 - Math.Abs(angle)) * 30);
                        if (Vehicle.Chassis.Speed > speed)
                            Vehicle.Chassis.Brake(1);
                        else
                            Vehicle.Chassis.Accelerate(0.4f);

                        GameConsole.WriteLine("rtt", angle);
                        GameConsole.WriteLine("rttspeed", speed);
                    }
                    else
                        Vehicle.Chassis.Accelerate(0.5f);
                }
                else
                {
                    if (Math.Abs(angle) > 0.7f)
                        Vehicle.Chassis.Accelerate(0.5f); //if were turning hard, go easy on the gas pedal
                    else
                        Vehicle.Chassis.Accelerate(1.0f);
                }
            }

            _lastDistance = distanceFromNode;

            if (_isReversing)
            {
                Vehicle.Chassis.Brake(0.3f);
                Vehicle.Chassis.Steer(_reverseTurning);
            }

            if (Vehicle.Chassis.Motor.Gearbox.CurrentGear == 0)
                Vehicle.Chassis.Motor.Gearbox.CurrentGear = 1;

            //Engine.DebugRenderer.AddWireframeCube(Matrix.CreateScale(2) * Matrix.CreateTranslation(_targetNode.Position), Color.Green);
        }
示例#5
0
        public virtual void Update()
        {
            if (!_raceStarted)
            {
                return;
            }
            Vector3 pos       = Vehicle.Position;
            bool    isBraking = false;

            if (IsDead || _state == CpuDriverState.Sleeping)
            {
                Vehicle.Chassis.Brake(0);
                Vehicle.Chassis.Steer(0);
                return;
            }

            if (DistanceFromPlayer > _catchupDistance)
            {
                _catchupDistance = GameEngine.Random.Next(MIN_CATCHUP_DISTANCE, MAX_CATCHUP_DISTANCE);
                Teleport(OpponentController.GetNodeCloseToPlayer());
            }

            // check position
            if (Helpers.HasTimePassed(1.5f, _lastPositionTime))
            {
                float distFromLastPosition = Vector3.Distance(_lastPosition, pos);
                if (distFromLastPosition < 2 && Vehicle.Chassis.Speed < 3)
                {
                    Escape(); //were stuck, try and escape
                }
                LogPosition(pos);
            }
            if (Vehicle.Chassis.Actor.GlobalPose.Up.Y < 0.002f && Vehicle.Chassis.Speed < 5 && !InPlayersView)
            {
                Vehicle.Chassis.Reset();
                return;
            }

            // check for state change
            if (_nextDirectionChangeTime < GameEngine.TotalSeconds)
            {
                if (_isReversing)
                {
                    _isReversing = false;
                    LogPosition(pos);
                }
            }

            float distanceFromNode = 0;

            if (_state == CpuDriverState.Racing)
            {
                distanceFromNode = Vector3.Distance(pos, _targetNode.Position);
            }
            else if (_state == CpuDriverState.ReturningToTrack)
            {
                distanceFromNode = Vector3.Distance(pos, _closestPointOnPath);
            }

            // if we've been trying to get to the same target for 20 seconds, get a new one
            if (_state != CpuDriverState.Attacking && Helpers.HasTimePassed(20, _lastTargetChangeTime))
            {
                if (_lastDistance <= distanceFromNode) //only get another node if were not getting closer
                {
                    TargetClosestNode(pos);
                    return;
                }
            }

            if (_state == CpuDriverState.Racing)
            {
                //if (_currentPath != null)
                //{
                //    GameConsole.WriteLine("Limits " + _currentPath.Number + ", " + _currentPath.MinSpeedAtEnd + ", " + _maxSpeedAtEndOfPath);
                //}

                if (_currentPath != null && Vehicle.Chassis.Speed > _maxSpeedAtEndOfPath)
                {
                    float distToBrake = Vehicle.Chassis.Speed * 0.45f + ((Vehicle.Chassis.Speed - _maxSpeedAtEndOfPath) * 1.4f);
                    //GameConsole.WriteLine("brake: " + (int)distToBrake + ", " + (int)distanceFromNode);
                    //Matrix mat = Matrix.CreateTranslation(0, 0, distToBrake) * Vehicle.Chassis.Actor.GlobalPose;

                    if (distToBrake >= distanceFromNode)
                    {
                        Vehicle.Chassis.Brake(1);
                        isBraking = true;
                    }
                }
                if (_currentPath != null)
                {
                    _closestPointOnPath   = Helpers.GetClosestPointOnLine(_currentPath.Start.Position, _currentPath.End.Position, pos);
                    _closestPointOnPath.Y = pos.Y; //ignore Y
                    if (Vector3.Distance(_closestPointOnPath, pos) > _currentPath.Width)
                    {
                        SetState(CpuDriverState.ReturningToTrack);
                    }
                }

                // now see if we're at the target ignoring height (if we jump over it for example)
                distanceFromNode = Vector2.Distance(new Vector2(pos.X, pos.Z), new Vector2(_targetNode.Position.X, _targetNode.Position.Z));
                if (distanceFromNode < 11 && pos.Y >= _targetNode.Position.Y)
                {
                    _nbrFails = 0; //reset fail counter

                    if (_currentPath != null)
                    {
                        if (Vehicle.Chassis.Speed < _currentPath.MinSpeedAtEnd)
                        {
                            Vehicle.Chassis.Boost();
                        }
                    }
                    _currentPath = _nextPath;

                    if (_currentPath != null && _currentPath.Type == PathType.Cheat)
                    {
                        Teleport(_currentPath.End);
                        SetState(CpuDriverState.Racing);
                        return;
                    }

                    if (_nextPath == null)  // the node didnt have any start paths
                    {
                        TargetClosestNode(pos);
                    }
                    else
                    {
                        TargetNode(_currentPath.End);
                    }

                    if (_currentPath == null && _nextPath == null)
                    {
                        Teleport(); //if the node we've just got to doesnt have any outgoing paths, teleport randomly
                    }
                }
            }
            else if (_state == CpuDriverState.ReturningToTrack)
            {
                _closestPointOnPath = Helpers.GetClosestPointOnLine(_currentPath.Start.Position, _currentPath.End.Position, pos);

                GameConsole.WriteLine("dist from track", Vector3.Distance(_closestPointOnPath, pos));
                if (Vector3.Distance(_closestPointOnPath, pos) > GIVEUP_DISTANCE_FROM_TRACK)
                {
                    TargetClosestNode(pos);
                    return;
                }

                _closestPointOnPath.Y = pos.Y; //ignore Y

                float dist = Vector3.Distance(_closestPointOnPath, pos);
                if (dist < _currentPath.Width)
                {
                    _state = CpuDriverState.Racing;
                }
                else if (dist < _currentPath.Width * 1.5f)
                {
                    _closestPointOnPath = Vector3.Lerp(_currentPath.End.Position, _closestPointOnPath, dist / (_currentPath.Width * 1.5f));
                }
                //GameEngine.DebugRenderer.AddCube(Matrix.CreateTranslation(_closestPointOnPath), Color.Blue);
            }
            else if (_state == CpuDriverState.Attacking)
            {
                if (DistanceFromPlayer > GIVEUP_ATTACK_DISTANCE)
                {
                    TargetClosestNode(pos);
                }
            }

            Vector3 towardsNode = Vector3.Zero;

            if (_state == CpuDriverState.Racing)
            {
                towardsNode = _targetNode.Position - pos;
            }
            else if (_state == CpuDriverState.Attacking)
            {
                towardsNode = Race.Current.PlayerVehicle.Position - pos;
            }
            else if (_state == CpuDriverState.ReturningToTrack)
            {
                towardsNode = _closestPointOnPath - pos;
            }

            GameConsole.WriteLine("state: " + _state);

            float angle = Helpers.GetSignedAngleBetweenVectors(Vehicle.Chassis.Actor.GlobalOrientation.Forward, towardsNode, true);

            angle *= 1.5f;
            if (angle > 1)
            {
                angle = 1;
            }
            else if (angle < -1)
            {
                angle = -1;
            }

            if (Math.Abs(angle) > 0.003f)
            {
                Vehicle.Chassis.Steer(angle);
            }

            if (!isBraking)
            {
                if (_state == CpuDriverState.ReturningToTrack)
                {
                    if (Math.Abs(angle) > 0.3f)
                    {
                        float speed = 20; // 20 + ((1 - Math.Abs(angle)) * 30);
                        if (Vehicle.Chassis.Speed > speed)
                        {
                            Vehicle.Chassis.Brake(1);
                        }
                        else
                        {
                            Vehicle.Chassis.Accelerate(0.4f);
                        }

                        GameConsole.WriteLine("rtt", angle);
                        GameConsole.WriteLine("rttspeed", speed);
                    }
                    else
                    {
                        Vehicle.Chassis.Accelerate(0.5f);
                    }
                }
                else
                {
                    if (Math.Abs(angle) > 0.7f)
                    {
                        Vehicle.Chassis.Accelerate(0.5f); //if were turning hard, go easy on the gas pedal
                    }
                    else
                    {
                        Vehicle.Chassis.Accelerate(1.0f);
                    }
                }
            }

            _lastDistance = distanceFromNode;

            if (_isReversing)
            {
                Vehicle.Chassis.Brake(0.3f);
                Vehicle.Chassis.Steer(_reverseTurning);
            }

            if (Vehicle.Chassis.Motor.Gearbox.CurrentGear == 0)
            {
                Vehicle.Chassis.Motor.Gearbox.CurrentGear = 1;
            }

            //GameEngine.DebugRenderer.AddWireframeCube(Matrix.CreateScale(2) * Matrix.CreateTranslation(_targetNode.Position), Color.Green);
        }