Esempio n. 1
0
    def backcheck(self, simple=False):
        if self.is_clear():
            self_from_goal = self.predictions['self_from_goal']
            if self_from_goal > 500:

                if self.playstyle != self.playstyles.Defensive and not simple and (
                    (self.team == 0 and self.ball.location.y > 2048) or
                    (self.team == 1 and self.ball.location.y < -2048)):
                    bc_x = 0
                    bc_y = 0
                    ball_loc = self.ball.location.y * side(not self.team)

                    if ball_loc > 2560 * side(not self.team):
                        if self.ball.location.x > 2048:
                            bc_x = 2048
                        elif self.ball.location.x < -2048:
                            bc_x = -2048

                    if len(self.predictions['teammates_from_goal']
                           ) > 0 and max(
                               self.predictions['teammates_from_goal']
                           ) is self_from_goal:
                        bc_y = max(1024, ball_loc - 1000) * side(not self.team)

                    self.push(goto(Vector(bc_x, bc_y, 17), self.ball.location))
                else:
                    self.push(goto(self.friend_goal.location))

                return True

            return False

        return True
Esempio n. 2
0
    def defend(self):
        if not self.me.airborne:
            if self.shooting and not self.predictions[
                    'own_goal'] and self.ball.location.y * side(
                        self.team) < self.defense_switch[self.playstyle]:
                self.clear()

            if self.is_clear():
                ball = self.ball_prediction_struct.slices[cap(
                    round(self.predictions['enemy_time_to_ball'] * 0.95) * 60,
                    0,
                    len(self.ball_prediction_struct.slices) -
                    1)].physics.location
                ball = Vector(ball.x, ball.y, ball.z)
                if self.predictions['self_from_goal'] > 2560:
                    self.backcheck()
                if self.me.boost < 72 and ball.y * side(self.team) < -1280:
                    self.goto_nearest_boost(
                        only_small=ball.y * side(self.team) > -2560)
                elif self.predictions['self_from_goal'] > 750:
                    self.backcheck()
                else:
                    face_target_routine = face_target(ball=True)
                    ball_f = face_target_routine.get_ball_target(self)
                    if ball_f.y * side(self.team) > -3840 and abs(
                            Vector(x=1).angle2D(self.me.local_location(ball_f))
                    ) >= 1 and self.me.velocity.magnitude() < 100:
                        self.push(face_target_routine)
                        return
Esempio n. 3
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
Esempio n. 4
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)
Esempio n. 5
0
    def handle_quick_chat(self, index, team, quick_chat):
        if self.kickoff_done and team is self.team and index is not self.index and len(
                self.friends) != 0:
            if quick_chat is QuickChats.Information_IGotIt:
                if side(
                        self.team
                ) * self.ball.location.y < 4200 and not self.predictions[
                        'own_goal'] and not self.shooting:
                    self.can_shoot = self.time
                    if side(self.team) * self.ball.location.y < 2560:
                        self.can_shoot -= 2.5
                    elif side(self.team) * self.ball.location.y < 750:
                        self.can_shoot -= 2
                    else:
                        self.can_shoot -= 1.5

                    if self.shooting and self.shot_weight == -1:
                        self.clear()
                        self.backcheck()
            elif quick_chat is QuickChats.Information_GoForIt:
                if self.playstyle is self.playstyles.Neutral:
                    self.can_shoot = None
                    if not self.shooting and self.me.boost >= 36:
                        if not self.smart_shot(
                                self.best_shot, cap=6) and not self.smart_shot(
                                    self.offensive_shots[0],
                                    cap=6) and not self.smart_shot(
                                        self.anti_shot,
                                        cap=6) and len(self.friends) > 1:
                            self.push(short_shot(self.foe_goal.location))
Esempio n. 6
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)))
Esempio n. 7
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)
Esempio n. 8
0
    def get_shot(self, target=None, weight=None, cap=None):
        if self.predictions['self_min_time_to_ball'] == 7:
            return

        if self.can_shoot is None or self.predictions['own_goal'] or (
                self.playstyle is self.playstyles.Neutral
                and target is self.best_shot):
            if weight is None:
                weight = get_weight(self, target)

            can_aerial = self.aerials
            can_double_jump = self.double_jump
            can_jump = self.jump
            can_ground = self.ground_shot

            if len(self.friends) == 0:
                can_aerial = can_aerial and (self.predictions['own_goal'] or
                                             (self.me.location.z > 300
                                              and self.me.airborne))
                self_intercept_location = self.ball_prediction_struct.slices[
                    self.min_intercept_slice].physics.location
                self_intercept_location = Vector(
                    abs(self_intercept_location.x),
                    self_intercept_location.y * side(self.team))
                can_double_jump = can_double_jump and (
                    self_intercept_location.x < 1300
                    or self_intercept_location.y > 3840)

            if not can_aerial and not can_double_jump and not can_jump and not can_ground:
                return

            if target is self.anti_shot and self.me.location.y * side(
                    self.team) > 5120:
                target = None

            shot = find_shot(self,
                             target,
                             weight=weight,
                             cap_=6 if cap is None else cap,
                             can_aerial=can_aerial,
                             can_double_jump=can_double_jump,
                             can_jump=can_jump,
                             can_ground=can_ground
                             ) if target is not None else find_any_shot(
                                 self,
                                 cap_=3 if cap is None else cap,
                                 can_aerial=can_aerial,
                                 can_double_jump=can_double_jump,
                                 can_jump=can_jump,
                                 can_ground=can_ground)

            if shot is not None:
                return {
                    "weight": weight,
                    "intercept_time": shot.intercept_time,
                    "is_best_shot": target is self.best_shot,
                    "shot": shot
                }
Esempio n. 9
0
    def playstyle_defend(self):
        if self.shooting and not self.predictions[
                'own_goal'] and self.ball.location.z * side(self.team) < 750:
            self.clear()

        if self.is_clear():
            if self.predictions['self_from_goal'] > 2560:
                self.backcheck(simple=True)
            if self.me.boost < 72:
                self.goto_nearest_boost(
                    only_small=self.ball.location.y * side(self.team) > -2560)
            elif self.predictions['self_from_goal'] > 750:
                self.backcheck(simple=True)
Esempio n. 10
0
def get_slices(agent, cap_, weight=None, start_slice=12):
    # Get the struct
    struct = agent.ball_prediction_struct
    min_time_to_ball = agent.predictions['self_min_time_to_ball'] - (1 / 15)

    # Make sure it isn't empty
    if struct is None or min_time_to_ball > cap_:
        return

    if start_slice / 60 < min_time_to_ball:
        start_slice = round(min_time_to_ball * 60) - 1

    ball_y = agent.ball.location.y * side(agent.team)
    foes = len(
        tuple(foe for foe in agent.foes
              if not foe.demolished and foe.location.y *
              side(agent.team) < ball_y + 75))
    if not agent.predictions[
            'goal'] and agent.ball_to_goal > 2560 and agent.ball.location.dist(
                agent.foe_goal.location) > 900 and foes > 0:
        factor = 1.2 - 0.04 * foes
        cap_ = min(agent.predictions['enemy_time_to_ball'] * factor, cap_)

    end_slices = None

    # If we're shooting, crop the struct
    if agent.shooting and agent.shot_weight != -1:
        # Get the time remaining
        time_remaining = agent.stack[0].intercept_time - agent.time
        if time_remaining < 0.5 and time_remaining >= 0:
            return

        # if the shot is done but it's working on it's 'follow through', then ignore this stuff
        if time_remaining > 0:
            # Convert the time remaining into number of slices, and take off the minimum gain accepted from the time
            min_gain = 0.05 if weight is None or weight is agent.shot_weight else -(
                agent.max_shot_weight - agent.shot_weight + 1)
            end_slice = round(min(time_remaining - min_gain, cap_) * 60)

    if end_slices is None:
        # Cap the slices
        end_slice = round(cap_ * 60)

    # We can't end a slice index that's lower than the start index
    if end_slice <= start_slice:
        return

    # for every second worth of slices that we have to search, skip 1 more slice (for performance reasons) - min 1 and max 3
    skip = cap(end_slice - start_slice / 60, 1, 3)
    return struct.slices[start_slice:end_slice:skip]
Esempio n. 11
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)))
Esempio n. 12
0
    def playstyle_neutral(self):
        if self.is_clear():
            if self.predictions['self_to_ball'] > 3840:
                self.backcheck()
            elif self.me.boost < 60 and self.ball.location.y * side(
                    self.team) < -1280 and not self.predictions[
                        'goal'] and self.ball.location.flat_dist(
                            self.foe_goal.location) > 1280:
                self.goto_nearest_boost()

            if self.is_clear():
                self.backcheck()
        elif self.odd_tick % 2 == 0 and self.shooting and not self.me.airborne and self.can_shoot is None:
            shot = self.get_shot(self.best_shot)
            if shot is None:
                shot = self.get_shot(self.offensive_shots[0], cap=2.5)

            if shot is not None:
                if shot['intercept_time'] < self.shot_time - 0.05:
                    self.shoot_from(shot, clear_on_valid=True)

        if self.is_clear() or self.stack[-1].__class__.__name__ in {
                "goto", "goto_boost", "brake", "dynamic_backcheck", "retreat"
        } and self.odd_tick == 0:
            if not self.smart_shot(self.best_shot) and not self.smart_shot(
                    self.offensive_shots[0], cap=2.5) and self.is_clear():
                self.backcheck()
Esempio n. 13
0
    def init(self):
        foe_team = -1 if self.team == 1 else 1
        team = -foe_team

        # note that the second value may be positive or negative
        self.kickoff_left = (-2048 * side(self.team), 2560)
        self.kickoff_right = (2048 * side(self.team), 2560)
        self.kickoff_back = (0, 4608)
        self.kickoff_back_left = (-256 * side(self.team), 3840)
        self.kickoff_back_right = (256 * side(self.team), 3840)

        self.offensive_shots = ((Vector(foe_team * 893, foe_team * 5120,
                                        321.3875),
                                 Vector(foe_team * -893, foe_team * 5120,
                                        321.3875)),
                                (Vector(foe_team * 893, foe_team * 5120,
                                        321.3875),
                                 Vector(foe_team * 893, foe_team * 6000,
                                        321.3875)),
                                (Vector(foe_team * -893, foe_team * 5120,
                                        321.3875),
                                 Vector(foe_team * -893, foe_team * 6000,
                                        321.3875)))

        self.defensive_shots = (self.offensive_shots[0], (Vector(
            4096, foe_team * 3968,
            1900), Vector(2944, foe_team * 5120,
                          1900)), (Vector(-4096, foe_team * 3968, 1900),
                                   Vector(-2944, foe_team * 5120, 1900)))

        self.best_shot = (Vector(foe_team * 793, foe_team * 5213, 321.3875),
                          Vector(-foe_team * 793, foe_team * 5213, 321.3875))
        self.anti_shot = (Vector(-team * 2048, team * 5120,
                                 2000), Vector(team * 2048, team * 5120, 2000))

        self.max_shot_weight = 4
        self.playstyles_switch = {
            self.playstyles.Defensive: self.defend,
            self.playstyles.Neutral: self.neutral,
            self.playstyles.Offensive: self.attack
        }

        self.defense_switch = {
            self.playstyles.Defensive: 1920,
            self.playstyles.Neutral: 1280,
            self.playstyles.Offensive: 640
        }
Esempio n. 14
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)
Esempio n. 15
0
 def handle_quick_chat(self, index, team, quick_chat):
     try:
         if team is self.team and index is not self.index:
             if quick_chat is QuickChats.Information_IGotIt:
                 if side(
                         self.team
                 ) * self.ball.location.y < 4200 and not self.predictions[
                         'own_goal'] and not self.shooting:
                     self.can_shoot = self.time
                     if side(self.team) * self.ball.location.y > 2560:
                         self.can_shoot += 2.5
                     elif side(self.team) * self.ball.location.y > 750:
                         self.can_shoot += 2
                     else:
                         self.can_shoot += 1
     except Exception:
         print_exc()
Esempio n. 16
0
    def offensive_kickoff(self):
        # note that the second value may be positive or negative
        left = (-2048 * side(self.team), 2560)
        right = (2048 * side(self.team), 2560)
        back = (0, 4608)

        # back_left = (-256 * side(self.team), 3840)
        # back_right = (256 * side(self.team), 3840)

        def kickoff_check(pair):
            return almost_equals(pair[0],
                                 self.me.location.x, 50) and almost_equals(
                                     pair[1], abs(self.me.location.y), 50)

        if kickoff_check(back):
            self.push(back_kickoff())
        elif kickoff_check(left) or kickoff_check(right):
            self.push(corner_kickoff())
        else:
            self.push(generic_kickoff())

        # if kickoff_check(right):
        #     self.push(right_kickoff())
        # elif kickoff_check(left):
        #     self.push(left_kickoff())
        # elif kickoff_check(back):
        #     self.push(back_kickoff())
        # elif kickoff_check(back_left):
        #     self.push(back_left_kickoff())
        # elif kickoff_check(back_right):
        #     self.push(back_right_kickoff())

        self.send_quick_chat(QuickChats.CHAT_TEAM_ONLY,
                             QuickChats.Information_IGotIt)

        self.print("I got it!")

        send_comm(self, {"attacking": True})

        self.playstyle = self.playstyles.Offensive
Esempio n. 17
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()
Esempio n. 18
0
    def neutral(self):
        if self.can_shoot is None and (self.is_clear() or self.odd_tick
                                       == 0) and self.smart_shot(
                                           self.best_shot, cap=5):
            return

        if not self.me.airborne and not self.shooting and self.me.boost < 12:
            if self.is_clear():
                self.goto_nearest_boost()

            if not self.is_clear():
                return

        if self.can_shoot is None and (self.is_clear() or self.odd_tick == 0):
            for i, shot in enumerate(
                    self.defensive_shots if self.ball.location.y *
                    side(self.team) > -2560 and len(self.friends) != 0 else
                    self.offensive_shots):
                shot_weight = get_weight(self, index=i)

                if self.shooting and shot_weight < self.shot_weight:
                    break

                shot = self.get_shot(shot, weight=shot_weight, cap=4)

                if shot is not None:
                    if self.shooting:
                        self.upgrade_shot(shot)
                    else:
                        self.shoot_from(shot, clear_on_valid=True)
                    return

        if (
                self.is_clear() or self.get_stack_name() == "ball_recovery"
        ) and self.boost_amount == 'unlimited' and self.gravity.z > -700 and self.me.location.z > 750 and self.predictions[
                'self_to_ball'] > 2560:
            if not self.is_clear():
                self.clear()

            self.push(boost_down())
            return

        if self.is_clear() and not self.me.airborne:
            if self.can_shoot is not None and self.me.boost < 50:
                self.goto_nearest_boost()

                if not self.is_clear():
                    return

            self.backcheck()
Esempio n. 19
0
def get_slices(agent, cap_, weight=None, start_slice=12):
    # Get the struct
    struct = agent.ball_prediction_struct

    # Make sure it isn't empty
    if struct is None:
        return

    ball_y = agent.ball.location.y * side(agent.team)
    foes = tuple(
        foe for foe in agent.foes
        if not foe.demolished and foe.location.y * side(agent.team) < ball_y)

    # If we're shooting, crop the struct
    if agent.shooting:
        # Get the time remaining
        time_remaining = agent.stack[0].intercept_time - agent.time

        # Convert the time remaining into number of slices, and take off the minimum gain accepted from the time
        min_gain = 0.05
        end_slice = math.ceil(min(time_remaining - min_gain, cap_) * 60)

        # We can't end a slice index that's lower than the start index
        if end_slice <= 12:
            return

        # Half the time, double the slices
        if time_remaining <= 3:
            return struct.slices[start_slice:end_slice]

        return struct.slices[start_slice:end_slice:2]

    # If we're not shooting, then cap the slices at the cap
    end_slice = math.ceil(cap_ * 60)

    # Start 0.2 seconds in, and skip every other data point
    return struct.slices[start_slice:end_slice:2]
Esempio n. 20
0
    def backcheck(self, simple=False, clear_on_valid=False):
        if self.is_clear() or clear_on_valid:
            if self.playstyle is not self.playstyles.Defensive and not simple and self.ball.location.y * side(
                    self.team) < 2560:
                if clear_on_valid:
                    self.clear()

                self.push(dynamic_backcheck())
            elif self.me.location.dist(self.friend_goal.location +
                                       Vector(y=-250 * side(self.team))) > 500:
                if clear_on_valid:
                    self.clear()

                self.push(retreat())
            else:
                return False

        return True
