Esempio n. 1
0
        public void Run(GoslingAgent agent)
        {
            var carToTarget       = target - agent.Me.Location;
            var distanceRemaining = carToTarget.Flatten().Length();

            agent.Line(target - new Vector3(0, 0, 500), target + new Vector3(0, 0, 500), Color.FromRgb(255, 0, 255));

            Vector3 finalTarget;

            if (vector.HasValue)
            {
                // See comments for adjustment in JumpShot or Aerial for explanation
                var sideOfVector =
                    Utils.Sign(Vector3.Dot(Vector3.Cross(vector.Value, Vector3.UnitZ), carToTarget));
                var carToTargetPerp = Vector3.Normalize(Vector3.Cross(carToTarget, new Vector3(0, 0, sideOfVector)));
                var adjustment      = carToTarget.Angle(vector.Value) * distanceRemaining / 3.14f;
                finalTarget = target + (carToTargetPerp * adjustment);
            }
            else
            {
                finalTarget = target;
            }

            // Some adjustment to the final target to ensure it's inside the field and we don't try to drive through any
            // goalposts to reach it
            if (Math.Abs(agent.Me.Location.Y) > 5150)
            {
                finalTarget.X = Utils.Cap(finalTarget.X, -750, 750);
            }

            var localTarget = agent.Me.Local(finalTarget - agent.Me.Location);

            var(_, angleY, _) = Utils.DefaultPd(agent, localTarget, direction);
            Utils.DefaultThrottle(agent, 2300, direction);

            agent.Controller.Boost     = false;
            agent.Controller.Handbrake = Math.Abs(angleY) > 2.3 || agent.Controller.Handbrake;

            var velocity = 1 + agent.Me.Velocity.Length();

            if (distanceRemaining < 350)
            {
                agent.Pop();
            }
            else if (Math.Abs(angleY) < 0.05 && velocity > 600 && velocity < 2150 &&
                     distanceRemaining / velocity > 2)
            {
                agent.Push(new Flip(localTarget));
            }
            else if (Math.Abs(angleY) > 2.8 && velocity < 200)
            {
                agent.Push(new Flip(localTarget, cancel: true));
            }
            else if (agent.Me.Airborne)
            {
                agent.Push(new Recovery(target));
            }
        }
Esempio n. 2
0
        public void Run(GoslingAgent agent)
        {
            var carToBall = agent.Ball.Physics.Location - agent.Me.Location;
            var distance  = carToBall.Length();

            carToBall = Vector3.Normalize(carToBall);
            var ballToTarget = Vector3.Normalize(target - agent.Ball.Physics.Location);

            var   relativeVelocity = Vector3.Dot(carToBall, agent.Me.Velocity - agent.Ball.Physics.Velocity);
            float eta;

            if (relativeVelocity != 0)
            {
                eta = Utils.Cap(distance / Utils.Cap(relativeVelocity, 400, 2300), 0, 1.5f);
            }
            else
            {
                eta = 1.5f;
            }

            // If we are approaching the ball from the wrong side the car will try to only hit the very edge of the ball
            var leftVector   = Vector3.Cross(carToBall, Vector3.UnitZ);
            var rightVector  = Vector3.Cross(carToBall, -Vector3.UnitZ);
            var targetVector = Vector3.Clamp(-ballToTarget, leftVector, rightVector);
            var finalTarget  = agent.Ball.Physics.Location + (targetVector * (distance / 2));

            // Some adjustment to the final target to ensure we don't try to dirve through any goalposts to reach it
            if (Math.Abs(agent.Me.Location.Y) > 5150)
            {
                finalTarget.X = Utils.Cap(finalTarget.X, -750, 750);
            }

            agent.Line(finalTarget - new Vector3(0, 0, 100), finalTarget + new Vector3(0, 0, 100), Colors.White);

            var(_, angleY, _) = Utils.DefaultPd(agent, agent.Me.Local(finalTarget - agent.Me.Location));
            Utils.DefaultThrottle(agent,
                                  distance > 1600
                    ? 2300
                    : 2300 - Utils.Cap(1600 * Math.Abs(angleY), 0, 2050)
                                  );
            agent.Controller.Boost     = agent.Me.Airborne || Math.Abs(angleY) > 0.3 ? false : agent.Controller.Boost;
            agent.Controller.Handbrake = Math.Abs(angleY) > 2.3 || agent.Controller.Handbrake;

            if (Math.Abs(angleY) < 0.05 && (eta < 0.45 || distance < 150))
            {
                agent.Pop();
                agent.Push(new Flip(agent.Me.Local(carToBall)));
            }
        }
