it's like elonmusk hype tube except it's the exact opposite and it works

This commit is contained in:
Boblet 2025-04-09 16:54:37 +02:00
parent 98bc692d29
commit 7b3e3284b3
4 changed files with 123 additions and 18 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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<Entry<IInventory, Pair<ForgeDirection, Long>>> 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<Entry<IInventory, Pair<ForgeDirection, Long>>> {

View File

@ -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);
}
}