Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions RLBotPack/sideswipe/sideswipe.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Locations]
script_file = ./sideswipe.py
name = SideSwipe

[Details]
developer = Eastvillage
description = Rocket League SideSwipe is Psyonix' mobile port of Rocket League. This script will emulate SideSwipe by forcing all players and the ball onto the YZ-plane. It is recommended to use the mutator Boost Amount: Recharge (fast) due to the lack of boost pads in the middle. Supports up to 5v5.
fun_fact = Actually better than the real SideSwipe
github https://github.com/NicEastvillage/SideSwipe
language = Python
93 changes: 93 additions & 0 deletions RLBotPack/sideswipe/sideswipe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import math
import random
from time import sleep

from rlbot.agents.base_script import BaseScript
from rlbot.utils.game_state_util import GameState, CarState, Physics, Vector3, BallState, Rotator

from vec import Vec3


class Tron(BaseScript):
def __init__(self):
super().__init__("SideSwipe")
self.is_kickoff = False
self.is_replay = True
self.last_score = (0, 0)

def run(self):
while True:
packet = self.wait_game_tick_packet()

ball_pos = Vec3(packet.game_ball.physics.location)

car_states = {}
for index in range(packet.num_cars):
car = packet.game_cars[index]
pos = Vec3(car.physics.location)
vel = Vec3(car.physics.velocity)
new_pos = pos.yz()
new_vel = vel.yz()
car_state = CarState(Physics(location=new_pos.desired(), velocity=new_vel.desired()))
car_states[index] = car_state

if ball_pos.x == 0 and ball_pos.y == 0 and 90 < ball_pos.z < 96 and packet.game_info.is_kickoff_pause:
# Kickoff
if not self.is_kickoff:
# It was not kickoff previous frame

car_states = self.setup_kickoff(packet)

self.is_kickoff = True
self.is_replay = False
else:
self.is_kickoff = False

ball = packet.game_ball
pos = Vec3(ball.physics.location)
vel = Vec3(ball.physics.velocity)

ball_state = BallState(Physics(location=pos.yz().desired(), velocity=vel.yz().desired()))

game_state = GameState(cars=car_states, ball=ball_state)
if not self.is_replay:
self.set_game_state(game_state)

new_score = (packet.teams[0].score, packet.teams[1].score)
if new_score != self.last_score:
self.is_replay = True
self.last_score = new_score

def setup_kickoff(self, packet):
indexes = list(range(5))
index_shuffle_table = {}
for i in range(5):
s = random.choice(indexes)
indexes.remove(s)
index_shuffle_table[i] = s

next_blue = 0
next_orange = 0
car_states = {}
for index in range(packet.num_cars):
car = packet.game_cars[index]
pos_index = index_shuffle_table[next_blue] if car.team == 0 else index_shuffle_table[next_orange]
y = 5000 - pos_index * 500

if car.team == 0:
kickoff_pos = Vec3(0, -y, 25)
yaw = math.pi / 2.0
next_blue += 1
else:
kickoff_pos = Vec3(0, y, 25)
yaw = -math.pi / 2.0
next_orange += 1

car_state = CarState(Physics(location=kickoff_pos.desired(), rotation=Rotator(yaw=yaw)))
car_states[index] = car_state
return car_states


if __name__ == "__main__":
script = Tron()
script.run()
71 changes: 71 additions & 0 deletions RLBotPack/sideswipe/vec.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import math
import random

from rlbot.utils.game_state_util import Vector3


class Vec3:
def __init__(self, x: float or 'Vec3'=0.0, y: float=0.0, z: float=0.0):
if hasattr(x, 'x'):
# We have been given a vector. Copy it
self.x = float(x.x)
self.y = float(x.y) if hasattr(x, 'y') else 0
self.z = float(x.z) if hasattr(x, 'z') else 0
else:
self.x = float(x)
self.y = float(y)
self.z = float(z)

def __getitem__(self, item: int):
return (self.x, self.y, self.z)[item]

