[Bug?] Break Block does not call onBreak of broken blocks
walksanatora opened this issue ยท 8 comments
so in Hexxy Dimensions I have a block that when broken checks the player and sends them back to the overworld
but break block does not pass that (or some other way my blocks onBreakBlock
method is not being called
can you please provide the minimal steps/code necessary to reproduce the issue?
made a block with
class TestBlock(set: Settings) : Block(set) {
override fun onBreak(world: World, pos: BlockPos?, state: BlockState?, player: PlayerEntity) {
super.onBreak(world, pos, state, player)
println("world: %s\npos: %s\nstate: %s\nplayer: %s".format(
world,pos,state,player
))
}
}
when I break with my fist the world,pos,state,player are printed to console
when I break with BreakBlock it fails
also also checked with /setblock and /fill and same effect occurs (no output)
Please post all of the relevant versions (game, modloader, hex, etc) and the modlist.
1.20.1, fabric, hexcasting 0.11.1-7-pre-609,
patchouli 1.20.1-84
paucal 0.6.0-pre-118
cloth config 11.1.118
cardinal componenets api 5.2.1
hexxy-dimensions 1.2.1
this could probally be fixed with a
if (env.caster is ServerPlayer) {
blockstate.block.onBreak(env.world,pos,blockstate,env.caster
}
after the call to env.world.destroyBlock
onBreak
(named playerWillDestroy
in the mojMap) seems to be specifically for when players break blocks, triggering things like piglin getting angry, ensuring shulker boxes are still dropped if the player is in creative, etc. I think it would break things elsewhere to add this call (example: if the player casts break block in creative shulker boxes will drop twice, once from the playerWillDestroy
call and once from the normal loot drop method).
then perhaps some sort of interface for HexcastingBreakAware
so you can make a block aware of onBreak manually
idea for HexcastingBreakAware intereface would be:
interface HexcastingBreakAwareBlock {
void onHexcastingBreak(CastingEnvironment env, BlockPos pos, BlockState state)
}
For comparison, this is how Psi does it: https://github.com/VazkiiMods/Psi/blob/3f9806bcb00caf1a17a24f2052161649d4d4a33c/src/main/java/vazkii/psi/common/spell/trick/block/PieceTrickBreakBlock.java#L106-L111
Alternatively, here's how net.minecraft.server.level.ServerPlayerGameMode#destroyBlock
works - maybe we could do something similar?
public boolean destroyBlock(BlockPos pos) {
BlockState blockState = this.level.getBlockState(pos);
if (!this.player.getMainHandItem().getItem().canAttackBlock(blockState, this.level, pos, this.player)) {
return false;
} else {
BlockEntity blockEntity = this.level.getBlockEntity(pos);
Block block = blockState.getBlock();
if (block instanceof GameMasterBlock && !this.player.canUseGameMasterBlocks()) {
this.level.sendBlockUpdated(pos, blockState, blockState, 3);
return false;
} else if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) {
return false;
} else {
block.playerWillDestroy(this.level, pos, blockState, this.player);
boolean bl = this.level.removeBlock(pos, false);
if (bl) {
block.destroy(this.level, pos, blockState);
}
if (this.isCreative()) {
return true;
} else {
ItemStack itemStack = this.player.getMainHandItem();
ItemStack itemStack2 = itemStack.copy();
boolean bl2 = this.player.hasCorrectToolForDrops(blockState);
itemStack.mineBlock(this.level, blockState, pos, this.player);
if (bl && bl2) {
block.playerDestroy(this.level, this.player, pos, blockState, blockEntity, itemStack2);
}
return true;
}
}
}
}