1
Fork 0

mining as task

This commit is contained in:
Andy Killorin 2023-12-22 23:16:41 -06:00
parent 2378e9a846
commit 9b1a588aab
Signed by: ank
GPG key ID: B6241CA3B552BCA4
3 changed files with 60 additions and 32 deletions

View file

@ -102,7 +102,6 @@ impl TreeFarm {
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(())
@ -110,12 +109,22 @@ impl TreeFarm {
pub async fn build(&self, turtle: TurtleCommander) -> Option<()> {
let trees = self.size.x * self.size.y * self.size.z;
turtle.dock().await;
let mut soil_to_lay = Vec::new();
for tree in 0..trees {
let index = fill(self.size, tree);
let offset = index.component_mul(&Vec3::new(2, 32, 2));
let tree = self.position + offset;
let soil = tree - Vec3::y();
if turtle.world().get(soil).await.map_or_else(|| true, |b| b.name.contains("dirt")) {
soil_to_lay.push(soil);
}
}
for block in soil_to_lay {
let near = turtle.goto_adjacent(block).await?;
// TODO: item management
//turtle.execute(TurtleCommand::Select(soil)).await;
turtle.execute(near.place(block)?).await;
}
Some(())

View file

@ -1,6 +1,9 @@
use log::{info, warn};
use serde::{Serialize, Deserialize};
use tokio::task::JoinHandle;
use typetag::serde;
use crate::{blocks::{Position, Vec3}, turtle::{TurtleCommand, TurtleCommander, TurtleCommandResponse, InventorySlot}, paths::TRANSPARENT};
use crate::{blocks::{Position, Vec3, Direction}, turtle::{TurtleCommand, TurtleCommander, TurtleCommandResponse, InventorySlot}, paths::TRANSPARENT, tasks::{Task, TaskState}};
use TurtleCommand::*;
/// Things to leave in the field (not worth fuel)
@ -18,24 +21,19 @@ const VALUABLE: [&str; 1] = [
"ore",
];
pub async fn mine(turtle: TurtleCommander, pos: Vec3, fuel: Position, storage: Position) -> Option<()> {
let chunk = Vec3::new(4,4,4);
pub async fn mine(turtle: TurtleCommander, pos: Vec3, chunk: Vec3) -> Option<()> {
let volume = chunk.x * chunk.y * chunk.z;
let mut pos = pos;
let mut valuables = Vec::new();
async fn refuel_needed(turtle: &TurtleCommander, volume: i32, fuel: Position) -> Option<()> {
Some(if (turtle.fuel() as f64) < (2 * volume + (fuel.pos-turtle.pos().await.pos).abs().sum()) as f64 * 1.8 {
let name = turtle.name().to_str();
info!("{name}: refueling");
turtle.goto(fuel).await?;
info!("{name}: docked");
refuel(turtle.clone()).await;
})
async fn refuel_needed(turtle: &TurtleCommander, volume: i32) {
if (turtle.fuel() as i32) < 2 * volume + 4000 {
turtle.dock().await;
}
}
loop {
refuel_needed(&turtle, volume, fuel).await?;
refuel_needed(&turtle, volume).await;
mine_chunk(turtle.clone(), pos, chunk).await?;
@ -50,16 +48,12 @@ pub async fn mine(turtle: TurtleCommander, pos: Vec3, fuel: Position, storage: P
observe(turtle.clone(), block).await;
valuables.append(&mut near_valuables(&turtle, near.pos, Vec3::new(2,2,2)).await);
refuel_needed(&turtle, volume, fuel).await?;
refuel_needed(&turtle, volume).await;
}
if dump_filter(turtle.clone(), |i| USELESS.iter().any(|u| **u == i.name)).await > 12 {
info!("storage rtb");
turtle.goto(storage).await?;
dump(turtle.clone()).await;
// while we're here
turtle.goto(fuel).await?;
refuel(turtle.clone()).await;
turtle.dock().await;
}
pos += Vec3::z() * chunk.z;
@ -179,3 +173,34 @@ async fn observe(turtle: TurtleCommander, pos: Vec3) -> Option<()> {
Some(())
}
#[derive(Serialize, Deserialize,Clone)]
pub struct Mine {
pos: Vec3,
chunk: Vec3,
#[serde(skip_deserializing)]
miners: usize, // Default is false
}
impl Mine {
pub fn new(pos: Vec3, chunk: Vec3) -> Self { Self { pos, chunk, miners: 0 } }
}
#[serde]
impl Task for Mine {
fn run(&mut self,turtle:TurtleCommander) -> JoinHandle<()> {
self.miners += 1;
let frozen = self.clone();
tokio::spawn(async move {
mine(turtle,frozen.pos, frozen.chunk).await.unwrap();
})
// TODO: mutability after spawn
}
fn poll(&mut self) -> TaskState {
if self.miners < 1 {
return TaskState::Ready(Position::new(self.pos, Direction::North));
}
TaskState::Waiting
}
}

View file

@ -2,6 +2,7 @@ use log::trace;
use tokio;
use blocks::Vec3;
use crate::fell::TreeFarm;
use crate::mine::Mine;
use crate::turtle::TurtleCommandResponse;
use crate::turtle::TurtleCommander;
use crate::turtle::TurtleInfo;
@ -34,12 +35,12 @@ pub fn turtle_api() -> Router<SharedControl> {
.route("/:id/update", post(command))
.route("/client.lua", get(client))
.route("/:id/setGoal", post(set_goal))
.route("/:id/dig", post(dig))
.route("/:id/cancelTask", post(cancel))
.route("/:id/manual", post(run_command))
.route("/:id/dock", post(dock))
.route("/:id/info", get(turtle_info))
.route("/createTreeFarm", post(fell))
.route("/createMine", post(dig))
.route("/registerDepot", post(new_depot))
.route("/pollScheduler", get(poll))
.route("/updateAll", get(update_turtles))
@ -101,19 +102,12 @@ pub(crate) async fn run_command(
}
pub(crate) async fn dig(
Path(id): Path<u32>,
State(state): State<SharedControl>,
Json(req): Json<(Vec3, Position, Position)>,
Json(req): Json<Vec3>,
) -> &'static str {
let turtle = state.read().await.get_turtle(id).await.unwrap();
let (req, fuel, inventory) = req;
//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(
async move {
mine::mine(turtle.clone(), req, fuel, inventory).await
}
);
let schedule = &mut state.write().await.tasks;
let chunk = Vec3::new(4,4,4);
schedule.add_task(Box::new(Mine::new(req,chunk)));
"ACK"
}