diff options
Diffstat (limited to 'server/bot/src/pathfinding.rs')
| -rw-r--r-- | server/bot/src/pathfinding.rs | 69 |
1 files changed, 67 insertions, 2 deletions
diff --git a/server/bot/src/pathfinding.rs b/server/bot/src/pathfinding.rs index 4aa7c2ff..f9f213fa 100644 --- a/server/bot/src/pathfinding.rs +++ b/server/bot/src/pathfinding.rs @@ -15,10 +15,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ +use crate::PacketSink; use hurrycurry_game_core::Game; -use hurrycurry_protocol::glam::{IVec2, Vec2}; #[cfg(feature = "debug_events")] -use hurrycurry_protocol::{DebugEvent, DebugEventDisplay, PlayerID}; +use hurrycurry_protocol::{DebugEvent, DebugEventDisplay}; +use hurrycurry_protocol::{ + PacketS, PlayerID, + glam::{IVec2, Vec2}, +}; use log::{debug, trace}; use std::{ cmp::Ordering, @@ -30,13 +34,39 @@ use std::{ pub struct Path { segments: Vec<Vec2>, seg_time: f32, + last_dir: Vec2, + last_boost: bool, } impl Path { pub const EMPTY: Path = Path { seg_time: 0., segments: Vec::new(), + last_boost: false, + last_dir: Vec2::ZERO, }; + pub fn update( + &mut self, + out: &mut PacketSink, + player: PlayerID, + position: Vec2, + dt: f32, + speed: f32, + allow_boost: bool, + ) { + let dir = speed * self.next_direction(position, dt); + let boost = allow_boost && self.is_stuck(0.5); + if dir.distance(self.last_dir) > 0.1 || boost != self.last_boost { + self.last_dir = dir; + self.last_boost = boost; + out.push(PacketS::Movement { + player, + dir, + boost, + pos: None, + }); + } + } pub fn next_direction(&mut self, position: Vec2, dt: f32) -> Vec2 { if let Some(next) = self.segments.last().copied() { trace!("next {next}"); @@ -171,5 +201,40 @@ pub fn find_path(game: &Game, from: IVec2, to: IVec2) -> Option<Path> { Some(Path { segments, seg_time: 0., + last_boost: false, + last_dir: Vec2::ZERO, }) } + +#[derive(Debug, Clone)] +pub struct HoldLocation { + target: Vec2, + facing: Vec2, + last_dir: Vec2, +} +impl HoldLocation { + pub fn new(target: Vec2, facing: Vec2) -> Self { + Self { + facing, + target, + last_dir: Vec2::ZERO, + } + } + pub fn update(&mut self, out: &mut PacketSink, player: PlayerID, pos: Vec2) { + let diff = (self.target + 0.5) - pos; + let dir = match diff.length() { + x if x < 0.3 => self.facing.clamp_length_max(1.) * 0.4, // TODO rotation not updating + x if x < 1.0 => diff.normalize() * 0.6, + _ => diff.normalize(), + }; + if dir.distance(self.last_dir) > 0.1 { + self.last_dir = dir; + out.push(PacketS::Movement { + player, + dir, + boost: false, + pos: None, + }); + } + } +} |