generalize item equality to fix some requesting inconsistencies

This commit is contained in:
Ellpeck 2020-05-08 02:51:07 +02:00
parent 157c6e4d8c
commit 320abbe74e
11 changed files with 73 additions and 47 deletions

View file

@ -3,6 +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.pipe.modules.FilterModifierModule; import de.ellpeck.prettypipes.pipe.modules.FilterModifierModule;
import de.ellpeck.prettypipes.pipe.modules.LowPriorityModuleItem; import de.ellpeck.prettypipes.pipe.modules.LowPriorityModuleItem;
import de.ellpeck.prettypipes.pipe.modules.RedstoneModuleItem; import de.ellpeck.prettypipes.pipe.modules.RedstoneModuleItem;
@ -116,7 +117,7 @@ public final class Registry {
registry.registerAll(createTieredModule("low_priority_module", LowPriorityModuleItem::new)); registry.registerAll(createTieredModule("low_priority_module", LowPriorityModuleItem::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(FilterModifierModule.Type.values()).map(t -> new FilterModifierModule(t.name().toLowerCase(Locale.ROOT) + "_filter_modifier", t)).toArray(Item[]::new)); registry.registerAll(Arrays.stream(ItemEqualityType.values()).map(t -> new FilterModifierModule(t.name().toLowerCase(Locale.ROOT) + "_filter_modifier", t)).toArray(Item[]::new));
registry.register(new RedstoneModuleItem("redstone_module")); registry.register(new RedstoneModuleItem("redstone_module"));
ForgeRegistries.BLOCKS.getValues().stream() ForgeRegistries.BLOCKS.getValues().stream()

View file

@ -68,7 +68,7 @@ public class PipeFrameEntity extends ItemFrameEntity implements IEntityAdditiona
ItemStack stack = this.getDisplayedItem(); ItemStack stack = this.getDisplayedItem();
if (!stack.isEmpty()) { if (!stack.isEmpty()) {
List<NetworkLocation> items = network.getOrderedNetworkItems(node); List<NetworkLocation> items = network.getOrderedNetworkItems(node);
int amount = items.stream().mapToInt(i -> i.getItemAmount(stack, false)).sum(); int amount = items.stream().mapToInt(i -> i.getItemAmount(stack)).sum();
this.dataManager.set(AMOUNT, amount); this.dataManager.set(AMOUNT, amount);
return; return;
} }

View file

@ -15,7 +15,7 @@ public class EquatableItemStack {
public boolean equals(Object o) { public boolean equals(Object o) {
if (o instanceof EquatableItemStack) { if (o instanceof EquatableItemStack) {
ItemStack other = ((EquatableItemStack) o).stack; ItemStack other = ((EquatableItemStack) o).stack;
return ItemStack.areItemsEqual(this.stack, other) && ItemStack.areItemStackTagsEqual(this.stack, other); return ItemEqualityType.compareItems(this.stack, other, ItemEqualityType.NBT);
} }
return false; return false;
} }

View file

@ -0,0 +1,42 @@
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);
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

@ -97,27 +97,25 @@ public class ItemFilter extends ItemStackHandler {
} }
private boolean isFiltered(ItemStack stack) { private boolean isFiltered(ItemStack stack) {
List<FilterModifierModule.Type> modifiers = this.pipe.streamModules() ItemEqualityType[] types = this.getEqualityTypes();
.map(Pair::getRight)
.filter(m -> m instanceof FilterModifierModule)
.map(m -> ((FilterModifierModule) m).type)
.collect(Collectors.toList());
for (int i = 0; i < this.getSlots(); i++) { for (int i = 0; i < this.getSlots(); i++) {
ItemStack filter = this.getStackInSlot(i); ItemStack filter = this.getStackInSlot(i);
if (filter.isEmpty()) if (filter.isEmpty())
continue; continue;
boolean equal = ItemStack.areItemsEqual(stack, filter); if (ItemEqualityType.compareItems(stack, filter, types))
if (modifiers.isEmpty()) { return true;
if (equal)
return true;
} else {
if (modifiers.stream().allMatch(m -> (m.ignoreItemEquality || equal) && m.filter.apply(stack, filter)))
return true;
}
} }
return false; return false;
} }
public ItemEqualityType[] getEqualityTypes() {
return this.pipe.streamModules()
.map(Pair::getRight)
.filter(m -> m instanceof FilterModifierModule)
.map(m -> ((FilterModifierModule) m).type)
.toArray(ItemEqualityType[]::new);
}
public void save() { public void save() {
this.stack.getOrCreateTag().put("filter", this.serializeNBT()); this.stack.getOrCreateTag().put("filter", this.serializeNBT());
} }

View file

@ -2,6 +2,7 @@ package de.ellpeck.prettypipes.network;
import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap; import com.google.common.collect.ListMultimap;
import de.ellpeck.prettypipes.misc.ItemEqualityType;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -32,18 +33,18 @@ public class NetworkLocation {
this.items.put(slot, stack); this.items.put(slot, stack);
} }
public List<Integer> getStackSlots(ItemStack stack) { public List<Integer> getStackSlots(ItemStack stack, ItemEqualityType... equalityTypes) {
if (this.isEmpty()) if (this.isEmpty())
return Collections.emptyList(); return Collections.emptyList();
return this.items.entrySet().stream() return this.items.entrySet().stream()
.filter(e -> e.getValue().isItemEqual(stack)) .filter(e -> ItemEqualityType.compareItems(e.getValue(), stack, equalityTypes))
.map(Map.Entry::getKey) .map(Map.Entry::getKey)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
public int getItemAmount(ItemStack stack, boolean compareTag) { public int getItemAmount(ItemStack stack, ItemEqualityType... equalityTypes) {
return this.items.values().stream() return this.items.values().stream()
.filter(i -> ItemStack.areItemsEqual(i, stack) && (!compareTag || ItemStack.areItemStackTagsEqual(i, stack))) .filter(i -> ItemEqualityType.compareItems(stack, i, equalityTypes))
.mapToInt(ItemStack::getCount).sum(); .mapToInt(ItemStack::getCount).sum();
} }

View file

@ -6,6 +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.pipe.PipeBlock; import de.ellpeck.prettypipes.pipe.PipeBlock;
import de.ellpeck.prettypipes.pipe.PipeTileEntity; import de.ellpeck.prettypipes.pipe.PipeTileEntity;
import de.ellpeck.prettypipes.packets.PacketHandler; import de.ellpeck.prettypipes.packets.PacketHandler;
@ -329,9 +330,9 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
return ret; return ret;
} }
public int getItemsOnTheWay(BlockPos goalPipe, ItemStack type) { public int getItemsOnTheWay(BlockPos goalPipe, ItemStack type, ItemEqualityType... equalityTypes) {
return this.getPipeItemsOnTheWay(goalPipe) return this.getPipeItemsOnTheWay(goalPipe)
.filter(i -> i.stack.isItemEqual(type)) .filter(i -> ItemEqualityType.compareItems(i.stack, type, equalityTypes))
.mapToInt(i -> i.stack.getCount()).sum(); .mapToInt(i -> i.stack.getCount()).sum();
} }

