Hex Casting

Hex Casting

6M Downloads

[Bug?] Break Block does not call onBreak of broken blocks

walksanatora opened this issue ยท 8 comments

commented

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

commented

can you please provide the minimal steps/code necessary to reproduce the issue?

commented

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)

commented

Please post all of the relevant versions (game, modloader, hex, etc) and the modlist.

commented

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

commented

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).

commented

then perhaps some sort of interface for HexcastingBreakAware so you can make a block aware of onBreak manually

commented

idea for HexcastingBreakAware intereface would be:

interface HexcastingBreakAwareBlock {
     void onHexcastingBreak(CastingEnvironment env, BlockPos pos, BlockState state)
}
commented

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;
                }
            }
        }
    }