mirror of
https://github.com/Ellpeck/PrettyPipes.git
synced 2024-11-22 19:58:35 +01:00
fixed all the bugs!
This commit is contained in:
parent
57c3b13b64
commit
87d983611e
11 changed files with 174 additions and 84 deletions
|
@ -33,7 +33,7 @@ public interface IModule {
|
||||||
|
|
||||||
boolean canPipeWork(ItemStack module, PipeTileEntity tile);
|
boolean canPipeWork(ItemStack module, PipeTileEntity tile);
|
||||||
|
|
||||||
List<ItemStack> getCraftables(ItemStack module, PipeTileEntity tile);
|
List<ItemStack> getCraftables(ItemStack module, PipeTileEntity tile, boolean onlyReturnPossible);
|
||||||
|
|
||||||
ItemStack craft(ItemStack module, PipeTileEntity tile, BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes);
|
ItemStack craft(ItemStack module, PipeTileEntity tile, BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ public abstract class ModuleItem extends Item implements IModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ItemStack> getCraftables(ItemStack module, PipeTileEntity tile) {
|
public List<ItemStack> getCraftables(ItemStack module, PipeTileEntity tile, boolean onlyReturnPossible) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ public class ItemFilter extends ItemStackHandler {
|
||||||
// populate filter from inventories
|
// populate filter from inventories
|
||||||
List<ItemFilter> filters = this.getAllFilters();
|
List<ItemFilter> filters = this.getAllFilters();
|
||||||
for (Direction direction : Direction.values()) {
|
for (Direction direction : Direction.values()) {
|
||||||
IItemHandler handler = this.pipe.getItemHandler(direction, null);
|
IItemHandler handler = this.pipe.getItemHandler(direction);
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
continue;
|
continue;
|
||||||
for (int i = 0; i < handler.getSlots(); i++) {
|
for (int i = 0; i < handler.getSlots(); i++) {
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class NetworkLocation implements INBTSerializable<CompoundNBT> {
|
||||||
if (this.handlerCache == null) {
|
if (this.handlerCache == null) {
|
||||||
PipeNetwork network = PipeNetwork.get(world);
|
PipeNetwork network = PipeNetwork.get(world);
|
||||||
PipeTileEntity pipe = network.getPipe(this.pipePos);
|
PipeTileEntity pipe = network.getPipe(this.pipePos);
|
||||||
this.handlerCache = pipe.getItemHandler(this.direction, null);
|
this.handlerCache = pipe.getItemHandler(this.direction);
|
||||||
}
|
}
|
||||||
return this.handlerCache;
|
return this.handlerCache;
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,7 +189,7 @@ public class PipeItem implements INBTSerializable<CompoundNBT>, ILiquidContainer
|
||||||
IPipeConnectable connectable = currPipe.getPipeConnectable(dir);
|
IPipeConnectable connectable = currPipe.getPipeConnectable(dir);
|
||||||
if (connectable != null)
|
if (connectable != null)
|
||||||
return connectable.insertItem(currPipe.getWorld(), currPipe.getPos(), dir, this);
|
return connectable.insertItem(currPipe.getWorld(), currPipe.getPos(), dir, this);
|
||||||
IItemHandler handler = currPipe.getItemHandler(dir, this);
|
IItemHandler handler = currPipe.getItemHandler(dir);
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
return ItemHandlerHelper.insertItemStacked(handler, this.stack, false);
|
return ItemHandlerHelper.insertItemStacked(handler, this.stack, false);
|
||||||
return this.stack;
|
return this.stack;
|
||||||
|
|
|
@ -185,16 +185,29 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack requestItem(BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes) {
|
public ItemStack requestItem(BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes) {
|
||||||
List<NetworkLocation> locations = this.getOrderedNetworkItems(destPipe);
|
|
||||||
if (locations.isEmpty())
|
|
||||||
return stack;
|
|
||||||
ItemStack remain = stack.copy();
|
ItemStack remain = stack.copy();
|
||||||
for (NetworkLocation location : locations) {
|
// check existing items
|
||||||
|
for (NetworkLocation location : this.getOrderedNetworkItems(destPipe)) {
|
||||||
remain = this.requestExistingItem(location, destPipe, destInventory, remain, equalityTypes);
|
remain = this.requestExistingItem(location, destPipe, destInventory, remain, equalityTypes);
|
||||||
if (remain.isEmpty())
|
if (remain.isEmpty())
|
||||||
|
return remain;
|
||||||
|
}
|
||||||
|
// check craftable items
|
||||||
|
return this.requestCraftedItem(destPipe, destInventory, remain, equalityTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack requestCraftedItem(BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes) {
|
||||||
|
for (Pair<BlockPos, ItemStack> craftable : this.getOrderedCraftables(destPipe, true)) {
|
||||||
|
if (!ItemEqualityType.compareItems(stack, craftable.getRight(), equalityTypes))
|
||||||
|
continue;
|
||||||
|
PipeTileEntity pipe = this.getPipe(craftable.getLeft());
|
||||||
|
if (pipe == null)
|
||||||
|
continue;
|
||||||
|
stack = pipe.craft(destPipe, destInventory, stack, equalityTypes);
|
||||||
|
if (stack.isEmpty())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return remain;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack requestExistingItem(NetworkLocation location, BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes) {
|
public ItemStack requestExistingItem(NetworkLocation location, BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes) {
|
||||||
|
@ -224,18 +237,19 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
|
||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Pair<BlockPos, ItemStack>> getOrderedCraftables(BlockPos node) {
|
public List<Pair<BlockPos, ItemStack>> getOrderedCraftables(BlockPos node, boolean onlyReturnPossible) {
|
||||||
if (!this.isNode(node))
|
if (!this.isNode(node))
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
this.startProfile("get_craftables");
|
this.startProfile("get_craftables");
|
||||||
List<Pair<BlockPos, ItemStack>> craftables = new ArrayList<>();
|
List<Pair<BlockPos, ItemStack>> craftables = new ArrayList<>();
|
||||||
for (BlockPos dest : this.getOrderedNetworkNodes(node)) {
|
for (BlockPos dest : this.getOrderedNetworkNodes(node)) {
|
||||||
|
// don't try to collect recipes for ourselves, since we need these recipes for that
|
||||||
|
if (dest.equals(node))
|
||||||
|
continue;
|
||||||
if (!this.world.isBlockLoaded(dest))
|
if (!this.world.isBlockLoaded(dest))
|
||||||
continue;
|
continue;
|
||||||
PipeTileEntity pipe = this.getPipe(dest);
|
PipeTileEntity pipe = this.getPipe(dest);
|
||||||
if (!pipe.canNetworkSee())
|
for (ItemStack stack : pipe.getCraftables(onlyReturnPossible))
|
||||||
continue;
|
|
||||||
for (ItemStack stack : pipe.getCraftables())
|
|
||||||
craftables.add(Pair.of(pipe.getPos(), stack));
|
craftables.add(Pair.of(pipe.getPos(), stack));
|
||||||
}
|
}
|
||||||
this.endProfile();
|
this.endProfile();
|
||||||
|
@ -254,7 +268,7 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
|
||||||
if (!pipe.canNetworkSee())
|
if (!pipe.canNetworkSee())
|
||||||
continue;
|
continue;
|
||||||
for (Direction dir : Direction.values()) {
|
for (Direction dir : Direction.values()) {
|
||||||
IItemHandler handler = pipe.getItemHandler(dir, null);
|
IItemHandler handler = pipe.getItemHandler(dir);
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
continue;
|
continue;
|
||||||
// check if this handler already exists (double-connected pipes, double chests etc.)
|
// check if this handler already exists (double-connected pipes, double chests etc.)
|
||||||
|
|
|
@ -12,10 +12,6 @@ public interface IPipeConnectable {
|
||||||
|
|
||||||
ConnectionType getConnectionType(World world, BlockPos pipePos, Direction direction);
|
ConnectionType getConnectionType(World world, BlockPos pipePos, Direction direction);
|
||||||
|
|
||||||
default IItemHandler getItemHandler(World world, BlockPos pipePos, Direction direction, PipeItem item) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
default ItemStack insertItem(World world, BlockPos pipePos, Direction direction, PipeItem item) {
|
default ItemStack insertItem(World world, BlockPos pipePos, Direction direction, PipeItem item) {
|
||||||
return item.stack;
|
return item.stack;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import net.minecraft.inventory.container.INamedContainerProvider;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.nbt.ListNBT;
|
||||||
import net.minecraft.profiler.IProfiler;
|
import net.minecraft.profiler.IProfiler;
|
||||||
import net.minecraft.tileentity.ChestTileEntity;
|
import net.minecraft.tileentity.ChestTileEntity;
|
||||||
import net.minecraft.tileentity.ITickableTileEntity;
|
import net.minecraft.tileentity.ITickableTileEntity;
|
||||||
|
@ -36,6 +37,7 @@ import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
import net.minecraftforge.items.ItemStackHandler;
|
import net.minecraftforge.items.ItemStackHandler;
|
||||||
import net.minecraftforge.items.wrapper.InvWrapper;
|
import net.minecraftforge.items.wrapper.InvWrapper;
|
||||||
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;
|
||||||
|
@ -61,6 +63,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
public final Queue<NetworkLock> craftIngredientRequests = new ArrayDeque<>();
|
public final Queue<NetworkLock> craftIngredientRequests = new ArrayDeque<>();
|
||||||
|
public final List<Triple<BlockPos, BlockPos, ItemStack>> craftResultRequests = new ArrayList<>();
|
||||||
public PressurizerTileEntity pressurizer;
|
public PressurizerTileEntity pressurizer;
|
||||||
public int moduleDropCheck;
|
public int moduleDropCheck;
|
||||||
protected List<PipeItem> items;
|
protected List<PipeItem> items;
|
||||||
|
@ -80,6 +83,15 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
||||||
compound.put("modules", this.modules.serializeNBT());
|
compound.put("modules", this.modules.serializeNBT());
|
||||||
compound.putInt("module_drop_check", this.moduleDropCheck);
|
compound.putInt("module_drop_check", this.moduleDropCheck);
|
||||||
compound.put("requests", Utility.serializeAll(this.craftIngredientRequests));
|
compound.put("requests", Utility.serializeAll(this.craftIngredientRequests));
|
||||||
|
ListNBT results = new ListNBT();
|
||||||
|
for (Triple<BlockPos, BlockPos, ItemStack> triple : this.craftResultRequests) {
|
||||||
|
CompoundNBT nbt = new CompoundNBT();
|
||||||
|
nbt.putLong("dest_pipe", triple.getLeft().toLong());
|
||||||
|
nbt.putLong("dest_inv", triple.getMiddle().toLong());
|
||||||
|
nbt.put("item", triple.getRight().serializeNBT());
|
||||||
|
results.add(nbt);
|
||||||
|
}
|
||||||
|
compound.put("craft_results", results);
|
||||||
return super.write(compound);
|
return super.write(compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +101,15 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
||||||
this.moduleDropCheck = compound.getInt("module_drop_check");
|
this.moduleDropCheck = compound.getInt("module_drop_check");
|
||||||
this.craftIngredientRequests.clear();
|
this.craftIngredientRequests.clear();
|
||||||
this.craftIngredientRequests.addAll(Utility.deserializeAll(compound.getList("requests", NBT.TAG_COMPOUND), NetworkLock::new));
|
this.craftIngredientRequests.addAll(Utility.deserializeAll(compound.getList("requests", NBT.TAG_COMPOUND), NetworkLock::new));
|
||||||
|
this.craftResultRequests.clear();
|
||||||
|
ListNBT results = compound.getList("craft_results", NBT.TAG_COMPOUND);
|
||||||
|
for (int i = 0; i < results.size(); i++) {
|
||||||
|
CompoundNBT nbt = results.getCompound(i);
|
||||||
|
this.craftResultRequests.add(Triple.of(
|
||||||
|
BlockPos.fromLong(nbt.getLong("dest_pipe")),
|
||||||
|
BlockPos.fromLong(nbt.getLong("dest_inv")),
|
||||||
|
ItemStack.read(nbt.getCompound("item"))));
|
||||||
|
}
|
||||||
super.read(state, compound);
|
super.read(state, compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,26 +161,6 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
||||||
PipeNetwork.get(this.world).clearDestinationCache(this.pos);
|
PipeNetwork.get(this.world).clearDestinationCache(this.pos);
|
||||||
}
|
}
|
||||||
profiler.endSection();
|
profiler.endSection();
|
||||||
|
|
||||||
// request crafting ingredients
|
|
||||||
if (this.world.getGameTime() % 4 == 0 && !this.craftIngredientRequests.isEmpty()) {
|
|
||||||
PipeNetwork network = PipeNetwork.get(this.world);
|
|
||||||
NetworkLock request = this.craftIngredientRequests.remove();
|
|
||||||
Pair<BlockPos, ItemStack> dest = this.getAvailableDestination(request.stack, true, true);
|
|
||||||
if (dest != null) {
|
|
||||||
network.requestExistingItem(request.location, this.getPos(), dest.getLeft(), dest.getRight(), ItemEqualityType.NBT);
|
|
||||||
network.resolveNetworkLock(request);
|
|
||||||
|
|
||||||
// if we couldn't fit all items into the destination, create another request for the rest
|
|
||||||
ItemStack remain = request.stack.copy();
|
|
||||||
remain.shrink(dest.getRight().getCount());
|
|
||||||
if (!remain.isEmpty()) {
|
|
||||||
NetworkLock remainRequest = new NetworkLock(request.location, remain);
|
|
||||||
this.craftIngredientRequests.add(remainRequest);
|
|
||||||
network.createNetworkLock(remainRequest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
profiler.startSection("ticking_items");
|
profiler.startSection("ticking_items");
|
||||||
|
@ -197,7 +198,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
||||||
if (!force && this.streamModules().anyMatch(m -> !m.getRight().canAcceptItem(m.getLeft(), this, stack)))
|
if (!force && this.streamModules().anyMatch(m -> !m.getRight().canAcceptItem(m.getLeft(), this, stack)))
|
||||||
return null;
|
return null;
|
||||||
for (Direction dir : Direction.values()) {
|
for (Direction dir : Direction.values()) {
|
||||||
IItemHandler handler = this.getItemHandler(dir, null);
|
IItemHandler handler = this.getItemHandler(dir);
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
continue;
|
continue;
|
||||||
ItemStack remain = ItemHandlerHelper.insertItem(handler, stack, true);
|
ItemStack remain = ItemHandlerHelper.insertItem(handler, stack, true);
|
||||||
|
@ -259,9 +260,9 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
||||||
return this.streamModules().allMatch(m -> m.getRight().canPipeWork(m.getLeft(), this));
|
return this.streamModules().allMatch(m -> m.getRight().canPipeWork(m.getLeft(), this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ItemStack> getCraftables() {
|
public List<ItemStack> getCraftables(boolean onlyReturnPossible) {
|
||||||
return this.streamModules()
|
return this.streamModules()
|
||||||
.flatMap(m -> m.getRight().getCraftables(m.getLeft(), this).stream())
|
.flatMap(m -> m.getRight().getCraftables(m.getLeft(), this, onlyReturnPossible).stream())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +277,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IItemHandler getItemHandler(Direction dir, PipeItem item) {
|
public IItemHandler getItemHandler(Direction dir) {
|
||||||
if (!this.isConnected(dir))
|
if (!this.isConnected(dir))
|
||||||
return null;
|
return null;
|
||||||
BlockPos pos = this.pos.offset(dir);
|
BlockPos pos = this.pos.offset(dir);
|
||||||
|
@ -288,13 +289,8 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
||||||
if (state.getBlock() instanceof ChestBlock)
|
if (state.getBlock() instanceof ChestBlock)
|
||||||
return new InvWrapper(ChestBlock.getChestInventory((ChestBlock) state.getBlock(), state, this.world, tile.getPos(), true));
|
return new InvWrapper(ChestBlock.getChestInventory((ChestBlock) state.getBlock(), state, this.world, tile.getPos(), true));
|
||||||
}
|
}
|
||||||
IItemHandler handler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir.getOpposite()).orElse(null);
|
return tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir.getOpposite()).orElse(null);
|
||||||
if (handler != null)
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
IPipeConnectable connectable = this.getPipeConnectable(dir);
|
|
||||||
if (connectable != null)
|
|
||||||
return connectable.getItemHandler(this.world, this.pos, dir, item);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,7 +302,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isConnectedInventory(Direction dir) {
|
public boolean isConnectedInventory(Direction dir) {
|
||||||
return this.getItemHandler(dir, null) != null;
|
return this.getItemHandler(dir) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canHaveModules() {
|
public boolean canHaveModules() {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import de.ellpeck.prettypipes.misc.ItemEqualityType;
|
||||||
import de.ellpeck.prettypipes.misc.ItemFilter;
|
import de.ellpeck.prettypipes.misc.ItemFilter;
|
||||||
import de.ellpeck.prettypipes.network.NetworkLocation;
|
import de.ellpeck.prettypipes.network.NetworkLocation;
|
||||||
import de.ellpeck.prettypipes.network.NetworkLock;
|
import de.ellpeck.prettypipes.network.NetworkLock;
|
||||||
|
import de.ellpeck.prettypipes.network.PipeItem;
|
||||||
import de.ellpeck.prettypipes.network.PipeNetwork;
|
import de.ellpeck.prettypipes.network.PipeNetwork;
|
||||||
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
|
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
|
||||||
import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer;
|
import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer;
|
||||||
|
@ -17,10 +18,16 @@ import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
import net.minecraftforge.items.ItemStackHandler;
|
import net.minecraftforge.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;
|
||||||
|
@ -29,11 +36,15 @@ public class CraftingModuleItem extends ModuleItem {
|
||||||
|
|
||||||
public final int inputSlots;
|
public final int inputSlots;
|
||||||
public final int outputSlots;
|
public final int outputSlots;
|
||||||
|
private final int speed;
|
||||||
|
private final int maxExtraction;
|
||||||
|
|
||||||
public CraftingModuleItem(String name, ModuleTier tier) {
|
public CraftingModuleItem(String name, ModuleTier tier) {
|
||||||
super(name);
|
super(name);
|
||||||
this.inputSlots = tier.forTier(1, 4, 9);
|
this.inputSlots = tier.forTier(1, 4, 9);
|
||||||
this.outputSlots = tier.forTier(1, 2, 4);
|
this.outputSlots = tier.forTier(1, 2, 4);
|
||||||
|
this.speed = tier.forTier(20, 10, 5);
|
||||||
|
this.maxExtraction = tier.forTier(1, 16, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,19 +63,95 @@ public class CraftingModuleItem extends ModuleItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ItemStack> getCraftables(ItemStack module, PipeTileEntity tile) {
|
public boolean canNetworkSee(ItemStack module, PipeTileEntity tile) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(ItemStack module, PipeTileEntity tile) {
|
||||||
|
if (tile.getWorld().getGameTime() % this.speed != 0 || !tile.canWork())
|
||||||
|
return;
|
||||||
|
PipeNetwork network = PipeNetwork.get(tile.getWorld());
|
||||||
|
// process crafting ingredient requests
|
||||||
|
if (!tile.craftIngredientRequests.isEmpty()) {
|
||||||
|
NetworkLock request = tile.craftIngredientRequests.remove();
|
||||||
|
Pair<BlockPos, ItemStack> dest = tile.getAvailableDestination(request.stack, true, true);
|
||||||
|
if (dest != null) {
|
||||||
|
network.requestExistingItem(request.location, tile.getPos(), dest.getLeft(), dest.getRight(), ItemEqualityType.NBT);
|
||||||
|
network.resolveNetworkLock(request);
|
||||||
|
|
||||||
|
// if we couldn't fit all items into the destination, create another request for the rest
|
||||||
|
ItemStack remain = request.stack.copy();
|
||||||
|
remain.shrink(dest.getRight().getCount());
|
||||||
|
if (!remain.isEmpty()) {
|
||||||
|
NetworkLock remainRequest = new NetworkLock(request.location, remain);
|
||||||
|
tile.craftIngredientRequests.add(remainRequest);
|
||||||
|
network.createNetworkLock(remainRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// pull requested crafting results from the network once they are stored
|
||||||
|
if (!tile.craftResultRequests.isEmpty()) {
|
||||||
|
List<NetworkLocation> items = network.getOrderedNetworkItems(tile.getPos());
|
||||||
|
ItemEqualityType[] equalityTypes = ItemFilter.getEqualityTypes(tile);
|
||||||
|
for (Triple<BlockPos, BlockPos, ItemStack> request : tile.craftResultRequests) {
|
||||||
|
ItemStack reqItem = request.getRight();
|
||||||
|
for (NetworkLocation item : items) {
|
||||||
|
int amount = item.getItemAmount(tile.getWorld(), reqItem, equalityTypes);
|
||||||
|
amount -= network.getLockedAmount(item.getPos(), reqItem, equalityTypes);
|
||||||
|
if (amount <= 0)
|
||||||
|
continue;
|
||||||
|
ItemStack remain = reqItem.copy();
|
||||||
|
if (remain.getCount() < amount)
|
||||||
|
amount = remain.getCount();
|
||||||
|
remain.shrink(amount);
|
||||||
|
while (amount > 0) {
|
||||||
|
ItemStack copy = reqItem.copy();
|
||||||
|
copy.setCount(Math.min(reqItem.getMaxStackSize(), amount));
|
||||||
|
// we don't need to do any checks here because we just calculated the max amount we can definitely extract
|
||||||
|
network.requestExistingItem(item, request.getLeft(), request.getMiddle(), copy, equalityTypes);
|
||||||
|
amount -= copy.getCount();
|
||||||
|
}
|
||||||
|
tile.craftResultRequests.remove(request);
|
||||||
|
// if we couldn't pull everything, log a new request
|
||||||
|
if (!remain.isEmpty())
|
||||||
|
tile.craftResultRequests.add(Triple.of(request.getLeft(), request.getMiddle(), remain));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ItemStack> getCraftables(ItemStack module, PipeTileEntity tile, boolean onlyReturnPossible) {
|
||||||
|
ItemStackHandler output = this.getOutput(module);
|
||||||
|
if (!onlyReturnPossible) {
|
||||||
|
// if we only need to return the ones we *could* craft, it's easy
|
||||||
|
List<ItemStack> ret = new ArrayList<>();
|
||||||
|
for (int i = 0; i < output.getSlots(); i++) {
|
||||||
|
ItemStack stack = output.getStackInSlot(i);
|
||||||
|
if (!stack.isEmpty())
|
||||||
|
ret.add(stack);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
PipeNetwork network = PipeNetwork.get(tile.getWorld());
|
PipeNetwork network = PipeNetwork.get(tile.getWorld());
|
||||||
List<NetworkLocation> items = network.getOrderedNetworkItems(tile.getPos());
|
List<NetworkLocation> items = network.getOrderedNetworkItems(tile.getPos());
|
||||||
List<Pair<BlockPos, ItemStack>> craftables = network.getOrderedCraftables(tile.getPos());
|
List<Pair<BlockPos, ItemStack>> craftables = network.getOrderedCraftables(tile.getPos(), true);
|
||||||
ItemEqualityType[] equalityTypes = ItemFilter.getEqualityTypes(tile);
|
ItemEqualityType[] equalityTypes = ItemFilter.getEqualityTypes(tile);
|
||||||
|
|
||||||
ItemStackHandler output = this.getOutput(module);
|
|
||||||
ItemStackHandler input = this.getInput(module);
|
ItemStackHandler input = this.getInput(module);
|
||||||
|
|
||||||
List<ItemStack> ret = new ArrayList<>();
|
List<ItemStack> ret = new ArrayList<>();
|
||||||
for (int i = 0; i < output.getSlots(); i++) {
|
for (int i = 0; i < output.getSlots(); i++) {
|
||||||
ItemStack stack = output.getStackInSlot(i);
|
ItemStack stack = output.getStackInSlot(i);
|
||||||
if (!stack.isEmpty()) {
|
if (!stack.isEmpty()) {
|
||||||
|
// figure out how many crafting operations we can actually do with the input items we have in the network
|
||||||
int availableCrafts = CraftingTerminalTileEntity.getAvailableCrafts(tile.getWorld(), input.getSlots(), input::getStackInSlot, k -> false, s -> items, craftables, null, equalityTypes);
|
int availableCrafts = CraftingTerminalTileEntity.getAvailableCrafts(tile.getWorld(), input.getSlots(), input::getStackInSlot, k -> false, s -> items, craftables, null, equalityTypes);
|
||||||
if (availableCrafts > 0) {
|
if (availableCrafts > 0) {
|
||||||
ItemStack copy = stack.copy();
|
ItemStack copy = stack.copy();
|
||||||
|
@ -79,26 +166,28 @@ public class CraftingModuleItem extends ModuleItem {
|
||||||
@Override
|
@Override
|
||||||
public ItemStack craft(ItemStack module, PipeTileEntity tile, BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes) {
|
public ItemStack craft(ItemStack module, PipeTileEntity tile, BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes) {
|
||||||
// check if we can craft the required amount of items
|
// check if we can craft the required amount of items
|
||||||
List<ItemStack> craftables = this.getCraftables(module, tile);
|
List<ItemStack> craftables = this.getCraftables(module, tile, true);
|
||||||
int craftableAmount = craftables.stream()
|
int craftableAmount = craftables.stream()
|
||||||
.filter(c -> ItemEqualityType.compareItems(c, stack, equalityTypes))
|
.filter(c -> ItemEqualityType.compareItems(c, stack, equalityTypes))
|
||||||
.mapToInt(ItemStack::getCount).sum();
|
.mapToInt(ItemStack::getCount).sum();
|
||||||
if (craftableAmount > 0) {
|
if (craftableAmount > 0) {
|
||||||
PipeNetwork network = PipeNetwork.get(tile.getWorld());
|
PipeNetwork network = PipeNetwork.get(tile.getWorld());
|
||||||
List<NetworkLocation> items = network.getOrderedNetworkItems(tile.getPos());
|
List<NetworkLocation> items = network.getOrderedNetworkItems(tile.getPos());
|
||||||
List<Pair<BlockPos, ItemStack>> allCraftables = network.getOrderedCraftables(tile.getPos());
|
List<Pair<BlockPos, ItemStack>> allCraftables = network.getOrderedCraftables(tile.getPos(), true);
|
||||||
|
|
||||||
int resultAmount = this.getResultAmountPerCraft(module, stack, equalityTypes);
|
int resultAmount = this.getResultAmountPerCraft(module, stack, equalityTypes);
|
||||||
int requiredCrafts = MathHelper.ceil(stack.getCount() / (float) resultAmount);
|
int requiredCrafts = MathHelper.ceil(stack.getCount() / (float) resultAmount);
|
||||||
|
|
||||||
ItemStackHandler input = this.getInput(module);
|
ItemStackHandler input = this.getInput(module);
|
||||||
for (int i = 0; i < input.getSlots(); i++) {
|
for (int i = 0; i < input.getSlots(); i++) {
|
||||||
ItemStack in = input.getStackInSlot(i).copy();
|
ItemStack in = input.getStackInSlot(i);
|
||||||
if (in.isEmpty())
|
if (in.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
in.setCount(in.getCount() * requiredCrafts);
|
ItemStack copy = in.copy();
|
||||||
List<NetworkLock> requests = ItemTerminalTileEntity.requestItemLater(tile.getWorld(), destPipe, destInventory, in, items, allCraftables, equalityTypes);
|
copy.setCount(in.getCount() * requiredCrafts);
|
||||||
tile.craftIngredientRequests.addAll(requests);
|
Pair<List<NetworkLock>, ItemStack> ret = ItemTerminalTileEntity.requestItemLater(tile.getWorld(), destPipe, destInventory, copy, items, allCraftables, equalityTypes);
|
||||||
|
tile.craftIngredientRequests.addAll(ret.getLeft());
|
||||||
|
tile.craftResultRequests.add(Triple.of(destPipe, destInventory, stack));
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack remain = stack.copy();
|
ItemStack remain = stack.copy();
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class ExtractionModuleItem extends ModuleItem {
|
||||||
|
|
||||||
PipeNetwork network = PipeNetwork.get(tile.getWorld());
|
PipeNetwork network = PipeNetwork.get(tile.getWorld());
|
||||||
for (Direction dir : Direction.values()) {
|
for (Direction dir : Direction.values()) {
|
||||||
IItemHandler handler = tile.getItemHandler(dir, null);
|
IItemHandler handler = tile.getItemHandler(dir);
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
continue;
|
continue;
|
||||||
for (int j = 0; j < handler.getSlots(); j++) {
|
for (int j = 0; j < handler.getSlots(); j++) {
|
||||||
|
|
|
@ -124,11 +124,13 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
||||||
PipeTileEntity pipe = this.getConnectedPipe();
|
PipeTileEntity pipe = this.getConnectedPipe();
|
||||||
if (pipe == null)
|
if (pipe == null)
|
||||||
return;
|
return;
|
||||||
|
PipeNetwork network = PipeNetwork.get(this.world);
|
||||||
this.networkItems = this.collectItems();
|
this.networkItems = this.collectItems();
|
||||||
this.craftables = PipeNetwork.get(this.world).getOrderedCraftables(pipe.getPos());
|
this.craftables = network.getOrderedCraftables(pipe.getPos(), true);
|
||||||
if (playersToSync.length > 0) {
|
if (playersToSync.length > 0) {
|
||||||
|
// the craftables we display should be displayed even if they can't be crafted!
|
||||||
|
List<ItemStack> clientCraftables = network.getOrderedCraftables(pipe.getPos(), false).stream().map(Pair::getRight).collect(Collectors.toList());
|
||||||
List<ItemStack> clientItems = this.networkItems.values().stream().map(NetworkItem::asStack).collect(Collectors.toList());
|
List<ItemStack> clientItems = this.networkItems.values().stream().map(NetworkItem::asStack).collect(Collectors.toList());
|
||||||
List<ItemStack> clientCraftables = this.craftables.stream().map(Pair::getRight).collect(Collectors.toList());
|
|
||||||
for (PlayerEntity player : playersToSync) {
|
for (PlayerEntity player : playersToSync) {
|
||||||
if (!(player.openContainer instanceof ItemTerminalContainer))
|
if (!(player.openContainer instanceof ItemTerminalContainer))
|
||||||
continue;
|
continue;
|
||||||
|
@ -154,11 +156,11 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
||||||
}
|
}
|
||||||
|
|
||||||
public int requestItemImpl(ItemStack stack) {
|
public int requestItemImpl(ItemStack stack) {
|
||||||
ItemStack remain = stack.copy();
|
NetworkItem item = this.networkItems.get(new EquatableItemStack(stack));
|
||||||
NetworkItem item = this.networkItems.get(new EquatableItemStack(remain));
|
|
||||||
Collection<NetworkLocation> locations = item == null ? Collections.emptyList() : item.getLocations();
|
Collection<NetworkLocation> locations = item == null ? Collections.emptyList() : item.getLocations();
|
||||||
this.existingRequests.addAll(requestItemLater(this.world, this.getConnectedPipe().getPos(), this.pos, remain, locations, this.craftables, ItemEqualityType.NBT));
|
Pair<List<NetworkLock>, ItemStack> ret = requestItemLater(this.world, this.getConnectedPipe().getPos(), this.pos, stack, locations, this.craftables, ItemEqualityType.NBT);
|
||||||
return stack.getCount() - remain.getCount();
|
this.existingRequests.addAll(ret.getLeft());
|
||||||
|
return stack.getCount() - ret.getRight().getCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PlayerEntity[] getLookingPlayers() {
|
protected PlayerEntity[] getLookingPlayers() {
|
||||||
|
@ -210,8 +212,9 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
||||||
return new ItemTerminalContainer(Registry.itemTerminalContainer, window, player, this.pos);
|
return new ItemTerminalContainer(Registry.itemTerminalContainer, window, player, this.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<NetworkLock> requestItemLater(World world, BlockPos destPipe, BlockPos destInventory, ItemStack stack, Collection<NetworkLocation> locations, List<Pair<BlockPos, ItemStack>> craftables, ItemEqualityType... equalityTypes) {
|
public static Pair<List<NetworkLock>, ItemStack> requestItemLater(World world, BlockPos destPipe, BlockPos destInventory, ItemStack stack, Collection<NetworkLocation> locations, List<Pair<BlockPos, ItemStack>> craftables, ItemEqualityType... equalityTypes) {
|
||||||
List<NetworkLock> requests = new ArrayList<>();
|
List<NetworkLock> requests = new ArrayList<>();
|
||||||
|
ItemStack remain = stack.copy();
|
||||||
PipeNetwork network = PipeNetwork.get(world);
|
PipeNetwork network = PipeNetwork.get(world);
|
||||||
// check for existing items
|
// check for existing items
|
||||||
for (NetworkLocation location : locations) {
|
for (NetworkLocation location : locations) {
|
||||||
|
@ -220,9 +223,9 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
||||||
continue;
|
continue;
|
||||||
amount -= network.getLockedAmount(location.getPos(), stack, ItemEqualityType.NBT);
|
amount -= network.getLockedAmount(location.getPos(), stack, ItemEqualityType.NBT);
|
||||||
if (amount > 0) {
|
if (amount > 0) {
|
||||||
if (stack.getCount() < amount)
|
if (remain.getCount() < amount)
|
||||||
amount = stack.getCount();
|
amount = remain.getCount();
|
||||||
stack.shrink(amount);
|
remain.shrink(amount);
|
||||||
while (amount > 0) {
|
while (amount > 0) {
|
||||||
ItemStack copy = stack.copy();
|
ItemStack copy = stack.copy();
|
||||||
copy.setCount(Math.min(stack.getMaxStackSize(), amount));
|
copy.setCount(Math.min(stack.getMaxStackSize(), amount));
|
||||||
|
@ -231,21 +234,13 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
||||||
requests.add(lock);
|
requests.add(lock);
|
||||||
amount -= copy.getCount();
|
amount -= copy.getCount();
|
||||||
}
|
}
|
||||||
if (stack.isEmpty())
|
if (remain.isEmpty())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check for craftable items
|
// check for craftable items
|
||||||
for (Pair<BlockPos, ItemStack> craftable : craftables) {
|
if (!remain.isEmpty())
|
||||||
if (!ItemEqualityType.compareItems(stack, craftable.getRight(), equalityTypes))
|
network.requestCraftedItem(destPipe, destInventory, remain, equalityTypes);
|
||||||
continue;
|
return Pair.of(requests, remain);
|
||||||
PipeTileEntity pipe = network.getPipe(craftable.getLeft());
|
|
||||||
if (pipe == null)
|
|
||||||
continue;
|
|
||||||
stack = pipe.craft(destPipe, destInventory, stack, equalityTypes);
|
|
||||||
if (stack.isEmpty())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return requests;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue