Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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)))
Ejemplo n.º 3
0
 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()
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
    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()
Ejemplo n.º 11
0
    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))
Ejemplo n.º 12
0
    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))
Ejemplo n.º 13
0
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']))
Ejemplo n.º 14
0
    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)))
Ejemplo n.º 15
0
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']))
Ejemplo n.º 16
0
    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)
Ejemplo n.º 17
0
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
Ejemplo n.º 18
0
    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
Ejemplo n.º 19
0
    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
Ejemplo n.º 20
0
    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))
Ejemplo n.º 21
0
    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
Ejemplo n.º 22
0
    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)))
Ejemplo n.º 23
0
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'])
Ejemplo n.º 24
0
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']))
Ejemplo n.º 25
0
    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()
Ejemplo n.º 26
0
    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)))
Ejemplo n.º 27
0
    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
Ejemplo n.º 28
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'])
Ejemplo n.º 29
0
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])))
Ejemplo n.º 30
0
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])))