diff options
Diffstat (limited to 'server/src/entity/bot.rs')
-rw-r--r-- | server/src/entity/bot.rs | 82 |
1 files changed, 77 insertions, 5 deletions
diff --git a/server/src/entity/bot.rs b/server/src/entity/bot.rs index 06477e8a..301dbca3 100644 --- a/server/src/entity/bot.rs +++ b/server/src/entity/bot.rs @@ -1,13 +1,85 @@ -use super::{EntityContext, Entity}; +/* + Hurry Curry! - a game about cooking + Copyright 2024 metamuffin + + 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 super::{Entity, EntityContext}; use anyhow::Result; -use hurrycurry_bot::BotAlgo; +use hurrycurry_bot::{BotAlgo, DynBotAlgo}; +use hurrycurry_protocol::{PacketS, PlayerID}; +use log::info; +use rand::random; + +pub type DynBotDriver = BotDriver<DynBotAlgo>; -pub struct BotDriver { - algo: Box<dyn BotAlgo>, +pub struct BotDriver<T> { + algo: T, + join_data: Option<(String, i32)>, + id: PlayerID, + interacting: bool, + pub left: bool, } -impl Entity for BotDriver { +impl<T: BotAlgo> BotDriver<T> { + pub fn new(name: String, character: i32, algo: T) -> Self { + Self { + algo, + id: PlayerID(0), + interacting: false, + join_data: Some((name, character)), + left: false, + } + } +} +impl<T: BotAlgo> Entity for BotDriver<T> { fn tick(&mut self, c: EntityContext<'_>) -> Result<()> { + if let Some((name, character)) = self.join_data.take() { + self.id = PlayerID(random()); // TODO bad code, can collide + info!("spawn {:?} ({name:?}, {character})", self.id); + c.packet_in.push_back(PacketS::Join { + name, + character, + id: Some(self.id), + }) + } + + let input = self.algo.tick(self.id, &c.game, c.dt); + if input.leave { + info!("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, + pos: input.interact, + }) + } + c.packet_in.push_back(PacketS::Movement { + player: self.id, + dir: input.direction, + boost: input.boost, + pos: None, + }); 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 }) + } + } } |