-
Notifications
You must be signed in to change notification settings - Fork 0
World and Blocks
Package: dev.goshi.omnimixin.api.event.world
Block interaction, placement, breaking, mining speed, and redstone power calculation.
Three independent events, not phases of one action.
Fires when a player right-clicks a block (the "use" interaction — opening a chest, pressing a button, etc.). Cancellable.
// Lock a specific chest behind a key item.
PlayBlock.INTERACT.register(ctx -> {
if (ctx.state().isOf(MyBlocks.VAULT_CHEST) && !hasKey(ctx.player())) {
ctx.cancel().cancel();
}
});
BlockInteractContext(World world, BlockPos pos, BlockState state, PlayerEntity player, BlockHitResult hit, Cancellable cancel)
Note: this covers the "use" interaction only, not item-based interactions like using bonemeal or flint-and-steel on a block — see [[Known Limitations]].
Fires when a block is about to be placed.
// Prevent placing blocks within a protected radius of spawn.
PlayBlock.PLACE.register(ctx -> {
if (isWithinSpawnProtection(ctx.pos())) {
ctx.cancel().cancel();
}
});
PlaceContext(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack, Cancellable cancel)
Fires when a block is notified that a neighboring block changed (the same signal that drives redstone updates, water flow triggers, etc.).
PlayBlock.NEIGHBOR_UPDATE.register(ctx -> {
if (ctx.state().isOf(MyBlocks.UNSTABLE_CRYSTAL) && ctx.sourceBlock() == Blocks.TNT) {
triggerCollapse(ctx.world(), ctx.pos());
}
});
NeighborUpdateContext(World world, BlockPos pos, BlockState state, Block sourceBlock, BlockPos sourcePos, Cancellable cancel)
Three phases across the lifetime of breaking a single block.
// Mining fatigue near a specific boss arena.
PlayBreak.CALCULATE_SPEED.register(ctx -> {
if (isInBossArena(ctx.player())) {
ctx.speed().multiply(0.25f);
}
});
// Unbreakable "core" blocks.
PlayBreak.PRE_BREAK.register(ctx -> {
if (ctx.state().isOf(MyBlocks.DUNGEON_CORE)) {
ctx.cancel().cancel();
}
});
// Custom particle burst on successfully breaking a block.
PlayBreak.POST_BREAK.register(ctx -> {
spawnBreakParticles(ctx.world(), ctx.pos(), ctx.state());
});
MiningSpeedContext(PlayerEntity player, BlockState state, MutableFloat speed) — CALCULATE_SPEED
BreakContext(World world, BlockPos pos, BlockState state, PlayerEntity player, Cancellable cancel) — PRE_BREAK
AfterBreakContext(World world, PlayerEntity player, BlockPos pos, BlockState state, BlockEntity blockEntity, ItemStack tool, Cancellable cancel) — POST_BREAK
PRE_BREAK's Cancellable stops the block from breaking at all.
POST_BREAK fires after the block is already gone — its Cancellable has
no effect on the break itself, but is still passed for consistency and in
case a future version needs to veto a specific side effect of breaking
(drops, XP) without touching the break itself.
Fires whenever a block's redstone power output (weak or strong) is being calculated.
// A custom lever variant that outputs full power in both directions.
PlayRedstone.MODIFY_POWER.register(ctx -> {
if (ctx.state().isOf(MyBlocks.OMNI_LEVER)) {
ctx.power().set(15);
}
});
RedstonePowerContext(BlockState state, BlockView world, BlockPos pos, Direction direction, boolean strong, MutableInt power)
strong tells you whether this is a strong-power query (the kind that can
power a block two steps away) or a weak-power query — check it if your
logic needs to differ between the two.
Note: there's no separate "signal changed" event — the closest verified
vanilla call site for that would just duplicate PlayBlock.NEIGHBOR_UPDATE
above, so it isn't exposed twice. See Known Limitations.