Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package de.dafuqs.spectrum.api.block;

import de.dafuqs.spectrum.*;
import de.dafuqs.spectrum.registries.*;
import it.unimi.dsi.fastutil.objects.*;
import net.fabricmc.fabric.api.transfer.v1.item.*;
import net.minecraft.item.*;
import net.minecraft.registry.*;
import net.minecraft.registry.tag.*;
import net.minecraft.util.*;
import org.apache.commons.lang3.*;

import java.util.*;

@SuppressWarnings("UnstableApiUsage")
public interface TagFilteringInventory {

List<ItemVariant> getItemFilters();
default Object2BooleanMap<TagKey<Item>> getFilteredTags() { return Object2BooleanMaps.emptyMap(); }
default boolean onlyDenyListTags() { return true; }
default void setOnlyDenyListTags(boolean onlyDenyListTags) { }

default boolean acceptsItem(Item item) {
if (item == null || item.equals(Items.AIR)) { return false; }

if (!this.getFilteredTags().isEmpty()) {
int returnValue = 0;
// Latest takes precedence. 1 for if it's allowed, -1 for if it's denied.
for(TagKey<Item> tag : this.getFilteredTags().keySet()) {
if(item.getRegistryEntry().isIn(tag)) { returnValue = this.getFilteredTags().getBoolean(tag) ? 1 : -1; }
}
if(returnValue != 0) { return returnValue == 1; }
// If we only have denyList tags, treat not being in any as am implicit c:everything.
if(this.onlyDenyListTags()) { return true; }
}

boolean allAir = true;
for (ItemVariant filterItem: this.getItemFilters()) {
if (filterItem.getItem().equals(item)) { return true; }
if (!filterItem.getItem().equals(Items.AIR)) { allAir = false; }
}
return allAir;
}

// Run on NBT read.
default void clearFilters() {
this.getFilteredTags().clear();
this.setOnlyDenyListTags(true);
}

default boolean addTagFilteringItem(ItemVariant itemVariant) {
ItemStack stack = itemVariant.toStack();
if (!stack.hasCustomName() || !stack.isIn(SpectrumItemTags.TAG_FILTERING_ITEMS)) {
this.setOnlyDenyListTags(false);
return false;
}
String name = StringUtils.trim(stack.getName().getString());
if (StringUtils.equalsAnyIgnoreCase(name, "*", "any", "all", "everything", "c:*", "c:any", "c:all", "c:everything")) {
this.setOnlyDenyListTags(true);
return true;
}

boolean allow = !name.startsWith("!");
Identifier identifier = Identifier.tryParse(StringUtils.remove(allow ? name : name.substring(1), '#'));
if(identifier == null) { return false; }

// Copied from PastelNodeBlockEntity. This entire section could potentially be a candidate to move into its own function.
TagKey<Item> tag = SpectrumCommon.CACHED_ITEM_TAG_MAP.computeIfAbsent(identifier, tagId -> Registries.ITEM.streamTags()
.filter(t -> t.id().equals(tagId))
.findFirst()
.orElse(null));

if(tag == null) { return false; }
if(allow) { this.setOnlyDenyListTags(false); }
return this.getFilteredTags().put(tag, allow);
}

// Call on change.
default void updateTagFilteringItems() {
this.clearFilters();
this.getItemFilters().forEach(this::addTagFilteringItem);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.dafuqs.spectrum.blocks.chests;

import de.dafuqs.spectrum.*;
import de.dafuqs.spectrum.api.block.*;
import de.dafuqs.spectrum.api.item.*;
import de.dafuqs.spectrum.events.*;
Expand All @@ -9,6 +10,7 @@
import de.dafuqs.spectrum.networking.*;
import de.dafuqs.spectrum.particle.*;
import de.dafuqs.spectrum.registries.*;
import it.unimi.dsi.fastutil.objects.*;
import net.fabricmc.fabric.api.screenhandler.v1.*;
import net.fabricmc.fabric.api.transfer.v1.item.*;
import net.minecraft.block.*;
Expand All @@ -18,23 +20,27 @@
import net.minecraft.item.*;
import net.minecraft.nbt.*;
import net.minecraft.network.*;
import net.minecraft.registry.*;
import net.minecraft.registry.tag.*;
import net.minecraft.screen.*;
import net.minecraft.server.network.*;
import net.minecraft.server.world.*;
import net.minecraft.sound.*;
import net.minecraft.text.*;
import net.minecraft.util.*;
import net.minecraft.util.collection.*;
import net.minecraft.util.math.*;
import net.minecraft.world.*;
import net.minecraft.world.event.*;
import net.minecraft.world.event.listener.*;
import org.apache.commons.lang3.*;
import org.jetbrains.annotations.*;

import java.util.*;
import java.util.stream.*;

@SuppressWarnings("UnstableApiUsage")
public class BlackHoleChestBlockEntity extends SpectrumChestBlockEntity implements ExtendedScreenHandlerFactory, SidedInventory, EventQueue.Callback<Object> {
public class BlackHoleChestBlockEntity extends SpectrumChestBlockEntity implements ExtendedScreenHandlerFactory, SidedInventory, EventQueue.Callback<Object>, TagFilteringInventory {

public static final int INVENTORY_SIZE = 28;
public static final int ITEM_FILTER_SLOT_COUNT = 5;
Expand All @@ -46,12 +52,15 @@ public class BlackHoleChestBlockEntity extends SpectrumChestBlockEntity implemen
private boolean isOpen, isFull, hasXPStorage;
float storageTarget, storagePos, lastStorageTarget, capTarget, capPos, lastCapTarget, orbTarget, orbPos, lastOrbTarget, yawTarget, orbYaw, lastYawTarget;
long interpTicks, interpLength = 1, age, storedXP, maxStoredXP;


private final Object2BooleanMap<TagKey<Item>> filteredTags;
private boolean allTagsDeny = true;

public BlackHoleChestBlockEntity(BlockPos blockPos, BlockState blockState) {
super(SpectrumBlockEntities.BLACK_HOLE_CHEST, blockPos, blockState);
this.itemAndExperienceEventQueue = new ItemAndExperienceEventQueue(new BlockPositionSource(this.pos), RANGE, this);
this.filterItems = DefaultedList.ofSize(ITEM_FILTER_SLOT_COUNT, ItemVariant.blank());
this.filteredTags = new Object2BooleanArrayMap<>();
}

public static void tick(@NotNull World world, BlockPos pos, BlockState state, BlackHoleChestBlockEntity chest) {
Expand Down Expand Up @@ -227,6 +236,7 @@ public void writeNbt(NbtCompound tag) {
public void readNbt(NbtCompound tag) {
super.readNbt(tag);
FilterConfigurable.readFilterNbt(tag, filterItems);
this.updateTagFilteringItems();
age = tag.getLong("age");
}

Expand Down Expand Up @@ -268,7 +278,7 @@ public void triggerEvent(World world, GameEventListener listener, Object entry)
}
} else if (entry instanceof ItemEntityEventQueue.EventEntry itemEntry) {
ItemEntity itemEntity = itemEntry.itemEntity;
if (itemEntity != null && itemEntity.isAlive() && !itemEntity.cannotPickup() && acceptsItemStack(itemEntity.getStack())) {
if (itemEntity != null && itemEntity.isAlive() && !itemEntity.cannotPickup() && this.acceptsItem(itemEntity.getStack().getItem())) {
int previousAmount = itemEntity.getStack().getCount();
ItemStack remainingStack = InventoryHelper.smartAddToInventory(itemEntity.getStack(), this, Direction.UP);

Expand Down Expand Up @@ -322,25 +332,13 @@ public List<ItemVariant> getItemFilters() {

public void setFilterItem(int slot, ItemVariant item) {
this.filterItems.set(slot, item);
this.updateTagFilteringItems();
this.markDirty();
}

public boolean acceptsItemStack(ItemStack itemStack) {
if (itemStack.isEmpty()) {
return false;
}

boolean allAir = true;
for (int i = 0; i < ITEM_FILTER_SLOT_COUNT; i++) {
ItemVariant filterItem = this.filterItems.get(i);
if (filterItem.getItem().equals(itemStack.getItem())) {
return true;
} else if (!filterItem.getItem().equals(Items.AIR)) {
allAir = false;
}
}
return allAir;
}
public Object2BooleanMap<TagKey<Item>> getFilteredTags() { return this.filteredTags; }
public boolean onlyDenyListTags() { return this.allTagsDeny; }
public void setOnlyDenyListTags(boolean onlyDenyListTags) { this.allTagsDeny = onlyDenyListTags; }

public boolean hasExperienceStorageItem() {
return this.inventory.get(EXPERIENCE_STORAGE_PROVIDER_ITEM_SLOT).getItem() instanceof ExperienceStorageItem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import de.dafuqs.spectrum.networking.*;
import de.dafuqs.spectrum.progression.*;
import de.dafuqs.spectrum.registries.*;
import it.unimi.dsi.fastutil.objects.*;
import net.fabricmc.fabric.api.lookup.v1.block.*;
import net.fabricmc.fabric.api.screenhandler.v1.*;
import net.fabricmc.fabric.api.transfer.v1.item.*;
Expand All @@ -28,6 +29,7 @@
import net.minecraft.network.packet.*;
import net.minecraft.network.packet.s2c.play.*;
import net.minecraft.registry.*;
import net.minecraft.registry.tag.*;
import net.minecraft.screen.*;
import net.minecraft.server.network.*;
import net.minecraft.server.world.*;
Expand All @@ -46,7 +48,7 @@
import java.util.function.Predicate;

@SuppressWarnings("UnstableApiUsage")
public class PastelNodeBlockEntity extends BlockEntity implements FilterConfigurable, ExtendedScreenHandlerFactory, Stampable, PastelUpgradeable {
public class PastelNodeBlockEntity extends BlockEntity implements FilterConfigurable, ExtendedScreenHandlerFactory, Stampable, PastelUpgradeable, TagFilteringInventory {

public static final int MAX_FILTER_SLOTS = 25;
public static final int SLOTS_PER_ROW = 5;
Expand Down Expand Up @@ -80,10 +82,14 @@ public class PastelNodeBlockEntity extends BlockEntity implements FilterConfigur
float rotationTarget, crystalRotation, lastRotationTarget, heightTarget, crystalHeight, lastHeightTarget, alphaTarget, ringAlpha, lastAlphaTarget;
long creationStamp = -1, interpTicks, interpLength = -1, spinTicks;
private State state;

private final Object2BooleanMap<TagKey<Item>> filteredTags;
private boolean allTagsDeny = true;

public PastelNodeBlockEntity(BlockPos blockPos, BlockState blockState) {
super(SpectrumBlockEntities.PASTEL_NODE, blockPos, blockState);
this.filterItems = DefaultedList.ofSize(MAX_FILTER_SLOTS, ItemVariant.blank());
this.filteredTags = new Object2BooleanArrayMap<>();
this.outerRing = Optional.empty();
this.innerRing = Optional.empty();
this.redstoneRing = Optional.empty();
Expand Down Expand Up @@ -253,6 +259,7 @@ public void updateUpgrades() {
if (filterSlotRows < oldFilterSlotCount) {
for (int i = getDrawnSlots(); i < filterItems.size(); i++) {
filterHashset.remove(filterItems.get(i).getItem());
updateNbtCheckingCount(this.filterItems.get(i), -1);
filterItems.set(i, ItemVariant.blank());
}
}
Expand Down Expand Up @@ -359,6 +366,7 @@ public void readNbt(NbtCompound nbt) {
this.filterHashset.add(itemVariant.getItem());
this.updateNbtCheckingCount(itemVariant, 1);
});
this.updateTagFilteringItems();
}
}

Expand Down Expand Up @@ -455,6 +463,9 @@ public void updateInClientWorld() {
public List<ItemVariant> getItemFilters() {
return this.filterItems;
}
public Object2BooleanMap<TagKey<Item>> getFilteredTags() { return this.filteredTags; }
public boolean onlyDenyListTags() { return this.allTagsDeny; }
public void setOnlyDenyListTags(boolean onlyDenyListTags) { this.allTagsDeny = onlyDenyListTags; }

@Override
public void setFilterItem(int slot, ItemVariant item) {
Expand All @@ -463,6 +474,7 @@ public void setFilterItem(int slot, ItemVariant item) {
if(Collections.frequency(this.filterItems, item) == 1) { this.filterHashset.remove(this.filterItems.get(slot).getItem()); }
this.filterItems.set(slot, item);
this.filterHashset.add(item.getItem());
this.updateTagFilteringItems();
}

private void updateNbtCheckingCount(ItemVariant itemVariant, int change) {
Expand Down Expand Up @@ -507,35 +519,9 @@ private boolean filter(ItemVariant variant) {
continue filter;
}
}

if (!filterStack.hasCustomName() || !filterStack.isIn(SpectrumItemTags.TAG_FILTERING_ITEMS)) {
if (filterStack.getItem() == variant.getItem()) {
return true;
} else {
continue;
}
}
var name = StringUtils.trim(filterStack.getName().getString());

// This is to allow nbt filtering without item / tag filtering.
if (StringUtils.equalsAnyIgnoreCase(name, "*", "any", "all", "everything", "c:*", "c:any", "c:all", "c:everything"))
return true;

var id = Identifier.tryParse(StringUtils.remove(name, '#')); // let's be nice and remove any pound signs for the dumb idiots
if (id == null)
continue;

var tag = SpectrumCommon.CACHED_ITEM_TAG_MAP.computeIfAbsent(id, tagId -> Registries.ITEM.streamTags()
.filter(t -> t.id().equals(tagId))
.findFirst()
.orElse(null));

if (tag == null)
continue;

if (variant.getItem().getRegistryEntry().isIn(tag))
return true;
}

if (this.acceptsItem(variant.getItem())) { return true; }
return false;
}

Expand Down