diff --git a/world/Cargo.toml b/world/Cargo.toml index 8f3feb6f86..60805141ab 100644 --- a/world/Cargo.toml +++ b/world/Cargo.toml @@ -36,7 +36,8 @@ ron = { version = "0.6", default-features = false } criterion = "0.3" tracing-subscriber = { version = "0.2.3", default-features = false, features = ["fmt", "chrono", "ansi", "smallvec"] } minifb = "0.19.1" -simple = "0.3" +svg_fmt = "0.4" +structopt = "0.3" [[bench]] harness = false diff --git a/world/examples/site.rs b/world/examples/site.rs index c89b901b25..05c01a34c9 100644 --- a/world/examples/site.rs +++ b/world/examples/site.rs @@ -1,3 +1,28 @@ +use structopt::StructOpt; +use svg_fmt::*; +use veloren_world::site2::test_site; + fn main() { - todo!(); + let site = test_site(); + let size = site.bounds().size(); + println!("{}", BeginSvg { w: size.w as f32, h: size.h as f32 }); + + for plot in site.plots() { + let bounds = plot.find_bounds(); + println!("{}", Rectangle { + x: bounds.min.x as f32, + y: bounds.min.y as f32, + w: bounds.size().w as f32, + h: bounds.size().h as f32, + style: Style { + fill: Fill::Color(Color { r: 50, g: 50, b: 50 }), + stroke: Stroke::Color(Color { r: 0, g: 0, b: 0 }, 1.0), + opacity: 1.0, + stroke_opacity: 1.0, + }, + border_radius: 0.0, + }); + } + + println!("{}", EndSvg); } diff --git a/world/src/site2/mod.rs b/world/src/site2/mod.rs index 9bf80a75b3..e580fdfc9f 100644 --- a/world/src/site2/mod.rs +++ b/world/src/site2/mod.rs @@ -6,10 +6,51 @@ use common::store::{Store, Id}; use crate::util::Grid; use self::{ tile::TileGrid, - plot::Plot, + plot::{Plot, PlotKind}, }; +use rand::prelude::*; +#[derive(Default)] pub struct Site { - grid: TileGrid, - plot: Store, + tiles: TileGrid, + plots: Store, +} + +impl Site { + pub fn bounds(&self) -> Aabr { + let radius = tile::MAX_BLOCK_RADIUS; + Aabr { + min: -Vec2::broadcast(radius as i32), + max: Vec2::broadcast(radius as i32), + } + } + + pub fn plots(&self) -> impl Iterator + '_ { + self.plots.values() + } + + pub fn create_plot(&mut self, plot: Plot) -> Id { + self.plots.insert(plot) + } + + pub fn generate(rng: &mut impl Rng) -> Self { + let mut site = Site::default(); + + for i in 0..10 { + let dir = Vec2::::zero().map(|_| rng.gen_range(-1.0..1.0)).normalized(); + let search_pos = (dir * 32.0).map(|e| e as i32); + + site.tiles + .find_near(search_pos, |tile| tile.is_empty()) + .map(|center| { + // TODO + }); + } + + site + } +} + +pub fn test_site() -> Site { + Site::generate(&mut thread_rng()) } diff --git a/world/src/site2/plot.rs b/world/src/site2/plot.rs index 9c2b8c658e..5b8627c25d 100644 --- a/world/src/site2/plot.rs +++ b/world/src/site2/plot.rs @@ -1,12 +1,21 @@ use vek::*; +use crate::util::DHashSet; pub struct Plot { kind: PlotKind, - center_tpos: Vec2, - units: Vec2>, + root_tile: Vec2, + tiles: DHashSet>, +} + +impl Plot { + pub fn find_bounds(&self) -> Aabr { + self.tiles + .iter() + .fold(Aabr::new_empty(self.root_tile), |b, t| b.expanded_to_contain_point(*t)) + } } pub enum PlotKind { - Path, - House { height: i32 }, + Field, + House, } diff --git a/world/src/site2/tile.rs b/world/src/site2/tile.rs index b4006c436b..4d7fa35f00 100644 --- a/world/src/site2/tile.rs +++ b/world/src/site2/tile.rs @@ -1,22 +1,24 @@ use super::*; -const TILE_SIZE: u32 = 7; -const ZONE_SIZE: u32 = 16; -const ZONE_RADIUS: u32 = 16; -const TILE_RADIUS: u32 = ZONE_SIZE * ZONE_RADIUS; -const MAX_BLOCK_RADIUS: u32 = TILE_SIZE * TILE_RADIUS; +pub const TILE_SIZE: u32 = 7; +pub const ZONE_SIZE: u32 = 16; +pub const ZONE_RADIUS: u32 = 16; +pub const TILE_RADIUS: u32 = ZONE_SIZE * ZONE_RADIUS; +pub const MAX_BLOCK_RADIUS: u32 = TILE_SIZE * TILE_RADIUS; pub struct TileGrid { zones: Grid>>>, } -impl TileGrid { - pub fn new() -> Self { +impl Default for TileGrid { + fn default() -> Self { Self { zones: Grid::populate_from(Vec2::broadcast(ZONE_RADIUS as i32 * 2 + 1), |_| None), } } +} +impl TileGrid { pub fn get(&self, tpos: Vec2) -> Option<&Tile> { let tpos = tpos + TILE_RADIUS as i32; self.zones @@ -34,16 +36,33 @@ impl TileGrid { .get_mut(tpos.map(|e| e.rem_euclid(ZONE_SIZE as i32))) .map(|tile| tile.get_or_insert_with(|| Tile::empty()))) } + + pub fn find_near(&self, tpos: Vec2, f: impl Fn(&Tile) -> bool) -> Option> { + None + } +} + +#[derive(PartialEq)] +pub enum TileKind { + Empty, + Farmland, + Building { levels: u32 }, } pub struct Tile { + kind: TileKind, plot: Option>, } impl Tile { pub fn empty() -> Self { Self { + kind: TileKind::Empty, plot: None, } } + + pub fn is_empty(&self) -> bool { + self.kind == TileKind::Empty + } }