1
Fork 0

automatic arbor

This commit is contained in:
Andy Killorin 2023-12-22 22:31:16 -06:00
parent 4c75d7e451
commit 2378e9a846
Signed by: ank
GPG key ID: B6241CA3B552BCA4
4 changed files with 79 additions and 8 deletions

View file

@ -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
/// Assumes that "to" can be dug from your position
pub fn dig(&self, to: Vec3) -> Option<TurtleCommand> {

View file

@ -1,6 +1,6 @@
use std::sync::Arc;
use log::{warn, info};
use log::{warn, info, trace};
use tokio::sync::{Mutex, OwnedMutexGuard};
use crate::{blocks::Position, turtle::TurtleCommander};
@ -28,6 +28,7 @@ impl Depots {
pub async fn dock(&self, turtle: TurtleCommander) -> Option<usize> {
let depot = self.clone().nearest(turtle.pos().await).await?;
trace!("depot at {depot:?}");
turtle.goto(*depot).await?;
// dump inventory
@ -39,7 +40,7 @@ impl Depots {
// refuel
turtle.execute(Select(1)).await;
let limit = turtle.fuel_limit();
while turtle.fuel() < limit {
while turtle.fuel() + 1000 < limit {
turtle.execute(SuckFront(64)).await;
let re = turtle.execute(Refuel).await;
turtle.execute(DropDown(64)).await;

View file

@ -1,9 +1,12 @@
use std::ops::Mul;
use log::{trace, warn, info};
use serde::{Serialize, Deserialize};
use time::OffsetDateTime;
use tokio::task::JoinHandle;
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<()> {
let mut log = bottom;
@ -38,15 +41,70 @@ impl TreeFarm {
}
pub async fn sweep(&self, turtle: TurtleCommander) -> Option<()> {
let trees = self.size.x * self.size.y * self.size.z;
//turtle.dock().await;
let trees = self.size.product();
let spacing = Vec3::new(2, 32, 2);
turtle.dock().await;
for tree in 0..trees {
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;
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(())
}

View file

@ -1,10 +1,10 @@
use crate::{
blocks::{World, Position, Direction, Vec3, WorldReadLock},
};
use log::trace;
use log::{trace, error};
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>> {
let facing = |p: &Position| {
@ -51,6 +51,7 @@ where D: FnMut(&Position) -> bool {
if limit != 0 {
Some(route.0)
} else {
error!("pathfinding timed out");
None
}
}