Compare commits

..

No commits in common. "c1ccdd848604c288868488a0f8348098f8f487d6" and "1b061759e13b1e4cb3408cecc666ea841652b720" have entirely different histories.

9 changed files with 117 additions and 107 deletions

View file

@ -13,7 +13,7 @@ apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'eclipse' apply plugin: 'eclipse'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
version = '1.12.5' version = '1.12.4'
group = 'de.ellpeck.prettypipes' // http://maven.apache.org/guides/mini/guide-naming-conventions.html group = 'de.ellpeck.prettypipes' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = 'PrettyPipes' archivesBaseName = 'PrettyPipes'

View file

@ -13,13 +13,9 @@ import net.minecraft.world.item.ItemStack;
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.client.gui.widget.ExtendedButton; import net.minecraftforge.client.gui.widget.ExtendedButton;
import org.apache.commons.lang3.ArrayUtils;
public class DirectionSelector { public class DirectionSelector {
private static final Direction[] ALL = ArrayUtils.addAll(Direction.values(), (Direction) null);
// null means old behavior, which is all directions
private Direction direction; private Direction direction;
private boolean modified; private boolean modified;
@ -39,8 +35,8 @@ public class DirectionSelector {
@Override @Override
public Component getMessage() { public Component getMessage() {
var pipe = DirectionSelector.this.pipe; var pipe = DirectionSelector.this.pipe;
var dir = DirectionSelector.this.direction; var dir = DirectionSelector.this.getDirection();
MutableComponent msg = new TranslatableComponent("dir." + PrettyPipes.ID + "." + (dir != null ? dir.getName() : "all")); MutableComponent msg = new TranslatableComponent("dir." + PrettyPipes.ID + "." + (dir != null ? dir.getName() : "none"));
if (dir != null) { if (dir != null) {
var blockName = pipe.getItemHandler(dir) != null ? pipe.getLevel().getBlockState(pipe.getBlockPos().relative(dir)).getBlock().getName() : null; var blockName = pipe.getItemHandler(dir) != null ? pipe.getLevel().getBlockState(pipe.getBlockPos().relative(dir)).getBlock().getName() : null;
if (blockName != null) if (blockName != null)
@ -52,10 +48,7 @@ public class DirectionSelector {
} }
public void onButtonPacket() { public void onButtonPacket() {
var dir = this.direction; var dir = this.getValidDirection(this.getDirection());
do {
dir = DirectionSelector.ALL[(ArrayUtils.indexOf(DirectionSelector.ALL, dir) + 1) % DirectionSelector.ALL.length];
} while (!this.isDirectionValid(dir));
if (this.direction != dir) { if (this.direction != dir) {
this.direction = dir; this.direction = dir;
this.modified = true; this.modified = true;
@ -68,8 +61,9 @@ public class DirectionSelector {
this.modified = false; this.modified = false;
var tag = new CompoundTag(); var tag = new CompoundTag();
if (this.direction != null) var dir = this.getDirection();
tag.putString("direction", this.direction.getName()); if (dir != null)
tag.putString("direction", dir.getName());
this.stack.getOrCreateTag().put("direction_selector", tag); this.stack.getOrCreateTag().put("direction_selector", tag);
} }
@ -80,25 +74,34 @@ public class DirectionSelector {
} }
} }
public Direction[] directions() { public Direction getDirection() {
return this.direction != null ? new Direction[]{this.direction} : Direction.values(); // default to the first direction with a container if ours is invalid or unset
} if (this.direction == null || !this.isDirectionValid(this.direction))
return this.getValidDirection(this.direction);
public boolean has(Direction dir) { return this.direction;
return this.direction == null || this.direction == dir;
} }
private boolean isDirectionValid(Direction dir) { private boolean isDirectionValid(Direction dir) {
if (dir == null)
return true;
if (this.pipe.getItemHandler(dir) == null) if (this.pipe.getItemHandler(dir) == null)
return false; return false;
return this.pipe.streamModules() return this.pipe.streamModules()
.filter(p -> p.getLeft() != this.stack) .filter(p -> p.getLeft() != this.stack)
.map(p -> p.getRight().getDirectionSelector(p.getLeft(), this.pipe)) .map(p -> p.getRight().getDirectionSelector(p.getLeft(), this.pipe))
// don't use getDirection here because we don't want a stack overflow
.noneMatch(p -> p != null && p.direction == dir); .noneMatch(p -> p != null && p.direction == dir);
} }
private Direction getValidDirection(Direction dir) {
if (dir == null)
dir = Direction.UP;
for (var i = 0; i < 6; i++) {
dir = Direction.from3DDataValue(dir.get3DDataValue() + 1);
if (this.isDirectionValid(dir))
return dir;
}
return null;
}
public interface IDirectionContainer { public interface IDirectionContainer {
DirectionSelector getSelector(); DirectionSelector getSelector();

View file

@ -147,7 +147,7 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundTag>, GraphL
if (!this.world.isLoaded(pipePos)) if (!this.world.isLoaded(pipePos))
continue; continue;
var pipe = this.getPipe(pipePos); var pipe = this.getPipe(pipePos);
var dest = pipe.getAvailableDestination(Direction.values(), stack, false, preventOversending); var dest = pipe.getAvailableDestination(stack, false, preventOversending);
if (dest == null || dest.getLeft().equals(startInventory)) if (dest == null || dest.getLeft().equals(startInventory))
continue; continue;
var sup = (Function<Float, IPipeItem>) speed -> itemSupplier.apply(dest.getRight(), speed); var sup = (Function<Float, IPipeItem>) speed -> itemSupplier.apply(dest.getRight(), speed);

View file

@ -167,7 +167,7 @@ public class PipeBlockEntity extends BlockEntity implements MenuProvider, IPipeC
} }
public Pair<BlockPos, ItemStack> getAvailableDestinationOrConnectable(ItemStack stack, boolean force, boolean preventOversending) { public Pair<BlockPos, ItemStack> getAvailableDestinationOrConnectable(ItemStack stack, boolean force, boolean preventOversending) {
var dest = this.getAvailableDestination(Direction.values(), stack, force, preventOversending); var dest = this.getAvailableDestination(stack, force, preventOversending);
if (dest != null) if (dest != null)
return dest; return dest;
// if there's no available destination, try inserting into terminals etc. // if there's no available destination, try inserting into terminals etc.
@ -185,66 +185,69 @@ public class PipeBlockEntity extends BlockEntity implements MenuProvider, IPipeC
return null; return null;
} }
public Pair<BlockPos, ItemStack> getAvailableDestination(Direction[] directions, ItemStack stack, boolean force, boolean preventOversending) { public Pair<BlockPos, ItemStack> getAvailableDestination(ItemStack stack, boolean force, boolean preventOversending) {
if (!this.canWork()) for (var dir : Direction.values()) {
return null; var dest = this.getAvailableDestination(dir, stack, force, preventOversending);
for (var dir : directions) { if (!dest.isEmpty())
var handler = this.getItemHandler(dir); return Pair.of(this.worldPosition.relative(dir), dest);
if (handler == null)
continue;
if (!force && this.streamModules().anyMatch(m -> !m.getRight().canAcceptItem(m.getLeft(), this, stack, dir, handler)))
continue;
var remain = ItemHandlerHelper.insertItem(handler, stack, true);
// did we insert anything?
if (remain.getCount() == stack.getCount())
continue;
var toInsert = stack.copy();
toInsert.shrink(remain.getCount());
// limit to the max amount that modules allow us to insert
var maxAmount = this.streamModules().mapToInt(m -> m.getRight().getMaxInsertionAmount(m.getLeft(), this, stack, handler)).min().orElse(Integer.MAX_VALUE);
if (maxAmount < toInsert.getCount())
toInsert.setCount(maxAmount);
var offset = this.worldPosition.relative(dir);
if (preventOversending || maxAmount < Integer.MAX_VALUE) {
var network = PipeNetwork.get(this.level);
// these are the items that are currently in the pipes, going to this inventory
var onTheWay = network.getItemsOnTheWay(offset, null);
if (onTheWay > 0) {
if (maxAmount < Integer.MAX_VALUE) {
// these are the items on the way, limited to items of the same type as stack
var onTheWaySame = network.getItemsOnTheWay(offset, stack);
// check if any modules are limiting us
if (toInsert.getCount() + onTheWaySame > maxAmount)
toInsert.setCount(maxAmount - onTheWaySame);
}
// totalSpace will be the amount of items that fit into the attached container
var totalSpace = 0;
for (var i = 0; i < handler.getSlots(); i++) {
var copy = stack.copy();
var maxStackSize = copy.getMaxStackSize();
// if the container can store more than 64 items in this slot, then it's likely
// a barrel or similar, meaning that the slot limit matters more than the max stack size
var limit = handler.getSlotLimit(i);
if (limit > 64)
maxStackSize = limit;
copy.setCount(maxStackSize);
// 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
var left = handler.insertItem(i, copy, true);
totalSpace += maxStackSize - left.getCount();
}
// 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);
}
}
// we return the item that can actually be inserted, NOT the remainder!
if (!toInsert.isEmpty())
return Pair.of(offset, toInsert);
} }
return null; return null;
} }
public ItemStack getAvailableDestination(Direction direction, ItemStack stack, boolean force, boolean preventOversending) {
if (!this.canWork())
return ItemStack.EMPTY;
var handler = this.getItemHandler(direction);
if (handler == null || !force && this.streamModules().anyMatch(m -> !m.getRight().canAcceptItem(m.getLeft(), this, stack, direction, handler)))
return ItemStack.EMPTY;
var remain = ItemHandlerHelper.insertItem(handler, stack, true);
// did we insert anything?
if (remain.getCount() == stack.getCount())
return ItemStack.EMPTY;
var toInsert = stack.copy();
toInsert.shrink(remain.getCount());
// limit to the max amount that modules allow us to insert
var maxAmount = this.streamModules().mapToInt(m -> m.getRight().getMaxInsertionAmount(m.getLeft(), this, stack, handler)).min().orElse(Integer.MAX_VALUE);
if (maxAmount < toInsert.getCount())
toInsert.setCount(maxAmount);
var offset = this.worldPosition.relative(direction);
if (preventOversending || maxAmount < Integer.MAX_VALUE) {
var network = PipeNetwork.get(this.level);
// these are the items that are currently in the pipes, going to this inventory
var onTheWay = network.getItemsOnTheWay(offset, null);
if (onTheWay > 0) {
if (maxAmount < Integer.MAX_VALUE) {
// these are the items on the way, limited to items of the same type as stack
var onTheWaySame = network.getItemsOnTheWay(offset, stack);
// check if any modules are limiting us
if (toInsert.getCount() + onTheWaySame > maxAmount)
toInsert.setCount(maxAmount - onTheWaySame);
}
// totalSpace will be the amount of items that fit into the attached container
var totalSpace = 0;
for (var i = 0; i < handler.getSlots(); i++) {
var copy = stack.copy();
var maxStackSize = copy.getMaxStackSize();
// if the container can store more than 64 items in this slot, then it's likely
// a barrel or similar, meaning that the slot limit matters more than the max stack size
var limit = handler.getSlotLimit(i);
if (limit > 64)
maxStackSize = limit;
copy.setCount(maxStackSize);
// 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
var left = handler.insertItem(i, copy, true);
totalSpace += maxStackSize - left.getCount();
}
// 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);
}
}
// we return the item that can actually be inserted, NOT the remainder!
return toInsert;
}
public int getPriority() { public int getPriority() {
return this.priority; return this.priority;
} }

View file

@ -75,7 +75,7 @@ public class CraftingModuleItem extends ModuleItem {
network.startProfile("crafting_ingredients"); network.startProfile("crafting_ingredients");
var request = tile.craftIngredientRequests.peek(); var request = tile.craftIngredientRequests.peek();
var equalityTypes = ItemFilter.getEqualityTypes(tile); var equalityTypes = ItemFilter.getEqualityTypes(tile);
var dest = tile.getAvailableDestination(Direction.values(), request.stack, true, true); var dest = tile.getAvailableDestination(request.stack, true, true);
if (dest != null) { if (dest != null) {
var requestRemain = network.requestExistingItem(request.location, tile.getBlockPos(), dest.getLeft(), request, dest.getRight(), equalityTypes); var requestRemain = network.requestExistingItem(request.location, tile.getBlockPos(), dest.getLeft(), request, dest.getRight(), equalityTypes);
network.resolveNetworkLock(request); network.resolveNetworkLock(request);

View file

@ -35,35 +35,36 @@ public class ExtractionModuleItem extends ModuleItem {
if (!tile.shouldWorkNow(this.speed) || !tile.canWork()) if (!tile.shouldWorkNow(this.speed) || !tile.canWork())
return; return;
var filter = this.getItemFilter(module, tile); var filter = this.getItemFilter(module, tile);
var dirSelector = this.getDirectionSelector(module, tile); var dir = this.getDirectionSelector(module, tile).getDirection();
for (var dir : dirSelector.directions()) { if (dir == null)
var handler = tile.getItemHandler(dir); return;
if (handler == null) var handler = tile.getItemHandler(dir);
if (handler == null)
return;
var network = PipeNetwork.get(tile.getLevel());
for (var j = 0; j < handler.getSlots(); j++) {
var stack = handler.extractItem(j, this.maxExtraction, true);
if (stack.isEmpty())
continue; continue;
var network = PipeNetwork.get(tile.getLevel()); if (!filter.isAllowed(stack))
for (var j = 0; j < handler.getSlots(); j++) { continue;
var stack = handler.extractItem(j, this.maxExtraction, true); var remain = network.routeItem(tile.getBlockPos(), tile.getBlockPos().relative(dir), stack, this.preventOversending);
if (stack.isEmpty()) if (remain.getCount() != stack.getCount()) {
continue; handler.extractItem(j, stack.getCount() - remain.getCount(), false);
if (!filter.isAllowed(stack)) return;
continue;
var remain = network.routeItem(tile.getBlockPos(), tile.getBlockPos().relative(dir), stack, this.preventOversending);
if (remain.getCount() != stack.getCount()) {
handler.extractItem(j, stack.getCount() - remain.getCount(), false);
return;
}
} }
} }
} }
@Override @Override
public boolean canNetworkSee(ItemStack module, PipeBlockEntity tile, Direction direction, IItemHandler handler) { public boolean canNetworkSee(ItemStack module, PipeBlockEntity tile, Direction direction, IItemHandler handler) {
return !this.getDirectionSelector(module, tile).has(direction); return direction != this.getDirectionSelector(module, tile).getDirection();
} }
@Override @Override
public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack, Direction direction, IItemHandler destination) { public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack, Direction direction, IItemHandler destination) {
return !this.getDirectionSelector(module, tile).has(direction); return direction != this.getDirectionSelector(module, tile).getDirection();
} }
@Override @Override

View file

@ -27,7 +27,7 @@ public class FilterModuleItem extends ModuleItem {
@Override @Override
public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack, Direction direction, IItemHandler destination) { public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack, Direction direction, IItemHandler destination) {
return !this.getDirectionSelector(module, tile).has(direction) || this.getItemFilter(module, tile).isAllowed(stack); return this.getDirectionSelector(module, tile).getDirection() != direction || this.getItemFilter(module, tile).isAllowed(stack);
} }
@Override @Override

View file

@ -34,7 +34,10 @@ public class RetrievalModuleItem extends ModuleItem {
public void tick(ItemStack module, PipeBlockEntity tile) { public void tick(ItemStack module, PipeBlockEntity tile) {
if (!tile.shouldWorkNow(this.speed) || !tile.canWork()) if (!tile.shouldWorkNow(this.speed) || !tile.canWork())
return; return;
var directions = this.getDirectionSelector(module, tile).directions(); var dir = this.getDirectionSelector(module, tile).getDirection();
if (dir == null)
return;
var network = PipeNetwork.get(tile.getLevel()); var network = PipeNetwork.get(tile.getLevel());
var equalityTypes = ItemFilter.getEqualityTypes(tile); var equalityTypes = ItemFilter.getEqualityTypes(tile);
// loop through filters to see which items to pull // loop through filters to see which items to pull
@ -45,13 +48,13 @@ public class RetrievalModuleItem extends ModuleItem {
continue; continue;
var copy = filtered.copy(); var copy = filtered.copy();
copy.setCount(this.maxExtraction); copy.setCount(this.maxExtraction);
var dest = tile.getAvailableDestination(directions, copy, true, this.preventOversending); var dest = tile.getAvailableDestination(dir, copy, true, this.preventOversending);
if (dest.getRight().isEmpty()) if (dest.isEmpty())
continue; continue;
var remain = dest.getRight().copy(); var remain = dest.copy();
// are we already waiting for crafting results? If so, don't request those again // are we already waiting for crafting results? If so, don't request those again
remain.shrink(network.getCurrentlyCraftingAmount(tile.getBlockPos(), copy, equalityTypes)); remain.shrink(network.getCurrentlyCraftingAmount(tile.getBlockPos(), copy, equalityTypes));
if (network.requestItem(tile.getBlockPos(), dest.getLeft(), remain, equalityTypes).isEmpty()) if (network.requestItem(tile.getBlockPos(), tile.getBlockPos().relative(dir), remain, equalityTypes).isEmpty())
break; break;
} }
} }
@ -59,12 +62,12 @@ public class RetrievalModuleItem extends ModuleItem {
@Override @Override
public boolean canNetworkSee(ItemStack module, PipeBlockEntity tile, Direction direction, IItemHandler handler) { public boolean canNetworkSee(ItemStack module, PipeBlockEntity tile, Direction direction, IItemHandler handler) {
return !this.getDirectionSelector(module, tile).has(direction); return direction != this.getDirectionSelector(module, tile).getDirection();
} }
@Override @Override
public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack, Direction direction, IItemHandler destination) { public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack, Direction direction, IItemHandler destination) {
return !this.getDirectionSelector(module, tile).has(direction); return direction != this.getDirectionSelector(module, tile).getDirection();
} }
@Override @Override

View file

@ -97,5 +97,5 @@
"dir.prettypipes.east": "East", "dir.prettypipes.east": "East",
"dir.prettypipes.south": "South", "dir.prettypipes.south": "South",
"dir.prettypipes.west": "West", "dir.prettypipes.west": "West",
"dir.prettypipes.all": "All Sides" "dir.prettypipes.none": "No Side Valid"
} }