dfs on ore find & ignore fluids in pathfinding
This commit is contained in:
parent
7d9cd93d1c
commit
7d2d85169f
4 changed files with 59 additions and 19 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, paths};
|
use crate::{turtle::TurtleCommand, paths::{self, TRANSPARENT}};
|
||||||
|
|
||||||
pub type WorldReadLock = OwnedRwLockReadGuard<RTree<Block>>;
|
pub type WorldReadLock = OwnedRwLockReadGuard<RTree<Block>>;
|
||||||
|
|
||||||
|
@ -30,9 +30,9 @@ impl World {
|
||||||
self.state.write().await.insert(block);
|
self.state.write().await.insert(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if a known non-air block exists at the point
|
/// Returns true if a known non-traversable block exists at the point
|
||||||
pub async fn occupied(&self, block: Vec3) -> bool {
|
pub async fn occupied(&self, block: Vec3) -> bool {
|
||||||
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| !TRANSPARENT.contains(&b.name.as_str()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if a "garbage" block exists at the given point which you are free to destroy
|
/// Returns true if a "garbage" block exists at the given point which you are free to destroy
|
||||||
|
|
|
@ -212,11 +212,12 @@ async fn run_command(
|
||||||
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<Vec3>,
|
Json(req): Json<(Vec3, Position, Position)>,
|
||||||
) -> &'static str {
|
) -> &'static str {
|
||||||
let turtle = state.read().await.get_turtle(id).await.unwrap();
|
let turtle = state.read().await.get_turtle(id).await.unwrap();
|
||||||
let fuel = Position::new(Vec3::new(-19, 93, 73), blocks::Direction::East);
|
let (req, fuel, inventory) = req;
|
||||||
let inventory = Position::new(Vec3::new(-19, 92, 73), blocks::Direction::East);
|
//let fuel = Position::new(Vec3::new(-19, 93, 73), blocks::Direction::East);
|
||||||
|
//let inventory = Position::new(Vec3::new(-19, 92, 73), blocks::Direction::East);
|
||||||
tokio::spawn(
|
tokio::spawn(
|
||||||
async move {
|
async move {
|
||||||
mine::mine(turtle.clone(), req, fuel, inventory).await
|
mine::mine(turtle.clone(), req, fuel, inventory).await
|
||||||
|
|
|
@ -130,8 +130,9 @@ impl TurtleTask for TurtleMineJob {
|
||||||
use TurtleCommand::*;
|
use TurtleCommand::*;
|
||||||
|
|
||||||
/// Things to leave in the field (not worth fuel)
|
/// Things to leave in the field (not worth fuel)
|
||||||
const USELESS: [&str; 4] = [
|
const USELESS: [&str; 5] = [
|
||||||
"minecraft:dirt",
|
"minecraft:dirt",
|
||||||
|
"minecraft:gravel",
|
||||||
"minecraft:cobblestone",
|
"minecraft:cobblestone",
|
||||||
"minecraft:cobbled_deepslate",
|
"minecraft:cobbled_deepslate",
|
||||||
"minecraft:diorite",
|
"minecraft:diorite",
|
||||||
|
@ -150,17 +151,13 @@ pub async fn mine(turtle: TurtleCommander, pos: Vec3, fuel: Position, storage: P
|
||||||
loop {
|
loop {
|
||||||
mine_chunk(turtle.clone(), pos, chunk).await?;
|
mine_chunk(turtle.clone(), pos, chunk).await?;
|
||||||
|
|
||||||
turtle.world().lock().await
|
valuables.append(&mut near_valuables(&turtle, pos, chunk).await);
|
||||||
.locate_within_distance(pos.into(), chunk.map(|n| n.pow(2)).sum())
|
|
||||||
.filter(|n| n.name != "minecraft:air")
|
|
||||||
.filter(|n| VALUABLE.iter().any(|v| n.name.contains(v)))
|
|
||||||
.map(|b|b.pos).collect_into(&mut valuables);
|
|
||||||
|
|
||||||
dump_filter(turtle.clone(), |i| USELESS.iter().any(|u| **u == i.name)).await;
|
|
||||||
|
|
||||||
while let Some(block) = valuables.pop() {
|
while let Some(block) = valuables.pop() {
|
||||||
let near = turtle.goto_adjacent(block).await?;
|
let near = turtle.goto_adjacent(block).await?;
|
||||||
turtle.execute(dbg!(near.dig(block))?).await;
|
turtle.execute(dbg!(near.dig(block))?).await;
|
||||||
|
observe(turtle.clone(), block).await;
|
||||||
|
valuables.append(&mut near_valuables(&turtle, near.pos, Vec3::new(2,2,2)).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (turtle.fuel().await as f64) < (volume + (fuel.pos-turtle.pos().await.pos).abs().sum()) as f64 * 1.1 {
|
if (turtle.fuel().await as f64) < (volume + (fuel.pos-turtle.pos().await.pos).abs().sum()) as f64 * 1.1 {
|
||||||
|
@ -169,7 +166,7 @@ pub async fn mine(turtle: TurtleCommander, pos: Vec3, fuel: Position, storage: P
|
||||||
refuel(turtle.clone()).await;
|
refuel(turtle.clone()).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let turtle::TurtleCommandResponse::Item(_) = turtle.execute(ItemInfo(13)).await.ret {
|
if dump_filter(turtle.clone(), |i| USELESS.iter().any(|u| **u == i.name)).await > 13 {
|
||||||
println!("storage rtb");
|
println!("storage rtb");
|
||||||
turtle.goto(storage).await?;
|
turtle.goto(storage).await?;
|
||||||
dump(turtle.clone()).await;
|
dump(turtle.clone()).await;
|
||||||
|
@ -179,6 +176,14 @@ pub async fn mine(turtle: TurtleCommander, pos: Vec3, fuel: Position, storage: P
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn near_valuables(turtle: &TurtleCommander, pos: Vec3, chunk: Vec3) -> Vec<Vec3> {
|
||||||
|
turtle.world().lock().await
|
||||||
|
.locate_within_distance(pos.into(), chunk.map(|n| n.pow(2)).sum())
|
||||||
|
.filter(|n| n.name != "minecraft:air")
|
||||||
|
.filter(|n| VALUABLE.iter().any(|v| n.name.contains(v)))
|
||||||
|
.map(|b|b.pos).collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn mine_chunk(turtle: TurtleCommander, pos: Vec3, chunk: Vec3) -> Option<()> {
|
pub async fn mine_chunk(turtle: TurtleCommander, pos: Vec3, chunk: Vec3) -> Option<()> {
|
||||||
let turtle = turtle.clone();
|
let turtle = turtle.clone();
|
||||||
let volume = chunk.x * chunk.y * chunk.z;
|
let volume = chunk.x * chunk.y * chunk.z;
|
||||||
|
@ -224,15 +229,20 @@ async fn dump(turtle: TurtleCommander) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dump all items that match the predicate
|
/// Dump all items that match the predicate
|
||||||
async fn dump_filter<F>(turtle: TurtleCommander, mut filter: F)
|
/// Returns the number of slots still full after the operation
|
||||||
|
async fn dump_filter<F>(turtle: TurtleCommander, mut filter: F) -> u32
|
||||||
where F: FnMut(InventorySlot) -> bool {
|
where F: FnMut(InventorySlot) -> bool {
|
||||||
|
let mut counter = 0;
|
||||||
for i in 1..=16 {
|
for i in 1..=16 {
|
||||||
if let TurtleCommandResponse::Item(item) = turtle.execute(Select(i)).await.ret {
|
if let TurtleCommandResponse::Item(item) = turtle.execute(Select(i)).await.ret {
|
||||||
if filter(item) {
|
if filter(item) {
|
||||||
turtle.execute(DropFront(64)).await;
|
turtle.execute(DropFront(64)).await;
|
||||||
|
} else {
|
||||||
|
counter += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
counter
|
||||||
}
|
}
|
||||||
|
|
||||||
/// zig from 0 to x and back, stopping on each end
|
/// zig from 0 to x and back, stopping on each end
|
||||||
|
@ -255,3 +265,26 @@ fn fill(scale: Vec3, n: i32) -> Vec3 {
|
||||||
step(n/scale.x/scale.y, scale.z)
|
step(n/scale.x/scale.y, scale.z)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Looks at all the blocks around the given pos
|
||||||
|
/// destructive
|
||||||
|
async fn observe(turtle: TurtleCommander, pos: Vec3) -> Option<()> {
|
||||||
|
let adjacent = [
|
||||||
|
pos,
|
||||||
|
pos + Vec3::y(),
|
||||||
|
pos + Vec3::x(),
|
||||||
|
pos + Vec3::z(),
|
||||||
|
pos - Vec3::x(),
|
||||||
|
pos - Vec3::z(),
|
||||||
|
pos - Vec3::y(),
|
||||||
|
];
|
||||||
|
|
||||||
|
for pos in adjacent {
|
||||||
|
if turtle.world().get(pos).await.is_none() {
|
||||||
|
turtle.goto_adjacent(pos).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
|
|
@ -35,8 +35,7 @@ where D: FnMut(&Position) -> bool {
|
||||||
move |p| next(p, &world),
|
move |p| next(p, &world),
|
||||||
|p1| (p1.pos - &to).abs().sum() as u32,
|
|p1| (p1.pos - &to).abs().sum() as u32,
|
||||||
done,
|
done,
|
||||||
)
|
)?;
|
||||||
.unwrap();
|
|
||||||
Some(route.0)
|
Some(route.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +73,13 @@ fn next(from: &Position, world: &WorldReadLock) -> Vec<(Position, u32)> {
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Blocks that you can go through without a pickaxe
|
||||||
|
pub const TRANSPARENT: [&str; 3] = [
|
||||||
|
"minecraft:air",
|
||||||
|
"minecraft:water",
|
||||||
|
"minecraft:lava",
|
||||||
|
];
|
||||||
|
|
||||||
/// Blocks that are fine to tunnel through
|
/// Blocks that are fine to tunnel through
|
||||||
const GARBAGE: [&str; 6] = [
|
const GARBAGE: [&str; 6] = [
|
||||||
"minecraft:stone",
|
"minecraft:stone",
|
||||||
|
@ -89,7 +95,7 @@ const UNKNOWN: Option<u32> = Some(2);
|
||||||
|
|
||||||
// time to go somewhere
|
// time to go somewhere
|
||||||
pub fn difficulty(name: &str) -> Option<u32> {
|
pub fn difficulty(name: &str) -> Option<u32> {
|
||||||
if name == "minecraft:air" {
|
if TRANSPARENT.contains(&name) {
|
||||||
return Some(1);
|
return Some(1);
|
||||||
};
|
};
|
||||||
if GARBAGE.contains(&name) {
|
if GARBAGE.contains(&name) {
|
||||||
|
|
Loading…
Reference in a new issue