Exemple #1
0
    def get_shot(self, target, weight=None, cap=None):
        if self.can_shoot is None:
            shots = (find_hits(self, {"target": target},
                               cap_=6 if cap is None else cap))['target']

            if (len(self.friends) > 0
                    or len(self.foes) > 1) and self.me.boost > 24:
                shots = list(
                    itertools.chain(shots, (find_risky_hits(
                        self, {"target": target},
                        cap_=4 if cap is None or cap > 4 else cap))['target']))

            if len(shots) > 0:
                shots.sort(key=lambda shot: shot.intercept_time)

                shot = shots[0]

                return {
                    "weight":
                    get_weight(self, target) if weight is None else weight,
                    "intercept_time": shot.intercept_time,
                    "shot": shot
                }

        return None
Exemple #2
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
                }
Exemple #3
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()
Exemple #4
0
    def get_shot(self, target=None, weight=None, cap=None):
        if self.can_shoot is None:
            final = shot = aerial_shot = None

            if self.me.airborne or self.air_bud:
                if self.me.boost < 24:
                    return

                aerial_shot = find_any_aerial(
                    self, cap_=3 if cap is None or cap > 3 else cap
                ) if target is None else find_aerial(
                    self, target, cap_=4 if cap is None or cap > 4 else cap)
            elif target is not None:
                shot = find_jump_shot(self,
                                      target,
                                      cap_=6 if cap is None else cap)
                aerial_shot = find_aerial(
                    self, target, cap_=4 if cap is None or cap > 4 else
                    cap) if self.me.boost > 24 else None
            else:
                shot = find_any_jump_shot(self, cap_=6 if cap is None else cap)
                aerial_shot = find_any_aerial(
                    self, cap_=4 if cap is None or cap > 4 else
                    cap) if self.me.boost > 24 else None

            if shot is not None:
                final = aerial_shot if aerial_shot is not None and aerial_shot.intercept_time <= shot.intercept_time else shot
            elif aerial_shot is not None:
                final = aerial_shot

            if final is None:
                return

            return {
                "weight":
                get_weight(self, target) if weight is None else weight,
                "intercept_time": final.intercept_time,
                "shot": final
            }

        return
Exemple #5
0
    def playstyle_attack(self):
        if self.is_clear() and self.me.airborne:
            self.recover_from_air()
        else:
            if not self.me.airborne:
                if not self.shooting and (self.is_clear()
                                          or self.stack[0].__class__.__name__
                                          == "atba" or self.shot_weight == -1):
                    if self.me.boost == 0:
                        self.clear()
                        self.backcheck(simple=True)
                    else:
                        for o_shot in self.offensive_shots:
                            self.line(*o_shot,
                                      self.renderer.team_color(alt_color=True))

                        if self.predictions['goal'] or (
                                self.foe_goal.location.dist(
                                    self.ball.location) <= 1500 and
                            (self.predictions['closest_enemy'] > 1500
                             or self.foe_goal.location.dist(self.me.location) <
                             self.predictions['closest_enemy'] + 250)):
                            shot = self.get_shot(self.offensive_shots[0])

                            if shot is not None:
                                self.clear()
                                self.shoot_from(shot, defend=False)
                        elif self.can_shoot is None:
                            for i, o_shot in enumerate(self.offensive_shots):
                                shot = self.get_shot(o_shot)
                                if shot is not None:
                                    self.clear()
                                    self.shoot_from(shot, defend=False)

                    if self.is_clear():
                        if 275 < abs(self.ball.location.y) and abs(
                                self.ball.location.y) > 3750:
                            self.push(atba())
                        elif self.predictions['self_to_ball'] > 1000:
                            self.push(atba(exit_distance=750, exit_flip=False))
                elif self.odd_tick % 2 == 0 and self.shooting:
                    if self.predictions['goal'] or (
                            self.foe_goal.location.dist(
                                self.ball.location) <= 1500 and
                        (self.predictions['closest_enemy'] > 1400
                         or self.foe_goal.location.dist(self.me.location) <
                         self.predictions['closest_enemy'] + 250)):
                        shot = self.get_shot(self.offensive_shots[0],
                                             weight=self.max_shot_weight)

                        if shot is not None:
                            if self.max_shot_weight is self.shot_weight:
                                if shot['intercept_time'] < self.shot_time - 0.05:
                                    self.clear()
                                    self.shoot_from(shot)
                            elif shot['intercept_time'] <= min(
                                    self.shot_time +
                                (self.max_shot_weight - self.shot_weight / 3),
                                    5):
                                self.clear()
                                self.shoot_from(shot)
                    elif self.odd_tick == 0:
                        for i, o_shot in enumerate(self.offensive_shots):
                            shot_weight = get_weight(self, index=i)

                            if shot_weight < self.shot_weight:
                                break

                            shot = self.get_shot(o_shot, weight=shot_weight)

                            if shot is not None:
                                if shot_weight is self.shot_weight:
                                    if shot['intercept_time'] < self.shot_time - 0.05:
                                        self.clear()
                                        self.shoot_from(shot)
                                elif shot['intercept_time'] <= min(
                                        self.shot_time +
                                    (shot_weight - self.shot_weight / 3), 5):
                                    self.clear()
                                    self.shoot_from(shot)

                if self.is_clear() or self.stack[0].__class__.__name__ in {
                        "goto", "goto_boost"
                } and self.odd_tick == 0:
                    if not self.smart_shot(
                            self.offensive_shots[0]) and self.is_clear():
                        if self.team == 1 and self.ball.location.y > -750:
                            self.backcheck()
                        elif self.team == 0 and self.ball.location.y < 750:
                            self.backcheck()