Esempio n. 21
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)))
Esempio n. 22
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)))
Esempio n. 23
0
    def run(self):
        # NOTE This method is ran every tick

        # If the kickoff isn't done
        if not self.kickoff_done:
            # If the stack is clear
            if self.is_clear():
                # Push a generic kickoff to the stack
                # TODO make kickoff routines for each of the 5 kickoffs positions
                self.push(routines.generic_kickoff())

            # we don't want to do anything else during our kickoff
            return

        # If the stack if clear and we're in the air
        if self.is_clear() and self.me.airborne:
            # Recover - This routine supports floor, wall, and ceiling recoveries, as well as recovering towards a target
            self.push(routines.recovery())

            # we've made our decision and we don't want to run anything else
            return

        # If we have less than 36 boost
        # TODO this bot will go for boost no matter what - this is AWFUL, especially in a 1v1!
        if self.me.boost < 36:
            # If the stack is clear
            if self.is_clear():
                # Get a list of all of the large, active boosts
                boosts = tuple(boost for boost in self.boosts
                               if boost.active and boost.large)

                # if there's at least one large and active boost
                if len(boosts) > 0:
                    # Get the closest boost
                    closest_boost = min(boosts,
                                        key=lambda boost: boost.location.dist(
                                            self.me.location))
                    # Goto the nearest boost
                    self.push(routines.goto_boost(closest_boost))

            # we've made our decision and we don't want to run anything else
            if not self.is_clear():
                return

        # if the stack is clear, then run the following - otherwise, if the stack isn't empty, then look for a shot every 4th tick while the other routine is running
        if self.is_clear() or self.odd_tick == 0:
            shot = None

            # TODO we might miss the net, even when using a target - make a pair of targets that are small than the goal so we have a better chance of scoring!
            # If the ball is on the enemy's side of the field, or slightly on our side
            if self.ball.location.y * utils.side(self.team) < 640:
                # Find a shot, on target - double_jump, jump_shot, and ground_shot  are automatically disabled if we're airborne
                shot = tools.find_shot(self, self.foe_goal_shot)

            # TODO Using an anti-target here could be cool - do to this, pass in a target tuple that's (right_target, left_target) (instead of (left, right)) into tools.find_shot (NOT tools.find_any_shot)
            # TODO When possible, we might want to take a little bit more time to shot the ball anywhere in the opponent's end - this target should probably be REALLY LONG AND HIGH!
            # If we're behind the ball and we couldn't find a shot on target
            if shot is None and self.ball.location.y * utils.side(
                    self.team) < self.me.location.y * utils.side(self.team):
                # Find a shot, but without a target - double_jump, jump_shot, and ground_shot are automatically disabled if we're airborne
                shot = tools.find_any_shot(self)

            # If we found a shot
            if shot is not None:
                # If the stack is clear
                if self.is_clear():
                    # Shoot
                    self.push(shot)
                # If the stack isn't clear
                else:
                    # Get the current shot's name (ex jump_shot, double_jump, ground_shot or Aerial) as a string
                    current_shot_name = self.stack[0].__class__.__name__
                    # Get the new shot's name as a string
                    new_shot_name = shot.__class__.__name__

                    # If the shots are the same type
                    if new_shot_name is current_shot_name:
                        # Update the existing shot with the new information
                        self.stack[0].update(shot)
                    # If the shots are of different types
                    else:
                        # Clear the stack
                        self.clear()
                        # Shoot
                        self.push(shot)

                # we've made our decision and we don't want to run anything else
                return

        # TODO this setup is far from ideal - a custom shadow/retreat routine is probably best for the bot...
        # Make sure to put custom routines in a separate file from VirxERLU routines, so you can easily update VirxERLU to newer versions.
        # If the stack is still clear
        if self.is_clear():
            # If ball is in our half
            if self.ball.location.y * utils.side(self.team) > 640:
                retreat_routine = routines.retreat()
                # Check if the retreat routine is viable
                if retreat_routine.is_viable(self):
                    # Retreat back to the net
                    self.push(retreat_routine)
            # If the ball isn't in our half
            else:
                shadow_routine = routines.shadow()
                # Check if the shadow routine is viable
                if shadow_routine.is_viable(self):
                    # Shadow
                    self.push(shadow_routine)
