diff --git a/src/main/java/de/ellpeck/prettypipes/Registry.java b/src/main/java/de/ellpeck/prettypipes/Registry.java index 3d2adcc..aa472eb 100644 --- a/src/main/java/de/ellpeck/prettypipes/Registry.java +++ b/src/main/java/de/ellpeck/prettypipes/Registry.java @@ -1,12 +1,10 @@ package de.ellpeck.prettypipes; -import de.ellpeck.prettypipes.blocks.pipe.PipeBlock; -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.blocks.pipe.*; import de.ellpeck.prettypipes.items.ExtractionUpgradeItem; import de.ellpeck.prettypipes.items.WrenchItem; import de.ellpeck.prettypipes.network.PipeNetwork; +import de.ellpeck.prettypipes.packets.PacketHandler; import net.minecraft.block.Block; import net.minecraft.client.gui.ScreenManager; import net.minecraft.client.renderer.RenderType; @@ -17,7 +15,6 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import net.minecraft.nbt.INBT; -import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; 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.event.RegistryEvent; 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.EventBusSubscriber.Bus; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; @@ -103,10 +101,12 @@ public final class Registry { } }, () -> null); + PacketHandler.setup(); } public static void setupClient(FMLClientSetupEvent event) { RenderTypeLookup.setRenderLayer(pipeBlock, RenderType.cutout()); + ClientRegistry.bindTileEntityRenderer(pipeTileEntity, PipeRenderer::new); ScreenManager.registerFactory(pipeContainer, PipeGui::new); } } diff --git a/src/main/java/de/ellpeck/prettypipes/blocks/pipe/PipeRenderer.java b/src/main/java/de/ellpeck/prettypipes/blocks/pipe/PipeRenderer.java new file mode 100644 index 0000000..8fb6526 --- /dev/null +++ b/src/main/java/de/ellpeck/prettypipes/blocks/pipe/PipeRenderer.java @@ -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 { + + 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(); + } + } +} diff --git a/src/main/java/de/ellpeck/prettypipes/blocks/pipe/PipeTileEntity.java b/src/main/java/de/ellpeck/prettypipes/blocks/pipe/PipeTileEntity.java index 4e49d03..aa6e712 100644 --- a/src/main/java/de/ellpeck/prettypipes/blocks/pipe/PipeTileEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/blocks/pipe/PipeTileEntity.java @@ -3,21 +3,40 @@ package de.ellpeck.prettypipes.blocks.pipe; import de.ellpeck.prettypipes.PrettyPipes; import de.ellpeck.prettypipes.Registry; 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.PlayerInventory; import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.ListNBT; +import net.minecraft.tileentity.ITickableTileEntity; 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.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 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 { +public class PipeTileEntity extends TileEntity implements INamedContainerProvider, ITickableTileEntity { public final ItemStackHandler upgrades = new ItemStackHandler(3) { @Override @@ -25,6 +44,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide return stack.getItem() instanceof UpgradeItem; } }; + public final List items = new ArrayList<>(); public PipeTileEntity() { super(Registry.pipeTileEntity); @@ -44,12 +64,70 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide @Override public CompoundNBT write(CompoundNBT compound) { 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); } @Override public void read(CompoundNBT compound) { 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); } + + @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); + } } diff --git a/src/main/java/de/ellpeck/prettypipes/network/NetworkEdge.java b/src/main/java/de/ellpeck/prettypipes/network/NetworkEdge.java index bffebba..ef1504a 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/NetworkEdge.java +++ b/src/main/java/de/ellpeck/prettypipes/network/NetworkEdge.java @@ -19,20 +19,22 @@ import java.util.Map; public class NetworkEdge extends DefaultWeightedEdge implements INBTSerializable { - public final World world; public BlockPos startPipe; public BlockPos endPipe; public final List pipes = new ArrayList<>(); private final Map tileCache = new HashMap<>(); - public NetworkEdge(World world) { - this.world = world; + public NetworkEdge(){ } - 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); 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); } return tile; diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java b/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java new file mode 100644 index 0000000..f709a67 --- /dev/null +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java @@ -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 { + + public static final int PIPE_TIME = 40; + + public ItemStack stack; + public float x; + public float y; + public float z; + + private final List 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 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))); + } +} diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java index 90d6853..f474525 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java @@ -5,11 +5,15 @@ 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; @@ -18,18 +22,25 @@ import net.minecraftforge.common.capabilities.Capability; 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; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class PipeNetwork implements ICapabilitySerializable { public final SimpleWeightedGraph graph = new SimpleWeightedGraph<>(NetworkEdge.class); private final DijkstraShortestPath dijkstra = new DijkstraShortestPath<>(this.graph); + private final Map tileCache = new HashMap<>(); private final World world; public PipeNetwork(World world) { @@ -63,34 +74,69 @@ public class PipeNetwork implements ICapabilitySerializable { 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++) { - NetworkEdge edge = new NetworkEdge(this.world); - edge.deserializeNBT(edges.getCompound(i)); - this.addEdge(edge); - } + for (int i = 0; i < edges.size(); i++) + this.addEdge(new NetworkEdge(edges.getCompound(i))); } public void addNode(BlockPos pos, BlockState state) { - if (!this.graph.containsVertex(pos)) { + if (!this.isNode(pos)) { this.graph.addVertex(pos); this.refreshNode(pos, state); } } public void removeNode(BlockPos pos) { - if (this.graph.containsVertex(pos)) + if (this.isNode(pos)) this.graph.removeVertex(pos); } + public boolean isNode(BlockPos pos) { + return this.graph.containsVertex(pos); + } + public void onPipeChanged(BlockPos pos, BlockState state) { List neighbors = this.createAllEdges(pos, state, true); // 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; for (NetworkEdge edge : neighbors) 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 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 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) { this.graph.removeAllEdges(new ArrayList<>(this.graph.edgesOf(pos))); for (NetworkEdge edge : this.createAllEdges(pos, state, false)) @@ -119,7 +165,7 @@ public class PipeNetwork implements ICapabilitySerializable { BlockState currState = this.world.getBlockState(currPos); if (!(currState.getBlock() instanceof PipeBlock)) return null; - NetworkEdge edge = new NetworkEdge(this.world); + NetworkEdge edge = new NetworkEdge(); edge.startPipe = pos; edge.pipes.add(pos); edge.pipes.add(currPos); @@ -127,7 +173,7 @@ public class PipeNetwork implements ICapabilitySerializable { while (true) { // 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 - if (this.graph.containsVertex(currPos)) { + if (this.isNode(currPos)) { edge.endPipe = edge.pipes.get(edge.pipes.size() - 1); return edge; } diff --git a/src/main/java/de/ellpeck/prettypipes/packets/PacketHandler.java b/src/main/java/de/ellpeck/prettypipes/packets/PacketHandler.java new file mode 100644 index 0000000..060e330 --- /dev/null +++ b/src/main/java/de/ellpeck/prettypipes/packets/PacketHandler.java @@ -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); + } +} diff --git a/src/main/java/de/ellpeck/prettypipes/packets/PacketItemEnterPipe.java b/src/main/java/de/ellpeck/prettypipes/packets/PacketItemEnterPipe.java new file mode 100644 index 0000000..45c39b2 --- /dev/null +++ b/src/main/java/de/ellpeck/prettypipes/packets/PacketItemEnterPipe.java @@ -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 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); + } +}