Exemple #6
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()
Exemple #7
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]()
        ""
Exemple #8
0
    def run(self):
        if not self.kickoff_done:
            if self.is_clear():
                if len(self.friends) > 0:
                    if almost_equals(min(self.predictions['team_to_ball']),
                                     self.predictions['self_to_ball'], 5):
                        self.offensive_kickoff()
                    elif almost_equals(max(self.predictions['team_to_ball']),
                                       self.predictions['self_to_ball'], 5):
                        self.defensive_kickoff()
                elif almost_equals(self.predictions['closest_enemy'],
                                   self.predictions['self_to_ball'], 50):
                    self.offensive_kickoff()
                else:
                    self.defensive_kickoff()
        else:
            if self.can_shoot is not None and self.time - self.can_shoot >= 3:
                self.can_shoot = None

            # :D
            if side(self.team) * self.ball.location.y >= self.panic_switch[
                    self.playstyle] or self.predictions['own_goal']:
                self.panic = True

                for shots in (self.defensive_shots, self.panic_shots):
                    for shot in shots:
                        self.line(*shot,
                                  self.renderer.team_color(alt_color=True))

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

                if self_loc.y <= ball_loc.y - 50 and not self.shooting and (
                        self.is_clear() or self.stack[0].__class__.__name__
                        == 'goto_boost') and self.backcheck(
                            clear_on_valid=True):
                    return

                # 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 +
                    50 and abs(car.location.x) < abs(ball_loc.x)
                ]
                self_to_ball = self.me.location.flat_dist(self.ball.location)
                team_to_ball.append(self_to_ball)
                team_to_ball.sort()

                if not self.shooting:
                    # What is 175?
                    # 175 is the radius of the ball rounded up (93) plus the half the length of the longest car rounded up (breakout; 66) with an extra 10% then rounded up
                    # Basicly it's the 'is an enemy dribbling the ball' detector
                    if self_loc.y > ball_loc.y and self.predictions[
                            'closest_enemy'] <= 175:
                        bgs = block_ground_shot()
                        if bgs.is_viable(self):
                            self.clear()
                            self.push(bgs)
                            return

                    if self_loc.y > ball_loc.y - 50 and (
                        (ball_loc.x > 0 and ball_loc.x < 900
                         and self_loc.x > ball_loc.x
                         and self.smart_shot(self.panic_shots[0])) or
                        (ball_loc.x < -100 and ball_loc.x > -900
                         and self_loc.x < ball_loc.x
                         and self.smart_shot(self.panic_shots[1]))):
                        return

                    if 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 < 2580):
                        if ball_loc.y < 1280:
                            for shot in self.defensive_shots:
                                if self.smart_shot(shot):
                                    return

                        if self_loc.y > ball_loc.y and team_to_ball[
                                0] is self_to_ball and self.smart_shot(
                                    weight=self.max_shot_weight - 1):
                            return

                    self.backcheck()

                elif self.shooting and self.odd_tick == 0:
                    if ball_loc.y < 1280:
                        for i, d_shot in enumerate(self.defensive_shots):
                            shot_weight = get_weight(self, index=i)

                            if shot_weight < self.shot_weight:
                                break

                            shot = self.get_shot(d_shot, weight=shot_weight)

                            if shot is not None:
                                if shot_weight is self.shot_weight:
                                    if shot['intercept_time'] < self.shot_time - 0.05:
                                        self.shoot_from(shot,
                                                        clear_on_valid=True)
                                elif shot['intercept_time'] <= min(
                                        self.shot_time +
                                    (shot_weight - self.shot_weight / 3), 5):
                                    self.shoot_from(shot, clear_on_valid=True)
                    else:
                        shot = None
                        if self.shot_weight is self.max_shot_weight:
                            if self_loc.y > ball_loc.y - 50:
                                if ball_loc.x > 100 and ball_loc.x < 900 and self_loc.x > ball_loc.x:
                                    shot = self.get_shot(
                                        self.panic_shots[0],
                                        weight=self.max_shot_weight)
                                elif ball_loc.x < -100 and ball_loc.x > -900 and self_loc.x < ball_loc.x:
                                    shot = self.get_shot(
                                        self.panic_shots[1],
                                        weight=self.max_shot_weight)
                        elif self_loc.y > ball_loc.y and team_to_ball[
                                0] is self_to_ball:
                            shot = self.get_shot(weight=self.max_shot_weight -
                                                 1)

                        if shot is not None:
                            if self.shot_weight is shot['weight'] and shot[
                                    'intercept_time'] < self.shot_time - 0.05:
                                self.shoot_from(shot, clear_on_valid=True)
            else:
                self.panic = False
                if not self.recover_from_air():
                    self.playstyles_switch[self.playstyle]()
        ""
