Skip to main content

rocketsim/sim/arena/
arena_events.rs

1use glam::Vec3A;
2
3use crate::RaycastHitInfo;
4
5/// Ball touched a static surface this tick (wall, floor, ceiling, goal mesh).
6///
7/// `contact_point` is in uu, `contact_normal` points off the surface.
8#[derive(Debug, Copy, Clone)]
9pub struct BallHitWorldEvent {
10    pub contact_point: Vec3A,
11    pub contact_normal: Vec3A,
12}
13
14/// A car touched the ball this tick.
15///
16/// `extra_hit_vel` (uu/s) is the additional velocity from the car's hit
17/// impulse (on top of the physics-solver bounce). Zero when the contact
18/// added no extra impulse (e.g. repeated-contact guard).
19#[derive(Debug, Copy, Clone)]
20pub struct CarHitBallEvent {
21    pub car_idx: usize,
22    pub contact_point: Vec3A,
23    pub extra_hit_vel: Vec3A,
24}
25
26/// Two cars collided this tick (tested both directions).
27///
28/// `is_demo == true` means the victim was demolished; otherwise a bump
29/// impulse was cached for the victim. See [`crate::MutatorConfig`] demo rules.
30#[derive(Debug, Copy, Clone)]
31pub struct CarHitCarEvent {
32    pub bumper_car_idx: usize,
33    pub victim_car_idx: usize,
34    pub contact_point: Vec3A,
35    pub is_demo: bool,
36}
37
38/// A car touched a static surface; also stored as
39/// `CarState::world_contact_normal` for that tick.
40#[derive(Debug, Copy, Clone)]
41pub struct CarHitWorldEvent {
42    pub car_idx: usize,
43    pub contact_point: Vec3A,
44    pub contact_normal: Vec3A,
45}
46
47/// A car collected a boost pad (`boost_pad_idx` matches
48/// `Arena::get_boost_pad_config` order).
49#[derive(Debug, Copy, Clone)]
50pub struct CarPickupBoostEvent {
51    pub car_idx: usize,
52    pub boost_pad_idx: usize,
53}
54
55/// A car's `is_on_ground` flipped `false` → `true` this tick.
56///
57/// `wheels` is a copy of [`crate::CarState::wheels_with_contact`] at landing
58/// (at least 3 entries are `Some`; the rest are airborne wheels).
59#[derive(Debug, Copy, Clone)]
60pub struct CarLandedEvent {
61    pub car_idx: usize,
62    pub wheels: [Option<RaycastHitInfo>; 4],
63}
64
65/// One tick's contact/pickup notifications.
66///
67/// Returned by [`crate::Arena::step_tick`] and
68/// [`crate::Arena::get_last_step_events`]; valid only until the next tick.
69#[derive(Debug, Copy, Clone)]
70pub enum ArenaEvent {
71    BallHitWorld(BallHitWorldEvent),
72    CarHitBall(CarHitBallEvent),
73    CarHitCar(CarHitCarEvent),
74    CarHitWorld(CarHitWorldEvent),
75    CarPickupBoost(CarPickupBoostEvent),
76    CarLanded(CarLandedEvent),
77}
78
79//////////////////////////////////////
80
81#[derive(Debug, Clone)]
82pub(crate) struct ArenaEventList {
83    events: Vec<ArenaEvent>,
84}
85
86impl ArenaEventList {
87    const STARTING_CAPACITY: usize = 12;
88
89    pub fn new() -> Self {
90        Self {
91            events: Vec::with_capacity(Self::STARTING_CAPACITY),
92        }
93    }
94
95    pub fn push(&mut self, event: ArenaEvent) {
96        self.events.push(event);
97    }
98
99    pub fn events(&self) -> &[ArenaEvent] {
100        &self.events
101    }
102
103    pub fn clear(&mut self) {
104        self.events.clear();
105    }
106}