automatic arbor
This commit is contained in:
parent
4c75d7e451
commit
2378e9a846
4 changed files with 79 additions and 8 deletions
|
@ -105,6 +105,17 @@ impl Position {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Command to place
|
||||||
|
/// Assumes that "to" can be reached from your position
|
||||||
|
pub fn place(&self, to: Vec3) -> Option<TurtleCommand> {
|
||||||
|
Some(match self.dig(to)? {
|
||||||
|
TurtleCommand::Dig => TurtleCommand::Place,
|
||||||
|
TurtleCommand::DigDown => TurtleCommand::PlaceDown,
|
||||||
|
TurtleCommand::DigUp => TurtleCommand::PlaceUp,
|
||||||
|
_ => None?
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Command to dig
|
/// Command to dig
|
||||||
/// Assumes that "to" can be dug from your position
|
/// Assumes that "to" can be dug from your position
|
||||||
pub fn dig(&self, to: Vec3) -> Option<TurtleCommand> {
|
pub fn dig(&self, to: Vec3) -> Option<TurtleCommand> {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use log::{warn, info};
|
use log::{warn, info, trace};
|
||||||
use tokio::sync::{Mutex, OwnedMutexGuard};
|
use tokio::sync::{Mutex, OwnedMutexGuard};
|
||||||
|
|
||||||
use crate::{blocks::Position, turtle::TurtleCommander};
|
use crate::{blocks::Position, turtle::TurtleCommander};
|
||||||
|
@ -28,6 +28,7 @@ impl Depots {
|
||||||
|
|
||||||
pub async fn dock(&self, turtle: TurtleCommander) -> Option<usize> {
|
pub async fn dock(&self, turtle: TurtleCommander) -> Option<usize> {
|
||||||
let depot = self.clone().nearest(turtle.pos().await).await?;
|
let depot = self.clone().nearest(turtle.pos().await).await?;
|
||||||
|
trace!("depot at {depot:?}");
|
||||||
turtle.goto(*depot).await?;
|
turtle.goto(*depot).await?;
|
||||||
|
|
||||||
// dump inventory
|
// dump inventory
|
||||||
|
@ -39,7 +40,7 @@ impl Depots {
|
||||||
// refuel
|
// refuel
|
||||||
turtle.execute(Select(1)).await;
|
turtle.execute(Select(1)).await;
|
||||||
let limit = turtle.fuel_limit();
|
let limit = turtle.fuel_limit();
|
||||||
while turtle.fuel() < limit {
|
while turtle.fuel() + 1000 < limit {
|
||||||
turtle.execute(SuckFront(64)).await;
|
turtle.execute(SuckFront(64)).await;
|
||||||
let re = turtle.execute(Refuel).await;
|
let re = turtle.execute(Refuel).await;
|
||||||
turtle.execute(DropDown(64)).await;
|
turtle.execute(DropDown(64)).await;
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
|
use std::ops::Mul;
|
||||||
|
|
||||||
|
use log::{trace, warn, info};
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
use typetag::serde;
|
use typetag::serde;
|
||||||
|
|
||||||
use crate::{blocks::{Vec3, Position, Direction}, turtle::TurtleCommander, tasks::{Task, TaskState}, depot::Depots, mine::fill};
|
use crate::{blocks::{Vec3, Position, Direction}, turtle::{TurtleCommander, TurtleCommand, TurtleCommandResponse, InventorySlot}, tasks::{Task, TaskState}, depot::Depots, mine::fill};
|
||||||
|
|
||||||
pub async fn fell_tree(turtle: TurtleCommander, bottom: Vec3) -> Option<()> {
|
pub async fn fell_tree(turtle: TurtleCommander, bottom: Vec3) -> Option<()> {
|
||||||
let mut log = bottom;
|
let mut log = bottom;
|
||||||
|
@ -38,15 +41,70 @@ impl TreeFarm {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn sweep(&self, turtle: TurtleCommander) -> Option<()> {
|
pub async fn sweep(&self, turtle: TurtleCommander) -> Option<()> {
|
||||||
let trees = self.size.x * self.size.y * self.size.z;
|
let trees = self.size.product();
|
||||||
//turtle.dock().await;
|
let spacing = Vec3::new(2, 32, 2);
|
||||||
|
turtle.dock().await;
|
||||||
for tree in 0..trees {
|
for tree in 0..trees {
|
||||||
let index = fill(self.size, tree);
|
let index = fill(self.size, tree);
|
||||||
let offset = index.component_mul(&Vec3::new(2, 32, 2));
|
let offset = index.component_mul(&spacing);
|
||||||
|
trace!("tree {tree}; {offset:?}");
|
||||||
let tree = self.position + offset;
|
let tree = self.position + offset;
|
||||||
fell_tree(turtle.clone(), tree).await?;
|
fell_tree(turtle.clone(), tree).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sweep across floor (not upper levels) to get saplings
|
||||||
|
// this goes one block past the far corner and to the near corner
|
||||||
|
let area = self.size.xz().component_mul(&spacing.xz()).product();
|
||||||
|
for tile in 0..area {
|
||||||
|
let offset = fill(self.size.component_mul(&Vec3::new(spacing.x, 1, spacing.z)), tile);
|
||||||
|
let tile = self.position + offset;
|
||||||
|
turtle.goto_adjacent(tile-Vec3::y()).await;
|
||||||
|
turtle.execute(TurtleCommand::SuckFront(64)).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
// scan inventory for saplings
|
||||||
|
let mut saplings = Vec::new();
|
||||||
|
let mut needed = trees;
|
||||||
|
for slot in 1..=16 {
|
||||||
|
if let TurtleCommandResponse::Item(i) = turtle.execute(TurtleCommand::ItemInfo(slot)).await.ret {
|
||||||
|
if i.name.contains("sapling") {
|
||||||
|
needed -= i.count as i32;
|
||||||
|
saplings.push((slot,i));
|
||||||
|
}
|
||||||
|
if needed <= 0 { break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if needed > 0 {
|
||||||
|
warn!("incomplete wood harvest, {needed} saplings short");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pop_item(vec: &mut Vec<(u32, InventorySlot)>) -> Option<u32> {
|
||||||
|
let mut slot = vec.pop()?;
|
||||||
|
let index = slot.0;
|
||||||
|
slot.1.count -= 1;
|
||||||
|
if slot.1.count > 0 {
|
||||||
|
vec.push(slot);
|
||||||
|
}
|
||||||
|
Some(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
// plant saplings
|
||||||
|
for tree in 0..trees {
|
||||||
|
let sapling = match pop_item(&mut saplings) {
|
||||||
|
Some(slot) => slot,
|
||||||
|
None => break,
|
||||||
|
};
|
||||||
|
|
||||||
|
let index = fill(self.size, tree);
|
||||||
|
let offset = index.component_mul(&spacing);
|
||||||
|
let tree = self.position + offset;
|
||||||
|
let near = turtle.goto_adjacent(tree).await?;
|
||||||
|
turtle.execute(TurtleCommand::Select(sapling)).await;
|
||||||
|
turtle.execute(near.place(tree)?).await;
|
||||||
|
fell_tree(turtle.clone(), tree).await?;
|
||||||
|
}
|
||||||
|
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
blocks::{World, Position, Direction, Vec3, WorldReadLock},
|
blocks::{World, Position, Direction, Vec3, WorldReadLock},
|
||||||
};
|
};
|
||||||
use log::trace;
|
use log::{trace, error};
|
||||||
use pathfinding::prelude::astar;
|
use pathfinding::prelude::astar;
|
||||||
|
|
||||||
const LOOKUP_LIMIT: usize = 1_000_000;
|
const LOOKUP_LIMIT: usize = 10_000_000;
|
||||||
|
|
||||||
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| {
|
||||||
|
@ -51,6 +51,7 @@ where D: FnMut(&Position) -> bool {
|
||||||
if limit != 0 {
|
if limit != 0 {
|
||||||
Some(route.0)
|
Some(route.0)
|
||||||
} else {
|
} else {
|
||||||
|
error!("pathfinding timed out");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue