diff options
| author | metamuffin <metamuffin@disroot.org> | 2025-10-20 20:11:02 +0200 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2025-10-20 20:11:02 +0200 |
| commit | a52785f4869a09e05417f97aff1c0d5b19587463 (patch) | |
| tree | 9d288a969a6da19ddb2848ac18a22f9d3c1879b7 /server/src/entity/bot.rs | |
| parent | f8d95d074c36ec35eee8def73b8d9f2b83c922cb (diff) | |
| download | hurrycurry-a52785f4869a09e05417f97aff1c0d5b19587463.tar hurrycurry-a52785f4869a09e05417f97aff1c0d5b19587463.tar.bz2 hurrycurry-a52785f4869a09e05417f97aff1c0d5b19587463.tar.zst | |
Refactor bot input to packet based
Diffstat (limited to 'server/src/entity/bot.rs')
| -rw-r--r-- | server/src/entity/bot.rs | 106 |
1 files changed, 57 insertions, 49 deletions
diff --git a/server/src/entity/bot.rs b/server/src/entity/bot.rs index 51a09b62..36f701ec 100644 --- a/server/src/entity/bot.rs +++ b/server/src/entity/bot.rs @@ -17,77 +17,85 @@ */ use super::{Entity, EntityContext}; use anyhow::Result; -use hurrycurry_bot::{BotAlgo, DynBotAlgo}; +use hurrycurry_bot::{BotAlgo, DynBotAlgo, PacketSink}; use hurrycurry_locale::TrError; -use hurrycurry_protocol::{Character, Hand, ItemLocation, PacketS, PlayerClass, PlayerID}; +use hurrycurry_protocol::{Character, PacketS, PlayerClass, PlayerID}; use log::debug; use std::any::Any; pub type DynBotDriver = BotDriver<DynBotAlgo>; -pub struct BotDriver<T> { - algo: T, - join_data: Option<(String, Character, PlayerClass)>, - id: PlayerID, - interacting: bool, - left: bool, +pub enum BotDriver<T> { + Joining { + name: String, + character: Character, + class: PlayerClass, + constructor: Option<Box<dyn FnOnce(PlayerID) -> T + Send + Sync>>, + }, + Running { + state: T, + id: PlayerID, + }, + Left, } impl<T: BotAlgo> BotDriver<T> { - pub fn new(name: String, character: Character, class: PlayerClass, algo: T) -> Self { - Self { - algo, - id: PlayerID(0), - interacting: false, - join_data: Some((name, character, class)), - left: false, + pub fn new( + name: String, + character: Character, + class: PlayerClass, + constructor: impl FnOnce(PlayerID) -> T + 'static + Send + Sync, + ) -> Self { + Self::Joining { + character, + class, + constructor: Some(Box::new(constructor)), + name, } } } impl<T: BotAlgo + Any> Entity for BotDriver<T> { fn finished(&self) -> bool { - self.left + matches!(self, Self::Left) } fn tick(&mut self, c: EntityContext<'_>) -> Result<(), TrError> { - if let Some((name, character, class)) = self.join_data.take() { - self.id = c.game.get_unused_player_id(); // TODO clashes when multiple bots join in the same tick - debug!("join {}", self.id); - c.packet_in.push_back(PacketS::Join { + match self { + BotDriver::Joining { name, character, - id: Some(self.id), class, - position: None, - }) + constructor, + } => { + let id = c.game.get_unused_player_id(); // TODO clashes when multiple bots join in the same tick + debug!("enter {id}"); + c.packet_in.push_back(PacketS::Join { + name: name.to_string(), + character: *character, + id: Some(id), + class: *class, + position: None, + }); + *self = BotDriver::Running { + state: constructor.take().unwrap()(id), + id, + }; + Ok(()) + } + BotDriver::Running { state, id } => { + state.tick(PacketSink::new(c.packet_in), c.game, c.dt); + if state.is_finished() { + debug!("leave {id}"); + c.packet_in.push_back(PacketS::Leave { player: *id }); + *self = BotDriver::Left + } + Ok(()) + } + BotDriver::Left => Ok(()), } - - let input = self.algo.tick(self.id, c.game, c.dt); - if input.leave { - debug!("leave {}", self.id); - c.packet_in.push_back(PacketS::Leave { player: self.id }); - self.left = true; - return Ok(()); - } - if input.interact.is_some() != self.interacting { - self.interacting = input.interact.is_some(); - c.packet_in.push_back(PacketS::Interact { - player: self.id, - target: input.interact.map(ItemLocation::Tile), - hand: Hand(0), - }) - } - c.packet_in.push_back(PacketS::Movement { - player: self.id, - dir: input.direction, - boost: input.boost, - pos: None, - }); - c.packet_in.extend(input.extra); - Ok(()) } fn destructor(&mut self, c: EntityContext<'_>) { - if self.join_data.is_none() && !self.left { - c.packet_in.push_back(PacketS::Leave { player: self.id }) + if let Self::Running { id, .. } = self { + c.packet_in.push_back(PacketS::Leave { player: *id }) } } } |