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