mirror of
https://github.com/Ellpeck/PrettyPipes.git
synced 2024-12-22 23:39:22 +01:00
made modules be able to send less than their expected amount
Closes #16
This commit is contained in:
parent
2a8d43bb30
commit
a026cfc550
5 changed files with 46 additions and 29 deletions
|
@ -26,6 +26,7 @@ import net.minecraftforge.common.util.Constants;
|
|||
import net.minecraftforge.common.util.Constants.NBT;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jgrapht.GraphPath;
|
||||
import org.jgrapht.ListenableGraph;
|
||||
|
@ -41,6 +42,7 @@ import org.jgrapht.traverse.BreadthFirstIterator;
|
|||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -129,31 +131,36 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
|
|||
}
|
||||
}
|
||||
|
||||
public boolean tryInsertItem(BlockPos startPipePos, BlockPos startInventory, ItemStack stack, boolean preventOversending) {
|
||||
return this.routeItem(startPipePos, startInventory, stack, speed -> new PipeItem(stack, speed), preventOversending);
|
||||
public ItemStack tryInsertItem(BlockPos startPipePos, BlockPos startInventory, ItemStack stack, boolean preventOversending) {
|
||||
return this.routeItem(startPipePos, startInventory, stack, PipeItem::new, preventOversending);
|
||||
}
|
||||
|
||||
public boolean routeItem(BlockPos startPipePos, BlockPos startInventory, ItemStack stack, Function<Float, PipeItem> itemSupplier, boolean preventOversending) {
|
||||
public ItemStack routeItem(BlockPos startPipePos, BlockPos startInventory, ItemStack stack, BiFunction<ItemStack, Float, PipeItem> itemSupplier, boolean preventOversending) {
|
||||
if (!this.isNode(startPipePos))
|
||||
return false;
|
||||
return stack;
|
||||
if (!this.world.isBlockLoaded(startPipePos))
|
||||
return false;
|
||||
return stack;
|
||||
PipeTileEntity startPipe = this.getPipe(startPipePos);
|
||||
if (startPipe == null)
|
||||
return false;
|
||||
return stack;
|
||||
this.startProfile("find_destination");
|
||||
for (BlockPos pipePos : this.getOrderedNetworkNodes(startPipePos)) {
|
||||
if (!this.world.isBlockLoaded(pipePos))
|
||||
continue;
|
||||
PipeTileEntity pipe = this.getPipe(pipePos);
|
||||
BlockPos dest = pipe.getAvailableDestination(stack, false, preventOversending);
|
||||
if (dest == null || dest.equals(startInventory))
|
||||
Pair<BlockPos, ItemStack> dest = pipe.getAvailableDestination(stack, false, preventOversending);
|
||||
if (dest == null || dest.getLeft().equals(startInventory))
|
||||
continue;
|
||||
this.endProfile();
|
||||
return this.routeItemToLocation(startPipePos, startInventory, pipe.getPos(), dest, itemSupplier);
|
||||
Function<Float, PipeItem> sup = speed -> itemSupplier.apply(dest.getRight(), speed);
|
||||
if (this.routeItemToLocation(startPipePos, startInventory, pipe.getPos(), dest.getLeft(), sup)) {
|
||||
ItemStack remain = stack.copy();
|
||||
remain.shrink(dest.getRight().getCount());
|
||||
this.endProfile();
|
||||
return remain;
|
||||
}
|
||||
}
|
||||
this.endProfile();
|
||||
return false;
|
||||
return stack;
|
||||
}
|
||||
|
||||
public boolean routeItemToLocation(BlockPos startPipePos, BlockPos startInventory, BlockPos destPipePos, BlockPos destInventory, Function<Float, PipeItem> itemSupplier) {
|
||||
|
|
|
@ -135,7 +135,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
|||
return this.getBlockState().get(PipeBlock.DIRECTIONS.get(dir)).isConnected();
|
||||
}
|
||||
|
||||
public BlockPos getAvailableDestination(ItemStack stack, boolean force, boolean preventOversending) {
|
||||
public Pair<BlockPos, ItemStack> getAvailableDestination(ItemStack stack, boolean force, boolean preventOversending) {
|
||||
if (!this.canWork())
|
||||
return null;
|
||||
if (!force && this.streamModules().anyMatch(m -> !m.getRight().canAcceptItem(m.getLeft(), this, stack)))
|
||||
|
@ -144,11 +144,16 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
|||
IItemHandler handler = this.getItemHandler(dir, null);
|
||||
if (handler == null)
|
||||
continue;
|
||||
if (!ItemHandlerHelper.insertItem(handler, stack, true).isEmpty())
|
||||
ItemStack remain = ItemHandlerHelper.insertItem(handler, stack, true);
|
||||
// did we insert anything?
|
||||
if (remain.getCount() == stack.getCount())
|
||||
continue;
|
||||
ItemStack toInsert = stack.copy();
|
||||
toInsert.shrink(remain.getCount());
|
||||
// limit to the max amount that modules allow us to insert
|
||||
int maxAmount = this.streamModules().mapToInt(m -> m.getRight().getMaxInsertionAmount(m.getLeft(), this, stack, handler)).min().orElse(Integer.MAX_VALUE);
|
||||
if (maxAmount < stack.getCount())
|
||||
continue;
|
||||
if (maxAmount < toInsert.getCount())
|
||||
toInsert.setCount(maxAmount);
|
||||
BlockPos offset = this.pos.offset(dir);
|
||||
if (preventOversending || maxAmount < Integer.MAX_VALUE) {
|
||||
PipeNetwork network = PipeNetwork.get(this.world);
|
||||
|
@ -159,8 +164,8 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
|||
// these are the items on the way, limited to items of the same type as stack
|
||||
int onTheWaySame = network.getItemsOnTheWay(offset, stack);
|
||||
// check if any modules are limiting us
|
||||
if (onTheWaySame + stack.getCount() > maxAmount)
|
||||
continue;
|
||||
if (toInsert.getCount() + onTheWaySame > maxAmount)
|
||||
toInsert.setCount(maxAmount - onTheWaySame);
|
||||
}
|
||||
ItemStack copy = stack.copy();
|
||||
copy.setCount(copy.getMaxStackSize());
|
||||
|
@ -169,15 +174,17 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
|||
for (int i = 0; i < handler.getSlots(); i++) {
|
||||
// this is an inaccurate check since it ignores the fact that some slots might
|
||||
// have space for items of other types, but it'll be good enough for us
|
||||
ItemStack remain = handler.insertItem(i, copy, true);
|
||||
totalSpace += copy.getMaxStackSize() - remain.getCount();
|
||||
ItemStack left = handler.insertItem(i, copy, true);
|
||||
totalSpace += copy.getMaxStackSize() - left.getCount();
|
||||
}
|
||||
// if the items on the way plus the items we're trying to move are too much, abort
|
||||
if (onTheWay + stack.getCount() > totalSpace)
|
||||
continue;
|
||||
// if the items on the way plus the items we're trying to move are too much, reduce
|
||||
if (onTheWay + toInsert.getCount() > totalSpace)
|
||||
toInsert.setCount(totalSpace - onTheWay);
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
// we return the item that can actually be inserted, NOT the remainder!
|
||||
if (!toInsert.isEmpty())
|
||||
return Pair.of(offset, toInsert);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -48,8 +48,9 @@ public class ExtractionModuleItem extends ModuleItem {
|
|||
continue;
|
||||
if (!filter.isAllowed(stack))
|
||||
continue;
|
||||
if (network.tryInsertItem(tile.getPos(), tile.getPos().offset(dir), stack, this.preventOversending)) {
|
||||
handler.extractItem(j, this.maxExtraction, false);
|
||||
ItemStack remain = network.tryInsertItem(tile.getPos(), tile.getPos().offset(dir), stack, this.preventOversending);
|
||||
if (remain.getCount() != stack.getCount()) {
|
||||
handler.extractItem(j, stack.getCount() - remain.getCount(), false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import net.minecraft.entity.player.PlayerInventory;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -50,10 +51,10 @@ public class RetrievalModuleItem extends ModuleItem {
|
|||
continue;
|
||||
ItemStack copy = filtered.copy();
|
||||
copy.setCount(this.maxExtraction);
|
||||
BlockPos dest = tile.getAvailableDestination(copy, true, this.preventOversending);
|
||||
Pair<BlockPos, ItemStack> dest = tile.getAvailableDestination(copy, true, this.preventOversending);
|
||||
if (dest == null)
|
||||
continue;
|
||||
if (network.requestItem(tile.getPos(), dest, copy, filter.getEqualityTypes()).isEmpty())
|
||||
if (network.requestItem(tile.getPos(), dest.getLeft(), dest.getRight(), filter.getEqualityTypes()).isEmpty())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,9 +75,10 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
|||
ItemStack extracted = this.items.extractItem(i, Integer.MAX_VALUE, true);
|
||||
if (extracted.isEmpty())
|
||||
continue;
|
||||
if (!network.tryInsertItem(pipe.getPos(), this.pos, extracted, true))
|
||||
ItemStack remain = network.tryInsertItem(pipe.getPos(), this.pos, extracted, true);
|
||||
if (remain.getCount() == extracted.getCount())
|
||||
continue;
|
||||
this.items.extractItem(i, extracted.getCount(), false);
|
||||
this.items.extractItem(i, extracted.getCount() - remain.getCount(), false);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue