/* Hurry Curry! - a game about cooking Copyright 2024 Miner34 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::simple::State; use crate::{algos::simple::Context, pathfinding::Path, BotAlgo, BotInput}; use hurrycurry_client_lib::Game; use hurrycurry_protocol::{glam::IVec2, ItemIndex, PlayerID}; #[derive(Default)] pub struct DishWasher { path: Option<(Path, IVec2, f32)>, cooldown: f32, dirty_plate: Option, } type LogicRes = Result; impl BotAlgo for DishWasher { fn tick(&mut self, me: PlayerID, game: &Game, dt: f32) -> BotInput { if self.dirty_plate.is_none() { self.dirty_plate = game.data.get_item_by_name("dirty-plate"); if self.dirty_plate.is_none() { return BotInput::default(); } } let Some(player) = game.players.get(&me) else { return BotInput::default(); }; let pos = player.movement.position; if self.cooldown > 0. { self.cooldown -= dt; return BotInput::default(); } if let Some((path, target, down)) = &mut self.path { let direction = path.next_direction(pos, dt); let arrived = path.is_done(); let target = *target; if arrived { *down -= dt; if *down < 0. { self.path = None; self.cooldown = 0.2; } } return BotInput { direction, boost: false, interact: if arrived { Some(target) } else { None }, ..Default::default() }; } Context { game, own_position: pos.as_ivec2(), me, state: self, recursion_abort: 0, } .update() .ok(); BotInput::default() } } impl State for DishWasher { fn cooldown(&mut self, dur: f32) { self.cooldown += dur } fn queue_segment(&mut self, path: Path, tile: IVec2, duration: f32) { self.path = Some((path, tile, duration)); } fn get_empty_tile_priority(&self) -> &'static [&'static str] { &["counter-window", "counter"] } } impl Context<'_, DishWasher> { fn update(&mut self) -> LogicRes { if let Some(sink) = self.find_empty_interactable_tile_by_name("sink") { if let Some(pos) = self.find_item_on_map(self.state.dirty_plate.unwrap()) { self.assert_tile_is_clear(pos)?; } if self.is_hand_item(self.state.dirty_plate.unwrap()) { // TODO clear sink first but dont "steal" items from others working there self.interact_with(sink, 2.0)?; } else { self.assert_hand_is_clear()?; } } else { self.assert_hand_is_clear()?; } Ok(()) } }