diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ab60297 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b1435e5 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# RLBotPythonExample +Example of a python bot using the RLBot framework + +## Installation + +### Video guide + +https://www.youtube.com/watch?v=UjsQFNN0nSA + +### Plain instructions + +1. Make sure you've installed [Python 3.6 64 bit](https://www.python.org/ftp/python/3.6.5/python-3.6.5-amd64.exe). During installation: + - Select "Add Python to PATH" + - Make sure pip is included in the installation +2. Open Rocket League +3. Download or clone this repository +3. In the files from the previous step, find and double click on run-gui.bat +4. Click the 'Run' button + +## Changing the bot + +- Bot behavior is controlled by `python_example/python_example.py` +- Bot appearance is controlled by `python_example/appearance.cfg` + +See https://github.com/RLBot/RLBotPythonExample/wiki for documentation and tutorials. diff --git a/RefreshEnv.cmd b/RefreshEnv.cmd new file mode 100644 index 0000000..567fd78 --- /dev/null +++ b/RefreshEnv.cmd @@ -0,0 +1,66 @@ +@echo off +:: This file is taken from chocolatey: +:: https://github.com/chocolatey/choco/blob/master/src/chocolatey.resources/redirects/RefreshEnv.cmd +:: +:: RefreshEnv.cmd +:: +:: Batch file to read environment variables from registry and +:: set session variables to these values. +:: +:: With this batch file, there should be no need to reload command +:: environment every time you want environment changes to propagate + +::echo "RefreshEnv.cmd only works from cmd.exe, please install the Chocolatey Profile to take advantage of refreshenv from PowerShell" +echo | set /p dummy="Refreshing environment variables from registry for cmd.exe. Please wait..." + +goto main + +:: Set one environment variable from registry key +:SetFromReg + "%WinDir%\System32\Reg" QUERY "%~1" /v "%~2" > "%TEMP%\_envset.tmp" 2>NUL + for /f "usebackq skip=2 tokens=2,*" %%A IN ("%TEMP%\_envset.tmp") do ( + echo/set "%~3=%%B" + ) + goto :EOF + +:: Get a list of environment variables from registry +:GetRegEnv + "%WinDir%\System32\Reg" QUERY "%~1" > "%TEMP%\_envget.tmp" + for /f "usebackq skip=2" %%A IN ("%TEMP%\_envget.tmp") do ( + if /I not "%%~A"=="Path" ( + call :SetFromReg "%~1" "%%~A" "%%~A" + ) + ) + goto :EOF + +:main + echo/@echo off >"%TEMP%\_env.cmd" + + :: Slowly generating final file + call :GetRegEnv "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" >> "%TEMP%\_env.cmd" + call :GetRegEnv "HKCU\Environment">>"%TEMP%\_env.cmd" >> "%TEMP%\_env.cmd" + + :: Special handling for PATH - mix both User and System + call :SetFromReg "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" Path Path_HKLM >> "%TEMP%\_env.cmd" + call :SetFromReg "HKCU\Environment" Path Path_HKCU >> "%TEMP%\_env.cmd" + + :: Caution: do not insert space-chars before >> redirection sign + echo/set "Path=%%Path_HKLM%%;%%Path_HKCU%%" >> "%TEMP%\_env.cmd" + + :: Cleanup + del /f /q "%TEMP%\_envset.tmp" 2>nul + del /f /q "%TEMP%\_envget.tmp" 2>nul + + :: capture user / architecture + SET "OriginalUserName=%USERNAME%" + SET "OriginalArchitecture=%PROCESSOR_ARCHITECTURE%" + + :: Set these variables + call "%TEMP%\_env.cmd" + + :: reset user / architecture + SET "USERNAME=%OriginalUserName%" + SET "PROCESSOR_ARCHITECTURE=%OriginalArchitecture%" + + echo | set /p dummy="Finished." + echo . \ No newline at end of file diff --git a/Skybot/SkyBot.cfg b/Skybot/SkyBot.cfg new file mode 100644 index 0000000..d3a361f --- /dev/null +++ b/Skybot/SkyBot.cfg @@ -0,0 +1,10 @@ +[Locations] +# Path to loadout config from runner +looks_config = ./Skylooks.cfg +# Bot's python file. +# Only need this if RLBot controlled +python_file = SkyBot.py +# The name that will be displayed in game +name = SkyBot + +[Bot Parameters] diff --git a/Skybot/SkyBot.py b/Skybot/SkyBot.py new file mode 100644 index 0000000..7092906 --- /dev/null +++ b/Skybot/SkyBot.py @@ -0,0 +1,488 @@ +import math +import time +import numpy as np +import bot_functions + +from rlbot.agents.base_agent import BaseAgent, SimpleControllerState +from rlbot.utils.structures.game_data_struct import GameTickPacket + +# malicious code, beware :p EXTERMINATE EXTERMINATE EXTERMENATE + +class SkyBot(BaseAgent): + def initialize_agent(self): + self.controller = SimpleControllerState() + self.num_cars = 0 + # Controller inputs + self.controller.throttle = 0 + self.controller.steer = 0 + self.controller.pitch = 0 + self.controller.yaw = 0 + self.controller.roll = 0 + self.controller.boost = False + self.controller.jump = False + self.controller.handbrake = False + # Game values + self.bot_loc_x = 0 + self.bot_loc_y = 0 + self.bot_loc_z = 0 + self.bot_speed_x = 0 + self.bot_speed_y = 0 + self.bot_speed_z = 0 + self.bot_rot_yaw = 0 + self.bot_rot_roll = 0 + self.bot_rot_pitch = 0 + self.bot_jumped = False + self.bot_doublejumped = False + self.bot_ground = False + self.bot_sonic = False + self.bot_dodge = False + self.bot_boost = 0 + self.bot_max_speed=[1410,2300] #normal, boost + self.bot_boost_to_max_speed=[27,57,30] #to normal, to boost, from normal to boost + self.ball_loc_x = 0 + self.ball_loc_y = 0 + self.ball_loc_z = 0 + self.ball_speed_x = 0 + self.ball_speed_y = 0 + self.ball_speed_z = 0 + self.ball_ang_speed_x = 0 + self.ball_ang_speed_y = 0 + self.ball_ang_speed_z = 0 + self.ball_lt_x = 0 + self.ball_lt_y = 0 + self.ball_lt_z = 0 + self.ball_lt_time = 0 + self.game_time = 0 + self.game_ball_touched = False + #game values converted + self.bot_yaw = 0 + self.bot_pitch = 0 + self.bot_roll = 0 + self.angle_front_to_target = 0 + self.angle_car_ball = 0 + #custom values + self.angle_car_ball = 0 + self.distance_car_ball = 0 + self.bot_speed_linear = 0 + self.ball_initial_speed_z = 0 + self.ball_initial_pos_z=0 + self.ball_test_for_start = False + + self.ttt=0.00 + self.lt_time=0.00 + #([self.game_time],[[self.ball_loc_x],[self.ball_loc_y],[self.ball_loc_z]],[[self.ball_speed_x],[self.ball_speed_y],[self.ball_speed_z]],[[self.ball_ang_speed_x],[self.ball_ang_speed_y],[self.ball_ang_speed_z]]) + self.prediction=[[],[]] + self.printed=False + + #self.predicted_loc=[[0,0,0],[[0,0,0],[0,0,0],[0,0,0]],[0,0,0]] + self.predicted_loc=[[0,0,0],[[0,0,0],[0,0,0],[0,0,0]],[0],[[0,0,0],[0,0,0],[0,0,0]]] + self.game_time_lst=[] + self.ball_speed_x_lst=[] + self.ball_speed_y_lst=[] + self.ball_speed_z_lst=[] + self.ball_ang_speed_x_lst=[] + self.ball_ang_speed_y_lst=[] + self.ball_ang_speed_z_lst=[] + self.ball_loc_x_lst=[] + self.ball_loc_y_lst=[] + self.ball_loc_z_lst=[] + + self.bounce_n=0 + self.hit=False + self.realtime=[[],[]] + self.time_to_hit=1 + self.jump_time_end = 0 + self.flick_time = 0 + self.stop_flick = False + self.last_predict = 0 + + def get_values(self,values): + self.controller.boost = False + + + if self.jump_time_end 180: + self.angle_front_to_target -= 360 + + if self.angle_front_to_target < -10: + # If the target is more than 10 degrees right from the centre, steer left + self.controller.steer = -1 + elif self.angle_front_to_target > 10: + # If the target is more than 10 degrees left from the centre, steer right + self.controller.steer = 1 + else: + # If the target is less than 10 degrees from the centre, steer straight + self.controller.steer = self.angle_front_to_target/10 + + if -3100: + self.controller.handbrake = 1 + else: self.controller.handbrake = 0 + if (self.bot_team == 0 and self.bot_loc_y<-5000) or (self.bot_team == 1 and self.bot_loc_y>5000) : + # Blue team's goal is located at (0, -5000) + # Orange team's goal is located at (0, 5000) + self.controller.handbrake = 0 + + if speed_needed==self.bot_max_speed[1] and self.bot_boost==0 and abs(self.angle_front_to_target)<3 and self.distance_to_target>3000: + self.flick(jump_timeout=0.05,flick_timeout=0.1) + + if self.game_state=='kickoff' and self.distance_to_target<3500 and self.bot_boost == 0: + self.flick(jump_timeout=0.05,flick_timeout=0.1) + + + if speed_needed!=0: + if speed_needed>self.bot_max_speed[0]: + self.controller.throttle=1 + self.controller.boost=1 + elif self.bot_speed_linear3: + if self.game_ball_touched and self.game_time_lst[-3]==self.ball_lt_time: + self.hit=True + else: + self.hit=False + else: + self.hit=False + + def predict(self, force_refresh=False): + if self.time_to_hit<0.5: + force_refresh=True + if self.hit or force_refresh: + data_loc_speed=([self.game_time], + [[self.ball_loc_x],[self.ball_loc_y],[self.ball_loc_z]], + [[self.ball_speed_x],[self.ball_speed_y],[self.ball_speed_z]], + [[self.ball_ang_speed_x],[self.ball_ang_speed_y],[self.ball_ang_speed_z]]) + + self.predicted_loc=bot_functions.ball_path_predict(data_loc_speed) + # self.predicted_loc= + # [time_l, + # [predic_loc_x_t, predic_loc_y_t, predic_loc_z_t] + # ground_t, + # [ground_loc_x, ground_loc_y, ground_loc_z] + # goal_time, + # [loc_x, loc_y, loc_z]] + self.bounce_n=0 + points=0 + line_multiplier = 20 + self.renderer.begin_rendering('path') + while points < len(self.predicted_loc[0])-line_multiplier: + self.renderer.draw_line_3d((self.predicted_loc[1][0][points], + self.predicted_loc[1][1][points], self.predicted_loc[1][2][points]), + (self.predicted_loc[1][0][points+line_multiplier], self.predicted_loc[1][1][points+line_multiplier], + self.predicted_loc[1][2][points+line_multiplier]), self.renderer.create_color(255, 0, 0, 0)) + points = points+line_multiplier + self.renderer.end_rendering() + # redo = False + # if not (self.predicted_loc[2][0] + 2/10 > self.last_predict and self.last_predict > self.predicted_loc[2][0] - 2/10): + # redo = True + # print(redo) + # redo = True + # #print(self.last_predict) + # #print(self.predicted_loc[2][0]) + # self.last_predict = self.predicted_loc[2][0] + # if redo: + # self.renderer.begin_rendering('path') + # while self.predicted_loc[0][points] < self.predicted_loc[2][0]: + # self.renderer.draw_line_3d((self.predicted_loc[1][0][points], + # self.predicted_loc[1][1][points], self.predicted_loc[1][2][points]), + # (self.predicted_loc[1][0][points+line_multiplier], self.predicted_loc[1][1][points+line_multiplier], + # self.predicted_loc[1][2][points+line_multiplier]), self.renderer.create_color(255, 0, 0, 0)) + # points = points+line_multiplier + # self.renderer.end_rendering() + + def time_to_impact(self): + if (self.bounce_n+1)0: + if self.predicted_loc[2][self.bounce_n]0: + print('real hit') + print(self.ball_loc_x,self.ball_loc_y,self.ball_loc_z) + + def get_game_state(self): + if self.game_active and self.game_ball_touched: + self.game_state='active' + if self.game_active and not self.game_ball_touched: + self.game_state='kickoff' + if not self.game_active and self.game_ball_touched: + self.game_state='goal_replay' + if not self.game_active and not self.game_ball_touched: + self.game_state='inactive' + if self.game_ended: + self.game_state='ended' + if self.game_overtime: + self.game_state+='_overtime' + + def boost_needed(self, initial_speed, goal_speed): + p1 = 6.31e-06 + p2 = 0.010383 + p3 = 1.3183 + boost_initial = p1*initial_speed**2 + p2*initial_speed + p3 + boost_goal = p1*goal_speed**2 + p2*goal_speed + p3 + boost_needed = boost_goal - boost_initial + return boost_needed + + def what_to_do(self): # todo: add goal destinction, add decision to attack or not, add defence mechanism + self.predict(True) + speed_needed=self.bot_max_speed[1] + n_hit=-1 + ball_vector = self.goal_to_ball_vector() + distance_multiplier=35 + x=ball_vector[0]*distance_multiplier + y=ball_vector[1]*distance_multiplier*ball_vector[2] + if self.game_state=='active': + for n_hit in range(len(self.predicted_loc[2])): + distance_to_hit=self.distance(self.predicted_loc[3][0][n_hit]+x,self.predicted_loc[3][1][n_hit]+y,self.predicted_loc[3][2][n_hit],self.bot_loc_x,self.bot_loc_y,self.bot_loc_z) + self.bot_speed_linear + if (self.predicted_loc[2][n_hit]-self.game_time) == 0: + break + speed_needed=(distance_to_hit-0)/(self.predicted_loc[2][n_hit]-self.game_time)#-20 fot it to go slightly slower + if (speed_neededself.bot_max_speed[0]: + if (self.bot_boost+1)>=self.boost_needed(self.bot_speed_linear,speed_needed): + break + else: + break + if ((self.bot_team == 1 and self.bot_loc_y+500 > self.ball_loc_y) or (self.bot_team == 0 and self.bot_loc_y-500 < self.ball_loc_y)): #or self.distance_car_ball<600: + if self.predicted_loc[3][0]: + self.aim(self.predicted_loc[3][0][n_hit]+x,self.predicted_loc[3][1][n_hit]+y,speed_needed) + else: + self.aim(self.ball_loc_x+x,self.ball_loc_y+y,speed_needed) + + if self.distance_car_ball<100 and ((self.bot_team == 0 and self.distance(0,self.ball_loc_y,0,0,5000,0)<200 and self.distance(self.ball_loc_x,self.ball_loc_y,0,0,5000,0)<1000) or (self.bot_team == 1 and self.distance(0,self.ball_loc_y,0,0,-5000,0)<200) and self.distance(self.ball_loc_x,self.ball_loc_y,0,0,-5000,0)<1000): + self.flick(-x,-y,jump_timeout=0.10,flick_timeout=0.20) + else: + if self.bot_team == 0: + # Blue team's goal is located at (0, -5000) + self.aim(0, -5000,speed_needed=self.bot_max_speed[1]) + else: + # Orange team's goal is located at (0, 5000) + self.aim(0, 5000, speed_needed=self.bot_max_speed[1]) + + if abs(self.angle_front_to_target)>150 and self.distance_to_target>3000 and self.flick_time==0: + self.flick(1,0,jump_timeout=0.25,flick_timeout=0.30) + #print("I'm too lazy to search for the function to skeap empty functions because this function was acting up") + + if self.bot_state == 'dribbling' and abs(self.angle_front_to_target)<90: + self.flick(-x,-y,jump_timeout=0.25,flick_timeout=0.30) + + def get_bot_state(self): + #print(self.distance_car_ball,abs(self.ball_speed_z),self.distance(self.bot_loc_z,0,0,self.ball_loc_z,0,0)) + if 30 180: + self.angle_enemy_to_bot -= 360 + + if (self.enemy_distance*self.enemy_speed)<1 and abs(self.angle_enemy_to_bot)<50: + enemy_avoid=True + + if self.bot_state=='dribbling' and enemy_avoid: + a = self.goal_to_ball_vector() + x=a[0] + y=a[1] + self.flick(pitch=-y,roll=-x) + elif enemy_avoid: + self.controller.jump=True + #self.jump_time_end=self.game_time+0.3 + + def flick(self, pitch=-1, roll=0.05, jump_timeout=0.1, flick_timeout=0.15): + if self.flick_time == 0 and self.bot_ground: + print('###################################jump') + self.controller.jump = True + #print('jumped') + self.jump_time_end = self.game_time + jump_timeout + self.flick_time = self.game_time + flick_timeout + self.controller.pitch = pitch + self.controller.roll = roll + #print("Flicking") + #print(self.flick_time) + + def goal_to_ball_vector(self): + if self.bot_team == 0: + # Blue team's goal is located at (0, -5000) + distance_ball_to_goal = self.distance(self.ball_loc_x,self.ball_loc_y,0,0,5400,0) + x=self.distance(self.ball_loc_x,0,0,0,0,0) + y=-self.distance(0,self.ball_loc_y,0,0,5400,0) + else: #elif self.bot_team == 1: + # Orange team's goal is located at (0, 5000) + distance_ball_to_goal = self.distance(self.ball_loc_x,self.ball_loc_y,0,0,-5400,0) + x=self.distance(self.ball_loc_x,0,0,0,0,0) + y=self.distance(0,self.ball_loc_y,0,0,-5400,0) + x=x/distance_ball_to_goal + if self.ball_loc_x<0: + x=-x + y=y/distance_ball_to_goal + if abs(self.ball_loc_x)<1200 and distance_ball_to_goal<800: + m=2.5 + else:m=1 + return [x,y,m] + + def get_output(self, packet: GameTickPacket) -> SimpleControllerState: + self.get_values(packet) + self.get_bot_state() + self.get_game_state() + self.was_hit() + self.what_to_do() + self.avoid_enemy_colision(packet) + + + return self.controller diff --git a/Skybot/SkybotPreset.cfg b/Skybot/SkybotPreset.cfg new file mode 100644 index 0000000..a2b3d6b --- /dev/null +++ b/Skybot/SkybotPreset.cfg @@ -0,0 +1,11 @@ +[Locations] +# Path to loadout config from runner +looks_config = ./Skylooks.cfg +# Bot's python file. +# Only need this if RLBot controlled +python_file = C:\Users\fabio\Fabio\Programing\Skybot\Skybot\SkyBot.py +# The name that will be displayed in game +name = Skybot + +[Bot Parameters] + diff --git a/Skybot/Skylooks.cfg b/Skybot/Skylooks.cfg new file mode 100644 index 0000000..2346a36 --- /dev/null +++ b/Skybot/Skylooks.cfg @@ -0,0 +1,56 @@ +[Bot Loadout] +# Primary Color selection +team_color_id = 3 +# Secondary Color selection +custom_color_id = 75 +# Car type (Octane, Merc, etc +car_id = 2070 +# Type of decal +decal_id = 1577 +# Wheel selection +wheels_id = 731 +# Boost selection +boost_id = 405 +# Antenna Selection +antenna_id = 0 +# Hat Selection +hat_id = 2064 +# Paint Type (for first color) +paint_finish_id = 273 +# Paint Type (for secondary color) +custom_finish_id = 1681 +# Engine Audio Selection +engine_audio_id = 0 +# Car trail Selection +trails_id = 1974 +# Goal Explosion Selection +goal_explosion_id = 1904 + +[Bot Loadout Orange] +# Primary Color selection +team_color_id = 6 +# Secondary Color selection +custom_color_id = 75 +# Car type (Octane, Merc, etc +car_id = 2070 +# Type of decal +decal_id = 1577 +# Wheel selection +wheels_id = 1564 +# Boost selection +boost_id = 1093 +# Antenna Selection +antenna_id = 0 +# Hat Selection +hat_id = 2064 +# Paint Type (for first color) +paint_finish_id = 273 +# Paint Type (for secondary color) +custom_finish_id = 1681 +# Engine Audio Selection +engine_audio_id = 0 +# Car trail Selection +trails_id = 1270 +# Goal Explosion Selection +goal_explosion_id = 1908 + diff --git a/Skybot/Skylookstest.cfg b/Skybot/Skylookstest.cfg new file mode 100644 index 0000000..7df8857 --- /dev/null +++ b/Skybot/Skylookstest.cfg @@ -0,0 +1,56 @@ +[Bot Loadout] +# Primary Color selection +team_color_id = 27 +# Secondary Color selection +custom_color_id = 75 +# Car type (Octane, Merc, etc +car_id = 1845 +# Type of decal +decal_id = 307 +# Wheel selection +wheels_id = 1656 +# Boost selection +boost_id = 0 +# Antenna Selection +antenna_id = 287 +# Hat Selection +hat_id = 0 +# Paint Type (for first color) +paint_finish_id = 1978 +# Paint Type (for secondary color) +custom_finish_id = 1978 +# Engine Audio Selection +engine_audio_id = 0 +# Car trail Selection +trails_id = 0 +# Goal Explosion Selection +goal_explosion_id = 1971 + +[Bot Loadout Orange] +# Primary Color selection +team_color_id = 27 +# Secondary Color selection +custom_color_id = 75 +# Car type (Octane, Merc, etc +car_id = 23 +# Type of decal +decal_id = 307 +# Wheel selection +wheels_id = 1656 +# Boost selection +boost_id = 0 +# Antenna Selection +antenna_id = 287 +# Hat Selection +hat_id = 0 +# Paint Type (for first color) +paint_finish_id = 1978 +# Paint Type (for secondary color) +custom_finish_id = 1978 +# Engine Audio Selection +engine_audio_id = 0 +# Car trail Selection +trails_id = 0 +# Goal Explosion Selection +goal_explosion_id = 1971 + diff --git a/Skybot/bot_functions.py b/Skybot/bot_functions.py new file mode 100644 index 0000000..fc7e42e --- /dev/null +++ b/Skybot/bot_functions.py @@ -0,0 +1,231 @@ +import math + +def ball_path_predict(data_loc_speed): # [self.game_time, self.ball_lt_z, self.ball_lt_speed_z] + start_on=0 + #print(data_loc_speed) + loc_x=data_loc_speed[1][0][start_on] + loc_y=data_loc_speed[1][1][start_on] + loc_z=data_loc_speed[1][2][start_on] + speed_x=data_loc_speed[2][0][start_on] + speed_y=data_loc_speed[2][1][start_on] + speed_z=data_loc_speed[2][2][start_on] + ang_speed_x=data_loc_speed[3][0][start_on] + ang_speed_y=data_loc_speed[3][1][start_on] + ang_speed_z=data_loc_speed[3][2][start_on] + time_i=data_loc_speed[0][start_on] + timer=0 + time_l=[] + ground_t=[] + predic_loc_z_t=[] + predic_loc_x_t=[] + predic_loc_y_t=[] + ground_loc_x=[] + ground_loc_y=[] + ground_loc_z=[] + predicted_loc=[[],[[],[],[]],[],[[],[],[]],[],[[],[],[]]] + bounce_t=0 + goal=False + ground_next=False + ball_rolling=False + air_friction=0.013 + gravity=-650 + ball_radius=93 + step=1/120 + perpendicular_restitution=0.60 + #todo: change depending on entry angle + paralel_restitution=0.713 + spin_inertia=0.4 + while timer < 5: + time=timer-bounce_t + #z + loc_z_t=loc_z+((speed_z*(1-air_friction*time))*time)+(0.5*(gravity)*(time**2)) + #x + loc_x_t=loc_x+((speed_x*(1-air_friction*time))*time) + #y + loc_y_t=loc_y+((speed_y*(1-air_friction*time))*time) + + if loc_z_t 6: + ang_speed_x,ang_speed_y,ang_speed_z = 6*ang_speed_x/total_ang_speed, 6*ang_speed_y/total_ang_speed, 6*ang_speed_z/total_ang_speed + elif abs(loc_z_t)>2044-ball_radius: + loc_z=2044-ball_radius + speed_z=-(speed_z*(1-air_friction*time-step)+gravity*(time-step)) + #speed_z=speed_z*(1-air_friction*(time)) + speed_z=speed_z*perpendicular_restitution + + loc_y=loc_y+((speed_y*(1-air_friction*(time)))*(time)) + speed_y=speed_y*(1-air_friction*(time)) #*paralel_restitution + + loc_x=loc_x+((speed_x*(1-air_friction*(time)))*(time)) + speed_x=speed_x*(1-air_friction*(time)) #*paralel_restitution + + if True: + + entry_angle = abs(math.atan2(speed_z,math.sqrt(speed_x**2+speed_y**2)))/math.pi*180 + # some more magic numbers + custom_friction = (paralel_restitution-1)/(28)*entry_angle +1 + + # limiting custom_friction to range [e1, 1] + if custom_friction 6: + ang_speed_x,ang_speed_y,ang_speed_z = 6*ang_speed_x/total_ang_speed, 6*ang_speed_y/total_ang_speed, 6*ang_speed_z/total_ang_speed + + bounce_t=timer + elif abs(loc_x_t)>4096-ball_radius: + if loc_x>0: + loc_x=4096-ball_radius + else: + loc_x=-4096+ball_radius + + speed_x=speed_x*(1-air_friction*(time)) + speed_x=-speed_x*perpendicular_restitution + + loc_y=loc_y+((speed_y*(1-air_friction*(time)))*(time)) + speed_y=speed_y*(1-air_friction*(time))#*paralel_restitution + + loc_z=loc_z+((speed_z*(1-air_friction*(time)))*(time))+(0.5*(gravity)*((time)**2)) + speed_z=(speed_z*(1-air_friction*(time-step))+gravity*((time-step)))#*paralel_restitution #implement spin + + if True: + + entry_angle = abs(math.atan2(speed_z,math.sqrt(speed_x**2+speed_y**2)))/math.pi*180 + # some more magic numbers + custom_friction = (paralel_restitution-1)/(28)*entry_angle +1 + + # limiting custom_friction to range [e1, 1] + if custom_friction 6: + ang_speed_x,ang_speed_y,ang_speed_z = 6*ang_speed_x/total_ang_speed, 6*ang_speed_y/total_ang_speed, 6*ang_speed_z/total_ang_speed + + bounce_t=timer + elif abs(loc_y_t)>5120-ball_radius: + if abs(loc_x_t)<892.755-ball_radius and abs(loc_z_t)<642.775-ball_radius: + goal=True + break + if loc_y>0: + loc_y=5120-ball_radius + else: + loc_y=-5120+ball_radius + + speed_y=speed_y*(1-air_friction*time)#*paralel_restitution + speed_y=-speed_y*perpendicular_restitution + + loc_z=loc_z+((speed_z*(1-air_friction*time))*time)+(0.5*(gravity)*(time**2)) + loc_x=loc_x+((speed_x*(1-air_friction*time))*time) + + speed_x=speed_x*(1-air_friction*time)#*paralel_restitution + speed_z=(speed_z*(1-air_friction*(time-step))+gravity*((time-step)))#*paralel_restitution + + if True: + + entry_angle = abs(math.atan2(speed_z,math.sqrt(speed_x**2+speed_y**2)))/math.pi*180 + # some more magic numbers + custom_friction = (paralel_restitution-1)/(28)*entry_angle +1 + + # limiting custom_friction to range [e1, 1] + if custom_friction 6: + ang_speed_x,ang_speed_y,ang_speed_z = 6*ang_speed_x/total_ang_speed, 6*ang_speed_y/total_ang_speed, 6*ang_speed_z/total_ang_speed + + bounce_t=timer + else: + predic_loc_z_t+=[loc_z_t] + predic_loc_x_t+=[loc_x_t] + predic_loc_y_t+=[loc_y_t] + tick_time=[timer+time_i] + time_l+=tick_time + timer+=step + if ground_next: + ground_t+=tick_time + ground_loc_x+=[loc_x_t] + ground_loc_y+=[loc_y_t] + ground_loc_z+=[loc_z_t] + ground_next=False + if ball_rolling: + ground_loc_x+=[loc_x_t] + ground_loc_y+=[loc_y_t] + ground_loc_z+=[loc_z_t] + predicted_loc[0]=time_l + predicted_loc[1][0]=predic_loc_x_t + predicted_loc[1][1]=predic_loc_y_t + predicted_loc[1][2]=predic_loc_z_t + predicted_loc[2]=ground_t + predicted_loc[3][0]=ground_loc_x + predicted_loc[3][1]=ground_loc_y + predicted_loc[3][2]=ground_loc_z + if goal: + predicted_loc[4]=timer + predicted_loc[5][0]=loc_x + predicted_loc[5][1]=loc_y + predicted_loc[5][2]=loc_z + else: + predicted_loc[4]=0 + predicted_loc[5][0]=0 + predicted_loc[5][1]=0 + predicted_loc[5][2]=0 + return predicted_loc diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..eb66004 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +# Include everything the framework requires +# You will automatically get updates for all versions starting with "1.". +rlbot==1.* diff --git a/rlbot.cfg b/rlbot.cfg new file mode 100644 index 0000000..e41fd4d --- /dev/null +++ b/rlbot.cfg @@ -0,0 +1,136 @@ +[RLBot Configuration] +# A path to the extension file we want to load +extension_path = None + +[Team Configuration] +# Changes Blue team color, use 0 to use default color +Team Blue Color = 0 +# Changes the Team name to use instead of 'Blue' +Team Blue Name = Blue +# Changes Blue team color, use 0 to use default color +Team Orange Color = 0 +# Changes the Team name to use instead of 'Orange' +Team Orange Name = Orange + +[Match Configuration] +# Number of bots/players which will be spawned. We support up to max 10. +num_participants = 2 +# What game mode the game should load. +# Accepted values are "Soccer", "Hoops", "Dropshot", "Hockey", "Rumble" +game_mode = Soccer +# Which map the game should load into. Too many to list. +game_map = Mannfield +# Automatically skip replays after a goal. +skip_replays = False +# Skip the kickoff countdown +start_without_countdown = True + +[Mutator Configuration] +# Match Length +Match Length = Unlimited +# Max Score +Max Score = Unlimited +# Overtime +Overtime = Unlimited +# Series Length +Series Length = Unlimited +# Game Speed +Game Speed = Default +# Ball Max Speed +Ball Max Speed = Default +# Ball Type +Ball Type = Default +# Ball Weight +Ball Weight = Default +# Ball Size +Ball Size = Default +# Ball Bounciness +Ball Bounciness = Default +# Boost Amount +Boost Amount = Default +# Rumble +Rumble = None +# Boost Strength +Boost Strength = 1x +# Gravity +Gravity = Default +# Demolish +Demolish = Default +# Respawn Time +Respawn Time = 3 Seconds + +[Participant Configuration] +# The location of the configuration file for your agent here. +# Only total_num_participants config files will be read! +# Everything needs a config, even players and default bots. +# We still set loadouts and names from config! +participant_config_0 = C:\Users\fabio\Fabio\Programing\Skybot\Skybot\SkybotPreset.cfg +participant_config_1 = C:\Users\fabio\Fabio\Programing\Skybot\python_example\python_example.cfg +participant_config_2 = python_example/python_example.cfg +participant_config_3 = python_example/python_example.cfg +participant_config_4 = python_example/python_example.cfg +participant_config_5 = python_example/python_example.cfg +participant_config_6 = python_example/python_example.cfg +participant_config_7 = python_example/python_example.cfg +participant_config_8 = python_example/python_example.cfg +participant_config_9 = python_example/python_example.cfg + +# Which team the player should be on: +# team 0 (blue) shoots on positive goal, team 1 (orange) shoots on negative goal +participant_team_0 = 0 +participant_team_1 = 1 +participant_team_2 = 0 +participant_team_3 = 1 +participant_team_4 = 0 +participant_team_5 = 1 +participant_team_6 = 0 +participant_team_7 = 1 +participant_team_8 = 0 +participant_team_9 = 1 + +# Accepted values are "human", "rlbot", "psyonix" and "party_member_bot" +# You can have up to 4 local players and they must +# be activated in game or it will crash. +# If no player is specified you will be spawned in as spectator! +# human - not controlled by the framework +# rlbot - controlled by the framework +# psyonix - default bots (skill level can be changed with participant_bot_skill +# party_member_bot - controlled by an rlbot but the game detects it as a human +participant_type_0 = rlbot +participant_type_1 = psyonix +participant_type_2 = rlbot +participant_type_3 = rlbot +participant_type_4 = rlbot +participant_type_5 = rlbot +participant_type_6 = rlbot +participant_type_7 = rlbot +participant_type_8 = rlbot +participant_type_9 = rlbot + +# If participant is a bot and not RLBot controlled, this value will be used to set bot skill. +# 0.0 is Rookie, 0.5 is pro, 1.0 is all-star. You can set values in-between as well. +participant_bot_skill_0 = 1.0 +participant_bot_skill_1 = 1.0 +participant_bot_skill_2 = 1.0 +participant_bot_skill_3 = 1.0 +participant_bot_skill_4 = 1.0 +participant_bot_skill_5 = 1.0 +participant_bot_skill_6 = 1.0 +participant_bot_skill_7 = 1.0 +participant_bot_skill_8 = 1.0 +participant_bot_skill_9 = 1.0 + +# A path to a loadout config file which will override the path in the agent config +# Use None to extract the path from the agent config +participant_loadout_config_0 = C:\Users\fabio\Fabio\Programing\Skybot\Skybot\Skylooks.cfg +participant_loadout_config_1 = C:\Users\fabio\Fabio\Programing\Skybot\python_example\appearance.cfg +participant_loadout_config_2 = None +participant_loadout_config_3 = None +participant_loadout_config_4 = None +participant_loadout_config_5 = None +participant_loadout_config_6 = None +participant_loadout_config_7 = None +participant_loadout_config_8 = None +participant_loadout_config_9 = None + + diff --git a/run-gui.bat b/run-gui.bat new file mode 100644 index 0000000..bf70233 --- /dev/null +++ b/run-gui.bat @@ -0,0 +1,31 @@ +@echo off + +@rem Change the working directory to the location of this file so that relative paths will work +cd /D "%~dp0" + +@rem Make sure the environment variables are up-to-date. This is useful if the user installed python a moment ago. +call ./RefreshEnv.cmd + +setlocal EnableDelayedExpansion + +@rem Run the is_safe_to_upgrade function and save the output to a temp file. +python -c "from rlbot.utils import public_utils; print(public_utils.is_safe_to_upgrade());" > %temp%\is_safe_to_upgrade.txt + +IF %ERRORLEVEL% NEQ 0 ( + @rem The python command failed, so rlbot is probably not installed at all. Safe to 'upgrade'. + set is_safe_to_upgrade=True +) ELSE ( + @rem read the file containing the python output. + set /p is_safe_to_upgrade= < %temp%\is_safe_to_upgrade.txt +) +del %temp%\is_safe_to_upgrade.txt + +IF "!is_safe_to_upgrade!"=="True" ( + python -m pip install -r requirements.txt --upgrade +) ELSE ( + echo Will not attempt to upgrade rlbot because files are in use. +) + +python -c "from rlbot.gui.qt_root import RLBotQTGui; RLBotQTGui.main();" + +pause diff --git a/run.bat b/run.bat new file mode 100644 index 0000000..ad53193 --- /dev/null +++ b/run.bat @@ -0,0 +1,31 @@ +@echo off + +@rem Change the working directory to the location of this file so that relative paths will work +cd /D "%~dp0" + +@rem Make sure the environment variables are up-to-date. This is useful if the user installed python a moment ago. +call ./RefreshEnv.cmd + +setlocal EnableDelayedExpansion + +@rem Run the is_safe_to_upgrade function and save the output to a temp file. +python -c "from rlbot.utils import public_utils; print(public_utils.is_safe_to_upgrade());" > %temp%\is_safe_to_upgrade.txt + +IF %ERRORLEVEL% NEQ 0 ( + @rem The python command failed, so rlbot is probably not installed at all. Safe to 'upgrade'. + set is_safe_to_upgrade=True +) ELSE ( + @rem read the file containing the python output. + set /p is_safe_to_upgrade= < %temp%\is_safe_to_upgrade.txt +) +del %temp%\is_safe_to_upgrade.txt + +IF "!is_safe_to_upgrade!"=="True" ( + python -m pip install -r requirements.txt --upgrade +) ELSE ( + echo Will not attempt to upgrade rlbot because files are in use. +) + +python -c "from rlbot import runner; runner.main();" + +pause