View file

@ -2,6 +2,7 @@ package de.ellpeck.prettypipes.pipe.modules;
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.pipe.PipeTileEntity; import de.ellpeck.prettypipes.pipe.PipeTileEntity;
import net.minecraft.client.util.ITooltipFlag; import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -16,9 +17,9 @@ import java.util.function.BiFunction;
public class FilterModifierModule extends ModuleItem { public class FilterModifierModule extends ModuleItem {
public final Type type; public final ItemEqualityType type;
public FilterModifierModule(String name, Type type) { public FilterModifierModule(String name, ItemEqualityType type) {
super(name); super(name);
this.type = type; this.type = type;
this.setRegistryName(name); this.setRegistryName(name);
@ -38,24 +39,4 @@ public class FilterModifierModule extends ModuleItem {
public void addInformation(ItemStack stack, @Nullable World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) { public void addInformation(ItemStack stack, @Nullable World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) {
super.addInformation(stack, worldIn, tooltip, flagIn); super.addInformation(stack, worldIn, tooltip, flagIn);
} }
public enum Type {
DAMAGE(false, (stack, filter) -> stack.getDamage() == filter.getDamage()),
NBT(false, ItemStack::areItemStackTagsEqual),
TAG(true, (stack, filter) -> {
Set<ResourceLocation> stackTags = stack.getItem().getTags();
Set<ResourceLocation> filterTags = filter.getItem().getTags();
if (filterTags.isEmpty())
return false;
return stackTags.containsAll(filterTags);
});
public final boolean ignoreItemEquality;
public final BiFunction<ItemStack, ItemStack, Boolean> filter;
Type(boolean ignoreItemEquality, BiFunction<ItemStack, ItemStack, Boolean> filter) {
this.ignoreItemEquality = ignoreItemEquality;
this.filter = filter;
}
}
} }

View file

@ -58,7 +58,7 @@ public class RetrievalModuleItem extends ModuleItem {
for (NetworkLocation location : locations) { for (NetworkLocation location : locations) {
if (location.pipePos.equals(tile.getPos())) if (location.pipePos.equals(tile.getPos()))
continue; continue;
for (int slot : location.getStackSlots(filtered)) { for (int slot : location.getStackSlots(filtered, filter.getEqualityTypes())) {
// try to extract from that location's inventory and send the item // try to extract from that location's inventory and send the item
ItemStack stack = location.handler.extractItem(slot, this.maxExtraction, true); ItemStack stack = location.handler.extractItem(slot, this.maxExtraction, true);
if (network.routeItemToLocation(location.pipePos, location.pos, tile.getPos(), dest, speed -> new PipeItem(stack, speed))) { if (network.routeItemToLocation(location.pipePos, location.pos, tile.getPos(), dest, speed -> new PipeItem(stack, speed))) {

View file

@ -3,6 +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.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;
@ -50,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 (!stored.isItemEqual(stack)) if (!ItemEqualityType.compareItems(stored, stack))
continue; continue;
amount += stored.getCount(); amount += stored.getCount();
if (amount >= max) if (amount >= max)

View file

@ -4,6 +4,7 @@ import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.Registry; import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.Utility; import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.misc.EquatableItemStack; import de.ellpeck.prettypipes.misc.EquatableItemStack;
import de.ellpeck.prettypipes.misc.ItemEqualityType;
import de.ellpeck.prettypipes.misc.ItemOrder; import de.ellpeck.prettypipes.misc.ItemOrder;
import de.ellpeck.prettypipes.network.NetworkItem; import de.ellpeck.prettypipes.network.NetworkItem;
import de.ellpeck.prettypipes.network.NetworkLocation; import de.ellpeck.prettypipes.network.NetworkLocation;
@ -136,7 +137,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
int remain = stack.getCount(); int remain = stack.getCount();
locations: locations:
for (NetworkLocation location : item.getLocations()) { for (NetworkLocation location : item.getLocations()) {
for (int slot : location.getStackSlots(stack)) { for (int slot : location.getStackSlots(stack, ItemEqualityType.NBT)) {
ItemStack extracted = location.handler.extractItem(slot, remain, true); ItemStack extracted = location.handler.extractItem(slot, remain, true);
if (!extracted.isEmpty()) { if (!extracted.isEmpty()) {
this.pendingRequests.add(Triple.of(location, slot, extracted.getCount())); this.pendingRequests.add(Triple.of(location, slot, extracted.getCount()));