Skip to content

Commit

Permalink
pass active crafts when started
Browse files Browse the repository at this point in the history
  • Loading branch information
Ellpeck committed Nov 28, 2024
1 parent 805393b commit 0eb8740
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 129 deletions.
5 changes: 4 additions & 1 deletion src/main/java/de/ellpeck/prettypipes/items/IModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import de.ellpeck.prettypipes.misc.DirectionSelector;
import de.ellpeck.prettypipes.misc.ItemFilter;
import de.ellpeck.prettypipes.network.ActiveCraft;
import de.ellpeck.prettypipes.pipe.PipeBlockEntity;
import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer;
import net.minecraft.core.BlockPos;
Expand All @@ -10,7 +11,9 @@
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.items.IItemHandler;
import org.apache.commons.lang3.tuple.Pair;

import java.util.Collection;
import java.util.List;
import java.util.Stack;
import java.util.function.Consumer;
Expand Down Expand Up @@ -41,7 +44,7 @@ public interface IModule {

int getCraftableAmount(ItemStack module, PipeBlockEntity tile, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain);

ItemStack craft(ItemStack module, PipeBlockEntity tile, BlockPos destPipe, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain);
Pair<ItemStack, Collection<ActiveCraft>> craft(ItemStack module, PipeBlockEntity tile, BlockPos destPipe, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain);

Integer getCustomNextNode(ItemStack module, PipeBlockEntity tile, List<BlockPos> nodes, int index);

Expand Down
7 changes: 5 additions & 2 deletions src/main/java/de/ellpeck/prettypipes/items/ModuleItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.misc.DirectionSelector;
import de.ellpeck.prettypipes.misc.ItemFilter;
import de.ellpeck.prettypipes.network.ActiveCraft;
import de.ellpeck.prettypipes.pipe.PipeBlockEntity;
import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer;
import net.minecraft.core.BlockPos;
Expand All @@ -16,7 +17,9 @@
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.items.IItemHandler;
import org.apache.commons.lang3.tuple.Pair;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Stack;
Expand Down Expand Up @@ -89,8 +92,8 @@ public int getCraftableAmount(ItemStack module, PipeBlockEntity tile, Consumer<I
}

@Override
public ItemStack craft(ItemStack module, PipeBlockEntity tile, BlockPos destPipe, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain) {
return stack;
public Pair<ItemStack, Collection<ActiveCraft>> craft(ItemStack module, PipeBlockEntity tile, BlockPos destPipe, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain) {
return Pair.of(stack, List.of());
}

@Override
Expand Down
77 changes: 77 additions & 0 deletions src/main/java/de/ellpeck/prettypipes/network/ActiveCraft.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package de.ellpeck.prettypipes.network;

import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.misc.ItemEquality;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.common.util.INBTSerializable;
import org.jetbrains.annotations.UnknownNullability;

import java.util.ArrayList;
import java.util.List;

public class ActiveCraft implements INBTSerializable<CompoundTag> {

public List<ItemStack> travelingIngredients = new ArrayList<>();
public List<NetworkLock> ingredientsToRequest;
public BlockPos resultDestPipe;
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, BlockPos resultDestPipe, ItemStack resultStackRemain) {
this.ingredientsToRequest = ingredientsToRequest;
this.resultDestPipe = resultDestPipe;
this.resultStackRemain = resultStackRemain;
}

public ActiveCraft(HolderLookup.Provider provider, CompoundTag tag) {
this.deserializeNBT(provider, tag);
}

@Override
public @UnknownNullability CompoundTag serializeNBT(HolderLookup.Provider provider) {
var ret = new CompoundTag();
ret.put("ingredients_to_request", Utility.serializeAll(this.ingredientsToRequest, n -> n.serializeNBT(provider)));
ret.put("traveling_ingredients", Utility.serializeAll(this.travelingIngredients, s -> (CompoundTag) s.save(provider, new CompoundTag())));
ret.putLong("result_dest_pipe", this.resultDestPipe.asLong());
ret.put("result_stack_remain", this.resultStackRemain.saveOptional(provider));
ret.putBoolean("in_progress", this.inProgress);
ret.putBoolean("canceled", this.canceled);
return ret;
}

@Override
public void deserializeNBT(HolderLookup.Provider provider, CompoundTag nbt) {
this.ingredientsToRequest = Utility.deserializeAll(nbt.getList("ingredients_to_request", Tag.TAG_COMPOUND), t -> new NetworkLock(provider, t));
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.resultStackRemain = ItemStack.parseOptional(provider, nbt.getCompound("result_stack_remain"));
this.inProgress = nbt.getBoolean("in_progress");
this.canceled = nbt.getBoolean("canceled");
}

public ItemStack getTravelingIngredient(ItemStack stack, ItemEquality... equalityTypes) {
for (var traveling : this.travelingIngredients) {
if (ItemEquality.compareItems(stack, traveling, equalityTypes))
return traveling;
}
return ItemStack.EMPTY;
}

public boolean markCanceledOrResolve(PipeNetwork network) {
if (this.inProgress) {
this.canceled = true;
return false;
} else {
for (var lock : this.ingredientsToRequest)
network.resolveNetworkLock(lock);
return true;
}
}

}
46 changes: 42 additions & 4 deletions src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import net.neoforged.neoforge.items.IItemHandler;
import net.neoforged.neoforge.network.PacketDistributor;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import org.jgrapht.ListenableGraph;
import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
import org.jgrapht.event.GraphEdgeChangeEvent;
Expand Down Expand Up @@ -213,21 +214,58 @@ public ItemStack requestItem(BlockPos destPipe, BlockPos destInventory, ItemStac
return remain;
}
// check craftable items
return this.requestCraftedItem(destPipe, null, remain, new Stack<>(), equalityTypes);
return this.requestCraftedItem(destPipe, null, remain, new Stack<>(), equalityTypes).getLeft();
}

public ItemStack requestCraftedItem(BlockPos destPipe, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain, ItemEquality... equalityTypes) {
public Triple<List<NetworkLock>, ItemStack, Collection<ActiveCraft>> requestLocksAndCrafts(BlockPos destPipe, Collection<NetworkLocation> locations, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain, ItemEquality... equalityTypes) {
List<NetworkLock> requests = new ArrayList<>();
var remain = stack.copy();
// check for existing items
for (var location : locations) {
var amount = location.getItemAmount(this.level, stack, equalityTypes);
if (amount <= 0)
continue;
amount -= this.getLockedAmount(location.getPos(), stack, null, equalityTypes);
if (amount > 0) {
if (remain.getCount() < amount)
amount = remain.getCount();
remain.shrink(amount);
while (amount > 0) {
var copy = stack.copy();
copy.setCount(Math.min(stack.getMaxStackSize(), amount));
var lock = new NetworkLock(location, copy);
this.createNetworkLock(lock);
requests.add(lock);
amount -= copy.getCount();
}
if (remain.isEmpty())
break;
}
}
if (!remain.isEmpty()) {
// check for craftable items
var started = this.requestCraftedItem(destPipe, unavailableConsumer, remain, dependencyChain, equalityTypes);
return Triple.of(requests, started.getLeft(), started.getRight());
} else {
return Triple.of(requests, remain, List.of());
}
}

public Pair<ItemStack, Collection<ActiveCraft>> requestCraftedItem(BlockPos destPipe, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain, ItemEquality... equalityTypes) {
var crafts = new ArrayList<ActiveCraft>();
for (var craftable : this.getAllCraftables(destPipe)) {
if (!ItemEquality.compareItems(stack, craftable.getRight(), equalityTypes))
continue;
var pipe = this.getPipe(craftable.getLeft());
if (pipe == null)
continue;
stack = pipe.craft(destPipe, unavailableConsumer, stack, dependencyChain);
var started = pipe.craft(destPipe, unavailableConsumer, stack, dependencyChain);
stack = started.getLeft();
crafts.addAll(started.getRight());
if (stack.isEmpty())
break;
}
return stack;
return Pair.of(stack, crafts);
}

public ItemStack requestExistingItem(NetworkLocation location, BlockPos destPipe, BlockPos destInventory, NetworkLock ignoredLock, ItemStack stack, ItemEquality... equalityTypes) {
Expand Down
17 changes: 9 additions & 8 deletions src/main/java/de/ellpeck/prettypipes/pipe/PipeBlockEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.items.IModule;
import de.ellpeck.prettypipes.misc.ItemFilter;
import de.ellpeck.prettypipes.network.NetworkLock;
import de.ellpeck.prettypipes.network.ActiveCraft;
import de.ellpeck.prettypipes.network.PipeNetwork;
import de.ellpeck.prettypipes.pipe.containers.MainPipeContainer;
import de.ellpeck.prettypipes.pipe.modules.craft.CraftingModuleItem;
import de.ellpeck.prettypipes.pressurizer.PressurizerBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
Expand Down Expand Up @@ -42,7 +41,6 @@
import net.neoforged.neoforge.items.ItemHandlerHelper;
import net.neoforged.neoforge.items.ItemStackHandler;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -72,7 +70,7 @@ protected void onContentsChanged(int slot) {
PipeBlockEntity.this.setChanged();
}
};
public final List<Pair<Integer, CraftingModuleItem.ActiveCraft>> activeCrafts = new ArrayList<>();
public final List<Pair<Integer, ActiveCraft>> activeCrafts = new ArrayList<>();
public PressurizerBlockEntity pressurizer;
public BlockState cover;
public int moduleDropCheck;
Expand Down Expand Up @@ -120,7 +118,7 @@ public void loadAdditional(CompoundTag compound, HolderLookup.Provider provider)
var crafts = compound.getList("active_crafts", Tag.TAG_COMPOUND);
for (var i = 0; i < crafts.size(); i++) {
var tag = crafts.getCompound(i);
this.activeCrafts.add(Pair.of(tag.getInt("module_slot"), new CraftingModuleItem.ActiveCraft(provider, tag.getCompound("data"))));
this.activeCrafts.add(Pair.of(tag.getInt("module_slot"), new ActiveCraft(provider, tag.getCompound("data"))));
}
super.loadAdditional(compound, provider);
}
Expand Down Expand Up @@ -296,15 +294,18 @@ public int getCraftableAmount(Consumer<ItemStack> unavailableConsumer, ItemStack
return total;
}

public ItemStack craft(BlockPos destPipe, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain) {
public Pair<ItemStack, Collection<ActiveCraft>> craft(BlockPos destPipe, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain) {
var crafts = new ArrayList<ActiveCraft>();
var modules = this.streamModules().iterator();
while (modules.hasNext()) {
var module = modules.next();
stack = module.getRight().craft(module.getLeft(), this, destPipe, unavailableConsumer, stack, dependencyChain);
var started = module.getRight().craft(module.getLeft(), this, destPipe, unavailableConsumer, stack, dependencyChain);
stack = started.getLeft();
crafts.addAll(started.getRight());
if (stack.isEmpty())
break;
}
return stack;
return Pair.of(stack, crafts);
}

public IItemHandler getItemHandler(Direction dir) {
Expand Down
Loading

0 comments on commit 0eb8740

Please sign in to comment.