Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: include terrain #26

Merged
merged 1 commit into from
Mar 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ COPY .cargo ./.cargo

COPY Cargo.toml Cargo.lock ./

COPY chunk/Cargo.toml ./chunk/Cargo.toml
COPY chunk/src ./chunk/src

COPY server/Cargo.toml ./server/Cargo.toml
COPY server/src ./server/src

Expand Down
2 changes: 2 additions & 0 deletions chunk/src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ impl IntoBlock for BlockState {
}

pub const SECTION_BLOCK_COUNT: usize = 16 * 16 * 16;
pub const SLICE_BLOCK_COUNT: usize = 16 * 16;

pub const SECTION_BIOME_COUNT: usize = 4 * 4 * 4;

/// The maximum height of a chunk.
Expand Down
3 changes: 2 additions & 1 deletion server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ chunk.workspace = true

#azalea-buf = { git = "https://github.com/azalea-rs/azalea", branch = "1.20.1" }
#azalea-world = { git = "https://github.com/azalea-rs/azalea", branch = "1.20.1" }
#azalea-buf = { git = "https://github.com/azalea-rs/azalea" }
azalea-buf = { git = "https://github.com/azalea-rs/azalea" }
azalea-world = { git = "https://github.com/azalea-rs/azalea" }


Expand All @@ -36,6 +36,7 @@ flume = "0.11.0"
monoio = { version = "0.2.3", features = ["sync"] }
signal-hook = "0.3.17"
base64 = "0.21.7"
#bit-set = "0.5.3"


[lints.rust]
Expand Down
3 changes: 0 additions & 3 deletions server/src/blocks.rs

This file was deleted.

2 changes: 0 additions & 2 deletions server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ mod handshake;
mod packets;
mod system;

mod blocks;

// A zero-sized component, often called a "marker" or "tag".
#[derive(Component)]
struct Player {
Expand Down
97 changes: 84 additions & 13 deletions server/src/system/player_join_world.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::{borrow::Cow, io::Write};

use azalea_world::BitStorage;
use chunk::{
bit_width,
chunk::{BiomeContainer, BlockStateContainer, SECTION_BLOCK_COUNT},
chunk::{BiomeContainer, BlockStateContainer, SECTION_BLOCK_COUNT, SLICE_BLOCK_COUNT},
palette::{BlockGetter, DirectEncoding},
};
use evenio::prelude::*;
Expand All @@ -12,7 +13,7 @@ use valence_protocol::{
math::DVec3,
nbt::{compound, List},
packets::{play, play::player_position_look_s2c::PlayerPositionLookFlags},
BlockPos, BlockState, ChunkPos, Encode,
BlockPos, BlockState, ChunkPos, Encode, FixedArray,
};
use valence_registry::{biome::BiomeId, RegistryIdx};

Expand Down Expand Up @@ -64,6 +65,25 @@ fn write_biomes(biomes: BiomeContainer, writer: &mut impl Write) -> anyhow::Resu
Ok(())
}

trait Array3d {
type Item;
fn get3(&self, x: usize, y: usize, z: usize) -> &Self::Item;
fn get3_mut(&mut self, x: usize, y: usize, z: usize) -> &mut Self::Item;
}

#[allow(clippy::indexing_slicing)]
impl<T, const N: usize> Array3d for [T; N] {
type Item = T;

fn get3(&self, x: usize, y: usize, z: usize) -> &Self::Item {
&self[x + z * 16 + y * 16 * 16]
}

fn get3_mut(&mut self, x: usize, y: usize, z: usize) -> &mut Self::Item {
&mut self[x + z * 16 + y * 16 * 16]
}
}

