pipe movement, part 1

This commit is contained in:
Ellpeck 2020-04-14 17:14:24 +02:00
parent 0a674ba1b5
commit a11693632d
8 changed files with 434 additions and 21 deletions

View file

@ -1,12 +1,10 @@
package de.ellpeck.prettypipes; package de.ellpeck.prettypipes;
import de.ellpeck.prettypipes.blocks.pipe.PipeBlock; import de.ellpeck.prettypipes.blocks.pipe.*;
import de.ellpeck.prettypipes.blocks.pipe.PipeContainer;
import de.ellpeck.prettypipes.blocks.pipe.PipeGui;
import de.ellpeck.prettypipes.blocks.pipe.PipeTileEntity;
import de.ellpeck.prettypipes.items.ExtractionUpgradeItem; import de.ellpeck.prettypipes.items.ExtractionUpgradeItem;
import de.ellpeck.prettypipes.items.WrenchItem; import de.ellpeck.prettypipes.items.WrenchItem;
import de.ellpeck.prettypipes.network.PipeNetwork; import de.ellpeck.prettypipes.network.PipeNetwork;
import de.ellpeck.prettypipes.packets.PacketHandler;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.client.gui.ScreenManager; import net.minecraft.client.gui.ScreenManager;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
@ -17,7 +15,6 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.INBT; import net.minecraft.nbt.INBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
@ -26,6 +23,7 @@ import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.extensions.IForgeContainerType; import net.minecraftforge.common.extensions.IForgeContainerType;
import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus; import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
@ -103,10 +101,12 @@ public final class Registry {
} }
}, () -> null); }, () -> null);
PacketHandler.setup();
} }
public static void setupClient(FMLClientSetupEvent event) { public static void setupClient(FMLClientSetupEvent event) {
RenderTypeLookup.setRenderLayer(pipeBlock, RenderType.cutout()); RenderTypeLookup.setRenderLayer(pipeBlock, RenderType.cutout());
ClientRegistry.bindTileEntityRenderer(pipeTileEntity, PipeRenderer::new);
ScreenManager.registerFactory(pipeContainer, PipeGui::new); ScreenManager.registerFactory(pipeContainer, PipeGui::new);
} }
} }

View file

@ -0,0 +1,37 @@
package de.ellpeck.prettypipes.blocks.pipe;
import com.mojang.blaze3d.matrix.MatrixStack;
import de.ellpeck.prettypipes.network.PipeItem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.model.ItemCameraTransforms;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.item.BlockItem;
import net.minecraft.util.math.BlockPos;
public class PipeRenderer extends TileEntityRenderer<PipeTileEntity> {
public PipeRenderer(TileEntityRendererDispatcher disp) {
super(disp);
}
@Override
public void render(PipeTileEntity tile, float v, MatrixStack matrixStack, IRenderTypeBuffer iRenderTypeBuffer, int i, int i1) {
BlockPos pos = tile.getPos();
for (PipeItem item : tile.items) {
matrixStack.push();
matrixStack.translate(item.x - pos.getX(), item.y - pos.getY(), item.z - pos.getZ());
if (item.stack.getItem() instanceof BlockItem) {
float scale = 0.65F;
matrixStack.scale(scale, scale, scale);
matrixStack.translate(0, -0.2F, 0);
} else {
float scale = 0.4F;
matrixStack.scale(scale, scale, scale);
}
Minecraft.getInstance().getItemRenderer().renderItem(item.stack, ItemCameraTransforms.TransformType.GROUND, i, i1, matrixStack, iRenderTypeBuffer);
matrixStack.pop();
}
}
}

View file

