From 7b3e3284b3d8f66c3f1fdc05c41c243c59920046 Mon Sep 17 00:00:00 2001 From: Boblet Date: Wed, 9 Apr 2025 16:54:37 +0200 Subject: [PATCH] it's like elonmusk hype tube except it's the exact opposite and it works --- CONTRIBUTING.md | 3 + .../network/TileEntityPneumoTube.java | 24 +++- .../networkproviders/PneumaticNetwork.java | 110 +++++++++++++++--- src/main/java/com/hbm/util/ItemStackUtil.java | 4 + 4 files changed, 123 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e6efdf8c8..c900bddfa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,6 +20,9 @@ This should go without saying, but please don't PR code that was never actually **Addendum:** Because apparently some people think that testing is somehow optional, it is now **mandatory** to test the code both on a client and on a server. If the PR contains compat code, the game has to work **with and without** the mod that the compat is for. +## No refactor PRs +Your refactors suck ass and usually something ends up breaking. + ## Communication If you're planning on adding some new thing or doing a grand change, it's best to ask whether that's a good idea before spending 50 hours on a project that won't end up getting merged, due to issues that could have been entirely avoidable with communication. diff --git a/src/main/java/com/hbm/tileentity/network/TileEntityPneumoTube.java b/src/main/java/com/hbm/tileentity/network/TileEntityPneumoTube.java index a232dd65b..be1a11823 100644 --- a/src/main/java/com/hbm/tileentity/network/TileEntityPneumoTube.java +++ b/src/main/java/com/hbm/tileentity/network/TileEntityPneumoTube.java @@ -61,6 +61,18 @@ public class TileEntityPneumoTube extends TileEntityMachineBase implements IGUIP public String getName() { return "container.pneumoTube"; } + + public boolean matchesFilter(ItemStack stack) { + + for(int i = 0; i < 15; i++) { + ItemStack filter = slots[i]; + if(filter != null && this.pattern.isValidForFilter(filter, i, stack)) { + return true; + } + } + + return false; + } @Override public void updateEntity() { @@ -103,7 +115,7 @@ public class TileEntityPneumoTube extends TileEntityMachineBase implements IGUIP if(sendFrom instanceof IInventory) { PneumaticNetwork net = node.net; - if(net.send((IInventory) sendFrom, this, this.insertionDir.getOpposite(), sendOrder, receiveOrder)) { + if(net.send((IInventory) sendFrom, this, this.insertionDir.getOpposite(), sendOrder, receiveOrder, getRangeFromPressure(compair.getPressure()))) { this.didSend = true; this.compair.setFill(this.compair.getFill() - 50); } @@ -120,6 +132,16 @@ public class TileEntityPneumoTube extends TileEntityMachineBase implements IGUIP } } + public static int getRangeFromPressure(int pressure) { + if(pressure == 0) return 0; + if(pressure == 1) return 10; + if(pressure == 2) return 25; + if(pressure == 3) return 100; + if(pressure == 4) return 250; + if(pressure == 5) return 1_000; + return 0; + } + // tactfully copy pasted from BlockPos public static int getIdentifier(int x, int y, int z) { return (y + z * 27644437) * 27644437 + x; diff --git a/src/main/java/com/hbm/uninos/networkproviders/PneumaticNetwork.java b/src/main/java/com/hbm/uninos/networkproviders/PneumaticNetwork.java index 0dafda6b6..9e7703b23 100644 --- a/src/main/java/com/hbm/uninos/networkproviders/PneumaticNetwork.java +++ b/src/main/java/com/hbm/uninos/networkproviders/PneumaticNetwork.java @@ -1,6 +1,7 @@ package com.hbm.uninos.networkproviders; import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.List; @@ -10,11 +11,14 @@ import java.util.Random; import com.hbm.tileentity.network.TileEntityPneumoTube; import com.hbm.uninos.NodeNet; import com.hbm.util.BobMathUtil; +import com.hbm.util.ItemStackUtil; import com.hbm.util.Tuple.Pair; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.MathHelper; import net.minecraftforge.common.util.ForgeDirection; public class PneumaticNetwork extends NodeNet { @@ -42,7 +46,7 @@ public class PneumaticNetwork extends NodeNet { receivers.entrySet().removeIf(x -> { return (timestamp - x.getValue().getValue() > timeout) || NodeNet.isBadLink(x.getKey()); }); } - public boolean send(IInventory source, TileEntityPneumoTube tube, ForgeDirection dir, int sendOrder, int receiveOrder) { + public boolean send(IInventory source, TileEntityPneumoTube tube, ForgeDirection accessDir, int sendOrder, int receiveOrder, int maxRange) { // turns out there may be a short time window where the cleanup hasn't happened yet, but chunkloading has already caused tiles to go invalid // so we just run it again here, just to be sure. @@ -50,21 +54,12 @@ public class PneumaticNetwork extends NodeNet { receivers.entrySet().removeIf(x -> { return (timestamp - x.getValue().getValue() > timeout) || NodeNet.isBadLink(x.getKey()); }); if(receivers.isEmpty()) return false; - - int[] slotAccess; - - if(source instanceof ISidedInventory) { - ISidedInventory sided = (ISidedInventory) source; - slotAccess = sided.getAccessibleSlotsFromSide(dir.ordinal()); - } else { - slotAccess = new int[source.getSizeInventory()]; - for(int i = 0; i < source.getSizeInventory(); i++) slotAccess[i] = i; - } - if(sendOrder == SEND_LAST) BobMathUtil.reverseIntArray(slotAccess); - if(sendOrder == SEND_RANDOM) BobMathUtil.shuffleIntArray(slotAccess); - - nextReceiver++; + int sourceSide = accessDir.ordinal(); + int[] sourceSlotAccess = getSlotAccess(source, sourceSide); + + if(sendOrder == SEND_LAST) BobMathUtil.reverseIntArray(sourceSlotAccess); + if(sendOrder == SEND_RANDOM) BobMathUtil.shuffleIntArray(sourceSlotAccess); ReceiverComparator comparator = new ReceiverComparator(tube); List>> receiverList = new ArrayList(receivers.size()); @@ -79,9 +74,90 @@ public class PneumaticNetwork extends NodeNet { if(chosenReceiverEntry == null) return false; - //TBI - the painful part + IInventory dest = chosenReceiverEntry.getKey(); + ISidedInventory sidedDest = dest instanceof ISidedInventory ? (ISidedInventory) dest : null; + ISidedInventory sidedSource = source instanceof ISidedInventory ? (ISidedInventory) source : null; - return false; + TileEntity tile1 = source instanceof TileEntity ? (TileEntity) source : null; + TileEntity tile2 = dest instanceof TileEntity ? (TileEntity) dest : null; + + if(source != null && dest != null) { + int sq = (tile1.xCoord - tile2.xCoord) * (tile1.xCoord - tile2.xCoord) + (tile1.yCoord - tile2.yCoord) * (tile1.yCoord - tile2.yCoord) + (tile1.zCoord - tile2.zCoord) * (tile1.zCoord - tile2.zCoord); + if(sq > maxRange * maxRange) { + nextReceiver++; + return false; + } + } + + int destSide = chosenReceiverEntry.getValue().getKey().getOpposite().ordinal(); + int[] destSlotAccess = getSlotAccess(source, destSide); + int itemsLeftToSend = 64; + boolean didSomething = false; + + for(int sourceIndex : sourceSlotAccess) { + ItemStack sourceStack = source.getStackInSlot(sourceIndex); + if(sourceStack == null) continue; + if(sidedSource != null && !sidedSource.canExtractItem(sourceIndex, sourceStack, sourceSide)) continue; + boolean match = tube.matchesFilter(sourceStack); + if((match && !tube.whitelist) || (!match && tube.whitelist)) continue; + int proportionalValue = MathHelper.clamp_int(64 / sourceStack.getMaxStackSize(), 1, 64); + + for(int destIndex : destSlotAccess) { + ItemStack destStack = dest.getStackInSlot(destIndex); + if(destStack == null) continue; + if(!dest.isItemValidForSlot(destIndex, sourceStack)) continue; + if(sidedDest != null && !sidedDest.canInsertItem(destIndex, sourceStack, destSide)) continue; + if(!ItemStackUtil.areStacksCompatible(sourceStack, destStack)) continue; + int toMove = BobMathUtil.min(sourceStack.stackSize, destStack.getMaxStackSize() - destStack.stackSize, dest.getInventoryStackLimit() - destStack.stackSize, itemsLeftToSend / proportionalValue); + if(toMove <= 0) continue; + + sourceStack.stackSize -= toMove; + if(sourceStack.stackSize <= 0) source.setInventorySlotContents(sourceIndex, null); + destStack.stackSize += toMove; + itemsLeftToSend -= toMove * proportionalValue; + didSomething = true; + if(itemsLeftToSend <= 0) break; + } + + if(itemsLeftToSend > 0 && sourceStack.stackSize > 0) for(int destIndex : destSlotAccess) { + if(dest.getStackInSlot(destIndex) != null) continue; + if(!dest.isItemValidForSlot(destIndex, sourceStack)) continue; + if(sidedDest != null && !sidedDest.canInsertItem(destIndex, sourceStack, destSide)) continue; + int toMove = BobMathUtil.min(sourceStack.stackSize, dest.getInventoryStackLimit(), itemsLeftToSend / proportionalValue); + if(toMove <= 0) continue; + + ItemStack newStack = sourceStack.copy(); + newStack.stackSize = toMove; + sourceStack.stackSize -= toMove; + if(sourceStack.stackSize <= 0) source.setInventorySlotContents(sourceIndex, null); + dest.setInventorySlotContents(destIndex, newStack); + itemsLeftToSend -= toMove * proportionalValue; + didSomething = true; + break; + } + + if(itemsLeftToSend <= 0) break; + } + + if(didSomething) { + nextReceiver++; + source.markDirty(); + dest.markDirty(); + } + + return didSomething; + } + + public static int[] getSlotAccess(IInventory inventory, int dir) { + + if(inventory instanceof ISidedInventory) { + int[] slotAccess = ((ISidedInventory) inventory).getAccessibleSlotsFromSide(dir); + return Arrays.copyOf(slotAccess, slotAccess.length); //we mess with the order, so better not use the original array + } else { + int[] slotAccess = new int[inventory.getSizeInventory()]; + for(int i = 0; i < inventory.getSizeInventory(); i++) slotAccess[i] = i; + return slotAccess; + } } public static class ReceiverComparator implements Comparator>> { diff --git a/src/main/java/com/hbm/util/ItemStackUtil.java b/src/main/java/com/hbm/util/ItemStackUtil.java index c5cb6abd7..ec39e1d3c 100644 --- a/src/main/java/com/hbm/util/ItemStackUtil.java +++ b/src/main/java/com/hbm/util/ItemStackUtil.java @@ -198,4 +198,8 @@ public class ItemStackUtil { world.func_147453_f(x, y, z, block); } } + + public static boolean areStacksCompatible(ItemStack sta1, ItemStack sta2) { + return sta1.getItem() == sta2.getItem() && sta1.getItemDamage() == sta2.getItemDamage() && ItemStack.areItemStackTagsEqual(sta1, sta2); + } }