def run(self, agent): ball_slice = agent.ball_prediction_struct.slices[ agent.future_ball_location_slice].physics.location ball = Vector(ball_slice.x, cap(ball_slice.y, -5100, 5100)) agent.line(ball, ball + Vector(z=185), agent.renderer.white()) ball.y *= side(agent.team) if ball.y < agent.ball.location.y * side(agent.team): ball = Vector(agent.ball.location.x, agent.ball.location.y * side(agent.team) + 640) target = self.get_target(agent) agent.line(target, target + Vector(z=642), (255, 0, 255)) if target.flat_dist(agent.me.location) < 350: if agent.me.velocity.magnitude() > 100: self.brake.run(agent, manual=True) elif abs(Vector(x=1).angle2D(agent.me.local_location(ball))) > 0.5: agent.pop() agent.push(face_target(ball=True)) else: agent.pop() else: self.goto.target = target self.goto.run(agent, manual=True)
def run(self, agent): target = agent.ball.location + Vector(y=200 * side(agent.team)) local_target = agent.me.local(target - agent.me.location) defaultPD(agent, local_target) defaultThrottle(agent, 2300) distance = local_target.magnitude() agent.controller.throttle = 1 agent.controller.boost = True if distance < 650: if len(agent.foes ) > 0 and agent.predictions['closest_enemy'] > 1000: if distance < 100 or distance > 500: agent.pop() agent.kickoff_done = True defaultPD( agent, agent.ball.location - Vector(y=500 * side(agent.team))) elif distance < 450: agent.pop() agent.kickoff_done = True agent.push(flip(agent.me.local(agent.foe_goal.location)))
def run(self, agent: VirxERLU): print("running speedflip routine") if self.stage == 0: agent.controller.boost = True if agent.me.boost > self.old_boost: self.stage = 1 agent.print(f"Next stage: {self.stage}") else: self.old_boost = agent.me.boost elif self.stage == 1: angles = defaultPD( agent, agent.me.local_location(Vector(110 * sign(agent.me.location.x)))) if abs(angles[1]) < 0.1: self.stage = 2 agent.print(f"Next stage: {self.stage}") elif self.stage == 2: agent.push(speed_flip()) self.stage = 3 agent.print(f"Next stage: {self.stage}") elif self.stage == 3: # TODO do a second flip is the opponent is speedflipping as well if False: agent.push( flip( agent.me.local_location( Vector(120 * sign(agent.me.location.x))))) self.stage = 4 agent.print(f"Next stage: {self.stage}") elif self.stage == 4: agent.pop()
def run(self, agent): if self.start_time is None: self.start_time = agent.time ball_loc = agent.ball.location.y * side(agent.team) if agent.time - self.start_time > 0.5 or agent.playstyle is agent.playstyles.Defensive or ball_loc > 2560: agent.pop() return target = Vector(y=(ball_loc + 1280) * side(agent.team)) if agent.ball.location.x > 2560: target.x = 2560 if ball_loc <= 0 else 1024 elif agent.ball.location.x < -2560: target.x = -2560 if ball_loc <= 0 else -1024 self_to_target = agent.me.location.dist(target) if self_to_target > 250: self.goto.target = target self.goto.vector = agent.ball.location self.goto.run(agent, manual=True) if self_to_target < 500: agent.controller.boost = False agent.controller.throttle = cap(agent.controller.throttle, -0.75, 0.75)
def find_aerial(agent, target, cap_=4): struct = agent.predictions['ball_struct'] if struct is None: return max_aerial_height = math.inf if len(agent.friends) == 0 and len(agent.foes) == 1: max_aerial_height = 643 i = 10 # Begin by looking 0.2 seconds into the future while i < struct.num_slices: intercept_time = struct.slices[i].game_seconds time_remaining = intercept_time - agent.time if time_remaining <= 0: return ball_location = Vector(struct.slices[i].physics.location.x, struct.slices[i].physics.location.y, struct.slices[i].physics.location.z) if abs(ball_location.y) > 5212: break ball_velocity = Vector( struct.slices[i].physics.velocity.x, struct.slices[i].physics.velocity.y, struct.slices[i].physics.velocity.z).magnitude() i += 15 - cap(int(ball_velocity // 150), 0, 13) # we don't actually need to calculate if we can get there; it is_viable function will do that for us # we just need a few variables to find the best shot vector car_to_ball = ball_location - agent.me.location direction = car_to_ball.normalize() left, right, swapped = post_correction(ball_location, target[0], target[1]) if not swapped: left_vector = (left - ball_location).normalize() right_vector = (right - ball_location).normalize() best_shot_vector = direction.clamp(left_vector, right_vector) # relax the in_field requirement # reduce cap_ from 6 to 4 (by default) if in_field(ball_location - (100 * best_shot_vector), 1) and is_fast_shot(agent.me.location, ball_location, intercept_time, agent.time, cap_): slope = find_slope(best_shot_vector, car_to_ball) ball_intercept = ball_location - 92 * best_shot_vector if slope > 0.5 and 275 < ball_intercept.z and ball_intercept.z < max_aerial_height: aerial = Aerial(ball_intercept, intercept_time) if aerial.is_viable(agent): return aerial
def find_any_jump_shot(agent, cap_=3): struct = agent.predictions['ball_struct'] if struct is None: return i = 5 while i < struct.num_slices: intercept_time = struct.slices[i].game_seconds time_remaining = intercept_time - agent.time if time_remaining <= 0: return ball_location = Vector(struct.slices[i].physics.location.x, struct.slices[i].physics.location.y, struct.slices[i].physics.location.z) if abs(ball_location.y) > 5212: break ball_velocity = Vector( struct.slices[i].physics.velocity.x, struct.slices[i].physics.velocity.y, struct.slices[i].physics.velocity.z).magnitude() i += 15 - cap(int(ball_velocity // 150), 0, 13) if ball_location.z > 350: continue car_to_ball = ball_location - agent.me.location direction, distance = car_to_ball.normalize(True) forward_angle = direction.angle(agent.me.forward) backward_angle = math.pi - forward_angle forward_time = time_remaining - (forward_angle * 0.318) backward_time = time_remaining - (backward_angle * 0.418) forward_flag = forward_time > 0 and ( distance * 1.05 / forward_time) < (2275 if agent.me.boost > distance / 100 else 1400) backward_flag = distance < 1500 and backward_time > 0 and ( distance * 1.05 / backward_time) < 1200 # our current direction IS our best shot vector, as we just want to get to the ball as fast as possible if (forward_flag or backward_flag) and is_fast_shot( agent.me.location, ball_location, intercept_time, agent.time, cap_): slope = find_slope(direction, car_to_ball) if forward_flag and ball_location.z <= 275 and slope > 0: return jump_shot(ball_location, intercept_time, direction) elif backward_flag and ball_location.z <= 250 and slope > 1.5: return jump_shot(ball_location, intercept_time, direction, -1)
def run(self, agent): if agent.me.boost == 0: agent.pop() agent.push(self.face) target = agent.me.local(agent.me.forward.flatten() * 100 - Vector(z=100)) defaultPD(agent, target) if not agent.me.airborne: agent.pop() elif abs(Vector(x=1).angle(target)) < 0.5: agent.controller.boost = True
def run(self, agent): agent.shooting = True if self.start_time is None: self.start_time = agent.time car_to_ball, distance = (agent.ball.location - agent.me.location).normalize(True) ball_to_target = (self.target - agent.ball.location).normalize() relative_velocity = car_to_ball.dot(agent.me.velocity - agent.ball.velocity) if relative_velocity != 0: eta = cap(distance / cap(relative_velocity, 400, 2300), 0, 1.5) else: eta = 1.5 # If we are approaching the ball from the wrong side the car will try to only hit the very edge of the ball left_vector = car_to_ball.cross(Vector(z=1)) right_vector = car_to_ball.cross(Vector(z=-1)) target_vector = -ball_to_target.clamp(left_vector, right_vector) final_target = agent.ball.location + (target_vector * (distance / 2)) # Some adjustment to the final target to ensure we don't try to dirve through any goalposts to reach it if abs(agent.me.location.y) > 5150: final_target.x = cap(final_target.x, -750, 750) agent.line(final_target - Vector(z=100), final_target + Vector(z=100), [255, 255, 255]) angles = defaultPD(agent, agent.me.local(final_target - agent.me.location)) defaultThrottle( agent, 2300 if distance > 1600 else 2300 - cap(1600 * abs(angles[1]), 0, 2050)) agent.controller.boost = False if agent.me.airborne or abs( angles[1]) > 0.3 else agent.controller.boost agent.controller.handbrake = True if abs( angles[1]) > 2.3 else agent.controller.handbrake if abs(angles[1]) < 0.05 and (eta < 0.45 or distance < 150): agent.pop() agent.shooting = False agent.shot_weight = -1 agent.shot_time = -1 agent.push(flip(agent.me.local(car_to_ball))) elif agent.time - self.start_time > 3: agent.pop() agent.shooting = False agent.shot_weight = -1 agent.shot_time = -1
def run(self, agent): ball_slice = agent.ball_prediction_struct.slices[ agent.future_ball_location_slice].physics.location ball_loc = Vector(ball_slice.x, ball_slice.y) agent.line(ball_loc, ball_loc + Vector(z=185), agent.renderer.white()) ball_loc.y *= side(agent.team) if ball_loc.y < -2560 or (ball_loc.y < agent.ball.location.y * side(agent.team)): ball_loc = Vector(agent.ball.location.x, agent.ball.location.y * side(agent.team) + 640) distance = 1280 target = Vector(y=(ball_loc.y + distance) * side(agent.team)) agent.line(target, target + Vector(z=642), (255, 0, 255)) target.x = (abs(ball_loc.x) + (250 if target.y < -1280 else -( 1024 if abs(ball_loc.x) > 1024 else ball_loc.x))) * sign( ball_loc.x) self_to_target = agent.me.location.dist(target) if self_to_target < 250 and ball_loc.y < -640 and agent.me.velocity.magnitude( ) < 100 and abs( Vector(x=1).angle2D( agent.me.local_location(agent.ball.location))) > 0.1: agent.push(face_target(ball=True)) else: self.goto.target = target self.goto.vector = agent.ball.location self.goto.run(agent, manual=True) if self_to_target < 500: agent.controller.boost = False
def run(self, agent): if self.start_time is None: self.start_time = agent.time car_to_boost = self.boost.location - agent.me.location distance_remaining = car_to_boost.flatten().magnitude() agent.line(self.boost.location - Vector(z=500), self.boost.location + Vector(z=500), [0, 255, 0]) if self.target is not None: vector = (self.target - self.boost.location).normalize() side_of_vector = sign(vector.cross(Vector(z=1)).dot(car_to_boost)) car_to_boost_perp = car_to_boost.cross( Vector(z=side_of_vector)).normalize() adjustment = car_to_boost.angle(vector) * distance_remaining / 3.14 final_target = self.boost.location + (car_to_boost_perp * adjustment) car_to_target = (self.target - agent.me.location).magnitude() else: adjustment = 9999 car_to_target = 0 final_target = self.boost.location # Some adjustment to the final target to ensure it's inside the field and we don't try to dirve through any goalposts to reach it if abs(agent.me.location.y) > 5150: final_target.x = cap(final_target.x, -750, 750) local_target = agent.me.local(final_target - agent.me.location) angles = defaultPD(agent, local_target) defaultThrottle(agent, 2300) agent.controller.boost = self.boost.large if abs( angles[1]) < 0.3 else False agent.controller.handbrake = True if abs( angles[1]) > 2.3 else agent.controller.handbrake velocity = 1 + agent.me.velocity.magnitude() if not self.boost.active or agent.me.boost >= 99.0 or distance_remaining < 350: agent.pop() elif agent.me.airborne: agent.push(recovery(self.target)) elif abs(angles[1]) < 0.05 and velocity > 600 and velocity < 2150 and ( distance_remaining / velocity > 2.0 or (adjustment < 90 and car_to_target / velocity > 2.0)): agent.push(flip(local_target)) elif agent.time - self.start_time > 6 and not agent.stack[ -1].__class__.__name__ == "flip": agent.pop()
def run(self, agent, manual=False): car_to_target = self.target - agent.me.location distance_remaining = car_to_target.flatten().magnitude() agent.dbg_2d(distance_remaining) agent.line(self.target - Vector(z=500), self.target + Vector(z=500), [255, 0, 255]) if (not self.brake and distance_remaining < 350) or (self.brake and distance_remaining < (agent.me.local(agent.me.velocity).x ** 2 * -1) / (2 * brake_accel.x)): if not manual: agent.pop() if self.brake: agent.push(brake()) return if self.vector != None: # See commends for adjustment in jump_shot or aerial for explanation side_of_vector = sign(self.vector.cross(Vector(z=1)).dot(car_to_target)) car_to_target_perp = car_to_target.cross(Vector(z=side_of_vector)).normalize() adjustment = car_to_target.angle(self.vector) * distance_remaining / 3.14 final_target = self.target + (car_to_target_perp * adjustment) else: final_target = self.target # Some adjustment to the final target to ensure it's inside the field and we don't try to dirve through any goalposts to reach it if abs(agent.me.location.y) > 5150: final_target.x = cap(final_target.x, -750, 750) local_target = agent.me.local(final_target - agent.me.location) angles = defaultPD(agent, local_target, self.direction) defaultThrottle(agent, 2300, self.direction) if len(agent.friends) > 0 and agent.me.local(agent.me.velocity).x < 250 and agent.controller.throttle > 0.75 and min(agent.me.location.flat_dist(car.location) for car in agent.friends) < 251: agent.push(flip(Vector(y=250))) return if agent.me.boost < 30 or (agent.playstyle is agent.playstyles.Defensive and agent.predictions['self_from_goal'] < 4000): agent.controller.boost = False agent.controller.handbrake = True if abs(angles[1]) >= 2.3 or (agent.me.local(agent.me.velocity).x >= 1400 and abs(angles[1]) > 1.5) else agent.controller.handbrake velocity = 1+agent.me.velocity.magnitude() if abs(angles[1]) < 0.05 and velocity > 600 and velocity < 2150 and distance_remaining / velocity > 2: agent.push(flip(local_target)) elif abs(angles[1]) > 2.8 and velocity < 200 and distance_remaining / velocity > 2: agent.push(flip(local_target, True)) elif agent.me.airborne: agent.push(recovery(self.target))
def run(self, agent): target = agent.ball.location car_to_target = target - agent.me.location distance_remaining = car_to_target.flatten().magnitude() angle_to_target = abs( Vector(x=1).angle2D(agent.me.local_location(target))) direction = 1 if angle_to_target < 2.2 else -1 local_target = agent.me.local_location(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 abs(agent.me.location.y) > 5120 - (agent.me.hitbox.width / 2): local_target.x = cap(local_target.x, -750, 750) angles = defaultPD(agent, local_target) defaultThrottle(agent, 1400) agent.controller.handbrake = angle_to_target > 1.54 velocity = agent.me.local_velocity().x if distance_remaining < self.exit_distance: agent.pop() if self.exit_flip: agent.push(flip(local_target)) elif angle_to_target < 0.05 and velocity > 600 and velocity < 1400 and distance_remaining / velocity > 3: agent.push(flip(local_target)) elif angle_to_target >= 2 and distance_remaining > 1000 and velocity < 200 and distance_remaining / abs( velocity) > 2: agent.push(flip(local_target, True)) elif agent.me.airborne: agent.push(recovery(local_target))
def find_double_jump(agent, target, weight=None, cap_=6): slices = get_slices(agent, cap_, weight=weight, start_slice=30) if slices is None: return target = (target[0].tuple(), target[1].tuple()) me = (agent.me.location.tuple(), agent.me.forward.tuple(), agent.me.boost if agent.boost_amount != 'unlimited' else 100000, agent.me.local_velocity().x) game_info = (agent.best_shot_value, agent.boost_accel) for ball_slice in slices: intercept_time = ball_slice.game_seconds time_remaining = intercept_time - agent.time if time_remaining <= 0: continue ball_location = (ball_slice.physics.location.x, ball_slice.physics.location.y, ball_slice.physics.location.z) if abs(ball_location[1]) > 5212.75: return shot = virxrlcu.parse_slice_for_double_jump_with_target( time_remaining - 0.3, *game_info, ball_location, *me, *target) if shot['found'] == 1: return double_jump(intercept_time, Vector(*shot['best_shot_vector']))
def run(self, agent): if self.start_time is None: self.start_time = agent.time if not self.wave_dash: time_elapsed = agent.time - self.start_time if time_elapsed > 0.75: self.wave_dash = True agent.push(wave_dash()) target = agent.ball.location + Vector(y=200 * side(agent.team)) local_target = agent.me.local(target - agent.me.location) defaultPD(agent, local_target) agent.controller.throttle = 1 agent.controller.boost = True distance = local_target.magnitude() if distance < 650: if len(agent.foes ) > 0 and agent.predictions['closest_enemy'] > 1000: if distance < 100 or distance > 700: agent.pop() agent.kickoff_done = True else: agent.pop() agent.kickoff_done = True agent.push( flip( agent.me.local(agent.foe_goal.location - agent.me.location)))
def find_any_jump_shot(agent, cap_=3): slices = get_slices(agent, cap_) if slices is None: return me = (agent.me.location.tuple(), agent.me.forward.tuple(), agent.me.boost if agent.boost_amount != 'unlimited' else 1000000, agent.me.local_velocity().x) game_info = (agent.best_shot_value, agent.boost_accel) for ball_slice in slices: intercept_time = ball_slice.game_seconds time_remaining = intercept_time - agent.time if time_remaining <= 0: continue ball_location = (ball_slice.physics.location.x, ball_slice.physics.location.y, ball_slice.physics.location.z) if abs(ball_location[1]) > 5212.75: return shot = virxrlcu.parse_slice_for_jump_shot(time_remaining - 0.1, *game_info, ball_location, *me) if shot['found'] == 1: return jump_shot(intercept_time, Vector(*shot['best_shot_vector']))
def run(self, agent): if agent.ball.location.y * side(agent.team) < 2560 and agent.playstyle is not agent.playstyles.Defensive: agent.pop() return team_to_ball = [car.location.flat_dist(agent.ball.location) for car in agent.friends if car.location.y * side(agent.team) >= agent.ball.location.y * side(agent.team) - 50 and abs(car.location.x) < abs(agent.ball.location.x)] self_to_ball = agent.me.location.flat_dist(agent.ball.location) team_to_ball.append(self_to_ball) team_to_ball.sort() if len(agent.friends) <= 1 or (agent.ball.location.x <= 900 and agent.ball.location.x >= -900) or len(team_to_ball) <= 1: target = agent.friend_goal.location elif team_to_ball[-1] == self_to_ball: target = agent.friend_goal.right_post if abs(agent.ball.location.x) > 900 else agent.friend_goal.left_post else: target = agent.friend_goal.left_post if abs(agent.ball.location.x) > 900 else agent.friend_goal.right_post target = target.copy() if agent.ball.location.y * side(agent.team) > 4620 and target == agent.friend_goal.location: target.y = (agent.ball.location.y * side(agent.team) + 250) * side(agent.team) else: target = target + Vector(y=-245 * side(agent.team)) target = target.flatten() agent.line(target, target + Vector(z=100)) if target.flat_dist(agent.me.location) < 100: if abs(agent.me.local(agent.me.velocity).x) > 10 and not self.facing: agent.push(brake()) return if self.facing or (abs(agent.me.local(agent.me.velocity).x) < 10 and Vector(x=1).angle(agent.me.local(agent.ball.location - agent.me.location)) > 0.25): self.facing = True if self.counter == 0: agent.controller.jump = True elif self.counter == 2: agent.pop() agent.push(ball_recovery()) self.counter += 1 return agent.pop() else: self.goto.target = target self.goto.run(agent, manual=True)
def find_any_aerial(agent, cap_=3): struct = agent.predictions['ball_struct'] if struct is None: return max_aerial_height = math.inf if len(agent.friends) == 0 and len(agent.foes) == 1: max_aerial_height = 643 i = 10 # Begin by looking 0.2 seconds into the future while i < struct.num_slices: intercept_time = struct.slices[i].game_seconds time_remaining = intercept_time - agent.time if time_remaining <= 0: return ball_location = Vector(struct.slices[i].physics.location.x, struct.slices[i].physics.location.y, struct.slices[i].physics.location.z) if abs(ball_location.y) > 5212: break ball_velocity = Vector( struct.slices[i].physics.velocity.x, struct.slices[i].physics.velocity.y, struct.slices[i].physics.velocity.z).magnitude() i += 15 - cap(int(ball_velocity // 150), 0, 13) if 275 > ball_location.z or ball_location.z > max_aerial_height: continue # remove the need for a target to hit the ball to if is_fast_shot(agent.me.location, ball_location, intercept_time, agent.time, cap_): aerial = Aerial(ball_location, intercept_time) if aerial.is_viable(agent): return aerial
def run(self, agent): if not agent.shooting: agent.shooting = True if self.start_time is None: self.start_time = agent.time car_to_ball, distance = (agent.ball.location - agent.me.location).normalize(True) ball_to_target = (self.target - agent.ball.location).normalize() angle_to_target = abs(Vector(x=1).angle2D(agent.me.local(car_to_ball))) relative_velocity = car_to_ball.dot(agent.me.velocity - agent.ball.velocity) eta = cap(distance / cap(relative_velocity, 400, 1400), 0, 1.5) if relative_velocity != 0 else 1.5 # If we are approaching the ball from the wrong side the car will try to only hit the very edge of the ball left_vector = car_to_ball.cross(Vector(z=1)) right_vector = car_to_ball.cross(Vector(z=-1)) target_vector = -ball_to_target.clamp2D(left_vector, right_vector) final_target = agent.ball.location + (target_vector * (distance / 2)) # Some adjustment to the final target to ensure we don't try to drive through any goalposts to reach it if abs(agent.me.location.y) > 5130: final_target.x = cap(final_target.x, -750, 750) agent.line(final_target - Vector(z=100), final_target + Vector(z=100), (255, 255, 255)) angles = defaultPD(agent, agent.me.local_location(final_target)) defaultThrottle(agent, 1400) agent.controller.handbrake = angle_to_target > 1.54 if abs(angles[1]) < 0.05 and (eta < 0.45 or distance < 150): agent.pop() agent.shooting = False agent.push(flip(agent.me.local(car_to_ball))) elif agent.time - self.start_time > 0.24: # This will run for 3 ticks, then pop agent.pop() agent.shooting = False
def get_intercept(self, agent): struct = agent.predictions['ball_struct'] intercepts = [] i = 30 # Begin by looking 0.3 seconds into the future while i < struct.num_slices: intercept_time = struct.slices[i].game_seconds time_remaining = intercept_time - agent.time ball_location = Vector(struct.slices[i].physics.location.x, struct.slices[i].physics.location.y, struct.slices[i].physics.location.z) if abs(ball_location.y) > 5212: break last_ball_location = Vector(struct.slices[i-2].physics.location.x, struct.slices[i-2].physics.location.y, struct.slices[i-2].physics.location.z) ball_velocity = Vector(struct.slices[i].physics.velocity.x, struct.slices[i].physics.velocity.y, struct.slices[i].physics.velocity.z).magnitude() i += 15 - cap(int(ball_velocity//150), 0, 13) if time_remaining < 0 or ball_location.z > 120 or ball_location.flat_dist(agent.friend_goal.location) > last_ball_location.flat_dist(agent.friend_goal.location): continue car_to_ball = ball_location - agent.me.location direction, distance = car_to_ball.normalize(True) forward_angle = direction.angle(agent.me.forward) backward_angle = math.pi - forward_angle forward_time = time_remaining - (forward_angle * 0.318) backward_time = time_remaining - (backward_angle * 0.418) forward_flag = forward_time > 0 and (distance / forward_time) < 1800 backward_flag = distance < 1500 and backward_time > 0 and (distance / backward_time) < 1200 if forward_flag or backward_flag: intercepts.append(( ball_location, intercept_time, 1 if forward_flag else -1 )) if len(intercepts) == 0: return None, None, None intercepts = list(filter(lambda i: i[1] - agent.time < 3, intercepts)) intercepts.sort(key=lambda i: agent.me.location.dist(i[0])) final = (None, None, None) last_speed = math.inf for intercept in intercepts: speed = agent.me.location.dist(intercept[0]) / ((intercept[1] / agent.time) * (3/5)) if abs(speed - 1100) < abs(last_speed - 1100): final = intercept last_speed = speed return final
def run(self, agent): if self.ball: target = (agent.ball.location - agent.me.location).flatten() else: target = agent.me.velocity.flatten() if self.target is None else ( self.target - agent.me.location).flatten() if agent.gravity.z < -550 and agent.gravity.z > -750: if self.counter == 0 and abs(Vector(x=1).angle(target)) <= 0.05: agent.pop() return if self.counter < 3: self.counter += 1 target = agent.me.local(target) if self.counter < 3: agent.controller.jump = True elif agent.me.airborne and abs(Vector(x=1).angle(target)) > 0.05: defaultPD(agent, target) else: agent.pop() else: target = agent.me.local(target) angle_to_target = abs(Vector(x=1).angle2D(target)) if angle_to_target > 0.1: if self.start_loc is None: self.start_loc = agent.me.location direction = -1 if angle_to_target < 1.57 else 1 agent.controller.steer = cap(target.y / 100, -1, 1) * direction agent.controller.throttle = 0.5 * direction agent.controller.handbrake = True else: agent.pop() if self.start_loc is not None: agent.push(goto(self.start_loc, target, True))
def run(self, agent): agent.shooting = True agent.shot_weight = agent.max_shot_weight - 1 if self.ball_location is None or not shot_valid(agent, self, threshold=75): self.ball_location, self.intercept_time, self.direction = self.get_intercept(agent) if self.ball_location is None: agent.shooting = False agent.shot_weight = -1 agent.pop() return agent.shot_time = self.intercept_time t = self.intercept_time - agent.time # if we ran out of time, just pop # this can be because we were successful or not - we can't tell if t < -0.3: agent.shooting = False agent.shot_weight = -1 agent.pop() return if self.brake: if agent.ball.location.dist(agent.me.location) < 250 and agent.ball.location.y * side(agent.team) + 10 < agent.me.location.y and agent.ball.location.z < 190: agent.pop() agent.flip(agent.me.local(agent.ball.location)) else: # current velocity u = agent.me.local(agent.me.velocity).x a = brake_accel.x # calculate how much distance we need to slow down x = (u ** 2 * -1) / (2 * a) if self.ball_location.dist(agent.me.location) <= x: self.brake = True agent.push(brake()) return agent.line(self.ball_location.flatten(), self.ball_location.flatten() + Vector(z=250), color=[255, 0, 255]) angles = defaultPD(agent, agent.me.local(self.ball_location - agent.me.location), self.direction) # We want to get there before the ball does, so take the time we have and get 3 fifths of it required_speed = cap(agent.me.location.dist(self.ball_location) / ((self.intercept_time - agent.time) * (3/5)), 600, 2275) defaultThrottle(agent, required_speed, self.direction) agent.controller.boost = False if abs(angles[1]) > 0.3 else agent.controller.boost agent.controller.handbrake = True if abs(angles[1]) >= 2.3 or (agent.me.local(agent.me.velocity).x >= 1400 and abs(angles[1]) > 1.5) and self.direction == 1 else False
def run(self, agent): if self.flip: agent.kickoff_done = True agent.pop() return target = agent.ball.location + Vector(y=200*side(agent.team)) local_target = agent.me.local(target - agent.me.location) defaultPD(agent, local_target) agent.controller.throttle = 1 agent.controller.boost = True distance = local_target.magnitude() if distance < 550: self.flip = True agent.push(flip(agent.me.local(agent.foe_goal.location - agent.me.location)))
def find_any_aerial(agent, cap_=3): slices = get_slices(agent, cap_) if slices is None: return me = (agent.me.location.tuple(), agent.me.velocity.tuple(), agent.me.up.tuple(), agent.me.forward.tuple(), 1 if agent.me.airborne else -1, agent.me.boost if agent.boost_amount != 'unlimited' else 100000) gravity = agent.gravity.tuple() max_aerial_height = 735 if len(agent.friends) == 0 and len( agent.foes) == 1 else math.inf min_aerial_height = 551 if max_aerial_height > 643 and agent.me.location.z >= 2044 - agent.me.hitbox.height * 1.1 else ( 0 if agent.boost_amount == 'unlimited' else 450) for ball_slice in slices: intercept_time = ball_slice.game_seconds time_remaining = intercept_time - agent.time if time_remaining <= 0: return ball_location = (ball_slice.physics.location.x, ball_slice.physics.location.y, ball_slice.physics.location.z) if abs(ball_location[1]) > 5212.75: return if min_aerial_height > ball_location[2] or ball_location[ 2] > max_aerial_height: continue shot = virxrlcu.parse_slice_for_aerial_shot(time_remaining, agent.best_shot_value, agent.boost_accel, gravity, ball_location, me) if shot['found'] == 1: return Aerial(intercept_time, Vector(*shot['best_shot_vector']), shot['fast'])
def find_jump_shot(agent, target, weight=None, cap_=6): # Takes a tuple of (left,right) target pairs and finds routines that could hit the ball between those target pairs # Only meant for routines that require a defined intercept time/place in the future # Here we get the slices that need to be searched - by defining a cap or a weight, we can reduce the number of slices and improve search times slices = get_slices(agent, cap_, weight=weight) if slices is None: return # Assemble data in a form that can be passed to C target = (target[0].tuple(), target[1].tuple()) me = (agent.me.location.tuple(), agent.me.forward.tuple(), agent.me.boost if agent.boost_amount != 'unlimited' else 100000, agent.me.local_velocity().x) game_info = (agent.best_shot_value, agent.boost_accel) # Loop through the slices for ball_slice in slices: # Gather some data about the slice intercept_time = ball_slice.game_seconds time_remaining = intercept_time - agent.time if time_remaining <= 0: continue ball_location = (ball_slice.physics.location.x, ball_slice.physics.location.y, ball_slice.physics.location.z) if abs(ball_location[1]) > 5212.75: return # abandon search if ball is scored at/after this point # Check if we can make a shot at this slice # This operation is very expensive, so we use a custom C function to improve run time shot = virxrlcu.parse_slice_for_jump_shot_with_target( time_remaining - 0.1, *game_info, ball_location, *me, *target) # If we found a viable shot, pass the data into the shot routine and return the shot if shot['found'] == 1: return jump_shot(intercept_time, Vector(*shot['best_shot_vector']))
def get_target(self, agent): target = None ball_slice = agent.ball_prediction_struct.slices[ agent.future_ball_location_slice].physics.location ball = Vector(ball_slice.x, ball_slice.y, ball_slice.z) ball_y = ball.y * side(agent.team) team_to_ball = [ car.location.flat_dist(ball) for car in agent.friends if car.location.y * side(agent.team) >= ball_y - 50 and abs(car.location.x) < abs(ball.x) ] self_to_ball = agent.me.location.flat_dist(ball) team_to_ball.append(self_to_ball) team_to_ball.sort() if agent.me.location.y * side(agent.team) >= ball_y - 50 and abs( agent.me.location.x) < abs(ball.x): if len(agent.friends) == 0 or abs( ball.x) < 900 or team_to_ball[-1] is self_to_ball: target = agent.friend_goal.location elif team_to_ball[0] is self_to_ball: target = agent.friend_goal.right_post if abs( ball.x) > 10 else agent.friend_goal.left_post if target is None: if len(agent.friends) <= 1: target = agent.friend_goal.location else: target = agent.friend_goal.left_post if abs( ball.x) > 10 else agent.friend_goal.right_post target = target.copy() target.y += 250 * side(agent.team) if len(agent.friends) == 0 or abs( ball.x) < 900 or team_to_ball[-1] is self_to_ball else -245 * side( agent.team) return target.flatten()
def run(self, agent): if self.start_time == -1: self.start_time = agent.time if self.flip or agent.time - self.start_time > 3: agent.kickoff_done = True agent.pop() return target = agent.ball.location + Vector(y=( 200 if agent.gravity.z < -600 and agent.gravity.z > -700 else 50) * side(agent.team)) local_target = agent.me.local_location(target) defaultPD(agent, local_target) agent.controller.throttle = 1 agent.controller.boost = True distance = local_target.magnitude() if distance < 550: self.flip = True agent.push(flip(agent.me.local_location(agent.foe_goal.location)))
def run(self, agent): self.step += 1 target_switch = { 0: agent.me.forward.flatten() * 100 + Vector(z=50), 1: agent.me.forward.flatten() * 100, 2: agent.me.forward.flatten() * 100 - Vector(z=50), 3: agent.me.forward.flatten() * 100 } target_up = { 0: agent.me.local(Vector(z=1)), 1: agent.me.local(Vector(y=-50, z=1)), 2: agent.me.local(Vector(z=1)), 3: agent.me.local(Vector(y=50, z=1)) } defaultPD(agent, agent.me.local(target_switch[self.direction]), up=target_up[self.direction]) if self.direction == 0: agent.controller.throttle = 1 elif self.direction == 2: agent.controller.throttle = -1 else: agent.controller.handbrake = True if self.step < 1: agent.controller.jump = True elif self.step < 4: pass elif not agent.me.airborne: agent.pop() elif agent.me.location.z + (agent.me.velocity.z * 0.2) < 5: agent.controller.jump = True agent.controller.yaw = 0 if self.direction in {0, 2}: agent.controller.roll = 0 agent.controller.pitch = -1 if self.direction is 0 else 1 else: agent.controller.roll = -1 if self.direction is 1 else 1 agent.controller.pitch = 0
def find_any_shot(agent, cap_=3, can_aerial=True, can_double_jump=True, can_jump=True): if not can_aerial and not can_double_jump and not can_jump: agent.print("WARNING: All shots were disabled when find_shot was ran") return slices = get_slices(agent, cap_) if slices is None: return me = (agent.me.location.tuple(), agent.me.forward.tuple(), agent.me.boost if agent.boost_amount != 'unlimited' else 100000, agent.me.local_velocity().x) game_info = (agent.best_shot_value, agent.boost_accel) if can_aerial: me_a = (me[0], agent.me.velocity.tuple(), agent.me.up.tuple(), me[1], 1 if agent.me.airborne else -1, me[2]) gravity = agent.gravity.tuple() max_aerial_height = 643 if len(agent.friends) == 0 and len( agent.foes) == 1 else math.inf min_aerial_height = 551 if max_aerial_height > 643 and agent.me.location.z >= 2044 - agent.me.hitbox.height * 1.1 else ( 0 if agent.boost_amount == 'unlimited' else 450) for ball_slice in slices: intercept_time = ball_slice.game_seconds time_remaining = intercept_time - agent.time if time_remaining <= 0: return ball_location = (ball_slice.physics.location.x, ball_slice.physics.location.y, ball_slice.physics.location.z) if abs(ball_location[1]) > 5212.75: return if can_jump: shot = virxrlcu.parse_slice_for_jump_shot(time_remaining - 0.1, *game_info, ball_location, *me) if shot['found'] == 1: return jump_shot(intercept_time, Vector(*shot['best_shot_vector'])) if can_double_jump and time_remaining >= 0.5: shot = virxrlcu.parse_slice_for_double_jump( time_remaining - 0.3, *game_info, ball_location, *me) if shot['found'] == 1: return double_jump(intercept_time, Vector(*shot['best_shot_vector'])) if can_aerial and not (min_aerial_height > ball_location[2] or ball_location[2] > max_aerial_height): shot = virxrlcu.parse_slice_for_aerial_shot( time_remaining, *game_info, gravity, ball_location, me_a) if shot['found'] == 1: return Aerial(intercept_time, Vector(*shot['best_shot_vector']), shot['fast'])
def find_shot(agent, target, cap_=6, can_aerial=True, can_double_jump=True, can_jump=True, can_ground=True): if not can_aerial and not can_double_jump and not can_jump and not can_ground: agent.print("WARNING: All shots were disabled when find_shot was ran") return # Takes a tuple of (left,right) target pairs and finds routines that could hit the ball between those target pairs # Only meant for routines that require a defined intercept time/place in the future # Assemble data in a form that can be passed to C targets = (tuple(target[0]), tuple(target[1])) me = agent.me.get_raw(agent) game_info = (agent.boost_accel, agent.ball_radius) gravity = tuple(agent.gravity) is_on_ground = not agent.me.airborne can_ground = is_on_ground and can_ground can_jump = is_on_ground and can_jump can_double_jump = is_on_ground and can_double_jump if not can_ground and not can_jump and not can_double_jump and not can_aerial: return # Here we get the slices that need to be searched - by defining a cap, we can reduce the number of slices and improve search times slices = get_slices(agent, cap_) if slices is None: return # Loop through the slices for ball_slice in slices: # Gather some data about the slice intercept_time = ball_slice.game_seconds T = intercept_time - agent.time - (1 / 120) if T <= 0: return ball_location = (ball_slice.physics.location.x, ball_slice.physics.location.y, ball_slice.physics.location.z) if abs(ball_location[1]) > 5212.75: return # abandon search if ball is scored at/after this point ball_info = (ball_location, (ball_slice.physics.velocity.x, ball_slice.physics.velocity.y, ball_slice.physics.velocity.z)) # Check if we can make a shot at this slice # This operation is very expensive, so we use C to improve run time shot = virxrlcu.parse_slice_for_shot_with_target( can_ground, can_jump, can_double_jump, can_aerial, T, *game_info, gravity, ball_info, me, targets) if shot['found'] == 1: shot_type = ShotType(shot["shot_type"]) if shot_type == ShotType.AERIAL: return Aerial( intercept_time, (Vector(*shot['targets'][0]), Vector(*shot['targets'][1])), shot['fast']) return SHOT_SWITCH[shot_type]( intercept_time, (Vector(*shot['targets'][0]), Vector(*shot['targets'][1])))
def find_shot(agent, target, cap_=6, can_aerial=True, can_double_jump=True, can_jump=True, can_ground=True): if not can_aerial and not can_double_jump and not can_jump and not can_ground: agent.print("WARNING: All shots were disabled when find_shot was ran") return # Takes a tuple of (left,right) target pairs and finds routines that could hit the ball between those target pairs # Only meant for routines that require a defined intercept time/place in the future # Assemble data in a form that can be passed to C targets = (tuple(target[0]), tuple(target[1])) me = agent.me.get_raw(agent) game_info = (agent.boost_accel, agent.best_shot_value) gravity = tuple(agent.gravity) max_aerial_height = 1200 if len(agent.friends) == 0 and len( agent.foes) == 1 else math.inf min_aerial_height = 551 if max_aerial_height > 1200 and agent.me.location.z >= 2044 - agent.me.hitbox.height * 1.1 else ( 150 if agent.boost_amount == 'unlimited' or agent.me.airborne else 450) is_on_ground = not agent.me.airborne can_ground = is_on_ground and can_ground can_jump = is_on_ground and can_jump can_double_jump = is_on_ground and can_double_jump if not can_ground and not can_jump and not can_double_jump and not can_aerial: return # Here we get the slices that need to be searched - by defining a cap, we can reduce the number of slices and improve search times slices = get_slices(agent, cap_) if slices is None: return # Loop through the slices for ball_slice in slices: # Gather some data about the slice intercept_time = ball_slice.game_seconds time_remaining = intercept_time - agent.time - (1 / 120) if time_remaining <= 0: return ball_location = (ball_slice.physics.location.x, ball_slice.physics.location.y, ball_slice.physics.location.z) if abs(ball_location[1]) > 5212.75: return # abandon search if ball is scored at/after this point ball_info = (ball_location, (ball_slice.physics.velocity.x, ball_slice.physics.velocity.y, ball_slice.physics.velocity.z)) # Check if we can make a shot at this slice # This operation is very expensive, so we use C to improve run time shot = virxrlcu.parse_slice_for_shot_with_target( can_ground, can_jump, can_double_jump, can_aerial and (min_aerial_height < ball_location[2] < max_aerial_height), time_remaining, *game_info, gravity, ball_info, me, targets) if shot['found'] == 1: if shot['shot_type'] == 3: return Aerial( intercept_time, (Vector(*shot['targets'][0]), Vector(*shot['targets'][1])), shot['fast']) shot_switch = [ground_shot, jump_shot, double_jump] return shot_switch[shot['shot_type']]( intercept_time, (Vector(*shot['targets'][0]), Vector(*shot['targets'][1])))