def __add__(self, other: 'Vec3') -> 'Vec3':
return Vec3(self.x + other.x, self.y + other.y, self.z + other.z)

def __sub__(self, other: 'Vec3') -> 'Vec3':
return Vec3(self.x - other.x, self.y - other.y, self.z - other.z)

def __neg__(self) -> 'Vec3':
return Vec3(-self.x, -self.y, -self.z)

def __mul__(self, scale: float) -> 'Vec3':
return Vec3(self.x * scale, self.y * scale, self.z * scale)

def __rmul__(self, scale: float) -> 'Vec3':
return self * scale

def __truediv__(self, scale: float) -> 'Vec3':
scale = 1 / float(scale)
return self * scale

def __str__(self):
return "Vec3(" + str(self.x) + ", " + str(self.y) + ", " + str(self.z) + ")"

def dot(self, other: 'Vec3') -> float:
return self.x * other.x + self.y * other.y + self.z * other.z

def mag2(self) -> float:
return self.dot(self)

def mag(self) -> float:
return math.sqrt(self.mag2())

def longer_than(self, magnitude: float) -> bool:
return magnitude * magnitude < self.mag2()

def unit(self) -> 'Vec3':
return self / self.mag()

def yz(self):
return Vec3(0, self.y, self.z)

def desired(self):
return Vector3(self.x, self.y, self.z)

@staticmethod
def random() -> 'Vec3':
return Vec3(
1 - 2 * random.random(),
1 - 2 * random.random(),
1 - 2 * random.random(),
)
46 changes: 46 additions & 0 deletions RLBotPack/tron/orientation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import math

from vec import Vec3


# This is a helper class for calculating directions relative to your car. You can extend it or delete if you want.
class Orientation:
"""
This class describes the orientation of an object from the rotation of the object.
Use this to find the direction of cars: forward, right, up.
It can also be used to find relative locations.
"""

def __init__(self, rotation):
self.yaw = float(rotation.yaw)
self.roll = float(rotation.roll)
self.pitch = float(rotation.pitch)

cr = math.cos(self.roll)
sr = math.sin(self.roll)
cp = math.cos(self.pitch)
sp = math.sin(self.pitch)
cy = math.cos(self.yaw)
sy = math.sin(self.yaw)

self.forward = Vec3(cp * cy, cp * sy, sp)
self.right = Vec3(cy*sp*sr-cr*sy, sy*sp*sr+cr*cy, -cp*sr)
self.up = Vec3(-cr*cy*sp-sr*sy, -cr*sy*sp+sr*cy, cp*cr)


# Sometimes things are easier, when everything is seen from your point of view.
# This function lets you make any location the center of the world.
# For example, set center to your car's location and ori to your car's orientation, then the target will be
# relative to your car!
def relative_location(center: Vec3, ori: Orientation, target: Vec3) -> Vec3:
"""
Returns target as a relative location from center's point of view, using the given orientation. The components of
the returned vector describes:
* x: how far in front
* y: how far right
* z: how far above
"""
x = (target - center).dot(ori.forward)
y = (target - center).dot(ori.right)
z = (target - center).dot(ori.up)
return Vec3(x, y, z)
27 changes: 27 additions & 0 deletions RLBotPack/tron/particle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import random
from dataclasses import dataclass
from typing import List, Tuple

from vec import Vec3


@dataclass
class Particle:
size: int
pos: Vec3
vel: Vec3
acc: Vec3
drag: float
color: Tuple[int, int, int]
death_time: float

def update(self):
self.vel = (1 - self.drag) * self.vel + 0.008333 * self.acc
self.pos = self.pos + 0.008333 * self.vel

def render(self, renderer):
color = renderer.create_color(255, self.color[0], self.color[1], self.color[2])
renderer.draw_rect_3d(self.pos, self.size, self.size, True, color)
if random.random() < 0.25:
spark = self.pos + 6 * Vec3.random()
renderer.draw_line_3d(self.pos, spark, color)
1 change: 1 addition & 0 deletions RLBotPack/tron/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
playsound
7 changes: 7 additions & 0 deletions RLBotPack/tron/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

