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
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 }
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()
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
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()
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()
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]() ""
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]() ""
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()