Skip to content

Commit c28100a

Browse files
committed
allow other crafts to happen while a craft is waiting to be able to insert its result items
1 parent b2630a1 commit c28100a

File tree

2 files changed

+71
-42
lines changed

2 files changed

+71
-42
lines changed

src/main/java/de/ellpeck/prettypipes/network/ActiveCraft.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public class ActiveCraft implements INBTSerializable<CompoundTag> {
2222
public BlockPos resultDestPipe;
2323
public ItemStack resultStackRemain;
2424
public boolean inProgress;
25+
public boolean resultFound;
2526
// 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.
2627
public boolean canceled;
2728

@@ -48,6 +49,7 @@ public ActiveCraft(HolderLookup.Provider provider, CompoundTag tag) {
4849
ret.putLong("result_dest_pipe", this.resultDestPipe.asLong());
4950
ret.put("result_stack_remain", this.resultStackRemain.saveOptional(provider));
5051
ret.putBoolean("in_progress", this.inProgress);
52+
ret.putBoolean("result_found", this.resultFound);
5153
ret.putBoolean("canceled", this.canceled);
5254
return ret;
5355
}
@@ -61,6 +63,7 @@ public void deserializeNBT(HolderLookup.Provider provider, CompoundTag nbt) {
6163
this.resultDestPipe = BlockPos.of(nbt.getLong("result_dest_pipe"));
6264
this.resultStackRemain = ItemStack.parseOptional(provider, nbt.getCompound("result_stack_remain"));
6365
this.inProgress = nbt.getBoolean("in_progress");
66+
this.resultFound = nbt.getBoolean("result_found");
6467
this.canceled = nbt.getBoolean("canceled");
6568
}
6669

@@ -74,6 +77,7 @@ public String toString() {
7477
", resultDestPipe=" + this.resultDestPipe +
7578
", resultStackRemain=" + this.resultStackRemain +
7679
", inProgress=" + this.inProgress +
80+
", resultFound=" + this.resultFound +
7781
", canceled=" + this.canceled + '}';
7882
}
7983

src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleItem.java

Lines changed: 67 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -70,54 +70,79 @@ public void tick(ItemStack module, PipeBlockEntity tile) {
7070
return;
7171
var slot = tile.getModuleSlot(module);
7272
var network = PipeNetwork.get(tile.getLevel());
73-
var crafts = tile.getActiveCrafts();
74-
if (!crafts.isEmpty()) {
75-
var craft = crafts.getFirst();
76-
if (craft.moduleSlot == slot) {
73+
var foundMainCraft = false;
74+
var crafts = tile.getActiveCrafts().iterator();
75+
while (crafts.hasNext()) {
76+
var craft = crafts.next();
77+
78+
// handle main crafting, which only one recipe (in the whole pipe!) should be able to do at a time so that items between recipes don't mix
79+
if (!foundMainCraft) {
80+
// process crafting ingredient requests
7781
if (!craft.ingredientsToRequest.isEmpty()) {
78-
// process crafting ingredient requests
79-
network.startProfile("crafting_ingredients");
80-
var lock = craft.ingredientsToRequest.getFirst();
81-
var equalityTypes = ItemFilter.getEqualityTypes(tile);
82-
var dest = tile.getAvailableDestination(Direction.values(), lock.stack, true, true);
83-
if (dest != null) {
84-
// if we're ensuring the correct item order and the item is already on the way, don't do anything yet
85-
if (!module.get(Contents.TYPE).ensureItemOrder || network.getPipeItemsOnTheWay(dest.getLeft()).findAny().isEmpty()) {
86-
network.requestExistingItem(lock.location, tile.getBlockPos(), dest.getLeft(), lock, dest.getRight(), equalityTypes);
87-
network.resolveNetworkLock(lock);
88-
craft.ingredientsToRequest.remove(lock);
89-
craft.travelingIngredients.add(lock.stack.copy());
90-
craft.inProgress = true;
91-
}
92-
}
93-
network.endProfile();
94-
} else if (craft.travelingIngredients.isEmpty()) {
95-
if (craft.resultStackRemain.isEmpty()) {
96-
// the result stack is empty from the start if this was a partial craft whose results shouldn't be delivered anywhere
97-
// (ie someone requested 3 sticks with ensureItemOrder, but the recipe always makes 4, so the 4th recipe has no destination)
98-
crafts.remove(craft);
99-
} else {
100-
// pull requested crafting results from the network once they are stored
101-
network.startProfile("crafting_results");
102-
var items = network.getOrderedNetworkItems(tile.getBlockPos());
82+
if (craft.moduleSlot == slot) {
83+
network.startProfile("crafting_ingredients");
84+
var lock = craft.ingredientsToRequest.getFirst();
10385
var equalityTypes = ItemFilter.getEqualityTypes(tile);
104-
var destPipe = network.getPipe(craft.resultDestPipe);
105-
if (destPipe != null) {
106-
var dest = destPipe.getAvailableDestinationOrConnectable(craft.resultStackRemain, true, true);
107-
if (dest != null) {
108-
for (var item : items) {
109-
var requestRemain = network.requestExistingItem(item, craft.resultDestPipe, dest.getLeft(), null, dest.getRight(), equalityTypes);
110-
craft.resultStackRemain.shrink(dest.getRight().getCount() - requestRemain.getCount());
111-
if (craft.resultStackRemain.isEmpty()) {
112-
crafts.remove(craft);
113-
break;
114-
}
115-
}
86+
var dest = tile.getAvailableDestination(Direction.values(), lock.stack, true, true);
87+
if (dest != null) {
88+
// if we're ensuring the correct item order and the item is already on the way, don't do anything yet
89+
if (!module.get(Contents.TYPE).ensureItemOrder || craft.travelingIngredients.isEmpty()) {
90+
network.requestExistingItem(lock.location, tile.getBlockPos(), dest.getLeft(), lock, dest.getRight(), equalityTypes);
91+
network.resolveNetworkLock(lock);
92+
craft.ingredientsToRequest.remove(lock);
93+
craft.travelingIngredients.add(lock.stack.copy());
94+
craft.inProgress = true;
11695
}
11796
}
11897
network.endProfile();
11998
}
99+
foundMainCraft = true;
100+
} else if (!craft.resultFound && craft.travelingIngredients.isEmpty()) {
101+
if (craft.moduleSlot == slot) {
102+
// check whether the crafting results have arrived in storage
103+
if (craft.resultStackRemain.isEmpty()) {
104+
// the result stack is empty from the start if this was a partial craft whose results shouldn't be delivered anywhere
105+
// (ie someone requested 3 sticks with ensureItemOrder, but the recipe always makes 4, so the 4th recipe has no destination)
106+
crafts.remove();
107+
} else {
108+
// check if the result is in storage
109+
var items = network.getOrderedNetworkItems(tile.getBlockPos());
110+
var equalityTypes = ItemFilter.getEqualityTypes(tile);
111+
network.startProfile("check_crafting_results");
112+
var remain = craft.resultStackRemain.copy();
113+
for (var item : items) {
114+
remain.shrink(item.getItemAmount(tile.getLevel(), remain, equalityTypes) - network.getLockedAmount(item.getPos(), remain, null, equalityTypes));
115+
if (remain.isEmpty())
116+
break;
117+
}
118+
craft.resultFound = remain.isEmpty();
119+
network.endProfile();
120+
}
121+
}
122+
foundMainCraft = true;
123+
}
124+
}
125+
126+
// pull requested crafting results from the network once they are stored
127+
if (craft.resultFound && craft.moduleSlot == slot) {
128+
var items = network.getOrderedNetworkItems(tile.getBlockPos());
129+
var equalityTypes = ItemFilter.getEqualityTypes(tile);
130+
network.startProfile("pull_crafting_results");
131+
var destPipe = network.getPipe(craft.resultDestPipe);
132+
if (destPipe != null) {
133+
var dest = destPipe.getAvailableDestinationOrConnectable(craft.resultStackRemain, true, true);
134+
if (dest != null) {
135+
for (var item : items) {
136+
var requestRemain = network.requestExistingItem(item, craft.resultDestPipe, dest.getLeft(), null, dest.getRight(), equalityTypes);
137+
craft.resultStackRemain.shrink(dest.getRight().getCount() - requestRemain.getCount());
138+
if (craft.resultStackRemain.isEmpty()) {
139+
crafts.remove();
140+
break;
141+
}
142+
}
143+
}
120144
}
145+
network.endProfile();
121146
}
122147
}
123148
}
@@ -234,7 +259,7 @@ public ItemStack store(ItemStack module, PipeBlockEntity tile, ItemStack stack,
234259
}
235260
}
236261

237-
if (craft.travelingIngredients.isEmpty() && craft.ingredientsToRequest.isEmpty()) {
262+
if (craft.ingredientsToRequest.isEmpty() && craft.travelingIngredients.isEmpty()) {
238263
if (contents.emitRedstone) {
239264
tile.redstoneTicks = 5;
240265
tile.getLevel().updateNeighborsAt(tile.getBlockPos(), tile.getBlockState().getBlock());

0 commit comments

Comments
 (0)