Skip to content

Commit

Permalink
feat: add multiple BlockUpdateService#scheduleRandomBlockUpdate met…
Browse files Browse the repository at this point in the history
…hod overloads, which can schedule a random block update at a specified position. These methods are used by fire block currently to make it able to change fire spreading speed by changing random block update speed
  • Loading branch information
smartcmd committed Jan 22, 2025
1 parent dc360b6 commit 8ed3d6f
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 21 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ Unless otherwise specified, any version comparison below is the comparison of se
- (API) Implemented ender chest, and several related interfaces & objects including `BlockEntityEnderChest`,
`EnderChestContainer`, are added to api module, see commit history for more details.
- (API) Added `VoxelShape#intersectsRay` method, which can determine whether the given ray intersects the voxel shape.
- (API) Added multiple `BlockUpdateService#scheduleRandomBlockUpdate` method overloads, which can schedule a random block
update at a specified position. These methods are used by fire block currently to make it able to change fire spreading
speed by changing random block update speed.

### Changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,26 @@
public interface BlockUpdateService {

/**
* Schedule a block update at the specified position.
*
* @param pos The position of the block to update.
* @param delay The delay of the block update, in ticks.
* @see #scheduleBlockUpdate(Vector3ic, int, int)
*/
default void scheduleBlockUpdate(Vector3ic pos, int delay) {
scheduleBlockUpdate(pos, delay, 0);
}

/**
* @see #scheduleBlockUpdate(Vector3ic, int, int)
*/
default void scheduleBlockUpdate(Vector3ic pos, Duration delay) {
scheduleBlockUpdate(pos, delay, 0);
}

/**
* @see #scheduleBlockUpdate(Vector3ic, int, int)
*/
default void scheduleBlockUpdate(Vector3ic pos, Duration delay, int layer) {
scheduleBlockUpdate(pos, (int) (delay.toNanos() / 50_000_000), layer);
}

/**
* Schedule a block update at the specified position.
*
Expand All @@ -32,25 +43,39 @@ default void scheduleBlockUpdate(Vector3ic pos, int delay) {
void scheduleBlockUpdate(Vector3ic pos, int delay, int layer);

/**
* Schedule a block update at the specified position.
*
* @param pos The position of the block to update
* @param delay The delay of the block update
* @see #scheduleRandomBlockUpdate(Vector3ic, int, int)
*/
default void scheduleBlockUpdate(Vector3ic pos, Duration delay) {
scheduleBlockUpdate(pos, delay, 0);
default void scheduleRandomBlockUpdate(Vector3ic pos, int delay) {
scheduleRandomBlockUpdate(pos, delay, 0);
}

/**
* Schedule a block update at the specified position.
* @see #scheduleRandomBlockUpdate(Vector3ic, int, int)
*/
default void scheduleRandomBlockUpdate(Vector3ic pos, Duration delay) {
scheduleRandomBlockUpdate(pos, delay, 0);
}

/**
* @see #scheduleRandomBlockUpdate(Vector3ic, int, int)
*/
default void scheduleRandomBlockUpdate(Vector3ic pos, Duration delay, int layer) {
scheduleRandomBlockUpdate(pos, (int) (delay.toNanos() / 50_000_000), layer);
}

/**
* Schedule a random block update at the specified position. Calling this method is considered
* equivalent to {@code scheduleBlockUpdate(pos, (int) ((float) delay / (float) randomTickSpeed), layer)}.
* <p>
* Unlike {@link #scheduleBlockUpdate(Vector3ic, int, int)}, in this method the delay will also
* be divided by the random tick speed of the current world. For example, this method is used
* by fire, so changing the random tick speed will also change the speed of fire spreading.
*
* @param pos The position of the block to update
* @param delay The delay of the block update
* @param pos The position of the block to update.
* @param delay The delay of the block update, in ticks.
* @param layer The layer of the block update.
*/
default void scheduleBlockUpdate(Vector3ic pos, Duration delay, int layer) {
scheduleBlockUpdate(pos, (int) (delay.toNanos() / 50_000_000), layer);
}
void scheduleRandomBlockUpdate(Vector3ic pos, int delay, int layer);

/**
* Check if a block update is scheduled at the specified position.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public BlockFireBaseComponentImpl(BlockType<? extends BlockBehavior> blockType)
@Override
public void onPlace(BlockStateWithPos currentBlockState, BlockState newBlockState, PlayerInteractInfo placementInfo) {
super.onPlace(currentBlockState, newBlockState, placementInfo);
currentBlockState.dimension().getBlockUpdateService().scheduleBlockUpdate(currentBlockState.pos(), FIRE_SCHEDULED_UPDATE_DELAY);
currentBlockState.dimension().getBlockUpdateService().scheduleRandomBlockUpdate(currentBlockState.pos(), FIRE_SCHEDULED_UPDATE_DELAY);
}

@Override
Expand All @@ -61,7 +61,7 @@ public void onNeighborUpdate(BlockStateWithPos current, BlockStateWithPos neighb
dimension.setBlockState(pos, event.getNewBlockState());
}
} else if (dimension.getWorld().getWorldData().<Boolean>getGameRuleValue(GameRule.DO_FIRE_TICK) && !dimension.getBlockUpdateService().hasScheduledBlockUpdate(pos)) {
dimension.getBlockUpdateService().scheduleBlockUpdate(pos, FIRE_SCHEDULED_UPDATE_DELAY);
dimension.getBlockUpdateService().scheduleRandomBlockUpdate(pos, FIRE_SCHEDULED_UPDATE_DELAY);
}
}

Expand Down Expand Up @@ -99,7 +99,7 @@ public void onScheduledUpdate(BlockStateWithPos blockStateWithPos) {
dimension.setBlockState(pos, newBlockState);
}

dimension.getBlockUpdateService().scheduleBlockUpdate(pos, FIRE_SCHEDULED_UPDATE_DELAY + random.nextInt(10));
dimension.getBlockUpdateService().scheduleRandomBlockUpdate(pos, FIRE_SCHEDULED_UPDATE_DELAY + random.nextInt(10));

var burnForever = canFireBurnForever(downBlockState);

Expand Down Expand Up @@ -191,7 +191,7 @@ protected void spreadFire(BlockStateWithPos source) {

if (event.call()) {
dimension.setBlockState(lx, ly, lz, BlockTypes.FIRE.ofState(BlockPropertyTypes.AGE_16.createValue(newAge)));
dimension.getBlockUpdateService().scheduleBlockUpdate(new Vector3i(lx, ly, lz), FIRE_SCHEDULED_UPDATE_DELAY);
dimension.getBlockUpdateService().scheduleRandomBlockUpdate(new Vector3i(lx, ly, lz), FIRE_SCHEDULED_UPDATE_DELAY);
}
}
}
Expand All @@ -211,7 +211,7 @@ protected void burnBlock(BlockStateWithPos source, BlockStateWithPos target, int
var event = new BlockIgniteEvent(target, source, null, BlockIgniteEvent.BlockIgniteCause.SPREAD);
if (event.call()) {
dimension.setBlockState(target.pos(), BlockTypes.FIRE.ofState(BlockPropertyTypes.AGE_16.createValue(currentFireAge)));
dimension.getBlockUpdateService().scheduleBlockUpdate(target.pos(), FIRE_SCHEDULED_UPDATE_DELAY);
dimension.getBlockUpdateService().scheduleRandomBlockUpdate(target.pos(), FIRE_SCHEDULED_UPDATE_DELAY);
}
} else {
var event = new BlockBurnEvent(target);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.allaymc.api.eventbus.event.block.BlockNeighborUpdateEvent;
import org.allaymc.api.math.position.Position3i;
import org.allaymc.api.world.Dimension;
import org.allaymc.api.world.gamerule.GameRule;
import org.allaymc.api.world.service.BlockUpdateService;
import org.joml.Vector3ic;

Expand Down Expand Up @@ -40,6 +41,11 @@ public void scheduleBlockUpdate(Vector3ic pos, int delay, int layer) {
chunk.addScheduledUpdate(pos.x() & 15, pos.y(), pos.z() & 15, delay, layer);
}

@Override
public void scheduleRandomBlockUpdate(Vector3ic pos, int delay, int layer) {
scheduleBlockUpdate(pos, (int) ((float) delay / (float) dimension.getWorld().getWorldData().<Integer>getGameRuleValue(GameRule.RANDOM_TICK_SPEED)), layer);
}

@Override
public boolean hasScheduledBlockUpdate(Vector3ic pos, int layer) {
var chunk = dimension.getChunkService().getChunkByDimensionPos(pos.x(), pos.z());
Expand Down

0 comments on commit 8ed3d6f

Please sign in to comment.