chore: less awaits more fun part 2
This commit is contained in:
parent
d5026cb55e
commit
cf9c7e85dc
@ -89,12 +89,6 @@ inherits = "release"
|
|||||||
debug = true
|
debug = true
|
||||||
strip = false
|
strip = false
|
||||||
|
|
||||||
[profile.dev]
|
|
||||||
debug = "line-tables-only"
|
|
||||||
debug-assertions = true
|
|
||||||
overflow-checks = false
|
|
||||||
split-debuginfo = "packed"
|
|
||||||
opt-level = 0
|
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
tokio = { version = "1.52", default-features = false }
|
tokio = { version = "1.52", default-features = false }
|
||||||
|
|||||||
@ -697,27 +697,27 @@ impl Level {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_block_state(self: &Arc<Self>, position: &BlockPos) -> RawBlockState {
|
pub fn get_block_state(&self, position: &BlockPos) -> RawBlockState {
|
||||||
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
|
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
|
||||||
let id = self
|
let id = self
|
||||||
.get_or_fetch_chunk(chunk_coordinate, |chunk| {
|
.read_chunk_sync(&chunk_coordinate, |chunk| {
|
||||||
chunk.section.get_block_absolute_y(
|
chunk.section.get_block_absolute_y(
|
||||||
relative.x as usize,
|
relative.x as usize,
|
||||||
relative.y,
|
relative.y,
|
||||||
relative.z as usize,
|
relative.z as usize,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.await;
|
.flatten();
|
||||||
RawBlockState(id.unwrap_or(Block::VOID_AIR.default_state.id))
|
RawBlockState(id.unwrap_or(Block::VOID_AIR.default_state.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_block_state(
|
pub fn set_block_state(
|
||||||
self: &Arc<Self>,
|
&self,
|
||||||
position: &BlockPos,
|
position: &BlockPos,
|
||||||
block_state_id: BlockStateId,
|
block_state_id: BlockStateId,
|
||||||
) -> BlockStateId {
|
) -> BlockStateId {
|
||||||
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
|
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
|
||||||
self.get_or_fetch_chunk(chunk_coordinate, |chunk| {
|
self.read_chunk_sync(&chunk_coordinate, |chunk| {
|
||||||
let replaced_block_state_id = chunk.set_block_absolute_y(
|
let replaced_block_state_id = chunk.set_block_absolute_y(
|
||||||
relative.x as usize,
|
relative.x as usize,
|
||||||
relative.y,
|
relative.y,
|
||||||
@ -729,7 +729,7 @@ impl Level {
|
|||||||
}
|
}
|
||||||
replaced_block_state_id
|
replaced_block_state_id
|
||||||
})
|
})
|
||||||
.await
|
.unwrap_or(Block::VOID_AIR.default_state.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn write_chunks(&self, chunks_to_write: Vec<(Vector2<i32>, SyncChunk)>) {
|
pub async fn write_chunks(&self, chunks_to_write: Vec<(Vector2<i32>, SyncChunk)>) {
|
||||||
@ -831,8 +831,8 @@ impl Level {
|
|||||||
self.loaded_entity_chunks.try_get(&coordinates).try_unwrap()
|
self.loaded_entity_chunks.try_get(&coordinates).try_unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn schedule_block_tick(
|
pub fn schedule_block_tick(
|
||||||
self: &Arc<Self>,
|
&self,
|
||||||
block: &Block,
|
block: &Block,
|
||||||
block_pos: BlockPos,
|
block_pos: BlockPos,
|
||||||
delay: u8,
|
delay: u8,
|
||||||
@ -847,15 +847,18 @@ impl Level {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let chunk_pos = block_pos.chunk_position();
|
let chunk_pos = block_pos.chunk_position();
|
||||||
self.get_or_fetch_chunk(chunk_pos, |chunk| {
|
if self
|
||||||
chunk.block_ticks.schedule_tick(&scheduled_tick, tick_order);
|
.read_chunk_sync(&chunk_pos, |chunk| {
|
||||||
})
|
chunk.block_ticks.schedule_tick(&scheduled_tick, tick_order);
|
||||||
.await;
|
})
|
||||||
self.chunks_with_scheduled_ticks.insert(chunk_pos);
|
.is_some()
|
||||||
|
{
|
||||||
|
self.chunks_with_scheduled_ticks.insert(chunk_pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn schedule_fluid_tick(
|
pub fn schedule_fluid_tick(
|
||||||
self: &Arc<Self>,
|
&self,
|
||||||
fluid: &Fluid,
|
fluid: &Fluid,
|
||||||
block_pos: BlockPos,
|
block_pos: BlockPos,
|
||||||
delay: u8,
|
delay: u8,
|
||||||
@ -870,32 +873,27 @@ impl Level {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let chunk_pos = block_pos.chunk_position();
|
let chunk_pos = block_pos.chunk_position();
|
||||||
self.get_or_fetch_chunk(chunk_pos, |chunk| {
|
if self
|
||||||
chunk.fluid_ticks.schedule_tick(&scheduled_tick, tick_order);
|
.read_chunk_sync(&chunk_pos, |chunk| {
|
||||||
})
|
chunk.fluid_ticks.schedule_tick(&scheduled_tick, tick_order);
|
||||||
.await;
|
})
|
||||||
self.chunks_with_scheduled_ticks.insert(chunk_pos);
|
.is_some()
|
||||||
|
{
|
||||||
|
self.chunks_with_scheduled_ticks.insert(chunk_pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn is_block_tick_scheduled(
|
pub fn is_block_tick_scheduled(&self, block_pos: &BlockPos, block: &Block) -> bool {
|
||||||
self: &Arc<Self>,
|
self.read_chunk_sync(&block_pos.chunk_position(), |chunk| {
|
||||||
block_pos: &BlockPos,
|
|
||||||
block: &Block,
|
|
||||||
) -> bool {
|
|
||||||
self.get_or_fetch_chunk(block_pos.chunk_position(), |chunk| {
|
|
||||||
chunk.block_ticks.is_scheduled(*block_pos, block)
|
chunk.block_ticks.is_scheduled(*block_pos, block)
|
||||||
})
|
})
|
||||||
.await
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn is_fluid_tick_scheduled(
|
pub fn is_fluid_tick_scheduled(&self, block_pos: &BlockPos, fluid: &Fluid) -> bool {
|
||||||
self: &Arc<Self>,
|
self.read_chunk_sync(&block_pos.chunk_position(), |chunk| {
|
||||||
block_pos: &BlockPos,
|
|
||||||
fluid: &Fluid,
|
|
||||||
) -> bool {
|
|
||||||
self.get_or_fetch_chunk(block_pos.chunk_position(), |chunk| {
|
|
||||||
chunk.fluid_ticks.is_scheduled(*block_pos, fluid)
|
chunk.fluid_ticks.is_scheduled(*block_pos, fluid)
|
||||||
})
|
})
|
||||||
.await
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,7 +40,7 @@ impl DynamicLightEngine {
|
|||||||
while current_pos.0.y < max_y {
|
while current_pos.0.y < max_y {
|
||||||
current_pos.0.y += 1;
|
current_pos.0.y += 1;
|
||||||
|
|
||||||
let state = level.get_block_state(¤t_pos).await.to_state();
|
let state = level.get_block_state(¤t_pos).to_state();
|
||||||
if state.opacity > 0 {
|
if state.opacity > 0 {
|
||||||
return false; // Hit an opaque block before reaching sky
|
return false; // Hit an opaque block before reaching sky
|
||||||
}
|
}
|
||||||
@ -130,8 +130,8 @@ impl DynamicLightEngine {
|
|||||||
for dir in BlockDirection::all() {
|
for dir in BlockDirection::all() {
|
||||||
let neighbor_pos = pos.offset(dir.to_offset());
|
let neighbor_pos = pos.offset(dir.to_offset());
|
||||||
|
|
||||||
if let Some(neighbor_light) = self.get_block_light_level(level, &neighbor_pos).await {
|
if let Some(neighbor_light) = self.get_block_light_level(level, &neighbor_pos) {
|
||||||
let neighbor_state = level.get_block_state(&neighbor_pos).await.to_state();
|
let neighbor_state = level.get_block_state(&neighbor_pos).to_state();
|
||||||
let opacity = neighbor_state.opacity.max(1);
|
let opacity = neighbor_state.opacity.max(1);
|
||||||
let new_light = light_level.saturating_sub(opacity);
|
let new_light = light_level.saturating_sub(opacity);
|
||||||
|
|
||||||
@ -139,7 +139,6 @@ impl DynamicLightEngine {
|
|||||||
if new_light > neighbor_light
|
if new_light > neighbor_light
|
||||||
&& self
|
&& self
|
||||||
.set_block_light_level(level, &neighbor_pos, new_light)
|
.set_block_light_level(level, &neighbor_pos, new_light)
|
||||||
.await
|
|
||||||
.is_ok()
|
.is_ok()
|
||||||
&& new_light > 1
|
&& new_light > 1
|
||||||
{
|
{
|
||||||
@ -156,7 +155,7 @@ impl DynamicLightEngine {
|
|||||||
removed_light_level: u8,
|
removed_light_level: u8,
|
||||||
) {
|
) {
|
||||||
// Check what the current light level actually is at this position
|
// Check what the current light level actually is at this position
|
||||||
let current_level = self.get_block_light_level(level, pos).await.unwrap_or(0);
|
let current_level = self.get_block_light_level(level, pos).unwrap_or(0);
|
||||||
|
|
||||||
// Only propagate decrease if this position hasn't already been reset to 0
|
// Only propagate decrease if this position hasn't already been reset to 0
|
||||||
// This prevents positions that were intentionally set to 0 from propagating light
|
// This prevents positions that were intentionally set to 0 from propagating light
|
||||||
@ -165,13 +164,12 @@ impl DynamicLightEngine {
|
|||||||
for dir in BlockDirection::all() {
|
for dir in BlockDirection::all() {
|
||||||
let neighbor_pos = pos.offset(dir.to_offset());
|
let neighbor_pos = pos.offset(dir.to_offset());
|
||||||
|
|
||||||
if let Some(neighbor_light) = self.get_block_light_level(level, &neighbor_pos).await
|
if let Some(neighbor_light) = self.get_block_light_level(level, &neighbor_pos) {
|
||||||
{
|
|
||||||
if neighbor_light == 0 {
|
if neighbor_light == 0 {
|
||||||
continue; // Skip if already 0
|
continue; // Skip if already 0
|
||||||
}
|
}
|
||||||
|
|
||||||
let neighbor_state = level.get_block_state(&neighbor_pos).await.to_state();
|
let neighbor_state = level.get_block_state(&neighbor_pos).to_state();
|
||||||
let opacity = neighbor_state.opacity.max(1);
|
let opacity = neighbor_state.opacity.max(1);
|
||||||
|
|
||||||
let expected_from_removed_source = removed_light_level.saturating_sub(opacity);
|
let expected_from_removed_source = removed_light_level.saturating_sub(opacity);
|
||||||
@ -181,14 +179,11 @@ impl DynamicLightEngine {
|
|||||||
|
|
||||||
if neighbor_luminance == 0 {
|
if neighbor_luminance == 0 {
|
||||||
// No self-emission, darken it completely and continue propagation
|
// No self-emission, darken it completely and continue propagation
|
||||||
self.set_block_light_level(level, &neighbor_pos, 0)
|
self.set_block_light_level(level, &neighbor_pos, 0).ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
self.queue_block_light_decrease(neighbor_pos, neighbor_light);
|
self.queue_block_light_decrease(neighbor_pos, neighbor_light);
|
||||||
} else {
|
} else {
|
||||||
// Has self-emission, set to its own light and re-propagate from it
|
// Has self-emission, set to its own light and re-propagate from it
|
||||||
self.set_block_light_level(level, &neighbor_pos, neighbor_luminance)
|
self.set_block_light_level(level, &neighbor_pos, neighbor_luminance)
|
||||||
.await
|
|
||||||
.ok();
|
.ok();
|
||||||
self.queue_block_light_increase(neighbor_pos, neighbor_luminance);
|
self.queue_block_light_increase(neighbor_pos, neighbor_luminance);
|
||||||
}
|
}
|
||||||
@ -204,32 +199,28 @@ impl DynamicLightEngine {
|
|||||||
pub async fn check_block_light_updates(&self, level: &Arc<Level>, pos: BlockPos) {
|
pub async fn check_block_light_updates(&self, level: &Arc<Level>, pos: BlockPos) {
|
||||||
match level.lighting_config {
|
match level.lighting_config {
|
||||||
LightingEngineConfig::Full => {
|
LightingEngineConfig::Full => {
|
||||||
self.set_block_light_level(level, &pos, 15).await.ok();
|
self.set_block_light_level(level, &pos, 15).ok();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LightingEngineConfig::Dark => {
|
LightingEngineConfig::Dark => {
|
||||||
self.set_block_light_level(level, &pos, 0).await.ok();
|
self.set_block_light_level(level, &pos, 0).ok();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LightingEngineConfig::Default => {}
|
LightingEngineConfig::Default => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let current_light = self.get_block_light_level(level, &pos).await.unwrap_or(0);
|
let current_light = self.get_block_light_level(level, &pos).unwrap_or(0);
|
||||||
let block_state = level.get_block_state(&pos).await.to_state();
|
let block_state = level.get_block_state(&pos).to_state();
|
||||||
let expected_light = block_state.luminance;
|
let expected_light = block_state.luminance;
|
||||||
|
|
||||||
// Handle light decrease (removing light source or placing opaque block)
|
// Handle light decrease (removing light source or placing opaque block)
|
||||||
if expected_light < current_light {
|
if expected_light < current_light {
|
||||||
// Set to expected value immediately, then queue decrease to darken neighbors
|
// Set to expected value immediately, then queue decrease to darken neighbors
|
||||||
self.set_block_light_level(level, &pos, expected_light)
|
self.set_block_light_level(level, &pos, expected_light).ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
self.queue_block_light_decrease(pos, current_light);
|
self.queue_block_light_decrease(pos, current_light);
|
||||||
} else if expected_light > current_light {
|
} else if expected_light > current_light {
|
||||||
// Handle light increase (placing light source)
|
// Handle light increase (placing light source)
|
||||||
self.set_block_light_level(level, &pos, expected_light)
|
self.set_block_light_level(level, &pos, expected_light).ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
self.queue_block_light_increase(pos, expected_light);
|
self.queue_block_light_increase(pos, expected_light);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +240,7 @@ impl DynamicLightEngine {
|
|||||||
) {
|
) {
|
||||||
for dir in BlockDirection::all() {
|
for dir in BlockDirection::all() {
|
||||||
let neighbor_pos = pos.offset(dir.to_offset());
|
let neighbor_pos = pos.offset(dir.to_offset());
|
||||||
if let Some(neighbor_light) = self.get_block_light_level(level, &neighbor_pos).await
|
if let Some(neighbor_light) = self.get_block_light_level(level, &neighbor_pos)
|
||||||
&& neighbor_light > current_light + 1
|
&& neighbor_light > current_light + 1
|
||||||
{
|
{
|
||||||
self.queue_block_light_increase(neighbor_pos, neighbor_light);
|
self.queue_block_light_increase(neighbor_pos, neighbor_light);
|
||||||
@ -301,8 +292,8 @@ impl DynamicLightEngine {
|
|||||||
for dir in BlockDirection::all() {
|
for dir in BlockDirection::all() {
|
||||||
let neighbor_pos = pos.offset(dir.to_offset());
|
let neighbor_pos = pos.offset(dir.to_offset());
|
||||||
|
|
||||||
let neighbor_light = self.get_sky_light_level(level, &neighbor_pos).await;
|
let neighbor_light = self.get_sky_light_level(level, &neighbor_pos);
|
||||||
let neighbor_state = level.get_block_state(&neighbor_pos).await.to_state();
|
let neighbor_state = level.get_block_state(&neighbor_pos).to_state();
|
||||||
let opacity = neighbor_state.opacity;
|
let opacity = neighbor_state.opacity;
|
||||||
|
|
||||||
// Calculate new light level for neighbor
|
// Calculate new light level for neighbor
|
||||||
@ -317,7 +308,6 @@ impl DynamicLightEngine {
|
|||||||
// Only propagate if new light is brighter than current light
|
// Only propagate if new light is brighter than current light
|
||||||
if new_light > neighbor_light {
|
if new_light > neighbor_light {
|
||||||
self.set_sky_light_level(level, &neighbor_pos, new_light)
|
self.set_sky_light_level(level, &neighbor_pos, new_light)
|
||||||
.await
|
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
if new_light > 0 {
|
if new_light > 0 {
|
||||||
@ -336,12 +326,12 @@ impl DynamicLightEngine {
|
|||||||
for dir in BlockDirection::all() {
|
for dir in BlockDirection::all() {
|
||||||
let neighbor_pos = pos.offset(dir.to_offset());
|
let neighbor_pos = pos.offset(dir.to_offset());
|
||||||
|
|
||||||
let neighbor_light = self.get_sky_light_level(level, &neighbor_pos).await;
|
let neighbor_light = self.get_sky_light_level(level, &neighbor_pos);
|
||||||
if neighbor_light == 0 {
|
if neighbor_light == 0 {
|
||||||
continue; // Already dark
|
continue; // Already dark
|
||||||
}
|
}
|
||||||
|
|
||||||
let neighbor_state = level.get_block_state(&neighbor_pos).await.to_state();
|
let neighbor_state = level.get_block_state(&neighbor_pos).to_state();
|
||||||
let opacity = neighbor_state.opacity;
|
let opacity = neighbor_state.opacity;
|
||||||
|
|
||||||
// Calculate what we would have given this neighbor
|
// Calculate what we would have given this neighbor
|
||||||
@ -353,7 +343,7 @@ impl DynamicLightEngine {
|
|||||||
|
|
||||||
if neighbor_light == expected || neighbor_light < removed_light {
|
if neighbor_light == expected || neighbor_light < removed_light {
|
||||||
// This neighbor was lit by us, darken it
|
// This neighbor was lit by us, darken it
|
||||||
self.set_sky_light_level(level, &neighbor_pos, 0).await.ok();
|
self.set_sky_light_level(level, &neighbor_pos, 0).ok();
|
||||||
self.queue_sky_light_decrease(neighbor_pos, neighbor_light);
|
self.queue_sky_light_decrease(neighbor_pos, neighbor_light);
|
||||||
} else if neighbor_light > removed_light {
|
} else if neighbor_light > removed_light {
|
||||||
// Neighbor has brighter light from another source
|
// Neighbor has brighter light from another source
|
||||||
@ -366,18 +356,18 @@ impl DynamicLightEngine {
|
|||||||
pub async fn check_sky_light_updates(&self, level: &Arc<Level>, pos: BlockPos) {
|
pub async fn check_sky_light_updates(&self, level: &Arc<Level>, pos: BlockPos) {
|
||||||
match level.lighting_config {
|
match level.lighting_config {
|
||||||
LightingEngineConfig::Full => {
|
LightingEngineConfig::Full => {
|
||||||
self.set_sky_light_level(level, &pos, 15).await.ok();
|
self.set_sky_light_level(level, &pos, 15).ok();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LightingEngineConfig::Dark => {
|
LightingEngineConfig::Dark => {
|
||||||
self.set_sky_light_level(level, &pos, 0).await.ok();
|
self.set_sky_light_level(level, &pos, 0).ok();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LightingEngineConfig::Default => {}
|
LightingEngineConfig::Default => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let current_light = self.get_sky_light_level(level, &pos).await;
|
let current_light = self.get_sky_light_level(level, &pos);
|
||||||
let block_state = level.get_block_state(&pos).await.to_state();
|
let block_state = level.get_block_state(&pos).to_state();
|
||||||
let opacity = block_state.opacity;
|
let opacity = block_state.opacity;
|
||||||
|
|
||||||
// Calculate expected sky light
|
// Calculate expected sky light
|
||||||
@ -398,7 +388,7 @@ impl DynamicLightEngine {
|
|||||||
for dir in BlockDirection::all() {
|
for dir in BlockDirection::all() {
|
||||||
let neighbor_pos = pos.offset(dir.to_offset());
|
let neighbor_pos = pos.offset(dir.to_offset());
|
||||||
|
|
||||||
let neighbor_light = self.get_sky_light_level(level, &neighbor_pos).await;
|
let neighbor_light = self.get_sky_light_level(level, &neighbor_pos);
|
||||||
// Calculate potential light from this neighbor
|
// Calculate potential light from this neighbor
|
||||||
let potential = if neighbor_light == 15 && dir == BlockDirection::Up {
|
let potential = if neighbor_light == 15 && dir == BlockDirection::Up {
|
||||||
// Sky light at 15 from above stays 15
|
// Sky light at 15 from above stays 15
|
||||||
@ -419,15 +409,11 @@ impl DynamicLightEngine {
|
|||||||
// Update if needed
|
// Update if needed
|
||||||
if expected_light < current_light {
|
if expected_light < current_light {
|
||||||
// Light decreased
|
// Light decreased
|
||||||
self.set_sky_light_level(level, &pos, expected_light)
|
self.set_sky_light_level(level, &pos, expected_light).ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
self.queue_sky_light_decrease(pos, current_light);
|
self.queue_sky_light_decrease(pos, current_light);
|
||||||
} else if expected_light > current_light {
|
} else if expected_light > current_light {
|
||||||
// Light increased
|
// Light increased
|
||||||
self.set_sky_light_level(level, &pos, expected_light)
|
self.set_sky_light_level(level, &pos, expected_light).ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
self.queue_sky_light_increase(pos, expected_light);
|
self.queue_sky_light_increase(pos, expected_light);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,70 +475,62 @@ impl DynamicLightEngine {
|
|||||||
.unwrap_or(0)
|
.unwrap_or(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_block_light_level(
|
pub fn get_block_light_level(&self, level: &Arc<Level>, position: &BlockPos) -> Option<u8> {
|
||||||
&self,
|
|
||||||
level: &Arc<Level>,
|
|
||||||
position: &BlockPos,
|
|
||||||
) -> Option<u8> {
|
|
||||||
let (chunk_pos, relative) = position.chunk_and_chunk_relative_position();
|
let (chunk_pos, relative) = position.chunk_and_chunk_relative_position();
|
||||||
|
|
||||||
level
|
level
|
||||||
.get_or_fetch_chunk(chunk_pos, |chunk| {
|
.read_chunk_sync(&chunk_pos, |chunk| {
|
||||||
let section_idx = (relative.y - chunk.section.min_y) as usize / 16;
|
let section_idx = (relative.y - chunk.section.min_y) as usize / 16;
|
||||||
let light_engine = chunk.light_engine.lock().ok()?;
|
let light_engine = chunk.light_engine.lock().ok()?;
|
||||||
|
|
||||||
light_engine
|
let light_level = light_engine.block_light.get(section_idx)?.get(
|
||||||
.block_light
|
relative.x as usize,
|
||||||
.get(section_idx)?
|
(relative.y - chunk.section.min_y) as usize % 16,
|
||||||
.get(
|
relative.z as usize,
|
||||||
relative.x as usize,
|
);
|
||||||
(relative.y - chunk.section.min_y) as usize % 16,
|
|
||||||
relative.z as usize,
|
Some(light_level)
|
||||||
)
|
|
||||||
.into()
|
|
||||||
})
|
})
|
||||||
.await
|
.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_block_light_level(
|
pub fn set_block_light_level(
|
||||||
&self,
|
&self,
|
||||||
level: &Arc<Level>,
|
level: &Arc<Level>,
|
||||||
position: &BlockPos,
|
position: &BlockPos,
|
||||||
light_level: u8,
|
light_level: u8,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
|
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
|
||||||
level
|
level.read_chunk_sync(&chunk_coordinate, |chunk| {
|
||||||
.get_or_fetch_chunk(chunk_coordinate, |chunk| {
|
let section_index = (relative.y - chunk.section.min_y) as usize / BlockPalette::SIZE;
|
||||||
let section_index =
|
// Bounds check for section index
|
||||||
(relative.y - chunk.section.min_y) as usize / BlockPalette::SIZE;
|
let mut light_engine = chunk
|
||||||
// Bounds check for section index
|
.light_engine
|
||||||
let mut light_engine = chunk
|
.lock()
|
||||||
.light_engine
|
.unwrap_or_else(std::sync::PoisonError::into_inner);
|
||||||
.lock()
|
if section_index >= light_engine.block_light.len() {
|
||||||
.unwrap_or_else(std::sync::PoisonError::into_inner);
|
return Err("Invalid section index".to_string());
|
||||||
if section_index >= light_engine.block_light.len() {
|
}
|
||||||
return Err("Invalid section index".to_string());
|
let relative_y = (relative.y - chunk.section.min_y) as usize % BlockPalette::SIZE;
|
||||||
}
|
light_engine.block_light[section_index].set(
|
||||||
let relative_y = (relative.y - chunk.section.min_y) as usize % BlockPalette::SIZE;
|
relative.x as usize,
|
||||||
light_engine.block_light[section_index].set(
|
relative_y,
|
||||||
relative.x as usize,
|
relative.z as usize,
|
||||||
relative_y,
|
light_level,
|
||||||
relative.z as usize,
|
);
|
||||||
light_level,
|
// Mark chunk as dirty so lighting changes are saved to disk
|
||||||
);
|
if !chunk.is_dirty() {
|
||||||
// Mark chunk as dirty so lighting changes are saved to disk
|
chunk.mark_dirty(true);
|
||||||
if !chunk.is_dirty() {
|
}
|
||||||
chunk.mark_dirty(true);
|
Ok(())
|
||||||
}
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_sky_light_level(&self, level: &Arc<Level>, position: &BlockPos) -> u8 {
|
pub fn get_sky_light_level(&self, level: &Arc<Level>, position: &BlockPos) -> u8 {
|
||||||
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
|
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
|
||||||
level
|
level
|
||||||
.get_or_fetch_chunk(chunk_coordinate, |chunk| {
|
.read_chunk_sync(&chunk_coordinate, |chunk| {
|
||||||
let section_index =
|
let section_index =
|
||||||
(relative.y - chunk.section.min_y) as usize / BlockPalette::SIZE;
|
(relative.y - chunk.section.min_y) as usize / BlockPalette::SIZE;
|
||||||
|
|
||||||
@ -571,41 +549,39 @@ impl DynamicLightEngine {
|
|||||||
relative.z as usize,
|
relative.z as usize,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.await
|
.unwrap_or(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_sky_light_level(
|
pub fn set_sky_light_level(
|
||||||
&self,
|
&self,
|
||||||
level: &Arc<Level>,
|
level: &Arc<Level>,
|
||||||
position: &BlockPos,
|
position: &BlockPos,
|
||||||
light_level: u8,
|
light_level: u8,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
|
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
|
||||||
level
|
level.read_chunk_sync(&chunk_coordinate, |chunk| {
|
||||||
.get_or_fetch_chunk(chunk_coordinate, |chunk| {
|
let section_index = (relative.y - chunk.section.min_y) as usize / BlockPalette::SIZE;
|
||||||
let section_index =
|
// Bounds check for section index
|
||||||
(relative.y - chunk.section.min_y) as usize / BlockPalette::SIZE;
|
let mut light_engine = chunk
|
||||||
// Bounds check for section index
|
.light_engine
|
||||||
let mut light_engine = chunk
|
.lock()
|
||||||
.light_engine
|
.unwrap_or_else(std::sync::PoisonError::into_inner);
|
||||||
.lock()
|
if section_index >= light_engine.sky_light.len() {
|
||||||
.unwrap_or_else(std::sync::PoisonError::into_inner);
|
return Err("Invalid section index".to_string());
|
||||||
if section_index >= light_engine.sky_light.len() {
|
}
|
||||||
return Err("Invalid section index".to_string());
|
let relative_y = (relative.y - chunk.section.min_y) as usize % BlockPalette::SIZE;
|
||||||
}
|
light_engine.sky_light[section_index].set(
|
||||||
let relative_y = (relative.y - chunk.section.min_y) as usize % BlockPalette::SIZE;
|
relative.x as usize,
|
||||||
light_engine.sky_light[section_index].set(
|
relative_y,
|
||||||
relative.x as usize,
|
relative.z as usize,
|
||||||
relative_y,
|
light_level,
|
||||||
relative.z as usize,
|
);
|
||||||
light_level,
|
// Mark chunk as dirty so lighting changes are saved to disk
|
||||||
);
|
if !chunk.is_dirty() {
|
||||||
// Mark chunk as dirty so lighting changes are saved to disk
|
chunk.mark_dirty(true);
|
||||||
if !chunk.is_dirty() {
|
}
|
||||||
chunk.mark_dirty(true);
|
Ok(())
|
||||||
}
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,8 +42,7 @@ impl BlockBehaviour for BannerBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if !can_place_at(args.world, args.position) {
|
if !can_place_at(args.world, args.position) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
args.state_id
|
args.state_id
|
||||||
})
|
})
|
||||||
|
|||||||
@ -75,9 +75,7 @@ impl BlockBehaviour for BarrelBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let barrel_block_entity = BarrelBlockEntity::new(*args.position);
|
let barrel_block_entity = BarrelBlockEntity::new(*args.position);
|
||||||
args.world
|
args.world.add_block_entity(Arc::new(barrel_block_entity));
|
||||||
.add_block_entity(Arc::new(barrel_block_entity))
|
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,14 +26,12 @@ impl BlockBehaviour for BarrierBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let props = BarrierLikeProperties::from_state_id(args.state_id, args.block);
|
let props = BarrierLikeProperties::from_state_id(args.state_id, args.block);
|
||||||
if props.waterlogged {
|
if props.waterlogged {
|
||||||
args.world
|
args.world.schedule_fluid_tick(
|
||||||
.schedule_fluid_tick(
|
&Fluid::WATER,
|
||||||
&Fluid::WATER,
|
*args.position,
|
||||||
*args.position,
|
Fluid::WATER.flow_speed as u8,
|
||||||
Fluid::WATER.flow_speed as u8,
|
TickPriority::Normal,
|
||||||
TickPriority::Normal,
|
);
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
props.to_state_id(args.block)
|
props.to_state_id(args.block)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -116,7 +116,7 @@ impl BlockBehaviour for BedBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let bed_entity = BedBlockEntity::new(*args.position);
|
let bed_entity = BedBlockEntity::new(*args.position);
|
||||||
args.world.add_block_entity(Arc::new(bed_entity)).await;
|
args.world.add_block_entity(Arc::new(bed_entity));
|
||||||
|
|
||||||
let mut bed_head_props = BedProperties::default(args.block);
|
let mut bed_head_props = BedProperties::default(args.block);
|
||||||
bed_head_props.facing = BedProperties::from_state_id(args.state_id, args.block).facing;
|
bed_head_props.facing = BedProperties::from_state_id(args.state_id, args.block).facing;
|
||||||
@ -132,7 +132,7 @@ impl BlockBehaviour for BedBlock {
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
let bed_head_entity = BedBlockEntity::new(bed_head_pos);
|
let bed_head_entity = BedBlockEntity::new(bed_head_pos);
|
||||||
args.world.add_block_entity(Arc::new(bed_head_entity)).await;
|
args.world.add_block_entity(Arc::new(bed_head_entity));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -122,8 +122,7 @@ impl BlockBehaviour for BlastFurnaceBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let blasting_furnace_block_entity = BlastingFurnaceBlockEntity::new(*args.position);
|
let blasting_furnace_block_entity = BlastingFurnaceBlockEntity::new(*args.position);
|
||||||
args.world
|
args.world
|
||||||
.add_block_entity(Arc::new(blasting_furnace_block_entity))
|
.add_block_entity(Arc::new(blasting_furnace_block_entity));
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +138,7 @@ impl BlockBehaviour for BlastFurnaceBlock {
|
|||||||
ExperienceOrbEntity::spawn(args.world, pos, xp as u32).await;
|
ExperienceOrbEntity::spawn(args.world, pos, xp as u32).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
args.world.remove_block_entity(args.position).await;
|
args.world.remove_block_entity(args.position);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,7 +68,7 @@ impl BlockBehaviour for BrewingStandBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let be = BrewingStandBlockEntity::new(*args.position);
|
let be = BrewingStandBlockEntity::new(*args.position);
|
||||||
args.world.add_block_entity(Arc::new(be)).await;
|
args.world.add_block_entity(Arc::new(be));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -182,8 +182,7 @@ impl BlockBehaviour for CakeBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if !can_place_at(args.world, args.position) {
|
if !can_place_at(args.world, args.position) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
args.state_id
|
args.state_id
|
||||||
})
|
})
|
||||||
|
|||||||
@ -81,14 +81,12 @@ impl BlockBehaviour for CampfireBlock {
|
|||||||
let mut props = CampfireLikeProperties::from_state_id(args.state_id, args.block);
|
let mut props = CampfireLikeProperties::from_state_id(args.state_id, args.block);
|
||||||
if props.waterlogged {
|
if props.waterlogged {
|
||||||
props.lit = false;
|
props.lit = false;
|
||||||
args.world
|
args.world.schedule_fluid_tick(
|
||||||
.schedule_fluid_tick(
|
&Fluid::WATER,
|
||||||
&Fluid::WATER,
|
*args.position,
|
||||||
*args.position,
|
Fluid::WATER.flow_speed as u8,
|
||||||
Fluid::WATER.flow_speed as u8,
|
TickPriority::Normal,
|
||||||
TickPriority::Normal,
|
);
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if args.direction == BlockDirection::Down {
|
if args.direction == BlockDirection::Down {
|
||||||
|
|||||||
@ -137,8 +137,7 @@ impl BlockBehaviour for CandleCakeBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if !can_place_at(args.world, args.position) {
|
if !can_place_at(args.world, args.position) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
args.state_id
|
args.state_id
|
||||||
})
|
})
|
||||||
|
|||||||
@ -149,8 +149,7 @@ impl BlockBehaviour for CandleBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if !can_place_at(args.world, args.position) {
|
if !can_place_at(args.world, args.position) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
args.state_id
|
args.state_id
|
||||||
})
|
})
|
||||||
|
|||||||
@ -23,8 +23,7 @@ impl BlockBehaviour for CarpetBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if !can_place_at(args.world, args.position) {
|
if !can_place_at(args.world, args.position) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
args.state_id
|
args.state_id
|
||||||
})
|
})
|
||||||
@ -56,8 +55,7 @@ impl BlockBehaviour for MossCarpetBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if !can_place_at(args.world, args.position) {
|
if !can_place_at(args.world, args.position) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
args.state_id
|
args.state_id
|
||||||
})
|
})
|
||||||
@ -89,8 +87,7 @@ impl BlockBehaviour for PaleMossCarpetBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if !can_place_at(args.world, args.position) {
|
if !can_place_at(args.world, args.position) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
args.state_id
|
args.state_id
|
||||||
})
|
})
|
||||||
|
|||||||
@ -96,7 +96,7 @@ async fn placed_chest_impl<E: BlockEntity + 'static>(
|
|||||||
create_entity: impl FnOnce(BlockPos) -> E,
|
create_entity: impl FnOnce(BlockPos) -> E,
|
||||||
) {
|
) {
|
||||||
let chest = create_entity(*args.position);
|
let chest = create_entity(*args.position);
|
||||||
args.world.add_block_entity(Arc::new(chest)).await;
|
args.world.add_block_entity(Arc::new(chest));
|
||||||
|
|
||||||
let chest_props = ChestLikeProperties::from_state_id(args.state_id, args.block);
|
let chest_props = ChestLikeProperties::from_state_id(args.state_id, args.block);
|
||||||
let connected_towards = match chest_props.r#type {
|
let connected_towards = match chest_props.r#type {
|
||||||
|
|||||||
@ -116,7 +116,7 @@ impl BlockBehaviour for ChiseledBookshelfBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let block_entity = ChiseledBookshelfBlockEntity::new(*args.position);
|
let block_entity = ChiseledBookshelfBlockEntity::new(*args.position);
|
||||||
args.world.add_block_entity(Arc::new(block_entity)).await;
|
args.world.add_block_entity(Arc::new(block_entity));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -66,7 +66,7 @@ impl CommandBlock {
|
|||||||
command_entity.success_count.load(Ordering::Relaxed) > 0
|
command_entity.success_count.load(Ordering::Relaxed) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update(
|
fn update(
|
||||||
world: &World,
|
world: &World,
|
||||||
block: &Block,
|
block: &Block,
|
||||||
command_block: &CommandBlockEntity,
|
command_block: &CommandBlockEntity,
|
||||||
@ -87,9 +87,7 @@ impl CommandBlock {
|
|||||||
let props = CommandBlockLikeProperties::from_state_id(state_id, block);
|
let props = CommandBlockLikeProperties::from_state_id(state_id, block);
|
||||||
|
|
||||||
if !props.conditional {
|
if !props.conditional {
|
||||||
world
|
world.schedule_block_tick(block, *pos, 1, TickPriority::Normal);
|
||||||
.schedule_block_tick(block, *pos, 1, TickPriority::Normal)
|
|
||||||
.await;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,9 +107,7 @@ impl CommandBlock {
|
|||||||
.expect("behind should always be a command block");
|
.expect("behind should always be a command block");
|
||||||
|
|
||||||
if behind_entity.success_count.load(Ordering::Relaxed) > 0 {
|
if behind_entity.success_count.load(Ordering::Relaxed) > 0 {
|
||||||
world
|
world.schedule_block_tick(block, *pos, 1, TickPriority::Normal);
|
||||||
.schedule_block_tick(block, *pos, 1, TickPriority::Normal)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +222,7 @@ impl BlockBehaviour for CommandBlock {
|
|||||||
let Some(block_entity) = args.world.get_block_entity(args.position) else {
|
let Some(block_entity) = args.world.get_block_entity(args.position) else {
|
||||||
return BlockActionResult::Pass;
|
return BlockActionResult::Pass;
|
||||||
};
|
};
|
||||||
args.world.update_block_entity(&block_entity).await;
|
args.world.update_block_entity(&block_entity);
|
||||||
BlockActionResult::SuccessServer
|
BlockActionResult::SuccessServer
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -253,8 +249,7 @@ impl BlockBehaviour for CommandBlock {
|
|||||||
command_entity,
|
command_entity,
|
||||||
args.position,
|
args.position,
|
||||||
block_receives_redstone_power(args.world, args.position).await,
|
block_receives_redstone_power(args.world, args.position).await,
|
||||||
)
|
);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -304,8 +299,7 @@ impl BlockBehaviour for CommandBlock {
|
|||||||
let can_run = command_entity.powered.load(Ordering::Relaxed) || is_auto;
|
let can_run = command_entity.powered.load(Ordering::Relaxed) || is_auto;
|
||||||
if block == &Block::REPEATING_COMMAND_BLOCK && can_run {
|
if block == &Block::REPEATING_COMMAND_BLOCK && can_run {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -332,7 +326,7 @@ impl BlockBehaviour for CommandBlock {
|
|||||||
send_command_feedback,
|
send_command_feedback,
|
||||||
args.block.id == Block::CHAIN_COMMAND_BLOCK.id,
|
args.block.id == Block::CHAIN_COMMAND_BLOCK.id,
|
||||||
);
|
);
|
||||||
args.world.add_block_entity(Arc::new(entity)).await;
|
args.world.add_block_entity(Arc::new(entity));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -132,9 +132,7 @@ impl ComposterBlock {
|
|||||||
.set_block_state(location, props.to_state_id(block), BlockFlags::NOTIFY_ALL)
|
.set_block_state(location, props.to_state_id(block), BlockFlags::NOTIFY_ALL)
|
||||||
.await;
|
.await;
|
||||||
if level == 7 {
|
if level == 7 {
|
||||||
world
|
world.schedule_block_tick(block, *location, 20, TickPriority::Normal);
|
||||||
.schedule_block_tick(block, *location, 20, TickPriority::Normal)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -47,8 +47,7 @@ impl BlockBehaviour for DirtPathBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if args.direction == BlockDirection::Up && !can_place_at(args.world, args.position) {
|
if args.direction == BlockDirection::Up && !can_place_at(args.world, args.position) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
args.state_id
|
args.state_id
|
||||||
})
|
})
|
||||||
|
|||||||
@ -48,8 +48,7 @@ impl BlockBehaviour for DragonEggBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 5, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 5, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -29,8 +29,7 @@ impl BlockBehaviour for EndPortalBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
args.world
|
args.world
|
||||||
.add_block_entity(Arc::new(EndPortalBlockEntity::new(*args.position)))
|
.add_block_entity(Arc::new(EndPortalBlockEntity::new(*args.position)));
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -103,7 +103,7 @@ impl BlockBehaviour for EnderChestBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let block_entity = EnderChestBlockEntity::new(*args.position);
|
let block_entity = EnderChestBlockEntity::new(*args.position);
|
||||||
args.world.add_block_entity(Arc::new(block_entity)).await;
|
args.world.add_block_entity(Arc::new(block_entity));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,8 +33,7 @@ impl BlockBehaviour for FallingBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
// TODO: make delay configurable
|
// TODO: make delay configurable
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 2, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 2, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn get_state_for_neighbor_update<'a>(
|
fn get_state_for_neighbor_update<'a>(
|
||||||
@ -44,8 +43,7 @@ impl BlockBehaviour for FallingBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
// TODO: make delay configurable
|
// TODO: make delay configurable
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 2, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 2, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
args.state_id
|
args.state_id
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,8 +57,7 @@ impl BlockBehaviour for FarmlandBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if args.direction == BlockDirection::Up && !can_place_at(args.world, args.position) {
|
if args.direction == BlockDirection::Up && !can_place_at(args.world, args.position) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
args.state_id
|
args.state_id
|
||||||
})
|
})
|
||||||
|
|||||||
@ -199,14 +199,12 @@ impl BlockBehaviour for FireBlock {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
args.world
|
args.world.schedule_block_tick(
|
||||||
.schedule_block_tick(
|
args.block,
|
||||||
args.block,
|
*args.position,
|
||||||
*args.position,
|
Self::get_fire_tick_delay() as u8,
|
||||||
Self::get_fire_tick_delay() as u8,
|
TickPriority::Normal,
|
||||||
TickPriority::Normal,
|
);
|
||||||
)
|
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,14 +253,12 @@ impl BlockBehaviour for FireBlock {
|
|||||||
let (world, block, pos) = (args.world, args.block, args.position);
|
let (world, block, pos) = (args.world, args.block, args.position);
|
||||||
|
|
||||||
// Schedule next tick first
|
// Schedule next tick first
|
||||||
world
|
world.schedule_block_tick(
|
||||||
.schedule_block_tick(
|
block,
|
||||||
block,
|
*pos,
|
||||||
*pos,
|
Self::get_fire_tick_delay() as u8,
|
||||||
Self::get_fire_tick_delay() as u8,
|
TickPriority::Normal,
|
||||||
TickPriority::Normal,
|
);
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
// Check if fire can survive
|
// Check if fire can survive
|
||||||
if !self.can_place_at(CanPlaceAtArgs {
|
if !self.can_place_at(CanPlaceAtArgs {
|
||||||
|
|||||||
@ -117,9 +117,7 @@ impl BlockBehaviour for FurnaceBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let furnace_block_entity = FurnaceBlockEntity::new(*args.position);
|
let furnace_block_entity = FurnaceBlockEntity::new(*args.position);
|
||||||
args.world
|
args.world.add_block_entity(Arc::new(furnace_block_entity));
|
||||||
.add_block_entity(Arc::new(furnace_block_entity))
|
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +133,7 @@ impl BlockBehaviour for FurnaceBlock {
|
|||||||
ExperienceOrbEntity::spawn(args.world, pos, xp as u32).await;
|
ExperienceOrbEntity::spawn(args.world, pos, xp as u32).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
args.world.remove_block_entity(args.position).await;
|
args.world.remove_block_entity(args.position);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -90,9 +90,7 @@ impl BlockBehaviour for HopperBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let props = HopperLikeProperties::from_state_id(args.state_id, args.block);
|
let props = HopperLikeProperties::from_state_id(args.state_id, args.block);
|
||||||
let hopper_block_entity = HopperBlockEntity::new(*args.position, props.facing);
|
let hopper_block_entity = HopperBlockEntity::new(*args.position, props.facing);
|
||||||
args.world
|
args.world.add_block_entity(Arc::new(hopper_block_entity));
|
||||||
.add_block_entity(Arc::new(hopper_block_entity))
|
|
||||||
.await;
|
|
||||||
if Block::from_state_id(args.old_state_id) != Block::from_state_id(args.state_id) {
|
if Block::from_state_id(args.old_state_id) != Block::from_state_id(args.state_id) {
|
||||||
check_powered_state(args.world, args.position, args.state_id, args.block).await;
|
check_powered_state(args.world, args.position, args.state_id, args.block).await;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -90,7 +90,7 @@ impl BlockBehaviour for JukeboxBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let block_entity = JukeboxBlockEntity::new(*args.position);
|
let block_entity = JukeboxBlockEntity::new(*args.position);
|
||||||
args.world.add_block_entity(Arc::new(block_entity)).await;
|
args.world.add_block_entity(Arc::new(block_entity));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -95,8 +95,7 @@ impl BlockBehaviour for LadderBlock {
|
|||||||
props.facing.to_block_direction().opposite(),
|
props.facing.to_block_direction().opposite(),
|
||||||
) {
|
) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,8 +58,7 @@ impl BlockBehaviour for LanternBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if !can_place_at(args.world, args.position) {
|
if !can_place_at(args.world, args.position) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
args.state_id
|
args.state_id
|
||||||
})
|
})
|
||||||
|
|||||||
@ -41,7 +41,7 @@ impl BlockBehaviour for LecternBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let block_entity = LecternBlockEntity::new(*args.position);
|
let block_entity = LecternBlockEntity::new(*args.position);
|
||||||
args.world.add_block_entity(Arc::new(block_entity)).await;
|
args.world.add_block_entity(Arc::new(block_entity));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,14 +24,12 @@ impl BlockBehaviour for MangroveRootsBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let props = MangroveRootsLikeProperties::from_state_id(args.state_id, args.block);
|
let props = MangroveRootsLikeProperties::from_state_id(args.state_id, args.block);
|
||||||
if props.waterlogged {
|
if props.waterlogged {
|
||||||
args.world
|
args.world.schedule_fluid_tick(
|
||||||
.schedule_fluid_tick(
|
&Fluid::WATER,
|
||||||
&Fluid::WATER,
|
*args.position,
|
||||||
*args.position,
|
Fluid::WATER.flow_speed as u8,
|
||||||
Fluid::WATER.flow_speed as u8,
|
TickPriority::Normal,
|
||||||
TickPriority::Normal,
|
);
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
props.to_state_id(args.block)
|
props.to_state_id(args.block)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -219,17 +219,15 @@ impl BlockBehaviour for PistonBlock {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.to_facing();
|
.to_facing();
|
||||||
|
|
||||||
world
|
world.add_block_entity(Arc::new(PistonBlockEntity {
|
||||||
.add_block_entity(Arc::new(PistonBlockEntity {
|
position: *pos,
|
||||||
position: *pos,
|
facing: dir,
|
||||||
facing: dir,
|
pushed_block_state: BlockState::from_id(props.to_state_id(block)),
|
||||||
pushed_block_state: BlockState::from_id(props.to_state_id(block)),
|
current_progress: 0.0.into(),
|
||||||
current_progress: 0.0.into(),
|
last_progress: 0.0.into(),
|
||||||
last_progress: 0.0.into(),
|
extending: false,
|
||||||
extending: false,
|
source: true,
|
||||||
source: true,
|
}));
|
||||||
}))
|
|
||||||
.await;
|
|
||||||
|
|
||||||
world.update_neighbors(pos, None).await;
|
world.update_neighbors(pos, None).await;
|
||||||
if sticky {
|
if sticky {
|
||||||
@ -425,17 +423,15 @@ async fn move_piston(
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
if let Some(moved_state) = moved_block_states.get(moved_blocks.len() - 1 - index) {
|
if let Some(moved_state) = moved_block_states.get(moved_blocks.len() - 1 - index) {
|
||||||
world
|
world.add_block_entity(Arc::new(PistonBlockEntity {
|
||||||
.add_block_entity(Arc::new(PistonBlockEntity {
|
position: target_pos,
|
||||||
position: target_pos,
|
facing: dir.to_facing().to_block_direction(),
|
||||||
facing: dir.to_facing().to_block_direction(),
|
pushed_block_state: moved_state,
|
||||||
pushed_block_state: moved_state,
|
current_progress: 0.0.into(),
|
||||||
current_progress: 0.0.into(),
|
last_progress: 0.0.into(),
|
||||||
last_progress: 0.0.into(),
|
extending: extend,
|
||||||
extending: extend,
|
source: false,
|
||||||
source: false,
|
}));
|
||||||
}))
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
affected_block_states.push(block_state);
|
affected_block_states.push(block_state);
|
||||||
}
|
}
|
||||||
@ -460,17 +456,15 @@ async fn move_piston(
|
|||||||
let mut props = PistonHeadLikeProperties::default(&Block::PISTON_HEAD);
|
let mut props = PistonHeadLikeProperties::default(&Block::PISTON_HEAD);
|
||||||
props.facing = dir.to_facing();
|
props.facing = dir.to_facing();
|
||||||
props.r#type = pistion_type;
|
props.r#type = pistion_type;
|
||||||
world
|
world.add_block_entity(Arc::new(PistonBlockEntity {
|
||||||
.add_block_entity(Arc::new(PistonBlockEntity {
|
position: extended_pos,
|
||||||
position: extended_pos,
|
facing: dir.to_facing().to_block_direction(),
|
||||||
facing: dir.to_facing().to_block_direction(),
|
pushed_block_state: BlockState::from_id(props.to_state_id(&Block::PISTON_HEAD)),
|
||||||
pushed_block_state: BlockState::from_id(props.to_state_id(&Block::PISTON_HEAD)),
|
current_progress: 0.0.into(),
|
||||||
current_progress: 0.0.into(),
|
last_progress: 0.0.into(),
|
||||||
last_progress: 0.0.into(),
|
extending: true,
|
||||||
extending: true,
|
source: true,
|
||||||
source: true,
|
}));
|
||||||
}))
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let air_state = Block::AIR.default_state.id;
|
let air_state = Block::AIR.default_state.id;
|
||||||
|
|||||||
@ -103,8 +103,7 @@ impl BlockBehaviour for BambooBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if !<Self as PlantBlockBase>::can_place_at(self, args.world, args.position) {
|
if !<Self as PlantBlockBase>::can_place_at(self, args.world, args.position) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
let neighbor_block = args.world.get_block(args.neighbor_position);
|
let neighbor_block = args.world.get_block(args.neighbor_position);
|
||||||
if args.direction == BlockDirection::Up && neighbor_block == &Block::BAMBOO {
|
if args.direction == BlockDirection::Up && neighbor_block == &Block::BAMBOO {
|
||||||
|
|||||||
@ -178,14 +178,12 @@ async fn set_tilt_and_schedule_tick(
|
|||||||
Tilt::Full => 100,
|
Tilt::Full => 100,
|
||||||
};
|
};
|
||||||
if tick_delay != -1 {
|
if tick_delay != -1 {
|
||||||
world
|
world.schedule_block_tick(
|
||||||
.schedule_block_tick(
|
&Block::BIG_DRIPLEAF,
|
||||||
&Block::BIG_DRIPLEAF,
|
*pos,
|
||||||
*pos,
|
tick_delay as u8,
|
||||||
tick_delay as u8,
|
pumpkin_world::tick::TickPriority::Normal,
|
||||||
pumpkin_world::tick::TickPriority::Normal,
|
);
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn play_tilt_sound(world: &Arc<World>, pos: &BlockPos, tilt_sound: Sound) {
|
fn play_tilt_sound(world: &Arc<World>, pos: &BlockPos, tilt_sound: Sound) {
|
||||||
|
|||||||
@ -104,8 +104,7 @@ impl BlockBehaviour for CactusBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if !can_place_at(args.world, args.position) {
|
if !can_place_at(args.world, args.position) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
args.state_id
|
args.state_id
|
||||||
|
|||||||
@ -29,8 +29,7 @@ impl BlockBehaviour for ChorusFlowerBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if args.direction != BlockDirection::Up && !can_survive(args.world, args.position) {
|
if args.direction != BlockDirection::Up && !can_survive(args.world, args.position) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
args.state_id
|
args.state_id
|
||||||
})
|
})
|
||||||
|
|||||||
@ -39,8 +39,7 @@ impl BlockBehaviour for ChorusPlantBlock {
|
|||||||
if !can_survive(args.world, args.position) {
|
if !can_survive(args.world, args.position) {
|
||||||
// Schedule delayed destruction so the whole plant cascades down.
|
// Schedule delayed destruction so the whole plant cascades down.
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
return args.state_id;
|
return args.state_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -71,8 +71,7 @@ impl BlockBehaviour for SugarCaneBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if !can_place_at(args.world, args.position) {
|
if !can_place_at(args.world, args.position) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
args.state_id
|
args.state_id
|
||||||
})
|
})
|
||||||
|
|||||||
@ -32,7 +32,6 @@ pub trait RedstoneGateBlockProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait RedstoneGateBlock<T: Send + Sync + BlockProperties + RedstoneGateBlockProperties> {
|
pub trait RedstoneGateBlock<T: Send + Sync + BlockProperties + RedstoneGateBlockProperties> {
|
||||||
// 💡 Converted async fn to fn
|
|
||||||
fn can_place_at(&self, world: &dyn BlockAccessor, pos: BlockPos) -> bool
|
fn can_place_at(&self, world: &dyn BlockAccessor, pos: BlockPos) -> bool
|
||||||
where
|
where
|
||||||
Self: Send + Sync,
|
Self: Send + Sync,
|
||||||
@ -42,7 +41,6 @@ pub trait RedstoneGateBlock<T: Send + Sync + BlockProperties + RedstoneGateBlock
|
|||||||
self.can_place_above(world, under_pos, under_state)
|
self.can_place_above(world, under_pos, under_state)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 💡 Converted async fn to fn
|
|
||||||
fn can_place_above(
|
fn can_place_above(
|
||||||
&self,
|
&self,
|
||||||
_world: &dyn BlockAccessor,
|
_world: &dyn BlockAccessor,
|
||||||
@ -76,7 +74,6 @@ pub trait RedstoneGateBlock<T: Send + Sync + BlockProperties + RedstoneGateBlock
|
|||||||
Box::pin(async move { self.get_weak_redstone_power(args).await })
|
Box::pin(async move { self.get_weak_redstone_power(args).await })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 💡 Converted async fn to fn returning BlockFuture
|
|
||||||
fn get_output_level<'a>(&'a self, world: &'a World, pos: BlockPos) -> BlockFuture<'a, u8>;
|
fn get_output_level<'a>(&'a self, world: &'a World, pos: BlockPos) -> BlockFuture<'a, u8>;
|
||||||
|
|
||||||
fn on_neighbor_update<'a>(&'a self, args: OnNeighborUpdateArgs<'a>) -> BlockFuture<'a, ()>
|
fn on_neighbor_update<'a>(&'a self, args: OnNeighborUpdateArgs<'a>) -> BlockFuture<'a, ()>
|
||||||
@ -105,7 +102,6 @@ pub trait RedstoneGateBlock<T: Send + Sync + BlockProperties + RedstoneGateBlock
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 💡 Converted async fn to fn returning BlockFuture
|
|
||||||
fn update_powered<'a>(
|
fn update_powered<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
world: &'a World,
|
world: &'a World,
|
||||||
@ -114,7 +110,6 @@ pub trait RedstoneGateBlock<T: Send + Sync + BlockProperties + RedstoneGateBlock
|
|||||||
block: &'a Block,
|
block: &'a Block,
|
||||||
) -> BlockFuture<'a, ()>;
|
) -> BlockFuture<'a, ()>;
|
||||||
|
|
||||||
// 💡 Converted async fn to fn returning BlockFuture
|
|
||||||
fn has_power<'a>(
|
fn has_power<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
world: &'a World,
|
world: &'a World,
|
||||||
@ -128,7 +123,6 @@ pub trait RedstoneGateBlock<T: Send + Sync + BlockProperties + RedstoneGateBlock
|
|||||||
Box::pin(async move { self.get_power(world, pos, state, block).await > 0 })
|
Box::pin(async move { self.get_power(world, pos, state, block).await > 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 💡 Converted async fn to fn returning BlockFuture
|
|
||||||
fn get_power<'a>(
|
fn get_power<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
world: &'a World,
|
world: &'a World,
|
||||||
@ -142,7 +136,6 @@ pub trait RedstoneGateBlock<T: Send + Sync + BlockProperties + RedstoneGateBlock
|
|||||||
Box::pin(async move { get_power::<T>(world, pos, state.id, block).await })
|
Box::pin(async move { get_power::<T>(world, pos, state.id, block).await })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 💡 Converted async fn to fn returning BlockFuture
|
|
||||||
fn get_max_input_level_sides<'a>(
|
fn get_max_input_level_sides<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
world: &'a World,
|
world: &'a World,
|
||||||
@ -164,7 +157,6 @@ pub trait RedstoneGateBlock<T: Send + Sync + BlockProperties + RedstoneGateBlock
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 💡 Converted async fn to fn returning BlockFuture
|
|
||||||
fn update_target<'a>(
|
fn update_target<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
world: &'a Arc<World>,
|
world: &'a Arc<World>,
|
||||||
@ -183,7 +175,6 @@ pub trait RedstoneGateBlock<T: Send + Sync + BlockProperties + RedstoneGateBlock
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 💡 Converted async fn to fn returning BlockFuture
|
|
||||||
fn on_place<'a>(
|
fn on_place<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
player: &'a Player,
|
player: &'a Player,
|
||||||
@ -217,8 +208,7 @@ pub trait RedstoneGateBlock<T: Send + Sync + BlockProperties + RedstoneGateBlock
|
|||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -242,29 +232,26 @@ pub trait RedstoneGateBlock<T: Send + Sync + BlockProperties + RedstoneGateBlock
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 💡 Converted async fn to fn returning BlockFuture
|
|
||||||
fn is_target_not_aligned<'a>(
|
fn is_target_not_aligned<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
world: &'a dyn BlockAccessor,
|
world: &'a dyn BlockAccessor,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
state: &'a BlockState,
|
state: &'a BlockState,
|
||||||
block: &'a Block,
|
block: &'a Block,
|
||||||
) -> BlockFuture<'a, bool> {
|
) -> bool {
|
||||||
Box::pin(async move {
|
let props = T::from_state_id(state.id, block);
|
||||||
let props = T::from_state_id(state.id, block);
|
let facing = props.get_facing().opposite();
|
||||||
let facing = props.get_facing().opposite();
|
let (target_block, target_state) =
|
||||||
let (target_block, target_state) =
|
world.get_block_and_state(&pos.offset(facing.to_offset()));
|
||||||
world.get_block_and_state(&pos.offset(facing.to_offset()));
|
if target_block == &Block::COMPARATOR {
|
||||||
if target_block == &Block::COMPARATOR {
|
let props = ComparatorLikeProperties::from_state_id(target_state.id, target_block);
|
||||||
let props = ComparatorLikeProperties::from_state_id(target_state.id, target_block);
|
props.facing != facing
|
||||||
props.facing != facing
|
} else if target_block == &Block::REPEATER {
|
||||||
} else if target_block == &Block::REPEATER {
|
let props = RepeaterLikeProperties::from_state_id(target_state.id, target_block);
|
||||||
let props = RepeaterLikeProperties::from_state_id(target_state.id, target_block);
|
props.facing != facing
|
||||||
props.facing != facing
|
} else {
|
||||||
} else {
|
false
|
||||||
false
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_update_delay_internal(&self, state_id: BlockStateId, block: &Block) -> u8;
|
fn get_update_delay_internal(&self, state_id: BlockStateId, block: &Block) -> u8;
|
||||||
|
|||||||
@ -114,15 +114,14 @@ impl BlockBehaviour for BellBlock {
|
|||||||
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
|
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let world: &World = args.world;
|
let world: &World = args.world;
|
||||||
world.remove_block_entity(args.position).await;
|
world.remove_block_entity(args.position);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
args.world
|
args.world
|
||||||
.add_block_entity(Arc::new(BellBlockEntity::new(*args.position)))
|
.add_block_entity(Arc::new(BellBlockEntity::new(*args.position)));
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
|
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
|
||||||
|
|||||||
@ -45,9 +45,7 @@ async fn click_button(world: &Arc<World>, block_pos: &BlockPos) {
|
|||||||
} else {
|
} else {
|
||||||
30
|
30
|
||||||
};
|
};
|
||||||
world
|
world.schedule_block_tick(block, *block_pos, delay, TickPriority::Normal);
|
||||||
.schedule_block_tick(block, *block_pos, delay, TickPriority::Normal)
|
|
||||||
.await;
|
|
||||||
ButtonBlock::update_neighbors(world, block_pos, &button_props).await;
|
ButtonBlock::update_neighbors(world, block_pos, &button_props).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,7 +57,7 @@ impl BlockBehaviour for ComparatorBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let comparator = ComparatorBlockEntity::new(*args.position);
|
let comparator = ComparatorBlockEntity::new(*args.position);
|
||||||
args.world.add_block_entity(Arc::new(comparator)).await;
|
args.world.add_block_entity(Arc::new(comparator));
|
||||||
|
|
||||||
RedstoneGateBlock::update_target(
|
RedstoneGateBlock::update_target(
|
||||||
self,
|
self,
|
||||||
@ -78,7 +78,7 @@ impl BlockBehaviour for ComparatorBlock {
|
|||||||
|
|
||||||
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
|
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
args.world.remove_block_entity(args.position).await;
|
args.world.remove_block_entity(args.position);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ impl RedstoneGateBlock<ComparatorLikeProperties> for ComparatorBlock {
|
|||||||
block: &'a Block,
|
block: &'a Block,
|
||||||
) -> BlockFuture<'a, ()> {
|
) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if world.is_block_tick_scheduled(&pos, block).await {
|
if world.is_block_tick_scheduled(&pos, block) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let i = self.calculate_output_signal(world, pos, state, block).await;
|
let i = self.calculate_output_signal(world, pos, state, block).await;
|
||||||
@ -187,20 +187,16 @@ impl RedstoneGateBlock<ComparatorLikeProperties> for ComparatorBlock {
|
|||||||
|| props.powered
|
|| props.powered
|
||||||
!= RedstoneGateBlock::has_power(self, world, pos, state, block).await
|
!= RedstoneGateBlock::has_power(self, world, pos, state, block).await
|
||||||
{
|
{
|
||||||
world
|
world.schedule_block_tick(
|
||||||
.schedule_block_tick(
|
block,
|
||||||
block,
|
pos,
|
||||||
pos,
|
RedstoneGateBlock::get_update_delay_internal(self, state.id, block),
|
||||||
RedstoneGateBlock::get_update_delay_internal(self, state.id, block),
|
if RedstoneGateBlock::is_target_not_aligned(self, world, pos, state, block) {
|
||||||
if RedstoneGateBlock::is_target_not_aligned(self, world, pos, state, block)
|
TickPriority::High
|
||||||
.await
|
} else {
|
||||||
{
|
TickPriority::Normal
|
||||||
TickPriority::High
|
},
|
||||||
} else {
|
);
|
||||||
TickPriority::Normal
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,14 +21,13 @@ impl BlockBehaviour for DaylightDetectorBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
args.world
|
args.world
|
||||||
.add_block_entity(Arc::new(DaylightDetectorBlockEntity::new(*args.position)))
|
.add_block_entity(Arc::new(DaylightDetectorBlockEntity::new(*args.position)));
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
|
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
args.world.remove_block_entity(args.position).await;
|
args.world.remove_block_entity(args.position);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -111,9 +111,7 @@ impl BlockBehaviour for DropperBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let dropper_block_entity = DropperBlockEntity::new(*args.position);
|
let dropper_block_entity = DropperBlockEntity::new(*args.position);
|
||||||
args.world
|
args.world.add_block_entity(Arc::new(dropper_block_entity));
|
||||||
.add_block_entity(Arc::new(dropper_block_entity))
|
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,8 +125,7 @@ impl BlockBehaviour for DropperBlock {
|
|||||||
);
|
);
|
||||||
if powered && !props.triggered {
|
if powered && !props.triggered {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 4, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 4, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
props.triggered = true;
|
props.triggered = true;
|
||||||
args.world
|
args.world
|
||||||
.set_block_state(
|
.set_block_state(
|
||||||
|
|||||||
@ -50,8 +50,7 @@ impl BlockBehaviour for ObserverBlock {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 2, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 2, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::update_neighbors(args.world, args.block, args.position, &props).await;
|
Self::update_neighbors(args.world, args.block, args.position, &props).await;
|
||||||
@ -66,7 +65,7 @@ impl BlockBehaviour for ObserverBlock {
|
|||||||
let props = ObserverLikeProperties::from_state_id(args.state_id, args.block);
|
let props = ObserverLikeProperties::from_state_id(args.state_id, args.block);
|
||||||
|
|
||||||
if props.facing.to_block_direction() == args.direction && !props.powered {
|
if props.facing.to_block_direction() == args.direction && !props.powered {
|
||||||
Self::schedule_tick(args.world, args.position).await;
|
Self::schedule_tick(args.world, args.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
args.state_id
|
args.state_id
|
||||||
@ -112,7 +111,6 @@ impl BlockBehaviour for ObserverBlock {
|
|||||||
&& args
|
&& args
|
||||||
.world
|
.world
|
||||||
.is_block_tick_scheduled(args.position, &Block::OBSERVER)
|
.is_block_tick_scheduled(args.position, &Block::OBSERVER)
|
||||||
.await
|
|
||||||
{
|
{
|
||||||
Self::update_neighbors(args.world, args.block, args.position, &props).await;
|
Self::update_neighbors(args.world, args.block, args.position, &props).await;
|
||||||
}
|
}
|
||||||
@ -137,9 +135,7 @@ impl ObserverBlock {
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn schedule_tick(world: &World, block_pos: &BlockPos) {
|
fn schedule_tick(world: &World, block_pos: &BlockPos) {
|
||||||
world
|
world.schedule_block_tick(&Block::OBSERVER, *block_pos, 2, TickPriority::Normal);
|
||||||
.schedule_block_tick(&Block::OBSERVER, *block_pos, 2, TickPriority::Normal)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,9 +74,7 @@ pub(crate) trait PressurePlate {
|
|||||||
world.update_neighbors(&pos.down(), None).await;
|
world.update_neighbors(&pos.down(), None).await;
|
||||||
}
|
}
|
||||||
if has_output {
|
if has_output {
|
||||||
world
|
world.schedule_block_tick(block, *pos, self.tick_rate(), TickPriority::Normal);
|
||||||
.schedule_block_tick(block, *pos, self.tick_rate(), TickPriority::Normal)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,9 +30,12 @@ impl BlockBehaviour for RedstoneLamp {
|
|||||||
|
|
||||||
if is_lit != is_receiving_power {
|
if is_lit != is_receiving_power {
|
||||||
if is_lit {
|
if is_lit {
|
||||||
args.world
|
args.world.schedule_block_tick(
|
||||||
.schedule_block_tick(args.block, *args.position, 4, TickPriority::Normal)
|
args.block,
|
||||||
.await;
|
*args.position,
|
||||||
|
4,
|
||||||
|
TickPriority::Normal,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
props.lit = !props.lit;
|
props.lit = !props.lit;
|
||||||
args.world
|
args.world
|
||||||
|
|||||||
@ -143,7 +143,6 @@ impl BlockBehaviour for RedstoneTorchBlock {
|
|||||||
if args
|
if args
|
||||||
.world
|
.world
|
||||||
.is_block_tick_scheduled(args.position, args.block)
|
.is_block_tick_scheduled(args.position, args.block)
|
||||||
.await
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -158,17 +157,23 @@ impl BlockBehaviour for RedstoneTorchBlock {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
args.world
|
args.world.schedule_block_tick(
|
||||||
.schedule_block_tick(args.block, *args.position, 2, TickPriority::Normal)
|
args.block,
|
||||||
.await;
|
*args.position,
|
||||||
|
2,
|
||||||
|
TickPriority::Normal,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if args.block == &Block::REDSTONE_TORCH {
|
} else if args.block == &Block::REDSTONE_TORCH {
|
||||||
let props = RTorchProps::from_state_id(state.id, args.block);
|
let props = RTorchProps::from_state_id(state.id, args.block);
|
||||||
if props.lit != should_be_lit(args.world, args.position, BlockDirection::Down).await
|
if props.lit != should_be_lit(args.world, args.position, BlockDirection::Down).await
|
||||||
{
|
{
|
||||||
args.world
|
args.world.schedule_block_tick(
|
||||||
.schedule_block_tick(args.block, *args.position, 2, TickPriority::Normal)
|
args.block,
|
||||||
.await;
|
*args.position,
|
||||||
|
2,
|
||||||
|
TickPriority::Normal,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -89,18 +89,16 @@ impl BlockBehaviour for RepeaterBlock {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
if !should_be_powered {
|
if !should_be_powered {
|
||||||
args.world
|
args.world.schedule_block_tick(
|
||||||
.schedule_block_tick(
|
args.block,
|
||||||
|
*args.position,
|
||||||
|
RedstoneGateBlock::get_update_delay_internal(
|
||||||
|
self,
|
||||||
|
props.to_state_id(args.block),
|
||||||
args.block,
|
args.block,
|
||||||
*args.position,
|
),
|
||||||
RedstoneGateBlock::get_update_delay_internal(
|
TickPriority::VeryHigh,
|
||||||
self,
|
);
|
||||||
props.to_state_id(args.block),
|
|
||||||
args.block,
|
|
||||||
),
|
|
||||||
TickPriority::VeryHigh,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
RedstoneGateBlock::update_target(
|
RedstoneGateBlock::update_target(
|
||||||
self,
|
self,
|
||||||
@ -240,16 +238,12 @@ impl RedstoneGateBlock<RepeaterProperties> for RepeaterBlock {
|
|||||||
let props = RepeaterProperties::from_state_id(state.id, block);
|
let props = RepeaterProperties::from_state_id(state.id, block);
|
||||||
let powered = props.powered;
|
let powered = props.powered;
|
||||||
|
|
||||||
// 💡 FIX 3: Trait method calls now return futures and must be awaited.
|
|
||||||
// Note: The signature for has_power must be called without self, as it's a trait method.
|
// Note: The signature for has_power must be called without self, as it's a trait method.
|
||||||
let has_power = RedstoneGateBlock::has_power(self, world, pos, state, block).await;
|
let has_power = RedstoneGateBlock::has_power(self, world, pos, state, block).await;
|
||||||
|
|
||||||
if powered != has_power && !world.is_block_tick_scheduled(&pos, block).await {
|
if powered != has_power && !world.is_block_tick_scheduled(&pos, block) {
|
||||||
// 💡 FIX 4: is_target_not_aligned returns a Future and must be awaited.
|
|
||||||
let priority =
|
let priority =
|
||||||
if RedstoneGateBlock::is_target_not_aligned(self, world, pos, state, block)
|
if RedstoneGateBlock::is_target_not_aligned(self, world, pos, state, block) {
|
||||||
.await
|
|
||||||
{
|
|
||||||
TickPriority::ExtremelyHigh
|
TickPriority::ExtremelyHigh
|
||||||
} else if powered {
|
} else if powered {
|
||||||
TickPriority::VeryHigh
|
TickPriority::VeryHigh
|
||||||
@ -257,15 +251,12 @@ impl RedstoneGateBlock<RepeaterProperties> for RepeaterBlock {
|
|||||||
TickPriority::High
|
TickPriority::High
|
||||||
};
|
};
|
||||||
|
|
||||||
world
|
world.schedule_block_tick(
|
||||||
.schedule_block_tick(
|
block,
|
||||||
block,
|
pos,
|
||||||
pos,
|
RedstoneGateBlock::get_update_delay_internal(self, state.id, block),
|
||||||
// 💡 FIX 5: get_update_delay_internal is not async and is called normally.
|
priority,
|
||||||
RedstoneGateBlock::get_update_delay_internal(self, state.id, block),
|
);
|
||||||
priority,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,8 +43,7 @@ impl BlockBehaviour for TripwireBlock {
|
|||||||
Self::update(args.world, args.position, state_id).await;
|
Self::update(args.world, args.position, state_id).await;
|
||||||
|
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 10, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 10, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,9 +150,12 @@ impl BlockBehaviour for TripwireBlock {
|
|||||||
.await;
|
.await;
|
||||||
Self::update(args.world, args.position, state_id).await;
|
Self::update(args.world, args.position, state_id).await;
|
||||||
} else {
|
} else {
|
||||||
args.world
|
args.world.schedule_block_tick(
|
||||||
.schedule_block_tick(args.block, *args.position, 10, TickPriority::Normal)
|
args.block,
|
||||||
.await;
|
*args.position,
|
||||||
|
10,
|
||||||
|
TickPriority::Normal,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -217,14 +217,12 @@ impl TripwireHookBlock {
|
|||||||
wire_attached |= (!current_wire_props.disarmed) && current_wire_props.powered;
|
wire_attached |= (!current_wire_props.disarmed) && current_wire_props.powered;
|
||||||
wires_props[k as usize] = Some(current_wire_props);
|
wires_props[k as usize] = Some(current_wire_props);
|
||||||
if k == raw_wire_index {
|
if k == raw_wire_index {
|
||||||
world
|
world.schedule_block_tick(
|
||||||
.schedule_block_tick(
|
&Block::TRIPWIRE_HOOK,
|
||||||
&Block::TRIPWIRE_HOOK,
|
start_hook_pos,
|
||||||
start_hook_pos,
|
10,
|
||||||
10,
|
TickPriority::Normal,
|
||||||
TickPriority::Normal,
|
);
|
||||||
)
|
|
||||||
.await;
|
|
||||||
can_attach &= !current_wire_props.disarmed;
|
can_attach &= !current_wire_props.disarmed;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -79,9 +79,7 @@ impl BlockBehaviour for ShulkerBoxBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let barrel_block_entity = ShulkerBoxBlockEntity::new(*args.position);
|
let barrel_block_entity = ShulkerBoxBlockEntity::new(*args.position);
|
||||||
args.world
|
args.world.add_block_entity(Arc::new(barrel_block_entity));
|
||||||
.add_block_entity(Arc::new(barrel_block_entity))
|
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -307,8 +307,7 @@ impl BlockBehaviour for SignBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
args.world
|
args.world
|
||||||
.add_block_entity(Arc::new(SignBlockEntity::empty(*args.position)))
|
.add_block_entity(Arc::new(SignBlockEntity::empty(*args.position)));
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,7 +367,7 @@ impl BlockBehaviour for SignBlock {
|
|||||||
|
|
||||||
fn on_state_replaced<'a>(&'a self, args: OnStateReplacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn on_state_replaced<'a>(&'a self, args: OnStateReplacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
args.world.remove_block_entity(args.position).await;
|
args.world.remove_block_entity(args.position);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,6 +466,7 @@ impl BlockBehaviour for SignBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Handles use with an item on the sign block.
|
/// Handles use with an item on the sign block.
|
||||||
|
#[expect(clippy::option_if_let_else)]
|
||||||
fn use_with_item<'a>(
|
fn use_with_item<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
args: UseWithItemArgs<'a>,
|
args: UseWithItemArgs<'a>,
|
||||||
@ -507,27 +507,39 @@ impl BlockBehaviour for SignBlock {
|
|||||||
return BlockActionResult::PassToDefaultBlockAction;
|
return BlockActionResult::PassToDefaultBlockAction;
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = if let Some(honeycomb_item) =
|
let result = pumpkin_item
|
||||||
pumpkin_item.as_any().downcast_ref::<HoneyCombItem>()
|
.as_any()
|
||||||
{
|
.downcast_ref::<HoneyCombItem>()
|
||||||
honeycomb_item
|
.map_or_else(
|
||||||
.apply_to_sign(&args, &block_entity, sign_entity)
|
|| {
|
||||||
.await
|
pumpkin_item
|
||||||
} else if let Some(g_ink_sac_item) =
|
.as_any()
|
||||||
pumpkin_item.as_any().downcast_ref::<GlowingInkSacItem>()
|
.downcast_ref::<GlowingInkSacItem>()
|
||||||
{
|
.map_or_else(
|
||||||
g_ink_sac_item
|
|| {
|
||||||
.apply_to_sign(&args, &block_entity, text)
|
if let Some(ink_sac_item) =
|
||||||
.await
|
pumpkin_item.as_any().downcast_ref::<InkSacItem>()
|
||||||
} else if let Some(ink_sac_item) = pumpkin_item.as_any().downcast_ref::<InkSacItem>() {
|
{
|
||||||
ink_sac_item.apply_to_sign(&args, &block_entity, text).await
|
ink_sac_item.apply_to_sign(&args, &block_entity, text)
|
||||||
} else if let Some(dye) = pumpkin_item.as_any().downcast_ref::<DyeItem>() {
|
} else if let Some(dye) =
|
||||||
let color_name = item.item.registry_key.strip_suffix("_dye").unwrap();
|
pumpkin_item.as_any().downcast_ref::<DyeItem>()
|
||||||
dye.apply_to_sign(&args, &block_entity, text, color_name)
|
{
|
||||||
.await
|
let color_name =
|
||||||
} else {
|
item.item.registry_key.strip_suffix("_dye").unwrap();
|
||||||
BlockActionResult::PassToDefaultBlockAction
|
dye.apply_to_sign(&args, &block_entity, text, color_name)
|
||||||
};
|
} else {
|
||||||
|
BlockActionResult::PassToDefaultBlockAction
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|g_ink_sac_item| {
|
||||||
|
g_ink_sac_item.apply_to_sign(&args, &block_entity, text)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|honeycomb_item| {
|
||||||
|
honeycomb_item.apply_to_sign(&args, &block_entity, sign_entity)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
if result == BlockActionResult::Success {
|
if result == BlockActionResult::Success {
|
||||||
if !args.player.has_infinite_materials() {
|
if !args.player.has_infinite_materials() {
|
||||||
|
|||||||
@ -116,9 +116,7 @@ impl BlockBehaviour for SmokerBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let smoker_block_entity = SmokerBlockEntity::new(*args.position);
|
let smoker_block_entity = SmokerBlockEntity::new(*args.position);
|
||||||
args.world
|
args.world.add_block_entity(Arc::new(smoker_block_entity));
|
||||||
.add_block_entity(Arc::new(smoker_block_entity))
|
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +132,7 @@ impl BlockBehaviour for SmokerBlock {
|
|||||||
ExperienceOrbEntity::spawn(args.world, pos, xp as u32).await;
|
ExperienceOrbEntity::spawn(args.world, pos, xp as u32).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
args.world.remove_block_entity(args.position).await;
|
args.world.remove_block_entity(args.position);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -93,8 +93,7 @@ impl BlockBehaviour for LayeredSnowBlock {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if !can_place_at(args.world, args.position) {
|
if !can_place_at(args.world, args.position) {
|
||||||
args.world
|
args.world
|
||||||
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal)
|
.schedule_block_tick(args.block, *args.position, 1, TickPriority::Normal);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
args.state_id
|
args.state_id
|
||||||
})
|
})
|
||||||
|
|||||||
@ -12,9 +12,7 @@ impl BlockBehaviour for SpawnerBlock {
|
|||||||
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let hopper_block_entity = MobSpawnerBlockEntity::new(*args.position, None);
|
let hopper_block_entity = MobSpawnerBlockEntity::new(*args.position, None);
|
||||||
args.world
|
args.world.add_block_entity(Arc::new(hopper_block_entity));
|
||||||
.add_block_entity(Arc::new(hopper_block_entity))
|
|
||||||
.await;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -97,10 +97,7 @@ impl DaylightDetectorBlockEntity {
|
|||||||
0 // full daylight
|
0 // full daylight
|
||||||
};
|
};
|
||||||
|
|
||||||
let sky_light_level = level
|
let sky_light_level = level.light_engine.get_sky_light_level(&level, block_pos);
|
||||||
.light_engine
|
|
||||||
.get_sky_light_level(&level, block_pos)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let mut power = sky_light_level - ambient_darkness;
|
let mut power = sky_light_level - ambient_darkness;
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ impl PistonBlockEntity {
|
|||||||
pub async fn finish(&self, world: Arc<World>) {
|
pub async fn finish(&self, world: Arc<World>) {
|
||||||
if self.last_progress.load() < 1.0 {
|
if self.last_progress.load() < 1.0 {
|
||||||
let pos = self.position;
|
let pos = self.position;
|
||||||
world.remove_block_entity(&pos).await;
|
world.remove_block_entity(&pos);
|
||||||
if world.get_block(&pos) == &Block::MOVING_PISTON {
|
if world.get_block(&pos) == &Block::MOVING_PISTON {
|
||||||
let state = if self.source {
|
let state = if self.source {
|
||||||
Block::AIR.default_state.id
|
Block::AIR.default_state.id
|
||||||
@ -67,7 +67,7 @@ impl BlockEntity for PistonBlockEntity {
|
|||||||
self.last_progress.store(current_progress);
|
self.last_progress.store(current_progress);
|
||||||
if current_progress >= 1.0 {
|
if current_progress >= 1.0 {
|
||||||
let pos = self.position;
|
let pos = self.position;
|
||||||
world.remove_block_entity(&pos).await;
|
world.remove_block_entity(&pos);
|
||||||
if world.get_block(&pos) == &Block::MOVING_PISTON {
|
if world.get_block(&pos) == &Block::MOVING_PISTON {
|
||||||
if self.pushed_block_state.is_air() {
|
if self.pushed_block_state.is_air() {
|
||||||
world
|
world
|
||||||
|
|||||||
@ -109,14 +109,12 @@ pub trait FlowingFluid: Send + Sync {
|
|||||||
|
|
||||||
// Schedule next tick for this position
|
// Schedule next tick for this position
|
||||||
let tick_delay = self.get_flow_speed(world);
|
let tick_delay = self.get_flow_speed(world);
|
||||||
world
|
world.schedule_fluid_tick(
|
||||||
.schedule_fluid_tick(
|
fluid,
|
||||||
fluid,
|
*block_pos,
|
||||||
*block_pos,
|
tick_delay,
|
||||||
tick_delay,
|
TickPriority::Normal,
|
||||||
TickPriority::Normal,
|
);
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the new state for spreading
|
// Use the new state for spreading
|
||||||
@ -400,9 +398,7 @@ pub trait FlowingFluid: Send + Sync {
|
|||||||
|
|
||||||
if !is_source {
|
if !is_source {
|
||||||
let tick_delay = self.get_flow_speed(world);
|
let tick_delay = self.get_flow_speed(world);
|
||||||
world
|
world.schedule_fluid_tick(fluid, *pos, tick_delay, TickPriority::Normal);
|
||||||
.schedule_fluid_tick(fluid, *pos, tick_delay, TickPriority::Normal)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -158,9 +158,7 @@ impl FluidBehaviour for FlowingLava {
|
|||||||
&& Self::receive_neighbor_fluids(world, fluid, block_pos).await
|
&& Self::receive_neighbor_fluids(world, fluid, block_pos).await
|
||||||
{
|
{
|
||||||
let flow_speed = self.get_flow_speed(world);
|
let flow_speed = self.get_flow_speed(world);
|
||||||
world
|
world.schedule_fluid_tick(fluid, *block_pos, flow_speed, TickPriority::Normal);
|
||||||
.schedule_fluid_tick(fluid, *block_pos, flow_speed, TickPriority::Normal)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -187,9 +185,7 @@ impl FluidBehaviour for FlowingLava {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if Self::receive_neighbor_fluids(world, fluid, block_pos).await {
|
if Self::receive_neighbor_fluids(world, fluid, block_pos).await {
|
||||||
let flow_speed = self.get_flow_speed(world);
|
let flow_speed = self.get_flow_speed(world);
|
||||||
world
|
world.schedule_fluid_tick(fluid, *block_pos, flow_speed, TickPriority::Normal);
|
||||||
.schedule_fluid_tick(fluid, *block_pos, flow_speed, TickPriority::Normal)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,9 +31,12 @@ impl FluidBehaviour for FlowingWater {
|
|||||||
) -> BlockFuture<'a, ()> {
|
) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if old_state_id != state_id {
|
if old_state_id != state_id {
|
||||||
world
|
world.schedule_fluid_tick(
|
||||||
.schedule_fluid_tick(fluid, *block_pos, WATER_FLOW_SPEED, TickPriority::Normal)
|
fluid,
|
||||||
.await;
|
*block_pos,
|
||||||
|
WATER_FLOW_SPEED,
|
||||||
|
TickPriority::Normal,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -59,10 +62,13 @@ impl FluidBehaviour for FlowingWater {
|
|||||||
) -> BlockFuture<'a, ()> {
|
) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
// Avoid rescheduling a fluid tick if one is already queued.
|
// Avoid rescheduling a fluid tick if one is already queued.
|
||||||
if !world.is_fluid_tick_scheduled(block_pos, fluid).await {
|
if !world.is_fluid_tick_scheduled(block_pos, fluid) {
|
||||||
world
|
world.schedule_fluid_tick(
|
||||||
.schedule_fluid_tick(fluid, *block_pos, WATER_FLOW_SPEED, TickPriority::Normal)
|
fluid,
|
||||||
.await;
|
*block_pos,
|
||||||
|
WATER_FLOW_SPEED,
|
||||||
|
TickPriority::Normal,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -157,7 +157,11 @@ impl BlockPosArgumentConsumer {
|
|||||||
) -> Result<BlockPos, CommandError> {
|
) -> Result<BlockPos, CommandError> {
|
||||||
let pos = Self::find_arg(args, name)?;
|
let pos = Self::find_arg(args, name)?;
|
||||||
|
|
||||||
if world.level.try_get_chunk(&pos.chunk_position()).is_none() {
|
if world
|
||||||
|
.level
|
||||||
|
.read_chunk_sync(&pos.chunk_position(), |_| ())
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
return Err(CommandError::CommandFailed(TextComponent::translate_cross(
|
return Err(CommandError::CommandFailed(TextComponent::translate_cross(
|
||||||
"argument.pos.unloaded",
|
"argument.pos.unloaded",
|
||||||
"argument.pos.unloaded",
|
"argument.pos.unloaded",
|
||||||
|
|||||||
@ -109,7 +109,11 @@ impl BlockPosArgumentType {
|
|||||||
world: &World,
|
world: &World,
|
||||||
) -> Result<BlockPos, CommandSyntaxError> {
|
) -> Result<BlockPos, CommandSyntaxError> {
|
||||||
let pos = Self::get_block_pos(context, name)?;
|
let pos = Self::get_block_pos(context, name)?;
|
||||||
if world.level.try_get_chunk(&pos.chunk_position()).is_none() {
|
if world
|
||||||
|
.level
|
||||||
|
.read_chunk_sync(&pos.chunk_position(), |_| ())
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
Err(NOT_LOADED_ERROR_TYPE.create_without_context())
|
Err(NOT_LOADED_ERROR_TYPE.create_without_context())
|
||||||
} else if !world.is_in_build_limit(pos) {
|
} else if !world.is_in_build_limit(pos) {
|
||||||
Err(OUT_OF_WORLD_ERROR_TYPE.create_without_context())
|
Err(OUT_OF_WORLD_ERROR_TYPE.create_without_context())
|
||||||
|
|||||||
@ -186,12 +186,13 @@ impl CommandSender {
|
|||||||
Self::CommandBlock(command_block, world) => {
|
Self::CommandBlock(command_block, world) => {
|
||||||
let pos = command_block.get_position();
|
let pos = command_block.get_position();
|
||||||
let (chunk_coordinate, relative) = pos.chunk_and_chunk_relative_position();
|
let (chunk_coordinate, relative) = pos.chunk_and_chunk_relative_position();
|
||||||
let chunk = world.level.try_get_chunk(&chunk_coordinate)?;
|
let state_id = world.level.read_chunk_sync(&chunk_coordinate, |chunk| {
|
||||||
let state_id = chunk.section.get_block_absolute_y(
|
chunk.section.get_block_absolute_y(
|
||||||
relative.x as usize,
|
relative.x as usize,
|
||||||
relative.y,
|
relative.y,
|
||||||
relative.z as usize,
|
relative.z as usize,
|
||||||
)?;
|
)
|
||||||
|
})??;
|
||||||
let block = Block::from_state_id(state_id);
|
let block = Block::from_state_id(state_id);
|
||||||
if !CommandBlockLikeProperties::handles_block_id(block.id) {
|
if !CommandBlockLikeProperties::handles_block_id(block.id) {
|
||||||
return None;
|
return None;
|
||||||
|
|||||||
@ -359,7 +359,10 @@ impl EntityBase for ArmorStandEntity {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if entity.is_invulnerable_to(&damage_type) || self.is_invisible() || self.is_marker() {
|
if entity.is_invulnerable_to(&damage_type).await
|
||||||
|
|| self.is_invisible()
|
||||||
|
|| self.is_marker()
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1850,7 +1850,7 @@ impl EntityBase for LivingEntity {
|
|||||||
let mut amount = amount;
|
let mut amount = amount;
|
||||||
|
|
||||||
// Check invulnerability before applying damage
|
// Check invulnerability before applying damage
|
||||||
if self.entity.is_invulnerable_to(&damage_type) {
|
if self.entity.is_invulnerable_to(&damage_type).await {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -51,7 +51,7 @@ impl BatEntity {
|
|||||||
if rand::random_bool(1.0) {
|
if rand::random_bool(1.0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if world.get_max_local_raw_brightness_sync(pos) > rand::random_range(0..4) {
|
if world.get_max_local_raw_brightness(pos) > rand::random_range(0..4) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if world
|
if world
|
||||||
|
|||||||
@ -184,7 +184,7 @@ impl MobEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_dark_enough_to_spawn(world: &World, pos: &BlockPos, is_thundering: bool) -> bool {
|
pub fn is_dark_enough_to_spawn(world: &World, pos: &BlockPos, is_thundering: bool) -> bool {
|
||||||
let sky_light = world.get_sky_light_level_sync(pos);
|
let sky_light = world.get_sky_light_level(pos);
|
||||||
if sky_light > rand::random_range(0..32) {
|
if sky_light > rand::random_range(0..32) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -192,7 +192,7 @@ impl MobEntity {
|
|||||||
let dimension = &world.dimension;
|
let dimension = &world.dimension;
|
||||||
let block_light_limit = dimension.monster_spawn_block_light_limit;
|
let block_light_limit = dimension.monster_spawn_block_light_limit;
|
||||||
|
|
||||||
let block_light = world.get_block_light_level_sync(pos).unwrap();
|
let block_light = world.get_block_light_level(pos).unwrap();
|
||||||
if block_light_limit < 15 && block_light > block_light_limit {
|
if block_light_limit < 15 && block_light > block_light_limit {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -307,7 +307,7 @@ impl MobEntity {
|
|||||||
.level
|
.level
|
||||||
.light_engine
|
.light_engine
|
||||||
.get_sky_light_level(&world.level, &eye_block_pos.to_block_pos())
|
.get_sky_light_level(&world.level, &eye_block_pos.to_block_pos())
|
||||||
.await as f32
|
as f32
|
||||||
/ 15.0;
|
/ 15.0;
|
||||||
|
|
||||||
if brightness <= 0.5 {
|
if brightness <= 0.5 {
|
||||||
|
|||||||
@ -2293,7 +2293,7 @@ impl Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the entity is invulnerable to the given damage type, considering both general invulnerability and specific immunities.
|
/// Checks if the entity is invulnerable to the given damage type, considering both general invulnerability and specific immunities.
|
||||||
pub fn is_invulnerable_to(&self, damage_type: &DamageType) -> bool {
|
pub async fn is_invulnerable_to(&self, damage_type: &DamageType) -> bool {
|
||||||
// Nothing is immune to void or kill
|
// Nothing is immune to void or kill
|
||||||
if matches!(
|
if matches!(
|
||||||
*damage_type,
|
*damage_type,
|
||||||
@ -2308,9 +2308,7 @@ impl Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Specific type immunities
|
// Specific type immunities
|
||||||
futures::executor::block_on(async {
|
self.damage_immunities.lock().await.contains(damage_type)
|
||||||
self.damage_immunities.lock().await.contains(damage_type)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets if the entity is invulnerable to a specific damage type
|
/// Sets if the entity is invulnerable to a specific damage type
|
||||||
|
|||||||
@ -142,9 +142,7 @@ async fn try_pickup_bucket_item(
|
|||||||
world
|
world
|
||||||
.set_block_state(&block_pos, state_id, BlockFlags::NOTIFY_NEIGHBORS)
|
.set_block_state(&block_pos, state_id, BlockFlags::NOTIFY_NEIGHBORS)
|
||||||
.await;
|
.await;
|
||||||
world
|
world.schedule_fluid_tick(&Fluid::WATER, block_pos, 5, TickPriority::Normal);
|
||||||
.schedule_fluid_tick(&Fluid::WATER, block_pos, 5, TickPriority::Normal)
|
|
||||||
.await;
|
|
||||||
return Some(&Item::WATER_BUCKET);
|
return Some(&Item::WATER_BUCKET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,9 +171,7 @@ async fn try_pickup_bucket_item(
|
|||||||
world
|
world
|
||||||
.set_block_state(&target_pos, state_id, BlockFlags::NOTIFY_NEIGHBORS)
|
.set_block_state(&target_pos, state_id, BlockFlags::NOTIFY_NEIGHBORS)
|
||||||
.await;
|
.await;
|
||||||
world
|
world.schedule_fluid_tick(&Fluid::WATER, target_pos, 5, TickPriority::Normal);
|
||||||
.schedule_fluid_tick(&Fluid::WATER, target_pos, 5, TickPriority::Normal)
|
|
||||||
.await;
|
|
||||||
return Some(&Item::WATER_BUCKET);
|
return Some(&Item::WATER_BUCKET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,9 +235,7 @@ async fn try_place_filled_bucket(
|
|||||||
world
|
world
|
||||||
.set_block_state(&pos, state_id, BlockFlags::NOTIFY_NEIGHBORS)
|
.set_block_state(&pos, state_id, BlockFlags::NOTIFY_NEIGHBORS)
|
||||||
.await;
|
.await;
|
||||||
world
|
world.schedule_fluid_tick(&Fluid::WATER, pos, 5, TickPriority::Normal);
|
||||||
.schedule_fluid_tick(&Fluid::WATER, pos, 5, TickPriority::Normal)
|
|
||||||
.await;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,9 +250,7 @@ async fn try_place_filled_bucket(
|
|||||||
world
|
world
|
||||||
.set_block_state(&target_pos, state_id, BlockFlags::NOTIFY_NEIGHBORS)
|
.set_block_state(&target_pos, state_id, BlockFlags::NOTIFY_NEIGHBORS)
|
||||||
.await;
|
.await;
|
||||||
world
|
world.schedule_fluid_tick(&Fluid::WATER, target_pos, 5, TickPriority::Normal);
|
||||||
.schedule_fluid_tick(&Fluid::WATER, target_pos, 5, TickPriority::Normal)
|
|
||||||
.await;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,7 @@ impl ItemBehaviour for DyeItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DyeItem {
|
impl DyeItem {
|
||||||
pub async fn apply_to_sign(
|
pub fn apply_to_sign(
|
||||||
&self,
|
&self,
|
||||||
args: &UseWithItemArgs<'_>,
|
args: &UseWithItemArgs<'_>,
|
||||||
block_entity: &Arc<dyn BlockEntity>,
|
block_entity: &Arc<dyn BlockEntity>,
|
||||||
@ -43,7 +43,7 @@ impl DyeItem {
|
|||||||
|
|
||||||
text.set_color(dye_color);
|
text.set_color(dye_color);
|
||||||
|
|
||||||
args.world.update_block_entity(block_entity).await;
|
args.world.update_block_entity(block_entity);
|
||||||
args.world.play_block_sound(
|
args.world.play_block_sound(
|
||||||
pumpkin_data::sound::Sound::ItemDyeUse,
|
pumpkin_data::sound::Sound::ItemDyeUse,
|
||||||
pumpkin_data::sound::SoundCategory::Blocks,
|
pumpkin_data::sound::SoundCategory::Blocks,
|
||||||
|
|||||||
@ -23,7 +23,7 @@ impl ItemBehaviour for GlowingInkSacItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GlowingInkSacItem {
|
impl GlowingInkSacItem {
|
||||||
pub async fn apply_to_sign(
|
pub fn apply_to_sign(
|
||||||
&self,
|
&self,
|
||||||
args: &UseWithItemArgs<'_>,
|
args: &UseWithItemArgs<'_>,
|
||||||
block_entity: &Arc<dyn BlockEntity>,
|
block_entity: &Arc<dyn BlockEntity>,
|
||||||
@ -35,7 +35,7 @@ impl GlowingInkSacItem {
|
|||||||
return BlockActionResult::PassToDefaultBlockAction;
|
return BlockActionResult::PassToDefaultBlockAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
args.world.update_block_entity(block_entity).await;
|
args.world.update_block_entity(block_entity);
|
||||||
args.world.play_block_sound(
|
args.world.play_block_sound(
|
||||||
pumpkin_data::sound::Sound::ItemGlowInkSacUse,
|
pumpkin_data::sound::Sound::ItemGlowInkSacUse,
|
||||||
pumpkin_data::sound::SoundCategory::Blocks,
|
pumpkin_data::sound::SoundCategory::Blocks,
|
||||||
|
|||||||
@ -86,7 +86,7 @@ impl ItemBehaviour for HoneyCombItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HoneyCombItem {
|
impl HoneyCombItem {
|
||||||
pub async fn apply_to_sign(
|
pub fn apply_to_sign(
|
||||||
&self,
|
&self,
|
||||||
args: &UseWithItemArgs<'_>,
|
args: &UseWithItemArgs<'_>,
|
||||||
block_entity: &Arc<dyn BlockEntity>,
|
block_entity: &Arc<dyn BlockEntity>,
|
||||||
@ -94,7 +94,7 @@ impl HoneyCombItem {
|
|||||||
) -> BlockActionResult {
|
) -> BlockActionResult {
|
||||||
sign_entity.is_waxed.store(true, Ordering::Relaxed);
|
sign_entity.is_waxed.store(true, Ordering::Relaxed);
|
||||||
|
|
||||||
args.world.update_block_entity(block_entity).await;
|
args.world.update_block_entity(block_entity);
|
||||||
args.world
|
args.world
|
||||||
.sync_world_event(WorldEvent::ParticlesAndSoundWaxOn, *args.position, 0);
|
.sync_world_event(WorldEvent::ParticlesAndSoundWaxOn, *args.position, 0);
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,7 @@ impl ItemBehaviour for InkSacItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl InkSacItem {
|
impl InkSacItem {
|
||||||
pub async fn apply_to_sign(
|
pub fn apply_to_sign(
|
||||||
&self,
|
&self,
|
||||||
args: &UseWithItemArgs<'_>,
|
args: &UseWithItemArgs<'_>,
|
||||||
block_entity: &Arc<dyn BlockEntity>,
|
block_entity: &Arc<dyn BlockEntity>,
|
||||||
@ -35,7 +35,7 @@ impl InkSacItem {
|
|||||||
return BlockActionResult::PassToDefaultBlockAction;
|
return BlockActionResult::PassToDefaultBlockAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
args.world.update_block_entity(block_entity).await;
|
args.world.update_block_entity(block_entity);
|
||||||
args.world.play_block_sound(
|
args.world.play_block_sound(
|
||||||
pumpkin_data::sound::Sound::ItemInkSacUse,
|
pumpkin_data::sound::Sound::ItemInkSacUse,
|
||||||
pumpkin_data::sound::SoundCategory::Blocks,
|
pumpkin_data::sound::SoundCategory::Blocks,
|
||||||
|
|||||||
@ -42,7 +42,7 @@ impl ItemBehaviour for SpawnEggItem {
|
|||||||
.downcast_ref::<MobSpawnerBlockEntity>()
|
.downcast_ref::<MobSpawnerBlockEntity>()
|
||||||
{
|
{
|
||||||
spawner.set_entity_type(entity_type);
|
spawner.set_entity_type(entity_type);
|
||||||
world.update_block_entity(&block_entity).await;
|
world.update_block_entity(&block_entity);
|
||||||
item.decrement_unless_creative(player.gamemode.load(), 1);
|
item.decrement_unless_creative(player.gamemode.load(), 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -769,10 +769,7 @@ impl JavaClient {
|
|||||||
track_output: (command.flags & 0x1 != 0).into(),
|
track_output: (command.flags & 0x1 != 0).into(),
|
||||||
success_count: AtomicU32::new(0),
|
success_count: AtomicU32::new(0),
|
||||||
};
|
};
|
||||||
player
|
player.world().add_block_entity(Arc::new(command_block));
|
||||||
.world()
|
|
||||||
.add_block_entity(Arc::new(command_block))
|
|
||||||
.await;
|
|
||||||
|
|
||||||
player
|
player
|
||||||
.send_system_message(&TextComponent::text(format!(
|
.send_system_message(&TextComponent::text(format!(
|
||||||
@ -783,15 +780,12 @@ impl JavaClient {
|
|||||||
|
|
||||||
// The 0x4 flag means always active
|
// The 0x4 flag means always active
|
||||||
if command.flags & 0x4 != 0 && block_type != Block::CHAIN_COMMAND_BLOCK {
|
if command.flags & 0x4 != 0 && block_type != Block::CHAIN_COMMAND_BLOCK {
|
||||||
player
|
player.world().schedule_block_tick(
|
||||||
.world()
|
&block_type,
|
||||||
.schedule_block_tick(
|
pos,
|
||||||
&block_type,
|
1,
|
||||||
pos,
|
pumpkin_world::tick::TickPriority::Normal,
|
||||||
1,
|
);
|
||||||
pumpkin_world::tick::TickPriority::Normal,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2228,7 +2222,7 @@ impl JavaClient {
|
|||||||
sign_data.line_4,
|
sign_data.line_4,
|
||||||
];
|
];
|
||||||
*sign_entity.currently_editing_player.lock().await = None;
|
*sign_entity.currently_editing_player.lock().await = None;
|
||||||
world.update_block_entity(&block_entity).await;
|
world.update_block_entity(&block_entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_use_item(
|
pub async fn handle_use_item(
|
||||||
|
|||||||
@ -1075,7 +1075,7 @@ impl World {
|
|||||||
|
|
||||||
let mut spawning_chunks = Vec::new();
|
let mut spawning_chunks = Vec::new();
|
||||||
for pos in active_chunks.iter() {
|
for pos in active_chunks.iter() {
|
||||||
if let Some(chunk) = self.level.try_get_chunk(pos) {
|
if let Some(chunk) = self.level.read_chunk_sync(pos, std::clone::Clone::clone) {
|
||||||
spawning_chunks.push((*pos, chunk));
|
spawning_chunks.push((*pos, chunk));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1536,15 +1536,36 @@ impl World {
|
|||||||
|
|
||||||
/// Gets the y position of the first non air block from the top down
|
/// Gets the y position of the first non air block from the top down
|
||||||
pub fn get_top_block(&self, position: Vector2<i32>) -> i32 {
|
pub fn get_top_block(&self, position: Vector2<i32>) -> i32 {
|
||||||
for y in (self.dimension.min_y..self.dimension.height).rev() {
|
let chunk_pos = Vector2::new(position.x >> 4, position.y >> 4);
|
||||||
let pos = BlockPos::new(position.x, y, position.y);
|
let relative_x = (position.x & 15) as usize;
|
||||||
let block = self.get_block_state(&pos);
|
let relative_z = (position.y & 15) as usize;
|
||||||
if block.is_air() {
|
|
||||||
continue;
|
self.level
|
||||||
}
|
.read_chunk_sync(&chunk_pos, |chunk| {
|
||||||
return y;
|
let height = chunk.heightmap.lock().unwrap().get(
|
||||||
}
|
ChunkHeightmapType::WorldSurface,
|
||||||
self.dimension.min_y
|
position.x,
|
||||||
|
position.y,
|
||||||
|
self.dimension.min_y,
|
||||||
|
);
|
||||||
|
|
||||||
|
if height >= self.dimension.min_y {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
for y in (self.dimension.min_y..self.dimension.min_y + self.dimension.height).rev()
|
||||||
|
{
|
||||||
|
if let Some(block_id) = chunk
|
||||||
|
.section
|
||||||
|
.get_block_absolute_y(relative_x, y, relative_z)
|
||||||
|
&& !is_air(block_id)
|
||||||
|
{
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.dimension.min_y
|
||||||
|
})
|
||||||
|
.unwrap_or(self.dimension.min_y)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_heightmap_height(&self, height_map: ChunkHeightmapType, x: i32, z: i32) -> i32 {
|
pub fn get_heightmap_height(&self, height_map: ChunkHeightmapType, x: i32, z: i32) -> i32 {
|
||||||
@ -3245,7 +3266,7 @@ impl World {
|
|||||||
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
|
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
|
||||||
let replaced_block_state_id = self
|
let replaced_block_state_id = self
|
||||||
.level
|
.level
|
||||||
.get_or_fetch_chunk(chunk_coordinate, |chunk| {
|
.read_chunk_sync(&chunk_coordinate, |chunk| {
|
||||||
let replaced_block_state_id = chunk.set_block_absolute_y(
|
let replaced_block_state_id = chunk.set_block_absolute_y(
|
||||||
relative.x as usize,
|
relative.x as usize,
|
||||||
relative.y,
|
relative.y,
|
||||||
@ -3258,7 +3279,7 @@ impl World {
|
|||||||
}
|
}
|
||||||
replaced_block_state_id
|
replaced_block_state_id
|
||||||
})
|
})
|
||||||
.await;
|
.unwrap_or(Block::AIR.default_state.id);
|
||||||
|
|
||||||
if replaced_block_state_id == block_state_id {
|
if replaced_block_state_id == block_state_id {
|
||||||
return block_state_id;
|
return block_state_id;
|
||||||
@ -3282,7 +3303,7 @@ impl World {
|
|||||||
&& let Some(entity) = self.get_block_entity(position)
|
&& let Some(entity) = self.get_block_entity(position)
|
||||||
{
|
{
|
||||||
entity.on_block_replaced(self.clone(), *position).await;
|
entity.on_block_replaced(self.clone(), *position).await;
|
||||||
self.remove_block_entity(position).await;
|
self.remove_block_entity(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// WorldChunk.java line 317
|
// WorldChunk.java line 317
|
||||||
@ -3377,49 +3398,25 @@ impl World {
|
|||||||
replaced_block_state_id
|
replaced_block_state_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_thundering_sync(&self) -> bool {
|
pub fn get_max_local_raw_brightness(&self, pos: &BlockPos) -> u8 {
|
||||||
self.weather.blocking_lock().thundering
|
let sky_light = self.get_sky_light_level(pos);
|
||||||
}
|
let block_light = self.get_block_light_level(pos).unwrap_or(0);
|
||||||
|
|
||||||
pub fn get_block_light_level_sync(&self, position: &BlockPos) -> Option<u8> {
|
|
||||||
self.level
|
|
||||||
.light_engine
|
|
||||||
.get_block_light_level_sync(&self.level, position)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_sky_light_level_sync(&self, position: &BlockPos) -> u8 {
|
|
||||||
self.level
|
|
||||||
.light_engine
|
|
||||||
.get_sky_light_level_sync(&self.level, position)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_max_local_raw_brightness_sync(&self, pos: &BlockPos) -> u8 {
|
|
||||||
let sky_light = self.get_sky_light_level_sync(pos);
|
|
||||||
let block_light = self.get_block_light_level_sync(pos).unwrap_or(0);
|
|
||||||
sky_light.max(block_light) // TODO: getSkyDarken
|
sky_light.max(block_light) // TODO: getSkyDarken
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_max_local_raw_brightness(&self, pos: &BlockPos) -> u8 {
|
pub fn get_block_light_level(&self, position: &BlockPos) -> Option<u8> {
|
||||||
let sky_light = self.get_sky_light_level(pos).await;
|
|
||||||
let block_light = self.get_block_light_level(pos).await.unwrap();
|
|
||||||
sky_light.max(block_light) // TODO: getSkyDarken
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_block_light_level(&self, position: &BlockPos) -> Option<u8> {
|
|
||||||
self.level
|
self.level
|
||||||
.light_engine
|
.light_engine
|
||||||
.get_block_light_level(&self.level, position)
|
.get_block_light_level(&self.level, position)
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_sky_light_level(&self, position: &BlockPos) -> u8 {
|
pub fn get_sky_light_level(&self, position: &BlockPos) -> u8 {
|
||||||
self.level
|
self.level
|
||||||
.light_engine
|
.light_engine
|
||||||
.get_sky_light_level(&self.level, position)
|
.get_sky_light_level(&self.level, position)
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn schedule_block_tick(
|
pub fn schedule_block_tick(
|
||||||
&self,
|
&self,
|
||||||
block: &Block,
|
block: &Block,
|
||||||
block_pos: BlockPos,
|
block_pos: BlockPos,
|
||||||
@ -3427,11 +3424,10 @@ impl World {
|
|||||||
priority: TickPriority,
|
priority: TickPriority,
|
||||||
) {
|
) {
|
||||||
self.level
|
self.level
|
||||||
.schedule_block_tick(block, block_pos, delay, priority)
|
.schedule_block_tick(block, block_pos, delay, priority);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn schedule_fluid_tick(
|
pub fn schedule_fluid_tick(
|
||||||
&self,
|
&self,
|
||||||
fluid: &Fluid,
|
fluid: &Fluid,
|
||||||
block_pos: BlockPos,
|
block_pos: BlockPos,
|
||||||
@ -3439,16 +3435,15 @@ impl World {
|
|||||||
priority: TickPriority,
|
priority: TickPriority,
|
||||||
) {
|
) {
|
||||||
self.level
|
self.level
|
||||||
.schedule_fluid_tick(fluid, block_pos, delay, priority)
|
.schedule_fluid_tick(fluid, block_pos, delay, priority);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn is_block_tick_scheduled(&self, block_pos: &BlockPos, block: &Block) -> bool {
|
pub fn is_block_tick_scheduled(&self, block_pos: &BlockPos, block: &Block) -> bool {
|
||||||
self.level.is_block_tick_scheduled(block_pos, block).await
|
self.level.is_block_tick_scheduled(block_pos, block)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn is_fluid_tick_scheduled(&self, block_pos: &BlockPos, fluid: &Fluid) -> bool {
|
pub fn is_fluid_tick_scheduled(&self, block_pos: &BlockPos, fluid: &Fluid) -> bool {
|
||||||
self.level.is_fluid_tick_scheduled(block_pos, fluid).await
|
self.level.is_fluid_tick_scheduled(block_pos, fluid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return new state
|
// Return new state
|
||||||
@ -3664,10 +3659,11 @@ impl World {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
|
let (chunk_coordinate, relative) = position.chunk_and_chunk_relative_position();
|
||||||
let chunk = self.level.try_get_chunk(&chunk_coordinate)?;
|
self.level.read_chunk_sync(&chunk_coordinate, |chunk| {
|
||||||
chunk
|
chunk
|
||||||
.section
|
.section
|
||||||
.get_block_absolute_y(relative.x as usize, relative.y, relative.z as usize)
|
.get_block_absolute_y(relative.x as usize, relative.y, relative.z as usize)
|
||||||
|
})?
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -3929,7 +3925,7 @@ impl World {
|
|||||||
.map(|e| e.value().clone())
|
.map(|e| e.value().clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_block_entity(&self, block_entity: Arc<dyn BlockEntity>) {
|
pub fn add_block_entity(&self, block_entity: Arc<dyn BlockEntity>) {
|
||||||
let block_pos = block_entity.get_position();
|
let block_pos = block_entity.get_position();
|
||||||
let chunk_pos = block_pos.chunk_position();
|
let chunk_pos = block_pos.chunk_position();
|
||||||
let block_entity_nbt = block_entity.chunk_data_nbt();
|
let block_entity_nbt = block_entity.chunk_data_nbt();
|
||||||
@ -3947,25 +3943,22 @@ impl World {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.block_entities.insert(block_pos, block_entity.clone());
|
self.block_entities.insert(block_pos, block_entity);
|
||||||
self.level
|
self.level.read_chunk_sync(&chunk_pos, |chunk| {
|
||||||
.get_or_fetch_chunk(chunk_pos, |chunk| {
|
chunk.mark_dirty(true);
|
||||||
chunk.mark_dirty(true);
|
});
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn remove_block_entity(&self, block_pos: &BlockPos) {
|
pub fn remove_block_entity(&self, block_pos: &BlockPos) {
|
||||||
if self.block_entities.remove(block_pos).is_some() {
|
if self.block_entities.remove(block_pos).is_some() {
|
||||||
self.level
|
self.level
|
||||||
.get_or_fetch_chunk(block_pos.chunk_position(), |chunk| {
|
.read_chunk_sync(&block_pos.chunk_position(), |chunk| {
|
||||||
chunk.mark_dirty(true);
|
chunk.mark_dirty(true);
|
||||||
})
|
});
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_block_entity(&self, block_entity: &Arc<dyn BlockEntity>) {
|
pub fn update_block_entity(&self, block_entity: &Arc<dyn BlockEntity>) {
|
||||||
let block_pos = block_entity.get_position();
|
let block_pos = block_entity.get_position();
|
||||||
let chunk_pos = block_pos.chunk_position();
|
let chunk_pos = block_pos.chunk_position();
|
||||||
let block_entity_nbt = block_entity.chunk_data_nbt();
|
let block_entity_nbt = block_entity.chunk_data_nbt();
|
||||||
@ -3982,11 +3975,9 @@ impl World {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
self.level
|
self.level.read_chunk_sync(&chunk_pos, |chunk| {
|
||||||
.get_or_fetch_chunk(chunk_pos, |chunk| {
|
chunk.mark_dirty(true);
|
||||||
chunk.mark_dirty(true);
|
});
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intersects_aabb_with_direction(
|
fn intersects_aabb_with_direction(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user