mirror of
https://github.com/Ellpeck/PrettyPipes.git
synced 2024-11-22 19:58:35 +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);
|
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);
|
int getPriority(ItemStack module, PipeTileEntity tile);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ import net.minecraft.util.text.*;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -48,12 +47,12 @@ public abstract class ModuleItem extends Item implements IModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack) {
|
public boolean canNetworkSee(ItemStack module, PipeTileEntity tile) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAvailableDestination(ItemStack module, PipeTileEntity tile, ItemStack stack, IItemHandler destination) {
|
public boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,18 +14,29 @@ import java.util.Map;
|
||||||
public class NetworkLocation {
|
public class NetworkLocation {
|
||||||
|
|
||||||
public final BlockPos pipePos;
|
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.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) {
|
public Pair<Direction, Integer> getStackLocation(ItemStack stack) {
|
||||||
|
if (this.isEmpty())
|
||||||
|
return null;
|
||||||
for (Map.Entry<Direction, Pair<Integer, ItemStack>> entry : this.items.entries()) {
|
for (Map.Entry<Direction, Pair<Integer, ItemStack>> entry : this.items.entries()) {
|
||||||
if (entry.getValue().getRight().isItemEqual(stack))
|
if (entry.getValue().getRight().isItemEqual(stack))
|
||||||
return Pair.of(entry.getKey(), entry.getValue().getLeft());
|
return Pair.of(entry.getKey(), entry.getValue().getLeft());
|
||||||
}
|
}
|
||||||
return null;
|
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);
|
return this.path.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BlockPos getDestPipe() {
|
public BlockPos getDestPipe() {
|
||||||
return this.path.get(this.path.size() - 1);
|
return this.path.get(this.path.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ import javax.annotation.Nullable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphListener<BlockPos, NetworkEdge> {
|
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));
|
this.refreshNode(edge.endPipe, this.world.getBlockState(edge.endPipe));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean tryInsertItem(BlockPos startPipePos, BlockPos startInventory, ItemStack stack) {
|
public boolean tryInsertItem(BlockPos startPipePos, BlockPos startInventory, ItemStack stack, boolean preventOversending) {
|
||||||
return this.routeItem(startPipePos, startInventory, stack, speed -> new PipeItem(stack, speed));
|
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))
|
if (!this.isNode(startPipePos))
|
||||||
return false;
|
return false;
|
||||||
if (!this.world.isBlockLoaded(startPipePos))
|
if (!this.world.isBlockLoaded(startPipePos))
|
||||||
|
@ -133,7 +134,7 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
|
||||||
this.startProfile("find_destination");
|
this.startProfile("find_destination");
|
||||||
for (BlockPos pipePos : this.getOrderedDestinations(startPipePos)) {
|
for (BlockPos pipePos : this.getOrderedDestinations(startPipePos)) {
|
||||||
PipeTileEntity pipe = this.getPipe(pipePos);
|
PipeTileEntity pipe = this.getPipe(pipePos);
|
||||||
BlockPos dest = pipe.getAvailableDestination(stack, false);
|
BlockPos dest = pipe.getAvailableDestination(stack, false, preventOversending);
|
||||||
if (dest != null) {
|
if (dest != null) {
|
||||||
this.endProfile();
|
this.endProfile();
|
||||||
return this.routeItemToLocation(startPipePos, startInventory, pipe.getPos(), dest, itemSupplier);
|
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");
|
this.startProfile("get_network_items");
|
||||||
List<NetworkLocation> info = new ArrayList<>();
|
List<NetworkLocation> info = new ArrayList<>();
|
||||||
for (BlockPos dest : this.getOrderedDestinations(node)) {
|
for (BlockPos dest : this.getOrderedDestinations(node)) {
|
||||||
|
NetworkLocation location = new NetworkLocation(dest);
|
||||||
PipeTileEntity pipe = this.getPipe(dest);
|
PipeTileEntity pipe = this.getPipe(dest);
|
||||||
|
if (!pipe.canNetworkSee())
|
||||||
|
continue;
|
||||||
for (Direction dir : Direction.values()) {
|
for (Direction dir : Direction.values()) {
|
||||||
IItemHandler handler = pipe.getItemHandler(dir);
|
IItemHandler handler = pipe.getItemHandler(dir);
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
continue;
|
continue;
|
||||||
ListMultimap<Direction, Pair<Integer, ItemStack>> items = null;
|
|
||||||
for (int i = 0; i < handler.getSlots(); i++) {
|
for (int i = 0; i < handler.getSlots(); i++) {
|
||||||
ItemStack found = handler.extractItem(i, Integer.MAX_VALUE, true);
|
ItemStack found = handler.extractItem(i, Integer.MAX_VALUE, true);
|
||||||
if (found.isEmpty())
|
if (found.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
if (items == null)
|
location.addItem(dir, i, found);
|
||||||
items = ArrayListMultimap.create();
|
|
||||||
items.put(dir, Pair.of(i, found));
|
|
||||||
}
|
}
|
||||||
if (items != null)
|
|
||||||
info.add(new NetworkLocation(dest, items));
|
|
||||||
}
|
}
|
||||||
|
if (!location.isEmpty())
|
||||||
|
info.add(location);
|
||||||
}
|
}
|
||||||
this.endProfile();
|
this.endProfile();
|
||||||
return info;
|
return info;
|
||||||
|
@ -299,6 +300,19 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
|
||||||
return this.pipeItems.get(pos);
|
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
|
@Override
|
||||||
public void edgeAdded(GraphEdgeChangeEvent<BlockPos, NetworkEdge> e) {
|
public void edgeAdded(GraphEdgeChangeEvent<BlockPos, NetworkEdge> e) {
|
||||||
this.clearDestinationCache(e.getEdgeSource(), e.getEdgeTarget());
|
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();
|
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)))
|
if (!internal && this.streamModules().anyMatch(m -> !m.getRight().canAcceptItem(m.getLeft(), this, stack)))
|
||||||
return null;
|
return null;
|
||||||
for (Direction dir : Direction.values()) {
|
for (Direction dir : Direction.values()) {
|
||||||
|
@ -133,8 +133,23 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
||||||
continue;
|
continue;
|
||||||
if (!ItemHandlerHelper.insertItem(handler, stack, true).isEmpty())
|
if (!ItemHandlerHelper.insertItem(handler, stack, true).isEmpty())
|
||||||
continue;
|
continue;
|
||||||
if (this.streamModules().anyMatch(m -> !m.getRight().isAvailableDestination(m.getLeft(), this, stack, handler)))
|
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;
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
return this.pos.offset(dir);
|
return this.pos.offset(dir);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -166,6 +181,10 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
||||||
return Arrays.stream(Direction.values()).anyMatch(this::isConnectedInventory);
|
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() {
|
private Stream<Pair<ItemStack, IModule>> streamModules() {
|
||||||
Stream.Builder<Pair<ItemStack, IModule>> builder = Stream.builder();
|
Stream.Builder<Pair<ItemStack, IModule>> builder = Stream.builder();
|
||||||
for (int i = 0; i < this.modules.getSlots(); i++) {
|
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 maxExtraction;
|
||||||
private final int speed;
|
private final int speed;
|
||||||
|
private final boolean preventOversending;
|
||||||
public final int filterSlots;
|
public final int filterSlots;
|
||||||
|
|
||||||
public ExtractionModuleItem(String name, ModuleTier tier) {
|
public ExtractionModuleItem(String name, ModuleTier tier) {
|
||||||
|
@ -25,6 +26,7 @@ public class ExtractionModuleItem extends ModuleItem {
|
||||||
this.maxExtraction = tier.forTier(1, 8, 64);
|
this.maxExtraction = tier.forTier(1, 8, 64);
|
||||||
this.speed = tier.forTier(20, 15, 10);
|
this.speed = tier.forTier(20, 15, 10);
|
||||||
this.filterSlots = tier.forTier(3, 6, 9);
|
this.filterSlots = tier.forTier(3, 6, 9);
|
||||||
|
this.preventOversending = tier.forTier(false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -44,7 +46,7 @@ public class ExtractionModuleItem extends ModuleItem {
|
||||||
continue;
|
continue;
|
||||||
if (!filter.isAllowed(stack))
|
if (!filter.isAllowed(stack))
|
||||||
continue;
|
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);
|
handler.extractItem(j, this.maxExtraction, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -52,6 +54,11 @@ public class ExtractionModuleItem extends ModuleItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canNetworkSee(ItemStack module, PipeTileEntity tile) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack) {
|
public boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.List;
|
||||||
public class RetrievalModuleItem extends ModuleItem {
|
public class RetrievalModuleItem extends ModuleItem {
|
||||||
private final int maxExtraction;
|
private final int maxExtraction;
|
||||||
private final int speed;
|
private final int speed;
|
||||||
|
private final boolean preventOversending;
|
||||||
public final int filterSlots;
|
public final int filterSlots;
|
||||||
|
|
||||||
public RetrievalModuleItem(String name, ModuleTier tier) {
|
public RetrievalModuleItem(String name, ModuleTier tier) {
|
||||||
|
@ -30,6 +31,7 @@ public class RetrievalModuleItem extends ModuleItem {
|
||||||
this.maxExtraction = tier.forTier(1, 8, 16);
|
this.maxExtraction = tier.forTier(1, 8, 16);
|
||||||
this.speed = tier.forTier(40, 20, 10);
|
this.speed = tier.forTier(40, 20, 10);
|
||||||
this.filterSlots = tier.forTier(3, 6, 9);
|
this.filterSlots = tier.forTier(3, 6, 9);
|
||||||
|
this.preventOversending = tier.forTier(false, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -48,7 +50,7 @@ public class RetrievalModuleItem extends ModuleItem {
|
||||||
continue;
|
continue;
|
||||||
ItemStack copy = filtered.copy();
|
ItemStack copy = filtered.copy();
|
||||||
copy.setCount(this.maxExtraction);
|
copy.setCount(this.maxExtraction);
|
||||||
BlockPos dest = tile.getAvailableDestination(copy, true);
|
BlockPos dest = tile.getAvailableDestination(copy, true, this.preventOversending);
|
||||||
if (dest == null)
|
if (dest == null)
|
||||||
continue;
|
continue;
|
||||||
// loop through locations to find a location that has the item
|
// 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
|
@Override
|
||||||
public boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack) {
|
public boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -15,11 +15,11 @@
|
||||||
"item.prettypipes.low_retrieval_module": "Low Retrieval Module",
|
"item.prettypipes.low_retrieval_module": "Low Retrieval Module",
|
||||||
"item.prettypipes.medium_retrieval_module": "Medium Retrieval Module",
|
"item.prettypipes.medium_retrieval_module": "Medium Retrieval Module",
|
||||||
"item.prettypipes.high_retrieval_module": "High 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.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.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.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",
|
"block.prettypipes.pipe": "Pipe",
|
||||||
"itemGroup.prettypipes": "Pretty Pipes",
|
"itemGroup.prettypipes": "Pretty Pipes",
|
||||||
"container.prettypipes.pipe": "Pipe",
|
"container.prettypipes.pipe": "Pipe",
|
||||||
|
|
Loading…
Reference in a new issue