Esempio n. 3
0
        public void Run(GoslingAgent agent)
        {
            var carToBoost = boost.Location - agent.Me.Location;

            var distanceRemaining = carToBoost.Flatten().Length();

            agent.Line(
                boost.Location - new Vector3(0, 0, 500),
                boost.Location + new Vector3(0, 0, 500),
                Colors.Lime
                );

            float   adjustment;
            Vector3 finalTarget;
            float   carToTarget;

            if (target.HasValue)
            {
                var vector         = Vector3.Normalize(target.Value - boost.Location);
                var sideOfVector   = Utils.Sign(Vector3.Dot(Vector3.Cross(vector, Vector3.UnitZ), carToBoost));
                var carToBoostPerp = Vector3.Normalize(Vector3.Cross(carToBoost, new Vector3(0, 0, sideOfVector)));
                adjustment  = carToBoost.Angle(vector) * distanceRemaining / 3.14f;
                finalTarget = boost.Location + (carToBoostPerp * adjustment);
                carToTarget = (target.Value - agent.Me.Location).Length();
            }
            else
            {
                adjustment  = 9999;
                carToTarget = 0;
                finalTarget = boost.Location;
            }

            // Some adjustment to the final target to ensure it's inside the field and we don't try to drive through any
            // goalposts to reach it
            if (Math.Abs(agent.Me.Location.Y) > 5150)
            {
                finalTarget.X = Utils.Cap(finalTarget.X, -750, 750);
            }

            var localTarget = agent.Me.Local(finalTarget - agent.Me.Location);

            var(_, angleY, _) = Utils.DefaultPd(agent, localTarget);
            Utils.DefaultThrottle(agent, 2300);

            agent.Controller.Boost     = Math.Abs(angleY) < 0.3 && boost.Large;
            agent.Controller.Handbrake = Math.Abs(angleY) > 2.3 || agent.Controller.Handbrake;

            var velocity = 1 + agent.Me.Velocity.Length();

            if (!boost.Active || agent.Me.Boost >= 99 || distanceRemaining < 350)
            {
                agent.Pop();
            }
            else if (agent.Me.Airborne)
            {
                agent.Push(new Recovery(target));
            }
            else if (Math.Abs(angleY) < 0.05 && velocity > 600 && velocity < 2150 && distanceRemaining / velocity > 2 ||
                     adjustment < 90 && carToTarget / velocity > 2.0)
            {
                agent.Push(new Flip(localTarget));
            }
        }
