def execute(self, bot): bot.renderer.draw_string_3d(bot.info.my_car.pos, 1, 1, "Aerial", bot.renderer.red()) self.aerial = Aerial(bot.info.my_car, vec3(0, 0, 0), 0) ball = DropshotBall(bot.info.ball) for i in range(60): ball.step_ds(0.016666) self.aerial.target = ball.pos self.aerial.t_arrival = ball.t # Check if we can reach it by an aerial if self.aerial.is_viable(): # One more step ball.step_ds(0.016666) self.aerial.target = ball.pos + vec3(0, 0, 15) self.aerial.t_arrival = ball.t break if self.aerial.is_viable(): bot.plan = AerialPlan(bot.info.my_car, self.aerial.target, self.aerial.t_arrival) self.drive = Drive(bot.info.my_car, bot.info.ball.pos, 2300) self.drive.step(0.016666) bot.controls = self.drive.controls
def init_kick_off(agent): if abs(agent.info.my_car.pos[0]) < 250: pad = get_closest_small_pad(agent) target = vec3(pad.pos[0], pad.pos[1], pad.pos[2]) - sign(agent.team) * vec3(0, 500, 0) agent.drive = Drive(agent.info.my_car, target, 2400) agent.kickoffStart = "Center" elif abs(agent.info.my_car.pos[0]) < 1000: target = agent.info.ball.pos agent.drive = Drive(agent.info.my_car, target, 2400) agent.kickoffStart = "offCenter" else: if random.choice([True, False]): pad = get_closest_small_pad(agent) vec3_pad = vec3(pad.pos[0], pad.pos[1], pad.pos[2]) car_to_pad = vec3_pad - agent.info.my_car.pos target = agent.info.my_car.pos + 1 * car_to_pad agent.drive = Drive(agent.info.my_car, target, 2300) agent.kickoffStart = "Diagonal_Scrub" else: target = agent.info.ball.pos agent.drive = Drive(agent.info.my_car, target, 2400) agent.kickoffStart = "Diagonal" agent.step = "Drive" agent.drive.step(agent.FPS) agent.controls = agent.drive.controls
class Dribble: def __init__(self, bot): self.drive = Drive(None, None, 0) def utility(self, bot): ball_height_01 = (bot.info.ball.pos[2] - 100) / 500 ball_vert_vel_01 = abs(bot.info.ball.vel[2]) / 500 if self.is_near_wall(bot.info.ball.pos): ball_height_01 = -1 return max( 0, 0.65 - 0.5 * ball_height_01 - 0.2 * ball_vert_vel_01 - 0.3 * bot.analyzer.team_mate_has_ball_01) def is_near_wall(self, ball_pos): TO_WALL = 4555 - 135 TO_CORNER = 5100 # (4555 -135) / math.sin(60) ax = abs(ball_pos[0]) ay = abs(ball_pos[1]) if TO_CORNER < ax or TO_WALL < ay: return True return TO_WALL * TO_CORNER - TO_WALL * ax - 0.5 * TO_CORNER * ay < 0 def execute(self, bot): bot.renderer.draw_string_3d(bot.info.my_car.pos, 1, 1, "Dribble", bot.renderer.pink()) ball = bot.info.ball car = bot.info.my_car aim = bot.analyzer.best_target_tile.location car_to_ball = ball.pos - car.pos ctb_n = normalize(car_to_ball) dist = norm(car_to_ball) - 100 vel_delta = ball.vel - car.vel vel_d = norm(vel_delta) time = max(0, dist / (1.5 * vel_d)) if vel_d != 0 else 0 bvel = norm(ball.vel) ball_to_aim_n = normalize(aim - ball.pos) nbp = DropshotBall(ball).step_ds(time).pos target = nbp - 120 * ball_to_aim_n dist_t = norm(target - car.pos) speed = min(rlmath.lerp(1.3 * bvel, 2300, dist_t / 1000), 2300) bot.renderer.draw_line_3d(ball.pos, nbp, bot.renderer.green()) bot.renderer.draw_rect_3d(nbp, 10, 10, True, bot.renderer.green()) bot.renderer.draw_rect_3d(target, 10, 10, True, bot.renderer.pink()) self.drive.car = bot.info.my_car self.drive.target_pos = target self.drive.target_speed = speed self.drive.step(0.016666) bot.controls = self.drive.controls
class Agent(BaseAgent): def __init__(self, name, team, index): self.info = GameInfo(index, team) self.controls = SimpleControllerState() self.action = None self.counter = 0 def get_output(self, packet: GameTickPacket) -> SimpleControllerState: self.info.read_packet(packet) if self.action == None or self.action.finished or self.counter == 400: target_pos = vec3( random.uniform(-3000, 3000), random.uniform(-2000, 2000), 25 ) target_speed = random.uniform(500, 2000) self.action = Drive(self.info.my_car, target_pos, target_speed) self.counter = 0 r = 200 self.renderer.begin_rendering() purple = self.renderer.create_color(255, 230, 30, 230) self.renderer.draw_line_3d(self.action.target_pos - r * vec3(1, 0, 0), self.action.target_pos + r * vec3(1, 0, 0), purple) self.renderer.draw_line_3d(self.action.target_pos - r * vec3(0, 1, 0), self.action.target_pos + r * vec3(0, 1, 0), purple) self.renderer.draw_line_3d(self.action.target_pos - r * vec3(0, 0, 1), self.action.target_pos + r * vec3(0, 0, 1), purple) self.renderer.end_rendering() if controller.L1: self.controls = controller.get_output() else: self.counter += 1 if (self.counter % 10) == 0: print(f"current speed: {norm(self.info.my_car.vel):4.4f}, \ desired speed: {self.action.target_speed:4.4f}") self.action.step(0.01666) self.controls = self.action.controls return self.controls
def __init__(self, bot): self.is_dribbling = False self.flick_timer = 0 # Constants self.drive = Drive(None, None, 0) self.extra_utility_bias = 0.2 self.wait_before_flick = 0.18 self.flick_init_jump_duration = 0.07 self.required_distance_to_ball_for_flick = 180 self.offset_bias = 35
class QuickAerial: def __init__(self, bot): self.aerial = None self.drive = None pass def utility(self, bot): ball = bot.info.ball if ball.pos[2] < 1000: return 0 car = bot.info.my_car if car.boost < 30: return 0 car_to_ball = ball.pos - car.pos ctb_flat = vec3(car_to_ball[0], car_to_ball[1], 0) ang = angle_between(ctb_flat, car.forward()) if ang > 1: return 0 vf = norm(car.vel) if vf < 800: return 0 return 0.8 def execute(self, bot): bot.renderer.draw_string_3d(bot.info.my_car.pos, 1, 1, "Aerial", bot.renderer.red()) self.aerial = Aerial(bot.info.my_car, vec3(0, 0, 0), 0) ball = DropshotBall(bot.info.ball) for i in range(60): ball.step_ds(0.016666) self.aerial.target = ball.pos self.aerial.t_arrival = ball.t # Check if we can reach it by an aerial if self.aerial.is_viable(): # One more step ball.step_ds(0.016666) self.aerial.target = ball.pos + vec3(0, 0, 15) self.aerial.t_arrival = ball.t break if self.aerial.is_viable(): bot.plan = AerialPlan(bot.info.my_car, self.aerial.target, self.aerial.t_arrival) self.drive = Drive(bot.info.my_car, bot.info.ball.pos, 2300) self.drive.step(0.016666) bot.controls = self.drive.controls
def get_output(self, info: GameInfo) -> SimpleControllerState: car = info.my_car boost_pad = closest_available_boost(car.pos, info.boost_pads) if boost_pad is None: # All boost pads are inactive. return self.controls self.action = Drive(car, boost_pad.pos, 2310) self.action.step(0.01666) self.controls = self.action.controls return self.controls
class DefensiveWait: def __init__(self, bot): self.drive = Drive(None, None, 0) pass def utility(self, bot): # The more the ball is on the enemy side in 3 seconds the more likely it is to DefWait ball_3_sec_pos = DropshotBall(bot.info.ball).step_ds(3.0).pos ball_side_01 = 1 / (1 + 2**(bot.tsgn * ball_3_sec_pos[1] / 400)) return rlmath.clamp01(0.7 * ball_side_01 - 0.55 * bot.analyzer.team_mate_is_defensive_01) def execute(self, bot): bot.renderer.draw_string_3d(bot.info.my_car.pos, 1, 1, "DefWait", bot.renderer.yellow()) ball_pos = bot.info.ball.pos target = vec3(ball_pos[0], -ball_pos[1], 0) target = rlmath.lerp(target, vec3(0, 0, 0), bot.analyzer.team_mate_is_defensive_01) for car in bot.info.teammates: to_me_n = normalize(bot.info.my_car.pos - car.pos) target += to_me_n * 400 bot.renderer.draw_line_3d(bot.info.my_car.pos, target, bot.renderer.yellow()) distance = norm(target - bot.info.my_car.pos) if distance > 2000: ctt_n = normalize(target - bot.info.my_car.pos) vtt = dot(bot.info.my_car.vel, ctt_n) / dot(ctt_n, ctt_n) if vtt > 750: bot.plan = DodgeTowardsPlan(target) speed = min(1410, distance / 3) self.drive.car = bot.info.my_car self.drive.target_pos = target self.drive.target_speed = speed self.drive.step(0.016666) bot.controls = self.drive.controls
def set_mechanics(self): if self.drive is None: self.drive = Drive(self.info.my_car, self.info.ball.pos, 1399) if self.catching is None: self.catching = Catching(self.info.my_car, self.info.ball.pos, 1399) if self.recovery is None: self.recovery = AerialTurn(self.info.my_car) if self.dodge is None: self.dodge = AirDodge(self.info.my_car, 0.25, self.info.ball.pos) if self.dribble is None: self.dribble = Dribbling(self.info.my_car, self.info.ball, self.info.their_goal)
def shooting(agent): agent.drive.step(agent.FPS) agent.controls = agent.drive.controls powerslide(agent) target = shooting_target(agent) agent.drive.target_pos = target agent.drive.target_speed = get_speed(agent, target) if should_dodge(agent): agent.step = "Dodge" agent.dodge = AirDodge(agent.info.my_car, 0.1, agent.info.ball.pos) elif not (abs(agent.info.ball.vel[2]) < 100 and sign(agent.team) * agent.info.ball.vel[1] < 0): agent.step = "Catching" agent.drive = Drive(agent.info.my_car, agent.info.ball.pos, 1399)
class CollectBoost(BaseAction): def get_output(self, info: GameInfo) -> SimpleControllerState: car = info.my_car boost_pad = closest_available_boost(car.pos, info.boost_pads) if boost_pad is None: # All boost pads are inactive. return self.controls self.action = Drive(car, boost_pad.pos, 2310) self.action.step(0.01666) self.controls = self.action.controls return self.controls def get_possible(self, info: GameInfo): return True def update_status(self, info: GameInfo): if info.my_car.boost == 100: self.finished = True
def prepare_kickoff(self, packet: GameTickPacket) -> None: bot_pos = Vector3(packet.game_cars[self.agent.index].physics.location) # Centre kickoff if abs(bot_pos.x) < 250: pad = self.get_closest_small_pad(bot_pos).location first_target: vec3 = vec3( pad.x, pad.y, pad.z) - vec3(0, 250, 0) * (1 if self.agent.team else -1) second_target: vec3 = vec3(0, 850, 0) * (1 if self.agent.team else -1) self.kickoff_steps = [ Drive(self.agent.game_info.my_car, first_target, 2400), AirDodge(self.agent.game_info.my_car, 0.075, vec3(0, 0, 0)), Drive(self.agent.game_info.my_car, second_target, 2400), AirDodge(self.agent.game_info.my_car, 0.075, vec3(0, 0, 0)) ] # Off-centre kickoff elif abs(bot_pos.x) < 1000: target: vec3 = normalize(self.agent.game_info.my_car.pos) * 500 self.kickoff_steps = [ Drive( self.agent.game_info.my_car, vec3(self.agent.game_info.my_car.pos[0], 3477 * (1 if self.agent.team else -1), 0), 2400), AirDodge(self.agent.game_info.my_car, 0.075, vec3(0, 0, 0)), Drive(self.agent.game_info.my_car, target, 2400), AirDodge(self.agent.game_info.my_car, 0.075, vec3(0, 0, 0)) ] # Diagonal kickoff else: pad = self.get_closest_small_pad(bot_pos).location car_to_pad: vec3 = vec3(pad.x, pad.y, pad.z) - self.agent.game_info.my_car.pos first_target: vec3 = self.agent.game_info.my_car.pos + 1.425 * car_to_pad second_target: vec3 = vec3(0, 150, 0) * (1 if self.agent.team else -1) third_target: vec3 = normalize( self.agent.game_info.my_car.pos) * 850 self.kickoff_steps = [ Drive(self.agent.game_info.my_car, first_target, 2300), AirDodge(self.agent.game_info.my_car, 0.035, second_target), Drive(self.agent.game_info.my_car, third_target, 2400), AirDodge(self.agent.game_info.my_car, 0.1, vec3(0, 0, 0)) ]
def __init__(self, bot): self.drive = Drive(None, None, 0)
def kick_off(agent): if agent.kickoffStart == "Diagonal_Scrub": if agent.step == "Drive": agent.drive.step(agent.FPS) agent.controls = agent.drive.controls if agent.drive.finished: agent.step = "Dodge1" # target = agent.info.ball.pos target = normalize(z0(agent.info.my_car.forward())) * 1000 agent.dodge = AirDodge(agent.info.my_car, 0.075, target) elif agent.step == "Dodge1": agent.dodge.step(agent.FPS) agent.controls = agent.dodge.controls if agent.dodge.finished: agent.step = "Steer" target = agent.info.ball.pos agent.drive = Drive(agent.info.my_car, target, 1399) elif agent.step == "Steer": agent.drive.step(agent.FPS) agent.controls = agent.drive.controls if agent.info.my_car.on_ground: agent.drive.target_speed = 2400 if distance_2d(agent.info.ball.pos, agent.info.my_car.pos) < 750: agent.step = "Dodge2" agent.dodge = AirDodge(agent.info.my_car, 0.075, agent.info.ball.pos) elif agent.step == "Dodge2": agent.dodge.step(agent.FPS) agent.controls = agent.dodge.controls if agent.dodge.finished and agent.info.my_car.on_ground: agent.step = "Catching" elif agent.kickoffStart == "Diagonal": if agent.step == "Drive": agent.drive.step(agent.FPS) agent.controls = agent.drive.controls if distance_2d(agent.info.ball.pos, agent.info.my_car.pos) < 850: agent.step = "Dodge" agent.dodge = AirDodge(agent.info.my_car, 0.075, agent.info.ball.pos) elif agent.step == "Dodge": agent.dodge.step(agent.FPS) agent.controls = agent.dodge.controls if agent.dodge.finished and agent.info.my_car.on_ground: agent.step = "Catching" elif agent.kickoffStart == "Center": if agent.step == "Drive": agent.drive.step(agent.FPS) agent.controls = agent.drive.controls if agent.drive.finished: agent.step = "Dodge1" agent.dodge = AirDodge(agent.info.my_car, 0.075, agent.info.ball.pos) elif agent.step == "Dodge1": agent.dodge.step(agent.FPS) agent.controls = agent.dodge.controls agent.controls.boost = 0 if agent.dodge.finished and agent.info.my_car.on_ground: agent.step = "Steer" target = agent.info.ball.pos + sign(agent.team) * vec3( 0, 850, 0) agent.drive = Drive(agent.info.my_car, target, 2400) elif agent.step == "Steer": agent.drive.step(agent.FPS) agent.controls = agent.drive.controls if agent.drive.finished: agent.step = "Dodge2" agent.dodge = AirDodge(agent.info.my_car, 0.075, agent.info.ball.pos) elif agent.step == "Dodge2": agent.dodge.step(agent.FPS) agent.controls = agent.dodge.controls if agent.dodge.finished and agent.info.my_car.on_ground: agent.step = "Catching" elif agent.kickoffStart == "offCenter": if agent.step == "Drive": agent.drive.step(agent.FPS) agent.controls = agent.drive.controls if agent.info.my_car.boost < 15 or agent.drive.finished: agent.step = "Dodge1" agent.dodge = AirDodge(agent.info.my_car, 0.075, agent.info.ball.pos) elif agent.step == "Dodge1": agent.dodge.step(agent.FPS) agent.controls = agent.dodge.controls agent.controls.boost = 0 if agent.dodge.finished and agent.info.my_car.on_ground: agent.step = "Steer" target = agent.info.ball.pos agent.drive = Drive(agent.info.my_car, target, 2400) elif agent.step == "Steer": agent.drive.step(agent.FPS) agent.controls = agent.drive.controls if distance_2d(agent.info.ball.pos, agent.info.my_car.pos) < 850: agent.step = "Dodge2" agent.dodge = AirDodge(agent.info.my_car, 0.075, agent.info.ball.pos) elif agent.step == "Dodge2": agent.dodge.step(agent.FPS) agent.controls = agent.dodge.controls if agent.dodge.finished and agent.info.my_car.on_ground: agent.step = "Catching"
def execute(self, bot): bot.renderer.draw_string_3d(bot.info.my_car.pos, 1, 1, "Atba", bot.renderer.white()) drive = Drive(bot.info.my_car, bot.info.ball.pos, 1500) drive.step(0.01666) bot.controls = drive.controls
def set_mechanics(self): if self.drive is None: self.drive = Drive(self.info.my_car, self.info.ball.pos, 1399) if self.dodge is None: self.dodge = AirDodge(self.info.my_car, 0.25, self.info.ball.pos)
def start_shooting(agent): agent.step = "Shooting" target = shooting_target(agent) speed = get_speed(agent, target) agent.drive = Drive(agent.info.my_car, target, speed)
def drive_controls(self, target, target_speed): self.action = self.action = Drive(self.info.my_car, target_pos = target, target_speed=target_speed) self.action.step(1/60) return self.action.controls
def get_output(self, packet): self.info.read_packet(packet) #additional processing not done by RLU self.kickoff_pause = packet.game_info.is_kickoff_pause self.round_active = packet.game_info.is_round_active self.dt = self.info.time - self.last_time self.last_time = self.info.time self.last_touch = packet.game_ball.latest_touch.player_name #trashtalk if packet.game_cars[self.index].score_info.goals == self.goals + 1: self.send_quick_chat(QuickChats.CHAT_EVERYONE, QuickChats.Reactions_Calculated) self.goals = packet.game_cars[self.index].score_info.goals #resets controls each tick self.controls = SimpleControllerState() #choose state if not self.round_active: self.state = None elif not self.state == "kickoff": if self.kickoff_pause: self.kickoff_pos = None self.action = None self.timer = 0.0 self.state = "kickoff" elif not self.info.my_car.on_ground and not isinstance(self.action, AirDodge): self.state = "recovery" self.action = self.action = AerialTurn(self.info.my_car) elif norm(self.info.my_goal.center - self.info.my_car.pos) > norm(self.info.my_goal.center - self.info.ball.pos) + self.def_extra_dist: self.action = None self.target_speed = 2300 self.state = "defence" if self.team == 0: sign = -1 else: sign = 1 #temporary 2v2 for Cow if len(self.info.teammates) > 0: if self.info.ball.pos[1] > 0: self.target = vec3(3000,sign*4000,0) else: self.target = vec3(-3000,sign*4000,0) else: self.target = vec3(0,sign*4000,0) elif self.info.my_car.pos[1] > 5120 or self.info.my_car.pos[1] < -5120: self.target = vec3(0,5000,0) if self.info.my_car.pos[1] > 5120 else vec3(0,-5000,0) self.action = self.action = Drive(self.info.my_car,self.target,1000) self.state = "goal escape" elif self.state == None: self.action = None self.target = None self.target_speed = 2300 self.state = "offence" #kickoff state if self.state == "kickoff": Kickoff.kickoff(self) #exit kickoff state if self.timer >= 2.6 or self.last_touch != '': self.state = None self.action = None #recovery state elif self.state == "recovery": self.action.step(self.dt) self.controls = self.action.controls self.controls.throttle = 1.0 #exit recovery state if self.info.my_car.on_ground == True: self.state = None self.action = None #defence state and offence state elif self.state == "defence" or self.state == "offence": #select target if self.target == None: #large boost if self.info.my_car.boost <= self.low_boost and norm(self.info.my_car.pos - self.info.ball.pos) > self.max_ball_dist: active_pads = [] for pad in self.info.boost_pads: if pad.is_active: active_pads.append(pad) if len(active_pads) != 0: closest_pad = active_pads[0] for pad in active_pads: if norm(pad.pos - self.info.ball.pos) < norm(closest_pad.pos - self.info.ball.pos): closest_pad = pad self.target = closest_pad.pos else: self.target = self.info.ball.pos #ball else: self.target = self.info.ball.pos forward_target = dot(self.target - self.info.my_car.pos, self.info.my_car.theta)[0] right_target = dot(self.target - self.info.my_car.pos, self.info.my_car.theta)[1] angle_to_target = math.atan2(right_target, forward_target) forward_goal = dot(self.info.their_goal.center - self.info.my_car.pos, self.info.my_car.theta)[0] right_goal = dot(self.info.their_goal.center - self.info.my_car.pos, self.info.my_car.theta)[1] angle_to_goal = math.atan2(right_goal, forward_goal) #select maneuver if not isinstance(self.action, AirDodge): #shooting if norm(self.info.ball.pos - self.info.my_car.pos) < self.dodge_dist and (angle_to_target - (math.pi/10.0) <= angle_to_goal <= angle_to_target + (math.pi/10.0)): self.action = AirDodge(self.info.my_car,0.2,self.info.their_goal.center) self.timer = 0.0 #dodging elif (-math.pi/24.0) <= angle_to_target <= (math.pi/24.0) and norm(self.info.my_car.vel) > 700 and norm(self.info.ball.pos - self.info.my_car.pos) > 1000 and not self.state == "defence": self.action = AirDodge(self.info.my_car,0.2,self.target) self.timer = 0.0 #Drive else: self.action = Drive(self.info.my_car,self.target,self.target_speed) #exit AirDodge else: self.timer += self.dt if self.timer >= 0.5: self.action = None #Drive if isinstance(self.action, Drive): speed = norm(self.info.my_car.vel) r = -6.901E-11 * speed**4 + 2.1815E-07 * speed**3 - 5.4437E-06 * speed**2 + 0.12496671 * speed + 157 #handbrake self.drift = False if (math.pi/2.0) <= angle_to_target or angle_to_target <= (-math.pi/2.0): self.drift = True #target speed elif (norm(self.target - (self.info.my_car.pos + dot(self.info.my_car.theta,vec3(0,r,0)))) < r or norm(self.target - (self.info.my_car.pos + dot(self.info.my_car.theta,vec3(0,-r,0)))) < r) and not self.target_speed < self.min_target_s: self.target_speed += -50 self.action = Drive(self.info.my_car,self.target,self.target_speed) elif self.target_speed < 1800: self.target_speed += 50 self.action = Drive(self.info.my_car,self.target,self.target_speed) #maneuver tick if self.action != None: self.action.step(self.dt) self.controls = self.action.controls self.controls.handbrake = self.drift #exit either state if (self.state == "defence" and norm(self.info.my_goal.center - self.info.my_car.pos) < norm(self.info.my_goal.center - self.info.ball.pos)) or (norm(self.target - self.info.my_car.pos) < self.target_range): self.state = None #goal escape state if self.state == "goal escape": self.action.step(self.dt) self.controls = self.action.controls #exit goal escape state if not (self.info.my_car.pos[1] > 5120 or self.info.my_car.pos[1] < -5120): self.state = None self.action = None if 'win32gui' in sys.modules: #finding the size of the Rocket League window def callback(hwnd, win_rect): if "Rocket League" in win32gui.GetWindowText(hwnd): rect = win32gui.GetWindowRect(hwnd) win_rect[0] = rect[0] win_rect[1] = rect[1] win_rect[2] = rect[2] - rect[0] win_rect[3] = rect[3] - rect[1] self.RLwindow = [0] * 4 win32gui.EnumWindows(callback, self.RLwindow) #Rendering Render.debug(self) Render.turn_circles(self) if not self.target == None: Render.target(self) return self.controls
class AirDrag: def __init__(self, bot): self.is_dribbling = False self.flick_timer = 0 # Constants self.drive = Drive(None, None, 0) self.extra_utility_bias = 0.2 self.wait_before_flick = 0.18 self.flick_init_jump_duration = 0.07 self.required_distance_to_ball_for_flick = 180 self.offset_bias = 35 def utility(self, bot): car_to_ball = bot.info.my_car.pos - bot.info.ball.pos bouncing_b = bot.info.ball.pos[2] > 130 or abs( bot.info.ball.vel[2]) > 300 if not bouncing_b: return 0 dist_01 = rlmath.clamp01(1 - norm(car_to_ball) / 3000) head_dir = rlmath.lerp(vec3(0, 0, 1), bot.info.my_car.forward(), 0.1) ang = angle_between(head_dir, car_to_ball) ang_01 = rlmath.clamp01(1 - ang / (math.pi / 2)) on_my_side_b = (sgn(bot.info.ball.pos[1]) == bot.tsgn) ball_landing_pos = bot.info.ball.next_landing().data tile = tiles.point_to_tile(bot.info, ball_landing_pos) protect_tile_b = (tile != None and tile.team == bot.team and (tile.state == tiles.Tile.OPEN or bot.info.ball.team != bot.team)) return rlmath.clamp01(0.3 * on_my_side_b + 0.3 * ang_01 + 0.3 * dist_01 + 0.8 * protect_tile_b - 0.3 * bot.analyzer.team_mate_has_ball_01 + self.is_dribbling * self.extra_utility_bias) def execute(self, bot): bot.renderer.draw_string_3d(bot.info.my_car.pos, 1, 1, "AirDrag", bot.renderer.purple()) self.is_dribbling = True ball_landing = bot.info.ball.next_landing() tile = tiles.point_to_tile(bot.info, ball_landing.data) # Decide on target pos and speed if tile != None and tile.team != bot.team and tile.state == tiles.Tile.OPEN: # It will hit enemy open tile - so don't save target = ball_landing.data speed = norm(target - bot.info.my_car.pos) / 2.0 else: target = ball_landing.data - self.offset_bias * bot.analyzer.best_target_dir dist = norm(target - bot.info.my_car.pos) speed = 1400 if ball_landing.time == 0 else dist / ball_landing.time # Do a flick? car_to_ball = bot.info.ball.pos - bot.info.my_car.pos dist = norm(car_to_ball) if dist <= self.required_distance_to_ball_for_flick: self.flick_timer += 0.016666 if self.flick_timer > self.wait_before_flick: bot.plan = DodgeTowardsPlan( bot.analyzer.best_target_tile.location, self.flick_init_jump_duration) else: self.flick_timer = 0 # dodge on far distances if dist > 2300 and speed > 1410: ctt_n = normalize(target - bot.info.my_car.pos) vtt = dot(bot.info.my_car.vel, ctt_n) / dot(ctt_n, ctt_n) if vtt > 750: bot.plan = DodgeTowardsPlan(target) self.drive.car = bot.info.my_car self.drive.target_pos = target self.drive.target_speed = speed self.drive.step(0.016666) bot.controls = self.drive.controls def reset(self): self.is_dribbling = False self.flick_timer = 0