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