@ -3,21 +3,40 @@ package de.ellpeck.prettypipes.blocks.pipe;
import de.ellpeck.prettypipes.PrettyPipes; import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.Registry; import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.items.UpgradeItem; import de.ellpeck.prettypipes.items.UpgradeItem;
import de.ellpeck.prettypipes.network.NetworkEdge;
import de.ellpeck.prettypipes.network.PipeItem;
import de.ellpeck.prettypipes.network.PipeNetwork;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.ItemStackHandler; 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.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class PipeTileEntity extends TileEntity implements INamedContainerProvider { public class PipeTileEntity extends TileEntity implements INamedContainerProvider, ITickableTileEntity {
public final ItemStackHandler upgrades = new ItemStackHandler(3) { public final ItemStackHandler upgrades = new ItemStackHandler(3) {
@Override @Override
@ -25,6 +44,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
return stack.getItem() instanceof UpgradeItem; return stack.getItem() instanceof UpgradeItem;
} }
}; };
public final List<PipeItem> items = new ArrayList<>();
public PipeTileEntity() { public PipeTileEntity() {
super(Registry.pipeTileEntity); super(Registry.pipeTileEntity);
@ -44,12 +64,70 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
@Override @Override
public CompoundNBT write(CompoundNBT compound) { public CompoundNBT write(CompoundNBT compound) {
compound.put("upgrades", this.upgrades.serializeNBT()); compound.put("upgrades", this.upgrades.serializeNBT());
ListNBT list = new ListNBT();
for (PipeItem item : this.items)
list.add(item.serializeNBT());
compound.put("items", list);
return super.write(compound); return super.write(compound);
} }
@Override @Override
public void read(CompoundNBT compound) { public void read(CompoundNBT compound) {
this.upgrades.deserializeNBT(compound.getCompound("upgrades")); this.upgrades.deserializeNBT(compound.getCompound("upgrades"));
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); super.read(compound);
} }
@Override
public void tick() {
for (int i = this.items.size() - 1; i >= 0; i--)
this.items.get(i).updateInPipe(this);
// TODO make this extraction module stuff proper
PipeNetwork network = PipeNetwork.get(this.world);
for (int i = 0; i < this.upgrades.getSlots(); i++) {
if (this.upgrades.getStackInSlot(i).getItem() != Registry.extractionUpgradeItem)
continue;
BlockState state = this.getBlockState();
for (Direction dir : Direction.values()) {
if (!state.get(PipeBlock.DIRECTIONS.get(dir)).isConnected())
continue;
IItemHandler handler = this.getItemHandler(dir);
if (handler != null) {
for (int j = 0; j < handler.getSlots(); j++) {
ItemStack stack = handler.extractItem(j, 64, true);
if (!stack.isEmpty() && network.tryInsertItem(this.pos, this.pos.offset(dir), stack)) {
handler.extractItem(j, 64, false);
return;
}
}
}
}
return;
}
}
public BlockPos getAvailableDestination(ItemStack stack) {
for (Direction dir : Direction.values()) {
IItemHandler handler = this.getItemHandler(dir);
if (handler == null)
continue;
if (ItemHandlerHelper.insertItem(handler, stack, true).isEmpty())
return this.pos.offset(dir);
}
return null;
}
private IItemHandler getItemHandler(Direction dir) {
BlockState state = this.getBlockState();
if (!state.get(PipeBlock.DIRECTIONS.get(dir)).isConnected())
return null;
TileEntity tile = this.world.getTileEntity(this.pos.offset(dir));
if (tile == null)
return null;
return tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(null);
}
} }

View file

