public void Run(GoslingAgent agent) { float elapsed; if (time == -1) { elapsed = 0; time = agent.Time; } else { elapsed = agent.Time - time; } if (elapsed < 0.15) { agent.Controller.Jump = true; } else if (elapsed >= 0.15 && counter < 3) { agent.Controller.Jump = false; counter++; } else if (elapsed < 0.3 || !cancel && elapsed < 0.9) { agent.Controller.Jump = true; agent.Controller.Pitch = pitch; agent.Controller.Yaw = yaw; } else { agent.Pop(); agent.Push(new Recovery()); } }
public void Run(GoslingAgent agent) { var relativeTarget = agent.Ball.Physics.Location - agent.Me.Location; var localTarget = agent.Me.Local(relativeTarget); Utils.DefaultPd(agent, localTarget); Utils.DefaultThrottle(agent, 2300); }
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)); } }
public void Run(GoslingAgent agent) { var target = agent.Ball.Physics.Location + new Vector3(0, 200 * Utils.Side(agent.team), 0); var localTarget = agent.Me.Local(target - agent.Me.Location); Utils.DefaultPd(agent, localTarget); Utils.DefaultThrottle(agent, 2300); if (localTarget.Length() < 650) { agent.Pop(); // Flip towards opponent goal agent.Push(new Flip(agent.Me.Local(agent.FoeGoal.Location - agent.Me.Location))); } }
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))); } }
public void Run(GoslingAgent agent) { Vector3 localTarget; if (target.HasValue) { localTarget = agent.Me.Local((target - agent.Me.Location).Value.Flatten()); } else { localTarget = agent.Me.Local(agent.Me.Velocity.Flatten()); } Utils.DefaultPd(agent, localTarget); agent.Controller.Throttle = 1; if (!agent.Me.Airborne) { agent.Pop(); } }
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)); } }
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; } } }
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(); } }