Esempio n. 4
0
        public void Run(GoslingAgent agent)
        {
            var rawTimeRemaining = InterceptTime - agent.Time;
            // Capping raw_time_remaining above 0 to prevent division problems
            var timeRemaining = Utils.Cap(rawTimeRemaining, 0.001f, 10);
            var carToBall     = BallLocation - agent.Me.Location;
            // Whether we are to the left or right of the shot vector
            var sideOfShot = Utils.Sign(Vector3.Dot(Vector3.Cross(shotVector, Vector3.UnitZ), carToBall));

            var carToDodgePoint   = dodgePoint - agent.Me.Location;
            var carToDodgePerp    = Vector3.Cross(carToDodgePoint, new Vector3(0, 0, sideOfShot)); // Perpendicular
            var distanceRemaining = carToDodgePoint.Length();

            var speedRequired             = distanceRemaining / timeRemaining;
            var accelerationRequired      = Utils.Backsolve(dodgePoint, agent.Me, timeRemaining, !jumping ? 0 : 650);
            var localAccelerationRequired = agent.Me.Local(accelerationRequired);

            // The adjustment causes the car to circle around the dodge point in an effort to line up with the shot
            // vector
            // The adjustment slowly decreases to 0 as the bot nears the time to jump
            var adjustment = carToDodgePoint.Angle(shotVector) * distanceRemaining / 2f; // Size of adjustment

            adjustment *= (Utils.Cap(jumpThreshold - (accelerationRequired.Z), 0, jumpThreshold) / jumpThreshold);
            // Factoring in how close to jump we are

            // We don't adjust the final target if we are already jumping
            var finalTarget =
                dodgePoint +
                (!jumping ? Vector3.Normalize(carToDodgePerp) * adjustment : Vector3.Zero) +
                new Vector3(0, 0, 50);

            // Ensuring our target isn't too close to the sides of the field, where our car would get messed up by the
            // radius of the curves

            // Some adjustment to the final target to ensure it's inside the field and we don't try to drive through any
            // goalposts to reach it
            if (Math.Abs(agent.Me.Location.Y) > 5150)
            {
                finalTarget.X = Utils.Cap(finalTarget.X, -750, 750);
            }

            var localFinalTarget = agent.Me.Local(finalTarget - agent.Me.Location);

            // Drawing debug lines to show the dodge point and final target (which differs due to the adjustment)
            agent.Line(agent.Me.Location, dodgePoint);
            agent.Line(dodgePoint - new Vector3(0, 0, 100), dodgePoint + new Vector3(0, 0, 100), Colors.Red);
            agent.Line(finalTarget - new Vector3(0, 0, 100), finalTarget + new Vector3(0, 0, 100), Colors.Lime);
            agent.Line(agent.Ball.Physics.Location, agent.Ball.Physics.Location + (shotVector * 300));

            // Calling our drive utils to get us going towards the final target
            var(_, angleY, _) = Utils.DefaultPd(agent, localFinalTarget, direction);
            Utils.DefaultThrottle(agent, speedRequired, direction);

            agent.Line(agent.Me.Location, agent.Me.Location + (shotVector * 200), Colors.White);

            agent.Controller.Boost     = Math.Abs(angleY) > 0.3 || agent.Me.Airborne ? false : agent.Controller.Boost;
            agent.Controller.Handbrake = Math.Abs(angleY) > 2.3 && direction == 1 || agent.Controller.Handbrake;


            if (!jumping)
            {
                if (rawTimeRemaining <= 0 ||
                    (speedRequired - 2300) * timeRemaining > 60 ||
                    !Utils.ShotValid(agent, this))
                {
                    // If we're out of time or not fast enough to be within 45 units of target at the intercept time, we
                    // pop
                    agent.Pop();
                    if (agent.Me.Airborne)
                    {
                        agent.Push(new Recovery());
                    }
                }

                else if (localAccelerationRequired.Z > jumpThreshold &&
                         localAccelerationRequired.Z > localAccelerationRequired.Flatten().Length())
                {
                    // Switch into the jump when the upward acceleration required reaches our threshold, and our lateral
                    // acceleration is negligible
                    jumping = true;
                }
            }
            else
            {
                if (rawTimeRemaining > 0.2 && !Utils.ShotValid(agent, this, 150) ||
                    rawTimeRemaining <= -0.9 ||
                    !agent.Me.Airborne && counter > 0)
                {
                    agent.Pop();
                    agent.Push(new Recovery());
                }
                else if (counter == 0 && localAccelerationRequired.Z > 0 && rawTimeRemaining > 0.083)
                {
                    // Initial jump to get airborne + we hold the jump button for extra power as required
                    agent.Controller.Jump = true;
                }
                else if (counter < 3)
                {
                    // Make sure we aren't jumping for at least 3 frames
                    agent.Controller.Jump = false;
                    counter++;
                }
                else if (rawTimeRemaining <= 0.1 && rawTimeRemaining > -0.9)
                {
                    // Dodge in the direction of the shotVector
                    agent.Controller.Jump = true;
                    if (!dodging)
                    {
                        var vector = agent.Me.Local(shotVector);
                        p       = Math.Abs(vector.X) * -Utils.Sign(vector.X);
                        y       = Math.Abs(vector.Y) * Utils.Sign(vector.Y) * direction;
                        dodging = true;
                    }

                    // Simulating a deadzone so that the dodge is more natural
                    agent.Controller.Pitch = Math.Abs(p) > 0.2 ? p : 0;
                    agent.Controller.Yaw   = Math.Abs(y) > 0.3 ? y : 0;
                }
            }
        }
