Ejemplo n.º 1
0
 def run(self, my_car, packet, agent):
     car_location = Vec3(my_car.physics.location)
     vertical_vel = my_car.physics.velocity.z
     controls = SimpleControllerState()
     controls.yaw = steer_toward_target(
         my_car, self.target, -my_car.physics.angular_velocity.z / 6)
     controls.boost = not (vertical_vel < 0 and car_location.z > 40
                           and self.tick < 20)
     controls.use_item = car_location.dist(
         Vec3(packet.game_ball.physics.location
              )) < 200 and relative_location(
                  car_location, Orientation(my_car.physics.rotation),
                  Vec3(packet.game_ball.physics.location)).z < 75
     if self.tick == 0:
         controls.jump = True
         self.tick = 1
     else:
         if self.tick <= 10: self.tick += 1
         elif my_car.has_wheel_contact: agent.stack.pop()
         if vertical_vel < 0 and car_location.z > 40 and self.tick < 20:
             self.tick += 1
             controls.pitch = 1
         if vertical_vel < 0 and car_location.z < 40:
             controls.jump = True
             controls.pitch = -1
             controls.yaw = 0
     return controls
Ejemplo n.º 2
0
 def get(self, data):
     c = SimpleControllerState()
     c.throttle = max(min(data[0], 1), -1)
     c.steer = max(min(data[1], 1), -1)
     c.pitch = max(min(data[2], 1), -1)
     c.yaw = max(min(data[3], 1), -1)
     c.roll = max(min(data[4], 1), -1)
     c.jump = data[5]
     c.boost = data[6]
     c.handbrake = data[7]
     c.use_item = data[8]
     return c
Ejemplo n.º 3
0
def copy_controls(obj_to: SimpleControllerState,
                  obj_from: SimpleControllerState):
    """Copies the attribute of one SimpleControlerStates to another"""
    obj_to.steer = obj_from.steer
    obj_to.throttle = obj_from.throttle
    obj_to.pitch = obj_from.pitch
    obj_to.yaw = obj_from.yaw
    obj_to.roll = obj_from.roll
    obj_to.jump = obj_from.jump
    obj_to.boost = obj_from.boost
    obj_to.handbrake = obj_from.handbrake
    obj_to.use_item = obj_from.use_item
Ejemplo n.º 4
0
    def get_output(self,
                   game_tick_packet: GameTickPacket) -> SimpleControllerState:
        controller_state = SimpleControllerState()

        if not game_tick_packet.game_info.is_round_active:
            return controller_state

        ball_location = Vector2(game_tick_packet.game_ball.physics.location.x,
                                game_tick_packet.game_ball.physics.location.y)

        my_car = game_tick_packet.game_cars[self.index]
        car_location = Vector2(my_car.physics.location.x,
                               my_car.physics.location.y)
        car_direction = get_car_facing_vector(my_car)
        car_to_ball = ball_location - car_location

        steer_correction_radians = car_direction.correction_to(car_to_ball)

        if steer_correction_radians > 0:
            # Positive radians in the unit circle is a turn to the left.
            turn = -1.0  # Negative value for a turn to the left.
        else:
            turn = 1.0

        if self.flip_turning:
            turn *= -1.0

        if self.test_quickchat:
            if turn == -1.0 and random() > .99:
                self.send_quick_chat(QuickChats.CHAT_EVERYONE,
                                     QuickChats.Information_IGotIt)

            if turn == 1.0 and random() > .99:
                self.send_quick_chat(QuickChats.CHAT_EVERYONE,
                                     QuickChats.Reactions_HolyCow)

        if self.test_rendering:
            self.do_rendering_test(game_tick_packet, my_car)

        if self.test_dropshot:
            self.do_dropshot_tile_test(game_tick_packet)

        if self.test_state:
            self.set_state_test(game_tick_packet)

        if self.test_ball_prediction:
            self.render_ball_prediction()

        if self.test_physics_tick:
            self.do_physics_tick_test(game_tick_packet)

        # Not making this configurable because it's easier to just modify the code
        # self.render_packet(game_tick_packet)

        if random() > .997:
            game_state = GameState(console_commands=["Stat FPS"])
            self.set_game_state(game_state)

        if random() > .99:
            game_map = self.get_match_settings().MutatorSettings(
            ).RumbleOption()
            self.logger.info(
                f'Is Spike Rush? {game_map == RumbleOption.Spike_Rush}')

        controller_state.throttle = 1.0
        controller_state.steer = turn
        controller_state.use_item = random() > .99

        return controller_state
Ejemplo n.º 5
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:

        self.boost_pad_tracker.update_boost_status(packet)

        if self.active_sequence is not None and not self.active_sequence.done:
            controls = self.active_sequence.tick(packet)
            if controls is not None:
                return controls
        # Get the distance from the nearest surface (walls, floor, roof, etc.)
        def distance_from_surface(pos):
            min_dist = math.inf
            nearest_surface = pos
            if min_dist > pos.z:
                min_dist = pos.z
                nearest_surface = Vec3(pos.x, pos.y, 0)
            if min_dist > self.map_size[1] - abs(pos.x):
                min_dist = self.map_size[1] - abs(pos.x)
                nearest_surface = Vec3(
                    sign(pos.x) * self.map_size[1], pos.y, pos.z)
            if min_dist > self.map_size[0] - abs(pos.y):
                min_dist = self.map_size[0] - abs(pos.y)
                nearest_surface = Vec3(pos.x,
                                       sign(pos.y) * self.map_size[0], pos.z)
            if min_dist > 99999 + (8064 - abs(pos.x) -
                                   abs(pos.y)) / math.sqrt(2):
                min_dist = (8064 - abs(pos.x) - abs(pos.y)) / math.sqrt(2)
                nearest_surface = Vec3(pos.x,
                                       sign(pos.y) * self.map_size[0], pos.z)
            return nearest_surface

        # Get the rate in which the object is moving away from the nearest surface
        def velocity_from_surface(pos, vel):
            val = pos - distance_from_surface(pos)
            if val.x != 0:
                return vel.x * sign(val.x)
            elif val.y != 0:
                return vel.y * sign(val.y)
            elif val.z != 0:
                return vel.z * sign(val.z)

        # Get the order within the team
        def distance_order(teams):
            nearest = 1
            overall_nearest = 1
            last = 0
            ref = (car_location - ball_location).length(
            ) / (car_velocity.length() + 2300) + math.asin(
                (car_velocity * safe_div(car_velocity.length()) -
                 ball_location * safe_div(ball_location.length())).length() /
                2) * 3 / math.pi * 0
            for i in range(len(packet.game_cars)):
                if (packet.game_cars[i].team !=
                    (-teams * packet.game_cars[self.index].team +
                     (1 + teams) / 2) or teams == False
                    ) and packet.game_cars[i].physics.location.z > 0:
                    time_taken = (
                        Vec3(packet.game_cars[i].physics.location) -
                        ball_location).length() / (Vec3(packet.game_cars[
                            i].physics.velocity).length() + 2300) + math.asin(
                                (Vec3(packet.game_cars[i].physics.velocity) *
                                 safe_div(
                                     Vec3(packet.game_cars[i].physics.velocity
                                          ).length()) - ball_location *
                                 safe_div(ball_location.length())).length() /
                                2) * 3 / math.pi * 0
                    # When the car is further front than the POV
                    if ref > time_taken:
                        if ((Vec3(packet.game_cars[i].physics.location) +
                             send_location).length() <=
                            (ball_location + send_location).length()
                                or (car_location + send_location).length() >
                            (ball_location + send_location).length()):
                            nearest += 1
                        overall_nearest += 1
                    last += 1
            # Keep the full-time goal keeper
            if overall_nearest == last:
                nearest = overall_nearest
            # Prevent the division by 0 error
            return last, nearest

        # Find the best boost pads to use to refuel as fast as possible
        def find_best_boost_pads():
            best_pad = None
            best_score = math.inf
            for i in range(len(self.get_field_info().boost_pads)):
                pad = self.get_field_info().boost_pads[i]
                if packet.game_boosts[
                        i].is_active == True or packet.game_boosts[i].timer <= (
                            Vec3(pad.location) - car_location).length() / 2300:
                    score = (Vec3(pad.location) - car_location).length(
                    ) * safe_div(car_velocity.length()) + math.sin(
                        ((Vec3(pad.location) - car_location) /
                         (Vec3(pad.location) - car_location).length() -
                         car_velocity * safe_div(car_velocity.length())
                         ).length() / 2) * 3 / math.pi
                    if pad.is_full_boost:
                        score *= safe_div((50 - my_car.boost / 2) / 6)
                    if score < best_score:
                        best_score = score
                        best_pad = pad
            return Vec3(best_pad.location)

        # Get the yaw based on position
        def get_yaw(x, y):
            a = math.acos(x / Vec3(x, y, 0).length())
            if abs(a) < math.pi:
                return a * sign(y)
            else:
                return math.pi

        # Get the angle between two places
        def get_angle(p1, p2):
            d = (p1 * safe_div(p1.length()) -
                 p2 * safe_div(p2.length())).length()
            angle = 2 * math.asin(d / 2)
            return angle

        # Determine when the car would intersect the ball assuming a speed
        def intersect_time(surface):
            t1 = 5
            t2 = 5
            best_spd = math.inf
            slowest = math.inf
            if surface == False:
                for i in range(1, 101):
                    time_location = Vec3(predict_ball(i / 20).physics.location)
                    if (time_location - car_location).length(
                    ) * 20 / i <= car_velocity.length() and t1 == 5:
                        t1 = i / 20
                    if (time_location -
                            car_location).length() * 20 / i <= slowest:
                        slowest = (time_location -
                                   car_location).length() * 20 / i
                        t2 = i / 20
            else:
                for i in range(1, 101):
                    time_location = Vec3(predict_ball(i / 20).physics.location)
                    if (distance_from_surface(time_location) -
                            distance_from_surface(car_location)).length(
                            ) * 20 / i <= car_velocity.length() and t1 == 5:
                        t1 = i / 20
                    if (distance_from_surface(time_location) -
                            distance_from_surface(car_location)
                        ).length() * 20 / i <= slowest:
                        slowest = (distance_from_surface(time_location) -
                                   distance_from_surface(car_location)
                                   ).length() * 20 / i
                        t2 = i / 20

            return t1, t2

        # Determine when the car should jump
        def jump_ready(val):
            if val <= 300 and val > 92.75:
                delay = (2 * (val - 92.75) / 650)**0.5
                return delay
            else:
                return 0

        # Get the nearest player to the ball
        def nearest_player(teams, speed_offset):
            nearest = None
            best_time = math.inf
            last = True
            for i in range(len(packet.game_cars)):
                if (packet.game_cars[i].team !=
                    (-teams * packet.game_cars[self.index].team +
                     (1 + teams) / 2) or teams == False) and Vec3(
                         packet.game_cars[i].physics.location) != Vec3(
                             0, 0, 0):
                    time_taken = (Vec3(
                        packet.game_cars[i].physics.location
                    ) - ball_location).length() / (Vec3(
                        packet.game_cars[i].physics.velocity
                    ).length() + speed_offset) + math.sin(
                        (Vec3(packet.game_cars[i].physics.velocity) * safe_div(
                            Vec3(packet.game_cars[i].physics.velocity).length(
                            )) - ball_location *
                         safe_div(ball_location.length())).length() /
                        2) * 3 / math.pi
                    if time_taken < best_time:
                        best_time = time_taken
                        nearest = packet.game_cars[i]
            return nearest, best_time

        # Get the list of moments when the ball should be hit
        def opportunities():
            li = []
            prev_pos = ball_location
            for i in range(1, 101):
                time_location = predict_ball(i / 20)
                if time_location.z <= 300:
                    li.append([
                        i / 20,
                        (time_location - car_location).length() * 20 / i
                    ])
                prev_pos = time_location
            return li

        # ???
        def plane_dist(pos, dist):
            if Vec3(pos.x, pos.y, 0).length() <= dist:
                return True
            elif Vec3(pos.x, 0, pos.z).length() <= dist:
                return True
            elif Vec3(0, pos.y, pos.z).length() <= dist:
                return True
            else:
                return False

        # Get the ball's position and velocity at a specific time
        def predict_ball(t):
            ball_in_future = find_slice_at_time(
                ball_prediction, packet.game_info.seconds_elapsed + t)
            if ball_in_future is not None:
                return ball_in_future
            else:
                return packet.game_ball

        # Divide numbers without division by 0
        def safe_div(x):
            if x == 0:
                return math.inf
            else:
                return 1 / x

        # Return the direction of the value from 0
        def sign(x):
            if x < 0:
                return -1
            elif x > 0:
                return 1
            else:
                return 0

        # Return a value with limitations
        def clamp(x, m, M):
            if x < m:
                return m
            elif x > M:
                return M
            else:
                return x

        # Move the target location to straighten the ascent up walls
        def move_target_for_walls(pos1, pos2):
            up1 = distance_from_surface(pos1)
            up2 = distance_from_surface(pos2)
            new_pos = pos2
            if up1.z == 0 and up2.z > 0:
                new_pos = Vec3(new_pos, 0, new_pos) + (up2 - pos2) * safe_div(
                    (up2 - pos2).length()) * up2.z
            if up1.z > 0 and up2.z == 0 and pos1.z >= 30:
                if abs(up1.x) == self.map_size[1]:
                    new_pos = Vec3(up1.x, up2.y, -abs(up2.x - up1.x))
                elif abs(up1.y) == self.map_size[0]:
                    new_pos = Vec3(up2.x, up1.y, -abs(up2.y - up1.y))
            return new_pos

        # Actions
        # Use flip jumps to attack the ball
        def jump_attack():
            dir_y = 0
            dir_x = 0
            if ((car_location + car_velocity / 5) -
                (ball_location + ball_velocity / 5)).length() <= 175:
                if (car_location + Vec3(car_velocity.y, -car_velocity.x, 0) *
                        safe_div(car_velocity.length()) -
                        ball_location).length() < (car_location -
                                                   ball_location).length():
                    dir_x = -1
                if (car_location + Vec3(-car_velocity.y, car_velocity.x, 0) *
                        safe_div(car_velocity.length()) -
                        ball_location).length() < (car_location -
                                                   ball_location).length():
                    dir_x = 1
                if (car_location + car_velocity / 5 - ball_location -
                        ball_velocity / 5
                    ).length() <= (car_location - ball_location).length() - 50:
                    dir_y = -1
                dir_x *= sign(math.pi / 2 -
                              get_angle(car_direction, car_velocity))
                dir_y *= sign(math.pi / 2 -
                              get_angle(car_direction, car_velocity))
                override = self.flip(packet, dir_x, dir_y, not my_car.jumped)

        # Jump over cars to prevent collision
        def avoid_bump():
            for i in range(len(packet.game_cars)):
                if i != self.index and packet.game_cars[
                        i].physics.location.z > 0:
                    pos = car_location
                    pos2 = Vec3(packet.game_cars[i].physics.location)
                    vel = car_velocity
                    vel2 = Vec3(packet.game_cars[i].physics.velocity)
                    dist = (pos - pos2).length()
                    on_course = False
                    if dist > 40:
                        if get_angle(pos2 - pos, vel) <= math.tan(
                                math.sqrt(40**2 / (dist**2 - 40**2))):
                            on_course = True
                    else:
                        on_course = True
                    if on_course == True and dist <= 40 + (vel - vel2).length(
                    ) / 2 and (vel.length() <= vel2.length()
                               or packet.game_cars[i].team != self.team):
                        self.jump_once(packet)

        # Modes
        def attack():
            # Target
            target_ball = predict_ball(earliest_intersection)
            target_location = Vec3(target_ball.physics.location)
            target_location = target_location + (
                target_location - send_location) / (
                    target_location - send_location).length() * 92.75
            # Smoother wall transitions
            target_location = move_target_for_walls(car_location,
                                                    target_location)
            jumping = jump_ready(
                (target_location -
                 distance_from_surface(target_location)).length())
            # Manage speed
            if velocity_from_surface(
                    Vec3(target_ball.physics.location),
                    Vec3(target_ball.physics.velocity)) >= 0 or (Vec3(
                        target_ball.physics.location) - distance_from_surface(
                            Vec3(target_ball.physics.location))).length(
                            ) <= 300 or target_ball.physics.location.y * sign(
                                send_location.y) <= -self.map_size[0]:
                controls.throttle = 1
            else:
                controls.throttle = 0
            # Boost
            controls.boost = abs(
                steer_toward_target(my_car, target_location)
            ) <= 0.1 and car_velocity.length() < 2300 and (
                (Vec3(target_ball.physics.location) - distance_from_surface(
                    Vec3(target_ball.physics.location))).length() <= 300
                or velocity_from_surface(Vec3(target_ball.physics.location),
                                         Vec3(target_ball.physics.velocity)) >=
                0) and car_index == 1
            # Jump
            h = (Vec3(target_ball.physics.location) - distance_from_surface(
                Vec3(target_ball.physics.location))).length()
            if jump_ready(
                (Vec3(target_ball.physics.location) -
                 distance_from_surface(Vec3(target_ball.physics.location))
                 ).length()) >= earliest_intersection and steer_toward_target(
                     my_car, target_location) < 1:
                controls.pitch = 0
                controls.yaw = 0
                controls.roll = 0
                controls.jump = True
                controls.boost = False
            else:
                jump_attack()
            # Catch the ball when in the air
            if abs(
                    target_location.z - car_location.z
            ) <= 92.75 * 0.75 and get_angle(
                    target_location - car_location, car_velocity
            ) >= math.atan(
                    200 * safe_div(car_velocity.length())
            ) and my_car.jumped == True and my_car.double_jumped == False and False:
                controls.yaw = sign(
                    (target_location - car_location -
                     Vec3(car_velocity.y, -car_velocity.x, car_velocity.z)
                     ).length() -
                    (target_location - car_location -
                     Vec3(-car_velocity.y, car_velocity.x, car_velocity.z)
                     ).length())
                controls.jump = True
            # Draw
            self.renderer.draw_line_3d(car_location, target_location,
                                       self.renderer.red())
            self.renderer.draw_rect_3d(target_location,
                                       8,
                                       8,
                                       True,
                                       self.renderer.red(),
                                       centered=True)
            return target_location

        def standby():
            # Friendly/enemey
            if enemy_time >= friendly_time + 0.2:
                nearest_ref = nearest_friendly
                md = "friendly"
            else:
                nearest_ref = nearest_enemy
                md = "enemy"
            # Target
            if md == "enemy" or True:
                target_location = ball_location - (
                    Vec3(nearest_ref.physics.location) - ball_location) / (
                        Vec3(nearest_ref.physics.location) -
                        ball_location).length() * (2500 + Vec3(
                            nearest_ref.physics.velocity).length() * 5 / 2.3)
                target_location = Vec3(
                    target_location.x,
                    ball_location.y + (target_location.y - ball_location.y) *
                    sign(target_location.y - ball_location.y) *
                    -sign(send_location.y), target_location.z)
            else:
                target_location = ball_location - (
                    Vec3(nearest_ref.physics.location) - ball_location) / (
                        Vec3(nearest_ref.physics.location) -
                        ball_location).length() * (2500 + Vec3(
                            nearest_ref.physics.velocity).length() * 5 / 2.3)
                target_location = target_location + (
                    target_location - send_location) / (
                        target_location - send_location).length() * 927.5
            # Walls
            if (distance_from_surface(target_location) -
                    target_location).length() <= 300:
                target_location = distance_from_surface(target_location)
                target_location = move_target_for_walls(
                    car_location, target_location)
            else:
                target_location = Vec3(target_location.x, target_location.y, 0)
            # Draw
            self.renderer.draw_line_3d(car_location, target_location,
                                       self.renderer.green())
            self.renderer.draw_rect_3d(target_location,
                                       8,
                                       8,
                                       True,
                                       self.renderer.green(),
                                       centered=True)
            # Manage speed
            controls.boost = False
            controls.throttle = clamp(
                (target_location - car_location).length() / 1000, -1, 1)
            return target_location

        def refuel():
            # Target
            target_location = find_best_boost_pads()
            # Draw
            self.renderer.draw_line_3d(car_location, target_location,
                                       self.renderer.green())
            self.renderer.draw_rect_3d(target_location,
                                       8,
                                       8,
                                       True,
                                       self.renderer.green(),
                                       centered=True)
            # Speed
            controls.throttle = 1
            controls.boost = False
            return target_location

        def goalie():
            target_location = car_location
            # Roll back onto the wheels
            if abs(car_rotation.roll) >= math.pi * 3 / 4:
                override = self.jump_once(packet)
            # Prepare for a save
            if sign(car_location.y) == -sign(send_location.y) and abs(
                    car_location.y) >= abs(send_location.y):
                target_location = car_location - Vec3(0, send_location.y, 0)
                if car_velocity.length() >= 850:
                    controls.throttle = -1
                else:
                    if Vec3(car_velocity.x, car_velocity.y, 0).length() >= 250:
                        override = self.reverse_flip(packet)
                    else:
                        controls.pitch = 0
                        controls.roll = 0
                        if (not math.pi * 0.4 <= abs(car_rotation.yaw) <=
                                math.pi * 0.6 or sign(car_rotation.yaw)
                                == -sign(send_location.y)) and abs(
                                    car_velocity.z) <= 1:
                            override = self.jump_once(packet)
                        controls.yaw = clamp(
                            steer_toward_target(my_car, send_location) -
                            my_car.physics.angular_velocity.z, -1, 1)
                    controls.throttle = 0
            # Drive into the goal unless it's already done so
            else:
                target_location = defend()
            return target_location

        def defend():
            if not in_goal:
                target_ball = predict_ball(earliest_intersection)
                target_location = Vec3(target_ball.physics.location)
                nearest_surface = (target_location - car_location) / (
                    target_location - car_location).length() * 140
                nearest_surface_r = Vec3(-nearest_surface.y, nearest_surface.x,
                                         nearest_surface.z)
                nearest_surface_l = Vec3(nearest_surface.y, -nearest_surface.x,
                                         nearest_surface.z)
                if False:
                    side = -sign((nearest_surface_l - send_location).length() -
                                 (nearest_surface_r - send_location).length())
                else:
                    side = -sign(((nearest_surface_l - ball_location) -
                                  ball_velocity).length() -
                                 ((nearest_surface_r - ball_location) -
                                  ball_velocity).length())
                nearest_surface = Vec3(-nearest_surface.y * side,
                                       nearest_surface.x * side,
                                       nearest_surface.z)
                if abs(target_location.x +
                       nearest_surface.x) >= self.map_size[1] or get_angle(
                           car_location - send_location,
                           car_location - target_location
                       ) > math.pi / 3 * 2 or ball_location.z > 130:
                    target_location = -send_location
                else:
                    target_location = target_location + nearest_surface / 140 * car_velocity.length(
                    )
                controls.boost = enemy_time < 1 and abs(
                    steer_toward_target(my_car, target_location)) <= 0.1
                # Jump
                h = (Vec3(target_ball.physics.location) -
                     distance_from_surface(Vec3(
                         target_ball.physics.location))).length()
                if jump_ready(
                        h) >= earliest_intersection and steer_toward_target(
                            my_car, target_location) < 1:
                    controls.pitch = 0
                    controls.yaw = 0
                    controls.roll = 0
                    controls.jump = True
                    controls.boost = False
                else:
                    jump_attack()
                # Draw
                self.renderer.draw_line_3d(car_location,
                                           ball_location + nearest_surface,
                                           self.renderer.cyan())
                self.renderer.draw_rect_3d(ball_location + nearest_surface,
                                           8,
                                           8,
                                           True,
                                           self.renderer.cyan(),
                                           centered=True)
                controls.throttle = 1
            else:
                target_location = -send_location
                controls.throttle = 1
            return target_location

        def recovery():
            tx = (self.map_size[1] - car_location.x *
                  sign(car_velocity.x)) * safe_div(car_velocity.x)
            ty = (self.map_size[0] - car_location.y *
                  sign(car_velocity.y)) * safe_div(car_velocity.y)
            tt = 0
            if car_location.z / 325 - (car_velocity.z / 650)**2 >= 0:
                tz = car_velocity.z / 650 + math.sqrt(car_location.z / 325 -
                                                      (car_velocity.z /
                                                       650)**2)
            else:
                tz = car_velocity.z / 650 - math.sqrt(car_location.z / 325 +
                                                      (car_velocity.z /
                                                       650)**2)
            if tx >= tz <= ty:
                controls.roll = clamp(-car_rotation.roll, -1, 1)
                controls.pitch = clamp(-car_rotation.pitch, -1, 1)
                tt = tz
            elif tx >= ty <= tz:
                point = (math.pi / 2 +
                         sign(abs(car_rotation.yaw) - math.pi / 2) * math.pi /
                         2) * sign(car_rotation.yaw)
                controls.roll = clamp(
                    math.pi / 2 * sign(car_velocity.y) *
                    sign(abs(car_rotation.yaw) - math.pi / 2) -
                    car_rotation.roll, -1, 1)
                controls.pitch = clamp(point - car_rotation.yaw, -1, 1)
                tt = ty
            draw_point = Vec3(
                car_location.x + car_velocity.x * tt,
                car_location.y + car_velocity.y * tt,
                car_location.z + car_velocity.z * tt - 325 * tt**2)
            self.renderer.draw_line_3d(car_location, draw_point,
                                       self.renderer.pink())
            self.renderer.draw_rect_3d(draw_point,
                                       8,
                                       8,
                                       True,
                                       self.renderer.pink(),
                                       centered=True)

        # Variables

        my_car = packet.game_cars[self.index]
        car_location = Vec3(my_car.physics.location)
        car_velocity = Vec3(my_car.physics.velocity)
        car_rotation = my_car.physics.rotation
        car_direction = Vec3(
            math.cos(car_rotation.yaw) * math.cos(car_rotation.pitch),
            math.sin(car_rotation.yaw) * math.cos(car_rotation.pitch),
            math.sin(car_rotation.pitch))
        ball_prediction = self.get_ball_prediction_struct()
        ball_location = Vec3(packet.game_ball.physics.location)
        ball_velocity = Vec3(packet.game_ball.physics.velocity)
        send_location = Vec3(0, sign(0.5 - self.team) * self.map_size[0], 0)
        earliest_intersection, easiest_intersection = intersect_time(True)
        team_size, car_index = distance_order(1)
        nearest_enemy, enemy_time = nearest_player(0, 460)
        nearest_friendly, friendly_time = nearest_player(0, 460)
        in_goal = (ball_location + send_location).length() > (
            car_location + send_location).length()
        target_location = car_location
        mode = ""
        override = None

        # Controls
        controls = SimpleControllerState()

        # Half-flip to quickly turn
        if car_velocity.length() <= 500 and get_angle(
                car_velocity,
                target_location - car_location) >= math.pi / 3 * 2:
            override = self.reverse_flip(packet)

        # Assign role in the team
        if abs(send_location.y + Vec3(predict_ball(2).physics.location).y
               ) <= 1000 or abs(send_location.y + ball_location.y) <= 1000:
            if in_goal:
                mode = "Attack"
            else:
                mode = "Defense"
        else:
            if car_index == 1:
                if in_goal:
                    mode = "Attack"
                else:
                    mode = "Defense"
            elif car_index < team_size:
                if my_car.boost == 100 and car_index == 2:
                    mode = "Standby"
                else:
                    mode = "Refuel"
            else:
                mode = "Goalie"
        # Recovery
        if my_car.double_jumped:
            recovery()
        # Demolition
        if mode == "Demo":
            target_location = demo()
        # Attack the ball
        if mode == "Attack":
            avoid_bump()
            target_location = attack()
            controls.use_item = True
        # Stand by for hit
        if mode == "Standby":
            avoid_bump()
            target_location = standby()
        # Collect boost
        if mode == "Refuel":
            avoid_bump()
            target_location = refuel()
        # Retreat
        if mode == "Defense":
            avoid_bump()
            target_location = defend()
        # Goalie
        if mode == "Goalie":
            avoid_bump()
            target_location = goalie()

        controls.steer = steer_toward_target(my_car, target_location)

        # Draw
        if False:
            self.renderer.draw_string_2d(
                800, 200, 1, 1, "X: " +
                str(packet.game_cars[1 - self.index].physics.location.x),
                self.renderer.white())
            self.renderer.draw_string_2d(
                800, 220, 1, 1, "Y: " +
                str(packet.game_cars[1 - self.index].physics.location.y),
                self.renderer.white())
            self.renderer.draw_string_2d(1400, 200, 1, 1,
                                         "Map: " + str(self.map),
                                         self.renderer.white())
        self.renderer.draw_string_2d(
            50, 680 + car_index * 20 * (0.5 - self.team) * 2, 1, 1,
            "Noob Bot " + str(car_index) + ": " + str(mode),
            self.renderer.white())
        self.renderer.draw_line_3d(target_location,
                                   distance_from_surface(target_location),
                                   self.renderer.yellow())

        if override:
            return override
        else:
            return controls
Ejemplo n.º 6
0
    def get_output(self,
                   game_tick_packet: GameTickPacket) -> SimpleControllerState:
        controller_state = SimpleControllerState()

        self.state_listener.tick(game_tick_packet)
        # if self.sequence is None or self.sequence.done:
        #     self.sequence = Sequence(steps=[
        #         Step(0.3, SimpleControllerState(jump=True)),
        #         Step(0.05, SimpleControllerState()),
        #         Step(0.6, SimpleControllerState(jump=True)),
        #         Step(2, SimpleControllerState())
        #     ])

        if not game_tick_packet.game_info.is_round_active:
            return controller_state

        ball_location = Vector2(game_tick_packet.game_ball.physics.location.x,
                                game_tick_packet.game_ball.physics.location.y)

        my_car = game_tick_packet.game_cars[self.index]
        # print(f'wheel contact: {my_car.jumped}')
        car_location = Vector2(my_car.physics.location.x,
                               my_car.physics.location.y)
        car_direction = get_car_facing_vector(my_car)
        car_to_ball = ball_location - car_location

        steer_correction_radians = car_direction.correction_to(car_to_ball)

        if steer_correction_radians > 0:
            # Positive radians in the unit circle is a turn to the left.
            turn = -1.0  # Negative value for a turn to the left.
        else:
            turn = 1.0

        if self.flip_turning:
            turn *= -1.0

        if self.test_quickchat or True:
            if turn == -1.0 and random() > .99:
                self.send_quick_chat(QuickChats.CHAT_EVERYONE,
                                     QuickChats.Custom_Excuses_Rigged)

            if turn == 1.0 and random() > .99:
                self.send_quick_chat(QuickChats.CHAT_EVERYONE,
                                     QuickChats.Reactions_HolyCow)

        if self.test_rendering:
            self.do_rendering_test(game_tick_packet, my_car)

        if self.test_dropshot:
            self.do_dropshot_tile_test(game_tick_packet)

        if self.test_state:
            self.set_state_test(game_tick_packet)

        if self.test_ball_prediction:
            self.render_ball_prediction()

        if self.test_physics_tick:
            self.do_physics_tick_test(game_tick_packet)

        # Not making this configurable because it's easier to just modify the code
        self.render_packet(game_tick_packet)

        # if random() > .997:
        #     game_state = GameState(console_commands=["Stat FPS"])
        #     self.set_game_state(game_state)

        # if random() > .99:
        #     mutator_settings = self.get_match_settings().MutatorSettings()
        #     if mutator_settings is not None:
        #         self.logger.info(f'Is Spike Rush? {mutator_settings.RumbleOption() == RumbleOption.Spike_Rush}')

        # controller_state = self.sequence.tick(game_tick_packet)
        controller_state.steer = turn
        controller_state.throttle = 1

        controller_state.use_item = int(game_tick_packet.game_info.seconds_elapsed) % 10 == 0 and \
                                    self.prev_seconds_elapsed % 10 != 0 and self.index == 0
        self.prev_seconds_elapsed = int(
            game_tick_packet.game_info.seconds_elapsed)

        # self.logger.info(f'idx {self.index} prev {self.prev_seconds_remaining} curr {game_tick_packet.game_info.game_time_remaining}')

        if controller_state.use_item:
            self.logger.info("Use item.")

        return controller_state