fn air_section() -> Vec<u8> {
let mut section_bytes = Vec::new();
0_u16.encode(&mut section_bytes).unwrap();
Expand All @@ -77,19 +97,54 @@ fn air_section() -> Vec<u8> {
section_bytes
}

fn stone_section() -> Vec<u8> {
let mut section_bytes = Vec::new();
(SECTION_BLOCK_COUNT as u16)
.encode(&mut section_bytes)
.unwrap();

let mut blocks = [BlockState::STONE; SECTION_BLOCK_COUNT];
let block_states = BlockStateContainer::Direct(Box::new(blocks));
write_block_states(block_states, &mut section_bytes).unwrap();

let biomes = BiomeContainer::Single(BiomeId::DEFAULT);
write_biomes(biomes, &mut section_bytes).unwrap();

section_bytes
}

fn ground_section() -> Vec<u8> {
let mut section_bytes = Vec::new();

let number_blocks: u16 = 16 * 16;
number_blocks.encode(&mut section_bytes).unwrap();

let blocks: [_; SECTION_BLOCK_COUNT] = std::array::from_fn(|i| {
if i < 16 * 16 {
BlockState::GRASS_BLOCK
} else {
BlockState::AIR
let mut blocks = [BlockState::AIR; SECTION_BLOCK_COUNT];
// set sin wave with peak at center of chunk

let bedrock_layers = 3;

for block in blocks.iter_mut().take(SLICE_BLOCK_COUNT * bedrock_layers) {
*block = BlockState::BEDROCK;
}

#[allow(clippy::cast_sign_loss)]
#[allow(clippy::suboptimal_flops)]
#[allow(clippy::indexing_slicing)]
for x in 0..16 {
for z in 0..16 {
let dist_from_center = (x as f64 - 8.0).hypot(z as f64 - 8.0);

// based on x and z
// should be highest at center of chunk
let height = (16.0 - dist_from_center) * 0.5 + 3.0;
let height = height as usize;
let height = height.min(16);
for y in 0..height {
*blocks.get3_mut(x, y, z) = BlockState::SAND;
}
}
});
}

let block_states = BlockStateContainer::Direct(Box::new(blocks));

Expand All @@ -112,7 +167,7 @@ fn inner(io: &mut Player) -> anyhow::Result<()> {
})?;

io.writer.send_packet(&play::PlayerPositionLookS2c {
position: DVec3::new(0.0, 3.0, 0.0),
position: DVec3::new(0.0, 30.0, 0.0),
yaw: 0.0,
pitch: 0.0,
flags: PlayerPositionLookFlags::default(),
Expand All @@ -124,15 +179,24 @@ fn inner(io: &mut Player) -> anyhow::Result<()> {
chunk_z: 0.into(),
})?;

let section_count = 384 / 16;
let section_count = 384 / 16_usize;
let air_section = air_section();
let ground_section = ground_section();
let stone_section = stone_section();

let mut bytes = Vec::new();

bytes.extend_from_slice(&stone_section);
bytes.extend_from_slice(&stone_section);
bytes.extend_from_slice(&stone_section);
bytes.extend_from_slice(&stone_section);
bytes.extend_from_slice(&ground_section);

for _ in (0..section_count).skip(1) {
// 2048 bytes per section -> long count = 2048 / 8 = 256
let sky_light_array = FixedArray([0xFF_u8; 2048]);
let sky_light_arrays = vec![sky_light_array; section_count + 2];

for _ in (0..section_count).skip(5) {
bytes.extend_from_slice(&air_section);
}

Expand All @@ -141,6 +205,13 @@ fn inner(io: &mut Player) -> anyhow::Result<()> {
let map = heightmap(dimension_height, dimension_height - 3);
let map: Vec<_> = map.into_iter().map(i64::try_from).try_collect()?;

// convert section_count + 2 0b1s into u64 array
let mut bits = BitStorage::new(1, section_count + 2, None).unwrap();

for i in 0..section_count + 2 {
bits.set(i, 1);
}

let mut pkt = play::ChunkDataS2c {
pos: ChunkPos::new(0, 0),
heightmaps: Cow::Owned(compound! {
Expand All @@ -149,11 +220,11 @@ fn inner(io: &mut Player) -> anyhow::Result<()> {
blocks_and_biomes: &bytes,
block_entities: Cow::Borrowed(&[]),

sky_light_mask: Cow::Borrowed(&[]),
sky_light_mask: Cow::Owned(bits.data),
block_light_mask: Cow::Borrowed(&[]),
empty_sky_light_mask: Cow::Borrowed(&[]),
empty_block_light_mask: Cow::Borrowed(&[]),
sky_light_arrays: Cow::Borrowed(&[]),
sky_light_arrays: Cow::Owned(sky_light_arrays),
block_light_arrays: Cow::Borrowed(&[]),
};
for x in -16..=16 {
Expand Down
Loading