@ -19,20 +19,22 @@ import java.util.Map;
public class NetworkEdge extends DefaultWeightedEdge implements INBTSerializable<CompoundNBT> { public class NetworkEdge extends DefaultWeightedEdge implements INBTSerializable<CompoundNBT> {
public final World world;
public BlockPos startPipe; public BlockPos startPipe;
public BlockPos endPipe; public BlockPos endPipe;
public final List<BlockPos> pipes = new ArrayList<>(); public final List<BlockPos> pipes = new ArrayList<>();
private final Map<Integer, PipeTileEntity> tileCache = new HashMap<>(); private final Map<Integer, PipeTileEntity> tileCache = new HashMap<>();
public NetworkEdge(World world) { public NetworkEdge(){
this.world = world;
} }
public PipeTileEntity getPipe(int index) { public NetworkEdge(CompoundNBT nbt){
this.deserializeNBT(nbt);
}
public PipeTileEntity getPipe(World world, int index) {
PipeTileEntity tile = this.tileCache.get(index); PipeTileEntity tile = this.tileCache.get(index);
if (tile == null || tile.isRemoved()) { if (tile == null || tile.isRemoved()) {
tile = Utility.getTileEntity(PipeTileEntity.class, this.world, this.pipes.get(index)); tile = Utility.getTileEntity(PipeTileEntity.class, world, this.pipes.get(index));
this.tileCache.put(index, tile); this.tileCache.put(index, tile);
} }
return tile; return tile;

View file

@ -0,0 +1,157 @@
package de.ellpeck.prettypipes.network;
import de.ellpeck.prettypipes.blocks.pipe.PipeTileEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.INBTSerializable;
import org.jgrapht.GraphPath;
import java.util.ArrayList;
import java.util.List;
public class PipeItem implements INBTSerializable<CompoundNBT> {
public static final int PIPE_TIME = 40;
public ItemStack stack;
public float x;
public float y;
public float z;
private final List<NetworkEdge> pathEdges;
private BlockPos startPipe;
private BlockPos destPipe;
private BlockPos destInventory;
private int pipeTimer;
private int currentEdge;
private int currentTile;
public PipeItem(ItemStack stack, BlockPos startPipe, BlockPos startInventory, BlockPos destPipe, BlockPos destInventory, GraphPath<BlockPos, NetworkEdge> path) {
this.stack = stack;
this.startPipe = startPipe;
this.destPipe = destPipe;
this.destInventory = destInventory;
this.pathEdges = path.getEdgeList();
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;
}
public PipeItem(CompoundNBT nbt) {
this.pathEdges = new ArrayList<>();
this.deserializeNBT(nbt);
}
public void updateInPipe(PipeTileEntity currPipe) {
this.pipeTimer++;
BlockPos goalPos;
if (this.pipeTimer >= PIPE_TIME) {
// we're done with the current pipe, so switch to the next one
currPipe.items.remove(this);
PipeTileEntity next = this.getNextTile(currPipe, true);
if (next == null) {
// ..or store in our destination container if there is no next one
this.store(currPipe);
return;
} else {
next.items.add(this);
this.pipeTimer = 0;
goalPos = next.getPos();
}
} else if (this.pipeTimer >= PIPE_TIME / 2) {
// we're past the start of the pipe, so move to the center of the next pipe
PipeTileEntity next = this.getNextTile(currPipe, false);
if (next == null) {
goalPos = this.destInventory;
} else {
goalPos = next.getPos();
}
} else {
// we're at the start of the pipe, so just move towards its center
goalPos = currPipe.getPos();
}
float speed = 1 / (float) PIPE_TIME;
Vec3d dist = new Vec3d(goalPos.getX() + 0.5F - this.x, goalPos.getY() + 0.5F - this.y, goalPos.getZ() + 0.5F - this.z);
dist = dist.normalize();
this.x += dist.x * speed;
this.y += dist.y * speed;
this.z += dist.z * speed;
}
private void store(PipeTileEntity currPipe) {
if (currPipe.getWorld().isRemote)
return;
// TODO store in destination
}
private PipeTileEntity getNextTile(PipeTileEntity currPipe, boolean progress) {
NetworkEdge edge = this.pathEdges.get(this.currentEdge);
int currTile = this.currentTile;
if (edge.pipes.size() > currTile + 1) {
currTile++;
} else {
// are we at the end of our path?
if (this.pathEdges.size() <= this.currentEdge + 1)
return null;
edge = this.pathEdges.get(this.currentEdge + 1);
// we're setting the current tile to 1 since the 0th index of
// the next edge is also the last index of the current edge
currTile = 1;
if (progress)
this.currentEdge++;
}
if (progress)
this.currentTile = currTile;
// TODO invert the current tile index if the current edge is the other way around
return edge.getPipe(currPipe.getWorld(), currTile);
}
@Override
public CompoundNBT serializeNBT() {
CompoundNBT nbt = new CompoundNBT();
nbt.put("stack", this.stack.serializeNBT());
nbt.put("start_pipe", NBTUtil.writeBlockPos(this.startPipe));
nbt.put("dest_pipe", NBTUtil.writeBlockPos(this.destPipe));
nbt.put("dest_inv", NBTUtil.writeBlockPos(this.destInventory));
nbt.putInt("timer", this.pipeTimer);
nbt.putInt("edge", this.currentEdge);
nbt.putInt("tile", this.currentTile);
nbt.putFloat("x", this.x);
nbt.putFloat("y", this.y);
nbt.putFloat("z", this.z);
ListNBT list = new ListNBT();
for (NetworkEdge edge : this.pathEdges)
list.add(edge.serializeNBT());
nbt.put("path", list);
return nbt;
}
@Override
public void deserializeNBT(CompoundNBT nbt) {
this.stack = ItemStack.read(nbt.getCompound("stack"));
this.startPipe = NBTUtil.readBlockPos(nbt.getCompound("start_pipe"));
this.destPipe = NBTUtil.readBlockPos(nbt.getCompound("dest_pipe"));
this.destInventory = NBTUtil.readBlockPos(nbt.getCompound("dest_inv"));
this.pipeTimer = nbt.getInt("timer");
this.currentEdge = nbt.getInt("edge");
this.currentTile = nbt.getInt("tile");
this.x = nbt.getFloat("x");
this.y = nbt.getFloat("y");
this.z = nbt.getFloat("z");
this.pathEdges.clear();
ListNBT list = nbt.getList("path", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < list.size(); i++)
this.pathEdges.add(new NetworkEdge(list.getCompound(i)));
}
}

View file

@ -5,11 +5,15 @@ import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.Utility; import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.blocks.pipe.PipeBlock; import de.ellpeck.prettypipes.blocks.pipe.PipeBlock;
import de.ellpeck.prettypipes.blocks.pipe.PipeTileEntity; 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.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT; import net.minecraft.nbt.ListNBT;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Tuple; import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -18,18 +22,25 @@ import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilitySerializable; import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.LazyOptional; 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.alg.shortestpath.DijkstraShortestPath;
import org.jgrapht.graph.SimpleWeightedGraph; import org.jgrapht.graph.SimpleWeightedGraph;
import org.jgrapht.traverse.ClosestFirstIterator;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> { public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
public final SimpleWeightedGraph<BlockPos, NetworkEdge> graph = new SimpleWeightedGraph<>(NetworkEdge.class); public final SimpleWeightedGraph<BlockPos, NetworkEdge> graph = new SimpleWeightedGraph<>(NetworkEdge.class);
private final DijkstraShortestPath<BlockPos, NetworkEdge> dijkstra = new DijkstraShortestPath<>(this.graph); private final DijkstraShortestPath<BlockPos, NetworkEdge> dijkstra = new DijkstraShortestPath<>(this.graph);
private final Map<BlockPos, PipeTileEntity> tileCache = new HashMap<>();
private final World world; private final World world;
public PipeNetwork(World world) { public PipeNetwork(World world) {
@ -63,34 +74,69 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
for (int i = 0; i < nodes.size(); i++) for (int i = 0; i < nodes.size(); i++)
this.graph.addVertex(NBTUtil.readBlockPos(nodes.getCompound(i))); this.graph.addVertex(NBTUtil.readBlockPos(nodes.getCompound(i)));
ListNBT edges = nbt.getList("edges", Constants.NBT.TAG_COMPOUND); ListNBT edges = nbt.getList("edges", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < edges.size(); i++) { for (int i = 0; i < edges.size(); i++)
NetworkEdge edge = new NetworkEdge(this.world); this.addEdge(new NetworkEdge(edges.getCompound(i)));
edge.deserializeNBT(edges.getCompound(i));
this.addEdge(edge);
}
} }
public void addNode(BlockPos pos, BlockState state) { public void addNode(BlockPos pos, BlockState state) {
if (!this.graph.containsVertex(pos)) { if (!this.isNode(pos)) {
this.graph.addVertex(pos); this.graph.addVertex(pos);
this.refreshNode(pos, state); this.refreshNode(pos, state);
} }
} }
public void removeNode(BlockPos pos) { public void removeNode(BlockPos pos) {
if (this.graph.containsVertex(pos)) if (this.isNode(pos))
this.graph.removeVertex(pos); this.graph.removeVertex(pos);
} }
public boolean isNode(BlockPos pos) {
return this.graph.containsVertex(pos);
}
public void onPipeChanged(BlockPos pos, BlockState state) { public void onPipeChanged(BlockPos pos, BlockState state) {
List<NetworkEdge> neighbors = this.createAllEdges(pos, state, true); List<NetworkEdge> neighbors = this.createAllEdges(pos, state, true);
// if we only have one neighbor, then there can't be any new connections // if we only have one neighbor, then there can't be any new connections
if (neighbors.size() <= 1 && !this.graph.containsVertex(pos)) if (neighbors.size() <= 1 && !this.isNode(pos))
return; return;
for (NetworkEdge edge : neighbors) for (NetworkEdge edge : neighbors)
this.refreshNode(edge.endPipe, this.world.getBlockState(edge.endPipe)); this.refreshNode(edge.endPipe, this.world.getBlockState(edge.endPipe));
} }
public boolean tryInsertItem(BlockPos startPipePos, BlockPos originInv, ItemStack stack) {
if (!this.isNode(startPipePos))
return false;
PipeTileEntity startPipe = this.getPipe(startPipePos);
if (startPipe == null)
return false;
ClosestFirstIterator<BlockPos, NetworkEdge> it = new ClosestFirstIterator<>(this.graph, startPipePos);
while (it.hasNext()) {
PipeTileEntity pipe = this.getPipe(it.next());
// don't try to insert into yourself, duh
if (pipe == startPipe)
continue;
BlockPos dest = pipe.getAvailableDestination(stack);
if (dest != null) {
GraphPath<BlockPos, NetworkEdge> path = this.dijkstra.getPath(startPipePos, pipe.getPos());
System.out.println("Found path " + path + " from " + startPipePos + " to " + 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;
}
}
return false;
}
public PipeTileEntity getPipe(BlockPos pos) {
PipeTileEntity tile = this.tileCache.get(pos);
if (tile == null || tile.isRemoved()) {
tile = Utility.getTileEntity(PipeTileEntity.class, this.world, pos);
this.tileCache.put(pos, tile);
}
return tile;
}
private void refreshNode(BlockPos pos, BlockState state) { private void refreshNode(BlockPos pos, BlockState state) {
this.graph.removeAllEdges(new ArrayList<>(this.graph.edgesOf(pos))); this.graph.removeAllEdges(new ArrayList<>(this.graph.edgesOf(pos)));
for (NetworkEdge edge : this.createAllEdges(pos, state, false)) for (NetworkEdge edge : this.createAllEdges(pos, state, false))
@ -119,7 +165,7 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
BlockState currState = this.world.getBlockState(currPos); BlockState currState = this.world.getBlockState(currPos);
if (!(currState.getBlock() instanceof PipeBlock)) if (!(currState.getBlock() instanceof PipeBlock))
return null; return null;
NetworkEdge edge = new NetworkEdge(this.world); NetworkEdge edge = new NetworkEdge();
edge.startPipe = pos; edge.startPipe = pos;
edge.pipes.add(pos); edge.pipes.add(pos);
edge.pipes.add(currPos); edge.pipes.add(currPos);
@ -127,7 +173,7 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT> {
while (true) { while (true) {
// if we found a vertex, we can stop since that's the next node // if we found a vertex, we can stop since that's the next node
// we do this here since the first offset pipe also needs to check this // we do this here since the first offset pipe also needs to check this
if (this.graph.containsVertex(currPos)) { if (this.isNode(currPos)) {
edge.endPipe = edge.pipes.get(edge.pipes.size() - 1); edge.endPipe = edge.pipes.get(edge.pipes.size() - 1);
return edge; return edge;
} }

View file

@ -0,0 +1,35 @@
package de.ellpeck.prettypipes.packets;
import de.ellpeck.prettypipes.PrettyPipes;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkRegistry;
import net.minecraftforge.fml.network.PacketDistributor;
import net.minecraftforge.fml.network.simple.SimpleChannel;
public final class PacketHandler {
private static final String VERSION = "1";
private static SimpleChannel network;
public static void setup() {
network = NetworkRegistry.newSimpleChannel(new ResourceLocation(PrettyPipes.ID, "network"), () -> VERSION, VERSION::equals, VERSION::equals);
network.registerMessage(0, PacketItemEnterPipe.class, PacketItemEnterPipe::toBytes, PacketItemEnterPipe::fromBytes, PacketItemEnterPipe::onMessage);
}
public static void sendToAllLoaded(World world, BlockPos pos, Object message) {
network.send(PacketDistributor.TRACKING_CHUNK.with(() -> world.getChunkAt(pos)), message);
}
public static void sendToAllAround(IWorld world, BlockPos pos, int range, Object message) {
network.send(PacketDistributor.NEAR.with(() -> new PacketDistributor.TargetPoint(pos.getX(), pos.getY(), pos.getZ(), range, world.getDimension().getType())), message);
}
public static void sendTo(PlayerEntity player, Object message) {
network.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) player), message);
}
}

View file

@ -0,0 +1,58 @@
package de.ellpeck.prettypipes.packets;
import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.blocks.pipe.PipeTileEntity;
import de.ellpeck.prettypipes.network.PipeItem;
import de.ellpeck.prettypipes.network.PipeNetwork;
import net.minecraft.client.Minecraft;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.network.NetworkEvent;
import java.util.function.Supplier;
public class PacketItemEnterPipe {
private BlockPos tilePos;
private CompoundNBT item;
public PacketItemEnterPipe(BlockPos tilePos, PipeItem item) {
this.tilePos = tilePos;
this.item = item.serializeNBT();
}
private PacketItemEnterPipe() {
}
public static PacketItemEnterPipe fromBytes(PacketBuffer buf) {
PacketItemEnterPipe client = new PacketItemEnterPipe();
client.tilePos = buf.readBlockPos();
client.item = buf.readCompoundTag();
return client;
}
public static void toBytes(PacketItemEnterPipe packet, PacketBuffer buf) {
buf.writeBlockPos(packet.tilePos);
buf.writeCompoundTag(packet.item);
}
@SuppressWarnings("Convert2Lambda")
public static void onMessage(PacketItemEnterPipe message, Supplier<NetworkEvent.Context> ctx) {
ctx.get().enqueueWork(new Runnable() {
@Override
public void run() {
Minecraft mc = Minecraft.getInstance();
if (mc.world == null)
return;
PipeItem item = new PipeItem(message.item);
PipeTileEntity pipe = Utility.getTileEntity(PipeTileEntity.class, mc.world, message.tilePos);
if (pipe != null)
pipe.items.add(item);
}
});
ctx.get().setPacketHandled(true);
}
}