/* 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 . */ use super::{Entity, EntityContext}; use anyhow::Result; use hurrycurry_bot::{BotAlgo, DynBotAlgo}; use hurrycurry_protocol::{PacketS, PlayerID}; use log::info; use rand::random; pub type DynBotDriver = BotDriver; pub struct BotDriver { algo: T, join_data: Option<(String, i32)>, id: PlayerID, interacting: bool, left: bool, } impl BotDriver { 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 Entity for BotDriver { fn finished(&self) -> bool { self.left } 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, }); 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 }) } } }