diff options
Diffstat (limited to 'server/bot/src/step.rs')
| -rw-r--r-- | server/bot/src/step.rs | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/server/bot/src/step.rs b/server/bot/src/step.rs new file mode 100644 index 00000000..001935ac --- /dev/null +++ b/server/bot/src/step.rs @@ -0,0 +1,121 @@ +/* + Hurry Curry! - a game about cooking + Copyright (C) 2025 Hurry Curry! Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + +*/ + +use crate::{ + PacketSink, + pathfinding::{Path, find_path_to_neighbour}, +}; +use hurrycurry_game_core::Game; +use hurrycurry_protocol::{Hand, ItemIndex, ItemLocation, PacketS, PlayerID, glam::IVec2}; + +pub struct StepState { + path: Path, + interact_position: IVec2, + destination_item: Option<ItemIndex>, + hand: Hand, + wait_timer: f32, + interact_start_pending: bool, + interact_stop_pending: bool, + me: PlayerID, +} + +impl StepState { + pub fn new_idle(me: PlayerID) -> Self { + Self::new_wait(me, 0.) + } + pub fn new_wait(me: PlayerID, timer: f32) -> Self { + Self { + destination_item: None, + interact_position: IVec2::ZERO, + hand: Hand(0), + interact_start_pending: false, + interact_stop_pending: false, + me, + path: Path::EMPTY, + wait_timer: timer, + } + } + pub fn new_segment( + game: &Game, + me: PlayerID, + hand: Hand, + pos: IVec2, + interact: f32, + ) -> Option<Self> { + let own_pos = game.players.get(&me)?.movement.position.as_ivec2(); + let path = find_path_to_neighbour(game, own_pos, pos)?; + Some(Self { + me, + path, + hand, + wait_timer: interact, + interact_stop_pending: true, + interact_start_pending: true, + interact_position: pos, + destination_item: game + .tiles + .get(&pos) + .and_then(|t| t.item.as_ref().map(|i| i.kind)), + }) + } + + pub fn is_busy(&self) -> bool { + self.wait_timer >= 0. || self.interact_stop_pending + } + + pub fn tick(&mut self, out: &mut PacketSink, game: &Game, dt: f32) { + if self.path.is_done() { + if self.interact_start_pending { + self.interact_start_pending = false; + out.push(PacketS::Interact { + player: self.me, + hand: self.hand, + target: Some(ItemLocation::Tile(self.interact_position)), + }); + } else { + if self.wait_timer < 0. { + if self.interact_stop_pending { + self.interact_stop_pending = false; + out.push(PacketS::Interact { + player: self.me, + hand: self.hand, + target: None, + }); + } + } else { + self.wait_timer -= dt; + } + } + } + + let position = game + .players + .get(&self.me) + .as_ref() + .map(|p| p.movement.position) + .unwrap_or_default(); + + let dir = self.path.next_direction(position, dt); + out.push(PacketS::Movement { + player: self.me, + dir, + boost: false, + pos: None, + }); + } +} |