diff --git a/endercore/src/main/java/com/enderio/core/common/blockentity/EnderBlockEntity.java b/endercore/src/main/java/com/enderio/core/common/blockentity/EnderBlockEntity.java index 2bf0eed441..c55107dcd7 100644 --- a/endercore/src/main/java/com/enderio/core/common/blockentity/EnderBlockEntity.java +++ b/endercore/src/main/java/com/enderio/core/common/blockentity/EnderBlockEntity.java @@ -11,7 +11,6 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; -import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.ChunkPos; @@ -42,6 +41,7 @@ public class EnderBlockEntity extends BlockEntity { public static final String INDEX = "Index"; private final List> dataSlots = new ArrayList<>(); private final List afterDataSync = new ArrayList<>(); + private boolean isChangedDeferred = true; private final Map, EnumMap>> selfCapabilities = new HashMap<>(); private final Map, EnumMap>> neighbourCapabilities = new HashMap<>(); @@ -59,26 +59,46 @@ public static void tick(Level level, BlockPos pos, BlockState state, EnderBlockE } else { blockEntity.serverTick(); } + blockEntity.endTick(); } /** * Perform server-side ticking */ + @EnsureSide(EnsureSide.Side.SERVER) public void serverTick() { // Perform syncing. - if (level != null && !level.isClientSide) { + if (level != null) { sync(); - level.blockEntityChanged(worldPosition); } } /** * Perform client side ticking. */ + @EnsureSide(EnsureSide.Side.CLIENT) public void clientTick() { } + /** + * Perform client and server side ticking. + */ + public void endTick() { + if (this.level == null) { + return; + } + if (isChangedDeferred) { + isChangedDeferred = false; + setChanged(level, getBlockPos(), getBlockState()); + } + } + + @Override + public void setChanged() { + this.isChangedDeferred = true; + } + // endregion // region Sync @@ -128,26 +148,25 @@ public void handleUpdateTag(CompoundTag syncData, HolderLookup.Provider lookupPr } private byte @Nullable [] createBufferSlotUpdate() { - RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.buffer(), level.registryAccess()); - int amount = 0; + List needsUpdate = new ArrayList<>(); for (int i = 0; i < dataSlots.size(); i++) { - var networkDataSlot = dataSlots.get(i); - if (networkDataSlot.doesNeedUpdate()) { - amount ++; - buf.writeInt(i); - networkDataSlot.write(buf); + if (dataSlots.get(i).doesNeedUpdate()) { + needsUpdate.add(i); } } - if (amount == 0) { + if (needsUpdate.isEmpty()) { return null; } // Fine to use a normal byte buf here, we're not using codecs in here. - FriendlyByteBuf result = new FriendlyByteBuf(Unpooled.buffer()); //Use 2 buffers to be able to write the amount of data - result.writeInt(amount); - result.writeBytes(buf.copy()); - return result.array(); + RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.buffer(), level.registryAccess()); + buf.writeInt(needsUpdate.size()); + needsUpdate.forEach(i -> { + buf.writeInt(i); + dataSlots.get(i).write(buf); + }); + return buf.array(); } public > T addDataSlot(T slot) { @@ -184,6 +203,7 @@ public void clientUpdateSlot(@Nullable NetworkDataSlot slot, T value) { public void sync() { var syncData = createBufferSlotUpdate(); if (syncData != null && level instanceof ServerLevel serverLevel) { + setChanged(); PacketDistributor.sendToPlayersTrackingChunk(serverLevel, new ChunkPos(getBlockPos()), new ServerboundCDataSlotUpdate(getBlockPos(), syncData)); } diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/block/MachineBlock.java b/enderio-machines/src/main/java/com/enderio/machines/common/block/MachineBlock.java index ac6e2b7891..aea00cf5db 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/block/MachineBlock.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/block/MachineBlock.java @@ -20,6 +20,7 @@ import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.BaseEntityBlock; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.RenderShape; @@ -161,4 +162,20 @@ public int getLightEmission(BlockState state, BlockGetter level, BlockPos pos) { } return super.getLightEmission(state, level, pos); } + + @Override + protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, BlockPos neighborPos, boolean movedByPiston) { + super.neighborChanged(state, level, pos, neighborBlock, neighborPos, movedByPiston); + if (level.getBlockEntity(pos) instanceof MachineBlockEntity machineBlock) { + machineBlock.neighborChanged(state, level, pos, neighborPos); + } + } + + @Override + public void onNeighborChange(BlockState state, LevelReader level, BlockPos pos, BlockPos neighbor) { + super.onNeighborChange(state, level, pos, neighbor); + if (level.getBlockEntity(pos) instanceof MachineBlockEntity machineBlock) { + machineBlock.neighborChanged(state, level, pos, neighbor); + } + } } diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/AlloySmelterBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/AlloySmelterBlockEntity.java index 214e9aea01..96b3fe776d 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/AlloySmelterBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/AlloySmelterBlockEntity.java @@ -161,7 +161,7 @@ protected SingleSlotAccess getOutputSlotAccess() { // region Inventory @Override - public MachineInventoryLayout getInventoryLayout() { + public MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder() .inputSlot(3, this::acceptSlotInput) .slotAccess(INPUTS) diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/AversionObeliskBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/AversionObeliskBlockEntity.java index d392c41e66..8b8f5ba247 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/AversionObeliskBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/AversionObeliskBlockEntity.java @@ -60,7 +60,7 @@ protected void updateLocations() { } @Override - public @Nullable MachineInventoryLayout getInventoryLayout() { + public @Nullable MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder() .inputSlot((integer, itemStack) -> itemStack.getCapability(EIOCapabilities.Filter.ITEM) instanceof EntityFilter) .slotAccess(FILTER) diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/CrafterBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/CrafterBlockEntity.java index f5c95a2349..5f71828a2d 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/CrafterBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/CrafterBlockEntity.java @@ -87,7 +87,7 @@ public AbstractContainerMenu createMenu(int containerId, Inventory inventory, Pl } @Override - public MachineInventoryLayout getInventoryLayout() { + public MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout .builder() .capacitor() diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/DrainBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/DrainBlockEntity.java index 6deec33e50..50de904bd0 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/DrainBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/DrainBlockEntity.java @@ -100,7 +100,7 @@ private void internalSetActionRange(ActionRange actionRange) { } @Override - public @Nullable MachineInventoryLayout getInventoryLayout() { + public @Nullable MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder() .capacitor() .build(); diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/FluidTankBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/FluidTankBlockEntity.java index fa294aafbf..8a712a46a8 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/FluidTankBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/FluidTankBlockEntity.java @@ -165,7 +165,7 @@ public boolean acceptItemDrain(ItemStack item) { } @Override - public MachineInventoryLayout getInventoryLayout() { + public MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout .builder() .inputSlot((slot, stack) -> acceptItemFill(stack)) diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/ImpulseHopperBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/ImpulseHopperBlockEntity.java index d5944ff46e..1933ede659 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/ImpulseHopperBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/ImpulseHopperBlockEntity.java @@ -35,7 +35,7 @@ public AbstractContainerMenu createMenu(int containerId, Inventory inventory, Pl } @Override - public MachineInventoryLayout getInventoryLayout() { + public MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder() .inputSlot(6, (integer, itemStack) -> ItemStack.isSameItemSameComponents(itemStack, GHOST.get(integer).getItemStack(this))) .slotAccess(INPUT) diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/InhibitorObeliskBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/InhibitorObeliskBlockEntity.java index 909aca6e0e..cb3ea8594e 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/InhibitorObeliskBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/InhibitorObeliskBlockEntity.java @@ -57,7 +57,7 @@ protected void updateLocations() { } @Override - public @Nullable MachineInventoryLayout getInventoryLayout() { + public @Nullable MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder() .capacitor() .build(); diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/MachineState.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/MachineState.java index 3ae7a9bfb6..6e77e6edce 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/MachineState.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/MachineState.java @@ -45,4 +45,21 @@ public record MachineState(MachineStateType type, MutableComponent component) { public static final NetworkDataSlot.CodecType> DATA_SLOT_TYPE = NetworkDataSlot.CodecType.createSet(CODEC, STREAM_CODEC.cast()); + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + MachineState that = (MachineState) obj; + return type == that.type && component == that.component; //Use identity + } + + @Override + public int hashCode() { + return 31 * type.ordinal() + System.identityHashCode(component); //Only hash instance + } } diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/PaintingMachineBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/PaintingMachineBlockEntity.java index 95ceb69562..9007ecfe44 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/PaintingMachineBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/PaintingMachineBlockEntity.java @@ -84,7 +84,7 @@ public void onLoad() { // region Inventory @Override - public MachineInventoryLayout getInventoryLayout() { + public MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder() .capacitor() .inputSlot(this::isValidInput) diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/PoweredSpawnerBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/PoweredSpawnerBlockEntity.java index d332cbc78e..7cc11a0463 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/PoweredSpawnerBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/PoweredSpawnerBlockEntity.java @@ -141,7 +141,7 @@ public void onLoad() { // region Inventory @Override - public MachineInventoryLayout getInventoryLayout() { + public MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder().capacitor().build(); } diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/PrimitiveAlloySmelterBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/PrimitiveAlloySmelterBlockEntity.java index 86cca351e5..bf85165b80 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/PrimitiveAlloySmelterBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/PrimitiveAlloySmelterBlockEntity.java @@ -63,7 +63,7 @@ protected SingleSlotAccess getOutputSlotAccess() { } @Override - public MachineInventoryLayout getInventoryLayout() { + public MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder() .inputSlot((s, i) -> i.getBurnTime(RecipeType.SMELTING) > 0) .slotAccess(FUEL) diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/RelocatorObeliskBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/RelocatorObeliskBlockEntity.java index 1e5b8ed75e..e9ade4925e 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/RelocatorObeliskBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/RelocatorObeliskBlockEntity.java @@ -62,7 +62,7 @@ protected void updateLocations() { } @Override - public @Nullable MachineInventoryLayout getInventoryLayout() { + public @Nullable MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder() .inputSlot((integer, itemStack) -> itemStack.getCapability(EIOCapabilities.Filter.ITEM) instanceof EntityFilter) .slotAccess(FILTER) diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SagMillBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SagMillBlockEntity.java index efa0db9464..aabe2458ac 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SagMillBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SagMillBlockEntity.java @@ -103,7 +103,7 @@ public void onLoad() { } @Override - public MachineInventoryLayout getInventoryLayout() { + public MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder() .inputSlot(this::isValidInput) .slotAccess(INPUT) diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SlicerBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SlicerBlockEntity.java index be90a5edeb..aae3471ab6 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SlicerBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SlicerBlockEntity.java @@ -85,7 +85,7 @@ public void onLoad() { // region Inventory @Override - public MachineInventoryLayout getInventoryLayout() { + public MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder() .setStackLimit(1) // Force all input slots to have 1 output .inputSlot(6, this::isValidInput) diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SoulBinderBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SoulBinderBlockEntity.java index 99e7c099ac..f824b5566d 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SoulBinderBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SoulBinderBlockEntity.java @@ -104,7 +104,7 @@ public void onLoad() { // region Inventory @Override - public MachineInventoryLayout getInventoryLayout() { + public MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder() .setStackLimit(1) .inputSlot((slot, stack) -> stack.is(EIOItems.FILLED_SOUL_VIAL.get())) diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SoulEngineBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SoulEngineBlockEntity.java index 7aa2ccc058..d9d1989681 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SoulEngineBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/SoulEngineBlockEntity.java @@ -83,7 +83,7 @@ public SoulEngineBlockEntity(BlockPos worldPosition, BlockState blockState) { } @Override - public MachineInventoryLayout getInventoryLayout() { + public MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder() .capacitor() .build(); diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/StirlingGeneratorBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/StirlingGeneratorBlockEntity.java index 6950a9d19b..9383ba36b9 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/StirlingGeneratorBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/StirlingGeneratorBlockEntity.java @@ -62,7 +62,7 @@ public int getGenerationRate() { } @Override - public MachineInventoryLayout getInventoryLayout() { + public MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder() .inputSlot((slot, stack) -> stack.getBurnTime(RecipeType.SMELTING) > 0 && stack.getCraftingRemainingItem().isEmpty()) .slotAccess(FUEL) diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/TravelAnchorBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/TravelAnchorBlockEntity.java index 18e70005e9..9710f075ac 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/TravelAnchorBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/TravelAnchorBlockEntity.java @@ -45,7 +45,7 @@ public AbstractContainerMenu createMenu(int containerId, Inventory inventory, Pl } @Override - public @Nullable MachineInventoryLayout getInventoryLayout() { + public @Nullable MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder().setStackLimit(1).ghostSlot().slotAccess(GHOST).build(); } diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/VacuumChestBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/VacuumChestBlockEntity.java index 74df35e588..9687e176f0 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/VacuumChestBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/VacuumChestBlockEntity.java @@ -31,7 +31,7 @@ public AbstractContainerMenu createMenu(int containerId, Inventory inventory, Pl } @Override - public MachineInventoryLayout getInventoryLayout() { + public MachineInventoryLayout createInventoryLayout() { return extractableGUISlot(MachineInventoryLayout.builder(), 27) .slot(slot -> slot.guiInsert().guiExtract().filter((i, s) -> s.getCapability(EIOCapabilities.Filter.ITEM) instanceof ItemFilterCapability)) .slotAccess(FILTER) diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/VatBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/VatBlockEntity.java index ac20f5fa1f..60016d436f 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/VatBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/VatBlockEntity.java @@ -122,7 +122,7 @@ protected VatCraftingMachineTask createTask(Level level, FermentingRecipe.Input } @Override - public @Nullable MachineInventoryLayout getInventoryLayout() { + public @Nullable MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout.builder().inputSlot(2).slotAccess(REAGENTS).build(); } diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/WiredChargerBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/WiredChargerBlockEntity.java index 2126103914..2dcc9df5cd 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/WiredChargerBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/WiredChargerBlockEntity.java @@ -36,7 +36,7 @@ public WiredChargerBlockEntity(BlockPos worldPosition, BlockState blockState) { } @Override - public MachineInventoryLayout getInventoryLayout() { + public MachineInventoryLayout createInventoryLayout() { return MachineInventoryLayout .builder() .capacitor() diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/base/MachineBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/base/MachineBlockEntity.java index 8a87474b82..134e443bd8 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/base/MachineBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/base/MachineBlockEntity.java @@ -34,6 +34,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.ItemContainerContents; import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; @@ -72,9 +73,13 @@ public abstract class MachineBlockEntity extends EnderBlockEntity implements Men @Nullable private final MachineInventory inventory; + @Nullable + private final MachineInventoryLayout inventoryLayout; // endregion + private boolean isRedstoneBlocked; + // region Common Dataslots public static final NetworkDataSlot.CodecType REDSTONE_CONTROL_DATA_SLOT_TYPE @@ -98,9 +103,9 @@ public MachineBlockEntity(BlockEntityType type, BlockPos worldPosition, Block } // If the machine declares an inventory layout, use it to create a handler - MachineInventoryLayout slotLayout = getInventoryLayout(); - if (slotLayout != null) { - inventory = createMachineInventory(slotLayout); + inventoryLayout = createInventoryLayout(); + if (inventoryLayout != null) { + inventory = createMachineInventory(inventoryLayout); } else { inventory = null; } @@ -269,6 +274,10 @@ public boolean supportsRedstoneControl() { return true; } + public boolean isRedstoneBlocked() { + return isRedstoneBlocked; + } + public RedstoneControl getRedstoneControl() { if (!supportsRedstoneControl()) { throw new IllegalStateException("This machine does not support redstone control."); @@ -292,18 +301,27 @@ public void setRedstoneControl(RedstoneControl redstoneControl) { private void internalSetRedstoneControl(RedstoneControl redstoneControl) { setData(MachineAttachments.REDSTONE_CONTROL, redstoneControl); setChanged(); + updateRedstone(); } // endregion // region Inventory + /** + * Create the block entity's inventory slot layout. + */ + @Nullable + public MachineInventoryLayout createInventoryLayout() { + return null; + } + /** * Get the block entity's inventory slot layout. */ @Nullable public MachineInventoryLayout getInventoryLayout() { - return null; + return inventoryLayout; } @Nullable @@ -359,13 +377,7 @@ public boolean canAct() { return false; } - if (supportsRedstoneControl()) { - boolean active = getRedstoneControl().isActive(this.level.hasNeighborSignal(worldPosition)); - updateMachineState(MachineState.REDSTONE, !active); - return active; - } - - return true; + return !isRedstoneBlocked; } public boolean canActSlow() { @@ -423,6 +435,12 @@ private void moveFluids(Direction side) { // region Serialization + @Override + public void onLoad() { + super.onLoad(); + updateRedstone(); + } + @Override public void saveAdditional(CompoundTag pTag, HolderLookup.Provider lookupProvider) { super.saveAdditional(pTag, lookupProvider); @@ -564,4 +582,16 @@ public void updateMachineState(MachineState state, boolean add) { states.remove(state); } } + + public void neighborChanged(BlockState state, LevelReader level, BlockPos pos, BlockPos neighbor) { + updateRedstone(); + } + + private void updateRedstone() { + if (supportsRedstoneControl()) { + boolean active = getRedstoneControl().isActive(this.level.hasNeighborSignal(worldPosition)); + updateMachineState(MachineState.REDSTONE, !active); + this.isRedstoneBlocked = !active; + } + } } diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/base/PoweredMachineBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/base/PoweredMachineBlockEntity.java index aeeb9dd341..01ee2093a0 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/base/PoweredMachineBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/base/PoweredMachineBlockEntity.java @@ -63,6 +63,7 @@ public abstract class PoweredMachineBlockEntity extends MachineBlockEntity imple private CapacitorData cachedCapacitorData = CapacitorData.NONE; private boolean capacitorCacheDirty; private boolean updateModel = false; + private final boolean hasActiveState; public PoweredMachineBlockEntity(EnergyIOMode energyIOMode, CapacitorScalable capacity, CapacitorScalable usageRate, BlockEntityType type, BlockPos worldPosition, BlockState blockState) { super(type, worldPosition, blockState); @@ -81,6 +82,8 @@ public PoweredMachineBlockEntity(EnergyIOMode energyIOMode, CapacitorScalable ca // new new new new way of syncing energy storage. addDataSlot(createEnergyDataSlot()); + + this.hasActiveState = blockState.hasProperty(ProgressMachineBlock.POWERED); } public NetworkDataSlot createEnergyDataSlot() { @@ -97,7 +100,7 @@ public void serverTick() { if (level != null) { BlockState blockState = getBlockState(); - boolean isBlockStateOutdated = blockState.hasProperty(ProgressMachineBlock.POWERED) && blockState.getValue(ProgressMachineBlock.POWERED) != isActive(); + boolean isBlockStateOutdated = hasActiveState && blockState.getValue(ProgressMachineBlock.POWERED) != isActive(); boolean isMachineStateOutdated = getMachineStates().contains(MachineState.ACTIVE) != isActive(); if (isBlockStateOutdated || isMachineStateOutdated) { if (updateModel) { @@ -316,10 +319,6 @@ protected void onInventoryContentsChanged(int slot) { } private void cacheCapacitorData() { - if (level == null) { - return; - } - capacitorCacheDirty = false; MachineInventoryLayout layout = getInventoryLayout(); @@ -351,15 +350,15 @@ public void saveAdditional(CompoundTag pTag, HolderLookup.Provider lookupProvide @Override public void loadAdditional(CompoundTag pTag, HolderLookup.Provider lookupProvider) { - super.loadAdditional(pTag, lookupProvider); - - cacheCapacitorData(); - var energyStorage = getEnergyStorage(); if (energyStorage instanceof MachineEnergyStorage storage && pTag.contains(MachineNBTKeys.ENERGY)) { storage.deserializeNBT(lookupProvider, pTag.getCompound(MachineNBTKeys.ENERGY)); } + super.loadAdditional(pTag, lookupProvider); + + cacheCapacitorData(); + updateMachineState(MachineState.NO_CAPACITOR, requiresCapacitor() && getCapacitorItem().isEmpty()); updateMachineState(MachineState.NO_POWER, energyStorage.getEnergyStored() <= 0); } diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/base/VacuumMachineBlockEntity.java b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/base/VacuumMachineBlockEntity.java index ac2b96afba..5a0cf705e5 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/base/VacuumMachineBlockEntity.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/blockentity/base/VacuumMachineBlockEntity.java @@ -44,7 +44,7 @@ public VacuumMachineBlockEntity(BlockEntityType pType, BlockPos pWorldPositio @Override public void serverTick() { - if (this.getRedstoneControl().isActive(level.hasNeighborSignal(worldPosition))) { + if (!this.isRedstoneBlocked()) { this.attractEntities(this.getLevel(), this.getBlockPos(), this.getRange()); } @@ -53,7 +53,7 @@ public void serverTick() { @Override public void clientTick() { - if (this.getRedstoneControl().isActive(level.hasNeighborSignal(worldPosition))) { + if (!this.isRedstoneBlocked()) { this.attractEntities(this.getLevel(), this.getBlockPos(), this.getRange()); } diff --git a/enderio-machines/src/main/java/com/enderio/machines/common/io/IOConfig.java b/enderio-machines/src/main/java/com/enderio/machines/common/io/IOConfig.java index d871cd2853..226e83155d 100644 --- a/enderio-machines/src/main/java/com/enderio/machines/common/io/IOConfig.java +++ b/enderio-machines/src/main/java/com/enderio/machines/common/io/IOConfig.java @@ -88,9 +88,18 @@ public boolean equals(Object o) { return Objects.equals(modes, that.modes); } + /** + * Simplified hashcode impl for EnumMap using ordinal instead of hashcode for enums + */ @Override public int hashCode() { - return Objects.hashCode(modes); + int h = 0; + + for (var entry : modes.entrySet()) { + h += entry.getKey().ordinal() ^ (31 * entry.getValue().ordinal()); + } + + return h; } public Tag save(HolderLookup.Provider lookupProvider) {