diff --git a/server/src/blocks.rs b/server/src/blocks.rs index 28b477e..44a188e 100644 --- a/server/src/blocks.rs +++ b/server/src/blocks.rs @@ -5,7 +5,7 @@ use anyhow::{Ok, anyhow}; use nalgebra::Vector3; use rstar::{PointDistance, RTree, RTreeObject, AABB, Envelope}; use serde::{Deserialize, Serialize}; -use tokio::sync::{RwLock, OwnedRwLockReadGuard}; +use tokio::sync::{RwLock, OwnedRwLockReadGuard, OwnedRwLockWriteGuard}; use crate::{turtle::TurtleCommand, paths::{self, TRANSPARENT}}; @@ -98,6 +98,10 @@ impl SharedWorld { pub async fn lock(self) -> OwnedRwLockReadGuard { self.state.read_owned().await } + + pub async fn lock_mut(self) -> OwnedRwLockWriteGuard { + self.state.write_owned().await + } } #[derive(Serialize, Deserialize, Clone, Debug)] diff --git a/server/src/construct.rs b/server/src/construct.rs index 830d9ef..e7588b1 100644 --- a/server/src/construct.rs +++ b/server/src/construct.rs @@ -13,24 +13,20 @@ fn schematic2world(region: &Schematic) -> anyhow::Result { let mut world = World::new(); let min = region.origin().context("bad schematic")?; - let area = Vec3::new( - region.width() as i32, - region.height() as i32, - region.length() as i32, - ); - info!("area {}", area); for (position, block) in region.blocks() { - println!("{:#?}, {}", block, position); let name = match block { BlockState::AIR => None, + BlockState(20) => None, // Glass + BlockState(102) => None, // Glass pane + BlockState(95) => None, // Stained glass + BlockState(160) => None, // Stained glass pane // who cares _ => Some("terrestria:hemlock_planks") }.map(|s| s.to_string()); if let Some(name) = name { - println!("{:#?}, {:?}", name, block); let block = Block { name, pos: position - min, @@ -98,6 +94,15 @@ impl BuildSimple { async fn build_layer(&self, turtle: TurtleCommander, layer: i32) -> Option<()> { let layer_size = Vec3::new(self.size.x, 1, self.size.z); + // assume the layer is empty for better pathfinding + let mut world = turtle.world().lock_mut().await; + for point in (0..layer_size.product()).map(|n| fill(layer_size, n)) { + if let None = world.get(point) { + world.set(Block { name: "minecraft:air".into(), pos: point }) + } + } + drop(world); + for point in (0..layer_size.product()) .map(|n| fill(layer_size, n)) { let point = point + Vec3::y() * layer; diff --git a/server/src/turtle_api.rs b/server/src/turtle_api.rs index 41a598b..7724771 100644 --- a/server/src/turtle_api.rs +++ b/server/src/turtle_api.rs @@ -296,7 +296,7 @@ pub(crate) async fn build( ) -> &'static str { let state = state.read().await; let mut schedule = state.tasks.lock().await; - let schematic = Schematic::load(&mut fs::File::open("thethinkman.schematic").await.unwrap().into_std().await).unwrap(); + let schematic = Schematic::load(&mut fs::File::open("schematics/greek-athelete1.schematic").await.unwrap().into_std().await).unwrap(); let input = Position::new( Vec3::new(53,73,77),