Add Batch Cutter 添加批量切割机#3393
Conversation
QiuShui1012
commented
Apr 7, 2026
- resolved [TODO] 批量切割机 #3243
- 添加了批量切割机
There was a problem hiding this comment.
Pull request overview
This PR adds a new Batch Cutter machine (stonecutting-equivalent of the Batch Crafter) and refactors batch-crafting logic into shared base block/block-entity classes to support multiple batch machines.
Changes:
- Added Batch Cutter block/entity/menu/screen + recipe/loot/advancement + client syncing packet.
- Refactored Batch Crafter into
block.batch/block.entity.batchwith a sharedBaseBatchCrafting*base and shared BE renderer. - Updated scrolling utility API (
Scrollable) and adjusted affected screens accordingly.
Reviewed changes
Copilot reviewed 35 out of 42 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/main/resources/assets/anvilcraft/models/block/auto_crafter.json | Removed unused model asset. |
| src/main/resources/assets/anvilcraft/models/block/auto_crafter_vertical.json | Removed unused model asset. |
| src/main/resources/assets/anvilcraft/models/block/auto_crafter_vertical_overload.json | Removed unused model asset. |
| src/main/resources/assets/anvilcraft/models/block/auto_crafter_overload.json | Removed unused model asset. |
| src/main/resources/assets/anvilcraft/blockstates/batch_cutter.json | Added Batch Cutter blockstate variants for facing/overload. |
| src/main/resources/assets/anvilcraft/blockstates/auto_crafter.json | Removed unused blockstate asset. |
| src/main/java/dev/dubhe/anvilcraft/util/Scrollable.java | Simplified scroll behavior to drive a “head” index. |
| src/main/java/dev/dubhe/anvilcraft/network/BatchCutterSelectPacket.java | Added network sync for recipe selection index. |
| src/main/java/dev/dubhe/anvilcraft/inventory/BatchCutterMenu.java | Added server/client menu container for Batch Cutter. |
| src/main/java/dev/dubhe/anvilcraft/inventory/BatchCrafterMenu.java | Updated import to new batch package. |
| src/main/java/dev/dubhe/anvilcraft/init/ModMenuTypes.java | Registered Batch Cutter menu/screen. |
| src/main/java/dev/dubhe/anvilcraft/init/block/ModBlocks.java | Registered Batch Cutter block + recipe; refactored batch block imports/registration. |
| src/main/java/dev/dubhe/anvilcraft/init/block/ModBlockEntities.java | Registered Batch Cutter BE; switched batch renderer to shared renderer. |
| src/main/java/dev/dubhe/anvilcraft/event/CapabilitiesEventListener.java | Added Batch Cutter to capability registration list. |
| src/main/java/dev/dubhe/anvilcraft/event/BlockEventListener.java | Added shift-right-click conversion between batch crafting blocks. |
| src/main/java/dev/dubhe/anvilcraft/data/lang/ItemTooltipLang.java | Updated tooltip map name reference. |
| src/main/java/dev/dubhe/anvilcraft/config/AnvilCraftServerConfig.java | Added batchCutterCooldown config. |
| src/main/java/dev/dubhe/anvilcraft/client/renderer/blockentity/BatchCraftingBERenderer.java | New shared BE renderer for batch machines. |
| src/main/java/dev/dubhe/anvilcraft/client/renderer/blockentity/BatchCrafterRenderer.java | Removed old Batch Crafter-specific renderer. |
| src/main/java/dev/dubhe/anvilcraft/client/gui/screen/FrostGrindstoneScreen.java | Updated Scrollable implementation to setHead. |
| src/main/java/dev/dubhe/anvilcraft/client/gui/screen/EnergyWeaponMakeScreen.java | Updated Scrollable implementation to setHead. |
| src/main/java/dev/dubhe/anvilcraft/client/gui/screen/EmberGrindstoneScreen.java | Updated Scrollable implementation to setHead. |
| src/main/java/dev/dubhe/anvilcraft/client/gui/screen/BatchCutterScreen.java | Added Batch Cutter GUI (recipe selection + scrolling + filter UI). |
| src/main/java/dev/dubhe/anvilcraft/client/gui/screen/BatchCrafterScreen.java | Minor GUI positioning adjustments. |
| src/main/java/dev/dubhe/anvilcraft/client/gui/screen/BaseMachineScreen.java | Added constructor overload + hook to render before tooltip. |
| src/main/java/dev/dubhe/anvilcraft/block/entity/BatchCrafterBlockEntity.java | Removed old (pre-refactor) Batch Crafter BE. |
| src/main/java/dev/dubhe/anvilcraft/block/entity/batch/package-info.java | Added default nullness annotations for batch BE package. |
| src/main/java/dev/dubhe/anvilcraft/block/entity/batch/BatchCutterBlockEntity.java | Added Batch Cutter BE implementation (stonecutting + selection). |
| src/main/java/dev/dubhe/anvilcraft/block/entity/batch/BatchCrafterBlockEntity.java | Added refactored Batch Crafter BE under shared base. |
| src/main/java/dev/dubhe/anvilcraft/block/entity/batch/BaseBatchCraftingBlockEntity.java | Added shared base BE logic for batch machines. |
| src/main/java/dev/dubhe/anvilcraft/block/batch/package-info.java | Added default nullness annotations for batch block package. |
| src/main/java/dev/dubhe/anvilcraft/block/batch/BatchCutterBlock.java | Added Batch Cutter block implementation. |
| src/main/java/dev/dubhe/anvilcraft/block/batch/BatchCrafterBlock.java | Added refactored Batch Crafter block implementation. |
| src/main/java/dev/dubhe/anvilcraft/block/batch/BaseBatchCraftingBlock.java | Introduced shared base block logic (use/onRemove/redstone, etc.). |
| src/main/java/dev/dubhe/anvilcraft/api/tooltip/ItemTooltipManager.java | Refactored tooltip maps; added Batch Cutter tooltip. |
| src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json | Added Batch Cutter to pickaxe-mineable tag. |
| src/generated/resources/data/anvilcraft/recipe/batch_cutter.json | Added Batch Cutter crafting recipe (generated). |
| src/generated/resources/data/anvilcraft/loot_table/blocks/batch_cutter.json | Added Batch Cutter loot table (generated). |
| src/generated/resources/data/anvilcraft/advancement/recipes/redstone/batch_cutter.json | Added recipe advancement unlock (generated). |
| src/generated/resources/assets/anvilcraft/models/item/batch_cutter.json | Added item model for Batch Cutter (generated). |
| src/generated/resources/assets/anvilcraft/lang/en_us.json | Added block/config/tooltips localization entries for Batch Cutter. |
Comments suppressed due to low confidence (1)
src/main/java/dev/dubhe/anvilcraft/block/batch/BaseBatchCraftingBlock.java:75
- getAnalogOutputSignal() only checks for BatchCrafterBlockEntity, so BatchCutterBlockEntity (and any other batch machines) will always output 0 redstone signal. This should likely accept BaseBatchCraftingBlockEntity (or an interface) so all batch crafting blocks expose their signal consistently.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/main/java/dev/dubhe/anvilcraft/block/entity/batch/BaseBatchCraftingBlockEntity.java
Show resolved
Hide resolved
src/main/java/dev/dubhe/anvilcraft/block/entity/batch/BatchCutterBlockEntity.java
Outdated
Show resolved
Hide resolved
src/main/java/dev/dubhe/anvilcraft/event/BlockEventListener.java
Outdated
Show resolved
Hide resolved
src/main/java/dev/dubhe/anvilcraft/client/gui/screen/BatchCutterScreen.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 35 out of 42 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (2)
src/main/java/dev/dubhe/anvilcraft/block/batch/BaseBatchCraftingBlock.java:75
getAnalogOutputSignalcurrently only checks forBatchCrafterBlockEntity, so otherBaseBatchCraftingBlockEntityimplementations (e.g. the new batch cutter) will always output 0 to comparators. Consider checkingBaseBatchCraftingBlockEntity(or a shared interface withgetRedstoneSignal()) instead of the concrete crafter class.
src/main/java/dev/dubhe/anvilcraft/block/batch/BaseBatchCraftingBlock.java:226getBatchCraftingBlockGetters()returns the mutable backing list while annotating it as@Unmodifiable. To prevent accidental external mutation (which could break the conversion logic), consider returningCollections.unmodifiableList(...)(or an immutable copy) instead.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| level.removeBlock(pos, false); | ||
| level.removeBlockEntity(pos); | ||
| level.setBlockAndUpdate(pos, BaseBatchCraftingBlock.copy(targetState, block.defaultBlockState())); |
There was a problem hiding this comment.
The conversion logic removes the block + block entity before placing the new state. This triggers onRemove and will drop (or lose) the machine inventory/filter data during a crafter<->cutter swap. Consider migrating the existing block entity data (NBT/filtering/contents) to the new block entity, or performing an in-place state swap when the BE type stays compatible.
| Level level = player.level(); | ||
| level.getBlockEntity(this.pos, ModBlockEntities.BATCH_CUTTER.get()) | ||
| .ifPresent(entity -> entity.setSelecting(this.selecting)); | ||
| if (player instanceof ServerPlayer) { | ||
| PacketDistributor.sendToAllPlayers(new BatchCutterSelectPacket(this.selecting, this.pos)); | ||
| } |
There was a problem hiding this comment.
handleOnBothSide calls entity.setSelecting(...), and BatchCutterBlockEntity#setSelecting already broadcasts a BatchCutterSelectPacket to all players on the server. The extra sendToAllPlayers(...) here causes duplicate broadcasts per selection change. Consider removing one of the broadcasts (typically keep it centralized in the BE setter).
| return true; | ||
| } | ||
| } | ||
| if (this.scrollable.canScroll()) this.scrollable.scrollOnScroll(scrollY / 1.2); |
There was a problem hiding this comment.
After scrolling the recipe list, this method calls super.mouseScrolled(...) and returns its result, rather than returning true when the list scroll is handled. In similar screens (e.g. Ember/Frost grindstone), mouseScrolled returns true after scrollOnScroll, otherwise scrolling may be ignored depending on the parent implementation.
| if (this.scrollable.canScroll()) this.scrollable.scrollOnScroll(scrollY / 1.2); | |
| if (this.scrollable.canScroll()) { | |
| this.scrollable.scrollOnScroll(scrollY / 1.2); | |
| return true; | |
| } |
| result.setCount(result.getCount() * times); | ||
| List<ItemStack> craftRemaining = cache.getRemaining(); | ||
| if (!craftRemaining.isEmpty()) { | ||
| craftRemaining = Lists.transform(craftRemaining, stack -> stack.copyWithCount(stack.getCount() * times)); |
There was a problem hiding this comment.
Lists.transform(...) returns a lazy view backed by the original craftRemaining list. Since this list comes from a cached NonNullList, using a view here can be surprising if the cached list is later reused/mutated. Consider eagerly copying/mapping into a new list (as done in BatchCrafterBlockEntity) to avoid aliasing the cached data.
| craftRemaining = Lists.transform(craftRemaining, stack -> stack.copyWithCount(stack.getCount() * times)); | |
| List<ItemStack> scaledCraftRemaining = Lists.newArrayListWithCapacity(craftRemaining.size()); | |
| for (ItemStack stack : craftRemaining) { | |
| scaledCraftRemaining.add(stack.copyWithCount(stack.getCount() * times)); | |
| } | |
| craftRemaining = scaledCraftRemaining; |