From 2cee3301ab978a2aa93d78598c42577be9ea169c Mon Sep 17 00:00:00 2001 From: VoidEx_ <64963148+Vo1dExr@users.noreply.github.com> Date: Tue, 14 Apr 2026 01:06:03 +0800 Subject: [PATCH 1/4] Fix #3375 and #2811 --- .../block/heatable/HeatableBlock.java | 16 ++++- .../anvilcraft/init/block/ModBlocks.java | 58 ++++++++++--------- .../anvilcraft/item/AnvilHammerItem.java | 8 +-- 3 files changed, 48 insertions(+), 34 deletions(-) diff --git a/src/main/java/dev/dubhe/anvilcraft/block/heatable/HeatableBlock.java b/src/main/java/dev/dubhe/anvilcraft/block/heatable/HeatableBlock.java index 8a69f62a76..b908e10182 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/heatable/HeatableBlock.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/heatable/HeatableBlock.java @@ -1,10 +1,12 @@ package dev.dubhe.anvilcraft.block.heatable; import dev.dubhe.anvilcraft.api.heat.HeatRecorder; +import dev.dubhe.anvilcraft.api.heat.HeatTier; import dev.dubhe.anvilcraft.api.heat.HeaterManager; import dev.dubhe.anvilcraft.block.entity.heatable.HeatableBlockEntity; import dev.dubhe.anvilcraft.util.Util; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; @@ -26,8 +28,18 @@ protected HeatableBlock(Properties properties) { } @Override + @SuppressWarnings("deprecation") protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) { super.onPlace(state, level, pos, oldState, movedByPiston); + Direction[] directions = Direction.values(); + for (Direction direction : directions) { + if (level.getBlockState(pos.relative(direction)).is(Blocks.TNT) + && HeatRecorder.getTier(level, pos, state).orElse(HeatTier.NORMAL) != HeatTier.NORMAL + ) { + TntBlock.explode(level, pos.relative(direction)); + level.removeBlock(pos.relative(direction), false); + } + } HeaterManager.addHeatableBlock(pos, level); } @@ -85,7 +97,9 @@ protected void neighborChanged( BlockPos neighborPos, boolean movedByPiston ) { - if (level.getBlockState(neighborPos).is(Blocks.TNT)) { + if (level.getBlockState(neighborPos).is(Blocks.TNT) + && HeatRecorder.getTier(level, pos, state).orElse(HeatTier.NORMAL) != HeatTier.NORMAL + ) { TntBlock.explode(level, neighborPos); level.removeBlock(neighborPos, false); } diff --git a/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlocks.java b/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlocks.java index 67c71727ca..ba448cb2a5 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlocks.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlocks.java @@ -446,12 +446,18 @@ public class ModBlocks { .define('B', ModItems.EMBER_METAL_INGOT) .define('C', ModBlocks.NEGATIVE_MATTER_BLOCK) .unlockedBy(AnvilCraftDatagen.hasItem(ModItems.NEUTRONIUM_INGOT), AnvilCraftDatagen.has(ModItems.NEUTRONIUM_INGOT)) - .unlockedBy(AnvilCraftDatagen.hasItem(ModItems.CHARGED_NEUTRONIUM_INGOT), - AnvilCraftDatagen.has(ModItems.CHARGED_NEUTRONIUM_INGOT)) - .unlockedBy(AnvilCraftDatagen.hasItem(ModItems.STABLE_NEUTRONIUM_INGOT), - AnvilCraftDatagen.has(ModItems.STABLE_NEUTRONIUM_INGOT)) - .unlockedBy(AnvilCraftDatagen.hasItem(ModBlocks.NEGATIVE_MATTER_BLOCK), - AnvilCraftDatagen.has(ModBlocks.NEGATIVE_MATTER_BLOCK)) + .unlockedBy( + AnvilCraftDatagen.hasItem(ModItems.CHARGED_NEUTRONIUM_INGOT), + AnvilCraftDatagen.has(ModItems.CHARGED_NEUTRONIUM_INGOT) + ) + .unlockedBy( + AnvilCraftDatagen.hasItem(ModItems.STABLE_NEUTRONIUM_INGOT), + AnvilCraftDatagen.has(ModItems.STABLE_NEUTRONIUM_INGOT) + ) + .unlockedBy( + AnvilCraftDatagen.hasItem(ModBlocks.NEGATIVE_MATTER_BLOCK), + AnvilCraftDatagen.has(ModBlocks.NEGATIVE_MATTER_BLOCK) + ) .unlockedBy(AnvilCraftDatagen.hasItem(ModItems.EMBER_METAL_INGOT), AnvilCraftDatagen.has(ModItems.EMBER_METAL_INGOT)) .save(provider); }) @@ -513,8 +519,10 @@ public class ModBlocks { .define('A', ModBlocks.CAKE_BLOCK) .define('B', ModFoodItems.CREAMY_BREAD_ROLL) .unlockedBy(AnvilCraftDatagen.hasItem(ModBlocks.CAKE_BLOCK), AnvilCraftDatagen.has(ModBlocks.CAKE_BLOCK)) - .unlockedBy(AnvilCraftDatagen.hasItem(ModFoodItems.CREAMY_BREAD_ROLL), - AnvilCraftDatagen.has(ModFoodItems.CREAMY_BREAD_ROLL)) + .unlockedBy( + AnvilCraftDatagen.hasItem(ModFoodItems.CREAMY_BREAD_ROLL), + AnvilCraftDatagen.has(ModFoodItems.CREAMY_BREAD_ROLL) + ) .save(provider); }) .register(); @@ -575,8 +583,6 @@ public class ModBlocks { }) .initialProperties(() -> Blocks.ANVIL) .tag( - BlockTags.WITHER_IMMUNE, - BlockTags.DRAGON_IMMUNE, BlockTags.ANVIL, ModBlockTags.CANT_BROKEN_ANVIL, BlockTags.MINEABLE_WITH_PICKAXE, @@ -608,7 +614,10 @@ public class ModBlocks { .unlocks("hasitem", AnvilCraftDatagen.has(ModBlocks.FROST_METAL_BLOCK)) .save(provider, AnvilCraft.of("smithing/frost_grindstone")); }) - .tag(BlockTags.WITHER_IMMUNE, BlockTags.DRAGON_IMMUNE, BlockTags.MINEABLE_WITH_PICKAXE, BlockTags.NEEDS_DIAMOND_TOOL) + .tag( + BlockTags.MINEABLE_WITH_PICKAXE, + BlockTags.NEEDS_DIAMOND_TOOL + ) .initialProperties(() -> Blocks.NETHERITE_BLOCK) .properties(properties -> properties.lightLevel(state -> 9).noOcclusion().emissiveRendering(ModBlocks::always)) .blockstate(DataGenUtil::noExtraModelOrState) @@ -628,7 +637,10 @@ public class ModBlocks { .unlocks("hasitem", AnvilCraftDatagen.has(ModBlocks.FROST_METAL_BLOCK)) .save(provider, AnvilCraft.of("smithing/frost_smithing_table")); }) - .tag(BlockTags.WITHER_IMMUNE, BlockTags.DRAGON_IMMUNE, BlockTags.MINEABLE_WITH_PICKAXE, BlockTags.NEEDS_DIAMOND_TOOL) + .tag( + BlockTags.MINEABLE_WITH_PICKAXE, + BlockTags.NEEDS_DIAMOND_TOOL + ) .initialProperties(() -> Blocks.NETHERITE_BLOCK) .properties(properties -> properties.lightLevel(state -> 9).noOcclusion().emissiveRendering(ModBlocks::always)) .blockstate(DataGenUtil::noExtraModelOrState) @@ -2221,9 +2233,7 @@ public class ModBlocks { BlockTags.NEEDS_IRON_TOOL, ModBlockTags.OVERSEER_BASE, Tags.Blocks.STORAGE_BLOCKS, - ModBlockTags.STORAGE_BLOCKS_FROST_METAL, - BlockTags.WITHER_IMMUNE, - BlockTags.DRAGON_IMMUNE + ModBlockTags.STORAGE_BLOCKS_FROST_METAL ) .blockstate((context, provider) -> provider.simpleBlock( context.get(), @@ -2251,9 +2261,7 @@ public class ModBlocks { .tag( BlockTags.MINEABLE_WITH_PICKAXE, BlockTags.NEEDS_IRON_TOOL, - ModBlockTags.OVERSEER_BASE, - BlockTags.WITHER_IMMUNE, - BlockTags.DRAGON_IMMUNE + ModBlockTags.OVERSEER_BASE ) .initialProperties(() -> Blocks.IRON_BLOCK) .properties( @@ -2285,9 +2293,7 @@ public class ModBlocks { .tag( BlockTags.MINEABLE_WITH_PICKAXE, BlockTags.NEEDS_IRON_TOOL, - ModBlockTags.OVERSEER_BASE, - BlockTags.WITHER_IMMUNE, - BlockTags.DRAGON_IMMUNE + ModBlockTags.OVERSEER_BASE ) .initialProperties(() -> Blocks.IRON_BLOCK) .properties( @@ -2320,9 +2326,7 @@ public class ModBlocks { BlockTags.MINEABLE_WITH_PICKAXE, BlockTags.NEEDS_IRON_TOOL, BlockTags.SLABS, - ModBlockTags.OVERSEER_BASE, - BlockTags.WITHER_IMMUNE, - BlockTags.DRAGON_IMMUNE + ModBlockTags.OVERSEER_BASE ) .initialProperties(() -> Blocks.IRON_BLOCK) .properties( @@ -2360,9 +2364,7 @@ public class ModBlocks { BlockTags.MINEABLE_WITH_PICKAXE, BlockTags.NEEDS_IRON_TOOL, BlockTags.STAIRS, - ModBlockTags.OVERSEER_BASE, - BlockTags.WITHER_IMMUNE, - BlockTags.DRAGON_IMMUNE + ModBlockTags.OVERSEER_BASE ) .initialProperties(() -> Blocks.IRON_BLOCK) .properties( @@ -4664,7 +4666,7 @@ private static BlockEntry registerPressu .register(); public static final BlockEntry OIL = REGISTRUM.block( - "oil", p -> new LiquidBlock(ModFluids.OIL.get(), p)) + "oil", p -> new LiquidBlock(ModFluids.OIL.get(), p)) .properties(it -> it.mapColor(MapColor.TERRACOTTA_BLACK) .replaceable() .noCollission() diff --git a/src/main/java/dev/dubhe/anvilcraft/item/AnvilHammerItem.java b/src/main/java/dev/dubhe/anvilcraft/item/AnvilHammerItem.java index 9c1f387270..339b933a2d 100644 --- a/src/main/java/dev/dubhe/anvilcraft/item/AnvilHammerItem.java +++ b/src/main/java/dev/dubhe/anvilcraft/item/AnvilHammerItem.java @@ -144,19 +144,17 @@ public static Property findModifyableProperty(BlockState state) { public static boolean dropAnvil(@Nullable Player player, Level level, BlockPos blockPos) { if (player == null || level.isClientSide) return false; - ItemStack itemStack = player.getItemInHand(player.getUsedItemHand()); + ItemStack itemStack = player.getMainHandItem(); Item item = itemStack.getItem(); if (!(item instanceof AnvilHammerItem anvilHammerItem)) return false; - if (player.getCooldowns().isOnCooldown(anvilHammerItem)) { - return false; - } + if (player.getCooldowns().isOnCooldown(anvilHammerItem)) return false; player.getCooldowns().addCooldown(itemStack.getItem(), 5); FallingBlockEntity dummyAnvilEntity = new FallingBlockEntity(EntityType.FALLING_BLOCK, level); dummyAnvilEntity.blockState = anvilHammerItem.getAnvil().defaultBlockState(); AnvilEvent.OnLand event = new AnvilEvent.OnLand(level, blockPos.above(), dummyAnvilEntity, player.fallDistance); NeoForge.EVENT_BUS.post(event); level.playSound(null, blockPos, SoundEvents.ANVIL_LAND, SoundSource.BLOCKS, 1f, 1f); - itemStack.hurtAndBreak(1, player, LivingEntity.getSlotForHand(player.getUsedItemHand())); + itemStack.hurtAndBreak(1, player, LivingEntity.getSlotForHand(InteractionHand.MAIN_HAND)); TriggerUtil.anvilHammerClickBlock(level, blockPos, "left_click"); return true; } From 1cc5505fcf8fc413337fa37016f5644697b17933 Mon Sep 17 00:00:00 2001 From: VoidEx_ <64963148+Vo1dExr@users.noreply.github.com> Date: Wed, 15 Apr 2026 19:15:23 +0800 Subject: [PATCH 2/4] Fix PulseGenerator --- .../anvilcraft/block/PulseGeneratorBlock.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/dev/dubhe/anvilcraft/block/PulseGeneratorBlock.java b/src/main/java/dev/dubhe/anvilcraft/block/PulseGeneratorBlock.java index d4e0dac439..eded6526bc 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/PulseGeneratorBlock.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/PulseGeneratorBlock.java @@ -94,6 +94,7 @@ protected int getSignal(BlockState state, BlockGetter level, BlockPos pos, Direc @Override protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block block, BlockPos fromPos, boolean isMoving) { + this.update(level, pos, () -> state); } @@ -137,18 +138,17 @@ public void update(Level level, BlockPos pos, Supplier stateGetter) boolean lastInputting = generator.isInputtingSignal(); boolean nowInputting = PulseGeneratorBlock.getInputSignal(level, pos, stateGetter.get()) > 0; generator.setInputtingSignal(nowInputting); - boolean canStart = switch (generator.getStartMode()) { case RISING_EDGE -> !lastInputting && nowInputting; case FALLING_EDGE -> lastInputting && !nowInputting; case LOOP -> !generator.isDeadlock() && generator.getState() == PulseGeneratorBlockEntity.State.DEFAULT; } && !generator.isProcessing(); + if (canStart) { this.startWaiting(level, pos, stateGetter, generator); + this.updateBlockAndNeighbours(level, pos, stateGetter, generator); } - this.checkIsDeadlock(level, pos, stateGetter, generator); - this.updateBlockAndNeighbours(level, pos, stateGetter, generator); } @Override @@ -274,10 +274,12 @@ protected InteractionResult useWithoutItem( BlockEntity be = level.getBlockEntity(pos); if (be instanceof PulseGeneratorBlockEntity blockEntity && player instanceof ServerPlayer sp) { if (sp.gameMode.getGameModeForPlayer() == GameType.SPECTATOR) return InteractionResult.PASS; - sp.openMenu(blockEntity, buf -> { - buf.writeBlockPos(pos); - buf.writeNbt(blockEntity.constructDataNbt()); - }); + sp.openMenu( + blockEntity, buf -> { + buf.writeBlockPos(pos); + buf.writeNbt(blockEntity.constructDataNbt()); + } + ); return InteractionResult.SUCCESS; } return InteractionResult.FAIL; From 1ea96bdf8aac76fb2db926c129a278b4696f2c3d Mon Sep 17 00:00:00 2001 From: VoidEx_ <64963148+Vo1dExr@users.noreply.github.com> Date: Fri, 17 Apr 2026 04:21:23 +0800 Subject: [PATCH 3/4] Fix PulseGenerator 0t bug --- .../anvilcraft/block/PulseGeneratorBlock.java | 45 ++++++++++--------- .../entity/PulseGeneratorBlockEntity.java | 8 ++-- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/main/java/dev/dubhe/anvilcraft/block/PulseGeneratorBlock.java b/src/main/java/dev/dubhe/anvilcraft/block/PulseGeneratorBlock.java index eded6526bc..8ce2474942 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/PulseGeneratorBlock.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/PulseGeneratorBlock.java @@ -94,7 +94,6 @@ protected int getSignal(BlockState state, BlockGetter level, BlockPos pos, Direc @Override protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block block, BlockPos fromPos, boolean isMoving) { - this.update(level, pos, () -> state); } @@ -141,14 +140,26 @@ public void update(Level level, BlockPos pos, Supplier stateGetter) boolean canStart = switch (generator.getStartMode()) { case RISING_EDGE -> !lastInputting && nowInputting; case FALLING_EDGE -> lastInputting && !nowInputting; - case LOOP -> !generator.isDeadlock() && generator.getState() == PulseGeneratorBlockEntity.State.DEFAULT; + case LOOP -> !generator.isLocked(); } && !generator.isProcessing(); if (canStart) { this.startWaiting(level, pos, stateGetter, generator); this.updateBlockAndNeighbours(level, pos, stateGetter, generator); } - this.checkIsDeadlock(level, pos, stateGetter, generator); + + if (generator.getStartMode() == PulseGeneratorBlockEntity.Mode.LOOP) { + if (generator.isLocked() && !generator.isInputtingSignal()) { + this.startWaiting(level, pos, stateGetter, generator); + generator.setLocked(false); + } else { + generator.setLocked(generator.isInputtingSignal()); + } + } + if (generator.isLocked()) { + generator.setState(PulseGeneratorBlockEntity.State.DEFAULT); + this.updateBlockAndNeighbours(level, pos, stateGetter, generator); + } } @Override @@ -156,7 +167,7 @@ protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSou Optional generatorOp = level.getBlockEntity(pos, ModBlockEntities.PULSE_GENERATOR.get()); if (generatorOp.isEmpty()) return; PulseGeneratorBlockEntity generator = generatorOp.get(); - if (!generator.isDeadlock()) { + if (!generator.isLocked()) { switch (generator.getState()) { case WAITING -> this.startOutputting(level, pos, () -> state, generator); case OUTPUTTING -> this.checkOnSignalEnd(level, pos, () -> state, generator); @@ -167,23 +178,15 @@ protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSou } } - protected void checkIsDeadlock(Level level, BlockPos pos, Supplier stateGetter, PulseGeneratorBlockEntity generator) { - if (generator.getStartMode() == PulseGeneratorBlockEntity.Mode.LOOP) { - if (generator.isDeadlock() && !generator.isInputtingSignal()) { - this.startWaiting(level, pos, stateGetter, generator); - generator.setDeadlock(false); - } else { - generator.setDeadlock(generator.isInputtingSignal()); - } - } - if (generator.isDeadlock()) { - generator.setState(PulseGeneratorBlockEntity.State.DEFAULT); - this.updateBlockAndNeighbours(level, pos, stateGetter, generator); - } - } - public void startWaiting(Level level, BlockPos pos, Supplier stateGetter, PulseGeneratorBlockEntity generator) { generator.setState(PulseGeneratorBlockEntity.State.WAITING); + if (generator.getWaitingTime() == 1 + && generator.getSignalDuration() == 0) { + generator.setState(PulseGeneratorBlockEntity.State.OUTPUTTING); + level.scheduleTick(pos, this, 1, TickPriority.LOW); + this.updateBlockAndNeighbours(level, pos, stateGetter, generator); + return; + } if (generator.getWaitingTime() != 0) { level.scheduleTick(pos, this, generator.getWaitingTime(), TickPriority.LOW); } else { @@ -194,10 +197,10 @@ public void startWaiting(Level level, BlockPos pos, Supplier stateGe protected void startOutputting(Level level, BlockPos pos, Supplier stateGetter, PulseGeneratorBlockEntity generator) { generator.setState(PulseGeneratorBlockEntity.State.OUTPUTTING); if (generator.getSignalDuration() != 0) { - level.scheduleTick(pos, this, generator.getSignalDuration(), TickPriority.VERY_LOW); + level.scheduleTick(pos, this, generator.getSignalDuration(), TickPriority.LOW); this.updateBlockAndNeighbours(level, pos, stateGetter, generator); } else { - this.updateBlockAndNeighbours(level, pos, generator::getBlockState, generator); + this.updateBlockAndNeighbours(level, pos, stateGetter, generator); this.checkOnSignalEnd(level, pos, stateGetter, generator); } } diff --git a/src/main/java/dev/dubhe/anvilcraft/block/entity/PulseGeneratorBlockEntity.java b/src/main/java/dev/dubhe/anvilcraft/block/entity/PulseGeneratorBlockEntity.java index fd9feab47c..0dd364ef11 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/entity/PulseGeneratorBlockEntity.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/entity/PulseGeneratorBlockEntity.java @@ -38,7 +38,7 @@ public class PulseGeneratorBlockEntity extends BlockEntity implements MenuProvid protected State state = State.DEFAULT; protected boolean isInputtingSignal = false; - protected boolean isDeadlock = false; + protected boolean isLocked = false; public PulseGeneratorBlockEntity(BlockPos pos, BlockState blockState) { super(ModBlockEntities.PULSE_GENERATOR.get(), pos, blockState); @@ -134,7 +134,7 @@ public void setState(State state) { public void setStartMode(int mode) { this.startMode = Mode.fromIndex(mode % 3); if (this.startMode != Mode.LOOP) { - this.isDeadlock = false; + this.isLocked = false; } else if (!this.isInputtingSignal && this.level != null) { Util.castSafely(this.getBlockState().getBlock(), PulseGeneratorBlock.class) .ifPresent(block -> block.update(this.level, this.getBlockPos(), this::getBlockState)); @@ -172,7 +172,7 @@ public boolean isProcessing() { } public boolean isOutputting() { - if (this.isDeadlock) return this.outputInvert; + if (this.isLocked) return this.outputInvert; return (this.state == State.OUTPUTTING) != this.outputInvert; } @@ -209,7 +209,7 @@ public void applyMoveData(Level level, BlockPos pos, BlockState state, CompoundT } } level.setBlock(pos, state.setValue(PulseGeneratorBlock.POWERED, this.isOutputting()), 3); - this.isDeadlock = false; + this.isLocked = false; Util.cast(this.getBlockState().getBlock()).update(level, pos, () -> state); From 1561ce871a62e56ad9afb17fa8dc460d90e47e48 Mon Sep 17 00:00:00 2001 From: VoidEx_ <64963148+Vo1dExr@users.noreply.github.com> Date: Mon, 20 Apr 2026 18:36:46 +0800 Subject: [PATCH 4/4] Fix --- .../dev/dubhe/anvilcraft/block/heatable/HeatableBlock.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/dev/dubhe/anvilcraft/block/heatable/HeatableBlock.java b/src/main/java/dev/dubhe/anvilcraft/block/heatable/HeatableBlock.java index b908e10182..d211441960 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/heatable/HeatableBlock.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/heatable/HeatableBlock.java @@ -32,10 +32,9 @@ protected HeatableBlock(Properties properties) { protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) { super.onPlace(state, level, pos, oldState, movedByPiston); Direction[] directions = Direction.values(); + if (HeatRecorder.getTier(level, pos, state).orElse(HeatTier.NORMAL) == HeatTier.NORMAL) return; for (Direction direction : directions) { - if (level.getBlockState(pos.relative(direction)).is(Blocks.TNT) - && HeatRecorder.getTier(level, pos, state).orElse(HeatTier.NORMAL) != HeatTier.NORMAL - ) { + if (level.getBlockState(pos.relative(direction)).is(Blocks.TNT)) { TntBlock.explode(level, pos.relative(direction)); level.removeBlock(pos.relative(direction), false); }