diff --git a/src/main/java/de/ellpeck/prettypipes/Utility.java b/src/main/java/de/ellpeck/prettypipes/Utility.java index 64e537b..69b8afb 100644 --- a/src/main/java/de/ellpeck/prettypipes/Utility.java +++ b/src/main/java/de/ellpeck/prettypipes/Utility.java @@ -121,8 +121,11 @@ public final class Utility { public static > List deserializeAll(ListNBT list, Function supplier) { List items = new ArrayList<>(); - for (int i = 0; i < list.size(); i++) - items.add(supplier.apply(list.getCompound(i))); + for (int i = 0; i < list.size(); i++) { + T item = supplier.apply(list.getCompound(i)); + if (item != null) + items.add(item); + } return items; } diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java b/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java index 9e78320..0adfc2f 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java @@ -1,25 +1,36 @@ package de.ellpeck.prettypipes.network; +import com.mojang.blaze3d.matrix.MatrixStack; +import de.ellpeck.prettypipes.PrettyPipes; import de.ellpeck.prettypipes.Utility; import de.ellpeck.prettypipes.pipe.IPipeConnectable; import de.ellpeck.prettypipes.pipe.PipeTileEntity; +import joptsimple.internal.Strings; import net.minecraft.block.BlockState; import net.minecraft.block.ILiquidContainer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.model.ItemCameraTransforms; import net.minecraft.entity.item.ItemEntity; import net.minecraft.fluid.Fluid; import net.minecraft.fluid.FluidState; +import net.minecraft.item.BlockItem; +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.tileentity.TileEntity; import net.minecraft.util.Direction; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorld; import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.items.CapabilityItemHandler; @@ -28,12 +39,18 @@ import net.minecraftforge.items.ItemHandlerHelper; import org.jgrapht.Graph; import org.jgrapht.GraphPath; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.util.*; +import java.util.function.BiFunction; import java.util.function.Consumer; -public class PipeItem implements INBTSerializable, ILiquidContainer { +public class PipeItem implements INBTSerializable { + + public static final Map> TYPES = new HashMap<>(); + public static final ResourceLocation TYPE = new ResourceLocation(PrettyPipes.ID, "pipe_item"); + + static { + TYPES.put(TYPE, PipeItem::new); + } public ItemStack stack; public float speed; @@ -51,13 +68,20 @@ public class PipeItem implements INBTSerializable, ILiquidContainer protected int currentTile; protected boolean retryOnObstruction; protected long lastWorldTick; + protected ResourceLocation type; - public PipeItem(ItemStack stack, float speed) { + public PipeItem(ResourceLocation type, ItemStack stack, float speed) { + this.type = type; this.stack = stack; this.speed = speed; } - public PipeItem(CompoundNBT nbt) { + public PipeItem(ItemStack stack, float speed) { + this(TYPE, stack, speed); + } + + private PipeItem(ResourceLocation type, CompoundNBT nbt) { + this.type = type; this.path = new ArrayList<>(); this.deserializeNBT(nbt); } @@ -224,6 +248,7 @@ public class PipeItem implements INBTSerializable, ILiquidContainer @Override public CompoundNBT serializeNBT() { CompoundNBT nbt = new CompoundNBT(); + nbt.putString("type", this.type.toString()); nbt.put("stack", this.stack.serializeNBT()); nbt.putFloat("speed", this.speed); nbt.put("start_inv", NBTUtil.writeBlockPos(this.startInventory)); @@ -259,6 +284,53 @@ public class PipeItem implements INBTSerializable, ILiquidContainer this.path.add(NBTUtil.readBlockPos(list.getCompound(i))); } + @OnlyIn(Dist.CLIENT) + public void render(PipeTileEntity tile, MatrixStack matrixStack, Random random, float partialTicks, int light, int overlay, IRenderTypeBuffer buffer) { + matrixStack.translate( + MathHelper.lerp(partialTicks, this.lastX, this.x), + MathHelper.lerp(partialTicks, this.lastY, this.y), + MathHelper.lerp(partialTicks, this.lastZ, this.z)); + + if (this.stack.getItem() instanceof BlockItem) { + float scale = 0.7F; + matrixStack.scale(scale, scale, scale); + matrixStack.translate(0, -0.2F, 0); + } else { + float scale = 0.45F; + matrixStack.scale(scale, scale, scale); + matrixStack.translate(0, -0.1F, 0); + } + + random.setSeed(Item.getIdFromItem(this.stack.getItem()) + this.stack.getDamage()); + int amount = this.getModelCount(); + + for (int i = 0; i < amount; i++) { + matrixStack.push(); + if (amount > 1) { + matrixStack.translate( + (random.nextFloat() * 2.0F - 1.0F) * 0.25F * 0.5F, + (random.nextFloat() * 2.0F - 1.0F) * 0.25F * 0.5F, + (random.nextFloat() * 2.0F - 1.0F) * 0.25F * 0.5F); + } + Minecraft.getInstance().getItemRenderer().renderItem(this.stack, ItemCameraTransforms.TransformType.GROUND, light, overlay, matrixStack, buffer); + matrixStack.pop(); + } + } + + private int getModelCount() { + int i = 1; + if (this.stack.getCount() > 48) { + i = 5; + } else if (this.stack.getCount() > 32) { + i = 4; + } else if (this.stack.getCount() > 16) { + i = 3; + } else if (this.stack.getCount() > 1) { + i = 2; + } + return i; + } + protected static List compilePath(GraphPath path) { Graph graph = path.getGraph(); List ret = new ArrayList<>(); @@ -292,13 +364,13 @@ public class PipeItem implements INBTSerializable, ILiquidContainer return ret; } - @Override - public boolean canContainFluid(IBlockReader worldIn, BlockPos pos, BlockState state, Fluid fluidIn) { - return true; - } + public static PipeItem load(CompoundNBT nbt) { + // TODO legacy compat, remove eventually + if (!nbt.contains("type")) + nbt.putString("type", TYPE.toString()); - @Override - public boolean receiveFluid(IWorld worldIn, BlockPos pos, BlockState state, FluidState fluidStateIn) { - return false; + ResourceLocation type = new ResourceLocation(nbt.getString("type")); + BiFunction func = TYPES.get(type); + return func != null ? func.apply(type, nbt) : null; } } diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java index 80d3a66..169a3cd 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java @@ -100,7 +100,7 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL ListNBT edges = nbt.getList("edges", NBT.TAG_COMPOUND); for (int i = 0; i < edges.size(); i++) this.addEdge(new NetworkEdge(edges.getCompound(i))); - for (PipeItem item : Utility.deserializeAll(nbt.getList("items", NBT.TAG_COMPOUND), PipeItem::new)) + for (PipeItem item : Utility.deserializeAll(nbt.getList("items", NBT.TAG_COMPOUND), PipeItem::load)) this.pipeItems.put(item.getCurrentPipe(), item); for (NetworkLock lock : Utility.deserializeAll(nbt.getList("locks", NBT.TAG_COMPOUND), NetworkLock::new)) this.createNetworkLock(lock); @@ -133,7 +133,7 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL } } - public ItemStack tryInsertItem(BlockPos startPipePos, BlockPos startInventory, ItemStack stack, boolean preventOversending) { + public ItemStack routeItem(BlockPos startPipePos, BlockPos startInventory, ItemStack stack, boolean preventOversending) { return this.routeItem(startPipePos, startInventory, stack, PipeItem::new, preventOversending); } @@ -212,6 +212,10 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL } public ItemStack requestExistingItem(NetworkLocation location, BlockPos destPipe, BlockPos destInventory, NetworkLock ignoredLock, ItemStack stack, ItemEqualityType... equalityTypes) { + return this.requestExistingItem(location, destPipe, destInventory, ignoredLock, PipeItem::new, stack, equalityTypes); + } + + public ItemStack requestExistingItem(NetworkLocation location, BlockPos destPipe, BlockPos destInventory, NetworkLock ignoredLock, BiFunction itemSupplier, ItemStack stack, ItemEqualityType... equalityTypes) { if (location.getPos().equals(destInventory)) return stack; // make sure we don't pull any locked items @@ -230,7 +234,7 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL // try to extract from that location's inventory and send the item IItemHandler handler = location.getItemHandler(this.world); ItemStack extracted = handler.extractItem(slot, amount, true); - if (this.routeItemToLocation(location.pipePos, location.getPos(), destPipe, destInventory, extracted, speed -> new PipeItem(extracted, speed))) { + if (this.routeItemToLocation(location.pipePos, location.getPos(), destPipe, destInventory, extracted, speed -> itemSupplier.apply(extracted, speed))) { handler.extractItem(slot, extracted.getCount(), false); amount -= extracted.getCount(); if (amount <= 0) diff --git a/src/main/java/de/ellpeck/prettypipes/packets/PacketItemEnterPipe.java b/src/main/java/de/ellpeck/prettypipes/packets/PacketItemEnterPipe.java index 60ec2cd..4316544 100644 --- a/src/main/java/de/ellpeck/prettypipes/packets/PacketItemEnterPipe.java +++ b/src/main/java/de/ellpeck/prettypipes/packets/PacketItemEnterPipe.java @@ -45,7 +45,7 @@ public class PacketItemEnterPipe { Minecraft mc = Minecraft.getInstance(); if (mc.world == null) return; - PipeItem item = new PipeItem(message.item); + PipeItem item = PipeItem.load(message.item); PipeTileEntity pipe = Utility.getTileEntity(PipeTileEntity.class, mc.world, message.tilePos); if (pipe != null) pipe.getItems().add(item); diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/PipeRenderer.java b/src/main/java/de/ellpeck/prettypipes/pipe/PipeRenderer.java index 13179b1..666e706 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/PipeRenderer.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/PipeRenderer.java @@ -24,7 +24,7 @@ public class PipeRenderer extends TileEntityRenderer { } @Override - public void render(PipeTileEntity tile, float v, MatrixStack matrixStack, IRenderTypeBuffer iRenderTypeBuffer, int k, int i1) { + public void render(PipeTileEntity tile, float partialTicks, MatrixStack matrixStack, IRenderTypeBuffer iRenderTypeBuffer, int k, int i1) { if (tile.getItems().isEmpty()) return; matrixStack.push(); @@ -32,51 +32,9 @@ public class PipeRenderer extends TileEntityRenderer { matrixStack.translate(-tilePos.getX(), -tilePos.getY(), -tilePos.getZ()); for (PipeItem item : tile.getItems()) { matrixStack.push(); - matrixStack.translate( - MathHelper.lerp(v, item.lastX, item.x), - MathHelper.lerp(v, item.lastY, item.y), - MathHelper.lerp(v, item.lastZ, item.z)); - - if (item.stack.getItem() instanceof BlockItem) { - float scale = 0.7F; - matrixStack.scale(scale, scale, scale); - matrixStack.translate(0, -0.2F, 0); - } else { - float scale = 0.45F; - matrixStack.scale(scale, scale, scale); - matrixStack.translate(0, -0.1F, 0); - } - - this.random.setSeed(Item.getIdFromItem(item.stack.getItem()) + item.stack.getDamage()); - int amount = this.getModelCount(item.stack); - - for (int i = 0; i < amount; i++) { - matrixStack.push(); - if (amount > 1) { - matrixStack.translate( - (this.random.nextFloat() * 2.0F - 1.0F) * 0.25F * 0.5F, - (this.random.nextFloat() * 2.0F - 1.0F) * 0.25F * 0.5F, - (this.random.nextFloat() * 2.0F - 1.0F) * 0.25F * 0.5F); - } - Minecraft.getInstance().getItemRenderer().renderItem(item.stack, ItemCameraTransforms.TransformType.GROUND, k, i1, matrixStack, iRenderTypeBuffer); - matrixStack.pop(); - } + item.render(tile, matrixStack, this.random, partialTicks, k, i1, iRenderTypeBuffer); matrixStack.pop(); } matrixStack.pop(); } - - protected int getModelCount(ItemStack stack) { - int i = 1; - if (stack.getCount() > 48) { - i = 5; - } else if (stack.getCount() > 32) { - i = 4; - } else if (stack.getCount() > 16) { - i = 3; - } else if (stack.getCount() > 1) { - i = 2; - } - return i; - } } diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java b/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java index 45e29cb..98833c9 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java @@ -125,7 +125,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide this.read(state, nbt); List items = this.getItems(); items.clear(); - items.addAll(Utility.deserializeAll(nbt.getList("items", NBT.TAG_COMPOUND), PipeItem::new)); + items.addAll(Utility.deserializeAll(nbt.getList("items", NBT.TAG_COMPOUND), PipeItem::load)); } @Override diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/modules/extraction/ExtractionModuleItem.java b/src/main/java/de/ellpeck/prettypipes/pipe/modules/extraction/ExtractionModuleItem.java index 3dff4ee..2887bf5 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/modules/extraction/ExtractionModuleItem.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/modules/extraction/ExtractionModuleItem.java @@ -48,7 +48,7 @@ public class ExtractionModuleItem extends ModuleItem { continue; if (!filter.isAllowed(stack)) continue; - ItemStack remain = network.tryInsertItem(tile.getPos(), tile.getPos().offset(dir), stack, this.preventOversending); + ItemStack remain = network.routeItem(tile.getPos(), tile.getPos().offset(dir), stack, this.preventOversending); if (remain.getCount() != stack.getCount()) { handler.extractItem(j, stack.getCount() - remain.getCount(), false); return; diff --git a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java index 93faf32..412c201 100644 --- a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java @@ -80,7 +80,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine ItemStack extracted = this.items.extractItem(i, Integer.MAX_VALUE, true); if (extracted.isEmpty()) continue; - ItemStack remain = network.tryInsertItem(pipe.getPos(), this.pos, extracted, true); + ItemStack remain = network.routeItem(pipe.getPos(), this.pos, extracted, true); if (remain.getCount() == extracted.getCount()) continue; this.items.extractItem(i, extracted.getCount() - remain.getCount(), false);