Exemple #9
0
    def playstyle_attack(self):
        if not self.shooting or self.shot_weight == -1:
            if self.me.boost == 0:
                self.backcheck(clear_on_valid=True)
            else:
                if self.predictions['goal'] or (
                        self.foe_goal.location.dist(self.ball.location) <= 5120
                        and (self.predictions['closest_enemy'] > 5120
                             or self.foe_goal.location.dist(self.me.location) <
                             self.predictions['closest_enemy'] + 250)
                ) or self.foe_goal.location.dist(self.ball.location) < 750:
                    self.line(*self.best_shot,
                              self.renderer.team_color(alt_color=True))
                    shot = self.get_shot(self.best_shot)

                    if shot is not None:
                        self.shoot_from(shot,
                                        defend=False,
                                        clear_on_valid=True)
                elif self.can_shoot is None:
                    for o_shot in self.offensive_shots:
                        self.line(*o_shot,
                                  self.renderer.team_color(alt_color=True))

                    for i, o_shot in enumerate(self.offensive_shots):
                        shot = self.get_shot(
                            self.best_shot) if i == 0 else None

                        if shot is None:
                            shot = self.get_shot(o_shot)

                        if shot is not None:
                            self.shoot_from(shot,
                                            defend=False,
                                            clear_on_valid=True)

            if self.is_clear():
                if abs(self.ball.location.y
                       ) > 2560 or self.predictions['self_to_ball'] > 1000:
                    self.push(short_shot(self.foe_goal.location))
                else:
                    self.backcheck()
        elif self.odd_tick % 2 == 0 and self.shooting:
            if self.predictions['goal'] or (
                    self.foe_goal.location.dist(self.ball.location) <= 1500 and
                (self.predictions['closest_enemy'] > 1400
                 or self.foe_goal.location.dist(self.me.location) <
                 self.predictions['closest_enemy'] + 250)):
                if self.odd_tick % 2 == 0:
                    self.line(*self.best_shot,
                              self.renderer.team_color(alt_color=True))
                    shot = self.get_shot(self.best_shot)

                    if shot is not None:
                        if self.max_shot_weight is self.shot_weight:
                            if shot['intercept_time'] < self.shot_time - 0.05:
                                self.shoot_from(shot, clear_on_valid=True)
                        elif shot['intercept_time'] <= min(
                                self.shot_time +
                            (self.max_shot_weight - self.shot_weight / 3), 5):
                            self.shoot_from(shot, clear_on_valid=True)
            elif self.odd_tick == 0:
                for o_shot in self.offensive_shots:
                    self.line(*o_shot,
                              self.renderer.team_color(alt_color=True))

                for i, o_shot in enumerate(self.offensive_shots):
                    shot = None
                    if i == 0:
                        shot_weight = self.max_shot_weight + 1
                        shot = self.get_shot(self.best_shot)

                    if shot is None:
                        shot_weight = get_weight(self, index=i)

                        if shot_weight < self.shot_weight:
                            break

                        shot = self.get_shot(o_shot, weight=shot_weight)

                    if shot is not None:
                        if shot_weight is self.shot_weight:
                            if shot['intercept_time'] < self.shot_time - 0.05:
                                self.shoot_from(shot, clear_on_valid=True)
                        elif shot['intercept_time'] <= min(
                                self.shot_time +
                            (shot_weight - self.shot_weight / 3), 5):
                            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]) and self.is_clear(
                    ) and not self.me.airborne:
                if self.team == 1 and self.ball.location.y > self.me.location.y + 250:
                    self.backcheck()
                elif self.team == 0 and self.ball.location.y < self.ball.location.y - 250:
                    self.backcheck()