From 4b0d2aee1e5e565e990021e6274935573e03c3c1 Mon Sep 17 00:00:00 2001 From: Zach Date: Sat, 2 May 2020 19:19:42 -0400 Subject: [PATCH 1/2] initial commit --- .classpath | 18 + .gitignore | 3 +- .project | 23 + .settings/org.eclipse.buildship.core.prefs | 2 + README.md | 2 +- rlbot.cfg | 487 +++++++++++++++--- src/main/java/fambot/FamBot07.java | 80 +++ src/main/java/fambot/FamBotMemory.java | 33 ++ .../FamBotPythonInterface.java} | 8 +- .../{rlbotexample => fambot}/JavaExample.java | 10 +- .../boost/BoostManager.java | 29 +- .../boost/BoostPad.java | 4 +- .../fambot/controller/DefaultController.java | 45 ++ .../fambot/controller/EncogController.java | 5 + .../java/fambot/controller/FamBotActions.java | 114 ++++ .../input/DataPacket.java | 32 +- .../input/ball/BallData.java | 8 +- .../input/ball/BallTouch.java | 4 +- .../input/car/CarData.java | 31 +- .../input/car/CarOrientation.java | 4 +- .../output/ControlsOutput.java | 2 +- .../prediction/BallPredictionHelper.java | 5 +- src/main/java/fambot/util/DebugDrawer.java | 50 ++ .../util/PortReader.java | 2 +- .../vector/Vector2.java | 2 +- .../vector/Vector3.java | 2 +- src/main/java/rlbotexample/SampleBot.java | 128 ----- unlimited_boost.cfg | 414 +++++++++++++++ 28 files changed, 1275 insertions(+), 272 deletions(-) create mode 100644 .classpath create mode 100644 .project create mode 100644 .settings/org.eclipse.buildship.core.prefs create mode 100644 src/main/java/fambot/FamBot07.java create mode 100644 src/main/java/fambot/FamBotMemory.java rename src/main/java/{rlbotexample/SamplePythonInterface.java => fambot/FamBotPythonInterface.java} (55%) rename src/main/java/{rlbotexample => fambot}/JavaExample.java (93%) rename src/main/java/{rlbotexample => fambot}/boost/BoostManager.java (70%) rename src/main/java/{rlbotexample => fambot}/boost/BoostPad.java (92%) create mode 100644 src/main/java/fambot/controller/DefaultController.java create mode 100644 src/main/java/fambot/controller/EncogController.java create mode 100644 src/main/java/fambot/controller/FamBotActions.java rename src/main/java/{rlbotexample => fambot}/input/DataPacket.java (59%) rename src/main/java/{rlbotexample => fambot}/input/ball/BallData.java (87%) rename src/main/java/{rlbotexample => fambot}/input/ball/BallTouch.java (91%) rename src/main/java/{rlbotexample => fambot}/input/car/CarData.java (61%) rename src/main/java/{rlbotexample => fambot}/input/car/CarOrientation.java (96%) rename src/main/java/{rlbotexample => fambot}/output/ControlsOutput.java (99%) rename src/main/java/{rlbotexample => fambot}/prediction/BallPredictionHelper.java (93%) create mode 100644 src/main/java/fambot/util/DebugDrawer.java rename src/main/java/{rlbotexample => fambot}/util/PortReader.java (95%) rename src/main/java/{rlbotexample => fambot}/vector/Vector2.java (98%) rename src/main/java/{rlbotexample => fambot}/vector/Vector3.java (99%) delete mode 100644 src/main/java/rlbotexample/SampleBot.java create mode 100644 unlimited_boost.cfg diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..6b41508 --- /dev/null +++ b/.classpath @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore index f32e792..e6c26aa 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ out/ build/ .gradle __pycache__ -*.iml \ No newline at end of file +*.iml +/bin/ diff --git a/.project b/.project new file mode 100644 index 0000000..200869e --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + RLBotJavaExample + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000..408b507 --- /dev/null +++ b/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir= +eclipse.preferences.version=1 diff --git a/README.md b/README.md index e7c2910..74348d3 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ open and it's OK if it says something like "75%". 1. Double click on run-gui.bat 1. Click the 'Run' button -- Bot behavior is controlled by `src/main/java/rlbotexample/SampleBot.java` +- Bot behavior is controlled by `src/main/java/fambot/SampleBot.java` - Bot appearance is controlled by `src/main/python/javaExampleAppearance.cfg` See the [wiki](https://github.com/RLBot/RLBotJavaExample/wiki) diff --git a/rlbot.cfg b/rlbot.cfg index 930f607..0252359 100644 --- a/rlbot.cfg +++ b/rlbot.cfg @@ -1,73 +1,414 @@ -[RLBot Configuration] -# Visit https://github.com/RLBot/RLBot/wiki/Config-File-Documentation to see what you can put here. - -[Team Configuration] -# Visit https://github.com/RLBot/RLBot/wiki/Config-File-Documentation to see what you can put here. - -[Match Configuration] -# Number of bots/players which will be spawned. We support up to max 64. -num_participants = 2 -game_mode = Soccer -game_map = Mannfield - -[Mutator Configuration] -# Visit https://github.com/RLBot/RLBot/wiki/Config-File-Documentation to see what you can put here. - -[Participant Configuration] -# Put the name of your bot config file here. Only 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 = src/main/python/javaExample.cfg -participant_config_1 = src/main/python/javaExample.cfg -participant_config_2 = src/main/python/javaExample.cfg -participant_config_3 = src/main/python/javaExample.cfg -participant_config_4 = src/main/python/javaExample.cfg -participant_config_5 = src/main/python/javaExample.cfg -participant_config_6 = src/main/python/javaExample.cfg -participant_config_7 = src/main/python/javaExample.cfg -participant_config_8 = src/main/python/javaExample.cfg -participant_config_9 = src/main/python/javaExample.cfg - -# team 0 shoots on positive goal, team 1 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 the framework but the game detects it as a human -participant_type_0 = rlbot -participant_type_1 = rlbot -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. -# Please leave a value here even if it isn't used :) -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 +[RLBot Configuration] +# A path to the extension file we want to load +extension_path = None +# Defines the behavior when connecting multiple RLBot instances over a network. +networking_role = none +# The IP address to connect to if networking is desired. +network_address = 127.0.0.1 + +[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 64. +num_participants = 2 +# What game mode the game should load. +# Accepted values are "Soccer", "Hoops", "Dropshot", "Hockey", "Rumble", "Heatseeker" +game_mode = Soccer +# Which map the game should load into. Too many to list. +game_map = Mannfield +# Automatically skip replays after a goal. Also stops match replays from being saved. +skip_replays = False +# Skip the kickoff countdown +start_without_countdown = False +# What should we do if you click run while a match is already in progress? +existing_match_behavior = Restart If Different +# If True, the framework will wait for outputs from all bots before advancing to the next frame. +enable_lockstep = False + +[Mutator Configuration] +# Match Length +Match Length = 5 Minutes +# 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 = src\main\python\javaExample.cfg +participant_config_1 = src\main\python\javaExample.cfg +participant_config_2 = src\main\python\javaExample.cfg +participant_config_3 = src\main\python\javaExample.cfg +participant_config_4 = src/main/python/javaExample.cfg +participant_config_5 = src/main/python/javaExample.cfg +participant_config_6 = src/main/python/javaExample.cfg +participant_config_7 = src/main/python/javaExample.cfg +participant_config_8 = src/main/python/javaExample.cfg +participant_config_9 = src/main/python/javaExample.cfg +participant_config_10 = None +participant_config_11 = None +participant_config_12 = None +participant_config_13 = None +participant_config_14 = None +participant_config_15 = None +participant_config_16 = None +participant_config_17 = None +participant_config_18 = None +participant_config_19 = None +participant_config_20 = None +participant_config_21 = None +participant_config_22 = None +participant_config_23 = None +participant_config_24 = None +participant_config_25 = None +participant_config_26 = None +participant_config_27 = None +participant_config_28 = None +participant_config_29 = None +participant_config_30 = None +participant_config_31 = None +participant_config_32 = None +participant_config_33 = None +participant_config_34 = None +participant_config_35 = None +participant_config_36 = None +participant_config_37 = None +participant_config_38 = None +participant_config_39 = None +participant_config_40 = None +participant_config_41 = None +participant_config_42 = None +participant_config_43 = None +participant_config_44 = None +participant_config_45 = None +participant_config_46 = None +participant_config_47 = None +participant_config_48 = None +participant_config_49 = None +participant_config_50 = None +participant_config_51 = None +participant_config_52 = None +participant_config_53 = None +participant_config_54 = None +participant_config_55 = None +participant_config_56 = None +participant_config_57 = None +participant_config_58 = None +participant_config_59 = None +participant_config_60 = None +participant_config_61 = None +participant_config_62 = None +participant_config_63 = None + +# 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 +participant_team_10 = 0 +participant_team_11 = 0 +participant_team_12 = 0 +participant_team_13 = 0 +participant_team_14 = 0 +participant_team_15 = 0 +participant_team_16 = 0 +participant_team_17 = 0 +participant_team_18 = 0 +participant_team_19 = 0 +participant_team_20 = 0 +participant_team_21 = 0 +participant_team_22 = 0 +participant_team_23 = 0 +participant_team_24 = 0 +participant_team_25 = 0 +participant_team_26 = 0 +participant_team_27 = 0 +participant_team_28 = 0 +participant_team_29 = 0 +participant_team_30 = 0 +participant_team_31 = 0 +participant_team_32 = 0 +participant_team_33 = 0 +participant_team_34 = 0 +participant_team_35 = 0 +participant_team_36 = 0 +participant_team_37 = 0 +participant_team_38 = 0 +participant_team_39 = 0 +participant_team_40 = 0 +participant_team_41 = 0 +participant_team_42 = 0 +participant_team_43 = 0 +participant_team_44 = 0 +participant_team_45 = 0 +participant_team_46 = 0 +participant_team_47 = 0 +participant_team_48 = 0 +participant_team_49 = 0 +participant_team_50 = 0 +participant_team_51 = 0 +participant_team_52 = 0 +participant_team_53 = 0 +participant_team_54 = 0 +participant_team_55 = 0 +participant_team_56 = 0 +participant_team_57 = 0 +participant_team_58 = 0 +participant_team_59 = 0 +participant_team_60 = 0 +participant_team_61 = 0 +participant_team_62 = 0 +participant_team_63 = 0 + +# 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 = rlbot +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 +participant_type_10 = rlbot +participant_type_11 = rlbot +participant_type_12 = rlbot +participant_type_13 = rlbot +participant_type_14 = rlbot +participant_type_15 = rlbot +participant_type_16 = rlbot +participant_type_17 = rlbot +participant_type_18 = rlbot +participant_type_19 = rlbot +participant_type_20 = rlbot +participant_type_21 = rlbot +participant_type_22 = rlbot +participant_type_23 = rlbot +participant_type_24 = rlbot +participant_type_25 = rlbot +participant_type_26 = rlbot +participant_type_27 = rlbot +participant_type_28 = rlbot +participant_type_29 = rlbot +participant_type_30 = rlbot +participant_type_31 = rlbot +participant_type_32 = rlbot +participant_type_33 = rlbot +participant_type_34 = rlbot +participant_type_35 = rlbot +participant_type_36 = rlbot +participant_type_37 = rlbot +participant_type_38 = rlbot +participant_type_39 = rlbot +participant_type_40 = rlbot +participant_type_41 = rlbot +participant_type_42 = rlbot +participant_type_43 = rlbot +participant_type_44 = rlbot +participant_type_45 = rlbot +participant_type_46 = rlbot +participant_type_47 = rlbot +participant_type_48 = rlbot +participant_type_49 = rlbot +participant_type_50 = rlbot +participant_type_51 = rlbot +participant_type_52 = rlbot +participant_type_53 = rlbot +participant_type_54 = rlbot +participant_type_55 = rlbot +participant_type_56 = rlbot +participant_type_57 = rlbot +participant_type_58 = rlbot +participant_type_59 = rlbot +participant_type_60 = rlbot +participant_type_61 = rlbot +participant_type_62 = rlbot +participant_type_63 = 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 +participant_bot_skill_10 = 1.0 +participant_bot_skill_11 = 1.0 +participant_bot_skill_12 = 1.0 +participant_bot_skill_13 = 1.0 +participant_bot_skill_14 = 1.0 +participant_bot_skill_15 = 1.0 +participant_bot_skill_16 = 1.0 +participant_bot_skill_17 = 1.0 +participant_bot_skill_18 = 1.0 +participant_bot_skill_19 = 1.0 +participant_bot_skill_20 = 1.0 +participant_bot_skill_21 = 1.0 +participant_bot_skill_22 = 1.0 +participant_bot_skill_23 = 1.0 +participant_bot_skill_24 = 1.0 +participant_bot_skill_25 = 1.0 +participant_bot_skill_26 = 1.0 +participant_bot_skill_27 = 1.0 +participant_bot_skill_28 = 1.0 +participant_bot_skill_29 = 1.0 +participant_bot_skill_30 = 1.0 +participant_bot_skill_31 = 1.0 +participant_bot_skill_32 = 1.0 +participant_bot_skill_33 = 1.0 +participant_bot_skill_34 = 1.0 +participant_bot_skill_35 = 1.0 +participant_bot_skill_36 = 1.0 +participant_bot_skill_37 = 1.0 +participant_bot_skill_38 = 1.0 +participant_bot_skill_39 = 1.0 +participant_bot_skill_40 = 1.0 +participant_bot_skill_41 = 1.0 +participant_bot_skill_42 = 1.0 +participant_bot_skill_43 = 1.0 +participant_bot_skill_44 = 1.0 +participant_bot_skill_45 = 1.0 +participant_bot_skill_46 = 1.0 +participant_bot_skill_47 = 1.0 +participant_bot_skill_48 = 1.0 +participant_bot_skill_49 = 1.0 +participant_bot_skill_50 = 1.0 +participant_bot_skill_51 = 1.0 +participant_bot_skill_52 = 1.0 +participant_bot_skill_53 = 1.0 +participant_bot_skill_54 = 1.0 +participant_bot_skill_55 = 1.0 +participant_bot_skill_56 = 1.0 +participant_bot_skill_57 = 1.0 +participant_bot_skill_58 = 1.0 +participant_bot_skill_59 = 1.0 +participant_bot_skill_60 = 1.0 +participant_bot_skill_61 = 1.0 +participant_bot_skill_62 = 1.0 +participant_bot_skill_63 = 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 = None +participant_loadout_config_1 = None +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 +participant_loadout_config_10 = None +participant_loadout_config_11 = None +participant_loadout_config_12 = None +participant_loadout_config_13 = None +participant_loadout_config_14 = None +participant_loadout_config_15 = None +participant_loadout_config_16 = None +participant_loadout_config_17 = None +participant_loadout_config_18 = None +participant_loadout_config_19 = None +participant_loadout_config_20 = None +participant_loadout_config_21 = None +participant_loadout_config_22 = None +participant_loadout_config_23 = None +participant_loadout_config_24 = None +participant_loadout_config_25 = None +participant_loadout_config_26 = None +participant_loadout_config_27 = None +participant_loadout_config_28 = None +participant_loadout_config_29 = None +participant_loadout_config_30 = None +participant_loadout_config_31 = None +participant_loadout_config_32 = None +participant_loadout_config_33 = None +participant_loadout_config_34 = None +participant_loadout_config_35 = None +participant_loadout_config_36 = None +participant_loadout_config_37 = None +participant_loadout_config_38 = None +participant_loadout_config_39 = None +participant_loadout_config_40 = None +participant_loadout_config_41 = None +participant_loadout_config_42 = None +participant_loadout_config_43 = None +participant_loadout_config_44 = None +participant_loadout_config_45 = None +participant_loadout_config_46 = None +participant_loadout_config_47 = None +participant_loadout_config_48 = None +participant_loadout_config_49 = None +participant_loadout_config_50 = None +participant_loadout_config_51 = None +participant_loadout_config_52 = None +participant_loadout_config_53 = None +participant_loadout_config_54 = None +participant_loadout_config_55 = None +participant_loadout_config_56 = None +participant_loadout_config_57 = None +participant_loadout_config_58 = None +participant_loadout_config_59 = None +participant_loadout_config_60 = None +participant_loadout_config_61 = None +participant_loadout_config_62 = None +participant_loadout_config_63 = None + + diff --git a/src/main/java/fambot/FamBot07.java b/src/main/java/fambot/FamBot07.java new file mode 100644 index 0000000..03df8c3 --- /dev/null +++ b/src/main/java/fambot/FamBot07.java @@ -0,0 +1,80 @@ +package fambot; + +import fambot.boost.BoostManager; +import fambot.controller.DefaultController; +import fambot.controller.FamBotActions; +import fambot.input.DataPacket; +import fambot.output.ControlsOutput; +import fambot.util.DebugDrawer; +import rlbot.Bot; +import rlbot.ControllerState; +import rlbot.flat.GameTickPacket; + +public class FamBot07 implements Bot { + + private final int playerIndex; + private FamBotMemory memory = new FamBotMemory(); + + public FamBot07(int playerIndex) { + this.playerIndex = playerIndex; + } + + /** + * This is where we keep the actual bot logic. This function shows how to chase + * the ball. Modify it to make your bot smarter! + */ + private ControlsOutput processInput(DataPacket input) { + //overwrite the incorrect touch from the previous goal or reset + if (input.gameInfo.isKickoffPause()) { + memory.resetKickoff(); + input.ball.hasBeenTouched = false; + } + + // This is optional! + DebugDrawer.drawDebugLines(this, input); + + DefaultController.setState(input); + return DefaultController.getControl(input, memory); + } + + + + + @Override + public int getIndex() { + return this.playerIndex; + } + + /** + * This is the most important function. It will automatically get called by the + * framework with fresh data every frame. Respond with appropriate controls! + */ + @Override + public ControllerState processInput(GameTickPacket packet) { + + if (packet.playersLength() <= playerIndex || packet.ball() == null || !packet.gameInfo().isRoundActive()) { + // Just return immediately if something looks wrong with the data. This helps us + // avoid stack traces. + return new ControlsOutput(); + } + + // Update the boost manager and tile manager with the latest data + BoostManager.loadGameTickPacket(packet); + + // Translate the raw packet data (which is in an unpleasant format) into our + // custom DataPacket class. + // The DataPacket might not include everything from GameTickPacket, so improve + // it if you need to! + DataPacket dataPacket = new DataPacket(packet, playerIndex); + + // Do the actual logic using our dataPacket. + ControlsOutput controlsOutput = processInput(dataPacket); + + return controlsOutput; + } + + @Override + public void retire() { + System.out.println("Retiring sample bot " + playerIndex); + } +} diff --git a/src/main/java/fambot/FamBotMemory.java b/src/main/java/fambot/FamBotMemory.java new file mode 100644 index 0000000..47f816c --- /dev/null +++ b/src/main/java/fambot/FamBotMemory.java @@ -0,0 +1,33 @@ +package fambot; + +import fambot.boost.BoostPad; + +public class FamBotMemory { + private int kickoffJumpTimer = 0; + private BoostPad kickoffBoost = null; + + public int getKickoffJumpTimer() { + return kickoffJumpTimer; + } + + public void incrementKickoffJumpTimer() { + kickoffJumpTimer++; + } + + public void resetKickoffJumpTimer() { + kickoffJumpTimer = 0; + } + + public BoostPad getKickoffBoost() { + return kickoffBoost; + } + + public void setKickoffBoost(BoostPad kickoffBoost) { + this.kickoffBoost = kickoffBoost; + } + + public void resetKickoff() { + resetKickoffJumpTimer(); + setKickoffBoost(null); + } +} diff --git a/src/main/java/rlbotexample/SamplePythonInterface.java b/src/main/java/fambot/FamBotPythonInterface.java similarity index 55% rename from src/main/java/rlbotexample/SamplePythonInterface.java rename to src/main/java/fambot/FamBotPythonInterface.java index aa679bc..853ba0c 100644 --- a/src/main/java/rlbotexample/SamplePythonInterface.java +++ b/src/main/java/fambot/FamBotPythonInterface.java @@ -1,17 +1,17 @@ -package rlbotexample; +package fambot; import rlbot.Bot; import rlbot.manager.BotManager; import rlbot.pyinterop.SocketServer; -public class SamplePythonInterface extends SocketServer { +public class FamBotPythonInterface extends SocketServer { - public SamplePythonInterface(int port, BotManager botManager) { + public FamBotPythonInterface(int port, BotManager botManager) { super(port, botManager); } @Override protected Bot initBot(int index, String botType, int team) { - return new SampleBot(index); + return new FamBot07(index); } } diff --git a/src/main/java/rlbotexample/JavaExample.java b/src/main/java/fambot/JavaExample.java similarity index 93% rename from src/main/java/rlbotexample/JavaExample.java rename to src/main/java/fambot/JavaExample.java index d3d7230..0eed1d9 100644 --- a/src/main/java/rlbotexample/JavaExample.java +++ b/src/main/java/fambot/JavaExample.java @@ -1,10 +1,12 @@ -package rlbotexample; +package fambot; import rlbot.manager.BotManager; -import rlbotexample.util.PortReader; import javax.swing.*; import javax.swing.border.EmptyBorder; + +import fambot.util.PortReader; + import java.awt.*; import java.awt.event.ActionListener; import java.net.URL; @@ -14,7 +16,7 @@ /** * See JavaAgent.py for usage instructions. * - * Look inside SampleBot.java for the actual bot logic! + * Look inside FamBot07.java for the actual bot logic! */ public class JavaExample { @@ -28,7 +30,7 @@ public static void main(String[] args) { return DEFAULT_PORT; }); - SamplePythonInterface pythonInterface = new SamplePythonInterface(port, botManager); + FamBotPythonInterface pythonInterface = new FamBotPythonInterface(port, botManager); new Thread(pythonInterface::start).start(); displayWindow(botManager, port); diff --git a/src/main/java/rlbotexample/boost/BoostManager.java b/src/main/java/fambot/boost/BoostManager.java similarity index 70% rename from src/main/java/rlbotexample/boost/BoostManager.java rename to src/main/java/fambot/boost/BoostManager.java index b93d7a6..ac3a8da 100644 --- a/src/main/java/rlbotexample/boost/BoostManager.java +++ b/src/main/java/fambot/boost/BoostManager.java @@ -1,14 +1,15 @@ -package rlbotexample.boost; +package fambot.boost; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import fambot.vector.Vector2; +import fambot.vector.Vector3; import rlbot.cppinterop.RLBotDll; import rlbot.flat.BoostPadState; import rlbot.flat.FieldInfo; import rlbot.flat.GameTickPacket; -import rlbotexample.vector.Vector3; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; /** * Information about where boost pads are located on the field and what status they have. @@ -69,4 +70,20 @@ public static void loadGameTickPacket(GameTickPacket packet) { } } + //TODO get BoostPadState from GameTickPacket and allow passing of pad that is inactive but about to be active + public static BoostPad nearestBoost(Vector2 carLocation, boolean full, boolean active){ + double dist = Double.MAX_VALUE; + BoostPad pad = null; + List boosts = full ? fullBoosts : orderedBoosts; + for (BoostPad thisPad : boosts) { + Vector2 padLocation = thisPad.getLocation().flatten(); + double thisDist = padLocation.distance(carLocation); + //System.out.println("ID: " + Thread.currentThread().getId() + "\tChecking Pad: " + thisPad.getLocation().x + " " + thisPad.getLocation().y + "\tThis Dist: " + thisDist + "\tDist :" + dist); + if (thisDist < dist && (active && thisPad.isActive() || (!active))) { + dist = thisDist; + pad = thisPad; + } + } + return pad; + } } diff --git a/src/main/java/rlbotexample/boost/BoostPad.java b/src/main/java/fambot/boost/BoostPad.java similarity index 92% rename from src/main/java/rlbotexample/boost/BoostPad.java rename to src/main/java/fambot/boost/BoostPad.java index c4f0c2d..1fd1df0 100644 --- a/src/main/java/rlbotexample/boost/BoostPad.java +++ b/src/main/java/fambot/boost/BoostPad.java @@ -1,7 +1,7 @@ -package rlbotexample.boost; +package fambot.boost; -import rlbotexample.vector.Vector3; +import fambot.vector.Vector3; /** * Representation of one of the boost pads on the field. diff --git a/src/main/java/fambot/controller/DefaultController.java b/src/main/java/fambot/controller/DefaultController.java new file mode 100644 index 0000000..388bba1 --- /dev/null +++ b/src/main/java/fambot/controller/DefaultController.java @@ -0,0 +1,45 @@ +package fambot.controller; + +import fambot.FamBotMemory; +import fambot.input.DataPacket; +import fambot.output.ControlsOutput; + +public class DefaultController { + private static String state = "default"; + + public static void setState(DataPacket input) { + System.out.println("ID: " + Thread.currentThread().getId() + "\tBall Touched: " + input.ball.hasBeenTouched); + if (!input.ball.hasBeenTouched) { + state = "kickoff"; + return; + } + + if (input.ball.hasBeenTouched && state.equals("kickoff")) { + state = "default"; + } + + if((int) input.gameInfo.secondsElapsed() % 30 == 0 && input.car.boost < 20) { + state = "largeBoost"; + } + + if (state.equals("largeBoost") && input.car.boost == 100) { + state = "default"; + } + } + + public static ControlsOutput getControl(DataPacket input, FamBotMemory memory) { + System.out.println("ID: " + Thread.currentThread().getId() + "\tState: " + state); + ControlsOutput output = null; + switch (state) { + case "largeBoost": + output = FamBotActions.getNearestLargeBoost(input); + break; + case "kickoff": + output = FamBotActions.kickoff(input, memory); + break; + default: + output = FamBotActions.ballChase(input); + } + return output; + } +} diff --git a/src/main/java/fambot/controller/EncogController.java b/src/main/java/fambot/controller/EncogController.java new file mode 100644 index 0000000..b0f008c --- /dev/null +++ b/src/main/java/fambot/controller/EncogController.java @@ -0,0 +1,5 @@ +package fambot.controller; + +public class EncogController { + +} diff --git a/src/main/java/fambot/controller/FamBotActions.java b/src/main/java/fambot/controller/FamBotActions.java new file mode 100644 index 0000000..1403d23 --- /dev/null +++ b/src/main/java/fambot/controller/FamBotActions.java @@ -0,0 +1,114 @@ +package fambot.controller; + +import fambot.FamBotMemory; +import fambot.boost.BoostManager; +import fambot.boost.BoostPad; +import fambot.input.DataPacket; +import fambot.input.ball.BallData; +import fambot.input.car.CarData; +import fambot.output.ControlsOutput; +import fambot.vector.Vector2; +import rlbot.cppinterop.RLBotDll; +import rlbot.flat.QuickChatSelection; + +public class FamBotActions { + public static void flyUp() { + // System.out.println("X: "+ ball3.x + "\tY: " + ball3.y + "\tZ: " + ball3.z); + +// if (ball3.z > 400) { +// return new ControlsOutput() +// .withJump() +// .withSteer(goLeft ? -1 : 1) +// .withThrottle(1); +// } +// return new ControlsOutput() +// .withSteer(goLeft ? -1 : 1) +// .withThrottle(1); + } + + public static ControlsOutput getNearestLargeBoost(DataPacket input) { + CarData car = input.car; + + BoostPad pad = BoostManager.nearestBoost(car.position.flatten(), true, true); + + return new ControlsOutput() + .withSteer(steer2d(car, pad.getLocation().flatten(), null)) + .withThrottle(1); + } + + public static ControlsOutput ballChase(DataPacket input) { + BallData ball = input.ball; + CarData car = input.car; + + return new ControlsOutput() + .withSteer(steer2d(car, ball.position.flatten(), ball.velocity.flatten())) + .withThrottle(1) + .withBoost(true); + } + + //TODO implement leading with targetDir + public static float steer2d(CarData car, Vector2 targetPos, Vector2 targetDir) { + Vector2 pointer = targetPos.minus(car.position.flatten()); + double radians = car.velocity.flatten().correctionAngle(pointer); + //System.out.println("ID: " + Thread.currentThread().getId() + "\tSteering Radians: " + radians); + return -5 * (float) Math.max(-.2, Math.min(radians, .2)); + } + + public static void spamChat(int playerIndex) { + RLBotDll.sendQuickChat(playerIndex, false, QuickChatSelection.Compliments_NiceOne); + } + + private static ControlsOutput hitBall(CarData car, BallData ball) { + return null; + } + + public static ControlsOutput kickoff(DataPacket input, FamBotMemory memory) { + CarData car = input.car; + BallData ball = input.ball; + + if (memory.getKickoffBoost() == null || !memory.getKickoffBoost().isActive()) { + memory.setKickoffBoost(BoostManager.nearestBoost(car.position.flatten(), false, true)); + if (car.position.flatten().distance(ball.position.flatten()) < car.position.flatten().distance(memory.getKickoffBoost().getLocation().flatten())) { + memory.setKickoffBoost(null); + } + } + if (car.hasWheelContact) { + double distance = car.position.flatten().distance(ball.position.flatten()); + if (memory.getKickoffJumpTimer() == 0 && distance < 850) { + System.out.println("ID: " + Thread.currentThread().getId() + "\tKickoff First Jump"); + memory.incrementKickoffJumpTimer(); + return new ControlsOutput() + .withJump() + .withThrottle(1); + + } else { + System.out.println("ID: " + Thread.currentThread().getId() + "\tBoostPad: " + (memory.getKickoffBoost() == null ? "null" : (memory.getKickoffBoost().isActive() ? "Active" : "Inactive"))); + if(false && memory.getKickoffBoost() != null && memory.getKickoffBoost().isActive()) { + System.out.println("ID: " + Thread.currentThread().getId() + "\tKickoff Boost"); + float steer = steer2d(input.car, memory.getKickoffBoost().getLocation().flatten(), null); + return new ControlsOutput() + .withBoost() + .withThrottle(1) + .withSteer(steer); + + } else { + System.out.println("ID: " + Thread.currentThread().getId() + "\tKickoff Ball Chase"); + return ballChase(input); + + } + } + } else { + if (memory.getKickoffJumpTimer() > 10) { + System.out.println("ID: " + Thread.currentThread().getId() + "\tKickoff Flip"); + return new ControlsOutput() + .withPitch(-1) + .withJump(); + + } else { + System.out.println("ID: " + Thread.currentThread().getId() + "\tKickoff Pre Flip\tTick Counter: " + memory.getKickoffJumpTimer()); + memory.incrementKickoffJumpTimer(); + return new ControlsOutput(); + } + } + } +} diff --git a/src/main/java/rlbotexample/input/DataPacket.java b/src/main/java/fambot/input/DataPacket.java similarity index 59% rename from src/main/java/rlbotexample/input/DataPacket.java rename to src/main/java/fambot/input/DataPacket.java index a61b69c..3907cc3 100644 --- a/src/main/java/rlbotexample/input/DataPacket.java +++ b/src/main/java/fambot/input/DataPacket.java @@ -1,12 +1,13 @@ -package rlbotexample.input; - -import rlbot.flat.GameTickPacket; -import rlbotexample.input.ball.BallData; -import rlbotexample.input.car.CarData; +package fambot.input; import java.util.ArrayList; import java.util.List; +import fambot.input.ball.BallData; +import fambot.input.car.CarData; +import rlbot.flat.GameInfo; +import rlbot.flat.GameTickPacket; + /** * This class is here for your convenience, it is NOT part of the framework. You can change it as much * as you want, or delete it. The benefits of using this instead of rlbot.flat.GameTickPacket are: @@ -15,26 +16,23 @@ * and leave your bot logic alone. */ public class DataPacket { - - /** Your own car, based on the playerIndex */ - public final CarData car; - + + public final CarData car; public final List allCars; - + public final GameInfo gameInfo; public final BallData ball; public final int team; - - /** The index of your player */ public final int playerIndex; - public DataPacket(GameTickPacket request, int playerIndex) { + public DataPacket(GameTickPacket packet, int playerIndex) { - this.playerIndex = playerIndex; - this.ball = new BallData(request.ball()); + this.gameInfo = packet.gameInfo(); + this.playerIndex = playerIndex; + this.ball = new BallData(packet.ball()); allCars = new ArrayList<>(); - for (int i = 0; i < request.playersLength(); i++) { - allCars.add(new CarData(request.players(i), request.gameInfo().secondsElapsed())); + for (int i = 0; i < packet.playersLength(); i++) { + allCars.add(new CarData(packet.players(i), packet.gameInfo().secondsElapsed())); } this.car = allCars.get(playerIndex); diff --git a/src/main/java/rlbotexample/input/ball/BallData.java b/src/main/java/fambot/input/ball/BallData.java similarity index 87% rename from src/main/java/rlbotexample/input/ball/BallData.java rename to src/main/java/fambot/input/ball/BallData.java index 8dffab4..2056076 100644 --- a/src/main/java/rlbotexample/input/ball/BallData.java +++ b/src/main/java/fambot/input/ball/BallData.java @@ -1,8 +1,8 @@ -package rlbotexample.input.ball; +package fambot.input.ball; +import fambot.vector.Vector3; import rlbot.flat.BallInfo; -import rlbotexample.vector.Vector3; /** * Basic information about the ball. @@ -15,7 +15,7 @@ public class BallData { public final Vector3 velocity; public final Vector3 spin; public final BallTouch latestTouch; - public final boolean hasBeenTouched; + public boolean hasBeenTouched; public BallData(final BallInfo ball) { this.position = new Vector3(ball.physics().location()); @@ -24,4 +24,6 @@ public BallData(final BallInfo ball) { this.hasBeenTouched = ball.latestTouch() != null; this.latestTouch = this.hasBeenTouched ? new BallTouch(ball.latestTouch()) : null; } + + } diff --git a/src/main/java/rlbotexample/input/ball/BallTouch.java b/src/main/java/fambot/input/ball/BallTouch.java similarity index 91% rename from src/main/java/rlbotexample/input/ball/BallTouch.java rename to src/main/java/fambot/input/ball/BallTouch.java index d0af1bb..fbccca6 100644 --- a/src/main/java/rlbotexample/input/ball/BallTouch.java +++ b/src/main/java/fambot/input/ball/BallTouch.java @@ -1,8 +1,8 @@ -package rlbotexample.input.ball; +package fambot.input.ball; +import fambot.vector.Vector3; import rlbot.flat.Touch; -import rlbotexample.vector.Vector3; /** * Basic information about the ball's latest touch. diff --git a/src/main/java/rlbotexample/input/car/CarData.java b/src/main/java/fambot/input/car/CarData.java similarity index 61% rename from src/main/java/rlbotexample/input/car/CarData.java rename to src/main/java/fambot/input/car/CarData.java index 1023e73..c3bfe3d 100644 --- a/src/main/java/rlbotexample/input/car/CarData.java +++ b/src/main/java/fambot/input/car/CarData.java @@ -1,7 +1,8 @@ -package rlbotexample.input.car; +package fambot.input.car; -import rlbotexample.vector.Vector3; +import fambot.boost.BoostPad; +import fambot.vector.Vector3; /** * Basic information about the car. @@ -11,31 +12,13 @@ */ public class CarData { - /** The location of the car on the field. (0, 0, 0) is center field. */ - public final Vector3 position; - - /** The velocity of the car. */ + public final Vector3 position; // (0,0,0) center field public final Vector3 velocity; - - /** The orientation of the car */ public final CarOrientation orientation; - - /** Boost ranges from 0 to 100 */ - public final double boost; - - /** True if the car is driving on the ground, the wall, etc. In other words, true if you can steer. */ + public final double boost; // 0 to 100 public final boolean hasWheelContact; - - /** - * True if the car is showing the supersonic and can demolish enemies on contact. - * This is a close approximation for whether the car is at max speed. - */ public final boolean isSupersonic; - - /** - * 0 for blue team, 1 for orange team. - */ - public final int team; + public final int team; // 0 = blue, 1 = orange /** * This is not really a car-specific attribute, but it's often very useful to know. It's included here @@ -53,4 +36,6 @@ public CarData(rlbot.flat.PlayerInfo playerInfo, float elapsedSeconds) { this.hasWheelContact = playerInfo.hasWheelContact(); this.elapsedSeconds = elapsedSeconds; } + + } diff --git a/src/main/java/rlbotexample/input/car/CarOrientation.java b/src/main/java/fambot/input/car/CarOrientation.java similarity index 96% rename from src/main/java/rlbotexample/input/car/CarOrientation.java rename to src/main/java/fambot/input/car/CarOrientation.java index 68370ec..691463d 100644 --- a/src/main/java/rlbotexample/input/car/CarOrientation.java +++ b/src/main/java/fambot/input/car/CarOrientation.java @@ -1,8 +1,8 @@ -package rlbotexample.input.car; +package fambot.input.car; +import fambot.vector.Vector3; import rlbot.flat.PlayerInfo; -import rlbotexample.vector.Vector3; /** * The car's orientation in space, a.k.a. what direction it's pointing. diff --git a/src/main/java/rlbotexample/output/ControlsOutput.java b/src/main/java/fambot/output/ControlsOutput.java similarity index 99% rename from src/main/java/rlbotexample/output/ControlsOutput.java rename to src/main/java/fambot/output/ControlsOutput.java index 9cdbd2b..718b3ca 100644 --- a/src/main/java/rlbotexample/output/ControlsOutput.java +++ b/src/main/java/fambot/output/ControlsOutput.java @@ -1,4 +1,4 @@ -package rlbotexample.output; +package fambot.output; import rlbot.ControllerState; diff --git a/src/main/java/rlbotexample/prediction/BallPredictionHelper.java b/src/main/java/fambot/prediction/BallPredictionHelper.java similarity index 93% rename from src/main/java/rlbotexample/prediction/BallPredictionHelper.java rename to src/main/java/fambot/prediction/BallPredictionHelper.java index 77b56c7..e6b9659 100644 --- a/src/main/java/rlbotexample/prediction/BallPredictionHelper.java +++ b/src/main/java/fambot/prediction/BallPredictionHelper.java @@ -1,12 +1,13 @@ -package rlbotexample.prediction; +package fambot.prediction; import rlbot.flat.BallPrediction; import rlbot.flat.PredictionSlice; import rlbot.render.Renderer; -import rlbotexample.vector.Vector3; import java.awt.*; +import fambot.vector.Vector3; + /** * This class can help you get started with ball prediction. Feel free to change it as much as you want, * this is part of your bot, not part of the framework! diff --git a/src/main/java/fambot/util/DebugDrawer.java b/src/main/java/fambot/util/DebugDrawer.java new file mode 100644 index 0000000..2b39488 --- /dev/null +++ b/src/main/java/fambot/util/DebugDrawer.java @@ -0,0 +1,50 @@ +package fambot.util; + +import java.awt.Color; + +import fambot.FamBot07; +import fambot.input.DataPacket; +import fambot.input.car.CarData; +import fambot.prediction.BallPredictionHelper; +import rlbot.cppinterop.RLBotDll; +import rlbot.cppinterop.RLBotInterfaceException; +import rlbot.flat.BallPrediction; +import rlbot.manager.BotLoopRenderer; +import rlbot.render.Renderer; + +public class DebugDrawer { + /** + * This is a nice example of using the rendering feature. + */ + public static void drawDebugLines(FamBot07 bot, DataPacket input) { + CarData car = input.car; + + // Here's an example of rendering debug data on the screen. + Renderer renderer = BotLoopRenderer.forBotLoop(bot); + + // Draw a line from the car to the ball + renderer.drawLine3d(Color.LIGHT_GRAY, car.position, input.ball.position); + + // Draw a line that points out from the nose of the car. + renderer.drawLine3d(Color.BLUE, car.position.plus(car.orientation.noseVector.scaled(150)), + car.position.plus(car.orientation.noseVector.scaled(300))); + + if (input.ball.hasBeenTouched) { + float lastTouchTime = car.elapsedSeconds - input.ball.latestTouch.gameSeconds; + Color touchColor = input.ball.latestTouch.team == 0 ? Color.BLUE : Color.ORANGE; + renderer.drawString3d((int) lastTouchTime + "s", touchColor, input.ball.position, 2, 2); + } + + try { + // Draw 3 seconds of ball prediction + BallPrediction ballPrediction = RLBotDll.getBallPrediction(); + BallPredictionHelper.drawTillMoment(ballPrediction, car.elapsedSeconds + 3, Color.CYAN, renderer); + } catch (RLBotInterfaceException e) { + e.printStackTrace(); + } + } + + public static void positionMarker(FamBot07 bot, DataPacket input) { + + } +} diff --git a/src/main/java/rlbotexample/util/PortReader.java b/src/main/java/fambot/util/PortReader.java similarity index 95% rename from src/main/java/rlbotexample/util/PortReader.java rename to src/main/java/fambot/util/PortReader.java index 3664bdd..2a7b14b 100644 --- a/src/main/java/rlbotexample/util/PortReader.java +++ b/src/main/java/fambot/util/PortReader.java @@ -1,4 +1,4 @@ -package rlbotexample.util; +package fambot.util; import java.util.Optional; diff --git a/src/main/java/rlbotexample/vector/Vector2.java b/src/main/java/fambot/vector/Vector2.java similarity index 98% rename from src/main/java/rlbotexample/vector/Vector2.java rename to src/main/java/fambot/vector/Vector2.java index dad1633..26320a3 100644 --- a/src/main/java/rlbotexample/vector/Vector2.java +++ b/src/main/java/fambot/vector/Vector2.java @@ -1,4 +1,4 @@ -package rlbotexample.vector; +package fambot.vector; /** * A vector that only knows about x and y components. diff --git a/src/main/java/rlbotexample/vector/Vector3.java b/src/main/java/fambot/vector/Vector3.java similarity index 99% rename from src/main/java/rlbotexample/vector/Vector3.java rename to src/main/java/fambot/vector/Vector3.java index 506ab21..8829326 100644 --- a/src/main/java/rlbotexample/vector/Vector3.java +++ b/src/main/java/fambot/vector/Vector3.java @@ -1,4 +1,4 @@ -package rlbotexample.vector; +package fambot.vector; import com.google.flatbuffers.FlatBufferBuilder; diff --git a/src/main/java/rlbotexample/SampleBot.java b/src/main/java/rlbotexample/SampleBot.java deleted file mode 100644 index 0a82f17..0000000 --- a/src/main/java/rlbotexample/SampleBot.java +++ /dev/null @@ -1,128 +0,0 @@ -package rlbotexample; - -import rlbot.Bot; -import rlbot.ControllerState; -import rlbot.cppinterop.RLBotDll; -import rlbot.cppinterop.RLBotInterfaceException; -import rlbot.flat.BallPrediction; -import rlbot.flat.GameTickPacket; -import rlbot.flat.QuickChatSelection; -import rlbot.manager.BotLoopRenderer; -import rlbot.render.Renderer; -import rlbotexample.boost.BoostManager; -import rlbotexample.input.DataPacket; -import rlbotexample.input.car.CarData; -import rlbotexample.output.ControlsOutput; -import rlbotexample.prediction.BallPredictionHelper; -import rlbotexample.vector.Vector2; - -import java.awt.*; - -public class SampleBot implements Bot { - - private final int playerIndex; - - public SampleBot(int playerIndex) { - this.playerIndex = playerIndex; - } - - /** - * This is where we keep the actual bot logic. This function shows how to chase the ball. - * Modify it to make your bot smarter! - */ - private ControlsOutput processInput(DataPacket input) { - - Vector2 ballPosition = input.ball.position.flatten(); - CarData myCar = input.car; - Vector2 carPosition = myCar.position.flatten(); - Vector2 carDirection = myCar.orientation.noseVector.flatten(); - - // Subtract the two positions to get a vector pointing from the car to the ball. - Vector2 carToBall = ballPosition.minus(carPosition); - - // How far does the car need to rotate before it's pointing exactly at the ball? - double steerCorrectionRadians = carDirection.correctionAngle(carToBall); - - boolean goLeft = steerCorrectionRadians > 0; - - // This is optional! - drawDebugLines(input, myCar, goLeft); - - // This is also optional! - if (input.ball.position.z > 300) { - RLBotDll.sendQuickChat(playerIndex, false, QuickChatSelection.Compliments_NiceOne); - } - - return new ControlsOutput() - .withSteer(goLeft ? -1 : 1) - .withThrottle(1); - } - - /** - * This is a nice example of using the rendering feature. - */ - private void drawDebugLines(DataPacket input, CarData myCar, boolean goLeft) { - // Here's an example of rendering debug data on the screen. - Renderer renderer = BotLoopRenderer.forBotLoop(this); - - // Draw a line from the car to the ball - renderer.drawLine3d(Color.LIGHT_GRAY, myCar.position, input.ball.position); - - // Draw a line that points out from the nose of the car. - renderer.drawLine3d(goLeft ? Color.BLUE : Color.RED, - myCar.position.plus(myCar.orientation.noseVector.scaled(150)), - myCar.position.plus(myCar.orientation.noseVector.scaled(300))); - - renderer.drawString3d(goLeft ? "left" : "right", Color.WHITE, myCar.position, 2, 2); - - if(input.ball.hasBeenTouched) { - float lastTouchTime = myCar.elapsedSeconds - input.ball.latestTouch.gameSeconds; - Color touchColor = input.ball.latestTouch.team == 0 ? Color.BLUE : Color.ORANGE; - renderer.drawString3d((int)lastTouchTime + "s", touchColor, input.ball.position, 2, 2); - } - - try { - // Draw 3 seconds of ball prediction - BallPrediction ballPrediction = RLBotDll.getBallPrediction(); - BallPredictionHelper.drawTillMoment(ballPrediction, myCar.elapsedSeconds + 3, Color.CYAN, renderer); - } catch (RLBotInterfaceException e) { - e.printStackTrace(); - } - } - - - @Override - public int getIndex() { - return this.playerIndex; - } - - /** - * This is the most important function. It will automatically get called by the framework with fresh data - * every frame. Respond with appropriate controls! - */ - @Override - public ControllerState processInput(GameTickPacket packet) { - - if (packet.playersLength() <= playerIndex || packet.ball() == null || !packet.gameInfo().isRoundActive()) { - // Just return immediately if something looks wrong with the data. This helps us avoid stack traces. - return new ControlsOutput(); - } - - // Update the boost manager and tile manager with the latest data - BoostManager.loadGameTickPacket(packet); - - // Translate the raw packet data (which is in an unpleasant format) into our custom DataPacket class. - // The DataPacket might not include everything from GameTickPacket, so improve it if you need to! - DataPacket dataPacket = new DataPacket(packet, playerIndex); - - // Do the actual logic using our dataPacket. - ControlsOutput controlsOutput = processInput(dataPacket); - - return controlsOutput; - } - - @Override - public void retire() { - System.out.println("Retiring sample bot " + playerIndex); - } -} diff --git a/unlimited_boost.cfg b/unlimited_boost.cfg new file mode 100644 index 0000000..216aabe --- /dev/null +++ b/unlimited_boost.cfg @@ -0,0 +1,414 @@ +[RLBot Configuration] +# A path to the extension file we want to load +extension_path = None +# Defines the behavior when connecting multiple RLBot instances over a network. +networking_role = none +# The IP address to connect to if networking is desired. +network_address = 127.0.0.1 + +[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 64. +num_participants = 2 +# What game mode the game should load. +# Accepted values are "Soccer", "Hoops", "Dropshot", "Hockey", "Rumble", "Heatseeker" +game_mode = Soccer +# Which map the game should load into. Too many to list. +game_map = StarbaseArc +# Automatically skip replays after a goal. Also stops match replays from being saved. +skip_replays = False +# Skip the kickoff countdown +start_without_countdown = False +# What should we do if you click run while a match is already in progress? +existing_match_behavior = Restart If Different +# If True, the framework will wait for outputs from all bots before advancing to the next frame. +enable_lockstep = False + +[Mutator Configuration] +# Match Length +Match Length = 5 Minutes +# 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 = Unlimited +# 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 = src\main\python\javaExample.cfg +participant_config_1 = src\main\python\javaExample.cfg +participant_config_2 = src/main/python/javaExample.cfg +participant_config_3 = src/main/python/javaExample.cfg +participant_config_4 = src/main/python/javaExample.cfg +participant_config_5 = src/main/python/javaExample.cfg +participant_config_6 = src/main/python/javaExample.cfg +participant_config_7 = src/main/python/javaExample.cfg +participant_config_8 = src/main/python/javaExample.cfg +participant_config_9 = src/main/python/javaExample.cfg +participant_config_10 = None +participant_config_11 = None +participant_config_12 = None +participant_config_13 = None +participant_config_14 = None +participant_config_15 = None +participant_config_16 = None +participant_config_17 = None +participant_config_18 = None +participant_config_19 = None +participant_config_20 = None +participant_config_21 = None +participant_config_22 = None +participant_config_23 = None +participant_config_24 = None +participant_config_25 = None +participant_config_26 = None +participant_config_27 = None +participant_config_28 = None +participant_config_29 = None +participant_config_30 = None +participant_config_31 = None +participant_config_32 = None +participant_config_33 = None +participant_config_34 = None +participant_config_35 = None +participant_config_36 = None +participant_config_37 = None +participant_config_38 = None +participant_config_39 = None +participant_config_40 = None +participant_config_41 = None +participant_config_42 = None +participant_config_43 = None +participant_config_44 = None +participant_config_45 = None +participant_config_46 = None +participant_config_47 = None +participant_config_48 = None +participant_config_49 = None +participant_config_50 = None +participant_config_51 = None +participant_config_52 = None +participant_config_53 = None +participant_config_54 = None +participant_config_55 = None +participant_config_56 = None +participant_config_57 = None +participant_config_58 = None +participant_config_59 = None +participant_config_60 = None +participant_config_61 = None +participant_config_62 = None +participant_config_63 = None + +# 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 +participant_team_10 = 0 +participant_team_11 = 0 +participant_team_12 = 0 +participant_team_13 = 0 +participant_team_14 = 0 +participant_team_15 = 0 +participant_team_16 = 0 +participant_team_17 = 0 +participant_team_18 = 0 +participant_team_19 = 0 +participant_team_20 = 0 +participant_team_21 = 0 +participant_team_22 = 0 +participant_team_23 = 0 +participant_team_24 = 0 +participant_team_25 = 0 +participant_team_26 = 0 +participant_team_27 = 0 +participant_team_28 = 0 +participant_team_29 = 0 +participant_team_30 = 0 +participant_team_31 = 0 +participant_team_32 = 0 +participant_team_33 = 0 +participant_team_34 = 0 +participant_team_35 = 0 +participant_team_36 = 0 +participant_team_37 = 0 +participant_team_38 = 0 +participant_team_39 = 0 +participant_team_40 = 0 +participant_team_41 = 0 +participant_team_42 = 0 +participant_team_43 = 0 +participant_team_44 = 0 +participant_team_45 = 0 +participant_team_46 = 0 +participant_team_47 = 0 +participant_team_48 = 0 +participant_team_49 = 0 +participant_team_50 = 0 +participant_team_51 = 0 +participant_team_52 = 0 +participant_team_53 = 0 +participant_team_54 = 0 +participant_team_55 = 0 +participant_team_56 = 0 +participant_team_57 = 0 +participant_team_58 = 0 +participant_team_59 = 0 +participant_team_60 = 0 +participant_team_61 = 0 +participant_team_62 = 0 +participant_team_63 = 0 + +# 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 = rlbot +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 +participant_type_10 = rlbot +participant_type_11 = rlbot +participant_type_12 = rlbot +participant_type_13 = rlbot +participant_type_14 = rlbot +participant_type_15 = rlbot +participant_type_16 = rlbot +participant_type_17 = rlbot +participant_type_18 = rlbot +participant_type_19 = rlbot +participant_type_20 = rlbot +participant_type_21 = rlbot +participant_type_22 = rlbot +participant_type_23 = rlbot +participant_type_24 = rlbot +participant_type_25 = rlbot +participant_type_26 = rlbot +participant_type_27 = rlbot +participant_type_28 = rlbot +participant_type_29 = rlbot +participant_type_30 = rlbot +participant_type_31 = rlbot +participant_type_32 = rlbot +participant_type_33 = rlbot +participant_type_34 = rlbot +participant_type_35 = rlbot +participant_type_36 = rlbot +participant_type_37 = rlbot +participant_type_38 = rlbot +participant_type_39 = rlbot +participant_type_40 = rlbot +participant_type_41 = rlbot +participant_type_42 = rlbot +participant_type_43 = rlbot +participant_type_44 = rlbot +participant_type_45 = rlbot +participant_type_46 = rlbot +participant_type_47 = rlbot +participant_type_48 = rlbot +participant_type_49 = rlbot +participant_type_50 = rlbot +participant_type_51 = rlbot +participant_type_52 = rlbot +participant_type_53 = rlbot +participant_type_54 = rlbot +participant_type_55 = rlbot +participant_type_56 = rlbot +participant_type_57 = rlbot +participant_type_58 = rlbot +participant_type_59 = rlbot +participant_type_60 = rlbot +participant_type_61 = rlbot +participant_type_62 = rlbot +participant_type_63 = 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 +participant_bot_skill_10 = 1.0 +participant_bot_skill_11 = 1.0 +participant_bot_skill_12 = 1.0 +participant_bot_skill_13 = 1.0 +participant_bot_skill_14 = 1.0 +participant_bot_skill_15 = 1.0 +participant_bot_skill_16 = 1.0 +participant_bot_skill_17 = 1.0 +participant_bot_skill_18 = 1.0 +participant_bot_skill_19 = 1.0 +participant_bot_skill_20 = 1.0 +participant_bot_skill_21 = 1.0 +participant_bot_skill_22 = 1.0 +participant_bot_skill_23 = 1.0 +participant_bot_skill_24 = 1.0 +participant_bot_skill_25 = 1.0 +participant_bot_skill_26 = 1.0 +participant_bot_skill_27 = 1.0 +participant_bot_skill_28 = 1.0 +participant_bot_skill_29 = 1.0 +participant_bot_skill_30 = 1.0 +participant_bot_skill_31 = 1.0 +participant_bot_skill_32 = 1.0 +participant_bot_skill_33 = 1.0 +participant_bot_skill_34 = 1.0 +participant_bot_skill_35 = 1.0 +participant_bot_skill_36 = 1.0 +participant_bot_skill_37 = 1.0 +participant_bot_skill_38 = 1.0 +participant_bot_skill_39 = 1.0 +participant_bot_skill_40 = 1.0 +participant_bot_skill_41 = 1.0 +participant_bot_skill_42 = 1.0 +participant_bot_skill_43 = 1.0 +participant_bot_skill_44 = 1.0 +participant_bot_skill_45 = 1.0 +participant_bot_skill_46 = 1.0 +participant_bot_skill_47 = 1.0 +participant_bot_skill_48 = 1.0 +participant_bot_skill_49 = 1.0 +participant_bot_skill_50 = 1.0 +participant_bot_skill_51 = 1.0 +participant_bot_skill_52 = 1.0 +participant_bot_skill_53 = 1.0 +participant_bot_skill_54 = 1.0 +participant_bot_skill_55 = 1.0 +participant_bot_skill_56 = 1.0 +participant_bot_skill_57 = 1.0 +participant_bot_skill_58 = 1.0 +participant_bot_skill_59 = 1.0 +participant_bot_skill_60 = 1.0 +participant_bot_skill_61 = 1.0 +participant_bot_skill_62 = 1.0 +participant_bot_skill_63 = 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 = None +participant_loadout_config_1 = None +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 +participant_loadout_config_10 = None +participant_loadout_config_11 = None +participant_loadout_config_12 = None +participant_loadout_config_13 = None +participant_loadout_config_14 = None +participant_loadout_config_15 = None +participant_loadout_config_16 = None +participant_loadout_config_17 = None +participant_loadout_config_18 = None +participant_loadout_config_19 = None +participant_loadout_config_20 = None +participant_loadout_config_21 = None +participant_loadout_config_22 = None +participant_loadout_config_23 = None +participant_loadout_config_24 = None +participant_loadout_config_25 = None +participant_loadout_config_26 = None +participant_loadout_config_27 = None +participant_loadout_config_28 = None +participant_loadout_config_29 = None +participant_loadout_config_30 = None +participant_loadout_config_31 = None +participant_loadout_config_32 = None +participant_loadout_config_33 = None +participant_loadout_config_34 = None +participant_loadout_config_35 = None +participant_loadout_config_36 = None +participant_loadout_config_37 = None +participant_loadout_config_38 = None +participant_loadout_config_39 = None +participant_loadout_config_40 = None +participant_loadout_config_41 = None +participant_loadout_config_42 = None +participant_loadout_config_43 = None +participant_loadout_config_44 = None +participant_loadout_config_45 = None +participant_loadout_config_46 = None +participant_loadout_config_47 = None +participant_loadout_config_48 = None +participant_loadout_config_49 = None +participant_loadout_config_50 = None +participant_loadout_config_51 = None +participant_loadout_config_52 = None +participant_loadout_config_53 = None +participant_loadout_config_54 = None +participant_loadout_config_55 = None +participant_loadout_config_56 = None +participant_loadout_config_57 = None +participant_loadout_config_58 = None +participant_loadout_config_59 = None +participant_loadout_config_60 = None +participant_loadout_config_61 = None +participant_loadout_config_62 = None +participant_loadout_config_63 = None + + From 258a6917257e4848a4a3c6761ec497f8f140f8c8 Mon Sep 17 00:00:00 2001 From: Zach Date: Sun, 3 May 2020 02:07:16 -0400 Subject: [PATCH 2/2] fixing ball flip, fixing boost on kickoff, refactored packaging and added test controller --- src/main/java/fambot/FamBot07.java | 12 +- src/main/java/fambot/FamBotMemory.java | 33 ----- .../java/fambot/actions/FamBotActions.java | 90 ++++++++++++++ .../java/fambot/actions/FamBotKickoffs.java | 81 +++++++++++++ src/main/java/fambot/boost/BoostManager.java | 4 + .../java/fambot/controller/Controller.java | 44 +++++++ .../fambot/controller/DefaultController.java | 19 +-- .../java/fambot/controller/FamBotActions.java | 114 ------------------ .../fambot/controller/TestController.java | 35 ++++++ .../java/fambot/output/ControlsOutput.java | 2 + src/main/java/fambot/util/DebugDrawer.java | 19 ++- 11 files changed, 286 insertions(+), 167 deletions(-) delete mode 100644 src/main/java/fambot/FamBotMemory.java create mode 100644 src/main/java/fambot/actions/FamBotActions.java create mode 100644 src/main/java/fambot/actions/FamBotKickoffs.java create mode 100644 src/main/java/fambot/controller/Controller.java delete mode 100644 src/main/java/fambot/controller/FamBotActions.java create mode 100644 src/main/java/fambot/controller/TestController.java diff --git a/src/main/java/fambot/FamBot07.java b/src/main/java/fambot/FamBot07.java index 03df8c3..063ca19 100644 --- a/src/main/java/fambot/FamBot07.java +++ b/src/main/java/fambot/FamBot07.java @@ -1,8 +1,8 @@ package fambot; import fambot.boost.BoostManager; -import fambot.controller.DefaultController; -import fambot.controller.FamBotActions; +import fambot.controller.Controller; +import fambot.controller.TestController; import fambot.input.DataPacket; import fambot.output.ControlsOutput; import fambot.util.DebugDrawer; @@ -13,7 +13,7 @@ public class FamBot07 implements Bot { private final int playerIndex; - private FamBotMemory memory = new FamBotMemory(); + private Controller controller = new TestController(); public FamBot07(int playerIndex) { this.playerIndex = playerIndex; @@ -25,16 +25,16 @@ public FamBot07(int playerIndex) { */ private ControlsOutput processInput(DataPacket input) { //overwrite the incorrect touch from the previous goal or reset + System.out.println(input.gameInfo.isKickoffPause()); if (input.gameInfo.isKickoffPause()) { - memory.resetKickoff(); input.ball.hasBeenTouched = false; } // This is optional! DebugDrawer.drawDebugLines(this, input); - DefaultController.setState(input); - return DefaultController.getControl(input, memory); + controller.setState(input); + return controller.getControl(input); } diff --git a/src/main/java/fambot/FamBotMemory.java b/src/main/java/fambot/FamBotMemory.java deleted file mode 100644 index 47f816c..0000000 --- a/src/main/java/fambot/FamBotMemory.java +++ /dev/null @@ -1,33 +0,0 @@ -package fambot; - -import fambot.boost.BoostPad; - -public class FamBotMemory { - private int kickoffJumpTimer = 0; - private BoostPad kickoffBoost = null; - - public int getKickoffJumpTimer() { - return kickoffJumpTimer; - } - - public void incrementKickoffJumpTimer() { - kickoffJumpTimer++; - } - - public void resetKickoffJumpTimer() { - kickoffJumpTimer = 0; - } - - public BoostPad getKickoffBoost() { - return kickoffBoost; - } - - public void setKickoffBoost(BoostPad kickoffBoost) { - this.kickoffBoost = kickoffBoost; - } - - public void resetKickoff() { - resetKickoffJumpTimer(); - setKickoffBoost(null); - } -} diff --git a/src/main/java/fambot/actions/FamBotActions.java b/src/main/java/fambot/actions/FamBotActions.java new file mode 100644 index 0000000..0a6c98d --- /dev/null +++ b/src/main/java/fambot/actions/FamBotActions.java @@ -0,0 +1,90 @@ +package fambot.actions; + +import fambot.boost.BoostManager; +import fambot.boost.BoostPad; +import fambot.controller.Controller; +import fambot.input.DataPacket; +import fambot.input.ball.BallData; +import fambot.input.car.CarData; +import fambot.output.ControlsOutput; +import fambot.vector.Vector2; +import rlbot.cppinterop.RLBotDll; +import rlbot.flat.QuickChatSelection; + +public class FamBotActions { + public static ControlsOutput getNearestLargeBoost(DataPacket input) { + CarData car = input.car; + + BoostPad pad = BoostManager.nearestBoost(car.position.flatten(), true, true); + + return new ControlsOutput() + .withSteer(steer2d(car, pad.getLocation().flatten())) + .withThrottle(1); + } + + public static ControlsOutput ballChase(DataPacket input) { + BallData ball = input.ball; + CarData car = input.car; + + return new ControlsOutput() + .withSteer(steer2d(car, ball.position.flatten())) + .withThrottle(1) + .withBoost(true); + } + + public static ControlsOutput ballChaseWithFlip(DataPacket input, Controller controller) { + BallData ball = input.ball; + CarData car = input.car; + + double distance = car.position.flatten().distance(ball.position.flatten()); + if (distance < 400) { + return flipAtBall(car, ball, controller, 6); + + } else { + return new ControlsOutput() + .withSteer(steer2d(car, ball.position.flatten())) + .withThrottle(1) + .withBoost(true); + } + } + + //TODO implement leading with targetDir + protected static float steer2d(CarData car, Vector2 targetPos) { + Vector2 pointer = targetPos.minus(car.position.flatten()); + double radians = car.velocity.flatten().correctionAngle(pointer); + //System.out.println("ID: " + Thread.currentThread().getId() + "\tSteering Radians: " + radians); + return -4 * (float) Math.max(-.25, Math.min(radians, .25)); + } + + public static void spamChat(int playerIndex) { + RLBotDll.sendQuickChat(playerIndex, false, QuickChatSelection.Compliments_NiceOne); + } + + protected static ControlsOutput flipAtBall(CarData car, BallData ball, Controller controller, int flipDelay) { + if (car.hasWheelContact) { + System.out.println("ID: " + Thread.currentThread().getId() + "\tInitial Jump"); + controller.resetJumpTimer(); + return new ControlsOutput() + .withJump(); + + } else { + if (controller.getJumpTimer() > flipDelay) { + Vector2 pointer = ball.position.flatten().minus(car.position.flatten()); + double radians = car.orientation.noseVector.flatten().correctionAngle(pointer); + float pitch = (float) -Math.cos(radians); + float yaw = (float) -Math.sin(radians); + //System.out.println("ID: " + Thread.currentThread().getId() + "\tJump Flip\tPitch: " + pitch + "\tYaw: " + yaw + "\tRadians: " + radians); + return new ControlsOutput() + .withPitch(pitch) + .withYaw(yaw) + .withJump(); + + } else { + //System.out.println("ID: " + Thread.currentThread().getId() + "\tJump Pre Flip\t Counter: " + controller.getJumpTimer()); + controller.incrementJumpTimer(); + return new ControlsOutput() + .withJump(false); + } + } + } +} diff --git a/src/main/java/fambot/actions/FamBotKickoffs.java b/src/main/java/fambot/actions/FamBotKickoffs.java new file mode 100644 index 0000000..8a7a8a9 --- /dev/null +++ b/src/main/java/fambot/actions/FamBotKickoffs.java @@ -0,0 +1,81 @@ +package fambot.actions; + +import fambot.boost.BoostManager; +import fambot.boost.BoostPad; +import fambot.controller.Controller; +import fambot.input.DataPacket; +import fambot.input.ball.BallData; +import fambot.input.car.CarData; +import fambot.output.ControlsOutput; +import fambot.vector.Vector2; + +public class FamBotKickoffs { + private static final int[][] kickoffBoosts = { + {11}, //Blue Right 0 + {10}, //Blue Left 1 + {7, 13}, //Blue Back 2 + {22}, //Orange Right 3 + {23}, //Orange Left 4 + {26, 20} //Orange Back 5 + }; + //third value is the index of the corresponding boosts above + private static final int[][] kickoffLocations = { + {-2048, -2560, 0}, //Blue Right + {2048, -2560, 1}, //Blue Left + {0, -4608, 2}, //Blue Back + {-256, -3840, 2}, //Blue Back Right + {256, -3840, 2}, //Blue Back Left + {2048, 2560, 3}, //Orange Right + {-2048, 2560, 4}, //Orange Left + {0, 4608, 5}, //Orange Back + {256, 3840, 5}, //Orange Back Right + {-256, 3840, 5}, //Orange Back Left + }; + public static ControlsOutput kickoffKill(DataPacket input, Controller controller) { + CarData car = input.car; + BallData ball = input.ball; + + double distance = car.position.flatten().distance(ball.position.flatten()); + if (distance < 850) { + return FamBotActions.flipAtBall(car, ball, controller, 8); + + } else { + if(controller.getKickoffBoost() == -1) { + for (int i = 0; i < kickoffLocations.length; i++) { + double dist = car.position.flatten().distance(new Vector2(kickoffLocations[i][0], kickoffLocations[i][1])); + System.out.println("ID: " + Thread.currentThread().getId() + "\tKickoff Location Distance: " + dist); + if (dist < 1) { + controller.setKickoffLocation(i); + controller.setKickoffBoost(kickoffBoosts[kickoffLocations[i][2]][0]); + break; + } + } + } + + if(controller.getKickoffBoost() != -1) { + BoostPad pad = BoostManager.getBoosts().get(controller.getKickoffBoost()); + //check for active pad and change to second pad or ball as target + if (!pad.isActive()) { + if (kickoffBoosts[kickoffLocations[controller.getKickoffLocation()][2]].length > 1) { + controller.setKickoffBoost(kickoffBoosts[kickoffLocations[controller.getKickoffLocation()][2]][1]); + pad = BoostManager.getBoosts().get(controller.getKickoffBoost()); + } else { + controller.setKickoffLocation(-1); + controller.setKickoffBoost(-1); + return FamBotActions.ballChase(input); + } + } + float steer = FamBotActions.steer2d(car, pad.getLocation().flatten()); + return new ControlsOutput() + .withBoost() + .withThrottle(1) + .withSteer(steer); + + } else { + System.out.println("ID: " + Thread.currentThread().getId() + "\tKickoff Ball Chase"); + return FamBotActions.ballChase(input); + + } + } + } +} diff --git a/src/main/java/fambot/boost/BoostManager.java b/src/main/java/fambot/boost/BoostManager.java index ac3a8da..e726d46 100644 --- a/src/main/java/fambot/boost/BoostManager.java +++ b/src/main/java/fambot/boost/BoostManager.java @@ -30,6 +30,10 @@ public static List getFullBoosts() { public static List getSmallBoosts() { return smallBoosts; } + + public static List getBoosts() { + return orderedBoosts; + } private static void loadFieldInfo(FieldInfo fieldInfo) { diff --git a/src/main/java/fambot/controller/Controller.java b/src/main/java/fambot/controller/Controller.java new file mode 100644 index 0000000..1ea7ec3 --- /dev/null +++ b/src/main/java/fambot/controller/Controller.java @@ -0,0 +1,44 @@ +package fambot.controller; + +import fambot.input.DataPacket; +import fambot.output.ControlsOutput; + +public abstract class Controller { + public abstract void setState(DataPacket input); + public abstract ControlsOutput getControl(DataPacket input); + + private int jumpTimer = 0; + private int kickoffBoost = -1; //cooresponds to the boosts in kickoffBoosts in FamBotActions + private int kickoffLocation = -1; //cooresponds to the locations in kickoffLocations in FamBotActions + + public int getJumpTimer() { + return jumpTimer; + } + + public void incrementJumpTimer() { + jumpTimer++; + } + + public void resetJumpTimer() { + jumpTimer = 0; + } + + public int getKickoffBoost() { + return kickoffBoost; + } + + public void setKickoffBoost(int kickoffBoost) { + this.kickoffBoost = kickoffBoost; + } + + public int getKickoffLocation() { + return kickoffLocation; + } + + public void setKickoffLocation(int kickoffLocation) { + this.kickoffLocation = kickoffLocation; + } +} + + + diff --git a/src/main/java/fambot/controller/DefaultController.java b/src/main/java/fambot/controller/DefaultController.java index 388bba1..1c8664f 100644 --- a/src/main/java/fambot/controller/DefaultController.java +++ b/src/main/java/fambot/controller/DefaultController.java @@ -1,20 +1,21 @@ package fambot.controller; -import fambot.FamBotMemory; +import fambot.actions.FamBotActions; +import fambot.actions.FamBotKickoffs; import fambot.input.DataPacket; import fambot.output.ControlsOutput; -public class DefaultController { - private static String state = "default"; - - public static void setState(DataPacket input) { - System.out.println("ID: " + Thread.currentThread().getId() + "\tBall Touched: " + input.ball.hasBeenTouched); +public class DefaultController extends Controller{ + private String state = "default"; + + public void setState(DataPacket input) { if (!input.ball.hasBeenTouched) { state = "kickoff"; return; } if (input.ball.hasBeenTouched && state.equals("kickoff")) { + setKickoffBoost(-1); state = "default"; } @@ -27,7 +28,7 @@ public static void setState(DataPacket input) { } } - public static ControlsOutput getControl(DataPacket input, FamBotMemory memory) { + public ControlsOutput getControl(DataPacket input) { System.out.println("ID: " + Thread.currentThread().getId() + "\tState: " + state); ControlsOutput output = null; switch (state) { @@ -35,10 +36,10 @@ public static ControlsOutput getControl(DataPacket input, FamBotMemory memory) { output = FamBotActions.getNearestLargeBoost(input); break; case "kickoff": - output = FamBotActions.kickoff(input, memory); + output = FamBotKickoffs.kickoffKill(input, this); break; default: - output = FamBotActions.ballChase(input); + output = FamBotActions.ballChaseWithFlip(input, this); } return output; } diff --git a/src/main/java/fambot/controller/FamBotActions.java b/src/main/java/fambot/controller/FamBotActions.java deleted file mode 100644 index 1403d23..0000000 --- a/src/main/java/fambot/controller/FamBotActions.java +++ /dev/null @@ -1,114 +0,0 @@ -package fambot.controller; - -import fambot.FamBotMemory; -import fambot.boost.BoostManager; -import fambot.boost.BoostPad; -import fambot.input.DataPacket; -import fambot.input.ball.BallData; -import fambot.input.car.CarData; -import fambot.output.ControlsOutput; -import fambot.vector.Vector2; -import rlbot.cppinterop.RLBotDll; -import rlbot.flat.QuickChatSelection; - -public class FamBotActions { - public static void flyUp() { - // System.out.println("X: "+ ball3.x + "\tY: " + ball3.y + "\tZ: " + ball3.z); - -// if (ball3.z > 400) { -// return new ControlsOutput() -// .withJump() -// .withSteer(goLeft ? -1 : 1) -// .withThrottle(1); -// } -// return new ControlsOutput() -// .withSteer(goLeft ? -1 : 1) -// .withThrottle(1); - } - - public static ControlsOutput getNearestLargeBoost(DataPacket input) { - CarData car = input.car; - - BoostPad pad = BoostManager.nearestBoost(car.position.flatten(), true, true); - - return new ControlsOutput() - .withSteer(steer2d(car, pad.getLocation().flatten(), null)) - .withThrottle(1); - } - - public static ControlsOutput ballChase(DataPacket input) { - BallData ball = input.ball; - CarData car = input.car; - - return new ControlsOutput() - .withSteer(steer2d(car, ball.position.flatten(), ball.velocity.flatten())) - .withThrottle(1) - .withBoost(true); - } - - //TODO implement leading with targetDir - public static float steer2d(CarData car, Vector2 targetPos, Vector2 targetDir) { - Vector2 pointer = targetPos.minus(car.position.flatten()); - double radians = car.velocity.flatten().correctionAngle(pointer); - //System.out.println("ID: " + Thread.currentThread().getId() + "\tSteering Radians: " + radians); - return -5 * (float) Math.max(-.2, Math.min(radians, .2)); - } - - public static void spamChat(int playerIndex) { - RLBotDll.sendQuickChat(playerIndex, false, QuickChatSelection.Compliments_NiceOne); - } - - private static ControlsOutput hitBall(CarData car, BallData ball) { - return null; - } - - public static ControlsOutput kickoff(DataPacket input, FamBotMemory memory) { - CarData car = input.car; - BallData ball = input.ball; - - if (memory.getKickoffBoost() == null || !memory.getKickoffBoost().isActive()) { - memory.setKickoffBoost(BoostManager.nearestBoost(car.position.flatten(), false, true)); - if (car.position.flatten().distance(ball.position.flatten()) < car.position.flatten().distance(memory.getKickoffBoost().getLocation().flatten())) { - memory.setKickoffBoost(null); - } - } - if (car.hasWheelContact) { - double distance = car.position.flatten().distance(ball.position.flatten()); - if (memory.getKickoffJumpTimer() == 0 && distance < 850) { - System.out.println("ID: " + Thread.currentThread().getId() + "\tKickoff First Jump"); - memory.incrementKickoffJumpTimer(); - return new ControlsOutput() - .withJump() - .withThrottle(1); - - } else { - System.out.println("ID: " + Thread.currentThread().getId() + "\tBoostPad: " + (memory.getKickoffBoost() == null ? "null" : (memory.getKickoffBoost().isActive() ? "Active" : "Inactive"))); - if(false && memory.getKickoffBoost() != null && memory.getKickoffBoost().isActive()) { - System.out.println("ID: " + Thread.currentThread().getId() + "\tKickoff Boost"); - float steer = steer2d(input.car, memory.getKickoffBoost().getLocation().flatten(), null); - return new ControlsOutput() - .withBoost() - .withThrottle(1) - .withSteer(steer); - - } else { - System.out.println("ID: " + Thread.currentThread().getId() + "\tKickoff Ball Chase"); - return ballChase(input); - - } - } - } else { - if (memory.getKickoffJumpTimer() > 10) { - System.out.println("ID: " + Thread.currentThread().getId() + "\tKickoff Flip"); - return new ControlsOutput() - .withPitch(-1) - .withJump(); - - } else { - System.out.println("ID: " + Thread.currentThread().getId() + "\tKickoff Pre Flip\tTick Counter: " + memory.getKickoffJumpTimer()); - memory.incrementKickoffJumpTimer(); - return new ControlsOutput(); - } - } - } -} diff --git a/src/main/java/fambot/controller/TestController.java b/src/main/java/fambot/controller/TestController.java new file mode 100644 index 0000000..46004da --- /dev/null +++ b/src/main/java/fambot/controller/TestController.java @@ -0,0 +1,35 @@ +package fambot.controller; + +import fambot.actions.FamBotActions; +import fambot.input.DataPacket; +import fambot.output.ControlsOutput; + +public class TestController extends Controller{ + private String state = "default"; + private int count = 0; + + public void setState(DataPacket input) { + System.out.println(count++); + if (count > 150 && count < 300) { + state = "test"; + } + + if (count > 300) { + count = 0; + state = "default"; + } + } + + public ControlsOutput getControl(DataPacket input) { + System.out.println("ID: " + Thread.currentThread().getId() + "\tState: " + state); + ControlsOutput output = null; + switch (state) { + case "test": + output = null;//FamBotActions.flipAtBall(input.car, input.ball, this, 6); + break; + default: + output = new ControlsOutput(); + } + return output; + } +} diff --git a/src/main/java/fambot/output/ControlsOutput.java b/src/main/java/fambot/output/ControlsOutput.java index 718b3ca..0f2e024 100644 --- a/src/main/java/fambot/output/ControlsOutput.java +++ b/src/main/java/fambot/output/ControlsOutput.java @@ -60,6 +60,7 @@ public ControlsOutput withThrottle(float throttle) { public ControlsOutput withJump(boolean jumpDepressed) { this.jumpDepressed = jumpDepressed; + System.out.println(this.jumpDepressed); return this; } @@ -80,6 +81,7 @@ public ControlsOutput withUseItem(boolean useItemDepressed) { public ControlsOutput withJump() { this.jumpDepressed = true; + System.out.println(this.jumpDepressed); return this; } diff --git a/src/main/java/fambot/util/DebugDrawer.java b/src/main/java/fambot/util/DebugDrawer.java index 2b39488..04b915a 100644 --- a/src/main/java/fambot/util/DebugDrawer.java +++ b/src/main/java/fambot/util/DebugDrawer.java @@ -4,8 +4,10 @@ import fambot.FamBot07; import fambot.input.DataPacket; +import fambot.input.ball.BallData; import fambot.input.car.CarData; import fambot.prediction.BallPredictionHelper; +import fambot.vector.Vector2; import rlbot.cppinterop.RLBotDll; import rlbot.cppinterop.RLBotInterfaceException; import rlbot.flat.BallPrediction; @@ -18,21 +20,28 @@ public class DebugDrawer { */ public static void drawDebugLines(FamBot07 bot, DataPacket input) { CarData car = input.car; + BallData ball = input.ball; // Here's an example of rendering debug data on the screen. Renderer renderer = BotLoopRenderer.forBotLoop(bot); // Draw a line from the car to the ball - renderer.drawLine3d(Color.LIGHT_GRAY, car.position, input.ball.position); + renderer.drawLine3d(Color.LIGHT_GRAY, car.position, ball.position); // Draw a line that points out from the nose of the car. renderer.drawLine3d(Color.BLUE, car.position.plus(car.orientation.noseVector.scaled(150)), car.position.plus(car.orientation.noseVector.scaled(300))); + + // Draw a the angle in radians between the car and ball + Vector2 pointer = ball.position.flatten().minus(car.position.flatten()); + double radians = car.orientation.noseVector.flatten().correctionAngle(pointer); + Color color =car.team == 0 ? Color.BLUE : Color.ORANGE; + renderer.drawString3d("" + radians, color, car.position, 2, 2); - if (input.ball.hasBeenTouched) { - float lastTouchTime = car.elapsedSeconds - input.ball.latestTouch.gameSeconds; - Color touchColor = input.ball.latestTouch.team == 0 ? Color.BLUE : Color.ORANGE; - renderer.drawString3d((int) lastTouchTime + "s", touchColor, input.ball.position, 2, 2); + if (ball.hasBeenTouched) { + float lastTouchTime = car.elapsedSeconds - ball.latestTouch.gameSeconds; + Color touchColor = ball.latestTouch.team == 0 ? Color.BLUE : Color.ORANGE; + renderer.drawString3d((int) lastTouchTime + "s", touchColor, ball.position, 2, 2); } try {