Esempio n. 24
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
Esempio n. 25
0
    def run(self):
        # predictions
        self.update_predictions()

        # act on the predictions
        if not self.kickoff_done:
            if self.is_clear():
                if len(self.friends) > 0:
                    if almost_equals(self.predictions['team_to_ball'][0],
                                     self.predictions['self_to_ball'], 5):
                        self.offensive_kickoff()
                    elif almost_equals(self.predictions['team_to_ball'][-1],
                                       self.predictions['self_to_ball'], 5):
                        self.defensive_kickoff()
                elif len(self.foes) == 0 or almost_equals(
                        self.predictions['closest_enemy'],
                        self.predictions['self_to_ball'], 10):
                    self.offensive_kickoff()
                else:
                    self.defensive_kickoff()
            return

        if self.can_shoot is None:
            self.dbg_3d("Can shoot: 0")
        else:
            self.dbg_3d(
                f"Can shoot: {round(3 - (self.time - self.can_shoot), 2)}")

        enemy_intercept_location = self.ball_prediction_struct.slices[
            self.future_ball_location_slice].physics.location
        enemy_intercept_location = Vector(enemy_intercept_location.x,
                                          enemy_intercept_location.y,
                                          enemy_intercept_location.z)
        if self.predictions['enemy_time_to_ball'] != 7:
            self.sphere(enemy_intercept_location, 92.75, self.renderer.red())

        self_intercept_location = self.ball_prediction_struct.slices[
            self.min_intercept_slice].physics.location
        self_intercept_location = Vector(self_intercept_location.x,
                                         self_intercept_location.y,
                                         self_intercept_location.z)
        if self.predictions['self_min_time_to_ball'] != 7:
            self.sphere(self_intercept_location, 92.75, self.renderer.green())

        if side(self.team) * enemy_intercept_location.y >= self.defense_switch[
                self.playstyle] or self.predictions['own_goal']:
            for shot in self.defensive_shots:
                self.line(*shot, self.renderer.team_color(alt_color=True))

            self.dbg_3d("(Defending)")

            if self.predictions['enemy_time_to_ball'] > self.predictions[
                    'self_min_time_to_ball'] + (
                        3 if self.shooting else
                        1) and self.me.boost < 36 and not self.is_clear(
                        ) and self.get_stack_name() == 'goto_boost':
                return

            ball_loc = self_intercept_location * side(self.team)
            self_loc = self.me.location * side(self.team)

            # This is a list of all tm8s that are onside
            team_to_ball = [
                car.location.flat_dist(self.ball.location)
                for car in self.friends
                if car.location.y * side(self.team) >= ball_loc.y +
                95 and abs(car.location.x) < abs(self.ball.location.x) - 320
            ]
            self_to_ball = self.me.location.flat_dist(self.ball.location)
            team_to_ball.append(self_to_ball)
            team_to_ball.sort()

            if len(team_to_ball) == 1 or team_to_ball[math.ceil(
                    len(team_to_ball) / 2)] + 10 > self_to_ball:
                self.can_shoot = None

            if self.can_shoot is None and (self.is_clear()
                                           or self.odd_tick == 0):
                if self_loc.y > ball_loc.y + 95 and self.smart_shot(
                        self.best_shot, cap=4):
                    return

                if ball_loc.y - self_loc.y > (
                        ball_loc.x - self_loc.x
                ) * 1.5 and (
                        self.predictions['own_goal'] or
                    (len(team_to_ball) > 1 and team_to_ball[math.ceil(
                        len(team_to_ball) / 2)] + 10 > self_to_ball) or
                    (len(team_to_ball) == 1 and self_to_ball < 2560) or
                    (abs(ball_loc.x) < 900 and ball_loc.y > 1280)
                ) and team_to_ball[0] is self_to_ball and self.smart_shot(
                        self.anti_shot, weight=self.max_shot_weight - 3,
                        cap=4):
                    return

                if self_loc.y > ball_loc.y + 95:
                    for i, shot in enumerate(
                            self.defensive_shots
                            if self.predictions['self_min_time_to_ball'] *
                            2 < self.predictions['enemy_time_to_ball'] else
                            self.defensive_shots[1:]):
                        shot_weight = get_weight(self, index=i)

                        if self.shooting and shot_weight < self.shot_weight:
                            break

                        shot = self.get_shot(shot, weight=shot_weight, cap=4)

                        if shot is not None:
                            if self.shooting:
                                self.upgrade_shot(shot)
                            else:
                                self.shoot_from(shot, clear_on_valid=True)
                            return

                    if self.smart_shot(self.anti_shot,
                                       weight=self.max_shot_weight - 3,
                                       cap=3):
                        return

            if not self.me.airborne and (not self.shooting
                                         or self.shot_weight == -1):
                if self.predictions['enemy_time_to_ball'] > self.predictions[
                        'self_min_time_to_ball'] + (
                            3 if self.shooting else
                            1) and self.me.boost < 36 and (
                                self.is_clear()
                                or self.get_stack_name() != 'goto_boost'
                            ) and self.goto_nearest_boost(clear_on_valid=True):
                    return

                if not self.predictions[
                        'own_goal'] and self_loc.y <= ball_loc.y - 50 and not self.is_clear(
                        ) and self.get_stack_name() == 'goto_boost' and abs(
                            ball_loc.x) > 1024 and self.backcheck(
                                clear_on_valid=True):
                    return

                if self.is_clear() and not self.backcheck():
                    face_target_routine = face_target(ball=True)
                    ball_f = face_target_routine.get_ball_target(self)
                    if ball_f.y * side(self.team) > -3840 and abs(
                            Vector(x=1).angle2D(self.me.local_location(ball_f))
                    ) >= 1 and self.me.velocity.magnitude() < 100:
                        self.push(face_target_routine)
                        return

            return

        if self.me.airborne and self.is_clear():
            self.push(recovery())

        if not self.is_clear() and self.get_stack_name(
        ) == "short_shot" and self.me.location.y * side(
                self.team) < self.ball.location.y * side(self.team):
            self.clear()

        self.playstyles_switch[self.playstyle]()
        ""
