made crafting modules only request and deliver their own items

This commit is contained in:
Ell 2024-09-27 16:29:27 +02:00
parent 3fbcd8c80a
commit c7f43c3500
5 changed files with 79 additions and 43 deletions

View file

@ -284,7 +284,7 @@ public class PipeNetwork extends SavedData implements GraphListener<BlockPos, Ne
while (craftingPipes.hasNext()) { while (craftingPipes.hasNext()) {
var pipe = craftingPipes.next(); var pipe = craftingPipes.next();
for (var request : pipe.craftResultRequests) { for (var request : pipe.craftResultRequests) {
var dest = request.getLeft(); var dest = request.getMiddle();
var stack = request.getRight(); var stack = request.getRight();
// 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()

View file

@ -271,7 +271,7 @@ public class PipeBlock extends BaseEntityBlock implements SimpleWaterloggedBlock
if (worldIn.getBlockEntity(pos) instanceof PipeBlockEntity pipe) { if (worldIn.getBlockEntity(pos) instanceof PipeBlockEntity pipe) {
pipe.getItems().clear(); pipe.getItems().clear();
for (var lock : pipe.craftIngredientRequests) for (var lock : pipe.craftIngredientRequests)
network.resolveNetworkLock(lock); network.resolveNetworkLock(lock.getRight());
} }
super.onRemove(state, worldIn, pos, newState, isMoving); super.onRemove(state, worldIn, pos, newState, isMoving);
} }

View file

@ -4,6 +4,7 @@ import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.Registry; import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.Utility; import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.items.IModule; import de.ellpeck.prettypipes.items.IModule;
import de.ellpeck.prettypipes.misc.EquatableItemStack;
import de.ellpeck.prettypipes.misc.ItemFilter; import de.ellpeck.prettypipes.misc.ItemFilter;
import de.ellpeck.prettypipes.network.NetworkLock; import de.ellpeck.prettypipes.network.NetworkLock;
import de.ellpeck.prettypipes.network.PipeNetwork; import de.ellpeck.prettypipes.network.PipeNetwork;
@ -40,6 +41,7 @@ import net.neoforged.neoforge.common.util.Lazy;
import net.neoforged.neoforge.items.IItemHandler; import net.neoforged.neoforge.items.IItemHandler;
import net.neoforged.neoforge.items.ItemStackHandler; import net.neoforged.neoforge.items.ItemStackHandler;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -69,8 +71,10 @@ public class PipeBlockEntity extends BlockEntity implements MenuProvider, IPipeC
PipeBlockEntity.this.setChanged(); PipeBlockEntity.this.setChanged();
} }
}; };
public final Queue<NetworkLock> craftIngredientRequests = new LinkedList<>(); // crafting module slot, ingredient request network lock
public final List<Pair<BlockPos, ItemStack>> craftResultRequests = new ArrayList<>(); public final Queue<Pair<Integer, NetworkLock>> craftIngredientRequests = new LinkedList<>();
// crafting module slot, destination pipe for the result, result item
public final List<Triple<Integer, BlockPos, ItemStack>> craftResultRequests = new ArrayList<>();
public PressurizerBlockEntity pressurizer; public PressurizerBlockEntity pressurizer;
public BlockState cover; public BlockState cover;
public int moduleDropCheck; public int moduleDropCheck;
@ -97,13 +101,21 @@ public class PipeBlockEntity extends BlockEntity implements MenuProvider, IPipeC
super.saveAdditional(compound, provider); super.saveAdditional(compound, provider);
compound.put("modules", this.modules.serializeNBT(provider)); compound.put("modules", this.modules.serializeNBT(provider));
compound.putInt("module_drop_check", this.moduleDropCheck); compound.putInt("module_drop_check", this.moduleDropCheck);
compound.put("requests", Utility.serializeAll(provider, this.craftIngredientRequests)); var requests = new ListTag();
for (var tuple : this.craftIngredientRequests) {
var nbt = new CompoundTag();
nbt.putInt("module_slot", tuple.getLeft());
nbt.put("lock", tuple.getRight().serializeNBT(provider));
requests.add(nbt);
}
compound.put("craft_requests", requests);
if (this.cover != null) if (this.cover != null)
compound.put("cover", NbtUtils.writeBlockState(this.cover)); compound.put("cover", NbtUtils.writeBlockState(this.cover));
var results = new ListTag(); var results = new ListTag();
for (var triple : this.craftResultRequests) { for (var triple : this.craftResultRequests) {
var nbt = new CompoundTag(); var nbt = new CompoundTag();
nbt.putLong("dest_pipe", triple.getLeft().asLong()); nbt.putInt("module_slot", triple.getLeft());
nbt.putLong("dest_pipe", triple.getMiddle().asLong());
nbt.put("item", triple.getRight().save(provider)); nbt.put("item", triple.getRight().save(provider));
results.add(nbt); results.add(nbt);
} }
@ -116,12 +128,19 @@ public class PipeBlockEntity extends BlockEntity implements MenuProvider, IPipeC
this.moduleDropCheck = compound.getInt("module_drop_check"); this.moduleDropCheck = compound.getInt("module_drop_check");
this.cover = compound.contains("cover") ? NbtUtils.readBlockState(this.level != null ? this.level.holderLookup(Registries.BLOCK) : BuiltInRegistries.BLOCK.asLookup(), compound.getCompound("cover")) : null; this.cover = compound.contains("cover") ? NbtUtils.readBlockState(this.level != null ? this.level.holderLookup(Registries.BLOCK) : BuiltInRegistries.BLOCK.asLookup(), compound.getCompound("cover")) : null;
this.craftIngredientRequests.clear(); this.craftIngredientRequests.clear();
this.craftIngredientRequests.addAll(Utility.deserializeAll(compound.getList("requests", Tag.TAG_COMPOUND), l -> new NetworkLock(provider, l))); var requests = compound.getList("craft_requests", Tag.TAG_COMPOUND);
for (var i = 0; i < requests.size(); i++) {
var nbt = requests.getCompound(i);
this.craftIngredientRequests.add(Pair.of(
nbt.getInt("module_slot"),
new NetworkLock(provider, nbt.getCompound("lock"))));
}
this.craftResultRequests.clear(); this.craftResultRequests.clear();
var results = compound.getList("craft_results", Tag.TAG_COMPOUND); var results = compound.getList("craft_results", Tag.TAG_COMPOUND);
for (var i = 0; i < results.size(); i++) { for (var i = 0; i < results.size(); i++) {
var nbt = results.getCompound(i); var nbt = results.getCompound(i);
this.craftResultRequests.add(Pair.of( this.craftResultRequests.add(Triple.of(
nbt.getInt("module_slot"),
BlockPos.of(nbt.getLong("dest_pipe")), BlockPos.of(nbt.getLong("dest_pipe")),
ItemStack.parseOptional(provider, nbt.getCompound("item")))); ItemStack.parseOptional(provider, nbt.getCompound("item"))));
} }
@ -359,6 +378,14 @@ public class PipeBlockEntity extends BlockEntity implements MenuProvider, IPipeC
return builder.build(); return builder.build();
} }
public int getModuleSlot(ItemStack module) {
for (var i = 0; i < this.modules.getSlots(); i++) {
if (this.modules.getStackInSlot(i) == module)
return i;
}
return -1;
}
public void removeCover(Player player, InteractionHand hand) { public void removeCover(Player player, InteractionHand hand) {
if (this.level.isClientSide) if (this.level.isClientSide)
return; return;

View file

@ -25,6 +25,7 @@ import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.items.IItemHandler; import net.neoforged.neoforge.items.IItemHandler;
import net.neoforged.neoforge.items.ItemStackHandler; import net.neoforged.neoforge.items.ItemStackHandler;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -69,25 +70,29 @@ public class CraftingModuleItem 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 slot = tile.getModuleSlot(module);
var network = PipeNetwork.get(tile.getLevel()); var network = PipeNetwork.get(tile.getLevel());
// process crafting ingredient requests // process crafting ingredient requests
if (!tile.craftIngredientRequests.isEmpty()) { if (!tile.craftIngredientRequests.isEmpty()) {
network.startProfile("crafting_ingredients"); network.startProfile("crafting_ingredients");
var request = tile.craftIngredientRequests.peek(); var request = tile.craftIngredientRequests.peek();
var equalityTypes = ItemFilter.getEqualityTypes(tile); if (request.getLeft() == slot) {
var dest = tile.getAvailableDestination(Direction.values(), request.stack, true, true); var lock = request.getRight();
if (dest != null) { var equalityTypes = ItemFilter.getEqualityTypes(tile);
var requestRemain = network.requestExistingItem(request.location, tile.getBlockPos(), dest.getLeft(), request, dest.getRight(), equalityTypes); var dest = tile.getAvailableDestination(Direction.values(), lock.stack, true, true);
network.resolveNetworkLock(request); if (dest != null) {
tile.craftIngredientRequests.remove(); var requestRemain = network.requestExistingItem(lock.location, tile.getBlockPos(), dest.getLeft(), lock, dest.getRight(), equalityTypes);
network.resolveNetworkLock(lock);
tile.craftIngredientRequests.remove();
// if we couldn't fit all items into the destination, create another request for the rest // if we couldn't fit all items into the destination, create another request for the rest
var remain = request.stack.copy(); var remain = lock.stack.copy();
remain.shrink(dest.getRight().getCount() - requestRemain.getCount()); remain.shrink(dest.getRight().getCount() - requestRemain.getCount());
if (!remain.isEmpty()) { if (!remain.isEmpty()) {
var remainRequest = new NetworkLock(request.location, remain); var remainRequest = new NetworkLock(lock.location, remain);
tile.craftIngredientRequests.add(remainRequest); tile.craftIngredientRequests.add(Pair.of(slot, remainRequest));
network.createNetworkLock(remainRequest); network.createNetworkLock(remainRequest);
}
} }
} }
network.endProfile(); network.endProfile();
@ -98,25 +103,27 @@ public class CraftingModuleItem extends ModuleItem {
var items = network.getOrderedNetworkItems(tile.getBlockPos()); var items = network.getOrderedNetworkItems(tile.getBlockPos());
var equalityTypes = ItemFilter.getEqualityTypes(tile); var equalityTypes = ItemFilter.getEqualityTypes(tile);
for (var request : tile.craftResultRequests) { for (var request : tile.craftResultRequests) {
var remain = request.getRight().copy(); if (request.getLeft() == slot) {
var destPipe = network.getPipe(request.getLeft()); var remain = request.getRight().copy();
if (destPipe != null) { var destPipe = network.getPipe(request.getMiddle());
var dest = destPipe.getAvailableDestinationOrConnectable(remain, true, true); if (destPipe != null) {
if (dest == null) var dest = destPipe.getAvailableDestinationOrConnectable(remain, true, true);
continue; if (dest == null)
for (var item : items) { continue;
var requestRemain = network.requestExistingItem(item, request.getLeft(), dest.getLeft(), null, dest.getRight(), equalityTypes); for (var item : items) {
remain.shrink(dest.getRight().getCount() - requestRemain.getCount()); var requestRemain = network.requestExistingItem(item, request.getMiddle(), dest.getLeft(), null, dest.getRight(), equalityTypes);
if (remain.isEmpty()) remain.shrink(dest.getRight().getCount() - requestRemain.getCount());
break; if (remain.isEmpty())
} break;
if (remain.getCount() != request.getRight().getCount()) { }
tile.craftResultRequests.remove(request); if (remain.getCount() != request.getRight().getCount()) {
// if we couldn't pull everything, log a new request tile.craftResultRequests.remove(request);
if (!remain.isEmpty()) // if we couldn't pull everything, log a new request
tile.craftResultRequests.add(Pair.of(request.getLeft(), remain)); if (!remain.isEmpty())
network.endProfile(); tile.craftResultRequests.add(Triple.of(slot, request.getMiddle(), remain));
return; network.endProfile();
return;
}
} }
} }
} }
@ -162,6 +169,7 @@ public class CraftingModuleItem extends ModuleItem {
var craftableAmount = this.getCraftableAmount(module, tile, unavailableConsumer, stack, dependencyChain); var craftableAmount = this.getCraftableAmount(module, tile, unavailableConsumer, stack, dependencyChain);
if (craftableAmount <= 0) if (craftableAmount <= 0)
return stack; return stack;
var slot = tile.getModuleSlot(module);
var network = PipeNetwork.get(tile.getLevel()); var network = PipeNetwork.get(tile.getLevel());
var items = network.getOrderedNetworkItems(tile.getBlockPos()); var items = network.getOrderedNetworkItems(tile.getBlockPos());
@ -181,7 +189,8 @@ public class CraftingModuleItem extends ModuleItem {
var copy = in.copy(); var copy = in.copy();
copy.setCount(in.getCount() * toCraft); copy.setCount(in.getCount() * toCraft);
var ret = ItemTerminalBlockEntity.requestItemLater(tile.getLevel(), tile.getBlockPos(), items, unavailableConsumer, copy, CraftingModuleItem.addDependency(dependencyChain, module), equalityTypes); var ret = ItemTerminalBlockEntity.requestItemLater(tile.getLevel(), tile.getBlockPos(), items, unavailableConsumer, copy, CraftingModuleItem.addDependency(dependencyChain, module), equalityTypes);
tile.craftIngredientRequests.addAll(ret.getLeft()); for (var lock : ret.getLeft())
tile.craftIngredientRequests.add(Pair.of(slot, lock));
} }
var remain = stack.copy(); var remain = stack.copy();
@ -189,7 +198,7 @@ public class CraftingModuleItem extends ModuleItem {
var result = stack.copy(); var result = stack.copy();
result.shrink(remain.getCount()); result.shrink(remain.getCount());
tile.craftResultRequests.add(Pair.of(destPipe, result)); tile.craftResultRequests.add(Triple.of(slot, destPipe, result));
return remain; return remain;
} }

View file

@ -218,7 +218,7 @@ public class ItemTerminalBlockEntity extends BlockEntity implements IPipeConnect
var otherPipe = network.getPipe(craftable.getLeft()); var otherPipe = network.getPipe(craftable.getLeft());
if (otherPipe != null) { if (otherPipe != null) {
for (var lock : otherPipe.craftIngredientRequests) for (var lock : otherPipe.craftIngredientRequests)
network.resolveNetworkLock(lock); network.resolveNetworkLock(lock.getRight());
otherPipe.craftIngredientRequests.clear(); otherPipe.craftIngredientRequests.clear();
otherPipe.craftResultRequests.clear(); otherPipe.craftResultRequests.clear();
} }