diff --git a/src/model/mod.rs b/src/model/mod.rs index 1f309ea..c6a7efc 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -5,6 +5,7 @@ use std::io::Write; use resources; use render; use world; +use world::block::TintType; use chunk_builder::{self, Direction}; use serde_json; @@ -723,6 +724,9 @@ impl Model { let this = snapshot.get_block(x, y, z); let this_mat = this.get_material(); let mut indices = 0; + + let tint = this.get_tint(); + for face in &self.faces { if face.cull_face != Direction::Invalid { let (ox, oy, oz) = face.cull_face.get_offset(); @@ -734,6 +738,21 @@ impl Model { let (mut cr, mut cg, mut cb) = (255, 255, 255); + match face.tint_index { + 0 => { + match tint { + TintType::Default => {}, + TintType::Color{r, g, b} => { + cr = r; + cg = g; + cb = b; + }, + TintType::Grass => {}, // TODO + TintType::Foliage => {}, // TODO + } + }, + _ => {}, + } if face.facing == Direction::West || face.facing == Direction::East { cr = ((cr as f64) * 0.8) as u8; cg = ((cg as f64) * 0.8) as u8; diff --git a/src/world/biome.rs b/src/world/biome.rs new file mode 100644 index 0000000..7610a48 --- /dev/null +++ b/src/world/biome.rs @@ -0,0 +1,110 @@ + +#[derive(Clone, Copy)] +pub struct Biome { + pub id: usize, + pub temperature: f64, + pub moisture: f64, + pub color_index: usize, +} + +impl Biome { + const fn new(id: usize, t: f64, m: f64) -> Biome{ + Biome { + id: id, + temperature: t, + moisture: m, + color_index: (((1.0 - t) * 255.0) as usize) | ((((1.0 - t) * 255.0) as usize) << 8), + } + } + + pub fn by_id(id: usize) -> Biome { + *BY_ID.get(id).unwrap_or(&INVALID) + } +} + +macro_rules! define_biomes { + ( + $(pub const $name:ident : Biome = $cr:expr;)* + ) => ( + $( + pub const $name: Biome = $cr; + )* + + lazy_static! { + static ref BY_ID: [Biome; 256] = { + let mut by_id = [INVALID; 256]; + $( + by_id[$name.id] = $name; + )* + by_id + }; + } + ) +} + +define_biomes! { +pub const OCEAN: Biome = Biome::new(0, 0.5, 0.5); +pub const PLAINS: Biome = Biome::new(1, 0.8, 0.4); +pub const DESERT: Biome = Biome::new(2, 2.0, 0.0); +pub const EXTREME_HILLS: Biome = Biome::new(3, 0.2, 0.3); +pub const FOREST: Biome = Biome::new(4, 0.7, 0.8); +pub const TAIGA: Biome = Biome::new(5, 0.05, 0.8); +pub const SWAMPLAND: Biome = Biome::new(6, 0.8, 0.9); +pub const RIVER: Biome = Biome::new(7, 0.5, 0.5); +pub const HELL: Biome = Biome::new(8, 2.0, 0.0); +pub const THE_END: Biome = Biome::new(9, 0.5, 0.5); +pub const FROZEN_OCEAN: Biome = Biome::new(10, 0.0, 0.5); +pub const FROZEN_RIVER: Biome = Biome::new(11, 0.0, 0.5); +pub const ICE_PLAINS: Biome = Biome::new(12, 0.0, 0.5); +pub const ICE_MOUNTAINS: Biome = Biome::new(13, 0.0, 0.5); +pub const MUSHROOM_ISLAND: Biome = Biome::new(14, 0.9, 1.0); +pub const MUSHROOM_ISLAND_SHORE: Biome = Biome::new(15, 0.9, 1.0); +pub const BEACH: Biome = Biome::new(16, 0.8, 0.4); +pub const DESERT_HILLS: Biome = Biome::new(17, 2.0, 0.0); +pub const FOREST_HILLS: Biome = Biome::new(18, 0.7, 0.8); +pub const TAIGA_HILLS: Biome = Biome::new(19, 0.2, 0.7); +pub const EXTREME_HILLS_EDGE: Biome = Biome::new(20, 0.2, 0.3); +pub const JUNGLE: Biome = Biome::new(21, 1.2, 0.9); +pub const JUNGLE_HILLS: Biome = Biome::new(22, 1.2, 0.9); +pub const JUNGLE_EDGE: Biome = Biome::new(23, 0.95, 0.8); +pub const DEEP_OCEAN: Biome = Biome::new(24, 0.5, 0.5); +pub const STONE_BEACH: Biome = Biome::new(25, 0.2, 0.3); +pub const COLD_BEACH: Biome = Biome::new(26, 0.05, 0.3); +pub const BIRCH_FOREST: Biome = Biome::new(27, 0.6, 0.6); +pub const BIRCH_FOREST_HILLS: Biome = Biome::new(28, 0.6, 0.6); +pub const ROOFED_FOREST: Biome = Biome::new(29, 0.7, 0.8); +pub const COLD_TAIGA: Biome = Biome::new(30, -0.5, 0.4); +pub const COLD_TAIGA_HILLS: Biome = Biome::new(31, -0.5, 0.4); +pub const MEGA_TAIGA: Biome = Biome::new(32, 0.3, 0.8); +pub const MEGA_TAIGA_HILLS: Biome = Biome::new(33, 0.3, 0.8); +pub const EXTREME_HILLS_PLUS: Biome = Biome::new(34, 0.2, 0.3); +pub const SAVANNA: Biome = Biome::new(35, 1.2, 0.0); +pub const SAVANNA_PLATEAU: Biome = Biome::new(36, 1.0, 0.0); +pub const MESA: Biome = Biome::new(37, 2.0, 0.0); +pub const MESA_PLATEAU_FOREST: Biome = Biome::new(38, 2.0, 0.0); +pub const MESA_PLATEAU: Biome = Biome::new(39, 2.0, 0.0); + +pub const SUNFLOWER_PLAINS: Biome = Biome::new(129, 0.8, 0.4); +pub const DESERT_MOUNTAIN: Biome = Biome::new(130, 2.0, 0.0); +pub const EXTREME_HILLS_MOUNTAINS: Biome = Biome::new(131, 0.2, 0.3); +pub const FLOWER_FOREST: Biome = Biome::new(132, 0.7, 0.8); +pub const TAIGA_M: Biome = Biome::new(133, 0.05, 0.8); +pub const SWAMPLAND_MOUNTAINS: Biome = Biome::new(134, 0.8, 0.9); +pub const ICE_PLAINS_SPIKES: Biome = Biome::new(140, 0.0, 0.5); +pub const JUNGLE_MOUNTAINS: Biome = Biome::new(149, 1.2, 0.9); +pub const JUNGLE_EDGE_MOUNTAINS: Biome = Biome::new(151, 0.95, 0.8); +pub const BIRCH_FOREST_MOUNTAINS: Biome = Biome::new(155, 0.6, 0.6); +pub const BIRCH_FOREST_HILLS_MOUNTAINS: Biome = Biome::new(156, 0.6, 0.6); +pub const ROOFED_FOREST_MOUNTAINS: Biome = Biome::new(157, 0.7, 0.8); +pub const COLD_TAIGA_MOUNTAINS: Biome = Biome::new(158, -0.5, 0.4); +pub const MEGA_SPRUCE_TAIGA: Biome = Biome::new(160, 0.25, 0.8); +pub const MEGA_SPRUCE_TAIGA_HILLS: Biome = Biome::new(161, 0.3, 0.8); +pub const EXTREME_HILLS_PLUS_MOUNTAINS: Biome = Biome::new(162, 0.2, 0.3); +pub const SAVANNA_MOUNTAINS: Biome = Biome::new(163, 1.2, 0.0); +pub const SAVANNA_PLATEAU_MOUNTAINS: Biome = Biome::new(164, 1.0, 0.0); +pub const MESA_BRYCE: Biome = Biome::new(165, 2.0, 0.0); +pub const MESA_PLATEAU_FOREST_MOUNTAINS: Biome = Biome::new(166, 2.0, 0.0); +pub const MESA_PLATEAU_MOUNTAINS: Biome = Biome::new(167, 2.0, 0.0); + +pub const INVALID: Biome = Biome::new(255, 0.0, 0.0); +} diff --git a/src/world/block/mod.rs b/src/world/block/mod.rs index 4439e7f..da8a5f6 100644 --- a/src/world/block/mod.rs +++ b/src/world/block/mod.rs @@ -124,7 +124,7 @@ macro_rules! define_blocks { let data: Option = ($datafunc).map(|v| v + (internal_ids::$name << 4)); return data; )* - return Some(0); + return Some(internal_ids::$name << 4); } )+ } @@ -169,7 +169,7 @@ macro_rules! define_blocks { $($fname,)* } => { $(return String::from($variant);)* - return "normal"; + return "normal".to_owned(); } )+ } @@ -214,6 +214,7 @@ pub struct Material { pub force_shade: bool, } +#[derive(Clone, Copy)] pub enum TintType { Default, Color{r: u8, g: u8, b: u8}, @@ -260,6 +261,7 @@ define_blocks! { }, model { ("minecraft", "grass" ) }, variant format!("snowy={}", snowy), + tint TintType::Grass, } Dirt { props { diff --git a/src/world/mod.rs b/src/world/mod.rs index 0e2bfc0..61e34c9 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -22,6 +22,8 @@ use types::nibble; use types::hash::FNVHash; use protocol; +pub mod biome; + pub struct World { chunks: HashMap>, } @@ -157,7 +159,13 @@ impl World { } } } - // TODO: Biomes + for zz in z1 .. z2 { + for xx in x1 .. x2 { + let ox = xx + (cx << 4); + let oz = zz + (cz << 4); + snapshot.set_biome(ox, oz, chunk.get_biome(xx, zz)); + } + } } } @@ -226,7 +234,12 @@ impl World { try!(data.read_exact(&mut section.block_light.data)); try!(data.read_exact(&mut section.sky_light.data)); } + + if new { + try!(data.read_exact(&mut chunk.biomes)); + } } + for i in 0 .. 16 { if mask & (1 << i) == 0 { continue; @@ -303,6 +316,14 @@ impl Snapshot { self.sky_light.set(idx, l); } + pub fn get_biome(&self, x: i32, z: i32) -> biome::Biome { + biome::Biome::by_id(self.biomes[((x - self.x) | ((z - self.z) << 4)) as usize] as usize) + } + + pub fn set_biome(&mut self, x: i32, z: i32, b: biome::Biome) { + self.biomes[((x - self.x) | ((z - self.z) << 4)) as usize] = b.id as u8; + } + #[inline] fn index(&self, x: i32, y: i32, z: i32) -> usize { ((x - self.x) + ((z - self.z) * self.w) + ((y - self.y) * self.w * self.d)) as usize @@ -358,6 +379,10 @@ impl Chunk { None => block::Air{}, } } + + fn get_biome(&self, x: i32, z: i32) -> biome::Biome { + biome::Biome::by_id(self.biomes[((z<<4)|x) as usize] as usize) + } } #[derive(PartialEq, Eq, Hash)]