fixed digging
This commit is contained in:
parent
3bb2344671
commit
25322aab0e
4 changed files with 48 additions and 9 deletions
|
@ -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)]
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 {
|
||||||
break 'route;
|
if world.garbage(next_position.pos).await {
|
||||||
|
self.execute(dbg!(recent.dig(next_position.pos))?).await;
|
||||||
|
} else {
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue