1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
#![allow(missing_docs)] use crate::flat; pub use flat::TileState; use smallvec::SmallVec; /// The inputs that control a car. #[derive(Default)] pub struct ControllerState { /// -1 for full reverse, 1 for full forward pub throttle: f32, /// -1 for full left, 1 for full right pub steer: f32, /// -1 for nose down, 1 for nose up pub pitch: f32, /// -1 for full left, 1 for full right pub yaw: f32, /// -1 for roll left, 1 for roll right pub roll: f32, /// true if you want to press the jump button pub jump: bool, /// true if you want to press the boost button pub boost: bool, /// true if you want to press the handbrake button pub handbrake: bool, } pub struct Vector3 { pub x: f32, pub y: f32, pub z: f32, } /// Expresses the rotation state of an object in Euler angles, with values in /// radians. pub struct Rotator { pub pitch: f32, pub yaw: f32, pub roll: f32, } /// Expresses the rotation state of an object. /// Learn about quaternions here: https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation /// You can tinker with them here to build an intuition: https://quaternions.online/ pub struct Quaternion { pub x: f32, pub y: f32, pub z: f32, pub w: f32, } /// Represents contact between a car and the ball. pub struct Touch { /// The name of the player involved with the touch. pub player_name: String, /// Seconds that had elapsed in the game when the touch occurred. pub game_seconds: f32, /// The point of contact for the touch. pub location: Vector3, /// The direction of the touch. pub normal: Vector3, /// The Team which the touch belongs to, 0 for blue 1 for orange. pub team: i32, pub(crate) _non_exhaustive: (), } pub struct ScoreInfo { pub score: i32, pub goals: i32, pub own_goals: i32, pub assists: i32, pub saves: i32, pub shots: i32, pub demolitions: i32, pub(crate) _non_exhaustive: (), } pub struct Physics { pub location: Vector3, pub rotation: Rotator, pub velocity: Vector3, pub angular_velocity: Vector3, pub(crate) _non_exhaustive: (), } pub struct PlayerInfo { pub physics: Physics, pub score_info: ScoreInfo, pub is_demolished: bool, /// True if your wheels are on the ground, the wall, or the ceiling. False /// if you're midair or turtling. pub has_wheel_contact: bool, pub is_supersonic: bool, pub is_bot: bool, /// True if the player has jumped. Falling off the ceiling / driving off the /// goal post does not count. pub jumped: bool, /// True if player has double jumped. False does not mean you have a jump /// remaining, because the aerial timer can run out, and that doesn't /// affect this flag. pub double_jumped: bool, pub name: String, pub team: i32, pub boost: i32, pub(crate) _non_exhaustive: (), } pub struct DropshotBallInfo { pub absorbed_force: f32, pub damage_index: i32, pub force_accum_recent: f32, pub(crate) _non_exhaustive: (), } pub struct BallInfo { pub physics: Physics, pub latest_touch: Option<Touch>, pub dropshot_info: Option<DropshotBallInfo>, pub(crate) _non_exhaustive: (), } pub struct BoostPadState { /// True if the boost can be picked up pub is_active: bool, /// The number of seconds since the boost has been picked up, or 0.0 if the /// boost is active. pub timer: f32, pub(crate) _non_exhaustive: (), } pub struct DropshotTile { pub tile_state: TileState, pub(crate) _non_exhaustive: (), } pub struct GameInfo { pub seconds_elapsed: f32, pub game_time_remaining: f32, pub is_overtime: bool, pub is_unlimited_time: bool, /// True when cars are allowed to move, and during the pause menu. False /// during replays. pub is_round_active: bool, /// True when the clock is paused due to kickoff, but false during kickoff /// countdown. In other words, it is true while cars can move during /// kickoff. Note that if both players sit still, game clock start and this /// will become false. pub is_kickoff_pause: bool, /// Turns true after final replay, the moment the 'winner' screen appears. /// Remains true during next match countdown. Turns false again the /// moment the 'choose team' screen appears. pub is_match_ended: bool, pub world_gravity_z: f32, /// Game speed multiplier, 1.0 is regular game speed. pub game_speed: f32, pub(crate) _non_exhaustive: (), } pub struct TeamInfo { pub team_index: i32, /// number of goals scored. pub score: i32, pub(crate) _non_exhaustive: (), } pub struct GameTickPacket { pub players: SmallVec<[PlayerInfo; 4]>, // Until generic const lands in Rust, we're limited to array sizes handpicked by smallvec. // Ideally this would be 34: pub boost_pad_states: SmallVec<[BoostPadState; 36]>, /// Info about the ball. This is usually present, but can be `None` at these /// times: /// /// - Briefly at the start of a goal replay /// - During PodiumSpotlight when the winning team is (ideally) celebrating. /// - Possibly at other times not during normal gameplay. pub ball: Option<BallInfo>, pub game_info: GameInfo, /// The state of each dropshot tile. This will be `None` if the current game /// is not a Dropshot game. // Ideally this would be 140: pub tile_information: Option<SmallVec<[DropshotTile; 256]>>, pub teams: SmallVec<[TeamInfo; 2]>, pub(crate) _non_exhaustive: (), } pub(crate) fn build_update_player_input( player_index: i32, controller_state: &ControllerState, ) -> flatbuffers::FlatBufferBuilder<'static> { let mut builder = flatbuffers::FlatBufferBuilder::new_with_capacity(64); let controller_state_args = flat::ControllerStateArgs { throttle: controller_state.throttle, steer: controller_state.steer, pitch: controller_state.pitch, yaw: controller_state.yaw, roll: controller_state.roll, jump: controller_state.jump, boost: controller_state.boost, handbrake: controller_state.handbrake, }; let controller_state = flat::ControllerState::create(&mut builder, &controller_state_args); let args = flat::PlayerInputArgs { playerIndex: player_index, controllerState: Some(controller_state), }; let player_input = flat::PlayerInput::create(&mut builder, &args); builder.finish(player_input, None); builder }