Replace usages of x,y,z for block positions with Position

This commit is contained in:
Thinkofname 2016-04-03 20:53:40 +01:00
parent 92d773bd72
commit 98ecd348c6
23 changed files with 494 additions and 520 deletions

6
Cargo.lock generated
View File

@ -19,6 +19,7 @@ dependencies = [
"steven_gl 0.0.1",
"steven_openssl 0.0.1",
"steven_resources 0.1.0",
"steven_shared 0.0.1",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"zip 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -483,6 +484,7 @@ dependencies = [
"cgmath 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"collision 0.5.1 (git+https://github.com/csherratt/collision-rs?rev=f80825e)",
"lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"steven_shared 0.0.1",
]
[[package]]
@ -506,6 +508,10 @@ dependencies = [
name = "steven_resources"
version = "0.1.0"
[[package]]
name = "steven_shared"
version = "0.0.1"
[[package]]
name = "tempdir"
version = "0.3.4"

View File

@ -36,3 +36,7 @@ version = "0"
[dependencies.steven_blocks]
path = "./blocks"
version = "0"
[dependencies.steven_shared]
path = "./shared"
version = "0"

5
blocks/Cargo.lock generated
View File

@ -5,6 +5,7 @@ dependencies = [
"cgmath 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"collision 0.5.1 (git+https://github.com/csherratt/collision-rs?rev=f80825e)",
"lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"steven_shared 0.0.1",
]
[[package]]
@ -58,3 +59,7 @@ name = "rustc-serialize"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "steven_shared"
version = "0.0.1"

View File

@ -7,3 +7,8 @@ authors = [ "Thinkofdeath <thinkofdeath@spigotmc.org>" ]
lazy_static = "0.1.15"
cgmath = "0.7.0"
collision = {git = "https://github.com/csherratt/collision-rs", rev = "f80825e"}
[dependencies.steven_shared]
path = "../shared"
version = "0"

View File

@ -30,7 +30,9 @@ extern crate cgmath;
extern crate collision;
#[macro_use]
extern crate lazy_static;
extern crate steven_shared as shared;
use shared::{Position, Direction};
use collision::{Aabb, Aabb3};
use cgmath::Point3;
@ -40,7 +42,7 @@ pub use self::material::Material;
pub use self::Block::*;
pub trait WorldAccess {
fn get_block(&self, x: i32, y: i32, z: i32) -> Block;
fn get_block(&self, pos: Position) -> Block;
}
#[doc(hidden)]
@ -102,7 +104,7 @@ macro_rules! define_blocks {
$(variant $variant:expr,)*
$(tint $tint:expr,)*
$(collision $collision:expr,)*
$(update_state ($world:ident, $x:ident, $y:ident, $z:ident) => $update_state:expr,)*
$(update_state ($world:ident, $pos:ident) => $update_state:expr,)*
$(multipart ($mkey:ident, $mval:ident) => $multipart:expr,)*
}
)+
@ -275,7 +277,7 @@ macro_rules! define_blocks {
}
#[allow(unused_variables, unreachable_code)]
pub fn update_state<W: WorldAccess>(&self, world: &W, x: i32, y: i32, z: i32) -> Block {
pub fn update_state<W: WorldAccess>(&self, world: &W, pos: Position) -> Block {
match *self {
$(
Block::$name {
@ -283,9 +285,7 @@ macro_rules! define_blocks {
} => {
$(
let $world = world;
let $x = x;
let $y = y;
let $z = z;
let $pos = pos;
return $update_state;
)*
Block::$name {
@ -383,9 +383,9 @@ define_blocks! {
model { ("minecraft", "grass") },
variant format!("snowy={}", snowy),
tint TintType::Grass,
update_state (world, x, y, z) => {
update_state (world, pos) => {
Block::Grass{
snowy: match world.get_block(x, y + 1, z) {
snowy: match world.get_block(pos.shift(Direction::Up)) {
Block::Snow { .. } | Block::SnowLayer { .. } => true,
_ => false,
}
@ -411,9 +411,9 @@ define_blocks! {
"normal".to_owned()
}
},
update_state (world, x, y, z) => if variant == DirtVariant::Podzol {
update_state (world, pos) => if variant == DirtVariant::Podzol {
Block::Dirt{
snowy: match world.get_block(x, y + 1, z) {
snowy: match world.get_block(pos.shift(Direction::Up)) {
Block::Snow{ .. } | Block::SnowLayer { .. } => true,
_ => false,
},
@ -1121,7 +1121,7 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "oak_stairs") },
variant format!("facing={},half={},shape={}", facing.as_string(), half.as_string(), shape.as_string()),
update_state (world, x, y, z) => Block::OakStairs{facing: facing, half: half, shape: update_stair_shape(world, x, y, z, facing)},
update_state (world, pos) => Block::OakStairs{facing: facing, half: half, shape: update_stair_shape(world, pos, facing)},
}
Chest {
props {
@ -1164,11 +1164,11 @@ define_blocks! {
model { ("minecraft", "redstone_wire") },
tint TintType::Color{r: ((255.0 / 30.0) * (power as f64) + 14.0) as u8, g: 0, b: 0},
collision vec![],
update_state (world, x, y, z) => Block::RedstoneWire {
north: can_connect_redstone(world, x, y, z, Direction::North),
south: can_connect_redstone(world, x, y, z, Direction::South),
east: can_connect_redstone(world, x, y, z, Direction::East),
west: can_connect_redstone(world, x, y, z, Direction::West),
update_state (world, pos) => Block::RedstoneWire {
north: can_connect_redstone(world, pos, Direction::North),
south: can_connect_redstone(world, pos, Direction::South),
east: can_connect_redstone(world, pos, Direction::East),
west: can_connect_redstone(world, pos, Direction::West),
power: power
},
multipart (key, val) => match key {
@ -1308,8 +1308,8 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "wooden_door") },
variant format!("facing={},half={},hinge={},open={}", facing.as_string(), half.as_string(), hinge.as_string(), open),
update_state (world, x, y, z) => {
let (facing, hinge, open, powered) = update_door_state(world, x, y, z, half, facing, hinge, open, powered);
update_state (world, pos) => {
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
Block::WoodenDoor{facing: facing, half: half, hinge: hinge, open: open, powered: powered}
},
}
@ -1375,7 +1375,7 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "stone_stairs") },
variant format!("facing={},half={},shape={}", facing.as_string(), half.as_string(), shape.as_string()),
update_state (world, x, y, z) => Block::StoneStairs{facing: facing, half: half, shape: update_stair_shape(world, x, y, z, facing)},
update_state (world, pos) => Block::StoneStairs{facing: facing, half: half, shape: update_stair_shape(world, pos, facing)},
}
WallSign {
props {
@ -1447,8 +1447,8 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "iron_door") },
variant format!("facing={},half={},hinge={},open={}", facing.as_string(), half.as_string(), hinge.as_string(), open),
update_state (world, x, y, z) => {
let (facing, hinge, open, powered) = update_door_state(world, x, y, z, half, facing, hinge, open, powered);
update_state (world, pos) => {
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
Block::IronDoor{facing: facing, half: half, hinge: hinge, open: open, powered: powered}
},
}
@ -1636,11 +1636,11 @@ define_blocks! {
data if !north && !south && !east && !west { Some(0) } else { None },
material material::NON_SOLID,
model { ("minecraft", "fence") },
update_state (world, x, y, z) => Block::Fence {
north: can_connect(world, x, y, z, Direction::North, &can_connect_fence),
south: can_connect(world, x, y, z, Direction::South, &can_connect_fence),
east: can_connect(world, x, y, z, Direction::East, &can_connect_fence),
west: can_connect(world, x, y, z, Direction::West, &can_connect_fence),
update_state (world, pos) => Block::Fence {
north: can_connect(world, pos.shift(Direction::North), &can_connect_fence),
south: can_connect(world, pos.shift(Direction::South), &can_connect_fence),
east: can_connect(world, pos.shift(Direction::East), &can_connect_fence),
west: can_connect(world, pos.shift(Direction::West), &can_connect_fence),
},
multipart (key, val) => match key {
"north" => north == (val == "true"),
@ -1953,17 +1953,17 @@ define_blocks! {
data if !north && !south && !east && !west { Some(0) } else { None },
material material::NON_SOLID,
model { ("minecraft", "iron_bars") },
update_state (world, x, y, z) => {
update_state (world, pos) => {
let f = |block| match block {
Block::IronBars{..} => true,
_ => false,
};
Block::IronBars {
north: can_connect(world, x, y, z, Direction::North, &f),
south: can_connect(world, x, y, z, Direction::South, &f),
east: can_connect(world, x, y, z, Direction::East, &f),
west: can_connect(world, x, y, z, Direction::West, &f),
north: can_connect(world, pos.shift(Direction::North), &f),
south: can_connect(world, pos.shift(Direction::South), &f),
east: can_connect(world, pos.shift(Direction::East), &f),
west: can_connect(world, pos.shift(Direction::West), &f),
}
},
multipart (key, val) => match key {
@ -1984,11 +1984,11 @@ define_blocks! {
data if !north && !south && !east && !west { Some(0) } else { None },
material material::NON_SOLID,
model { ("minecraft", "glass_pane") },
update_state (world, x, y, z) => Block::GlassPane {
north: can_connect(world, x, y, z, Direction::North, &can_connect_glasspane),
south: can_connect(world, x, y, z, Direction::South, &can_connect_glasspane),
east: can_connect(world, x, y, z, Direction::East, &can_connect_glasspane),
west: can_connect(world, x, y, z, Direction::West, &can_connect_glasspane),
update_state (world, pos) => Block::GlassPane {
north: can_connect(world, pos.shift(Direction::North), &can_connect_glasspane),
south: can_connect(world, pos.shift(Direction::South), &can_connect_glasspane),
east: can_connect(world, pos.shift(Direction::East), &can_connect_glasspane),
west: can_connect(world, pos.shift(Direction::West), &can_connect_glasspane),
},
multipart (key, val) => match key {
"north" => north == (val == "true"),
@ -2026,9 +2026,9 @@ define_blocks! {
},
tint TintType::Color{r: age as u8 * 32, g: 255 - (age as u8 * 8), b: age as u8 * 4},
collision vec![],
update_state (world, x, y, z) => {
let facing = match (world.get_block(x - 1, y, z), world.get_block(x + 1, y, z),
world.get_block(x, y, z - 1), world.get_block(x, y, z + 1)) {
update_state (world, pos) => {
let facing = match (world.get_block(pos.shift(Direction::East)), world.get_block(pos.shift(Direction::West)),
world.get_block(pos.shift(Direction::North)), world.get_block(pos.shift(Direction::South))) {
(Block::Pumpkin{ .. }, _, _, _) => Direction::East,
(_, Block::Pumpkin{ .. }, _, _) => Direction::West,
(_, _, Block::Pumpkin{ .. }, _) => Direction::North,
@ -2062,9 +2062,9 @@ define_blocks! {
},
tint TintType::Color{r: age as u8 * 32, g: 255 - (age as u8 * 8), b: age as u8 * 4},
collision vec![],
update_state (world, x, y, z) => {
let facing = match (world.get_block(x - 1, y, z), world.get_block(x + 1, y, z),
world.get_block(x, y, z - 1), world.get_block(x, y, z + 1)) {
update_state (world, pos) => {
let facing = match (world.get_block(pos.shift(Direction::East)), world.get_block(pos.shift(Direction::West)),
world.get_block(pos.shift(Direction::North)), world.get_block(pos.shift(Direction::South))) {
(Block::MelonBlock{ .. }, _, _, _) => Direction::East,
(_, Block::MelonBlock{ .. }, _, _) => Direction::West,
(_, _, Block::MelonBlock{ .. }, _) => Direction::North,
@ -2133,7 +2133,7 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "brick_stairs") },
variant format!("facing={},half={},shape={}", facing.as_string(), half.as_string(), shape.as_string()),
update_state (world, x, y, z) => Block::BrickStairs{facing: facing, half: half, shape: update_stair_shape(world, x, y, z, facing)},
update_state (world, pos) => Block::BrickStairs{facing: facing, half: half, shape: update_stair_shape(world, pos, facing)},
}
StoneBrickStairs {
props {
@ -2154,7 +2154,7 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "stone_brick_stairs") },
variant format!("facing={},half={},shape={}", facing.as_string(), half.as_string(), shape.as_string()),
update_state (world, x, y, z) => Block::StoneBrickStairs{facing: facing, half: half, shape: update_stair_shape(world, x, y, z, facing)},
update_state (world, pos) => Block::StoneBrickStairs{facing: facing, half: half, shape: update_stair_shape(world, pos, facing)},
}
Mycelium {
props {
@ -2164,9 +2164,9 @@ define_blocks! {
material material::SOLID,
model { ("minecraft", "mycelium") },
variant format!("snowy={}", snowy),
update_state (world, x, y, z) => {
update_state (world, pos) => {
Block::Grass{
snowy: match world.get_block(x, y + 1, z) {
snowy: match world.get_block(pos.shift(Direction::Up)) {
Block::Snow { .. } | Block::SnowLayer { .. } => true,
_ => false,
}
@ -2195,17 +2195,17 @@ define_blocks! {
data if !north && !south && !east && !west { Some(0) } else { None },
material material::NON_SOLID,
model { ("minecraft", "nether_brick_fence") },
update_state (world, x, y, z) => {
update_state (world, pos) => {
let f = |block| match block {
Block::NetherBrickFence{..} => true,
_ => false,
};
Block::NetherBrickFence {
north: can_connect(world, x, y, z, Direction::North, &f),
south: can_connect(world, x, y, z, Direction::South, &f),
east: can_connect(world, x, y, z, Direction::East, &f),
west: can_connect(world, x, y, z, Direction::West, &f),
north: can_connect(world, pos.shift(Direction::North), &f),
south: can_connect(world, pos.shift(Direction::South), &f),
east: can_connect(world, pos.shift(Direction::East), &f),
west: can_connect(world, pos.shift(Direction::West), &f),
}
},
multipart (key, val) => match key {
@ -2235,7 +2235,7 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "nether_brick_stairs") },
variant format!("facing={},half={},shape={}", facing.as_string(), half.as_string(), shape.as_string()),
update_state (world, x, y, z) => Block::NetherBrickStairs{facing: facing, half: half, shape: update_stair_shape(world, x, y, z, facing)},
update_state (world, pos) => Block::NetherBrickStairs{facing: facing, half: half, shape: update_stair_shape(world, pos, facing)},
}
NetherWart {
props {
@ -2450,7 +2450,7 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "sandstone_stairs") },
variant format!("facing={},half={},shape={}", facing.as_string(), half.as_string(), shape.as_string()),
update_state (world, x, y, z) => Block::SandstoneStairs{facing: facing, half: half, shape: update_stair_shape(world, x, y, z, facing)},
update_state (world, pos) => Block::SandstoneStairs{facing: facing, half: half, shape: update_stair_shape(world, pos, facing)},
}
EmeraldOre {
props {},
@ -2564,7 +2564,7 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "spruce_stairs") },
variant format!("facing={},half={},shape={}", facing.as_string(), half.as_string(), shape.as_string()),
update_state (world, x, y, z) => Block::SpruceStairs{facing: facing, half: half, shape: update_stair_shape(world, x, y, z, facing)},
update_state (world, pos) => Block::SpruceStairs{facing: facing, half: half, shape: update_stair_shape(world, pos, facing)},
}
BirchStairs {
props {
@ -2585,7 +2585,7 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "birch_stairs") },
variant format!("facing={},half={},shape={}", facing.as_string(), half.as_string(), shape.as_string()),
update_state (world, x, y, z) => Block::BirchStairs{facing: facing, half: half, shape: update_stair_shape(world, x, y, z, facing)},
update_state (world, pos) => Block::BirchStairs{facing: facing, half: half, shape: update_stair_shape(world, pos, facing)},
}
JungleStairs {
props {
@ -2606,7 +2606,7 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "jungle_stairs") },
variant format!("facing={},half={},shape={}", facing.as_string(), half.as_string(), shape.as_string()),
update_state (world, x, y, z) => Block::JungleStairs{facing: facing, half: half, shape: update_stair_shape(world, x, y, z, facing)},
update_state (world, pos) => Block::JungleStairs{facing: facing, half: half, shape: update_stair_shape(world, pos, facing)},
}
CommandBlock {
props {
@ -2653,18 +2653,18 @@ define_blocks! {
data if !north && !south && !east && !west && !up { Some(variant.data()) } else { None },
material material::NON_SOLID,
model { ("minecraft", format!("{}_wall", variant.as_string())) },
update_state (world, x, y, z) => {
update_state (world, pos) => {
let f = |block| match block {
Block::CobblestoneWall{..} => true,
_ => false,
};
Block::CobblestoneWall {
up: can_connect(world, x, y, z, Direction::Up, &f),
north: can_connect(world, x, y, z, Direction::North, &f),
south: can_connect(world, x, y, z, Direction::South, &f),
east: can_connect(world, x, y, z, Direction::East, &f),
west: can_connect(world, x, y, z, Direction::West, &f),
up: can_connect(world, pos.shift(Direction::Up), &f),
north: can_connect(world, pos.shift(Direction::North), &f),
south: can_connect(world, pos.shift(Direction::South), &f),
east: can_connect(world, pos.shift(Direction::East), &f),
west: can_connect(world, pos.shift(Direction::West), &f),
variant: variant,
}
},
@ -3008,7 +3008,7 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "quartz_stairs") },
variant format!("facing={},half={},shape={}", facing.as_string(), half.as_string(), shape.as_string()),
update_state (world, x, y, z) => Block::QuartzStairs{facing: facing, half: half, shape: update_stair_shape(world, x, y, z, facing)},
update_state (world, pos) => Block::QuartzStairs{facing: facing, half: half, shape: update_stair_shape(world, pos, facing)},
}
ActivatorRail {
props {
@ -3110,12 +3110,12 @@ define_blocks! {
data if !north && !south && !east && !west { Some(color.data()) } else { None },
material material::TRANSPARENT,
model { ("minecraft", format!("{}_stained_glass_pane", color.as_string()) ) },
update_state (world, x, y, z) => Block::StainedGlassPane {
update_state (world, pos) => Block::StainedGlassPane {
color: color,
north: can_connect(world, x, y, z, Direction::North, &can_connect_glasspane),
south: can_connect(world, x, y, z, Direction::South, &can_connect_glasspane),
east: can_connect(world, x, y, z, Direction::East, &can_connect_glasspane),
west: can_connect(world, x, y, z, Direction::West, &can_connect_glasspane),
north: can_connect(world, pos.shift(Direction::North), &can_connect_glasspane),
south: can_connect(world, pos.shift(Direction::South), &can_connect_glasspane),
east: can_connect(world, pos.shift(Direction::East), &can_connect_glasspane),
west: can_connect(world, pos.shift(Direction::West), &can_connect_glasspane),
},
multipart (key, val) => match key {
"north" => north == (val == "true"),
@ -3173,7 +3173,7 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "acacia_stairs") },
variant format!("facing={},half={},shape={}", facing.as_string(), half.as_string(), shape.as_string()),
update_state (world, x, y, z) => Block::AcaciaStairs{facing: facing, half: half, shape: update_stair_shape(world, x, y, z, facing)},
update_state (world, pos) => Block::AcaciaStairs{facing: facing, half: half, shape: update_stair_shape(world, pos, facing)},
}
DarkOakStairs {
props {
@ -3194,7 +3194,7 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "dark_oak_stairs") },
variant format!("facing={},half={},shape={}", facing.as_string(), half.as_string(), shape.as_string()),
update_state (world, x, y, z) => Block::DarkOakStairs{facing: facing, half: half, shape: update_stair_shape(world, x, y, z, facing)},
update_state (world, pos) => Block::DarkOakStairs{facing: facing, half: half, shape: update_stair_shape(world, pos, facing)},
}
Slime {
props {},
@ -3331,8 +3331,8 @@ define_blocks! {
variant format!("half={}", half.as_string()),
tint TintType::Foliage,
collision vec![],
update_state (world, x, y, z) => {
let (half, variant) = update_double_plant_state(world, x, y, z, half, variant);
update_state (world, pos) => {
let (half, variant) = update_double_plant_state(world, pos, half, variant);
Block::DoublePlant{half: half, variant: variant}
},
}
@ -3423,7 +3423,7 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "red_sandstone_stairs") },
variant format!("facing={},half={},shape={}", facing.as_string(), half.as_string(), shape.as_string()),
update_state (world, x, y, z) => Block::RedSandstoneStairs{facing: facing, half: half, shape: update_stair_shape(world, x, y, z, facing)},
update_state (world, pos) => Block::RedSandstoneStairs{facing: facing, half: half, shape: update_stair_shape(world, pos, facing)},
}
DoubleStoneSlab2 {
props {
@ -3547,11 +3547,11 @@ define_blocks! {
data if !north && !south && !east && !west { Some(0) } else { None },
material material::NON_SOLID,
model { ("minecraft", "spruce_fence") },
update_state (world, x, y, z) => Block::SpruceFence {
north: can_connect(world, x, y, z, Direction::North, &can_connect_fence),
south: can_connect(world, x, y, z, Direction::South, &can_connect_fence),
east: can_connect(world, x, y, z, Direction::East, &can_connect_fence),
west: can_connect(world, x, y, z, Direction::West, &can_connect_fence),
update_state (world, pos) => Block::SpruceFence {
north: can_connect(world, pos.shift(Direction::North), &can_connect_fence),
south: can_connect(world, pos.shift(Direction::South), &can_connect_fence),
east: can_connect(world, pos.shift(Direction::East), &can_connect_fence),
west: can_connect(world, pos.shift(Direction::West), &can_connect_fence),
},
multipart (key, val) => match key {
"north" => north == (val == "true"),
@ -3571,11 +3571,11 @@ define_blocks! {
data if !north && !south && !east && !west { Some(0) } else { None },
material material::NON_SOLID,
model { ("minecraft", "birch_fence") },
update_state (world, x, y, z) => Block::BirchFence {
north: can_connect(world, x, y, z, Direction::North, &can_connect_fence),
south: can_connect(world, x, y, z, Direction::South, &can_connect_fence),
east: can_connect(world, x, y, z, Direction::East, &can_connect_fence),
west: can_connect(world, x, y, z, Direction::West, &can_connect_fence),
update_state (world, pos) => Block::BirchFence {
north: can_connect(world, pos.shift(Direction::North), &can_connect_fence),
south: can_connect(world, pos.shift(Direction::South), &can_connect_fence),
east: can_connect(world, pos.shift(Direction::East), &can_connect_fence),
west: can_connect(world, pos.shift(Direction::West), &can_connect_fence),
},
multipart (key, val) => match key {
"north" => north == (val == "true"),
@ -3595,11 +3595,11 @@ define_blocks! {
data if !north && !south && !east && !west { Some(0) } else { None },
material material::NON_SOLID,
model { ("minecraft", "jungle_fence") },
update_state (world, x, y, z) => Block::JungleFence {
north: can_connect(world, x, y, z, Direction::North, &can_connect_fence),
south: can_connect(world, x, y, z, Direction::South, &can_connect_fence),
east: can_connect(world, x, y, z, Direction::East, &can_connect_fence),
west: can_connect(world, x, y, z, Direction::West, &can_connect_fence),
update_state (world, pos) => Block::JungleFence {
north: can_connect(world, pos.shift(Direction::North), &can_connect_fence),
south: can_connect(world, pos.shift(Direction::South), &can_connect_fence),
east: can_connect(world, pos.shift(Direction::East), &can_connect_fence),
west: can_connect(world, pos.shift(Direction::West), &can_connect_fence),
},
multipart (key, val) => match key {
"north" => north == (val == "true"),
@ -3619,11 +3619,11 @@ define_blocks! {
data if !north && !south && !east && !west { Some(0) } else { None },
material material::NON_SOLID,
model { ("minecraft", "dark_oak_fence") },
update_state (world, x, y, z) => Block::DarkOakFence {
north: can_connect(world, x, y, z, Direction::North, &can_connect_fence),
south: can_connect(world, x, y, z, Direction::South, &can_connect_fence),
east: can_connect(world, x, y, z, Direction::East, &can_connect_fence),
west: can_connect(world, x, y, z, Direction::West, &can_connect_fence),
update_state (world, pos) => Block::DarkOakFence {
north: can_connect(world, pos.shift(Direction::North), &can_connect_fence),
south: can_connect(world, pos.shift(Direction::South), &can_connect_fence),
east: can_connect(world, pos.shift(Direction::East), &can_connect_fence),
west: can_connect(world, pos.shift(Direction::West), &can_connect_fence),
},
multipart (key, val) => match key {
"north" => north == (val == "true"),
@ -3643,11 +3643,11 @@ define_blocks! {
data if !north && !south && !east && !west { Some(0) } else { None },
material material::NON_SOLID,
model { ("minecraft", "acacia_fence") },
update_state (world, x, y, z) => Block::AcaciaFence {
north: can_connect(world, x, y, z, Direction::North, &can_connect_fence),
south: can_connect(world, x, y, z, Direction::South, &can_connect_fence),
east: can_connect(world, x, y, z, Direction::East, &can_connect_fence),
west: can_connect(world, x, y, z, Direction::West, &can_connect_fence),
update_state (world, pos) => Block::AcaciaFence {
north: can_connect(world, pos.shift(Direction::North), &can_connect_fence),
south: can_connect(world, pos.shift(Direction::South), &can_connect_fence),
east: can_connect(world, pos.shift(Direction::East), &can_connect_fence),
west: can_connect(world, pos.shift(Direction::West), &can_connect_fence),
},
multipart (key, val) => match key {
"north" => north == (val == "true"),
@ -3674,8 +3674,8 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "spruce_door") },
variant format!("facing={},half={},hinge={},open={}", facing.as_string(), half.as_string(), hinge.as_string(), open),
update_state (world, x, y, z) => {
let (facing, hinge, open, powered) = update_door_state(world, x, y, z, half, facing, hinge, open, powered);
update_state (world, pos) => {
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
Block::SpruceDoor{facing: facing, half: half, hinge: hinge, open: open, powered: powered}
},
}
@ -3696,8 +3696,8 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "birch_door") },
variant format!("facing={},half={},hinge={},open={}", facing.as_string(), half.as_string(), hinge.as_string(), open),
update_state (world, x, y, z) => {
let (facing, hinge, open, powered) = update_door_state(world, x, y, z, half, facing, hinge, open, powered);
update_state (world, pos) => {
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
Block::BirchDoor{facing: facing, half: half, hinge: hinge, open: open, powered: powered}
},
}
@ -3718,8 +3718,8 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "jungle_door") },
variant format!("facing={},half={},hinge={},open={}", facing.as_string(), half.as_string(), hinge.as_string(), open),
update_state (world, x, y, z) => {
let (facing, hinge, open, powered) = update_door_state(world, x, y, z, half, facing, hinge, open, powered);
update_state (world, pos) => {
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
Block::JungleDoor{facing: facing, half: half, hinge: hinge, open: open, powered: powered}
},
}
@ -3740,8 +3740,8 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "acacia_door") },
variant format!("facing={},half={},hinge={},open={}", facing.as_string(), half.as_string(), hinge.as_string(), open),
update_state (world, x, y, z) => {
let (facing, hinge, open, powered) = update_door_state(world, x, y, z, half, facing, hinge, open, powered);
update_state (world, pos) => {
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
Block::AcaciaDoor{facing: facing, half: half, hinge: hinge, open: open, powered: powered}
},
}
@ -3762,8 +3762,8 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "dark_oak_door") },
variant format!("facing={},half={},hinge={},open={}", facing.as_string(), half.as_string(), hinge.as_string(), open),
update_state (world, x, y, z) => {
let (facing, hinge, open, powered) = update_door_state(world, x, y, z, half, facing, hinge, open, powered);
update_state (world, pos) => {
let (facing, hinge, open, powered) = update_door_state(world, pos, half, facing, hinge, open, powered);
Block::DarkOakDoor{facing: facing, half: half, hinge: hinge, open: open, powered: powered}
},
}
@ -3813,13 +3813,13 @@ define_blocks! {
data if !north && !south && !east && !west && !up && !down { Some(0) } else { None },
material material::NON_SOLID,
model { ("minecraft", "chorus_plant") },
update_state (world, x, y, z) => Block::ChorusPlant {
north: match world.get_block(x, y, z - 1) { Block::ChorusPlant{..} | Block::ChorusFlower{..} => true, _ => false,},
south: match world.get_block(x, y, z + 1) { Block::ChorusPlant{..} | Block::ChorusFlower{..} => true, _ => false,},
west: match world.get_block(x - 1, y, z) { Block::ChorusPlant{..} | Block::ChorusFlower{..} => true, _ => false,},
east: match world.get_block(x + 1, y, z) { Block::ChorusPlant{..} | Block::ChorusFlower{..} => true, _ => false,},
up: match world.get_block(x, y + 1, z) { Block::ChorusPlant{..} | Block::ChorusFlower{..} => true, _ => false,},
down: match world.get_block(x, y - 1, z) { Block::ChorusPlant{..} | Block::ChorusFlower{..} | Block::EndStone{..} => true, _ => false,},
update_state (world, pos) => Block::ChorusPlant {
north: match world.get_block(pos.shift(Direction::North)) { Block::ChorusPlant{..} | Block::ChorusFlower{..} => true, _ => false,},
south: match world.get_block(pos.shift(Direction::South)) { Block::ChorusPlant{..} | Block::ChorusFlower{..} => true, _ => false,},
west: match world.get_block(pos.shift(Direction::West)) { Block::ChorusPlant{..} | Block::ChorusFlower{..} => true, _ => false,},
east: match world.get_block(pos.shift(Direction::East)) { Block::ChorusPlant{..} | Block::ChorusFlower{..} => true, _ => false,},
up: match world.get_block(pos.shift(Direction::Up)) { Block::ChorusPlant{..} | Block::ChorusFlower{..} => true, _ => false,},
down: match world.get_block(pos.shift(Direction::Down)) { Block::ChorusPlant{..} | Block::ChorusFlower{..} | Block::EndStone{..} => true, _ => false,},
},
multipart (key, val) => match key {
"north" => north == (val == "true"),
@ -3878,7 +3878,7 @@ define_blocks! {
material material::NON_SOLID,
model { ("minecraft", "purpur_stairs") },
variant format!("facing={},half={},shape={}", facing.as_string(), half.as_string(), shape.as_string()),
update_state (world, x, y, z) => Block::PurpurStairs{facing: facing, half: half, shape: update_stair_shape(world, x, y, z, facing)},
update_state (world, pos) => Block::PurpurStairs{facing: facing, half: half, shape: update_stair_shape(world, pos, facing)},
}
PurpurDoubleSlab {
props {
@ -3975,9 +3975,8 @@ define_blocks! {
}
}
fn can_connect<F: Fn(Block) -> bool, W: WorldAccess>(world: &W, x: i32, y: i32, z: i32, dir: Direction, f: &F) -> bool {
let (ox, oy, oz) = dir.get_offset();
let block = world.get_block(x + ox, y + oy, z + oz);
fn can_connect<F: Fn(Block) -> bool, W: WorldAccess>(world: &W, pos: Position, f: &F) -> bool {
let block = world.get_block(pos);
f(block) || (block.get_material().renderable && block.get_material().should_cull_against)
}
@ -4009,13 +4008,13 @@ fn can_connect_glasspane(block: Block) -> bool {
}
}
fn can_connect_redstone<W: WorldAccess>(world: &W, x: i32, y: i32, z: i32, dir: Direction) -> RedstoneSide {
let (ox, oy, oz) = dir.get_offset();
let block = world.get_block(x + ox, y + oy, z + oz);
fn can_connect_redstone<W: WorldAccess>(world: &W, pos: Position, dir: Direction) -> RedstoneSide {
let shift_pos = pos.shift(dir);
let block = world.get_block(shift_pos);
if block.get_material().should_cull_against {
let side_up = world.get_block(x + ox, y + oy + 1, z + oz);
let up = world.get_block(x, y + 1, z);
let side_up = world.get_block(shift_pos.shift(Direction::Up));
let up = world.get_block(pos.shift(Direction::Up));
if match side_up { Block::RedstoneWire{..} => true, _ => false,} && !up.get_material().should_cull_against {
return RedstoneSide::Up;
@ -4024,7 +4023,7 @@ fn can_connect_redstone<W: WorldAccess>(world: &W, x: i32, y: i32, z: i32, dir:
return RedstoneSide::None;
}
let side_down = world.get_block(x + ox, y + oy - 1, z + oz);
let side_down = world.get_block(shift_pos.shift(Direction::Down));
if match block { Block::RedstoneWire{..} => true, _ => false,} || match side_down { Block::RedstoneWire{..} => true, _ => false,} {
return RedstoneSide::Side;
}
@ -4076,14 +4075,14 @@ fn door_data(facing: Direction, half: DoorHalf, hinge: Side, open: bool, powered
}
}
fn update_door_state<W: WorldAccess>(world: &W, x: i32, y: i32, z: i32, ohalf: DoorHalf, ofacing: Direction, ohinge: Side, oopen: bool, opowered: bool) -> (Direction, Side, bool, bool) {
fn update_door_state<W: WorldAccess>(world: &W, pos: Position, ohalf: DoorHalf, ofacing: Direction, ohinge: Side, oopen: bool, opowered: bool) -> (Direction, Side, bool, bool) {
let oy = if ohalf == DoorHalf::Upper {
-1
} else {
1
};
match world.get_block(x, y + oy, z) {
match world.get_block(pos + (0, oy, 0)) {
Block::WoodenDoor{half, facing, hinge, open, powered} |
Block::SpruceDoor{half, facing, hinge, open, powered} |
Block::BirchDoor{half, facing, hinge, open, powered} |
@ -4105,12 +4104,12 @@ fn update_door_state<W: WorldAccess>(world: &W, x: i32, y: i32, z: i32, ohalf: D
(ofacing, ohinge, oopen, opowered)
}
fn update_double_plant_state<W: WorldAccess>(world: &W, x: i32, y: i32, z: i32, ohalf: BlockHalf, ovariant: DoublePlantVariant) -> (BlockHalf, DoublePlantVariant) {
fn update_double_plant_state<W: WorldAccess>(world: &W, pos: Position, ohalf: BlockHalf, ovariant: DoublePlantVariant) -> (BlockHalf, DoublePlantVariant) {
if ohalf != BlockHalf::Upper {
return (ohalf, ovariant);
}
match world.get_block(x, y - 1, z) {
match world.get_block(pos.shift(Direction::Down)) {
Block::DoublePlant{variant, ..} => (ohalf, variant),
_ => (ohalf, ovariant),
}
@ -4933,9 +4932,9 @@ impl StairShape {
}
}
fn get_stair_info<W: WorldAccess>(world: &W, x: i32, y: i32, z: i32) -> Option<(Direction, BlockHalf)> {
fn get_stair_info<W: WorldAccess>(world: &W, pos: Position) -> Option<(Direction, BlockHalf)> {
use self::Block::*;
match world.get_block(x, y, z) {
match world.get_block(pos) {
OakStairs{facing, half, ..} |
StoneStairs{facing, half, ..} |
BrickStairs{facing, half, ..} |
@ -4954,9 +4953,8 @@ fn get_stair_info<W: WorldAccess>(world: &W, x: i32, y: i32, z: i32) -> Option<(
}
}
fn update_stair_shape<W: WorldAccess>(world: &W, x: i32, y: i32, z: i32, facing: Direction) -> StairShape {
let (ox, oy, oz) = facing.get_offset();
if let Some((other_facing, _)) = get_stair_info(world, x+ox, y+oy, z+oz) {
fn update_stair_shape<W: WorldAccess>(world: &W, pos: Position, facing: Direction) -> StairShape {
if let Some((other_facing, _)) = get_stair_info(world, pos.shift(facing)) {
if other_facing != facing && other_facing != facing.opposite() {
if other_facing == facing.clockwise() {
return StairShape::OuterRight;
@ -4966,8 +4964,7 @@ fn update_stair_shape<W: WorldAccess>(world: &W, x: i32, y: i32, z: i32, facing:
}
}
let (ox, oy, oz) = facing.opposite().get_offset();
if let Some((other_facing, _)) = get_stair_info(world, x+ox, y+oy, z+oz) {
if let Some((other_facing, _)) = get_stair_info(world, pos.shift(facing.opposite())) {
if other_facing != facing && other_facing != facing.opposite() {
if other_facing == facing.clockwise() {
return StairShape::InnerRight;
@ -5145,96 +5142,3 @@ impl FlowerPotVariant {
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Direction {
Invalid,
Up,
Down,
North,
South,
West,
East,
}
impl Direction {
pub fn all() -> Vec<Direction> {
vec![
Direction::Up, Direction::Down,
Direction::North, Direction::South,
Direction::West, Direction::East,
]
}
pub fn from_string(val: &str) -> Direction {
match val {
"up" => Direction::Up,
"down" => Direction::Down,
"north" => Direction::North,
"south" => Direction::South,
"west" => Direction::West,
"east" => Direction::East,
_ => Direction::Invalid,
}
}
pub fn opposite(&self) -> Direction {
match *self {
Direction::Up => Direction::Down,
Direction::Down => Direction::Up,
Direction::North => Direction::South,
Direction::South => Direction::North,
Direction::West => Direction::East,
Direction::East => Direction::West,
_ => unreachable!(),
}
}
pub fn clockwise(&self) -> Direction {
match *self {
Direction::Up => Direction::Up,
Direction::Down => Direction::Down,
Direction::East => Direction::South,
Direction::West => Direction::North,
Direction::South => Direction::West,
Direction::North => Direction::East,
_ => unreachable!(),
}
}
pub fn counter_clockwise(&self) -> Direction {
match *self {
Direction::Up => Direction::Up,
Direction::Down => Direction::Down,
Direction::East => Direction::North,
Direction::West => Direction::South,
Direction::South => Direction::East,
Direction::North => Direction::West,
_ => unreachable!(),
}
}
pub fn get_offset(&self) -> (i32, i32, i32) {
match *self {
Direction::Up => (0, 1, 0),
Direction::Down => (0, -1, 0),
Direction::North => (0, 0, -1),
Direction::South => (0, 0, 1),
Direction::West => (-1, 0, 0),
Direction::East => (1, 0, 0),
_ => unreachable!(),
}
}
pub fn as_string(&self) -> &'static str {
match *self {
Direction::Up => "up",
Direction::Down => "down",
Direction::North => "north",
Direction::South => "south",
Direction::West => "west",
Direction::East => "east",
Direction::Invalid => "invalid",
}
}
}

4
shared/Cargo.lock generated Normal file
View File

@ -0,0 +1,4 @@
[root]
name = "steven_shared"
version = "0.0.1"

6
shared/Cargo.toml Normal file
View File

@ -0,0 +1,6 @@
[package]
name = "steven_shared"
version = "0.0.1"
authors = [ "Thinkofdeath <thinkofdeath@spigotmc.org>" ]
[dependencies]

104
shared/src/direction.rs Normal file
View File

@ -0,0 +1,104 @@
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Direction {
Invalid,
Up,
Down,
North,
South,
West,
East,
}
impl Direction {
pub fn all() -> Vec<Direction> {
vec![
Direction::Up, Direction::Down,
Direction::North, Direction::South,
Direction::West, Direction::East,
]
}
pub fn from_string(val: &str) -> Direction {
match val {
"up" => Direction::Up,
"down" => Direction::Down,
"north" => Direction::North,
"south" => Direction::South,
"west" => Direction::West,
"east" => Direction::East,
_ => Direction::Invalid,
}
}
pub fn opposite(&self) -> Direction {
match *self {
Direction::Up => Direction::Down,
Direction::Down => Direction::Up,
Direction::North => Direction::South,
Direction::South => Direction::North,
Direction::West => Direction::East,
Direction::East => Direction::West,
_ => unreachable!(),
}
}
pub fn clockwise(&self) -> Direction {
match *self {
Direction::Up => Direction::Up,
Direction::Down => Direction::Down,
Direction::East => Direction::South,
Direction::West => Direction::North,
Direction::South => Direction::West,
Direction::North => Direction::East,
_ => unreachable!(),
}
}
pub fn counter_clockwise(&self) -> Direction {
match *self {
Direction::Up => Direction::Up,
Direction::Down => Direction::Down,
Direction::East => Direction::North,
Direction::West => Direction::South,
Direction::South => Direction::East,
Direction::North => Direction::West,
_ => unreachable!(),
}
}
pub fn get_offset(&self) -> (i32, i32, i32) {
match *self {
Direction::Up => (0, 1, 0),
Direction::Down => (0, -1, 0),
Direction::North => (0, 0, -1),
Direction::South => (0, 0, 1),
Direction::West => (-1, 0, 0),
Direction::East => (1, 0, 0),
_ => unreachable!(),
}
}
pub fn as_string(&self) -> &'static str {
match *self {
Direction::Up => "up",
Direction::Down => "down",
Direction::North => "north",
Direction::South => "south",
Direction::West => "west",
Direction::East => "east",
Direction::Invalid => "invalid",
}
}
pub fn index(&self) -> usize {
match *self {
Direction::Up => 0,
Direction::Down => 1,
Direction::North => 2,
Direction::South => 3,
Direction::West => 4,
Direction::East => 5,
_ => unreachable!(),
}
}
}

6
shared/src/lib.rs Normal file
View File

@ -0,0 +1,6 @@
pub mod direction;
pub use direction::Direction;
pub mod position;
pub use position::Position;

91
shared/src/position.rs Normal file
View File

@ -0,0 +1,91 @@
use std::fmt;
use direction::Direction;
use std::ops;
#[derive(Clone, Copy)]
pub struct Position {
pub x: i32,
pub y: i32,
pub z: i32,
}
impl Position {
pub fn new(x: i32, y: i32, z: i32) -> Position {
Position {
x: x,
y: y,
z: z,
}
}
pub fn shift(self, dir: Direction) -> Position {
let (ox, oy, oz) = dir.get_offset();
self + (ox, oy, oz)
}
pub fn shift_by(self, dir: Direction, by: i32) -> Position {
let (ox, oy, oz) = dir.get_offset();
self + (ox * by, oy * by, oz * by)
}
}
impl ops::Add<Position> for Position {
type Output = Position;
fn add(self, o: Position) -> Position {
Position {
x: self.x + o.x,
y: self.y + o.y,
z: self.z + o.z,
}
}
}
impl ops::Add<(i32, i32, i32)> for Position {
type Output = Position;
fn add(self, (x, y, z): (i32, i32, i32)) -> Position {
Position {
x: self.x + x,
y: self.y + y,
z: self.z + z,
}
}
}
impl ops::Sub<Position> for Position {
type Output = Position;
fn sub(self, o: Position) -> Position {
Position {
x: self.x - o.x,
y: self.y - o.y,
z: self.z - o.z,
}
}
}
impl ops::Sub<(i32, i32, i32)> for Position {
type Output = Position;
fn sub(self, (x, y, z): (i32, i32, i32)) -> Position {
Position {
x: self.x - x,
y: self.y - y,
z: self.z - z,
}
}
}
impl Default for Position {
fn default() -> Position {
Position::new(0, 0, 0)
}
}
impl fmt::Debug for Position {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "<{},{},{}>", self.x, self.y, self.z)
}
}

View File

@ -9,7 +9,7 @@ use render;
use resources;
use model;
use types::bit::Set;
use types::Direction;
use shared::Direction;
const NUM_WORKERS: usize = 8;

View File

@ -18,6 +18,7 @@ use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use types::hash::FNVHash;
use sdl2::keyboard::Keycode;
use shared::Position as BPosition;
pub fn add_systems(m: &mut ecs::Manager) {
// Not actually rendering related but the faster
@ -570,7 +571,7 @@ fn check_collisions(world: &world::World, position: &mut Position, bounds: Aabb3
for y in min_y .. max_y {
for z in min_z .. max_z {
for x in min_x .. max_x {
let block = world.get_block(x, y, z);
let block = world.get_block(BPosition::new(x, y, z));
for bb in block.get_collision_boxes() {
let bb = bb.add_v(cgmath::Vector3::new(x as f64, y as f64, z as f64));
if bb.collides(&bounds) {

View File

@ -43,6 +43,7 @@ extern crate log;
extern crate lazy_static;
extern crate collision;
pub extern crate steven_blocks;
extern crate steven_shared as shared;
#[macro_use]
pub mod macros;

View File

@ -2,7 +2,8 @@
use std::io::Write;
use std::sync::{Arc, RwLock};
use world::{self, block};
use types::Direction;
use shared::Direction;
use model::BlockVertex;
use render;
pub fn render_liquid<W: Write>(textures: Arc<RwLock<render::TextureManager>>,lava: bool, snapshot: &world::Snapshot, x: i32, y: i32, z: i32, buf: &mut W) -> usize {
@ -42,7 +43,7 @@ pub fn render_liquid<W: Write>(textures: Arc<RwLock<render::TextureManager>>,lav
let special = dir == Direction::Up && (tl < 8 || tr < 8 || bl < 8 || br < 8);
let block = snapshot.get_block(x+ox, y+oy, z+oz);
if special || (!block.get_material().should_cull_against && get_liquid(snapshot, x+ox, y+oy, z+oz).is_none()) {
let verts = dir.get_verts();
let verts = BlockVertex::face_by_direction(dir);
for vert in verts {
let mut vert = vert.clone();
vert.tx = tex.get_x() as u16;

View File

@ -10,7 +10,7 @@ use resources;
use render;
use world;
use world::block::{Block, TintType};
use types::Direction;
use shared::Direction;
use serde_json;
use std::hash::BuildHasherDefault;
@ -507,7 +507,7 @@ impl Factory {
]);
}
let mut verts = all_dirs[i].get_verts().to_vec();
let mut verts = BlockVertex::face_by_direction(all_dirs[i]).to_vec();
let texture_name = raw.lookup_texture(&face.texture);
let texture = render::Renderer::get_texture(&self.textures, &texture_name);
@ -1101,4 +1101,16 @@ impl BlockVertex {
let _ = w.write_u16::<NativeEndian>(0);
let _ = w.write_u16::<NativeEndian>(0);
}
pub fn face_by_direction(dir: Direction) -> &'static [BlockVertex; 4] {
match dir {
Direction::Up => PRECOMPUTED_VERTS[0],
Direction::Down => PRECOMPUTED_VERTS[1],
Direction::North => PRECOMPUTED_VERTS[2],
Direction::South => PRECOMPUTED_VERTS[3],
Direction::West => PRECOMPUTED_VERTS[4],
Direction::East => PRECOMPUTED_VERTS[5],
_ => unreachable!(),
}
}
}

View File

@ -32,6 +32,7 @@ use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
use flate2::read::{ZlibDecoder, ZlibEncoder};
use flate2;
use time;
use shared::Position;
pub const SUPPORTED_PROTOCOL: i32 = 109;
@ -73,6 +74,7 @@ macro_rules! state_packets {
use nbt;
use types;
use item;
use shared::Position;
pub mod internal_ids {
@ -620,6 +622,25 @@ impl fmt::Debug for VarLong {
}
}
impl Serializable for Position {
fn read_from(buf: &mut io::Read) -> Result<Position, io::Error> {
let pos = try!(buf.read_u64::<BigEndian>());
Ok(Position::new(
((pos as i64) >> 38) as i32,
(((pos as i64) >> 26) & 0xFFF) as i32,
((pos as i64) << 38 >> 38) as i32
))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
let pos = (((self.x as u64) & 0x3FFFFFF) << 38)
| (((self.y as u64) & 0xFFF) << 26)
| ((self.z as u64) & 0x3FFFFFF);
try!(buf.write_u64::<BigEndian>(pos));
Result::Ok(())
}
}
/// Direction is used to define whether packets are going to the
/// server or the client.
#[derive(Clone, Copy)]

View File

@ -59,7 +59,7 @@ state_packets!(
text: String =,
assume_command: bool =,
has_target: bool =,
target: Option<types::Position> = when(|p: &TabComplete| p.has_target),
target: Option<Position> = when(|p: &TabComplete| p.has_target),
}
// ChatMessage is sent by the client when it sends a chat message or
// executes a command (prefixed by '/').
@ -177,7 +177,7 @@ state_packets!(
// It also can be sent for droppping items and eating/shooting.
PlayerDigging {
status: VarInt =,
location: types::Position =,
location: Position =,
face: u8 =,
}
// PlayerAction is sent when a player preforms various actions.
@ -212,7 +212,7 @@ state_packets!(
}
// SetSign sets the text on a sign after placing it.
SetSign {
location: types::Position =,
location: Position =,
line1: String =,
line2: String =,
line3: String =,
@ -229,7 +229,7 @@ state_packets!(
}
// PlayerBlockPlacement is sent when the client tries to place a block.
PlayerBlockPlacement {
location: types::Position =,
location: Position =,
face: VarInt =,
hand: VarInt =,
cursor_x: u8 =,
@ -300,7 +300,7 @@ state_packets!(
entity_id: VarInt =,
uuid: UUID =,
title: String =,
location: types::Position =,
location: Position =,
direction: u8 =,
}
// SpawnPlayer is used to spawn a player when they are in range of the client.
@ -329,26 +329,26 @@ state_packets!(
// animation played when a player starts digging a block.
BlockBreakAnimation {
entity_id: VarInt =,
location: types::Position =,
location: Position =,
stage: i8 =,
}
// UpdateBlockEntity updates the nbt tag of a block entity in the
// world.
UpdateBlockEntity {
location: types::Position =,
location: Position =,
action: u8 =,
nbt: Option<nbt::NamedTag> =,
}
// BlockAction triggers different actions depending on the target block.
BlockAction {
location: types::Position =,
location: Position =,
byte1: u8 =,
byte2: u8 =,
block_type: VarInt =,
}
// BlockChange is used to update a single block on the client.
BlockChange {
location: types::Position =,
location: Position =,
block_id: VarInt =,
}
// BossBar displays and/or changes a boss bar that is displayed on the
@ -505,7 +505,7 @@ state_packets!(
// DisableRelative is set to true.
Effect {
effect_id: i32 =,
location: types::Position =,
location: Position =,
data: i32 =,
disable_relative: bool =,
}
@ -596,7 +596,7 @@ state_packets!(
// SignEditorOpen causes the client to open the editor for a sign so that
// it can write to it. Only sent in vanilla when the player places a sign.
SignEditorOpen {
location: types::Position =,
location: Position =,
}
// PlayerAbilities is used to modify the players current abilities. Flying,
// creative, god mode etc.
@ -634,7 +634,7 @@ state_packets!(
// EntityUsedBed is sent by the server when a player goes to bed.
EntityUsedBed {
entity_id: VarInt =,
location: types::Position =,
location: Position =,
}
// EntityDestroy destroys the entities with the ids in the provided slice.
EntityDestroy {
@ -765,7 +765,7 @@ state_packets!(
// SpawnPosition is sent to change the player's current spawn point. Currently
// only used by the client for the compass.
SpawnPosition {
location: types::Position =,
location: Position =,
}
// TimeUpdate is sent to sync the world's time to the client, the client
// will manually tick the time itself so this doesn't need to sent repeatedly
@ -786,7 +786,7 @@ state_packets!(
}
// UpdateSign sets or changes the text on a sign.
UpdateSign {
location: types::Position =,
location: Position =,
line1: format::Component =,
line2: format::Component =,
line3: format::Component =,

View File

@ -8,8 +8,9 @@ use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use std::sync::{Arc, RwLock};
use types::hash::FNVHash;
use types::Direction;
use shared::Direction;
use byteorder::{WriteBytesExt, NativeEndian};
use model::BlockVertex;
pub struct Manager {
collections: Vec<Collection>,
@ -346,7 +347,7 @@ pub fn append_box_texture_scale(
continue;
}
let tex = tex.unwrap();
for vert in dir.get_verts() {
for vert in BlockVertex::face_by_direction(dir) {
let (rr, gg, bb) = if dir == Direction::West || dir == Direction::East {
((255.0 * 0.8) as u8, (255.0 * 0.8) as u8, (255.0 * 0.8) as u8)
} else {

View File

@ -33,6 +33,7 @@ use cgmath;
use collision::Aabb;
use sdl2::keyboard::Keycode;
use types::Gamemode;
use shared::Position;
mod sun;
@ -200,7 +201,7 @@ impl Server {
for z in -7*16 .. 7*16 {
let h = rng.gen_range(3, 10);
for y in 0 .. h {
server.world.set_block(x, y, z, block::Dirt{ snowy: false, variant: block::DirtVariant::Normal });
server.world.set_block(Position::new(x, y, z), block::Dirt{ snowy: false, variant: block::DirtVariant::Normal });
}
}
}
@ -513,9 +514,7 @@ impl Server {
fn on_block_change(&mut self, block_change: packet::play::clientbound::BlockChange) {
self.world.set_block(
block_change.location.get_x(),
block_change.location.get_y(),
block_change.location.get_z(),
block_change.location,
block::Block::by_vanilla_id(block_change.block_id.0 as usize)
);
}
@ -525,9 +524,11 @@ impl Server {
let oz = block_change.chunk_z << 4;
for record in block_change.records.data {
self.world.set_block(
ox + (record.xz >> 4) as i32,
record.y as i32,
oz + (record.xz & 0xF) as i32,
Position::new(
ox + (record.xz >> 4) as i32,
record.y as i32,
oz + (record.xz & 0xF) as i32
),
block::Block::by_vanilla_id(record.block_id.0 as usize)
);
}

View File

@ -1,66 +0,0 @@
// Copyright 2016 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
extern crate byteorder;
use std::fmt;
use protocol::Serializable;
use std::io;
use std::io::Write;
use self::byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
#[derive(Clone, Copy)]
pub struct Position(u64);
impl Position {
#[allow(dead_code)]
pub fn new(x: i32, y: i32, z: i32) -> Position {
Position((((x as u64) & 0x3FFFFFF) << 38) | (((y as u64) & 0xFFF) << 26) |
((z as u64) & 0x3FFFFFF))
}
pub fn get_x(&self) -> i32 {
((self.0 as i64) >> 38) as i32
}
pub fn get_y(&self) -> i32 {
(((self.0 as i64) >> 26) & 0xFFF) as i32
}
pub fn get_z(&self) -> i32 {
((self.0 as i64) << 38 >> 38) as i32
}
}
impl Default for Position {
fn default() -> Position {
Position(0)
}
}
impl fmt::Debug for Position {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "<{},{},{}>", self.get_x(), self.get_y(), self.get_z())
}
}
impl Serializable for Position {
fn read_from(buf: &mut io::Read) -> Result<Position, io::Error> {
Result::Ok(Position(try!(buf.read_u64::<BigEndian>())))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_u64::<BigEndian>(self.0));
Result::Ok(())
}
}

View File

@ -21,6 +21,7 @@ use protocol;
use protocol::Serializable;
use format;
use item;
use shared::Position;
pub struct MetadataKey<T: MetaValue> {
index: i32,
@ -81,12 +82,12 @@ impl Serializable for Metadata {
[try!(f32::read_from(buf)),
try!(f32::read_from(buf)),
try!(f32::read_from(buf))]),
8 => m.put_raw(index, try!(super::Position::read_from(buf))),
8 => m.put_raw(index, try!(Position::read_from(buf))),
9 => {
if try!(bool::read_from(buf)) {
m.put_raw(index, try!(Option::<super::Position>::read_from(buf)));
m.put_raw(index, try!(Option::<Position>::read_from(buf)));
} else {
m.put_raw::<Option<super::Position>>(index, None);
m.put_raw::<Option<Position>>(index, None);
}
}
10 => m.put_raw(index, try!(protocol::VarInt::read_from(buf))),
@ -199,8 +200,8 @@ pub enum Value {
OptionalItemStack(Option<item::Stack>),
Bool(bool),
Vector([f32; 3]),
Position(super::Position),
OptionalPosition(Option<super::Position>),
Position(Position),
OptionalPosition(Option<Position>),
Direction(protocol::VarInt), // TODO: Proper type
OptionalUUID(Option<protocol::UUID>),
Block(u16), // TODO: Proper type
@ -307,7 +308,7 @@ impl MetaValue for [f32; 3] {
}
}
impl MetaValue for super::Position {
impl MetaValue for Position {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::Position(ref val) => val,
@ -319,7 +320,7 @@ impl MetaValue for super::Position {
}
}
impl MetaValue for Option<super::Position> {
impl MetaValue for Option<Position> {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::OptionalPosition(ref val) => val,

View File

@ -12,9 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
mod blockpos;
pub use self::blockpos::*;
mod metadata;
pub use self::metadata::*;
@ -22,127 +19,6 @@ pub mod bit;
pub mod nibble;
pub mod hash;
use model::{PRECOMPUTED_VERTS, BlockVertex};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Direction {
Invalid,
Up,
Down,
North,
South,
West,
East,
}
impl Direction {
pub fn all() -> Vec<Direction> {
vec![
Direction::Up, Direction::Down,
Direction::North, Direction::South,
Direction::West, Direction::East,
]
}
pub fn from_string(val: &str) -> Direction {
match val {
"up" => Direction::Up,
"down" => Direction::Down,
"north" => Direction::North,
"south" => Direction::South,
"west" => Direction::West,
"east" => Direction::East,
_ => Direction::Invalid,
}
}
pub fn opposite(&self) -> Direction {
match *self {
Direction::Up => Direction::Down,
Direction::Down => Direction::Up,
Direction::North => Direction::South,
Direction::South => Direction::North,
Direction::West => Direction::East,
Direction::East => Direction::West,
_ => unreachable!(),
}
}
pub fn clockwise(&self) -> Direction {
match *self {
Direction::Up => Direction::Up,
Direction::Down => Direction::Down,
Direction::East => Direction::South,
Direction::West => Direction::North,
Direction::South => Direction::West,
Direction::North => Direction::East,
_ => unreachable!(),
}
}
pub fn counter_clockwise(&self) -> Direction {
match *self {
Direction::Up => Direction::Up,
Direction::Down => Direction::Down,
Direction::East => Direction::North,
Direction::West => Direction::South,
Direction::South => Direction::East,
Direction::North => Direction::West,
_ => unreachable!(),
}
}
pub fn get_verts(&self) -> &'static [BlockVertex; 4] {
match *self {
Direction::Up => PRECOMPUTED_VERTS[0],
Direction::Down => PRECOMPUTED_VERTS[1],
Direction::North => PRECOMPUTED_VERTS[2],
Direction::South => PRECOMPUTED_VERTS[3],
Direction::West => PRECOMPUTED_VERTS[4],
Direction::East => PRECOMPUTED_VERTS[5],
_ => unreachable!(),
}
}
pub fn get_offset(&self) -> (i32, i32, i32) {
match *self {
Direction::Up => (0, 1, 0),
Direction::Down => (0, -1, 0),
Direction::North => (0, 0, -1),
Direction::South => (0, 0, 1),
Direction::West => (-1, 0, 0),
Direction::East => (1, 0, 0),
_ => unreachable!(),
}
}
pub fn as_string(&self) -> &'static str {
match *self {
Direction::Up => "up",
Direction::Down => "down",
Direction::North => "north",
Direction::South => "south",
Direction::West => "west",
Direction::East => "east",
Direction::Invalid => "invalid",
}
}
pub fn index(&self) -> usize {
match *self {
Direction::Up => 0,
Direction::Down => 1,
Direction::North => 2,
Direction::South => 3,
Direction::West => 4,
Direction::East => 5,
_ => unreachable!(),
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum Gamemode {
Survival = 0,

View File

@ -17,7 +17,8 @@ pub use steven_blocks as block;
use std::collections::HashMap;
use std::collections::VecDeque;
use std::hash::BuildHasherDefault;
use types::{bit, nibble, Direction};
use types::{bit, nibble};
use shared::{Position, Direction};
use types::hash::FNVHash;
use protocol;
use render;
@ -42,25 +43,23 @@ enum LightType {
}
impl LightType {
fn get_light(self, world: &World, x: i32, y: i32, z: i32) -> u8 {
fn get_light(self, world: &World, pos: Position) -> u8 {
match self {
LightType::Block => world.get_block_light(x, y, z),
LightType::Sky => world.get_sky_light(x, y, z),
LightType::Block => world.get_block_light(pos),
LightType::Sky => world.get_sky_light(pos),
}
}
fn set_light(self, world: &mut World, x: i32, y: i32, z: i32, light: u8) {
fn set_light(self, world: &mut World, pos: Position, light: u8) {
match self {
LightType::Block => world.set_block_light(x, y, z, light),
LightType::Sky => world.set_sky_light(x, y, z, light),
LightType::Block => world.set_block_light(pos, light),
LightType::Sky => world.set_sky_light(pos, light),
}
}
}
struct LightUpdate {
ty: LightType,
x: i32,
y: i32,
z: i32,
pos: Position,
}
impl World {
@ -76,31 +75,31 @@ impl World {
self.chunks.contains_key(&CPos(x, z))
}
pub fn set_block(&mut self, x: i32, y: i32, z: i32, b: block::Block) {
if self.set_block_raw(x, y, z, b) {
self.update_block(x, y, z);
pub fn set_block(&mut self, pos: Position, b: block::Block) {
if self.set_block_raw(pos, b) {
self.update_block(pos);
}
}
fn set_block_raw(&mut self, x: i32, y: i32, z: i32, b: block::Block) -> bool {
let cpos = CPos(x >> 4, z >> 4);
fn set_block_raw(&mut self, pos: Position, b: block::Block) -> bool {
let cpos = CPos(pos.x >> 4, pos.z >> 4);
let chunk = self.chunks.entry(cpos).or_insert_with(|| Chunk::new(cpos));
chunk.set_block(x & 0xF, y, z & 0xF, b)
chunk.set_block(pos.x & 0xF, pos.y, pos.z & 0xF, b)
}
pub fn update_block(&mut self, x: i32, y: i32, z: i32) {
pub fn update_block(&mut self, pos: Position) {
for yy in -1 .. 2 {
for zz in -1 .. 2 {
for xx in -1 .. 2 {
let (bx, by, bz) = (x+xx, y+yy, z+zz);
let current = self.get_block(bx, by, bz);
let new = current.update_state(self, bx, by, bz);
let bp = pos + (xx, yy, zz);
let current = self.get_block(bp);
let new = current.update_state(self, bp);
if current != new {
self.set_block_raw(bx, by, bz, new);
self.set_block_raw(bp, new);
}
self.set_dirty(bx >> 4, by >> 4, bz >> 4);
self.update_light(bx, by, bz, LightType::Block);
self.update_light(bx, by, bz, LightType::Sky);
self.set_dirty(bp.x >> 4, bp.y >> 4, bp.z >> 4);
self.update_light(bp, LightType::Block);
self.update_light(bp, LightType::Sky);
}
}
}
@ -110,60 +109,54 @@ impl World {
for by in y1 .. y2 {
for bz in z1 .. z2 {
for bx in x1 .. x2 {
let current = self.get_block(bx, by, bz);
let new = current.update_state(self, bx, by, bz);
let bp = Position::new(bx, by, bz);
let current = self.get_block(bp);
let new = current.update_state(self, bp);
if current != new {
self.set_block_raw(bx, by, bz, new);
self.set_block_raw(bp, new);
}
}
}
}
}
pub fn get_block_offset(&self, x: i32, y: i32, z: i32, dir: Direction) -> block::Block {
let (ox, oy, oz) = dir.get_offset();
self.get_block(x + ox, y + oy, z + oz)
}
pub fn get_block(&self, x: i32, y: i32, z: i32) -> block::Block {
match self.chunks.get(&CPos(x >> 4, z >> 4)) {
Some(ref chunk) => chunk.get_block(x & 0xF, y, z & 0xF),
pub fn get_block(&self, pos: Position) -> block::Block {
match self.chunks.get(&CPos(pos.x >> 4, pos.z >> 4)) {
Some(ref chunk) => chunk.get_block(pos.x & 0xF, pos.y, pos.z & 0xF),
None => block::Missing{},
}
}
fn set_block_light(&mut self, x: i32, y: i32, z: i32, light: u8) {
let cpos = CPos(x >> 4, z >> 4);
fn set_block_light(&mut self, pos: Position, light: u8) {
let cpos = CPos(pos.x >> 4, pos.z >> 4);
let chunk = self.chunks.entry(cpos).or_insert_with(|| Chunk::new(cpos));
chunk.set_block_light(x & 0xF, y, z & 0xF, light);
chunk.set_block_light(pos.x & 0xF, pos.y, pos.z & 0xF, light);
}
fn get_block_light(&self, x: i32, y: i32, z: i32) -> u8 {
match self.chunks.get(&CPos(x >> 4, z >> 4)) {
Some(ref chunk) => chunk.get_block_light(x & 0xF, y, z & 0xF),
fn get_block_light(&self, pos: Position) -> u8 {
match self.chunks.get(&CPos(pos.x >> 4, pos.z >> 4)) {
Some(ref chunk) => chunk.get_block_light(pos.x & 0xF, pos.y, pos.z & 0xF),
None => 0,
}
}
fn set_sky_light(&mut self, x: i32, y: i32, z: i32, light: u8) {
let cpos = CPos(x >> 4, z >> 4);
fn set_sky_light(&mut self, pos: Position, light: u8) {
let cpos = CPos(pos.x >> 4, pos.z >> 4);
let chunk = self.chunks.entry(cpos).or_insert_with(|| Chunk::new(cpos));
chunk.set_sky_light(x & 0xF, y, z & 0xF, light);
chunk.set_sky_light(pos.x & 0xF, pos.y, pos.z & 0xF, light);
}
fn get_sky_light(&self, x: i32, y: i32, z: i32) -> u8 {
match self.chunks.get(&CPos(x >> 4, z >> 4)) {
Some(ref chunk) => chunk.get_sky_light(x & 0xF, y, z & 0xF),
fn get_sky_light(&self, pos: Position) -> u8 {
match self.chunks.get(&CPos(pos.x >> 4, pos.z >> 4)) {
Some(ref chunk) => chunk.get_sky_light(pos.x & 0xF, pos.y, pos.z & 0xF),
None => 15,
}
}
fn update_light(&mut self, x: i32, y: i32, z: i32, ty: LightType) {
fn update_light(&mut self, pos: Position, ty: LightType) {
self.light_updates.push_back(LightUpdate {
ty: ty,
x: x,
y: y,
z: z,
pos: pos,
});
}
@ -186,17 +179,16 @@ impl World {
fn do_light_update(&mut self) {
use std::cmp;
if let Some(update) = self.light_updates.pop_front() {
if update.y < 0 || update.y > 255 || !self.is_chunk_loaded(update.x >> 4, update.z >> 4) {
if update.pos.y < 0 || update.pos.y > 255 || !self.is_chunk_loaded(update.pos.x >> 4, update.pos.z >> 4) {
return;
}
let block = self.get_block(update.x, update.y, update.z).get_material();
let block = self.get_block(update.pos).get_material();
// Find the brightest source of light nearby
let mut best = update.ty.get_light(self, update.x, update.y, update.z);
let mut best = update.ty.get_light(self, update.pos);
let old = best;
for dir in Direction::all() {
let (ox, oy, oz) = dir.get_offset();
let light = update.ty.get_light(self, update.x + ox, update.y + oy, update.z + oz);
let light = update.ty.get_light(self, update.pos.shift(dir));
if light > best {
best = light;
}
@ -210,7 +202,7 @@ impl World {
// Sky light doesn't decrease when going down at full brightness
if update.ty == LightType::Sky
&& block.absorbed_light == 0
&& update.ty.get_light(self, update.x, update.y + 1, update.z) == 15 {
&& update.ty.get_light(self, update.pos.shift(Direction::Up)) == 15 {
best = 15;
}
@ -219,21 +211,20 @@ impl World {
return;
}
// Use our new light value
update.ty.set_light(self, update.x, update.y, update.z, best);
update.ty.set_light(self, update.pos, best);
// Flag surrounding chunks as dirty
for yy in -1 .. 2 {
for zz in -1 .. 2 {
for xx in -1 .. 2 {
let (bx, by, bz) = (update.x+xx, update.y+yy, update.z+zz);
self.set_dirty(bx >> 4, by >> 4, bz >> 4);
let bp = update.pos + (xx, yy, zz);
self.set_dirty(bp.x >> 4, bp.y >> 4, bp.z >> 4);
}
}
}
// Update surrounding blocks
for dir in Direction::all() {
let (ox, oy, oz) = dir.get_offset();
self.update_light(update.x + ox, update.y + oy, update.z + oz, update.ty);
self.update_light(update.pos.shift(dir), update.ty);
}
}
}
@ -259,7 +250,6 @@ impl World {
pub fn compute_render_list(&mut self, renderer: &mut render::Renderer) {
use chunk_builder;
use types::Direction;
use cgmath::Vector;
use std::collections::VecDeque;
self.render_list.clear();
@ -591,8 +581,8 @@ impl World {
}
impl block::WorldAccess for World {
fn get_block(&self, x: i32, y: i32, z: i32) -> block::Block {
World::get_block(self, x, y, z)
fn get_block(&self, pos: Position) -> block::Block {
World::get_block(self, pos)
}
}