MAX_TRAIL_LENGTH = 200
IGNORE_BOT_COLLISION = True
IGNORE_HUMAN_COLLISION = False
IGNORE_BALL_COLLISION = False
PLAY_SOUNDS = False
MIN_SOUND_INTERVAL = 0.15
63 changes: 63 additions & 0 deletions RLBotPack/tron/sounds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import random
from time import time
from dataclasses import dataclass
from pathlib import Path
from threading import Thread

from playsound import playsound

from settings import MIN_SOUND_INTERVAL, PLAY_SOUNDS


@dataclass
class TrailHitSound:
file: Path
strength_min: float
strength_max: float


class SoundPlayer:
def __init__(self):
path = Path(__file__).parent / "sounds"
self.trail_ball_hit_sounds = [
TrailHitSound(path / "electro hum.wav", 100, 400),
TrailHitSound(path / "electro hum 2.wav", 100, 400),
TrailHitSound(path / "electro hum 3.wav", 300, 600),
TrailHitSound(path / "electro bounce light.wav", 500, 900),
TrailHitSound(path / "electro bounce light 2.wav", 400, 800),
TrailHitSound(path / "electro bounce medium.wav", 700, 1600),
TrailHitSound(path / "electro bounce heavy.wav", 1600, 3000),
]
self.trail_car_hit_sounds = [
TrailHitSound(path / "electro hum.wav", 100, 400),
TrailHitSound(path / "electro hum 2.wav", 100, 400),
TrailHitSound(path / "electro hum 3.wav", 300, 600),
TrailHitSound(path / "electro crash light.wav", 500, 900),
TrailHitSound(path / "electro crash light 2.wav", 400, 800),
TrailHitSound(path / "electro crash medium.wav", 700, 1600),
TrailHitSound(path / "electro crash heavy.wav", 1600, 3000),
]
self.last_sound_time = time()

def ball_hit(self, strength):
if not PLAY_SOUNDS:
return
sounds = list(filter(lambda s: s.strength_min <= strength <= s.strength_max, self.trail_ball_hit_sounds))
if len(sounds) > 0 and self.last_sound_time < time() - MIN_SOUND_INTERVAL:
sound_file = random.choice(sounds).file
Thread(target=playsound, args=[str(sound_file)]).start()
self.last_sound_time = time()

def car_hit(self, strength):
if not PLAY_SOUNDS:
return
sounds = list(filter(lambda s: s.strength_min <= strength <= s.strength_max, self.trail_car_hit_sounds))
if len(sounds) > 0 and self.last_sound_time < time() - MIN_SOUND_INTERVAL:
sound_file = random.choice(sounds).file
Thread(target=playsound, args=[str(sound_file)]).start()
self.last_sound_time = time()


if __name__ == '__main__':
sounds = SoundPlayer()
sounds.ball_hit(400)
Binary file added RLBotPack/tron/sounds/electro bounce heavy.wav
Binary file not shown.
Binary file added RLBotPack/tron/sounds/electro bounce light 2.wav
Binary file not shown.
Binary file added RLBotPack/tron/sounds/electro bounce light.wav
Binary file not shown.
Binary file added RLBotPack/tron/sounds/electro bounce medium.wav
Binary file not shown.
Binary file added RLBotPack/tron/sounds/electro crash heavy.wav
Binary file not shown.
Binary file added RLBotPack/tron/sounds/electro crash light 2.wav
Binary file not shown.
Binary file added RLBotPack/tron/sounds/electro crash light.wav
Binary file not shown.
Binary file added RLBotPack/tron/sounds/electro crash medium.wav
Binary file not shown.
Binary file added RLBotPack/tron/sounds/electro hum 2.wav
Binary file not shown.
Binary file added RLBotPack/tron/sounds/electro hum 3.wav
Binary file not shown.
Binary file added RLBotPack/tron/sounds/electro hum.wav
Binary file not shown.
Loading