improved the tag filter modifier

This commit is contained in:
Ell 2021-03-03 01:56:19 +01:00
parent 4c0862c9ed
commit 3f79cfb83e
22 changed files with 381 additions and 169 deletions

View file

@ -3,7 +3,7 @@ package de.ellpeck.prettypipes;
import de.ellpeck.prettypipes.entities.PipeFrameEntity; import de.ellpeck.prettypipes.entities.PipeFrameEntity;
import de.ellpeck.prettypipes.entities.PipeFrameRenderer; import de.ellpeck.prettypipes.entities.PipeFrameRenderer;
import de.ellpeck.prettypipes.items.*; import de.ellpeck.prettypipes.items.*;
import de.ellpeck.prettypipes.misc.ItemEqualityType; import de.ellpeck.prettypipes.misc.ItemEquality;
import de.ellpeck.prettypipes.network.PipeNetwork; import de.ellpeck.prettypipes.network.PipeNetwork;
import de.ellpeck.prettypipes.packets.PacketHandler; import de.ellpeck.prettypipes.packets.PacketHandler;
import de.ellpeck.prettypipes.pipe.IPipeConnectable; import de.ellpeck.prettypipes.pipe.IPipeConnectable;
@ -26,6 +26,9 @@ import de.ellpeck.prettypipes.pipe.modules.filter.FilterIncreaseModuleItem;
import de.ellpeck.prettypipes.pipe.modules.insertion.FilterModuleContainer; import de.ellpeck.prettypipes.pipe.modules.insertion.FilterModuleContainer;
import de.ellpeck.prettypipes.pipe.modules.insertion.FilterModuleGui; import de.ellpeck.prettypipes.pipe.modules.insertion.FilterModuleGui;
import de.ellpeck.prettypipes.pipe.modules.insertion.FilterModuleItem; import de.ellpeck.prettypipes.pipe.modules.insertion.FilterModuleItem;
import de.ellpeck.prettypipes.pipe.modules.modifier.FilterModifierModuleContainer;
import de.ellpeck.prettypipes.pipe.modules.modifier.FilterModifierModuleGui;
import de.ellpeck.prettypipes.pipe.modules.modifier.FilterModifierModuleItem;
import de.ellpeck.prettypipes.pipe.modules.retrieval.RetrievalModuleContainer; import de.ellpeck.prettypipes.pipe.modules.retrieval.RetrievalModuleContainer;
import de.ellpeck.prettypipes.pipe.modules.retrieval.RetrievalModuleGui; import de.ellpeck.prettypipes.pipe.modules.retrieval.RetrievalModuleGui;
import de.ellpeck.prettypipes.pipe.modules.retrieval.RetrievalModuleItem; import de.ellpeck.prettypipes.pipe.modules.retrieval.RetrievalModuleItem;
@ -122,6 +125,7 @@ public final class Registry {
public static ContainerType<StackSizeModuleContainer> stackSizeModuleContainer; public static ContainerType<StackSizeModuleContainer> stackSizeModuleContainer;
public static ContainerType<FilterIncreaseModuleContainer> filterIncreaseModuleContainer; public static ContainerType<FilterIncreaseModuleContainer> filterIncreaseModuleContainer;
public static ContainerType<CraftingModuleContainer> craftingModuleContainer; public static ContainerType<CraftingModuleContainer> craftingModuleContainer;
public static ContainerType<FilterModifierModuleContainer> filterModifierModuleContainer;
@SubscribeEvent @SubscribeEvent
public static void registerBlocks(RegistryEvent.Register<Block> event) { public static void registerBlocks(RegistryEvent.Register<Block> event) {
@ -148,7 +152,7 @@ public final class Registry {
registry.registerAll(createTieredModule("high_priority_module", HighPriorityModuleItem::new)); registry.registerAll(createTieredModule("high_priority_module", HighPriorityModuleItem::new));
registry.registerAll(createTieredModule("retrieval_module", RetrievalModuleItem::new)); registry.registerAll(createTieredModule("retrieval_module", RetrievalModuleItem::new));
registry.register(new StackSizeModuleItem("stack_size_module")); registry.register(new StackSizeModuleItem("stack_size_module"));
registry.registerAll(Arrays.stream(ItemEqualityType.values()).map(t -> new FilterModifierModuleItem(t.name().toLowerCase(Locale.ROOT) + "_filter_modifier", t)).toArray(Item[]::new)); registry.registerAll(Arrays.stream(ItemEquality.Type.values()).map(t -> new FilterModifierModuleItem(t.name().toLowerCase(Locale.ROOT) + "_filter_modifier", t)).toArray(Item[]::new));
registry.register(new RedstoneModuleItem("redstone_module")); registry.register(new RedstoneModuleItem("redstone_module"));
registry.register(new FilterIncreaseModuleItem("filter_increase_modifier")); registry.register(new FilterIncreaseModuleItem("filter_increase_modifier"));
registry.registerAll(createTieredModule("crafting_module", CraftingModuleItem::new)); registry.registerAll(createTieredModule("crafting_module", CraftingModuleItem::new));
@ -188,7 +192,8 @@ public final class Registry {
retrievalModuleContainer = createPipeContainer("retrieval_module"), retrievalModuleContainer = createPipeContainer("retrieval_module"),
stackSizeModuleContainer = createPipeContainer("stack_size_module"), stackSizeModuleContainer = createPipeContainer("stack_size_module"),
filterIncreaseModuleContainer = createPipeContainer("filter_increase_module"), filterIncreaseModuleContainer = createPipeContainer("filter_increase_module"),
craftingModuleContainer = createPipeContainer("crafting_module") craftingModuleContainer = createPipeContainer("crafting_module"),
filterModifierModuleContainer = createPipeContainer("filter_modifier_module")
); );
} }
@ -230,6 +235,7 @@ public final class Registry {
ScreenManager.registerFactory(stackSizeModuleContainer, StackSizeModuleGui::new); ScreenManager.registerFactory(stackSizeModuleContainer, StackSizeModuleGui::new);
ScreenManager.registerFactory(filterIncreaseModuleContainer, FilterIncreaseModuleGui::new); ScreenManager.registerFactory(filterIncreaseModuleContainer, FilterIncreaseModuleGui::new);
ScreenManager.registerFactory(craftingModuleContainer, CraftingModuleGui::new); ScreenManager.registerFactory(craftingModuleContainer, CraftingModuleGui::new);
ScreenManager.registerFactory(filterModifierModuleContainer, FilterModifierModuleGui::new);
} }
} }

View file