Esempio n. 26
0
    def run(self, agent):
        if not agent.shooting:
            agent.shooting = True

        if self.time == -1:
            self.time = agent.time

        elapsed = agent.time - self.time
        T = self.intercept_time - agent.time
        xf = agent.me.location + agent.me.velocity * T + 0.5 * agent.gravity * T * T
        vf = agent.me.velocity + agent.gravity * T

        slice_n = math.ceil(T * 60)
        agent.dbg_2d(f"Shot slice #: {slice_n}")

        if T > 0.1 or self.target is None:
            ball = agent.ball_prediction_struct.slices[
                slice_n].physics.location

            self.ball = Vector(ball.x, ball.y, ball.z)
            self.target = self.ball - (self.shot_vector *
                                       agent.best_shot_value * 0.8)

            if agent.me.location.z > 2044 - agent.me.hitbox.height * 1.1:
                self.ceiling = True
                self.target -= Vector(z=92)

        if not self.ceiling and (self.jumping or not agent.me.airborne):
            agent.dbg_2d("Jumping")

            if not self.jumping or not agent.me.airborne:
                self.jumping = True
                self.jump_time = agent.time
                self.counter = 0

            jump_elapsed = agent.time - self.jump_time

            tau = jump_max_duration - jump_elapsed

            if jump_elapsed == 0:
                vf += agent.me.up * jump_speed
                xf += agent.me.up * jump_speed * T

            vf += agent.me.up * jump_acc * tau
            xf += agent.me.up * jump_acc * tau * (T - 0.5 * tau)

            if self.fast_aerial:
                vf += agent.me.up * jump_speed
                xf += agent.me.up * jump_speed * (T - tau)

                if jump_elapsed < jump_max_duration:
                    agent.controller.jump = True
                elif self.counter < 6:
                    self.counter += 1

                if self.counter == 3:
                    agent.controller.jump = True
                    self.dodging = True
                elif self.counter == 6:
                    self.dodging = self.jumping = False
            elif jump_elapsed < jump_max_duration:
                agent.controller.jump = True
            else:
                self.jumping = False

        if self.ceiling:
            agent.dbg_2d(f"Ceiling shot")

        delta_x = self.target - xf
        direction = delta_x.normalize()

        agent.line(agent.me.location, self.target, agent.renderer.white())
        c_vf = vf + agent.me.location
        agent.line(c_vf - Vector(z=100), c_vf + Vector(z=100),
                   agent.renderer.blue())
        agent.line(xf - Vector(z=100), xf + Vector(z=100),
                   agent.renderer.red())
        agent.line(self.target - Vector(z=100), self.target + Vector(z=100),
                   agent.renderer.green())

        if not self.dodging:
            target = delta_x if delta_x.magnitude() > 50 else (
                self.target - agent.me.location)

            if self.jumping:
                target = target.flatten()

            target = agent.me.local(target)
            if abs(Vector(x=1).angle(target)) > 0.005:
                defaultPD(agent,
                          target,
                          upside_down=self.shot_vector.z < 0
                          and not self.jumping)

        if abs(agent.me.forward.dot(direction)) > 0.5:
            delta_v = delta_x.dot(agent.me.forward) / T
            if agent.me.boost > 0 and delta_v >= agent.boost_accel * min_boost_time:
                agent.controller.boost = True
            else:
                agent.controller.throttle = cap(
                    delta_v / (throttle_accel * min_boost_time), -1, 1)

        if T <= 0 or (not self.jumping and not agent.me.airborne) or (
                not self.jumping and T > 2 and self.fast_aerial
                and not virxrlcu.aerial_shot_is_viable(
                    T + 0.3, 144, agent.boost_accel, agent.gravity.tuple(),
                    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,
                    self.ball.tuple())):
            agent.pop()
            agent.shooting = False
            agent.shot_weight = -1
            agent.shot_time = -1
            agent.push(ball_recovery())
        elif (self.ceiling and
              self.target.dist(agent.me.location) < 92 + agent.me.hitbox.length
              and not agent.me.doublejumped
              and agent.me.location.z < agent.ball.location.z + 92
              and self.target.y * side(agent.team) > -4240) or (
                  not self.ceiling and not self.fast_aerial
                  and self.target.dist(agent.me.location) <
                  92 + agent.me.hitbox.length and not agent.me.doublejumped):
            agent.dbg_2d("Flipping")
            agent.controller.jump = True
            local_target = agent.me.local_location(self.target)
            agent.controller.pitch = abs(
                local_target.x) * -sign(local_target.x)
            agent.controller.yaw = abs(local_target.y) * sign(local_target.y)
Esempio n. 27
0
    def attack(self):
        if self.can_shoot is None and (self.is_clear() or self.odd_tick
                                       == 0) and self.smart_shot(
                                           self.best_shot, cap=6):
            return

        if (self.is_clear() or self.get_stack_name() == "short_shot"
            ) and not self.me.airborne and self.me.boost < 12:
            self.goto_nearest_boost(clear_on_valid=True)

            if not self.is_clear() and self.get_stack_name() == "goto_boost":
                self.send_quick_chat(QuickChats.CHAT_EVERYONE,
                                     QuickChats.Information_GoForIt)
                return

        if not self.is_clear() and self.get_stack_name(
        ) == "goto_boost" and self.me.boost < 24:
            return

        if self.can_shoot is None and (self.is_clear() or self.odd_tick == 0):
            for i, shot in enumerate(
                    self.defensive_shots if self.ball.location.y *
                    side(self.team) > -2560 and len(self.friends) != 0 else
                    self.offensive_shots):
                shot_weight = get_weight(self, index=i)

                if self.shooting and shot_weight < self.shot_weight:
                    break

                shot = self.get_shot(shot, weight=shot_weight, cap=6)

                if shot is not None:
                    if self.shooting:
                        self.upgrade_shot(shot)
                    else:
                        self.shoot_from(shot, clear_on_valid=True)
                    return

            if not self.predictions['goal'] and (
                    self.is_clear()
                    or self.shot_weight == self.max_shot_weight -
                    3) and self.me.location.y * side(self.team) > (
                        self.ball.location.y * side(self.team)) + 1280:
                shot = self.get_shot(self.anti_shot,
                                     weight=self.max_shot_weight - 3,
                                     cap=6)
                if shot is not None:
                    if self.shooting:
                        self.upgrade_shot(shot)
                    else:
                        self.shoot_from(shot, clear_on_valid=True)
                    return

        if self.is_clear():
            self.send_quick_chat(QuickChats.CHAT_EVERYONE,
                                 QuickChats.Information_GoForIt)

        if (
                self.is_clear() or self.get_stack_name() == "ball_recovery"
        ) and self.boost_amount == 'unlimited' and self.gravity.z > -700 and self.me.location.z > 750 and self.predictions[
                'self_to_ball'] > 2560:
            if not self.is_clear():
                self.clear()

            self.push(boost_down())
            return

        if self.is_clear() and not self.me.airborne:
            if self.can_shoot is not None and self.me.boost < 50:
                self.goto_nearest_boost()

                if not self.is_clear():
                    return

            self.backcheck()
