diff options
author | metamuffin <metamuffin@disroot.org> | 2024-09-14 16:21:37 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-09-14 16:21:37 +0200 |
commit | 26af8f970dd5d28faf0e8244112a50505018eae0 (patch) | |
tree | 4181e64fc44620f540347242c2935dc661cb1aeb /server | |
parent | 577c5324fa495adbde47a4d16bd39a4570a559b6 (diff) | |
download | hurrycurry-26af8f970dd5d28faf0e8244112a50505018eae0.tar hurrycurry-26af8f970dd5d28faf0e8244112a50505018eae0.tar.bz2 hurrycurry-26af8f970dd5d28faf0e8244112a50505018eae0.tar.zst |
bot: frank
Diffstat (limited to 'server')
-rw-r--r-- | server/bot/src/algos/frank.rs | 122 | ||||
-rw-r--r-- | server/bot/src/algos/mod.rs | 3 |
2 files changed, 125 insertions, 0 deletions
diff --git a/server/bot/src/algos/frank.rs b/server/bot/src/algos/frank.rs new file mode 100644 index 00000000..980d8c08 --- /dev/null +++ b/server/bot/src/algos/frank.rs @@ -0,0 +1,122 @@ +/* + 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 crate::{ + pathfinding::{find_path_to_neighbour, Path}, + BotAlgo, BotInput, +}; +use hurrycurry_client_lib::Game; +use hurrycurry_protocol::{glam::Vec2, Message, PacketS, PlayerID}; +use rand::{seq::IndexedRandom, thread_rng}; + +#[derive(Default)] +pub struct Frank { + sleep: f32, + idle: f32, + idle_dir: f32, + + target: Option<PlayerID>, + path: Option<Path>, +} + +const MESSAGES: &[fn(&str) -> String] = &[ + |_name| format!("Work faster, {_name}!"), + |_name| format!("Quick! There is no time for chit-chat!"), + |_name| format!("Look what a mess you've made! Clean this up immediatly!"), + |_name| format!("Don't let the customers starve!"), + |_name| format!("You are wasting me money, {_name}!"), + |_name| format!("I'm not paying you to stand around!"), + |_name| format!("Get back to work, {_name}!"), + |_name| format!("You're FIRED!"), +]; + +impl BotAlgo for Frank { + fn tick(&mut self, me: PlayerID, game: &Game, dt: f32) -> BotInput { + let Some(player) = game.players.get(&me) else { + return BotInput::default(); + }; + + if self.sleep > 0. { + self.sleep -= dt; + return BotInput::default(); + } + if self.idle > 0. { + self.idle -= dt; + self.idle_dir += self.idle.sin() * dt * (self.idle / 10.).fract() * 10.; + return BotInput { + direction: Vec2::from_angle(self.idle_dir), + ..Default::default() + }; + } + + let pos = player.movement.position; + + if let Some(target) = self.target { + if let Some(player) = game.players.get(&target) { + let tpos = player.movement.position; + + if let Some(path) = &mut self.path { + let direction = path.next_direction(pos, dt); + if path.is_stuck() { + self.path = None; + } else if path.is_done() { + self.path = None; + if pos.distance(tpos) < 2. { + self.sleep = 8.; + self.idle = 15.; + let message = MESSAGES.choose(&mut thread_rng()).unwrap()(&player.name); + return BotInput { + extra: vec![PacketS::Communicate { + player: me, + message: Some(Message::Text(message)), + timeout: Some(3.), + }], + ..Default::default() + }; + } + } else { + return BotInput { + direction, + boost: false, + interact: None, + ..Default::default() + }; + } + } else if let Some(path) = + find_path_to_neighbour(&game.walkable, pos.as_ivec2(), tpos.as_ivec2()) + { + self.path = Some(path); + } + } else { + self.target = None; + } + } else if let Some(target) = find_chef(game, me) { + self.target = Some(target); + } + BotInput::default() + } +} + +fn find_chef(game: &Game, me: PlayerID) -> Option<PlayerID> { + let chefs = game + .players + .iter() + .filter(|(i, p)| p.character >= 0 && **i != me) + .map(|(i, _)| *i) + .collect::<Vec<_>>(); + chefs.choose(&mut thread_rng()).copied() +} diff --git a/server/bot/src/algos/mod.rs b/server/bot/src/algos/mod.rs index 54cdd495..bb1d615b 100644 --- a/server/bot/src/algos/mod.rs +++ b/server/bot/src/algos/mod.rs @@ -19,15 +19,18 @@ mod customer; mod simple; mod test; mod waiter; +pub mod frank; pub use customer::Customer; pub use simple::Simple; pub use test::Test; pub use waiter::Waiter; +pub use frank::Frank; pub const ALGO_CONSTRUCTORS: &'static [(&'static str, fn() -> crate::DynBotAlgo)] = &[ ("test", || Box::new(Test::default())), ("simple", || Box::new(Simple::default())), ("waiter", || Box::new(Waiter::default())), ("customer", || Box::new(Customer::default())), + ("frank", || Box::new(Frank::default())), ]; |