diff options
author | metamuffin <metamuffin@disroot.org> | 2024-08-12 11:36:16 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-08-12 11:36:16 +0200 |
commit | 355ba85a62345883fb05609b1075208cc7aae0ea (patch) | |
tree | 37e8d099b2845a037319234f141031aadb7de68f | |
parent | 33f46bf3637ab2bec3dc0c84c7d6d29c0787f658 (diff) | |
download | hurrycurry-355ba85a62345883fb05609b1075208cc7aae0ea.tar hurrycurry-355ba85a62345883fb05609b1075208cc7aae0ea.tar.bz2 hurrycurry-355ba85a62345883fb05609b1075208cc7aae0ea.tar.zst |
bot: passive recipes, still buggy
-rw-r--r-- | server/bot/src/algos/simple.rs | 92 |
1 files changed, 84 insertions, 8 deletions
diff --git a/server/bot/src/algos/simple.rs b/server/bot/src/algos/simple.rs index 99f75780..af02f81e 100644 --- a/server/bot/src/algos/simple.rs +++ b/server/bot/src/algos/simple.rs @@ -6,7 +6,7 @@ use hurrycurry_client_lib::Game; use hurrycurry_protocol::{ glam::IVec2, ItemIndex, Message, PlayerID, Recipe, RecipeIndex, TileIndex, }; -use log::warn; +use log::{info, warn}; #[derive(Default)] pub struct Simple { @@ -61,6 +61,7 @@ impl BotAlgo for Simple { } .update() .ok(); + info!("target={:?}", self.path.as_ref().map(|a| a.1)); BotInput::default() } @@ -73,6 +74,13 @@ impl SimpleContext<'_> { .get(&self.me) .map_or(false, |p| p.item.as_ref().map_or(false, |i| i.kind == item)) } + pub fn is_hand_occupied(&self) -> bool { + self.game + .players + .get(&self.me) + .map(|p| p.item.is_some()) + .unwrap_or(false) + } fn find_demand(&self) -> Option<(ItemIndex, IVec2)> { self.game .players @@ -118,17 +126,44 @@ impl SimpleContext<'_> { .map(|(p, _)| *p) } fn find_empty_interactable_tile(&self) -> Option<IVec2> { + if let Some(t) = self + .game + .tiles + .iter() + .find(|(_, t)| { + self.game.data.tile_interact[t.kind.0] + && t.item.is_none() + && self.game.data.tile_names[t.kind.0] == "counter" + }) + .map(|(p, _)| *p) + { + return Some(t); + } self.game .tiles .iter() .find(|(_, t)| self.game.data.tile_interact[t.kind.0] && t.item.is_none()) .map(|(p, _)| *p) } - pub fn aquire_placed_item(&mut self, item: ItemIndex) -> LogicRes<IVec2> { - if let Some(pos) = self.find_item_on_map(item) { - return Ok(pos); + fn is_tile_occupied(&self, pos: IVec2) -> bool { + self.game + .tiles + .get(&pos) + .map(|t| t.item.is_some()) + .unwrap_or(true) + } + fn clear_tile(&mut self, pos: IVec2) -> LogicRes { + self.dispose_hand()?; + self.interact_with(pos, 0.) + } + fn assert_tile_is_clear(&mut self, pos: IVec2) -> LogicRes { + if self.is_tile_occupied(pos) { + self.clear_tile(pos)?; } - self.aquire_item(item)?; + Ok(()) + } + + pub fn dispose_hand(&mut self) -> LogicRes<IVec2> { if let Some(pos) = self.find_empty_interactable_tile() { if let Err(()) = self.interact_with(pos, 0.) { return Ok(pos); @@ -141,10 +176,20 @@ impl SimpleContext<'_> { Err(()) } } + pub fn aquire_placed_item(&mut self, item: ItemIndex) -> LogicRes<IVec2> { + if let Some(pos) = self.find_item_on_map(item) { + return Ok(pos); + } + self.aquire_item(item)?; + self.dispose_hand() + } pub fn aquire_item(&mut self, item: ItemIndex) -> LogicRes { if self.is_hand_item(item) { return Ok(()); } + if self.is_hand_occupied() { + self.dispose_hand()?; + } if let Some(pos) = self.find_item_on_map(item) { self.interact_with(pos, 0.)?; return Ok(()); @@ -155,10 +200,10 @@ impl SimpleContext<'_> { Recipe::Instant { tile: Some(tile), inputs: [None, None], - outputs: [Some(_), None], .. } => { if let Some(pos) = self.find_tile(*tile) { + self.assert_tile_is_clear(pos)?; self.interact_with(pos, 0.)?; } } @@ -171,14 +216,27 @@ impl SimpleContext<'_> { self.aquire_item(*b)?; self.interact_with(apos, 0.)?; } + Recipe::Instant { + tile: None, + inputs: [Some(input), None], + .. + } => { + self.aquire_item(*input)?; + if let Some(pos) = self.find_empty_interactable_tile() { + self.interact_with(pos, 0.)?; + } else { + warn!("no empty space left") + } + } Recipe::Active { tile: Some(tile), input, duration, .. } => { - self.aquire_item(*input)?; if let Some(pos) = self.find_tile(*tile) { + self.assert_tile_is_clear(pos)?; + self.aquire_item(*input)?; self.interact_with(pos, duration + 0.5)?; } } @@ -187,7 +245,24 @@ impl SimpleContext<'_> { input, .. } => { - + if let Some(pos) = self.find_tile(*tile) { + if let Some(item) = &self.game.tiles.get(&pos).unwrap().item { + if item.kind == *input { + info!("waiting for passive to finish at {pos}"); + return Err(()); // waiting for it to finish + // TODO check progress + } + } + self.aquire_item(*input)?; + self.interact_with(pos, 0.)?; + } + } + Recipe::Passive { + tile: None, input, .. + } => { + self.aquire_placed_item(*input)?; + info!("waiting for passive to finish"); + return Err(()); } _ => warn!("recipe too hard {r:?}"), } @@ -208,6 +283,7 @@ impl SimpleContext<'_> { } pub fn update(&mut self) -> LogicRes { if let Some((item, table)) = self.find_demand() { + self.assert_tile_is_clear(table)?; self.aquire_item(item)?; self.interact_with(table, 0.)?; } |