mirror of
https://github.com/Ellpeck/PrettyPipes.git
synced 2024-12-22 23:39:22 +01:00
prevent over-sending
This commit is contained in:
parent
16dae95d50
commit
a7bdd85139
9 changed files with 83 additions and 26 deletions
|
@ -11,9 +11,9 @@ public interface IModule {
|
|||
|
||||
void tick(ItemStack module, PipeTileEntity tile);
|
||||
|
||||
boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack);
|
||||
boolean canNetworkSee(ItemStack module, PipeTileEntity tile);
|
||||
|
||||
boolean isAvailableDestination(ItemStack module, PipeTileEntity tile, ItemStack stack, IItemHandler destination);
|
||||
boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack);
|
||||
|
||||
int getPriority(ItemStack module, PipeTileEntity tile);
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ import net.minecraft.util.text.*;
|
|||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
@ -48,12 +47,12 @@ public abstract class ModuleItem extends Item implements IModule {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack) {
|
||||
public boolean canNetworkSee(ItemStack module, PipeTileEntity tile) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailableDestination(ItemStack module, PipeTileEntity tile, ItemStack stack, IItemHandler destination) {
|
||||
public boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,18 +14,29 @@ import java.util.Map;
|
|||
public class NetworkLocation {
|
||||
|
||||
public final BlockPos pipePos;
|
||||
public final ListMultimap<Direction, Pair<Integer, ItemStack>> items;
|
||||
private ListMultimap<Direction, Pair<Integer, ItemStack>> items;
|
||||
|
||||
public NetworkLocation(BlockPos pipePos, ListMultimap<Direction, Pair<Integer, ItemStack>> items) {
|
||||
public NetworkLocation(BlockPos pipePos) {
|
||||
this.pipePos = pipePos;
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public void addItem(Direction direction, int slot, ItemStack stack) {
|
||||
if (this.items == null)
|
||||
this.items = ArrayListMultimap.create();
|
||||
this.items.put(direction, Pair.of(slot, stack));
|
||||
}
|
||||
|
||||
public Pair<Direction, Integer> getStackLocation(ItemStack stack) {
|
||||
if (this.isEmpty())
|
||||
return null;
|
||||
for (Map.Entry<Direction, Pair<Integer, ItemStack>> entry : this.items.entries()) {
|
||||
if (entry.getValue().getRight().isItemEqual(stack))
|
||||
return Pair.of(entry.getKey(), entry.getValue().getLeft());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.items == null || this.items.isEmpty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,7 +191,7 @@ public class PipeItem implements INBTSerializable<CompoundNBT> {
|
|||
return this.path.get(0);
|
||||
}
|
||||
|
||||
private BlockPos getDestPipe() {
|
||||
public BlockPos getDestPipe() {
|
||||
return this.path.get(this.path.size() - 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ import javax.annotation.Nullable;
|
|||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphListener<BlockPos, NetworkEdge> {
|
||||
|
||||
|
@ -118,11 +119,11 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
|
|||
this.refreshNode(edge.endPipe, this.world.getBlockState(edge.endPipe));
|
||||
}
|
||||
|
||||
public boolean tryInsertItem(BlockPos startPipePos, BlockPos startInventory, ItemStack stack) {
|
||||
return this.routeItem(startPipePos, startInventory, stack, speed -> new PipeItem(stack, speed));
|
||||
public boolean tryInsertItem(BlockPos startPipePos, BlockPos startInventory, ItemStack stack, boolean preventOversending) {
|
||||
return this.routeItem(startPipePos, startInventory, stack, speed -> new PipeItem(stack, speed), preventOversending);
|
||||
}
|
||||
|
||||
public boolean routeItem(BlockPos startPipePos, BlockPos startInventory, ItemStack stack, Function<Float, PipeItem> itemSupplier) {
|
||||
public boolean routeItem(BlockPos startPipePos, BlockPos startInventory, ItemStack stack, Function<Float, PipeItem> itemSupplier, boolean preventOversending) {
|
||||
if (!this.isNode(startPipePos))
|
||||
return false;
|
||||
if (!this.world.isBlockLoaded(startPipePos))
|
||||
|
@ -133,7 +134,7 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
|
|||
this.startProfile("find_destination");
|
||||
for (BlockPos pipePos : this.getOrderedDestinations(startPipePos)) {
|
||||
PipeTileEntity pipe = this.getPipe(pipePos);
|
||||
BlockPos dest = pipe.getAvailableDestination(stack, false);
|
||||
BlockPos dest = pipe.getAvailableDestination(stack, false, preventOversending);
|
||||
if (dest != null) {
|
||||
this.endProfile();
|
||||
return this.routeItemToLocation(startPipePos, startInventory, pipe.getPos(), dest, itemSupplier);
|
||||
|
@ -179,23 +180,23 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
|
|||
this.startProfile("get_network_items");
|
||||
List<NetworkLocation> info = new ArrayList<>();
|
||||
for (BlockPos dest : this.getOrderedDestinations(node)) {
|
||||
NetworkLocation location = new NetworkLocation(dest);
|
||||
PipeTileEntity pipe = this.getPipe(dest);
|
||||
if (!pipe.canNetworkSee())
|
||||
continue;
|
||||
for (Direction dir : Direction.values()) {
|
||||
IItemHandler handler = pipe.getItemHandler(dir);
|
||||
if (handler == null)
|
||||
continue;
|
||||
ListMultimap<Direction, Pair<Integer, ItemStack>> items = null;
|
||||
for (int i = 0; i < handler.getSlots(); i++) {
|
||||
ItemStack found = handler.extractItem(i, Integer.MAX_VALUE, true);
|
||||
if (found.isEmpty())
|
||||
continue;
|
||||
if (items == null)
|
||||
items = ArrayListMultimap.create();
|
||||
items.put(dir, Pair.of(i, found));
|
||||
location.addItem(dir, i, found);
|
||||
}
|
||||
if (items != null)
|
||||
info.add(new NetworkLocation(dest, items));
|
||||
}
|
||||
if (!location.isEmpty())
|
||||
info.add(location);
|
||||
}
|
||||
this.endProfile();
|
||||
return info;
|
||||
|
@ -299,6 +300,19 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
|
|||
return this.pipeItems.get(pos);
|
||||
}
|
||||
|
||||
public Stream<PipeItem> getPipeItemsOnTheWay(BlockPos goalPipe) {
|
||||
this.startProfile("get_pipe_items_on_the_way");
|
||||
Stream<PipeItem> ret = this.pipeItems.values().stream().filter(i -> i.getDestPipe().equals(goalPipe));
|
||||
this.endProfile();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int getItemsOnTheWay(BlockPos goalPipe, ItemStack type) {
|
||||
return this.getPipeItemsOnTheWay(goalPipe)
|
||||
.filter(i -> i.stack.isItemEqual(type))
|
||||
.mapToInt(i -> i.stack.getCount()).sum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void edgeAdded(GraphEdgeChangeEvent<BlockPos, NetworkEdge> e) {
|
||||
this.clearDestinationCache(e.getEdgeSource(), e.getEdgeTarget());
|
||||
|
|
|
@ -124,7 +124,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
|||
return this.getBlockState().get(PipeBlock.DIRECTIONS.get(dir)).isConnected();
|
||||
}
|
||||
|
||||
public BlockPos getAvailableDestination(ItemStack stack, boolean internal) {
|
||||
public BlockPos getAvailableDestination(ItemStack stack, boolean internal, boolean preventOversending) {
|
||||
if (!internal && this.streamModules().anyMatch(m -> !m.getRight().canAcceptItem(m.getLeft(), this, stack)))
|
||||
return null;
|
||||
for (Direction dir : Direction.values()) {
|
||||
|
@ -133,8 +133,23 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
|||
continue;
|
||||
if (!ItemHandlerHelper.insertItem(handler, stack, true).isEmpty())
|
||||
continue;
|
||||
if (this.streamModules().anyMatch(m -> !m.getRight().isAvailableDestination(m.getLeft(), this, stack, handler)))
|
||||
continue;
|
||||
if (preventOversending) {
|
||||
// these are the items that are currently in the pipes, going to this pipe
|
||||
int onTheWay = PipeNetwork.get(this.world).getItemsOnTheWay(this.pos, stack);
|
||||
if (onTheWay > 0) {
|
||||
ItemStack copy = stack.copy();
|
||||
copy.setCount(copy.getMaxStackSize());
|
||||
// totalSpace will be the amount of items that fit into the attached container
|
||||
int totalSpace = 0;
|
||||
for (int i = 0; i < handler.getSlots(); i++) {
|
||||
ItemStack remain = handler.insertItem(i, copy, true);
|
||||
totalSpace += copy.getMaxStackSize() - remain.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;
|
||||
}
|
||||
}
|
||||
return this.pos.offset(dir);
|
||||
}
|
||||
return null;
|
||||
|
@ -166,6 +181,10 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
|||
return Arrays.stream(Direction.values()).anyMatch(this::isConnectedInventory);
|
||||
}
|
||||
|
||||
public boolean canNetworkSee() {
|
||||
return this.streamModules().allMatch(m -> m.getRight().canNetworkSee(m.getLeft(), this));
|
||||
}
|
||||
|
||||
private Stream<Pair<ItemStack, IModule>> streamModules() {
|
||||
Stream.Builder<Pair<ItemStack, IModule>> builder = Stream.builder();
|
||||
for (int i = 0; i < this.modules.getSlots(); i++) {
|
||||
|
|
|
@ -18,6 +18,7 @@ public class ExtractionModuleItem extends ModuleItem {
|
|||
|
||||
private final int maxExtraction;
|
||||
private final int speed;
|
||||
private final boolean preventOversending;
|
||||
public final int filterSlots;
|
||||
|
||||
public ExtractionModuleItem(String name, ModuleTier tier) {
|
||||
|
@ -25,6 +26,7 @@ public class ExtractionModuleItem extends ModuleItem {
|
|||
this.maxExtraction = tier.forTier(1, 8, 64);
|
||||
this.speed = tier.forTier(20, 15, 10);
|
||||
this.filterSlots = tier.forTier(3, 6, 9);
|
||||
this.preventOversending = tier.forTier(false, false, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -44,7 +46,7 @@ public class ExtractionModuleItem extends ModuleItem {
|
|||
continue;
|
||||
if (!filter.isAllowed(stack))
|
||||
continue;
|
||||
if (network.tryInsertItem(tile.getPos(), tile.getPos().offset(dir), stack)) {
|
||||
if (network.tryInsertItem(tile.getPos(), tile.getPos().offset(dir), stack, this.preventOversending)) {
|
||||
handler.extractItem(j, this.maxExtraction, false);
|
||||
return;
|
||||
}
|
||||
|
@ -52,6 +54,11 @@ public class ExtractionModuleItem extends ModuleItem {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canNetworkSee(ItemStack module, PipeTileEntity tile) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack) {
|
||||
return false;
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.List;
|
|||
public class RetrievalModuleItem extends ModuleItem {
|
||||
private final int maxExtraction;
|
||||
private final int speed;
|
||||
private final boolean preventOversending;
|
||||
public final int filterSlots;
|
||||
|
||||
public RetrievalModuleItem(String name, ModuleTier tier) {
|
||||
|
@ -30,6 +31,7 @@ public class RetrievalModuleItem extends ModuleItem {
|
|||
this.maxExtraction = tier.forTier(1, 8, 16);
|
||||
this.speed = tier.forTier(40, 20, 10);
|
||||
this.filterSlots = tier.forTier(3, 6, 9);
|
||||
this.preventOversending = tier.forTier(false, true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -48,7 +50,7 @@ public class RetrievalModuleItem extends ModuleItem {
|
|||
continue;
|
||||
ItemStack copy = filtered.copy();
|
||||
copy.setCount(this.maxExtraction);
|
||||
BlockPos dest = tile.getAvailableDestination(copy, true);
|
||||
BlockPos dest = tile.getAvailableDestination(copy, true, this.preventOversending);
|
||||
if (dest == null)
|
||||
continue;
|
||||
// loop through locations to find a location that has the item
|
||||
|
@ -71,6 +73,11 @@ public class RetrievalModuleItem extends ModuleItem {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canNetworkSee(ItemStack module, PipeTileEntity tile) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack) {
|
||||
return false;
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
"item.prettypipes.low_retrieval_module": "Low Retrieval Module",
|
||||
"item.prettypipes.medium_retrieval_module": "Medium Retrieval Module",
|
||||
"item.prettypipes.high_retrieval_module": "High Retrieval Module",
|
||||
"info.prettypipes.extraction_module": "Pulls items from adjacent inventories\nFilters and pull rates vary by tier",
|
||||
"info.prettypipes.extraction_module": "Pulls items from adjacent inventories\nFilters and pull rates vary by tier\nHigh tiers prevent over-sending",
|
||||
"info.prettypipes.filter_module": "Restricts flow from pipes into adjacent inventories\nFilter amount varies by tier",
|
||||
"info.prettypipes.speed_module": "Increases speed of items exiting adjacent inventories\nSpeed varies by tier",
|
||||
"info.prettypipes.low_priority_module": "Decreases the reception priority of adjacent inventories\nLower priority means items will prefer other inventories",
|
||||
"info.prettypipes.retrieval_module": "Pulls items from other inventories in the network\nFilters and pull rates vary by tier",
|
||||
"info.prettypipes.retrieval_module": "Pulls items from other inventories in the network\nFilters and pull rates vary by tier\nHigh tiers prevent over-sending",
|
||||
"block.prettypipes.pipe": "Pipe",
|
||||
"itemGroup.prettypipes": "Pretty Pipes",
|
||||
"container.prettypipes.pipe": "Pipe",
|
||||
|
|
Loading…
Reference in a new issue