11import math
2+ from typing import List
23
34from rlbot .agents .base_agent import BaseAgent , SimpleControllerState
45from rlbot .utils .structures .game_data_struct import GameTickPacket
@@ -25,6 +26,13 @@ def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
2526
2627 self .spike_watcher .read_packet (packet )
2728
29+ ball_prediction = self .get_ball_prediction_struct ()
30+ predicted_goal = find_future_goal (ball_prediction )
31+ goal_text = "No Goal Threats"
32+
33+ if predicted_goal :
34+ goal_text = f"Goal in { '%.4s' % str (predicted_goal [1 ]- packet .game_info .seconds_elapsed )} s"
35+
2836 ball_location = Vec3 (packet .game_ball .physics .location )
2937 my_car = packet .game_cars [self .index ]
3038 car_location = Vec3 (my_car .physics .location )
@@ -62,6 +70,8 @@ def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
6270 self .controller_state .throttle = 1.0
6371 self .controller_state .steer = - 1 if steer_correction_radians > 0 else 1.0
6472
73+ draw_debug (self .renderer , [goal_text ])
74+
6575 return self .controller_state
6676
6777
@@ -82,3 +92,22 @@ def find_correction(current: Vec3, ideal: Vec3) -> float:
8292 diff -= 2 * math .pi
8393
8494 return diff
95+
96+
97+ def draw_debug (renderer , text_lines : List [str ]):
98+ renderer .begin_rendering ()
99+ y = 200
100+ for line in text_lines :
101+ renderer .draw_string_2d (50 , y , 1 , 1 , line , renderer .yellow ())
102+ y += 20
103+ renderer .end_rendering ()
104+
105+
106+ def find_future_goal (ball_predictions ):
107+ for i in range (0 , ball_predictions .num_slices ):
108+ # field length(5120) + ball radius(93) = 5213 however that results in false positives
109+ if abs (ball_predictions .slices [i ].physics .location .y ) >= 5235 :
110+ # returns the position the ball crosses the goal as well as the time it's predicted to occur
111+ return [Vec3 (ball_predictions .slices [i ].physics .location ), ball_predictions .slices [i ].game_seconds ]
112+
113+ return None
0 commit comments