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.PipeFrameRenderer;
import de.ellpeck.prettypipes.items.*;
import de.ellpeck.prettypipes.misc.ItemEqualityType;
import de.ellpeck.prettypipes.pipe.modules.FilterModifierModule;
import de.ellpeck.prettypipes.pipe.modules.LowPriorityModuleItem;
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("retrieval_module", RetrievalModuleItem::new));
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"));
ForgeRegistries.BLOCKS.getValues().stream()

View file

@ -68,7 +68,7 @@ public class PipeFrameEntity extends ItemFrameEntity implements IEntityAdditiona
ItemStack stack = this.getDisplayedItem();
if (!stack.isEmpty()) {
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);
return;
}

View file

@ -15,7 +15,7 @@ public class EquatableItemStack {
public boolean equals(Object o) {
if (o instanceof EquatableItemStack) {
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;
}

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) {
List<FilterModifierModule.Type> modifiers = this.pipe.streamModules()
.map(Pair::getRight)
.filter(m -> m instanceof FilterModifierModule)
.map(m -> ((FilterModifierModule) m).type)
.collect(Collectors.toList());
ItemEqualityType[] types = this.getEqualityTypes();
for (int i = 0; i < this.getSlots(); i++) {
ItemStack filter = this.getStackInSlot(i);
if (filter.isEmpty())
continue;
boolean equal = ItemStack.areItemsEqual(stack, filter);
if (modifiers.isEmpty()) {
if (equal)
return true;
} else {
if (modifiers.stream().allMatch(m -> (m.ignoreItemEquality || equal) && m.filter.apply(stack, filter)))
return true;
}
if (ItemEqualityType.compareItems(stack, filter, types))
return true;
}
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() {
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.ListMultimap;
import de.ellpeck.prettypipes.misc.ItemEqualityType;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
@ -32,18 +33,18 @@ public class NetworkLocation {
this.items.put(slot, stack);
}
public List<Integer> getStackSlots(ItemStack stack) {
public List<Integer> getStackSlots(ItemStack stack, ItemEqualityType... equalityTypes) {
if (this.isEmpty())
return Collections.emptyList();
return this.items.entrySet().stream()
.filter(e -> e.getValue().isItemEqual(stack))
.filter(e -> ItemEqualityType.compareItems(e.getValue(), stack, equalityTypes))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
public int getItemAmount(ItemStack stack, boolean compareTag) {
public int getItemAmount(ItemStack stack, ItemEqualityType... equalityTypes) {
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();
}

View file

@ -6,6 +6,7 @@ import com.google.common.collect.Streams;
import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.misc.ItemEqualityType;
import de.ellpeck.prettypipes.pipe.PipeBlock;
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
import de.ellpeck.prettypipes.packets.PacketHandler;
@ -329,9 +330,9 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
return ret;
}
public int getItemsOnTheWay(BlockPos goalPipe, ItemStack type) {
public int getItemsOnTheWay(BlockPos goalPipe, ItemStack type, ItemEqualityType... equalityTypes) {
return this.getPipeItemsOnTheWay(goalPipe)
.filter(i -> i.stack.isItemEqual(type))
.filter(i -> ItemEqualityType.compareItems(i.stack, type, equalityTypes))
.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.ModuleItem;
import de.ellpeck.prettypipes.misc.ItemEqualityType;
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.ItemStack;
@ -16,9 +17,9 @@ import java.util.function.BiFunction;
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);
this.type = type;
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) {
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) {
if (location.pipePos.equals(tile.getPos()))
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
ItemStack stack = location.handler.extractItem(slot, this.maxExtraction, true);
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.items.IModule;
import de.ellpeck.prettypipes.items.ModuleItem;
import de.ellpeck.prettypipes.misc.ItemEqualityType;
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer;
import net.minecraft.entity.player.PlayerEntity;
@ -50,7 +51,7 @@ public class StackSizeModuleItem extends ModuleItem {
ItemStack stored = destination.getStackInSlot(i);
if (stored.isEmpty())
continue;
if (!stored.isItemEqual(stack))
if (!ItemEqualityType.compareItems(stored, stack))
continue;
amount += stored.getCount();
if (amount >= max)

View file

@ -4,6 +4,7 @@ import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.misc.EquatableItemStack;
import de.ellpeck.prettypipes.misc.ItemEqualityType;
import de.ellpeck.prettypipes.misc.ItemOrder;
import de.ellpeck.prettypipes.network.NetworkItem;
import de.ellpeck.prettypipes.network.NetworkLocation;
@ -136,7 +137,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
int remain = stack.getCount();
locations:
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);
if (!extracted.isEmpty()) {
this.pendingRequests.add(Triple.of(location, slot, extracted.getCount()));