From 16dae95d509b9087897eca17aec9adc5c7afa541 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Fri, 17 Apr 2020 21:32:01 +0200 Subject: [PATCH] moved some stuff around in preparation for over-sending module --- .../ellpeck/prettypipes/network/PipeItem.java | 55 +++++++++++++------ .../prettypipes/network/PipeNetwork.java | 33 +++++++---- .../packets/PacketItemEnterPipe.java | 2 +- .../ellpeck/prettypipes/pipe/PipeBlock.java | 3 +- .../prettypipes/pipe/PipeRenderer.java | 4 +- .../prettypipes/pipe/PipeTileEntity.java | 37 ++++++++----- 6 files changed, 87 insertions(+), 47 deletions(-) diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java b/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java index a7e534d..4ee17c7 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java @@ -22,6 +22,7 @@ import org.jgrapht.Graph; import org.jgrapht.GraphPath; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.function.Consumer; @@ -37,9 +38,7 @@ public class PipeItem implements INBTSerializable { public float lastZ; private List path; - private BlockPos startPipe; private BlockPos startInventory; - private BlockPos destPipe; private BlockPos destInventory; private BlockPos currGoalPos; private int currentTile; @@ -56,20 +55,18 @@ public class PipeItem implements INBTSerializable { this.deserializeNBT(nbt); } - public void setDestination(BlockPos startPipe, BlockPos startInventory, BlockPos destPipe, BlockPos destInventory, GraphPath path) { - this.startPipe = startPipe; + public void setDestination(BlockPos startInventory, BlockPos destInventory, GraphPath path) { this.startInventory = startInventory; - this.destPipe = destPipe; this.destInventory = destInventory; - this.currGoalPos = startPipe; this.path = compilePath(path); + this.currGoalPos = this.getStartPipe(); this.currentTile = 0; // initialize position if new if (this.x == 0 && this.y == 0 && this.z == 0) { - this.x = MathHelper.lerp(0.5F, startInventory.getX(), startPipe.getX()) + 0.5F; - this.y = MathHelper.lerp(0.5F, startInventory.getY(), startPipe.getY()) + 0.5F; - this.z = MathHelper.lerp(0.5F, startInventory.getZ(), startPipe.getZ()) + 0.5F; + this.x = MathHelper.lerp(0.5F, startInventory.getX(), this.currGoalPos.getX()) + 0.5F; + this.y = MathHelper.lerp(0.5F, startInventory.getY(), this.currGoalPos.getY()) + 0.5F; + this.z = MathHelper.lerp(0.5F, startInventory.getZ(), this.currGoalPos.getZ()) + 0.5F; } } @@ -85,7 +82,7 @@ public class PipeItem implements INBTSerializable { BlockPos myPos = new BlockPos(this.x, this.y, this.z); if (!myPos.equals(currPipe.getPos()) && (this.reachedDestination() || !myPos.equals(this.startInventory))) { // we're done with the current pipe, so switch to the next one - currPipe.items.remove(this); + currPipe.getItems().remove(this); PipeTileEntity next = this.getNextTile(currPipe, true); if (next == null) { if (!currPipe.getWorld().isRemote) { @@ -100,7 +97,7 @@ public class PipeItem implements INBTSerializable { } return; } else { - next.items.add(this); + next.getItems().add(this); } } else { double dist = new Vec3d(this.currGoalPos).squareDistanceTo(this.x - 0.5F, this.y - 0.5F, this.z - 0.5F); @@ -112,7 +109,7 @@ public class PipeItem implements INBTSerializable { if (this.reachedDestination()) { nextPos = this.destInventory; } else { - currPipe.items.remove(this); + currPipe.getItems().remove(this); if (!currPipe.getWorld().isRemote) this.onPathObstructed(currPipe, false); return; @@ -152,7 +149,7 @@ public class PipeItem implements INBTSerializable { private void onPathObstructed(PipeTileEntity currPipe, boolean tryReturn) { if (!this.dropOnObstruction && tryReturn) { PipeNetwork network = PipeNetwork.get(currPipe.getWorld()); - if (network.routeItemToLocation(currPipe.getPos(), this.destInventory, this.startPipe, this.startInventory, speed -> this)) { + if (network.routeItemToLocation(currPipe.getPos(), this.destInventory, this.getStartPipe(), this.startInventory, speed -> this)) { this.dropOnObstruction = true; return; } @@ -169,7 +166,7 @@ public class PipeItem implements INBTSerializable { TileEntity tile = currPipe.getWorld().getTileEntity(this.destInventory); if (tile == null) return this.stack; - Direction dir = Utility.getDirectionFromOffset(this.destPipe, this.destInventory); + Direction dir = Utility.getDirectionFromOffset(this.getDestPipe(), this.destInventory); IItemHandler handler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir).orElse(null); if (handler == null) return this.stack; @@ -190,14 +187,24 @@ public class PipeItem implements INBTSerializable { return network.getPipe(pos); } + private BlockPos getStartPipe() { + return this.path.get(0); + } + + private BlockPos getDestPipe() { + return this.path.get(this.path.size() - 1); + } + + public BlockPos getCurrentPipe() { + return this.path.get(this.currentTile); + } + @Override public CompoundNBT serializeNBT() { CompoundNBT nbt = new CompoundNBT(); nbt.put("stack", this.stack.serializeNBT()); nbt.putFloat("speed", this.speed); - nbt.put("start_pipe", NBTUtil.writeBlockPos(this.startPipe)); nbt.put("start_inv", NBTUtil.writeBlockPos(this.startInventory)); - nbt.put("dest_pipe", NBTUtil.writeBlockPos(this.destPipe)); nbt.put("dest_inv", NBTUtil.writeBlockPos(this.destInventory)); nbt.put("curr_goal", NBTUtil.writeBlockPos(this.currGoalPos)); nbt.putBoolean("drop_on_obstruction", this.dropOnObstruction); @@ -216,9 +223,7 @@ public class PipeItem implements INBTSerializable { public void deserializeNBT(CompoundNBT nbt) { this.stack = ItemStack.read(nbt.getCompound("stack")); this.speed = nbt.getFloat("speed"); - this.startPipe = NBTUtil.readBlockPos(nbt.getCompound("start_pipe")); this.startInventory = NBTUtil.readBlockPos(nbt.getCompound("start_inv")); - this.destPipe = NBTUtil.readBlockPos(nbt.getCompound("dest_pipe")); this.destInventory = NBTUtil.readBlockPos(nbt.getCompound("dest_inv")); this.currGoalPos = NBTUtil.readBlockPos(nbt.getCompound("curr_goal")); this.dropOnObstruction = nbt.getBoolean("drop_on_obstruction"); @@ -257,4 +262,18 @@ public class PipeItem implements INBTSerializable { } return ret; } + + public static ListNBT serializeAll(Collection items) { + ListNBT list = new ListNBT(); + for (PipeItem item : items) + list.add(item.serializeNBT()); + return list; + } + + public static List deserializeAll(ListNBT list) { + List items = new ArrayList<>(); + for (int i = 0; i < list.size(); i++) + items.add(new PipeItem(list.getCompound(i))); + return items; + } } diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java index d457fba..a16376f 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java @@ -47,6 +47,7 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL private final DijkstraShortestPath dijkstra; private final Map> nodeToConnectedNodes = new HashMap<>(); private final Map tileCache = new HashMap<>(); + private final ListMultimap pipeItems = ArrayListMultimap.create(); private final World world; public PipeNetwork(World world) { @@ -73,18 +74,23 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL for (NetworkEdge edge : this.graph.edgeSet()) edges.add(edge.serializeNBT()); nbt.put("edges", edges); + nbt.put("items", PipeItem.serializeAll(this.pipeItems.values())); return nbt; } @Override public void deserializeNBT(CompoundNBT nbt) { this.graph.removeAllVertices(new ArrayList<>(this.graph.vertexSet())); + this.pipeItems.clear(); + ListNBT nodes = nbt.getList("nodes", Constants.NBT.TAG_COMPOUND); for (int i = 0; i < nodes.size(); i++) this.graph.addVertex(NBTUtil.readBlockPos(nodes.getCompound(i))); ListNBT edges = nbt.getList("edges", Constants.NBT.TAG_COMPOUND); for (int i = 0; i < edges.size(); i++) this.addEdge(new NetworkEdge(edges.getCompound(i))); + for (PipeItem item : PipeItem.deserializeAll(nbt.getList("items", Constants.NBT.TAG_COMPOUND))) + this.pipeItems.put(item.getCurrentPipe(), item); } public void addNode(BlockPos pos, BlockState state) { @@ -137,23 +143,23 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL return false; } - public boolean routeItemToLocation(BlockPos startPipePos, BlockPos startInventory, BlockPos destPipe, BlockPos destInventory, Function itemSupplier) { - if (!this.isNode(startPipePos) || !this.isNode(destPipe)) + public boolean routeItemToLocation(BlockPos startPipePos, BlockPos startInventory, BlockPos destPipePos, BlockPos destInventory, Function itemSupplier) { + if (!this.isNode(startPipePos) || !this.isNode(destPipePos)) return false; - if (!this.world.isBlockLoaded(startPipePos) || !this.world.isBlockLoaded(destPipe)) + if (!this.world.isBlockLoaded(startPipePos) || !this.world.isBlockLoaded(destPipePos)) return false; PipeTileEntity startPipe = this.getPipe(startPipePos); if (startPipe == null) return false; this.startProfile("get_path"); - GraphPath path = this.dijkstra.getPath(startPipePos, destPipe); + GraphPath path = this.dijkstra.getPath(startPipePos, destPipePos); this.endProfile(); if (path == null) return false; PipeItem item = itemSupplier.apply(startPipe.getItemSpeed()); - item.setDestination(startPipePos, startInventory, destPipe, destInventory, path); - if (!startPipe.items.contains(item)) - startPipe.items.add(item); + item.setDestination(startInventory, destInventory, path); + if (!startPipe.getItems().contains(item)) + startPipe.getItems().add(item); PacketHandler.sendToAllLoaded(this.world, startPipePos, new PacketItemEnterPipe(startPipePos, item)); return true; } @@ -266,10 +272,6 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL return null; } - public static PipeNetwork get(World world) { - return world.getCapability(Registry.pipeNetworkCapability).orElse(null); - } - private List getOrderedDestinations(BlockPos node) { List ret = this.nodeToConnectedNodes.get(node); if (ret == null) { @@ -293,6 +295,10 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL this.endProfile(); } + public List getItemsInPipe(BlockPos pos) { + return this.pipeItems.get(pos); + } + @Override public void edgeAdded(GraphEdgeChangeEvent e) { this.clearDestinationCache(e.getEdgeSource(), e.getEdgeTarget()); @@ -318,4 +324,9 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL private void endProfile() { this.world.getProfiler().endSection(); } + + public static PipeNetwork get(World world) { + return world.getCapability(Registry.pipeNetworkCapability).orElse(null); + } + } diff --git a/src/main/java/de/ellpeck/prettypipes/packets/PacketItemEnterPipe.java b/src/main/java/de/ellpeck/prettypipes/packets/PacketItemEnterPipe.java index 34eca7d..60ec2cd 100644 --- a/src/main/java/de/ellpeck/prettypipes/packets/PacketItemEnterPipe.java +++ b/src/main/java/de/ellpeck/prettypipes/packets/PacketItemEnterPipe.java @@ -48,7 +48,7 @@ public class PacketItemEnterPipe { PipeItem item = new PipeItem(message.item); PipeTileEntity pipe = Utility.getTileEntity(PipeTileEntity.class, mc.world, message.tilePos); if (pipe != null) - pipe.items.add(item); + pipe.getItems().add(item); } }); ctx.get().setPacketHandled(true); diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlock.java b/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlock.java index 2179b13..da41b52 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlock.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlock.java @@ -203,12 +203,13 @@ public class PipeBlock extends ContainerBlock { PipeTileEntity tile = Utility.getTileEntity(PipeTileEntity.class, worldIn, pos); if (tile != null) { Utility.dropInventory(tile, tile.modules); - for (PipeItem item : tile.items) + for (PipeItem item : tile.getItems()) item.drop(worldIn); } PipeNetwork network = PipeNetwork.get(worldIn); network.removeNode(pos); network.onPipeChanged(pos, state); + network.getItemsInPipe(pos).clear(); super.onReplaced(state, worldIn, pos, newState, isMoving); } } diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/PipeRenderer.java b/src/main/java/de/ellpeck/prettypipes/pipe/PipeRenderer.java index e63be99..13179b1 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/PipeRenderer.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/PipeRenderer.java @@ -25,12 +25,12 @@ public class PipeRenderer extends TileEntityRenderer { @Override public void render(PipeTileEntity tile, float v, MatrixStack matrixStack, IRenderTypeBuffer iRenderTypeBuffer, int k, int i1) { - if (tile.items.isEmpty()) + if (tile.getItems().isEmpty()) return; matrixStack.push(); BlockPos tilePos = tile.getPos(); matrixStack.translate(-tilePos.getX(), -tilePos.getY(), -tilePos.getZ()); - for (PipeItem item : tile.items) { + for (PipeItem item : tile.getItems()) { matrixStack.push(); matrixStack.translate( MathHelper.lerp(v, item.lastX, item.x), diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java b/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java index 8d9266f..5b9786a 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java @@ -14,6 +14,7 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.ListNBT; +import net.minecraft.nbt.NBTUtil; import net.minecraft.profiler.IProfiler; import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntity; @@ -50,7 +51,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide return 1; } }; - public final List items = new ArrayList<>(); + private List items; private int priority; public PipeTileEntity() { @@ -60,28 +61,29 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide @Override public CompoundNBT write(CompoundNBT compound) { compound.put("modules", this.modules.serializeNBT()); - ListNBT list = new ListNBT(); - for (PipeItem item : this.items) - list.add(item.serializeNBT()); - compound.put("items", list); return super.write(compound); } @Override public void read(CompoundNBT compound) { this.modules.deserializeNBT(compound.getCompound("modules")); - this.items.clear(); - ListNBT list = compound.getList("items", Constants.NBT.TAG_COMPOUND); - for (int i = 0; i < list.size(); i++) - this.items.add(new PipeItem(list.getCompound(i))); super.read(compound); } @Override public CompoundNBT getUpdateTag() { - // by default, this is just writeInternal, but we - // want to sync the current pipe items on load too - return this.write(new CompoundNBT()); + // sync pipe items on load + CompoundNBT nbt = this.write(new CompoundNBT()); + nbt.put("items", PipeItem.serializeAll(this.getItems())); + return nbt; + } + + @Override + public void handleUpdateTag(CompoundNBT nbt) { + this.read(nbt); + List items = this.getItems(); + items.clear(); + items.addAll(PipeItem.deserializeAll(nbt.getList("items", Constants.NBT.TAG_COMPOUND))); } @Override @@ -106,11 +108,18 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide profiler.endSection(); profiler.startSection("ticking_items"); - for (int i = this.items.size() - 1; i >= 0; i--) - this.items.get(i).updateInPipe(this); + List items = this.getItems(); + for (int i = items.size() - 1; i >= 0; i--) + items.get(i).updateInPipe(this); profiler.endSection(); } + public List getItems() { + if (this.items == null) + this.items = PipeNetwork.get(this.world).getItemsInPipe(this.pos); + return this.items; + } + public boolean isConnected(Direction dir) { return this.getBlockState().get(PipeBlock.DIRECTIONS.get(dir)).isConnected(); }