mirror of
https://github.com/Ellpeck/PrettyPipes.git
synced 2024-12-05 00:38:35 +01:00
fully deliver items of canceled crafting requests so that containers don't get stuck with partial recipes
This commit is contained in:
parent
704027c3dc
commit
2c8ab9ed07
5 changed files with 42 additions and 20 deletions
|
@ -277,7 +277,7 @@ public class PipeNetwork extends SavedData implements GraphListener<BlockPos, Ne
|
||||||
this.tileCache.remove(pos);
|
this.tileCache.remove(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Pair<BlockPos, ItemStack>> getCurrentlyCrafting(BlockPos node, ItemEquality... equalityTypes) {
|
public List<Pair<BlockPos, ItemStack>> getCurrentlyCrafting(BlockPos node, boolean includeCanceled, ItemEquality... equalityTypes) {
|
||||||
this.startProfile("get_currently_crafting");
|
this.startProfile("get_currently_crafting");
|
||||||
List<Pair<BlockPos, ItemStack>> items = new ArrayList<>();
|
List<Pair<BlockPos, ItemStack>> items = new ArrayList<>();
|
||||||
var craftingPipes = this.getAllCraftables(node).stream().map(c -> this.getPipe(c.getLeft())).distinct().iterator();
|
var craftingPipes = this.getAllCraftables(node).stream().map(c -> this.getPipe(c.getLeft())).distinct().iterator();
|
||||||
|
@ -285,6 +285,8 @@ public class PipeNetwork extends SavedData implements GraphListener<BlockPos, Ne
|
||||||
var pipe = craftingPipes.next();
|
var pipe = craftingPipes.next();
|
||||||
for (var craft : pipe.activeCrafts) {
|
for (var craft : pipe.activeCrafts) {
|
||||||
var data = craft.getRight();
|
var data = craft.getRight();
|
||||||
|
if (!includeCanceled && data.canceled)
|
||||||
|
continue;
|
||||||
// add up all the items that should go to the same location
|
// add up all the items that should go to the same location
|
||||||
var existing = items.stream()
|
var existing = items.stream()
|
||||||
.filter(s -> s.getLeft().equals(data.resultDestPipe) && ItemEquality.compareItems(s.getRight(), data.resultStackRemain, equalityTypes))
|
.filter(s -> s.getLeft().equals(data.resultDestPipe) && ItemEquality.compareItems(s.getRight(), data.resultStackRemain, equalityTypes))
|
||||||
|
@ -300,8 +302,8 @@ public class PipeNetwork extends SavedData implements GraphListener<BlockPos, Ne
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCurrentlyCraftingAmount(BlockPos destNode, ItemStack stack, ItemEquality... equalityTypes) {
|
public int getCurrentlyCraftingAmount(BlockPos destNode, ItemStack stack, boolean includeCanceled, ItemEquality... equalityTypes) {
|
||||||
return this.getCurrentlyCrafting(destNode).stream()
|
return this.getCurrentlyCrafting(destNode, includeCanceled).stream()
|
||||||
.filter(p -> p.getLeft().equals(destNode) && ItemEquality.compareItems(p.getRight(), stack, equalityTypes))
|
.filter(p -> p.getLeft().equals(destNode) && ItemEquality.compareItems(p.getRight(), stack, equalityTypes))
|
||||||
.mapToInt(p -> p.getRight().getCount()).sum();
|
.mapToInt(p -> p.getRight().getCount()).sum();
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,7 @@ public class CraftingModuleItem extends ModuleItem {
|
||||||
var requestRemain = network.requestExistingItem(lock.location, tile.getBlockPos(), dest.getLeft(), lock, dest.getRight(), equalityTypes);
|
var requestRemain = network.requestExistingItem(lock.location, tile.getBlockPos(), dest.getLeft(), lock, dest.getRight(), equalityTypes);
|
||||||
network.resolveNetworkLock(lock);
|
network.resolveNetworkLock(lock);
|
||||||
craftData.ingredientsToRequest.remove(lock);
|
craftData.ingredientsToRequest.remove(lock);
|
||||||
|
craftData.inProgress = true;
|
||||||
|
|
||||||
var traveling = lock.stack.copy();
|
var traveling = lock.stack.copy();
|
||||||
traveling.shrink(requestRemain.getCount());
|
traveling.shrink(requestRemain.getCount());
|
||||||
|
@ -222,10 +223,12 @@ public class CraftingModuleItem extends ModuleItem {
|
||||||
var slot = tile.getModuleSlot(module);
|
var slot = tile.getModuleSlot(module);
|
||||||
var equalityTypes = ItemFilter.getEqualityTypes(tile);
|
var equalityTypes = ItemFilter.getEqualityTypes(tile);
|
||||||
var matchingCraft = tile.activeCrafts.stream()
|
var matchingCraft = tile.activeCrafts.stream()
|
||||||
.filter(c -> c.getLeft() == slot && c.getRight().isMatchingIngredient(stack, equalityTypes))
|
.filter(c -> c.getLeft() == slot && !c.getRight().getTravelingIngredient(stack, equalityTypes).isEmpty())
|
||||||
.findAny().orElse(null);
|
.findAny().orElse(null);
|
||||||
if (matchingCraft != null) {
|
if (matchingCraft != null) {
|
||||||
matchingCraft.getRight().travelingIngredients.removeIf(s -> ItemEquality.compareItems(stack, s, equalityTypes));
|
var data = matchingCraft.getRight();
|
||||||
|
data.travelingIngredients.remove(data.getTravelingIngredient(stack, equalityTypes));
|
||||||
|
|
||||||
if (module.get(Contents.TYPE).insertSingles) {
|
if (module.get(Contents.TYPE).insertSingles) {
|
||||||
var handler = tile.getItemHandler(direction);
|
var handler = tile.getItemHandler(direction);
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
|
@ -237,6 +240,10 @@ public class CraftingModuleItem extends ModuleItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we canceled the request and all input items are delivered (ie the machine actually got what it expected), remove it from the queue
|
||||||
|
if (data.canceled && data.travelingIngredients.size() <= 0 && data.ingredientsToRequest.size() <= 0)
|
||||||
|
tile.activeCrafts.remove(matchingCraft);
|
||||||
}
|
}
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
@ -276,6 +283,9 @@ public class CraftingModuleItem extends ModuleItem {
|
||||||
public List<ItemStack> travelingIngredients;
|
public List<ItemStack> travelingIngredients;
|
||||||
public BlockPos resultDestPipe;
|
public BlockPos resultDestPipe;
|
||||||
public ItemStack resultStackRemain;
|
public ItemStack resultStackRemain;
|
||||||
|
public boolean inProgress;
|
||||||
|
// we only remove canceled requests from the queue once their items are fully delivered to the crafting location, so that unfinished recipes don't get stuck in crafters etc.
|
||||||
|
public boolean canceled;
|
||||||
|
|
||||||
public ActiveCraft(List<NetworkLock> ingredientsToRequest, List<ItemStack> travelingIngredients, BlockPos resultDestPipe, ItemStack resultStackRemain) {
|
public ActiveCraft(List<NetworkLock> ingredientsToRequest, List<ItemStack> travelingIngredients, BlockPos resultDestPipe, ItemStack resultStackRemain) {
|
||||||
this.ingredientsToRequest = ingredientsToRequest;
|
this.ingredientsToRequest = ingredientsToRequest;
|
||||||
|
@ -295,6 +305,8 @@ public class CraftingModuleItem extends ModuleItem {
|
||||||
ret.put("traveling_ingredients", Utility.serializeAll(this.travelingIngredients, s -> (CompoundTag) s.save(provider, new CompoundTag())));
|
ret.put("traveling_ingredients", Utility.serializeAll(this.travelingIngredients, s -> (CompoundTag) s.save(provider, new CompoundTag())));
|
||||||
ret.putLong("result_dest_pipe", this.resultDestPipe.asLong());
|
ret.putLong("result_dest_pipe", this.resultDestPipe.asLong());
|
||||||
ret.put("result_stack_remain", this.resultStackRemain.saveOptional(provider));
|
ret.put("result_stack_remain", this.resultStackRemain.saveOptional(provider));
|
||||||
|
ret.putBoolean("in_progress", this.inProgress);
|
||||||
|
ret.putBoolean("canceled", this.canceled);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,14 +316,16 @@ public class CraftingModuleItem extends ModuleItem {
|
||||||
this.travelingIngredients = Utility.deserializeAll(nbt.getList("traveling_ingredients", Tag.TAG_COMPOUND), t -> ItemStack.parse(provider, t).orElseThrow());
|
this.travelingIngredients = Utility.deserializeAll(nbt.getList("traveling_ingredients", Tag.TAG_COMPOUND), t -> ItemStack.parse(provider, t).orElseThrow());
|
||||||
this.resultDestPipe = BlockPos.of(nbt.getLong("result_dest_pipe"));
|
this.resultDestPipe = BlockPos.of(nbt.getLong("result_dest_pipe"));
|
||||||
this.resultStackRemain = ItemStack.parseOptional(provider, nbt.getCompound("result_stack_remain"));
|
this.resultStackRemain = ItemStack.parseOptional(provider, nbt.getCompound("result_stack_remain"));
|
||||||
|
this.inProgress = nbt.getBoolean("in_progress");
|
||||||
|
this.canceled = nbt.getBoolean("canceled");
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMatchingIngredient(ItemStack stack, ItemEquality... equalityTypes) {
|
public ItemStack getTravelingIngredient(ItemStack stack, ItemEquality... equalityTypes) {
|
||||||
for (var traveling : this.travelingIngredients) {
|
for (var traveling : this.travelingIngredients) {
|
||||||
if (ItemEquality.compareItems(stack, traveling, equalityTypes))
|
if (ItemEquality.compareItems(stack, traveling, equalityTypes))
|
||||||
return true;
|
return traveling;
|
||||||
}
|
}
|
||||||
return false;
|
return ItemStack.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class RetrievalModuleItem extends ModuleItem {
|
||||||
continue;
|
continue;
|
||||||
var remain = dest.getRight().copy();
|
var remain = dest.getRight().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, true, equalityTypes));
|
||||||
if (network.requestItem(tile.getBlockPos(), dest.getLeft(), remain, equalityTypes).isEmpty())
|
if (network.requestItem(tile.getBlockPos(), dest.getLeft(), remain, equalityTypes).isEmpty())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ public class ItemTerminalBlockEntity extends BlockEntity implements IPipeConnect
|
||||||
if (playersToSync.length > 0) {
|
if (playersToSync.length > 0) {
|
||||||
var clientItems = this.networkItems.values().stream().map(NetworkItem::asStack).collect(Collectors.toList());
|
var clientItems = this.networkItems.values().stream().map(NetworkItem::asStack).collect(Collectors.toList());
|
||||||
var clientCraftables = PipeNetwork.get(this.level).getAllCraftables(pipe.getBlockPos()).stream().map(Pair::getRight).collect(Collectors.toList());
|
var clientCraftables = PipeNetwork.get(this.level).getAllCraftables(pipe.getBlockPos()).stream().map(Pair::getRight).collect(Collectors.toList());
|
||||||
var currentlyCrafting = this.getCurrentlyCrafting().stream().sorted(Comparator.comparingInt(ItemStack::getCount).reversed()).collect(Collectors.toList());
|
var currentlyCrafting = this.getCurrentlyCrafting(false).stream().sorted(Comparator.comparingInt(ItemStack::getCount).reversed()).collect(Collectors.toList());
|
||||||
for (var player : playersToSync) {
|
for (var player : playersToSync) {
|
||||||
if (!(player.containerMenu instanceof ItemTerminalContainer container))
|
if (!(player.containerMenu instanceof ItemTerminalContainer container))
|
||||||
continue;
|
continue;
|
||||||
|
@ -200,12 +200,12 @@ public class ItemTerminalBlockEntity extends BlockEntity implements IPipeConnect
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ItemStack> getCurrentlyCrafting() {
|
private List<ItemStack> getCurrentlyCrafting(boolean includeCanceled) {
|
||||||
var network = PipeNetwork.get(this.level);
|
var network = PipeNetwork.get(this.level);
|
||||||
var pipe = this.getConnectedPipe();
|
var pipe = this.getConnectedPipe();
|
||||||
if (pipe == null)
|
if (pipe == null)
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
var crafting = network.getCurrentlyCrafting(pipe.getBlockPos());
|
var crafting = network.getCurrentlyCrafting(pipe.getBlockPos(), includeCanceled);
|
||||||
return crafting.stream().map(Pair::getRight).collect(Collectors.toList());
|
return crafting.stream().map(Pair::getRight).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,11 +217,17 @@ public class ItemTerminalBlockEntity extends BlockEntity implements IPipeConnect
|
||||||
for (var craftable : network.getAllCraftables(pipe.getBlockPos())) {
|
for (var craftable : network.getAllCraftables(pipe.getBlockPos())) {
|
||||||
var otherPipe = network.getPipe(craftable.getLeft());
|
var otherPipe = network.getPipe(craftable.getLeft());
|
||||||
if (otherPipe != null) {
|
if (otherPipe != null) {
|
||||||
for (var craft : otherPipe.activeCrafts) {
|
otherPipe.activeCrafts.removeIf(c -> {
|
||||||
for (var lock : craft.getRight().ingredientsToRequest)
|
var data = c.getRight();
|
||||||
|
if (data.inProgress) {
|
||||||
|
data.canceled = true;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
for (var lock : data.ingredientsToRequest)
|
||||||
network.resolveNetworkLock(lock);
|
network.resolveNetworkLock(lock);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
otherPipe.activeCrafts.clear();
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var lookingPlayers = this.getLookingPlayers();
|
var lookingPlayers = this.getLookingPlayers();
|
||||||
|
|
|
@ -68,10 +68,10 @@
|
||||||
"info.prettypipes.blacklist.description": "Items in filter slots are disallowed",
|
"info.prettypipes.blacklist.description": "Items in filter slots are disallowed",
|
||||||
"info.prettypipes.insert_singles_on": "\u00A72S",
|
"info.prettypipes.insert_singles_on": "\u00A72S",
|
||||||
"info.prettypipes.insert_singles_off": "\u00A74\u00A7mS",
|
"info.prettypipes.insert_singles_off": "\u00A74\u00A7mS",
|
||||||
"info.prettypipes.insert_singles.description": "Whether items should be inserted one at a time, rather than as a stack\nRecommended for use with the Crafter",
|
"info.prettypipes.insert_singles.description": "Whether items should be inserted one at a time, rather than as a stack\n\u00A7oRecommended for use with the Crafter",
|
||||||
"info.prettypipes.ensure_item_order_on": "\u00A72O",
|
"info.prettypipes.ensure_item_order_on": "\u00A72O",
|
||||||
"info.prettypipes.ensure_item_order_off": "\u00A74\u00A7mO",
|
"info.prettypipes.ensure_item_order_off": "\u00A74\u00A7mO",
|
||||||
"info.prettypipes.ensure_item_order.description": "Whether the module should wait for items to be inserted in the order they appear in the input slots\nRecommended for use with the Crafter",
|
"info.prettypipes.ensure_item_order.description": "Whether the module should wait for items to be inserted in the order they appear in the input slots\n\u00A7oRecommended for use with the Crafter",
|
||||||
"info.prettypipes.shift": "Hold Shift for info",
|
"info.prettypipes.shift": "Hold Shift for info",
|
||||||
"info.prettypipes.populate": "P",
|
"info.prettypipes.populate": "P",
|
||||||
"info.prettypipes.populate.description": "Populate filter slots with items from adjacent inventories",
|
"info.prettypipes.populate.description": "Populate filter slots with items from adjacent inventories",
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
"info.prettypipes.energy": "%s / %s FE",
|
"info.prettypipes.energy": "%s / %s FE",
|
||||||
"info.prettypipes.crafting": "Awaiting",
|
"info.prettypipes.crafting": "Awaiting",
|
||||||
"info.prettypipes.cancel_all": "Cancel",
|
"info.prettypipes.cancel_all": "Cancel",
|
||||||
"info.prettypipes.cancel_all.desc": "Stops waiting for current crafting outputs\nDoesn't remove inputs from blocks",
|
"info.prettypipes.cancel_all.desc": "Stops waiting for current crafting outputs\nOngoing crafting operations are still completed",
|
||||||
"info.prettypipes.no_pipe_connected": "The terminal needs to be connected to a pipe network",
|
"info.prettypipes.no_pipe_connected": "The terminal needs to be connected to a pipe network",
|
||||||
"info.prettypipes.too_many_pipes_connected": "The terminal can only be connected to a single pipe at a time",
|
"info.prettypipes.too_many_pipes_connected": "The terminal can only be connected to a single pipe at a time",
|
||||||
"dir.prettypipes.up": "Up",
|
"dir.prettypipes.up": "Up",
|
||||||
|
|
Loading…
Reference in a new issue