diff --git a/src/main/java/com/simibubi/create/content/logistics/packagePort/postbox/PostboxBlockEntity.java b/src/main/java/com/simibubi/create/content/logistics/packagePort/postbox/PostboxBlockEntity.java index a1f155f2ba..c3d8e6eb2d 100644 --- a/src/main/java/com/simibubi/create/content/logistics/packagePort/postbox/PostboxBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/packagePort/postbox/PostboxBlockEntity.java @@ -8,8 +8,8 @@ import com.simibubi.create.compat.computercraft.AbstractComputerBehaviour; import com.simibubi.create.compat.computercraft.ComputerCraftProxy; import com.simibubi.create.content.logistics.packagePort.PackagePortBlockEntity; +import com.simibubi.create.content.trains.station.GlobalPackagePort; import com.simibubi.create.content.trains.station.GlobalStation; -import com.simibubi.create.content.trains.station.GlobalStation.GlobalPackagePort; import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; @@ -117,23 +117,24 @@ protected void read(CompoundTag tag, boolean clientPacket) { } @Override - public void onChunkUnloaded() { + public void setChanged() { + saveOfflineBuffer(); + super.setChanged(); + } + + private void saveOfflineBuffer() { if (level == null || level.isClientSide) return; + GlobalStation station = trackedGlobalStation.get(); if (station == null) return; - if (!station.connectedPorts.containsKey(worldPosition)) - return; + GlobalPackagePort globalPackagePort = station.connectedPorts.get(worldPosition); - for (int i = 0; i < inventory.getSlots(); i++) { - globalPackagePort.offlineBuffer.setStackInSlot(i, inventory.getStackInSlot(i)); - inventory.setStackInSlot(i, ItemStack.EMPTY); - } + if (globalPackagePort == null) + return; - globalPackagePort.primed = true; - Create.RAILWAYS.markTracksDirty(); - super.onChunkUnloaded(); + globalPackagePort.saveOfflineBuffer(inventory); } @Override @@ -141,5 +142,4 @@ public void invalidateCaps() { super.invalidate(); computerBehaviour.removePeripheral(); } - } diff --git a/src/main/java/com/simibubi/create/content/trains/schedule/destination/DeliverPackagesInstruction.java b/src/main/java/com/simibubi/create/content/trains/schedule/destination/DeliverPackagesInstruction.java index b9ceaedec4..5bf65ce87b 100644 --- a/src/main/java/com/simibubi/create/content/trains/schedule/destination/DeliverPackagesInstruction.java +++ b/src/main/java/com/simibubi/create/content/trains/schedule/destination/DeliverPackagesInstruction.java @@ -16,8 +16,8 @@ import com.simibubi.create.content.trains.graph.EdgePointType; import com.simibubi.create.content.trains.schedule.ScheduleRuntime; import com.simibubi.create.content.trains.schedule.ScheduleRuntime.State; +import com.simibubi.create.content.trains.station.GlobalPackagePort; import com.simibubi.create.content.trains.station.GlobalStation; -import com.simibubi.create.content.trains.station.GlobalStation.GlobalPackagePort; import com.simibubi.create.foundation.utility.CreateLang; import net.createmod.catnip.data.Pair; diff --git a/src/main/java/com/simibubi/create/content/trains/schedule/destination/FetchPackagesInstruction.java b/src/main/java/com/simibubi/create/content/trains/schedule/destination/FetchPackagesInstruction.java index 86c62bec9a..87b76978c5 100644 --- a/src/main/java/com/simibubi/create/content/trains/schedule/destination/FetchPackagesInstruction.java +++ b/src/main/java/com/simibubi/create/content/trains/schedule/destination/FetchPackagesInstruction.java @@ -17,8 +17,8 @@ import com.simibubi.create.content.trains.graph.EdgePointType; import com.simibubi.create.content.trains.schedule.ScheduleRuntime; import com.simibubi.create.content.trains.schedule.ScheduleRuntime.State; +import com.simibubi.create.content.trains.station.GlobalPackagePort; import com.simibubi.create.content.trains.station.GlobalStation; -import com.simibubi.create.content.trains.station.GlobalStation.GlobalPackagePort; import com.simibubi.create.foundation.utility.CreateLang; import net.createmod.catnip.data.Glob; diff --git a/src/main/java/com/simibubi/create/content/trains/station/GlobalPackagePort.java b/src/main/java/com/simibubi/create/content/trains/station/GlobalPackagePort.java new file mode 100644 index 0000000000..e49de41dff --- /dev/null +++ b/src/main/java/com/simibubi/create/content/trains/station/GlobalPackagePort.java @@ -0,0 +1,43 @@ +package com.simibubi.create.content.trains.station; + +import com.simibubi.create.Create; + +import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemStackHandler; + +public class GlobalPackagePort { + public String address = ""; + public ItemStackHandler offlineBuffer = new ItemStackHandler(18); + public boolean primed = false; + private boolean restoring = false; + + public void restoreOfflineBuffer(IItemHandlerModifiable inventory) { + if (!primed) return; + + restoring = true; + + for (int slot = 0; slot < offlineBuffer.getSlots(); slot++) { + inventory.setStackInSlot(slot, offlineBuffer.getStackInSlot(slot)); + } + + restoring = false; + primed = false; + } + + public void saveOfflineBuffer(IItemHandlerModifiable inventory) { + /* + * Each time restoreOfflineBuffer changes a slot, the inventory + * calls this method. We must filter out those calls to prevent + * overwriting later slots which haven't been restored yet, and + * to avoid unnecessary work. + */ + if (restoring) return; + + // TODO: Call save method on individual slots rather than iterating + for (int slot = 0; slot < inventory.getSlots(); slot++) { + offlineBuffer.setStackInSlot(slot, inventory.getStackInSlot(slot)); + } + + Create.RAILWAYS.markTracksDirty(); + } +} diff --git a/src/main/java/com/simibubi/create/content/trains/station/GlobalStation.java b/src/main/java/com/simibubi/create/content/trains/station/GlobalStation.java index edcbbf6c4a..b8d52a4e8e 100644 --- a/src/main/java/com/simibubi/create/content/trains/station/GlobalStation.java +++ b/src/main/java/com/simibubi/create/content/trains/station/GlobalStation.java @@ -11,7 +11,6 @@ import com.simibubi.create.content.logistics.box.PackageItem; import com.simibubi.create.content.logistics.packagePort.postbox.PostboxBlockEntity; import com.simibubi.create.content.trains.entity.Carriage; -import com.simibubi.create.content.trains.entity.CarriageContraptionEntity; import com.simibubi.create.content.trains.entity.Train; import com.simibubi.create.content.trains.graph.DimensionPalette; import com.simibubi.create.content.trains.graph.TrackNode; @@ -24,7 +23,7 @@ import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.MinecraftServer; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; @@ -33,7 +32,7 @@ import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemHandlerHelper; -import net.minecraftforge.items.ItemStackHandler; +import net.minecraftforge.server.ServerLifecycleHooks; public class GlobalStation extends SingleBlockEntityEdgePoint { @@ -162,27 +161,15 @@ public Train getNearestTrain() { return this.nearestTrain.get(); } - // Package Port integration - public static class GlobalPackagePort { - public String address = ""; - public ItemStackHandler offlineBuffer = new ItemStackHandler(18); - public boolean primed = false; - } - public void runMailTransfer() { Train train = getPresentTrain(); if (train == null || connectedPorts.isEmpty()) return; - Level level = null; - for (Carriage carriage : train.carriages) { - if (level == null) { - CarriageContraptionEntity entity = carriage.anyAvailableEntity(); - if (entity != null && entity.level() instanceof ServerLevel sl) - level = sl.getServer() - .getLevel(getBlockEntityDimension()); - } + MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); + Level level = server.getLevel(getBlockEntityDimension()); + for (Carriage carriage : train.carriages) { IItemHandlerModifiable carriageInventory = carriage.storage.getAllItems(); if (carriageInventory == null) continue; @@ -212,9 +199,14 @@ public void runMailTransfer() { continue; postboxInventory.setStackInSlot(slot, ItemStack.EMPTY); - Create.RAILWAYS.markTracksDirty(); - if (box != null) + + if (box == null) { + port.primed = true; + } else { box.spawnParticles(); + } + + Create.RAILWAYS.markTracksDirty(); } } @@ -243,10 +235,15 @@ public void runMailTransfer() { if (!result.isEmpty()) continue; - Create.RAILWAYS.markTracksDirty(); carriageInventory.setStackInSlot(slot, ItemStack.EMPTY); - if (box != null) + + if (box == null) { + port.primed = true; + } else { box.spawnParticles(); + } + + Create.RAILWAYS.markTracksDirty(); break; } diff --git a/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java b/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java index eae80b1e4b..6b71200e4b 100644 --- a/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java @@ -50,7 +50,7 @@ import com.simibubi.create.content.trains.graph.TrackNodeLocation.DiscoveredLocation; import com.simibubi.create.content.trains.schedule.Schedule; import com.simibubi.create.content.trains.schedule.ScheduleItem; -import com.simibubi.create.content.trains.station.GlobalStation.GlobalPackagePort; +import com.simibubi.create.content.trains.station.GlobalPackagePort; import com.simibubi.create.content.trains.track.ITrackBlock; import com.simibubi.create.content.trains.track.TrackTargetingBehaviour; import com.simibubi.create.foundation.advancement.AllAdvancements; @@ -985,22 +985,15 @@ public void attachPackagePort(PackagePortBlockEntity ppbe) { if (ppbe instanceof PostboxBlockEntity pbe) pbe.trackedGlobalStation = new WeakReference<>(station); - if (station.connectedPorts.containsKey(ppbe.getBlockPos())) - restoreOfflineBuffer(ppbe, station.connectedPorts.get(ppbe.getBlockPos())); + GlobalPackagePort globalPackagePort = station.connectedPorts.get(ppbe.getBlockPos()); - GlobalPackagePort globalPackagePort = new GlobalPackagePort(); - globalPackagePort.address = ppbe.addressFilter; - station.connectedPorts.put(ppbe.getBlockPos(), globalPackagePort); - } - - private void restoreOfflineBuffer(PackagePortBlockEntity ppbe, GlobalPackagePort globalPackagePort) { - if (!globalPackagePort.primed) - return; - for (int i = 0; i < globalPackagePort.offlineBuffer.getSlots(); i++) { - ppbe.inventory.setStackInSlot(i, globalPackagePort.offlineBuffer.getStackInSlot(i)); - globalPackagePort.offlineBuffer.setStackInSlot(i, ItemStack.EMPTY); + if (globalPackagePort == null) { + globalPackagePort = new GlobalPackagePort(); + globalPackagePort.address = ppbe.addressFilter; + station.connectedPorts.put(ppbe.getBlockPos(), globalPackagePort); + } else { + globalPackagePort.restoreOfflineBuffer(ppbe.inventory); } - globalPackagePort.primed = false; } public void removePackagePort(PackagePortBlockEntity ppbe) {