Skip to content
This repository has been archived by the owner on Jul 1, 2024. It is now read-only.

Commit

Permalink
Implement SectionLightData
Browse files Browse the repository at this point in the history
  • Loading branch information
DimitriTimoz committed Dec 24, 2023
1 parent 5e0ed0f commit 782f974
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
80 changes: 80 additions & 0 deletions minecraft-server/src/world/light.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use crate::prelude::*;
use super::*;

const MAX_LIGHT_LEVEL: u8 = 15;

#[derive(Debug, Clone)]
struct SectionLightData(Vec<u8>); // TODO(optimization): Use simd

impl SectionLightData {
pub fn new() -> SectionLightData {
SectionLightData(vec![0; 2048])
}

pub fn set_with(&mut self, level: u8) {
let level = level << 4 | level;
self.0.iter_mut().for_each(|v| *v = level);
}


/// Get the light level at the given position.
pub fn get(&self, postion: BlockPositionInChunk) -> Result<u8, ()> {
let (x, y, z) = (postion.bx as usize, postion.by as usize, postion.bz as usize);
let index = (y << 8) | (z << 4) | x;
let byte_index = index >> 1;

if byte_index >= 2048 {
return Err(());
}

if index & 1 == 0 {
Ok(self.0[byte_index] & 0x0F)
} else {
Ok((self.0[byte_index] & 0xF0) >> 4)
}
}

/// Set the light level at the given position.
pub fn set(&mut self, postion: BlockPositionInChunk, level: u8) -> Result<(), ()> {
if level > MAX_LIGHT_LEVEL {
return Err(());
}

let (x, y, z) = (postion.bx as usize, postion.by as usize, postion.bz as usize);
let index = (y << 8) | (z << 4) | x;
let byte_index = index >> 1;

if byte_index >= 2048 {
return Err(());
}

if index & 1 == 0 {
self.0[byte_index] = (self.0[byte_index] & 0xF0) | (level & 0x0F);
} else {
self.0[byte_index] = (self.0[byte_index] & 0x0F) | ((level & 0x0F) << 4);
}

Ok(())
}

/// Set the light level at the given layer to the given level.
pub(super) fn set_layer(&mut self, layer: u8 , level: u8) -> Result<(), ()> {
if level > MAX_LIGHT_LEVEL {
return Err(());
}

if layer > MAX_LIGHT_LEVEL {
return Err(());
}

let level = level << 4 | level;
let layer = layer as usize;

// Because a layer is 16x16 blocks, we can just set 128 blocks at once and the y coordinate is the most significant bit of the index.
for i in layer*128..(layer+1)*128 {
self.0[i] = level;
}

Ok(())
}
}
2 changes: 2 additions & 0 deletions minecraft-server/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ mod loading_manager;
use loading_manager::*;
mod map;
use map::*;
mod light;
use light::*;
mod ecs;
use ecs::*;
mod collisions;
Expand Down

0 comments on commit 782f974

Please sign in to comment.