1
Fork 0

fixed digging

This commit is contained in:
Andy Killorin 2023-12-19 18:13:08 -06:00
parent 3bb2344671
commit 25322aab0e
Signed by: ank
GPG key ID: B6241CA3B552BCA4
4 changed files with 48 additions and 9 deletions

View file

@ -5,7 +5,7 @@ use rstar::{self, PointDistance, RTree, RTreeObject, AABB};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::sync::{RwLock, RwLockReadGuard, OwnedRwLockReadGuard}; use tokio::sync::{RwLock, RwLockReadGuard, OwnedRwLockReadGuard};
use crate::turtle::TurtleCommand; use crate::{turtle::TurtleCommand, paths};
pub type WorldReadLock = OwnedRwLockReadGuard<RTree<Block>>; pub type WorldReadLock = OwnedRwLockReadGuard<RTree<Block>>;
@ -34,12 +34,17 @@ impl World {
self.state.read().await.locate_at_point(&block.into()).is_some_and(|b| b.name != "minecraft:air") self.state.read().await.locate_at_point(&block.into()).is_some_and(|b| b.name != "minecraft:air")
} }
/// Returns true if a "garbage" block exists at the given point which you are free to destroy
pub async fn garbage(&self, block: Vec3) -> bool {
self.state.read().await.locate_at_point(&block.into()).is_some_and(|b| paths::difficulty(&b.name).is_some())
}
pub async fn lock(self) -> WorldReadLock { pub async fn lock(self) -> WorldReadLock {
self.state.read_owned().await self.state.read_owned().await
} }
} }
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Block { pub struct Block {
pub name: String, pub name: String,
pub pos: Vec3, pub pos: Vec3,
@ -99,6 +104,26 @@ impl Position {
} }
} }
/// Command to dig
/// Assumes that "to" can be dug from your position
pub fn dig(&self, to: Vec3) -> Option<TurtleCommand> {
// manhattan distance of 1 required to dig
if (self.pos-to).abs().sum()!=1 {
return None;
}
// not covered: pointing away from to
Some(match self.pos.y - to.y {
0 => TurtleCommand::Dig,
1 => TurtleCommand::DigDown,
-1 => TurtleCommand::DigUp,
_ => None?
})
}
} }
#[derive(Serialize, Deserialize, Clone, Hash, PartialEq, Eq, Copy, Debug)] #[derive(Serialize, Deserialize, Clone, Hash, PartialEq, Eq, Copy, Debug)]

View file

@ -9,7 +9,7 @@ use axum::{
routing::{get, post}, routing::{get, post},
Json, Router, Json, Router,
}; };
use blocks::{World, Position}; use blocks::{World, Position, Vec3};
use mine::TurtleMineJob; use mine::TurtleMineJob;
use rstar::{self, AABB, RTree}; use rstar::{self, AABB, RTree};
@ -100,6 +100,7 @@ async fn main() -> Result<(), Error> {
.route("/turtle/:id/update", post(command)) .route("/turtle/:id/update", post(command))
.route("/turtle/client.lua", get(client)) .route("/turtle/client.lua", get(client))
.route("/turtle/:id/setGoal", post(set_goal)) .route("/turtle/:id/setGoal", post(set_goal))
.route("/turtle/:id/dig", post(dig))
.route("/turtle/:id/cancelTask", post(cancel)) .route("/turtle/:id/cancelTask", post(cancel))
.route("/turtle/:id/info", get(turtle_info)) .route("/turtle/:id/info", get(turtle_info))
//.route("/turtle/:id/placeUp", get(place_up)) //.route("/turtle/:id/placeUp", get(place_up))
@ -165,13 +166,13 @@ async fn place_up(
async fn dig( async fn dig(
Path(id): Path<u32>, Path(id): Path<u32>,
State(state): State<SharedControl>, State(state): State<SharedControl>,
Json(req): Json<Position>, Json(req): Json<Vec3>,
) -> &'static str { ) -> &'static str {
let turtle = state.read().await.get_turtle(id).await.unwrap(); let turtle = state.read().await.get_turtle(id).await.unwrap();
tokio::spawn( tokio::spawn(
async move { async move {
turtle.goto_adjacent(req.pos).await; let pos = turtle.goto_adjacent(req).await.unwrap();
turtle.execute(TurtleCommand::Dig).await turtle.execute(pos.dig(req).unwrap()).await
} }
); );

View file

@ -8,7 +8,9 @@ use pathfinding::prelude::astar;
pub async fn route_facing(from: Position, to: Vec3, world: &World) -> Option<Vec<Position>> { pub async fn route_facing(from: Position, to: Vec3, world: &World) -> Option<Vec<Position>> {
let facing = |p: &Position| { let facing = |p: &Position| {
let ahead = p.dir.unit() + p.pos; let ahead = p.dir.unit() + p.pos;
to == ahead let above = Vec3::y() + p.pos;
let below = -Vec3::y() + p.pos;
to == ahead || to == below || to == above
}; };
route_to(from, to, facing, world).await route_to(from, to, facing, world).await
} }
@ -87,7 +89,7 @@ const GARBAGE: [&str; 6] = [
const UNKNOWN: Option<u32> = Some(2); const UNKNOWN: Option<u32> = Some(2);
// time to go somewhere // time to go somewhere
fn difficulty(name: &str) -> Option<u32> { pub fn difficulty(name: &str) -> Option<u32> {
if name == "minecraft:air" { if name == "minecraft:air" {
return Some(1); return Some(1);
}; };

View file

@ -7,6 +7,7 @@ use crate::blocks::Vec3;
use crate::blocks::World; use crate::blocks::World;
use crate::blocks::nearest; use crate::blocks::nearest;
use crate::mine::TurtleMineJob; use crate::mine::TurtleMineJob;
use crate::paths;
use crate::paths::route_facing; use crate::paths::route_facing;
use anyhow::Ok; use anyhow::Ok;
@ -217,10 +218,19 @@ impl TurtleCommander {
// valid routes will explicitly tell you to break ground // valid routes will explicitly tell you to break ground
if world.occupied(next_position.pos).await { if world.occupied(next_position.pos).await {
if world.garbage(next_position.pos).await {
self.execute(dbg!(recent.dig(next_position.pos))?).await;
} else {
break 'route; break 'route;
} }
}
let state = self.execute(command).await; let state = self.execute(command).await;
if let TurtleCommandResponse::Failure = state.ret {
break 'route;
}
recent = state.pos; recent = state.pos;
} }
} }
@ -292,6 +302,7 @@ pub(crate) async fn process_turtle_update(
_ => {} _ => {}
} }
turtle.queued_movement = cmd.unit(turtle.position.dir); turtle.queued_movement = cmd.unit(turtle.position.dir);
println!("Turtle {}: {cmd:?}", turtle.name.to_str());
return Ok(cmd); return Ok(cmd);
} }
} }