示例#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
        private void GetNextPath()
        {
            // for the next node, look at direction we will be turning and decide if we will need to slow down before we get there
            _nextPath = OpponentController.GetNextPath(_targetNode);

            if (_nextPath != null && _currentPath != null)
            {
                float nextPathAngle = MathHelper.ToDegrees(Helpers.GetUnsignedAngleBetweenVectors(_currentPath.End.Position - _currentPath.Start.Position, _nextPath.End.Position - _nextPath.Start.Position, false));

                if (nextPathAngle > 5)
                {
                    float newspeed = (180 - nextPathAngle) * 0.50f;
                    _maxSpeedAtEndOfPath = newspeed;
                }
                else
                {
                    _maxSpeedAtEndOfPath = 255;
                }
            }
        }
示例#3
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);
        }
示例#4
0
 private void Teleport()
 {
     Teleport(OpponentController.GetRandomNode());
 }
示例#5
0
        public void Update()
        {
            RaceTime.Update();

            if (!RaceTime.IsStarted)
            {
                if ((int)RaceTime.TotalTime == 2 && !RaceTime.CountingDown)
                {
                    RaceTime.StartCountdown();
                    foreach (IDriver driver in Drivers)
                    {
                        driver.Vehicle.Chassis.FixSuspension();
                    }
                }
                if (GameEngine.Camera is FixedChaseCamera)
                {
                    float height = 55 - (RaceTime.CountdownTime * 35f);
                    ((FixedChaseCamera)GameEngine.Camera).MinHeight = Math.Max(0, height);
                }
                var closestPath = OpponentController.GetClosestPath(ConfigFile.GridPosition);

                foreach (IDriver driver in Drivers)
                {
                    if (driver is CpuDriver)
                    {
                        if (closestPath == null)
                        {
                            ((CpuDriver)driver).SetState(CpuDriverState.Sleeping);
                        }
                        else
                        {
                            ((CpuDriver)driver).TargetNode(closestPath.End);
                        }
                    }
                }
                PlayerVehicle.Audio.Play();
            }

            Peds.Update();


            foreach (IDriver driver in Drivers)
            {
                driver.Update();
            }

            foreach (BaseGroove groove in ConfigFile.Grooves)
            {
                groove.Update();
            }
            foreach (BaseFunk funk in ConfigFile.Funks)
            {
                funk.Update();
            }

            foreach (NonCar nonCar in _nonCars)
            {
                if (nonCar.CActor.PhysXActor != null && !nonCar.CActor.PhysXActor.IsSleeping && nonCar.CActor.PhysXActor.LinearVelocity.Length() > 1)
                {
                    _actors.RecalculateActorParent(nonCar.CActor);
                }
                if (nonCar.Hit)
                {
                    nonCar.OnHit();
                }
            }

            PlayerVehicle.Update();

            foreach (Opponent opponent in Opponents)
            {
                opponent.Vehicle.Update();
            }

            MessageRenderer.Instance.Update();

            if (GameEngine.Input.WasPressed(Keys.Tab) || GameEngine.Input.WasPressed(Buttons.DPadUp))
            {
                _map.Show = !_map.Show;
            }
#if DEBUG
            if (GameEngine.Input.WasPressed(Keys.T) || GameEngine.Input.WasPressed(Buttons.DPadRight))
            {
                RaceTime.TimeRemaining += 60;
            }
#endif
        }