Ejemplo n.º 7
-1
def goto(target_location, target_speed, my_car, agent, packet):
    car_speed = Vec3(my_car.physics.velocity).length()
    distance = Vec3(my_car.physics.location).flat().dist(
        target_location.flat())
    angle = Orientation(
        my_car.physics.rotation).forward.ang_to(target_location -
                                                Vec3(my_car.physics.location))
    controls = SimpleControllerState()
    controls.steer = steer_toward_target(my_car, target_location, 0)
    controls.yaw = steer_toward_target(my_car, target_location,
                                       -my_car.physics.angular_velocity.z / 6)
    controls.throttle = cap(target_speed - car_speed, -1, 1)
    controls.boost = (target_speed > 1410
                      and abs(target_speed - car_speed) > 20 and angle < 0.3)
    controls.handbrake = angle > 2.3
    controls.jump = (1 if my_car.physics.location.y >= 0 else -1) == (
        1 if agent.team == 1 else -1
    ) and abs(
        my_car.physics.location.y) > 5000 and my_car.physics.location.z > 200
    controls.use_item = Vec3(my_car.physics.location).dist(
        Vec3(packet.game_ball.physics.location)) < 200 and relative_location(
            Vec3(my_car.physics.location), Orientation(
                my_car.physics.rotation),
            Vec3(packet.game_ball.physics.location)).z < 75
    if (abs(target_speed - car_speed) > 20 and angle < 0.3 and
            distance > 600) and ((target_speed > 1410 and my_car.boost == 0)
                                 or 700 < car_speed < 800):
        agent.stack.append(wavedash(target_location))
    return controls