Esempio n. 5
0
        public void Run(GoslingAgent agent)
        {
            var rawTimeRemaining = InterceptTime - agent.Time;
            // Capping rawTimeRemaining above 0 to prevent division problems
            var timeRemaining = Utils.Cap(rawTimeRemaining, 0.01f, 10);

            var carToBall = BallLocation - agent.Me.Location;
            // Whether we are to the left or right of the shot vector
            var sideOfShot = Utils.Sign(Vector3.Dot(Vector3.Cross(shotVector, Vector3.UnitZ), carToBall));

            var carToIntercept        = intercept - agent.Me.Location;
            var carToInterceptPerp    = Vector3.Cross(carToIntercept, new Vector3(0, 0, sideOfShot)); // Perpendicular
            var flatDistanceRemaining = carToIntercept.Flatten().Length();

            var speedRequired = flatDistanceRemaining / timeRemaining;
            // When still on the ground we pretend gravity doesn't exist, for better or worse
            var accelerationRequired      = Utils.Backsolve(intercept, agent.Me, timeRemaining, 325);
            var localAccelerationRequired = agent.Me.Local(accelerationRequired);

            // The adjustment causes the car to circle around the dodge point in an effort to line up with the shot vector
            // The adjustment slowly decreases to 0 as the bot nears the time to jump
            var adjustment = carToIntercept.Angle(shotVector) * flatDistanceRemaining / 1.57f; // Size of adjustment

            // Factoring in how close to jump we are
            adjustment *= Utils.Cap(jumpThreshold - accelerationRequired.Z, 0, jumpThreshold) / jumpThreshold;
            // We don't adjust the final target if we are already jumping
            var finalTarget = intercept + (
                jumpTime == 0
                    ? Vector3.Normalize(carToInterceptPerp) * adjustment
                    : Vector3.Zero
                );

            // Some adjustment to the final target to ensure it's inside the field and we don't try to drive through any
            // goalposts to reach it
            if (Math.Abs(agent.Me.Location.Y) > 5150)
            {
                finalTarget.X = Utils.Cap(finalTarget.X, -750, 750);
            }

            var localTarget = agent.Me.Local(finalTarget - agent.Me.Location);

            // Drawing debug lines to show the dodge point and final target (which differs due to the adjustment)
            agent.Line(agent.Me.Location, intercept);
            agent.Line(intercept - new Vector3(0, 0, 100), intercept + new Vector3(0, 0, 100), Colors.Red);
            agent.Line(finalTarget - new Vector3(0, 0, 100), finalTarget + new Vector3(0, 0, 100), Colors.Lime);

            var(angleX, angleY, _) = Utils.DefaultPd(agent, localTarget);

            float timeSinceJump;

            if (jumpTime == 0)
            {
                Utils.DefaultThrottle(agent, speedRequired);
                agent.Controller.Boost     = Math.Abs(angleY) > 0.3 || agent.Me.Airborne ? false : agent.Controller.Boost;
                agent.Controller.Handbrake = Math.Abs(angleY) > 2.3 || agent.Controller.Handbrake;

                var velocityRequired = carToIntercept / timeRemaining;
                var velAbs           = velocityRequired.Abs();
                var goodSlope        = velocityRequired.Z / Utils.Cap(velAbs.X + velAbs.Y, 1, 10000) > 0.15;
                var dot = Vector3.Dot(
                    Vector3.Normalize(agent.Me.Velocity.Flatten()),
                    Vector3.Normalize(accelerationRequired.Flatten())
                    );
                if (goodSlope && localAccelerationRequired.Z > jumpThreshold && dot > 0.8)
                {
                    // Switch into the jump when the upward acceleration required reaches our threshold, hopefully we
                    // have aligned already...
                    jumpTime = agent.Time;
                }
            }
            else
            {
                timeSinceJump = agent.Time - jumpTime;

                // While airborne we boost if we're within 30 degrees of our local acceleration requirement
                if (agent.Me.Airborne && localAccelerationRequired.Length() * timeRemaining > 90)
                {
                    (angleX, angleY, _) = Utils.DefaultPd(agent, localAccelerationRequired);
                    if (Math.Abs(angleX) + Math.Abs(angleY) < 0.45)
                    {
                        agent.Controller.Boost = true;
                    }
                }
                else
                {
                    finalTarget -= new Vector3(0, 0, 45);
                    var localFinalTarget = agent.Me.Local(finalTarget - agent.Me.Location);
                    (angleX, angleY, _) = Utils.DefaultPd(agent, localFinalTarget);
                }

                if (counter == 0 && (timeSinceJump <= 0.2 && localAccelerationRequired.Z > 0))
                {
                    // Hold the jump button up to 0.2 seconds to get the most acceleration from the first jump
                    agent.Controller.Jump = true;
                }
                else if (timeSinceJump > 0.2 && counter < 3)
                {
                    // Release the jump button for 3 ticks
                    agent.Controller.Jump  = false;
                    agent.Controller.Pitch = 0;
                    agent.Controller.Yaw   = 0;
                    agent.Controller.Roll  = 0;
                    counter++;
                }
                else if (localAccelerationRequired.Z > 300 && counter == 3)
                {
                    // The acceleration from the second jump is instant, so we only do it for 1 frame
                    agent.Controller.Jump  = true;
                    agent.Controller.Pitch = 0;
                    agent.Controller.Yaw   = 0;
                    agent.Controller.Roll  = 0;
                    counter++;
                }
            }

            if (rawTimeRemaining < -0.25)
            {
                agent.Pop();
                agent.Push(new Recovery());
            }

            if (!Utils.ShotValid(agent, this, 90))
            {
                agent.Pop();
            }
        }