Esempio n. 28
0
    def run(self):
        """
        This is for state setting the ball to high up for aerial testing
        ""
        if not self.shooting and self.ball.location.z < 98:
            ball_state = BallState(Physics(location=GSVec3(0, -3000, self.ball.location.z), velocity=GSVec3(0, 0, 2000), angular_velocity=GSVec3(0, 0, 0)))
            game_state = GameState(ball=ball_state)
            self.set_game_state(game_state)

        if not self.shooting:
            self.smart_shot((self.foe_goal.left_post, self.foe_goal.right_post))

        if self.is_clear():
            self.push(goto(Vector(), self.foe_goal.location))
        """
        self.dbg_3d(self.playstyle.name)

        for _ in range(len(self.friends) + len(self.foes) + 1):
            try:
                msg = self.matchcomms.incoming_broadcast.get_nowait()
            except Empty:
                break

            if msg.get("VirxEB"
                       ) is not None and msg['VirxEB']['team'] is self.team:
                msg = msg['VirxEB']
                if self.playstyle is self.playstyles.Defensive:
                    if msg.get("match_defender") and msg['index'] < self.index:
                        self.playstyle = self.playstyles.Neutral
                        self.clear()
                        self.goto_nearest_boost()
                        self.can_shoot = self.time

                        self.print("You can defend")
                elif self.playstyle is self.playstyles.Offensive:
                    if msg.get("attacking") and msg['index'] < self.index:
                        self.playstyle = self.playstyles.Neutral
                        self.clear()
                        self.goto_nearest_boost()
                        self.kickoff_done = True
                        self.can_shoot = self.time

                        self.print("All yours!")

        if not self.kickoff_done:
            if self.is_clear():
                if len(self.friends) > 0:
                    try:
                        if almost_equals(
                                min(self.predictions['teammates_to_ball']),
                                self.predictions['self_to_ball'], 5):
                            self.offensive_kickoff()
                        elif almost_equals(
                                max(self.predictions['teammates_to_ball']),
                                self.predictions['self_to_ball'], 5):
                            self.defensive_kickoff()
                    except ValueError:
                        return
                elif almost_equals(self.predictions['closest_enemy'],
                                   self.predictions['self_to_ball'], 50):
                    self.offensive_kickoff()
                else:
                    self.can_shoot = self.time
                    self.defensive_kickoff()
        else:
            if self.can_shoot is not None and self.time - self.can_shoot >= 3:
                self.can_shoot = None

            if not self.is_clear(
            ) and self.stack[0].__class__.__name__ == "atba" and (
                    self.predictions['closest_enemy'] < 1000
                    or self.ball_to_goal > 1500):
                self.clear()
            elif self.is_clear() and self.predictions[
                    'closest_enemy'] is not None and self.predictions[
                        'closest_enemy'] > 2500 and self.ball_to_goal < 1500 and side(
                            self.team) is sign(self.me.location.y) and abs(
                                self.me.location.y) > 5400:
                self.push(atba())

            self.playstyles_switch[self.playstyle]()

            if self.debug_ball_path:
                ball_prediction = self.predictions['ball_struct']

                if ball_prediction is not None:
                    for i in range(
                            0, ball_prediction.num_slices -
                        (ball_prediction.num_slices %
                         self.debug_ball_path_precision) -
                            self.debug_ball_path_precision,
                            self.debug_ball_path_precision):
                        self.line(
                            ball_prediction.slices[i].physics.location,
                            ball_prediction.slices[
                                i + self.debug_ball_path_precision].physics.
                            location)

            if self.shooting and self.shot_weight != -1:
                self.dbg_2d(self.stack[0].intercept_time - self.time)

        ""
Esempio n. 29
0
    def goto_nearest_boost(self, only_small=False, clear_on_valid=False):
        if self.is_clear() or clear_on_valid:
            self.send_quick_chat(QuickChats.CHAT_TEAM_ONLY,
                                 QuickChats.Information_NeedBoost)

            ball_slice = self.ball_prediction_struct.slices[min(
                round(self.future_ball_location_slice * 1.1), 6)].physics
            ball = Vector(ball_slice.location.x, ball_slice.location.y,
                          ball_slice.location.z)
            ball_v = Vector(ball_slice.velocity.x, ball_slice.velocity.y,
                            ball_slice.velocity.z)
            ball_y = ball.y * side(self.team)

            if not only_small:
                if len(self.friends) > 0:
                    large_boosts = (
                        boost for boost in self.boosts
                        if boost.large and boost.active and (
                            (self.playstyle is self.playstyles.Offensive
                             and boost.location.y * side(self.team) < -3000) or
                            (self.playstyle is self.playstyles.Neutral
                             and boost.location.y * side(self.team) > -100) or
                            (self.playstyle is self.playstyles.Defensive
                             and boost.location.y * side(self.team) > 3000)))
                else:
                    if (ball_v.angle2D(self.foe_goal.location - ball) < 1
                            and ball_y > 0) or abs(
                                ball.x) < 900 or self.predictions['own_goal']:
                        large_boosts = None
                    else:
                        ball_x = sign(ball.x)
                        large_boosts = (
                            boost for boost in self.boosts
                            if boost.large and boost.active and (
                                boost.location.y * side(self.team) > ball_y -
                                50) and sign(boost.location.x) == ball_x)

                if large_boosts is not None:
                    closest = peek_generator(large_boosts)

                    if closest is not None:
                        closest_distance = closest.location.flat_dist(
                            self.me.location)

                        for item in large_boosts:
                            item_distance = item.location.flat_dist(
                                self.me.location)
                            if item_distance is closest_distance:
                                if item.location.flat_dist(
                                        self.me.location
                                ) < closest.location.flat_dist(
                                        self.me.location):
                                    closest = item
                                    closest_distance = item_distance
                            elif item_distance < closest_distance:
                                closest = item
                                closest_distance = item_distance

                        if clear_on_valid: self.clear()
                        self.push(goto_boost(closest))
                        return True

            if (ball_v.angle2D(self.foe_goal.location - ball) < 1
                    and ball_y > 0) or self.predictions['own_goal']:
                return False

            ball_x = sign(ball.x)
            small_boosts = (boost for boost in self.boosts
                            if not boost.large and boost.active
                            and boost.location.y * side(self.team) > ball_y -
                            50 and sign(boost.location.x) == ball_x)

            closest = peek_generator(small_boosts)

            if closest is not None:
                closest_distance = closest.location.flat_dist(
                    self.me.location) + (closest.location.flat_dist(
                        self.friend_goal.location) / 400)

                for item in small_boosts:
                    item_distance = item.location.flat_dist(
                        self.me.location) + (item.location.flat_dist(
                            self.friend_goal.location) / 400)

                    if item_distance < closest_distance:
                        item_loc = item.location.y * side(self.team)
                        if (self.playstyle is self.playstyles.Offensive
                                and item_loc < -2560
                            ) or (
                                self.playstyle is self.playstyles.Neutral
                                and item_loc < -100) or (
                                    self.playstyle is self.playstyles.Defensive
                                    and item_loc > 1280):
                            closest = item
                            closest_distance = item_distance

                if clear_on_valid: self.clear()
                self.push(goto_boost(closest))
                return True

        return False