@ -1,6 +1,6 @@
package de.ellpeck.prettypipes.compat.jei; package de.ellpeck.prettypipes.compat.jei;
import de.ellpeck.prettypipes.misc.ItemEqualityType; import de.ellpeck.prettypipes.misc.ItemEquality;
import de.ellpeck.prettypipes.packets.PacketCraftingModuleTransfer; import de.ellpeck.prettypipes.packets.PacketCraftingModuleTransfer;
import de.ellpeck.prettypipes.packets.PacketHandler; import de.ellpeck.prettypipes.packets.PacketHandler;
import de.ellpeck.prettypipes.pipe.modules.craft.CraftingModuleContainer; import de.ellpeck.prettypipes.pipe.modules.craft.CraftingModuleContainer;
@ -35,7 +35,7 @@ public class CraftingModuleTransferHandler implements IRecipeTransferHandler<Cra
ItemStack remain = allIngredients.get(0).copy(); ItemStack remain = allIngredients.get(0).copy();
List<ItemStack> toAdd = entry.getValue().isInput() ? inputs : outputs; List<ItemStack> toAdd = entry.getValue().isInput() ? inputs : outputs;
for (ItemStack stack : toAdd) { for (ItemStack stack : toAdd) {
if (ItemEqualityType.compareItems(stack, remain)) { if (ItemEquality.compareItems(stack, remain)) {
int fits = Math.min(stack.getMaxStackSize() - stack.getCount(), remain.getCount()); int fits = Math.min(stack.getMaxStackSize() - stack.getCount(), remain.getCount());
stack.grow(fits); stack.grow(fits);
remain.shrink(fits); remain.shrink(fits);

View file

@ -8,9 +8,9 @@ import java.util.Objects;
public class EquatableItemStack { public class EquatableItemStack {
public final ItemStack stack; public final ItemStack stack;
public final ItemEqualityType[] equalityTypes; public final ItemEquality[] equalityTypes;
public EquatableItemStack(ItemStack stack, ItemEqualityType... equalityTypes) { public EquatableItemStack(ItemStack stack, ItemEquality... equalityTypes) {
this.stack = stack; this.stack = stack;
this.equalityTypes = equalityTypes; this.equalityTypes = equalityTypes;
} }
@ -18,7 +18,7 @@ public class EquatableItemStack {
public boolean equals(Object o) { public boolean equals(Object o) {
if (o instanceof EquatableItemStack) { if (o instanceof EquatableItemStack) {
EquatableItemStack other = (EquatableItemStack) o; EquatableItemStack other = (EquatableItemStack) o;
return Arrays.equals(this.equalityTypes, other.equalityTypes) && ItemEqualityType.compareItems(this.stack, other.stack, this.equalityTypes); return Arrays.equals(this.equalityTypes, other.equalityTypes) && ItemEquality.compareItems(this.stack, other.stack, this.equalityTypes);
} }
return false; return false;
} }

View file

@ -0,0 +1,58 @@
package de.ellpeck.prettypipes.misc;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import java.util.function.BiFunction;
import java.util.function.Supplier;
public class ItemEquality {
public static final ItemEquality DAMAGE = new ItemEquality((stack, filter) -> stack.getDamage() == filter.getDamage(), false, Type.DAMAGE);
public static final ItemEquality NBT = new ItemEquality(ItemStack::areItemStackTagsEqual, false, Type.NBT);
public static final ItemEquality MOD = new ItemEquality((stack, filter) -> stack.getItem().getCreatorModId(stack).equals(filter.getItem().getCreatorModId(filter)), true, Type.MOD);
public final Type type;
private final BiFunction<ItemStack, ItemStack, Boolean> filter;
private final boolean ignoreItemEquality;
ItemEquality(BiFunction<ItemStack, ItemStack, Boolean> filter, boolean ignoreItemEquality, Type type) {
this.filter = filter;
this.ignoreItemEquality = ignoreItemEquality;
this.type = type;
}
public static ItemEquality tag(ResourceLocation tag) {
return new ItemEquality((stack, filter) -> stack.getItem().getTags().contains(tag), true, Type.TAG);
}
public static boolean compareItems(ItemStack stack, ItemStack filter, ItemEquality... types) {
boolean equal = ItemStack.areItemsEqual(stack, filter);
if (types.length <= 0)
return equal;
for (ItemEquality type : types) {
if (!type.ignoreItemEquality && !equal)
return false;
if (!type.filter.apply(stack, filter))
return false;
}
return true;
}
public enum Type {
DAMAGE(() -> ItemEquality.DAMAGE),
NBT(() -> ItemEquality.NBT),
MOD(() -> ItemEquality.MOD),
TAG(null);
private final Supplier<ItemEquality> defaultInstance;
Type(Supplier<ItemEquality> defaultInstance) {
this.defaultInstance = defaultInstance;
}
public ItemEquality getDefaultInstance() {
return this.defaultInstance.get();
}
}
}

View file

@ -1,43 +0,0 @@
package de.ellpeck.prettypipes.misc;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import java.util.Arrays;
import java.util.Set;
import java.util.function.BiFunction;
public enum ItemEqualityType {
DAMAGE((stack, filter) -> stack.getDamage() == filter.getDamage(), false),
NBT(ItemStack::areItemStackTagsEqual, false),
TAG((stack, filter) -> {
Set<ResourceLocation> stackTags = stack.getItem().getTags();
Set<ResourceLocation> filterTags = filter.getItem().getTags();
if (filterTags.isEmpty())
return false;
return stackTags.containsAll(filterTags);
}, true),
MOD((stack, filter) -> stack.getItem().getCreatorModId(stack).equals(filter.getItem().getCreatorModId(filter)), true);
public final BiFunction<ItemStack, ItemStack, Boolean> filter;
public final boolean ignoreItemEquality;
ItemEqualityType(BiFunction<ItemStack, ItemStack, Boolean> filter, boolean ignoreItemEquality) {
this.filter = filter;
this.ignoreItemEquality = ignoreItemEquality;
}
public static boolean compareItems(ItemStack stack, ItemStack filter, ItemEqualityType... types) {
boolean equal = ItemStack.areItemsEqual(stack, filter);
if (types.length <= 0)
return equal;
for (ItemEqualityType type : types) {
if (!type.ignoreItemEquality && !equal)
return false;
if (!type.filter.apply(stack, filter))
return false;
}
return true;
}
}

View file

@ -4,7 +4,7 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import de.ellpeck.prettypipes.PrettyPipes; import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.packets.PacketButton; import de.ellpeck.prettypipes.packets.PacketButton;
import de.ellpeck.prettypipes.pipe.PipeTileEntity; import de.ellpeck.prettypipes.pipe.PipeTileEntity;
import de.ellpeck.prettypipes.pipe.modules.FilterModifierModuleItem; import de.ellpeck.prettypipes.pipe.modules.modifier.FilterModifierModuleItem;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.Widget; import net.minecraft.client.gui.widget.Widget;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
@ -19,7 +19,6 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -106,14 +105,14 @@ public class ItemFilter extends ItemStackHandler {
} }
private boolean isFiltered(ItemStack stack) { private boolean isFiltered(ItemStack stack) {
ItemEqualityType[] types = getEqualityTypes(this.pipe); ItemEquality[] types = getEqualityTypes(this.pipe);
// also check if any filter increase modules have the item we need // also check if any filter increase modules have the item we need
for (ItemStackHandler handler : this.pipe.getFilters()) { for (ItemStackHandler handler : this.pipe.getFilters()) {
for (int i = 0; i < handler.getSlots(); i++) { for (int i = 0; i < handler.getSlots(); i++) {
ItemStack filter = handler.getStackInSlot(i); ItemStack filter = handler.getStackInSlot(i);
if (filter.isEmpty()) if (filter.isEmpty())
continue; continue;
if (ItemEqualityType.compareItems(stack, filter, types)) if (ItemEquality.compareItems(stack, filter, types))
return true; return true;
} }
} }
@ -147,12 +146,11 @@ public class ItemFilter extends ItemStackHandler {
this.modified = true; this.modified = true;
} }
public static ItemEqualityType[] getEqualityTypes(PipeTileEntity pipe) { public static ItemEquality[] getEqualityTypes(PipeTileEntity pipe) {
return pipe.streamModules() return pipe.streamModules()
.map(Pair::getRight) .filter(m -> m.getRight() instanceof FilterModifierModuleItem)
.filter(m -> m instanceof FilterModifierModuleItem) .map(m -> ((FilterModifierModuleItem) m.getRight()).getEqualityType(m.getLeft()))
.map(m -> ((FilterModifierModuleItem) m).type) .toArray(ItemEquality[]::new);
.toArray(ItemEqualityType[]::new);
} }
public interface IFilteredContainer { public interface IFilteredContainer {

View file

@ -1,6 +1,6 @@
package de.ellpeck.prettypipes.network; package de.ellpeck.prettypipes.network;
import de.ellpeck.prettypipes.misc.ItemEqualityType; import de.ellpeck.prettypipes.misc.ItemEquality;
import de.ellpeck.prettypipes.pipe.PipeTileEntity; import de.ellpeck.prettypipes.pipe.PipeTileEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
@ -33,19 +33,19 @@ public class NetworkLocation implements INBTSerializable<CompoundNBT> {
this.deserializeNBT(nbt); this.deserializeNBT(nbt);
} }
public List<Integer> getStackSlots(World world, ItemStack stack, ItemEqualityType... equalityTypes) { public List<Integer> getStackSlots(World world, ItemStack stack, ItemEquality... equalityTypes) {
if (this.isEmpty(world)) if (this.isEmpty(world))
return Collections.emptyList(); return Collections.emptyList();
return this.getItems(world).entrySet().stream() return this.getItems(world).entrySet().stream()
.filter(kv -> ItemEqualityType.compareItems(kv.getValue(), stack, equalityTypes) && this.canExtract(world, kv.getKey())) .filter(kv -> ItemEquality.compareItems(kv.getValue(), stack, equalityTypes) && this.canExtract(world, kv.getKey()))
.map(Map.Entry::getKey).collect(Collectors.toList()); .map(Map.Entry::getKey).collect(Collectors.toList());
} }
public int getItemAmount(World world, ItemStack stack, ItemEqualityType... equalityTypes) { public int getItemAmount(World world, ItemStack stack, ItemEquality... equalityTypes) {
if (this.isEmpty(world)) if (this.isEmpty(world))
return 0; return 0;
return this.getItems(world).entrySet().stream() return this.getItems(world).entrySet().stream()
.filter(kv -> ItemEqualityType.compareItems(stack, kv.getValue(), equalityTypes) && this.canExtract(world, kv.getKey())) .filter(kv -> ItemEquality.compareItems(stack, kv.getValue(), equalityTypes) && this.canExtract(world, kv.getKey()))
.mapToInt(kv -> kv.getValue().getCount()).sum(); .mapToInt(kv -> kv.getValue().getCount()).sum();
} }

View file

@ -6,7 +6,7 @@ import com.google.common.collect.Streams;
import de.ellpeck.prettypipes.PrettyPipes; 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.misc.ItemEqualityType; import de.ellpeck.prettypipes.misc.ItemEquality;
import de.ellpeck.prettypipes.packets.PacketHandler; import de.ellpeck.prettypipes.packets.PacketHandler;
import de.ellpeck.prettypipes.packets.PacketItemEnterPipe; import de.ellpeck.prettypipes.packets.PacketItemEnterPipe;
import de.ellpeck.prettypipes.pipe.IPipeItem; import de.ellpeck.prettypipes.pipe.IPipeItem;
@ -185,7 +185,7 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
return true; return true;
} }
public ItemStack requestItem(BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes) { public ItemStack requestItem(BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEquality... equalityTypes) {
ItemStack remain = stack.copy(); ItemStack remain = stack.copy();
// check existing items // check existing items
for (NetworkLocation location : this.getOrderedNetworkItems(destPipe)) { for (NetworkLocation location : this.getOrderedNetworkItems(destPipe)) {
@ -197,9 +197,9 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
return this.requestCraftedItem(destPipe, null, remain, new Stack<>(), equalityTypes); return this.requestCraftedItem(destPipe, null, remain, new Stack<>(), equalityTypes);
} }
public ItemStack requestCraftedItem(BlockPos destPipe, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain, ItemEqualityType... equalityTypes) { public ItemStack requestCraftedItem(BlockPos destPipe, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain, ItemEquality... equalityTypes) {
for (Pair<BlockPos, ItemStack> craftable : this.getAllCraftables(destPipe)) { for (Pair<BlockPos, ItemStack> craftable : this.getAllCraftables(destPipe)) {
if (!ItemEqualityType.compareItems(stack, craftable.getRight(), equalityTypes)) if (!ItemEquality.compareItems(stack, craftable.getRight(), equalityTypes))
continue; continue;
PipeTileEntity pipe = this.getPipe(craftable.getLeft()); PipeTileEntity pipe = this.getPipe(craftable.getLeft());
if (pipe == null) if (pipe == null)
@ -211,11 +211,11 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
return stack; return stack;
} }
public ItemStack requestExistingItem(NetworkLocation location, BlockPos destPipe, BlockPos destInventory, NetworkLock ignoredLock, ItemStack stack, ItemEqualityType... equalityTypes) { public ItemStack requestExistingItem(NetworkLocation location, BlockPos destPipe, BlockPos destInventory, NetworkLock ignoredLock, ItemStack stack, ItemEquality... equalityTypes) {
return this.requestExistingItem(location, destPipe, destInventory, ignoredLock, PipeItem::new, stack, equalityTypes); return this.requestExistingItem(location, destPipe, destInventory, ignoredLock, PipeItem::new, stack, equalityTypes);
} }
public ItemStack requestExistingItem(NetworkLocation location, BlockPos destPipe, BlockPos destInventory, NetworkLock ignoredLock, BiFunction<ItemStack, Float, IPipeItem> itemSupplier, ItemStack stack, ItemEqualityType... equalityTypes) { public ItemStack requestExistingItem(NetworkLocation location, BlockPos destPipe, BlockPos destInventory, NetworkLock ignoredLock, BiFunction<ItemStack, Float, IPipeItem> itemSupplier, ItemStack stack, ItemEquality... equalityTypes) {
if (location.getPos().equals(destInventory)) if (location.getPos().equals(destInventory))
return stack; return stack;
// make sure we don't pull any locked items // make sure we don't pull any locked items
@ -253,7 +253,7 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
return tile; return tile;
} }
public List<Pair<BlockPos, ItemStack>> getCurrentlyCrafting(BlockPos node, ItemEqualityType... equalityTypes) { public List<Pair<BlockPos, ItemStack>> getCurrentlyCrafting(BlockPos node, 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<>();
Iterator<PipeTileEntity> craftingPipes = this.getAllCraftables(node).stream().map(c -> this.getPipe(c.getLeft())).distinct().iterator(); Iterator<PipeTileEntity> craftingPipes = this.getAllCraftables(node).stream().map(c -> this.getPipe(c.getLeft())).distinct().iterator();
@ -264,7 +264,7 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
ItemStack stack = request.getRight(); ItemStack 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
Optional<Pair<BlockPos, ItemStack>> existing = items.stream() Optional<Pair<BlockPos, ItemStack>> existing = items.stream()
.filter(s -> s.getLeft().equals(dest) && ItemEqualityType.compareItems(s.getRight(), stack, equalityTypes)) .filter(s -> s.getLeft().equals(dest) && ItemEquality.compareItems(s.getRight(), stack, equalityTypes))
.findFirst(); .findFirst();
if (existing.isPresent()) { if (existing.isPresent()) {
existing.get().getRight().grow(stack.getCount()); existing.get().getRight().grow(stack.getCount());
@ -277,9 +277,9 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
return items; return items;
} }
public int getCurrentlyCraftingAmount(BlockPos destNode, ItemStack stack, ItemEqualityType... equalityTypes) { public int getCurrentlyCraftingAmount(BlockPos destNode, ItemStack stack, ItemEquality... equalityTypes) {
return this.getCurrentlyCrafting(destNode).stream() return this.getCurrentlyCrafting(destNode).stream()
.filter(p -> p.getLeft().equals(destNode) && ItemEqualityType.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();
} }
@ -299,10 +299,10 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
return craftables; return craftables;
} }
public int getCraftableAmount(BlockPos node, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain, ItemEqualityType... equalityTypes) { public int getCraftableAmount(BlockPos node, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain, ItemEquality... equalityTypes) {
int total = 0; int total = 0;
for (Pair<BlockPos, ItemStack> pair : this.getAllCraftables(node)) { for (Pair<BlockPos, ItemStack> pair : this.getAllCraftables(node)) {
if (!ItemEqualityType.compareItems(pair.getRight(), stack, equalityTypes)) if (!ItemEquality.compareItems(pair.getRight(), stack, equalityTypes))
continue; continue;
if (!this.world.isBlockLoaded(pair.getLeft())) if (!this.world.isBlockLoaded(pair.getLeft()))
continue; continue;
@ -352,9 +352,9 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
return this.networkLocks.get(pos); return this.networkLocks.get(pos);
} }
public int getLockedAmount(BlockPos pos, ItemStack stack, NetworkLock ignoredLock, ItemEqualityType... equalityTypes) { public int getLockedAmount(BlockPos pos, ItemStack stack, NetworkLock ignoredLock, ItemEquality... equalityTypes) {
return this.getNetworkLocks(pos).stream() return this.getNetworkLocks(pos).stream()
.filter(l -> !l.equals(ignoredLock) && ItemEqualityType.compareItems(l.stack, stack, equalityTypes)) .filter(l -> !l.equals(ignoredLock) && ItemEquality.compareItems(l.stack, stack, equalityTypes))
.mapToInt(l -> l.stack.getCount()).sum(); .mapToInt(l -> l.stack.getCount()).sum();
} }
@ -481,9 +481,9 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
return ret; return ret;
} }
public int getItemsOnTheWay(BlockPos goalInv, ItemStack type, ItemEqualityType... equalityTypes) { public int getItemsOnTheWay(BlockPos goalInv, ItemStack type, ItemEquality... equalityTypes) {
return this.getPipeItemsOnTheWay(goalInv) return this.getPipeItemsOnTheWay(goalInv)
.filter(i -> type == null || ItemEqualityType.compareItems(i.getContent(), type, equalityTypes)) .filter(i -> type == null || ItemEquality.compareItems(i.getContent(), type, equalityTypes))
.mapToInt(i -> i.getItemsOnTheWay(goalInv)).sum(); .mapToInt(i -> i.getItemsOnTheWay(goalInv)).sum();
} }

View file

@ -1,12 +1,13 @@
package de.ellpeck.prettypipes.packets; package de.ellpeck.prettypipes.packets;
import de.ellpeck.prettypipes.PrettyPipes;
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.ItemFilter; import de.ellpeck.prettypipes.misc.ItemFilter;
import de.ellpeck.prettypipes.misc.ItemFilter.IFilteredContainer; import de.ellpeck.prettypipes.misc.ItemFilter.IFilteredContainer;
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;
import de.ellpeck.prettypipes.pipe.modules.modifier.FilterModifierModuleContainer;
import de.ellpeck.prettypipes.pipe.modules.modifier.FilterModifierModuleItem;
import de.ellpeck.prettypipes.pipe.modules.stacksize.StackSizeModuleItem; import de.ellpeck.prettypipes.pipe.modules.stacksize.StackSizeModuleItem;
import de.ellpeck.prettypipes.terminal.CraftingTerminalTileEntity; import de.ellpeck.prettypipes.terminal.CraftingTerminalTileEntity;
import de.ellpeck.prettypipes.terminal.ItemTerminalTileEntity; import de.ellpeck.prettypipes.terminal.ItemTerminalTileEntity;
@ -118,6 +119,10 @@ public class PacketButton {
CANCEL_CRAFTING((pos, data, player) -> { CANCEL_CRAFTING((pos, data, player) -> {
ItemTerminalTileEntity tile = Utility.getTileEntity(ItemTerminalTileEntity.class, player.world, pos); ItemTerminalTileEntity tile = Utility.getTileEntity(ItemTerminalTileEntity.class, player.world, pos);
tile.cancelCrafting(); tile.cancelCrafting();
}),
TAG_FILTER((pos, data, player) -> {
FilterModifierModuleContainer container = (FilterModifierModuleContainer) player.openContainer;
FilterModifierModuleItem.setFilterTag(container.moduleStack, container.getTags().get(data[0]));
}); });
public final TriConsumer<BlockPos, int[], PlayerEntity> action; public final TriConsumer<BlockPos, int[], PlayerEntity> action;

View file

@ -1,30 +1,15 @@
package de.ellpeck.prettypipes.packets; package de.ellpeck.prettypipes.packets;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.misc.FilterSlot;
import de.ellpeck.prettypipes.misc.ItemEqualityType;
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
import de.ellpeck.prettypipes.pipe.modules.craft.CraftingModuleContainer; import de.ellpeck.prettypipes.pipe.modules.craft.CraftingModuleContainer;
import de.ellpeck.prettypipes.pipe.modules.craft.CraftingModuleItem;
import de.ellpeck.prettypipes.terminal.CraftingTerminalTileEntity;
import de.ellpeck.prettypipes.terminal.ItemTerminalTileEntity;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.network.NetworkEvent; import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
public class PacketCraftingModuleTransfer { public class PacketCraftingModuleTransfer {

View file

@ -4,7 +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.ItemEqualityType; import de.ellpeck.prettypipes.misc.ItemEquality;
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;
@ -314,7 +314,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
while (modules.hasNext()) { while (modules.hasNext()) {
Pair<ItemStack, IModule> module = modules.next(); Pair<ItemStack, IModule> module = modules.next();
// make sure we don't factor in recursive dependencies like ingot -> block -> ingot etc. // make sure we don't factor in recursive dependencies like ingot -> block -> ingot etc.
if (dependencyChain.stream().noneMatch(d -> ItemEqualityType.compareItems(module.getLeft(), d, ItemEqualityType.NBT))) { if (dependencyChain.stream().noneMatch(d -> ItemEquality.compareItems(module.getLeft(), d, ItemEquality.NBT))) {
int amount = module.getRight().getCraftableAmount(module.getLeft(), this, unavailableConsumer, stack, dependencyChain); int amount = module.getRight().getCraftableAmount(module.getLeft(), this, unavailableConsumer, stack, dependencyChain);
if (amount > 0) if (amount > 0)
total += amount; total += amount;

View file

@ -1,42 +0,0 @@
package de.ellpeck.prettypipes.pipe.modules;
import de.ellpeck.prettypipes.items.IModule;
import de.ellpeck.prettypipes.items.ModuleItem;
import de.ellpeck.prettypipes.misc.ItemEqualityType;
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Set;
import java.util.function.BiFunction;
public class FilterModifierModuleItem extends ModuleItem {
public final ItemEqualityType type;
public FilterModifierModuleItem(String name, ItemEqualityType type) {
super(name);
this.type = type;
this.setRegistryName(name);
}
@Override
public boolean isCompatible(ItemStack module, PipeTileEntity tile, IModule other) {
return other != this;
}
@Override
public boolean hasContainer(ItemStack module, PipeTileEntity tile) {
return false;
}
@Override
public void addInformation(ItemStack stack, @Nullable World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) {
super.addInformation(stack, worldIn, tooltip, flagIn);
}
}

View file

@ -4,7 +4,7 @@ import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.items.IModule; import de.ellpeck.prettypipes.items.IModule;
import de.ellpeck.prettypipes.items.ModuleItem; import de.ellpeck.prettypipes.items.ModuleItem;
import de.ellpeck.prettypipes.items.ModuleTier; import de.ellpeck.prettypipes.items.ModuleTier;
import de.ellpeck.prettypipes.misc.ItemEqualityType; import de.ellpeck.prettypipes.misc.ItemEquality;
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;
@ -74,7 +74,7 @@ public class CraftingModuleItem extends ModuleItem {
if (!tile.craftIngredientRequests.isEmpty()) { if (!tile.craftIngredientRequests.isEmpty()) {
network.startProfile("crafting_ingredients"); network.startProfile("crafting_ingredients");
NetworkLock request = tile.craftIngredientRequests.peek(); NetworkLock request = tile.craftIngredientRequests.peek();
ItemEqualityType[] equalityTypes = ItemFilter.getEqualityTypes(tile); ItemEquality[] equalityTypes = ItemFilter.getEqualityTypes(tile);
Pair<BlockPos, ItemStack> dest = tile.getAvailableDestination(request.stack, true, true); Pair<BlockPos, ItemStack> dest = tile.getAvailableDestination(request.stack, true, true);
if (dest != null) { if (dest != null) {
ItemStack requestRemain = network.requestExistingItem(request.location, tile.getPos(), dest.getLeft(), request, dest.getRight(), equalityTypes); ItemStack requestRemain = network.requestExistingItem(request.location, tile.getPos(), dest.getLeft(), request, dest.getRight(), equalityTypes);
@ -96,7 +96,7 @@ public class CraftingModuleItem extends ModuleItem {
if (!tile.craftResultRequests.isEmpty()) { if (!tile.craftResultRequests.isEmpty()) {
network.startProfile("crafting_results"); network.startProfile("crafting_results");
List<NetworkLocation> items = network.getOrderedNetworkItems(tile.getPos()); List<NetworkLocation> items = network.getOrderedNetworkItems(tile.getPos());
ItemEqualityType[] equalityTypes = ItemFilter.getEqualityTypes(tile); ItemEquality[] equalityTypes = ItemFilter.getEqualityTypes(tile);
for (Pair<BlockPos, ItemStack> request : tile.craftResultRequests) { for (Pair<BlockPos, ItemStack> request : tile.craftResultRequests) {
ItemStack remain = request.getRight().copy(); ItemStack remain = request.getRight().copy();
PipeTileEntity destPipe = network.getPipe(request.getLeft()); PipeTileEntity destPipe = network.getPipe(request.getLeft());
@ -140,14 +140,14 @@ public class CraftingModuleItem extends ModuleItem {
public int getCraftableAmount(ItemStack module, PipeTileEntity tile, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain) { public int getCraftableAmount(ItemStack module, PipeTileEntity tile, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain) {
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());
ItemEqualityType[] equalityTypes = ItemFilter.getEqualityTypes(tile); ItemEquality[] equalityTypes = ItemFilter.getEqualityTypes(tile);
ItemStackHandler input = this.getInput(module); ItemStackHandler input = this.getInput(module);
int craftable = 0; int craftable = 0;
ItemStackHandler output = this.getOutput(module); ItemStackHandler output = this.getOutput(module);
for (int i = 0; i < output.getSlots(); i++) { for (int i = 0; i < output.getSlots(); i++) {
ItemStack out = output.getStackInSlot(i); ItemStack out = output.getStackInSlot(i);
if (!out.isEmpty() && ItemEqualityType.compareItems(out, stack, equalityTypes)) { if (!out.isEmpty() && ItemEquality.compareItems(out, stack, equalityTypes)) {
// figure out how many crafting operations we can actually do with the input items we have in the network // figure out how many crafting operations we can actually do with the input items we have in the network
int availableCrafts = CraftingTerminalTileEntity.getAvailableCrafts(tile, input.getSlots(), input::getStackInSlot, k -> true, s -> items, unavailableConsumer, addDependency(dependencyChain, module), equalityTypes); int availableCrafts = CraftingTerminalTileEntity.getAvailableCrafts(tile, input.getSlots(), input::getStackInSlot, k -> true, s -> items, unavailableConsumer, addDependency(dependencyChain, module), equalityTypes);
if (availableCrafts > 0) if (availableCrafts > 0)
@ -167,7 +167,7 @@ public class CraftingModuleItem extends ModuleItem {
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());
ItemEqualityType[] equalityTypes = ItemFilter.getEqualityTypes(tile); ItemEquality[] equalityTypes = ItemFilter.getEqualityTypes(tile);
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);
int toCraft = Math.min(craftableAmount, requiredCrafts); int toCraft = Math.min(craftableAmount, requiredCrafts);
@ -215,12 +215,12 @@ public class CraftingModuleItem extends ModuleItem {
tag.put("output", output.serializeNBT()); tag.put("output", output.serializeNBT());
} }
private int getResultAmountPerCraft(ItemStack module, ItemStack stack, ItemEqualityType... equalityTypes) { private int getResultAmountPerCraft(ItemStack module, ItemStack stack, ItemEquality... equalityTypes) {
ItemStackHandler output = this.getOutput(module); ItemStackHandler output = this.getOutput(module);
int resultAmount = 0; int resultAmount = 0;
for (int i = 0; i < output.getSlots(); i++) { for (int i = 0; i < output.getSlots(); i++) {
ItemStack out = output.getStackInSlot(i); ItemStack out = output.getStackInSlot(i);
if (ItemEqualityType.compareItems(stack, out, equalityTypes)) if (ItemEquality.compareItems(stack, out, equalityTypes))
resultAmount += out.getCount(); resultAmount += out.getCount();
} }
return resultAmount; return resultAmount;

View file

@ -0,0 +1,38 @@
package de.ellpeck.prettypipes.pipe.modules.modifier;
import de.ellpeck.prettypipes.misc.ItemFilter;
import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class FilterModifierModuleContainer extends AbstractPipeContainer<FilterModifierModuleItem> {
public FilterModifierModuleContainer(@Nullable ContainerType<?> type, int id, PlayerEntity player, BlockPos pos, int moduleIndex) {
super(type, id, player, pos, moduleIndex);
}
public List<ResourceLocation> getTags() {
Set<ResourceLocation> unsortedTags = new HashSet<>();
for (ItemFilter filter : this.tile.getFilters()) {
for (int i = 0; i < filter.getSlots(); i++) {
ItemStack stack = filter.getStackInSlot(i);
unsortedTags.addAll(stack.getItem().getTags());
}
}
return unsortedTags.stream().sorted().collect(Collectors.toList());
}
@Override
protected void addSlots() {
}
}

View file

@ -0,0 +1,138 @@
package de.ellpeck.prettypipes.pipe.modules.modifier;
import com.mojang.blaze3d.matrix.MatrixStack;
import de.ellpeck.prettypipes.packets.PacketButton;
import de.ellpeck.prettypipes.pipe.containers.AbstractPipeGui;
import net.minecraft.client.audio.SimpleSound;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextFormatting;
import java.util.ArrayList;
import java.util.List;
public class FilterModifierModuleGui extends AbstractPipeGui<FilterModifierModuleContainer> {
private int scrollOffset;
private boolean isScrolling;
private List<ResourceLocation> tags;
private final List<Tag> tagButtons = new ArrayList<>();
public FilterModifierModuleGui(FilterModifierModuleContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) {
super(screenContainer, inv, titleIn);
}
@Override
protected void drawGuiContainerBackgroundLayer(MatrixStack matrix, float partialTicks, int mouseX, int mouseY) {
super.drawGuiContainerBackgroundLayer(matrix, partialTicks, mouseX, mouseY);
this.blit(matrix, this.guiLeft + 7, this.guiTop + 32 + 15, 0, 196, 162, 60);
for (Tag tag : this.tagButtons)
tag.draw(matrix, mouseX, mouseY);
if (this.tags.size() >= 6) {
float percentage = this.scrollOffset / (float) (this.tags.size() - 5);
this.blit(matrix, this.guiLeft + 156, this.guiTop + 32 + 16 + (int) (percentage * (58 - 15)), 232, 241, 12, 15);
} else {
this.blit(matrix, this.guiLeft + 156, this.guiTop + 32 + 16, 244, 241, 12, 15);
}
}
@Override
protected void init() {
super.init();
this.tags = this.container.getTags();
this.updateWidgets();
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
for (Tag tag : this.tagButtons) {
if (tag.onClicked(mouseX, mouseY, button))
return true;
}
if (button == 0 && mouseX >= this.guiLeft + 156 && this.guiTop + mouseY >= 32 + 16 && mouseX < this.guiLeft + 156 + 12 && mouseY < this.guiTop + 32 + 16 + 58) {
this.isScrolling = true;
return true;
}
return super.mouseClicked(mouseX, mouseY, button);
}
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
if (button == 0)
this.isScrolling = false;
return super.mouseReleased(mouseX, mouseY, button);
}
@Override
public boolean mouseDragged(double mouseX, double mouseY, int i, double j, double k) {
if (this.isScrolling) {
float percentage = MathHelper.clamp(((float) mouseY - (this.guiTop + 32 + 18)) / (58 - 15), 0, 1);
int offset = (int) (percentage * (float) (this.tags.size() - 5));
if (offset != this.scrollOffset) {
this.scrollOffset = offset;
this.updateWidgets();
}
return true;
}
return super.mouseDragged(mouseX, mouseY, i, j, k);
}
@Override
public boolean mouseScrolled(double x, double y, double scroll) {
if (this.tags.size() >= 6) {
int offset = MathHelper.clamp(this.scrollOffset - (int) Math.signum(scroll), 0, this.tags.size() - 5);
if (offset != this.scrollOffset) {
this.scrollOffset = offset;
this.updateWidgets();
}
}
return true;
}
private void updateWidgets() {
this.tagButtons.clear();
for (int i = 0; i < 5; i++) {
if (i >= this.tags.size())
break;
this.tagButtons.add(new Tag(this.tags.get(this.scrollOffset + i), this.guiLeft + 10, this.guiTop + 32 + 17 + i * 12));
}
}
private class Tag {
private final ResourceLocation tag;
private final int x;
private final int y;
public Tag(ResourceLocation tag, int x, int y) {
this.tag = tag;
this.x = x;
this.y = y;
}
private void draw(MatrixStack matrix, double mouseX, double mouseY) {
int color = 4210752;
String text = this.tag.toString();
if (mouseX >= this.x && mouseY >= this.y && mouseX < this.x + 140 && mouseY < this.y + 12)
color = 0xFFFFFF;
if (this.tag.equals(FilterModifierModuleItem.getFilterTag(FilterModifierModuleGui.this.container.moduleStack)))
text = TextFormatting.BOLD + text;
FilterModifierModuleGui.this.font.drawString(matrix, text, this.x, this.y, color);
FilterModifierModuleGui.this.getMinecraft().getTextureManager().bindTexture(TEXTURE);
}
private boolean onClicked(double mouseX, double mouseY, int button) {
if (button != 0)
return false;
if (mouseX < this.x || mouseY < this.y || mouseX >= this.x + 140 || mouseY >= this.y + 12)
return false;
PacketButton.sendAndExecute(FilterModifierModuleGui.this.container.tile.getPos(), PacketButton.ButtonResult.TAG_FILTER, FilterModifierModuleGui.this.tags.indexOf(this.tag));
FilterModifierModuleGui.this.getMinecraft().getSoundHandler().play(SimpleSound.master(SoundEvents.UI_BUTTON_CLICK, 1));
return true;
}
}
}

View file

@ -0,0 +1,71 @@
package de.ellpeck.prettypipes.pipe.modules.modifier;
import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.items.IModule;
import de.ellpeck.prettypipes.items.ModuleItem;
import de.ellpeck.prettypipes.misc.ItemEquality;
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer;
import joptsimple.internal.Strings;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import javax.annotation.Nullable;
import java.util.List;
public class FilterModifierModuleItem extends ModuleItem {
public final ItemEquality.Type type;
public FilterModifierModuleItem(String name, ItemEquality.Type type) {
super(name);
this.type = type;
this.setRegistryName(name);
}
@Override
public boolean isCompatible(ItemStack module, PipeTileEntity tile, IModule other) {
return other != this;
}
@Override
public boolean hasContainer(ItemStack module, PipeTileEntity tile) {
return this.type == ItemEquality.Type.TAG;
}
@Override
public AbstractPipeContainer<?> getContainer(ItemStack module, PipeTileEntity tile, int windowId, PlayerInventory inv, PlayerEntity player, int moduleIndex) {
return new FilterModifierModuleContainer(Registry.filterModifierModuleContainer, windowId, player, tile.getPos(), moduleIndex);
}
@Override
public void addInformation(ItemStack stack, @Nullable World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) {
super.addInformation(stack, worldIn, tooltip, flagIn);
}
public ItemEquality getEqualityType(ItemStack stack) {
if (this.type == ItemEquality.Type.TAG) {
return ItemEquality.tag(getFilterTag(stack));
} else {
return this.type.getDefaultInstance();
}
}
public static ResourceLocation getFilterTag(ItemStack stack) {
if (!stack.hasTag())
return null;
String tag = stack.getTag().getString("filter_tag");
if (Strings.isNullOrEmpty(tag))
return null;
return new ResourceLocation(tag);
}
public static void setFilterTag(ItemStack stack, ResourceLocation tag) {
stack.getOrCreateTag().putString("filter_tag", tag.toString());
}
}

View file

@ -4,7 +4,7 @@ import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.items.IModule; import de.ellpeck.prettypipes.items.IModule;
import de.ellpeck.prettypipes.items.ModuleItem; import de.ellpeck.prettypipes.items.ModuleItem;
import de.ellpeck.prettypipes.items.ModuleTier; import de.ellpeck.prettypipes.items.ModuleTier;
import de.ellpeck.prettypipes.misc.ItemEqualityType; import de.ellpeck.prettypipes.misc.ItemEquality;
import de.ellpeck.prettypipes.misc.ItemFilter; import de.ellpeck.prettypipes.misc.ItemFilter;
import de.ellpeck.prettypipes.network.PipeNetwork; import de.ellpeck.prettypipes.network.PipeNetwork;
import de.ellpeck.prettypipes.pipe.PipeTileEntity; import de.ellpeck.prettypipes.pipe.PipeTileEntity;
@ -35,7 +35,7 @@ public class RetrievalModuleItem extends ModuleItem {
return; return;
PipeNetwork network = PipeNetwork.get(tile.getWorld()); PipeNetwork network = PipeNetwork.get(tile.getWorld());
ItemEqualityType[] equalityTypes = ItemFilter.getEqualityTypes(tile); ItemEquality[] equalityTypes = ItemFilter.getEqualityTypes(tile);
// loop through filters to see which items to pull // loop through filters to see which items to pull
for (ItemFilter subFilter : tile.getFilters()) { for (ItemFilter subFilter : tile.getFilters()) {
for (int f = 0; f < subFilter.getSlots(); f++) { for (int f = 0; f < subFilter.getSlots(); f++) {

View file

@ -3,7 +3,7 @@ package de.ellpeck.prettypipes.pipe.modules.stacksize;
import de.ellpeck.prettypipes.Registry; import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.items.IModule; import de.ellpeck.prettypipes.items.IModule;
import de.ellpeck.prettypipes.items.ModuleItem; import de.ellpeck.prettypipes.items.ModuleItem;
import de.ellpeck.prettypipes.misc.ItemEqualityType; import de.ellpeck.prettypipes.misc.ItemEquality;
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;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
@ -51,7 +51,7 @@ public class StackSizeModuleItem extends ModuleItem {
ItemStack stored = destination.getStackInSlot(i); ItemStack stored = destination.getStackInSlot(i);
if (stored.isEmpty()) if (stored.isEmpty())
continue; continue;
if (!ItemEqualityType.compareItems(stored, stack)) if (!ItemEquality.compareItems(stored, stack))
continue; continue;
amount += stored.getCount(); amount += stored.getCount();
if (amount >= max) if (amount >= max)

View file

@ -5,10 +5,8 @@ import com.google.common.collect.ListMultimap;
import de.ellpeck.prettypipes.PrettyPipes; 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.ModuleItem;
import de.ellpeck.prettypipes.misc.EquatableItemStack; import de.ellpeck.prettypipes.misc.EquatableItemStack;
import de.ellpeck.prettypipes.misc.ItemEqualityType; import de.ellpeck.prettypipes.misc.ItemEquality;
import de.ellpeck.prettypipes.network.NetworkItem; import de.ellpeck.prettypipes.network.NetworkItem;
import de.ellpeck.prettypipes.network.NetworkLocation; import de.ellpeck.prettypipes.network.NetworkLocation;
import de.ellpeck.prettypipes.network.PipeNetwork; import de.ellpeck.prettypipes.network.PipeNetwork;
@ -79,17 +77,17 @@ public class CraftingTerminalTileEntity extends ItemTerminalTileEntity {
for (ItemStack stack : items) { for (ItemStack stack : items) {
int amount = 0; int amount = 0;
// check existing items // check existing items
NetworkItem network = this.networkItems.get(new EquatableItemStack(stack, ItemEqualityType.NBT)); NetworkItem network = this.networkItems.get(new EquatableItemStack(stack, ItemEquality.NBT));
if (network != null) { if (network != null) {
amount = network.getLocations().stream() amount = network.getLocations().stream()
.mapToInt(l -> l.getItemAmount(this.world, stack, ItemEqualityType.NBT)) .mapToInt(l -> l.getItemAmount(this.world, stack, ItemEquality.NBT))
.sum(); .sum();
} }
// check craftables // check craftables
if (amount <= 0 && highestAmount <= 0) { if (amount <= 0 && highestAmount <= 0) {
PipeTileEntity pipe = this.getConnectedPipe(); PipeTileEntity pipe = this.getConnectedPipe();
if (pipe != null) if (pipe != null)
amount = PipeNetwork.get(this.world).getCraftableAmount(pipe.getPos(), null, stack, new Stack<>(), ItemEqualityType.NBT); amount = PipeNetwork.get(this.world).getCraftableAmount(pipe.getPos(), null, stack, new Stack<>(), ItemEquality.NBT);
} }
if (amount > highestAmount) { if (amount > highestAmount) {
highestAmount = amount; highestAmount = amount;
@ -119,7 +117,7 @@ public class CraftingTerminalTileEntity extends ItemTerminalTileEntity {
int lowestAvailable = getAvailableCrafts(pipe, this.craftItems.getSlots(), i -> ItemHandlerHelper.copyStackWithSize(this.getRequestedCraftItem(i), 1), this::isGhostItem, s -> { int lowestAvailable = getAvailableCrafts(pipe, this.craftItems.getSlots(), i -> ItemHandlerHelper.copyStackWithSize(this.getRequestedCraftItem(i), 1), this::isGhostItem, s -> {
NetworkItem item = this.networkItems.get(s); NetworkItem item = this.networkItems.get(s);
return item != null ? item.getLocations() : Collections.emptyList(); return item != null ? item.getLocations() : Collections.emptyList();
}, onItemUnavailable(player), new Stack<>(), ItemEqualityType.NBT); }, onItemUnavailable(player), new Stack<>(), ItemEquality.NBT);
if (lowestAvailable > 0) { if (lowestAvailable > 0) {
// if we're limiting the amount, pretend we only have that amount available // if we're limiting the amount, pretend we only have that amount available
if (maxAmount < lowestAvailable) if (maxAmount < lowestAvailable)
@ -196,7 +194,7 @@ public class CraftingTerminalTileEntity extends ItemTerminalTileEntity {
return remain; return remain;
} }
public static int getAvailableCrafts(PipeTileEntity tile, int slots, Function<Integer, ItemStack> inputFunction, Predicate<Integer> isGhost, Function<EquatableItemStack, Collection<NetworkLocation>> locationsFunction, Consumer<ItemStack> unavailableConsumer, Stack<ItemStack> dependencyChain, ItemEqualityType... equalityTypes) { public static int getAvailableCrafts(PipeTileEntity tile, int slots, Function<Integer, ItemStack> inputFunction, Predicate<Integer> isGhost, Function<EquatableItemStack, Collection<NetworkLocation>> locationsFunction, Consumer<ItemStack> unavailableConsumer, Stack<ItemStack> dependencyChain, ItemEquality... equalityTypes) {
PipeNetwork network = PipeNetwork.get(tile.getWorld()); PipeNetwork network = PipeNetwork.get(tile.getWorld());
// the highest amount we can craft with the items we have // the highest amount we can craft with the items we have
int lowestAvailable = Integer.MAX_VALUE; int lowestAvailable = Integer.MAX_VALUE;

View file

@ -4,7 +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.misc.EquatableItemStack; import de.ellpeck.prettypipes.misc.EquatableItemStack;
import de.ellpeck.prettypipes.misc.ItemEqualityType; import de.ellpeck.prettypipes.misc.ItemEquality;
import de.ellpeck.prettypipes.network.NetworkItem; import de.ellpeck.prettypipes.network.NetworkItem;
import de.ellpeck.prettypipes.network.NetworkLocation; import de.ellpeck.prettypipes.network.NetworkLocation;
import de.ellpeck.prettypipes.network.NetworkLock; import de.ellpeck.prettypipes.network.NetworkLock;
@ -91,7 +91,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
if (!this.existingRequests.isEmpty()) { if (!this.existingRequests.isEmpty()) {
NetworkLock request = this.existingRequests.remove(); NetworkLock request = this.existingRequests.remove();
network.resolveNetworkLock(request); network.resolveNetworkLock(request);
network.requestExistingItem(request.location, pipe.getPos(), this.pos, request, request.stack, ItemEqualityType.NBT); network.requestExistingItem(request.location, pipe.getPos(), this.pos, request, request.stack, ItemEquality.NBT);
update = true; update = true;
} }
} }
@ -126,7 +126,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
PipeTileEntity pipe = this.getConnectedPipe(); PipeTileEntity pipe = this.getConnectedPipe();
if (pipe == null) if (pipe == null)
return; return;
this.networkItems = this.collectItems(ItemEqualityType.NBT); this.networkItems = this.collectItems(ItemEquality.NBT);
if (playersToSync.length > 0) { if (playersToSync.length > 0) {
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 = PipeNetwork.get(this.world).getAllCraftables(pipe.getPos()).stream().map(Pair::getRight).collect(Collectors.toList()); List<ItemStack> clientCraftables = PipeNetwork.get(this.world).getAllCraftables(pipe.getPos()).stream().map(Pair::getRight).collect(Collectors.toList());
@ -156,9 +156,9 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
} }
public int requestItemImpl(ItemStack stack, Consumer<ItemStack> unavailableConsumer) { public int requestItemImpl(ItemStack stack, Consumer<ItemStack> unavailableConsumer) {
NetworkItem item = this.networkItems.get(new EquatableItemStack(stack, ItemEqualityType.NBT)); NetworkItem item = this.networkItems.get(new EquatableItemStack(stack, ItemEquality.NBT));
Collection<NetworkLocation> locations = item == null ? Collections.emptyList() : item.getLocations(); Collection<NetworkLocation> locations = item == null ? Collections.emptyList() : item.getLocations();
Pair<List<NetworkLock>, ItemStack> ret = requestItemLater(this.world, this.getConnectedPipe().getPos(), locations, unavailableConsumer, stack, new Stack<>(), ItemEqualityType.NBT); Pair<List<NetworkLock>, ItemStack> ret = requestItemLater(this.world, this.getConnectedPipe().getPos(), locations, unavailableConsumer, stack, new Stack<>(), ItemEquality.NBT);
this.existingRequests.addAll(ret.getLeft()); this.existingRequests.addAll(ret.getLeft());
return stack.getCount() - ret.getRight().getCount(); return stack.getCount() - ret.getRight().getCount();
} }
@ -170,7 +170,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
.toArray(PlayerEntity[]::new); .toArray(PlayerEntity[]::new);
} }
private Map<EquatableItemStack, NetworkItem> collectItems(ItemEqualityType... equalityTypes) { private Map<EquatableItemStack, NetworkItem> collectItems(ItemEquality... equalityTypes) {
PipeNetwork network = PipeNetwork.get(this.world); PipeNetwork network = PipeNetwork.get(this.world);
network.startProfile("terminal_collect_items"); network.startProfile("terminal_collect_items");
PipeTileEntity pipe = this.getConnectedPipe(); PipeTileEntity pipe = this.getConnectedPipe();
@ -269,7 +269,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
return true; return true;
} }
public static Pair<List<NetworkLock>, ItemStack> requestItemLater(World world, BlockPos destPipe, Collection<NetworkLocation> locations, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain, ItemEqualityType... equalityTypes) { public static Pair<List<NetworkLock>, ItemStack> requestItemLater(World world, BlockPos destPipe, Collection<NetworkLocation> locations, Consumer<ItemStack> unavailableConsumer, ItemStack stack, Stack<ItemStack> dependencyChain, ItemEquality... equalityTypes) {
List<NetworkLock> requests = new ArrayList<>(); List<NetworkLock> requests = new ArrayList<>();
ItemStack remain = stack.copy(); ItemStack remain = stack.copy();
PipeNetwork network = PipeNetwork.get(world); PipeNetwork network = PipeNetwork.get(world);

View file

@ -43,7 +43,7 @@
"info.prettypipes.stack_size_module": "Limits the amount of items that can enter adjacent inventories\nAutomatically prevents over-sending", "info.prettypipes.stack_size_module": "Limits the amount of items that can enter adjacent inventories\nAutomatically prevents over-sending",
"info.prettypipes.damage_filter_modifier": "Causes any filter slots to filter by item damage", "info.prettypipes.damage_filter_modifier": "Causes any filter slots to filter by item damage",
"info.prettypipes.nbt_filter_modifier": "Causes any filter slots to filter by item data (NBT)", "info.prettypipes.nbt_filter_modifier": "Causes any filter slots to filter by item data (NBT)",
"info.prettypipes.tag_filter_modifier": "Causes any filter slots to filter by tags\n(Modern equivalent of the Ore Dictionary)", "info.prettypipes.tag_filter_modifier": "Causes any filter slots to filter by tags\nTag can be chosen from items in filter slots",
"info.prettypipes.mod_filter_modifier": "Causes any filter slots to filter by mod", "info.prettypipes.mod_filter_modifier": "Causes any filter slots to filter by mod",
"info.prettypipes.redstone_module": "Allows disabling the pipe with a redstone signal\nWorks for both extraction and retrieval", "info.prettypipes.redstone_module": "Allows disabling the pipe with a redstone signal\nWorks for both extraction and retrieval",
"info.prettypipes.item_terminal": "Allows viewing and requesting all items in a pipe network\nAlso has slots for putting items into the network", "info.prettypipes.item_terminal": "Allows viewing and requesting all items in a pipe network\nAlso has slots for putting items into the network",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB