misc pipe fixes

This commit is contained in:
Ellpeck 2020-04-14 21:04:41 +02:00
parent 6abfec9c94
commit 44a5d6b4ec
3 changed files with 65 additions and 29 deletions

View file

@ -25,16 +25,11 @@ import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.ItemStackHandler;
import org.jgrapht.GraphPath;
import org.jgrapht.alg.interfaces.ShortestPathAlgorithm;
import org.jgrapht.alg.interfaces.ShortestPathAlgorithm.SingleSourcePaths;
import org.jgrapht.traverse.ClosestFirstIterator;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class PipeTileEntity extends TileEntity implements INamedContainerProvider, ITickableTileEntity {
@ -81,8 +76,18 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
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());
}
@Override
public void tick() {
if (!this.world.isAreaLoaded(this.pos, 1))
return;
for (int i = this.items.size() - 1; i >= 0; i--)
this.items.get(i).updateInPipe(this);

View file

@ -37,19 +37,18 @@ public class PipeItem implements INBTSerializable<CompoundNBT> {
public float lastY;
public float lastZ;
private final List<BlockPos> path;
private List<BlockPos> path;
private BlockPos startPipe;
private BlockPos startInventory;
private BlockPos destPipe;
private BlockPos destInventory;
private int pipeTimer;
private int currentTile;
private boolean dropOnObstruction;
public PipeItem(ItemStack stack, BlockPos startPipe, BlockPos startInventory, BlockPos destPipe, BlockPos destInventory, GraphPath<BlockPos, NetworkEdge> path) {
public PipeItem(ItemStack stack, BlockPos startPipe, BlockPos startInventory) {
this.stack = stack;
this.startPipe = startPipe;
this.destPipe = destPipe;
this.destInventory = destInventory;
this.path = compilePath(path);
this.startInventory = startInventory;
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;
@ -60,6 +59,15 @@ public class PipeItem implements INBTSerializable<CompoundNBT> {
this.deserializeNBT(nbt);
}
public void setDestination(BlockPos startPipe, BlockPos destPipe, BlockPos destInventory, GraphPath<BlockPos, NetworkEdge> path) {
this.startPipe = startPipe;
this.destPipe = destPipe;
this.destInventory = destInventory;
this.path = compilePath(path);
this.currentTile = 0;
this.pipeTimer = 0;
}
public void updateInPipe(PipeTileEntity currPipe) {
this.pipeTimer++;
BlockPos goalPos;
@ -73,9 +81,9 @@ public class PipeItem implements INBTSerializable<CompoundNBT> {
// ..or store in our destination container if we reached our destination
this.stack = this.store(currPipe);
if (!this.stack.isEmpty())
this.onPathObstructed(currPipe);
this.onPathObstructed(currPipe, true);
} else {
this.onPathObstructed(currPipe);
this.onPathObstructed(currPipe, false);
}
}
return;
@ -93,7 +101,7 @@ public class PipeItem implements INBTSerializable<CompoundNBT> {
} else {
currPipe.items.remove(this);
if (!currPipe.getWorld().isRemote)
this.onPathObstructed(currPipe);
this.onPathObstructed(currPipe, false);
return;
}
} else {
@ -116,8 +124,14 @@ public class PipeItem implements INBTSerializable<CompoundNBT> {
this.z += dist.z * speed;
}
private void onPathObstructed(PipeTileEntity currPipe) {
// TODO when the path is obstructed, try to turn back home first
private void onPathObstructed(PipeTileEntity currPipe, boolean tryReturn) {
if (!this.dropOnObstruction && tryReturn) {
PipeNetwork network = PipeNetwork.get(currPipe.getWorld());
if (network.routeItemToLocation(currPipe.getPos(), this.startPipe, this.startInventory, () -> this)) {
this.dropOnObstruction = true;
return;
}
}
this.drop(currPipe.getWorld());
}
@ -156,8 +170,10 @@ public class PipeItem implements INBTSerializable<CompoundNBT> {
CompoundNBT nbt = new CompoundNBT();
nbt.put("stack", this.stack.serializeNBT());
nbt.put("start_pipe", NBTUtil.writeBlockPos(this.startPipe));
nbt.put("start_inventory", NBTUtil.writeBlockPos(this.startInventory));
nbt.put("dest_pipe", NBTUtil.writeBlockPos(this.destPipe));
nbt.put("dest_inv", NBTUtil.writeBlockPos(this.destInventory));
nbt.putBoolean("drop_on_obstruction", this.dropOnObstruction);
nbt.putInt("timer", this.pipeTimer);
nbt.putInt("tile", this.currentTile);
nbt.putFloat("x", this.x);
@ -174,8 +190,10 @@ public class PipeItem implements INBTSerializable<CompoundNBT> {
public void deserializeNBT(CompoundNBT nbt) {
this.stack = ItemStack.read(nbt.getCompound("stack"));
this.startPipe = NBTUtil.readBlockPos(nbt.getCompound("start_pipe"));
this.startInventory = NBTUtil.readBlockPos(nbt.getCompound("start_inventory"));
this.destPipe = NBTUtil.readBlockPos(nbt.getCompound("dest_pipe"));
this.destInventory = NBTUtil.readBlockPos(nbt.getCompound("dest_inv"));
this.dropOnObstruction = nbt.getBoolean("drop_on_obstruction");
this.pipeTimer = nbt.getInt("timer");
this.currentTile = nbt.getInt("tile");
this.x = nbt.getFloat("x");

View file

@ -1,21 +1,17 @@
package de.ellpeck.prettypipes.network;
import com.google.common.collect.Sets;
import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.blocks.pipe.PipeBlock;
import de.ellpeck.prettypipes.blocks.pipe.PipeTileEntity;
import de.ellpeck.prettypipes.packets.PacketHandler;
import de.ellpeck.prettypipes.packets.PacketItemEnterPipe;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
@ -23,8 +19,6 @@ import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.LazyOptional;
import org.jgrapht.GraphPath;
import org.jgrapht.alg.interfaces.ShortestPathAlgorithm;
import org.jgrapht.alg.interfaces.ShortestPathAlgorithm.SingleSourcePaths;
import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
import org.jgrapht.graph.SimpleWeightedGraph;
import org.jgrapht.traverse.ClosestFirstIterator;
@ -35,6 +29,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
@ -104,8 +99,14 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
}
public boolean tryInsertItem(BlockPos startPipePos, BlockPos originInv, ItemStack stack) {
return this.routeItem(startPipePos, stack, () -> new PipeItem(stack, startPipePos, originInv));
}
public boolean routeItem(BlockPos startPipePos, ItemStack stack, Supplier<PipeItem> itemSupplier) {
if (!this.isNode(startPipePos))
return false;
if (!this.world.isBlockLoaded(startPipePos))
return false;
PipeTileEntity startPipe = this.getPipe(startPipePos);
if (startPipe == null)
return false;
@ -116,17 +117,29 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
if (pipe == startPipe)
continue;
BlockPos dest = pipe.getAvailableDestination(stack);
if (dest != null) {
GraphPath<BlockPos, NetworkEdge> path = this.dijkstra.getPath(startPipePos, pipe.getPos());
PipeItem item = new PipeItem(stack.copy(), startPipePos, originInv, pipe.getPos(), dest, path);
startPipe.items.add(item);
PacketHandler.sendToAllLoaded(this.world, startPipePos, new PacketItemEnterPipe(startPipePos, item));
return true;
}
if (dest != null)
return this.routeItemToLocation(startPipePos, pipe.getPos(), dest, itemSupplier);
}
return false;
}
public boolean routeItemToLocation(BlockPos startPipePos, BlockPos destPipe, BlockPos destInventory, Supplier<PipeItem> itemSupplier) {
if (!this.isNode(startPipePos))
return false;
if (!this.world.isBlockLoaded(startPipePos))
return false;
PipeTileEntity startPipe = this.getPipe(startPipePos);
if (startPipe == null)
return false;
GraphPath<BlockPos, NetworkEdge> path = this.dijkstra.getPath(startPipePos, destPipe);
PipeItem item = itemSupplier.get();
item.setDestination(startPipePos, destPipe, destInventory, path);
if (!startPipe.items.contains(item))
startPipe.items.add(item);
PacketHandler.sendToAllLoaded(this.world, startPipePos, new PacketItemEnterPipe(startPipePos, item));
return true;
}
public PipeTileEntity getPipe(BlockPos pos) {
PipeTileEntity tile = this.tileCache.get(pos);
if (tile == null || tile.isRemoved()) {