Esempio n. 30
0
    def update_predictions(self):
        len_friends = len(self.friends)
        can_shoot = True

        if len(self.foes) > 0:
            foe_distances = tuple(
                self.ball.location.flat_dist(foe.location) for foe in self.foes
                if not foe.demolished)
            self_dist = self.ball.location.flat_dist(self.me.location)
            if len(foe_distances) > 0:
                if self.odd_tick == 0:
                    self.predictions['enemy_time_to_ball'] = min(
                        tuple(self.time_to_ball(foe) for foe in self.foes))

                self.predictions['closest_enemy'] = min(foe_distances)
            else:
                self.predictions['enemy_time_to_ball'] = 7
                self.predictions['closest_enemy'] = math.inf
        else:
            self.predictions['enemy_time_to_ball'] = 7
            self.predictions['closest_enemy'] = math.inf

        self.future_ball_location_slice = cap(
            round(self.predictions['enemy_time_to_ball'] * 60), 0,
            len(self.ball_prediction_struct.slices) - 1)
        self.dbg_2d(
            f"Predicted enemy time to ball: {round(self.predictions['enemy_time_to_ball'], 1)}"
        )

        self.predictions[
            'self_from_goal'] = self.friend_goal.location.flat_dist(
                self.me.location)
        self.predictions['self_to_ball'] = self.ball.location.flat_dist(
            self.me.location)

        if not self.predictions['was_down']:
            self.predictions[
                'was_down'] = self.game.friend_score - self.game.foe_score > 1

        if len_friends > 0:
            teammates = tuple(itertools.chain(self.friends, [self.me]))

            self.predictions["team_from_goal"] = sorted(
                tuple(
                    self.friend_goal.location.flat_dist(teammate.location)
                    if not teammate.demolished else math.inf
                    for teammate in teammates))
            self.predictions["team_to_ball"] = sorted(
                tuple(
                    self.ball.location.flat_dist(teammate.location)
                    if not teammate.demolished else math.inf
                    for teammate in teammates))
            if len_friends >= 2 and can_shoot:
                can_shoot = self.predictions[
                    'self_from_goal'] != self.predictions["team_from_goal"][0]

        if self.odd_tick == 0:
            self.predictions['self_min_time_to_ball'] = self.time_to_ball(
                self.me)
        self.min_intercept_slice = cap(
            round(self.predictions['self_min_time_to_ball'] * 60), 0,
            len(self.ball_prediction_struct.slices) - 1)

        if self.odd_tick % 2 == 0:
            if self.goalie:
                self.playstyle = self.playstyles.Defensive
            # elif len_friends > 0:
            #     ball_loc_y = self.ball.location.y * side(self.team)

            #     if ball_loc_y < 2560:
            #         # If we're down or up by 2 goals in 2's, then start playing more defensive
            #         self_time_to_ball = self.predictions['self_min_time_to_ball'] * 1.05
            #         team_time_to_ball = min(tuple(self.time_to_ball(teammate) for teammate in self.friends)) * 1.05
            #         if ball_loc_y < -1280 and self_time_to_ball < team_time_to_ball and self.predictions['self_from_goal'] != self.predictions["team_from_goal"][0]:
            #             self.playstyle = self.playstyles.Offensive if len_friends > 1 or (len_friends == 1 and (self.predictions['was_down'] or abs(self.game.friend_score - self.game.foe_score) <= 1)) else self.playstyles.Neutral
            #         elif self.predictions['self_from_goal'] == self.predictions["team_from_goal"][0]:
            #             self.playstyle = self.playstyles.Defensive if len_friends > 1 else self.playstyles.Neutral
            #         else:
            #             self.playstyle = self.playstyles.Neutral
            #     else:
            #         self.playstyle = self.playstyles.Defensive
            else:
                self_time_to_ball = self.predictions[
                    'self_min_time_to_ball'] * 1.05

                if self.ball.location.y * side(self.team) < 640:
                    self.playstyle = self.playstyles.Offensive if self_time_to_ball < self.predictions[
                        'enemy_time_to_ball'] else self.playstyles.Neutral
                else:
                    self.playstyle = self.playstyles.Neutral if self_time_to_ball < self.predictions[
                        'enemy_time_to_ball'] else self.playstyles.Defensive

            is_own_goal = False
            is_goal = False

            if self.ball_prediction_struct is not None:
                for ball_slice in self.ball_prediction_struct.slices[30::12]:
                    location = ball_slice.physics.location.y * side(self.team)

                    if location >= 5212.75:
                        is_own_goal = True
                        break

                    if location <= -5212.75:
                        is_goal = True
                        break

            if is_own_goal and not self.predictions['own_goal']:
                self.send_quick_chat(QuickChats.CHAT_EVERYONE,
                                     QuickChats.Compliments_NiceShot)

            if is_goal and not self.predictions['goal']:
                self.send_quick_chat(QuickChats.CHAT_EVERYONE,
                                     QuickChats.Reactions_Wow)

            self.predictions["own_goal"] = is_own_goal
            self.predictions["goal"] = is_goal

        self.dbg_2d(
            f"Minimum time to ball: {round(self.predictions['self_min_time_to_ball'], 1)}"
        )

        if not can_shoot and self.can_shoot is None:
            self.can_shoot = self.time - 2.9

        if self.can_shoot is not None and (self.time - self.can_shoot >= 3
                                           or self.predictions['own_goal']):
            self.can_shoot = None