Files
StructureLib/src/main/java/com/gtnewhorizon/structurelib/util/ItemStackPredicate.java
T

112 lines
3.9 KiB
Java
Raw Normal View History

2022-08-08 17:40:12 +08:00
package com.gtnewhorizon.structurelib.util;
import java.util.Objects;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
import net.minecraft.block.Block;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
public final class ItemStackPredicate implements Predicate<ItemStack> {
public static ItemStackPredicate from(Item item) {
return new ItemStackPredicate(item);
}
public static ItemStackPredicate from(ItemStack itemStack) {
return new ItemStackPredicate(itemStack.getItem()).setMeta(Items.feather.getDamage(itemStack));
}
public static ItemStackPredicate from(ItemStack itemStack, NBTMode mode) {
return new ItemStackPredicate(itemStack.getItem())
.setMeta(Items.feather.getDamage(itemStack))
.setTag(mode, itemStack.stackTagCompound);
}
public static ItemStackPredicate from(Block block) {
return new ItemStackPredicate(Item.getItemFromBlock(block));
}
private final Item item;
private int meta = -1;
private NBTTagCompound tag;
private NBTMode mode = NBTMode.IGNORE;
private ItemStackPredicate(Item item) {
this.item = item;
}
public ItemStackPredicate ignoreMeta() {
this.meta = -1;
return this;
}
public ItemStackPredicate setMeta(int meta) {
this.meta = meta;
return this;
}
public ItemStackPredicate setTag(NBTMode mode, NBTTagCompound tag) {
this.mode = mode;
this.tag = tag;
return this;
}
@Override
public boolean test(ItemStack itemStack) {
if (item != null) if (itemStack.getItem() != item) return false;
if (meta != -1) if (Items.feather.getDamage(itemStack) != meta) return false;
return mode.test(tag, itemStack.stackTagCompound);
}
public enum NBTMode implements BiPredicate<NBTTagCompound, NBTTagCompound> {
IGNORE {
@Override
public boolean test(NBTTagCompound lhs, NBTTagCompound rhs) {
return true;
}
},
IN {
@Override
public boolean test(NBTTagCompound lhs, NBTTagCompound rhs) {
if (lhs == null || lhs.hasNoTags()) return true;
if (rhs == null || rhs.hasNoTags()) return false;
for (String key : MiscUtils.getTagKeys(lhs)) {
if (!rhs.hasKey(key, lhs.func_150299_b(key))) return false;
NBTBase tag = lhs.getTag(key);
if (tag instanceof NBTTagCompound) {
if (!test((NBTTagCompound) tag, rhs.getCompoundTag(key))) return false;
} else {
if (!tag.equals(rhs.getTag(key))) return false;
}
}
return true;
}
},
EXACT {
@Override
public boolean test(NBTTagCompound lhs, NBTTagCompound rhs) {
if (lhs != null && lhs.hasNoTags()) lhs = null;
if (rhs != null && rhs.hasNoTags()) rhs = null;
return Objects.equals(lhs, rhs);
}
},
IGNORE_KNOWN_INSIGNIFICANT_TAGS {
@Override
public boolean test(NBTTagCompound lhs, NBTTagCompound rhs) {
// fast path for empty tags
if (rhs == null || rhs.hasNoTags()) return lhs == null || lhs.hasNoTags();
// TODO make an implementation without copying a potentially huge tag
rhs = (NBTTagCompound) rhs.copy();
for (String s : KNOWN_INSIGNIFICANT_TAGS) rhs.removeTag(s);
return EXACT.test(lhs, rhs);
}
};
private static final String[] KNOWN_INSIGNIFICANT_TAGS = {
"display", // TODO expand/refine this
};
}
}