From 5b4fa2e9ed45caf7e83d2e663b79943f4b670c8d Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Mon, 12 Aug 2024 20:18:39 +0700 Subject: [PATCH] Update ItemFilter to behave like it did previously, with fixed amount of slots but still being immutable --- .../entity/storage/StorageBusBlockEntity.kt | 12 ++-- .../block/entity/storage/StorageInterfaces.kt | 5 +- .../screen/storage/DriveViewerScreen.kt | 2 +- .../storage/StorageImporterExporterScreen.kt | 10 ++- .../mc/otm/container/ItemFilter.kt | 54 ++++++++++------ .../otm/item/PortableCondensationDriveItem.kt | 11 ++++ .../ru/dbotthepony/mc/otm/menu/MatteryMenu.kt | 38 ----------- .../ru/dbotthepony/mc/otm/menu/Slots.kt | 64 +++++++++++++++++++ .../menu/input/BooleanInputWithFeedback.kt | 26 ++++++++ .../mc/otm/menu/storage/DriveViewerMenu.kt | 21 +++--- .../storage/StorageImporterExporterMenu.kt | 7 +- 11 files changed, 161 insertions(+), 89 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt index cc1c9610b..7d1d84e17 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt @@ -122,13 +122,15 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter }) } - val filter = ItemFilter(MAX_FILTERS) { - component?.scan() - markDirtyFast() - } + var filter = ItemFilter(MAX_FILTERS) + set(value) { + field = value + component?.scan() + markDirtyFast() + } init { - savetables.stateful(::filter, FILTER_KEY) + savetables.codec(::filter, ItemFilter.CODEC, FILTER_KEY) } override fun setLevel(level: Level) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt index 00e70677a..2eb5f7747 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt @@ -97,10 +97,11 @@ abstract class AbstractStorageImportExport( protected val target = CapabilityCache(RelativeSide.FRONT, Capabilities.ItemHandler.BLOCK) - var filter: ItemFilter = ItemFilter.EMPTY + var filter: ItemFilter = ItemFilter(MAX_FILTERS) set(value) { if (value != field) { field = value + markDirtyFast() itemFilterUpdated() } } @@ -115,6 +116,7 @@ abstract class AbstractStorageImportExport( companion object { const val FILTER_KEY = "filter" + const val MAX_FILTERS = 6 * 3 } } @@ -263,7 +265,6 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : } lastSlot = 0 - markDirtyFast() } private var lastSlot = 0 diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/DriveViewerScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/DriveViewerScreen.kt index 52a82e135..3f86beea7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/DriveViewerScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/DriveViewerScreen.kt @@ -73,7 +73,7 @@ class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Comp it.dock = Dock.LEFT CheckBoxLabelInputPanel(this, it, menu.isWhitelist, TranslatableComponent("otm.gui.filter.is_whitelist")).also { it.dockTop = 20f; it.dock = Dock.TOP } CheckBoxLabelInputPanel(this, it, menu.matchTag, TranslatableComponent("otm.gui.filter.match_tag")).also { it.dockTop = 4f; it.dock = Dock.TOP } - CheckBoxLabelInputPanel(this, it, menu.matchNBT, TranslatableComponent("otm.gui.filter.match_nbt")).also { it.dockTop = 4f; it.dock = Dock.TOP } + CheckBoxLabelInputPanel(this, it, menu.matchComponents, TranslatableComponent("otm.gui.filter.match_nbt")).also { it.dockTop = 4f; it.dock = Dock.TOP } }) frame.Tab(view, activeIcon = ItemStackIcon(ItemStack(MItems.PORTABLE_CONDENSATION_DRIVE))) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageImporterExporterScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageImporterExporterScreen.kt index 75f24ef60..e67b1d901 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageImporterExporterScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageImporterExporterScreen.kt @@ -8,10 +8,8 @@ import ru.dbotthepony.mc.otm.client.screen.panels.* import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelInputPanel import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel -import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.FilterSlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.util.GridPanel -import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel import ru.dbotthepony.mc.otm.menu.storage.StorageImporterExporterMenu @@ -26,23 +24,23 @@ class StorageImporterExporterScreen(menu: StorageImporterExporterMenu, inventory val grid = GridPanel(this, right, columns = 6, rows = 3, height = AbstractSlotPanel.SIZE * 3f) grid.dock = Dock.TOP - for (slot in menu.filterSlots) { + for (slot in menu.filter.slots) { FilterSlotPanel(this, grid, slot) } - CheckBoxLabelInputPanel(this, right, menu.isWhitelist, TranslatableComponent("otm.gui.filter.is_whitelist")).also { + CheckBoxLabelInputPanel(this, right, menu.filter.isWhitelist, TranslatableComponent("otm.gui.filter.is_whitelist")).also { it.dock = Dock.BOTTOM it.dockTop = 2f it.childrenOrder = -1 } - CheckBoxLabelInputPanel(this, right, menu.matchNBT, TranslatableComponent("otm.gui.filter.match_nbt")).also { + CheckBoxLabelInputPanel(this, right, menu.filter.matchComponents, TranslatableComponent("otm.gui.filter.match_nbt")).also { it.dock = Dock.BOTTOM it.dockTop = 2f it.childrenOrder = -2 } - CheckBoxLabelInputPanel(this, right, menu.matchTag, TranslatableComponent("otm.gui.filter.match_tag")).also { + CheckBoxLabelInputPanel(this, right, menu.filter.matchTag, TranslatableComponent("otm.gui.filter.match_tag")).also { it.dock = Dock.BOTTOM it.dockTop = 2f it.childrenOrder = -3 diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt index 58be92692..cd11e2b6b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt @@ -1,36 +1,48 @@ package ru.dbotthepony.mc.otm.container -import com.google.common.collect.ImmutableList import com.mojang.serialization.Codec import com.mojang.serialization.codecs.RecordCodecBuilder +import it.unimi.dsi.fastutil.objects.ObjectArrayList import net.minecraft.tags.TagKey import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack -data class ItemFilter(val filter: List, val isWhitelist: Boolean = false, val matchTag: Boolean = false, val matchComponents: Boolean = false) { - fun add(item: ItemStack): ItemFilter { - if (filter.any { ItemStack.isSameItemSameComponents(it, item) }) +class ItemFilter private constructor(private val filter: Array, val isWhitelist: Boolean, val matchTag: Boolean, val matchComponents: Boolean) { + constructor(size: Int, isWhitelist: Boolean = false, matchTag: Boolean = false, matchComponents: Boolean = false) : this(Array(size) { ItemStack.EMPTY }, isWhitelist, matchTag, matchComponents) + constructor(list: List, isWhitelist: Boolean = false, matchTag: Boolean = false, matchComponents: Boolean = false) : this(list.toTypedArray(), isWhitelist, matchTag, matchComponents) + + override fun equals(other: Any?): Boolean { + return this === other || other is ItemFilter && + this.filter.contentEquals(other.filter) && + this.isWhitelist == other.isWhitelist && + this.matchTag == other.matchTag && + this.matchComponents == other.matchComponents + } + + override fun hashCode(): Int { + return filter.contentHashCode() + } + + val size: Int + get() = filter.size + + fun set(index: Int, value: ItemStack): ItemFilter { + if (ItemStack.isSameItemSameComponents(filter[index], value) || filter.any { ItemStack.isSameItemSameComponents(it, value) }) return this - return copy( - filter = ArrayList(filter).also { it.add(item) } - ) + return copy(filter.copyOf().also { it[index] = value }) } - fun remove(item: ItemStack): ItemFilter { - val indexOf = filter.indexOfFirst { ItemStack.isSameItemSameComponents(it, item) } - - if (indexOf == -1) - return this - - return copy( - filter = ArrayList(filter).also { it.removeAt(indexOf) } - ) + operator fun get(index: Int): ItemStack { + return filter[index] } - fun get(index: Int): ItemStack { - return filter.getOrElse(index) { ItemStack.EMPTY } - } + private fun copy( + filter: Array = this.filter, + isWhitelist: Boolean = this.isWhitelist, + matchTag: Boolean = this.matchTag, + matchComponents: Boolean = this.matchComponents, + ) = ItemFilter(filter, isWhitelist, matchTag, matchComponents) fun isWhitelist(flag: Boolean): ItemFilter { if (flag == isWhitelist) @@ -96,12 +108,12 @@ data class ItemFilter(val filter: List, val isWhitelist: Boolean = fa } companion object { - val EMPTY = ItemFilter(ImmutableList.of()) + val EMPTY = ItemFilter(0) val CODEC: Codec by lazy { RecordCodecBuilder.create { it.group( - Codec.list(ItemStack.CODEC, 0, 40).fieldOf("filter").forGetter { it.filter }, + Codec.list(ItemStack.CODEC, 0, 40).fieldOf("filter").forGetter { ObjectArrayList.wrap(it.filter) }, Codec.BOOL.optionalFieldOf("isWhitelist", false).forGetter { it.isWhitelist }, Codec.BOOL.optionalFieldOf("matchTag", false).forGetter { it.matchTag }, Codec.BOOL.optionalFieldOf("matchComponents", false).forGetter { it.matchComponents }, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/PortableCondensationDriveItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/PortableCondensationDriveItem.kt index dc9c23b7f..ece5207f5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/PortableCondensationDriveItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/PortableCondensationDriveItem.kt @@ -55,8 +55,19 @@ class PortableCondensationDriveItem(capacity: Int) : Item(Properties().stacksTo( }, this) } + fun getFilterSettings(item: ItemStack): ItemFilter { + return item.getOrDefault(MDataComponentTypes.ITEM_FILTER, EMPTY_FILTER) + } + + fun setFilterSettings(item: ItemStack, filter: ItemFilter) { + item.set(MDataComponentTypes.ITEM_FILTER, filter) + } + @Suppress("unused") companion object { + const val MAX_FILTERS = 4 * 3 + private val EMPTY_FILTER = ItemFilter(MAX_FILTERS) + fun onPickupEvent(event: ItemEntityPickupEvent.Pre) { if (event.itemEntity.owner != null && event.itemEntity.owner != event.player && event.itemEntity.age < 200 || event.itemEntity.item.isEmpty) { return diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt index 96e342ac8..6fb4c5090 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt @@ -25,7 +25,6 @@ import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.item.enchantment.EnchantmentEffectComponents import net.minecraft.world.item.enchantment.EnchantmentHelper -import net.minecraft.world.item.enchantment.Enchantments import net.minecraft.world.level.block.entity.BlockEntity import net.neoforged.neoforge.network.PacketDistributor import net.neoforged.neoforge.network.handling.IPayloadContext @@ -42,7 +41,6 @@ import ru.dbotthepony.mc.otm.compat.cos.cosmeticArmorSlots import ru.dbotthepony.mc.otm.compat.curios.curiosSlots import ru.dbotthepony.mc.otm.compat.curios.isCurioSlot import ru.dbotthepony.mc.otm.container.IMatteryContainer -import ru.dbotthepony.mc.otm.container.ItemFilter import ru.dbotthepony.mc.otm.container.UpgradeContainer import ru.dbotthepony.mc.otm.container.computeSortedIndices import ru.dbotthepony.mc.otm.container.sortWithIndices @@ -241,42 +239,6 @@ abstract class MatteryMenu( protected var inventorySlotIndexStart = 0 protected var inventorySlotIndexEnd = 0 - fun addFilterSlots(slots: ItemFilter): List> { - val result = ArrayList>(slots.size) - - for (i in 0 until slots.size) { - result.add(Delegate.Of( - mSynchronizer.computedItem { slots[i] }, - itemStackInput { slots[i] = it } - )) - } - - return result - } - - fun addFilterSlots(amount: Int): List> { - val result = ArrayList>(amount) - - for (i in 0 until amount) { - result.add(Delegate.Of( - mSynchronizer.computedItem { ItemStack.EMPTY }, - itemStackInput { throw UnsupportedOperationException() } - )) - } - - return result - } - - fun addFilterSlots(slots: ItemFilter?, amount: Int): List> { - if (slots != null && amount != slots.size) - throw IllegalStateException("Provided ItemFiler has different amount of slots than expected: ${slots.size} != $amount") - - if (slots == null) - return addFilterSlots(amount) - else - return addFilterSlots(slots) - } - open inner class InventorySlot(container: Container, index: Int, addFilter: Boolean = false) : UserFilteredSlot(container, index, 0, 0) { override fun mayPlace(itemStack: ItemStack): Boolean { return !isInventorySlotLocked(index) && super.mayPlace(itemStack) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt index 89c463723..940a3f7cf 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt @@ -9,14 +9,19 @@ import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.kommons.util.Delegate +import ru.dbotthepony.kommons.util.value import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.energy import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.container.IMatteryContainer +import ru.dbotthepony.mc.otm.container.ItemFilter import ru.dbotthepony.mc.otm.core.immutableList +import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback import ru.dbotthepony.mc.otm.runOnClient +import java.util.ArrayList import java.util.function.Predicate +import kotlin.reflect.KMutableProperty0 /** * Make slots for single container @@ -159,3 +164,62 @@ open class DriveSlot(container: Container, index: Int, x: Int = 0, y: Int = 0) : return super.mayPlace(itemStack) && itemStack.getCapability(MatteryCapability.CONDENSATION_DRIVE) != null } } + +fun MatteryMenu.addFilterSlots(slots: Delegate): List> { + val result = ArrayList>(slots.value.size) + + for (i in 0 until slots.value.size) { + result.add(Delegate.Of( + mSynchronizer.computedItem { slots.value[i] }, + itemStackInput { slots.value = slots.value.set(i, it) } + )) + } + + return result +} + +fun MatteryMenu.addFilterSlots(amount: Int): List> { + val result = ArrayList>(amount) + + for (i in 0 until amount) { + result.add(Delegate.Of( + mSynchronizer.computedItem { ItemStack.EMPTY }, + itemStackInput { throw UnsupportedOperationException() } + )) + } + + return result +} + +fun MatteryMenu.addFilterSlots(slots: Delegate?, amount: Int): List> { + if (slots != null && amount != slots.value.size) + throw IllegalStateException("Provided ItemFiler has different amount of slots than expected: ${slots.value.size} != $amount") + + if (slots == null) + return addFilterSlots(amount) + else + return addFilterSlots(slots) +} + +fun MatteryMenu.addFilterSlots(slots: KMutableProperty0?, amount: Int): List> { + return addFilterSlots(if (slots == null) null else Delegate.Of(slots), amount) +} + +data class FilterControls(val slots: List>, val isWhitelist: BooleanInputWithFeedback, val matchComponents: BooleanInputWithFeedback, val matchTag: BooleanInputWithFeedback) + +fun MatteryMenu.addFilterControls(slots: Delegate?, amount: Int): FilterControls { + if (slots == null) { + return FilterControls(addFilterSlots(amount), BooleanInputWithFeedback(this), BooleanInputWithFeedback(this), BooleanInputWithFeedback(this)) + } else { + return FilterControls( + addFilterSlots(slots, amount), + BooleanInputWithFeedback.dispatch(this, slots, ItemFilter::isWhitelist, ItemFilter::isWhitelist), + BooleanInputWithFeedback.dispatch(this, slots, ItemFilter::matchComponents, ItemFilter::matchComponents), + BooleanInputWithFeedback.dispatch(this, slots, ItemFilter::matchTag, ItemFilter::matchTag), + ) + } +} + +fun MatteryMenu.addFilterControls(slots: KMutableProperty0?, amount: Int): FilterControls { + return addFilterControls(slots?.let { Delegate.Of(it) }, amount) +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/BooleanInputWithFeedback.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/BooleanInputWithFeedback.kt index ff3eba3ca..f8c5844b5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/BooleanInputWithFeedback.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/BooleanInputWithFeedback.kt @@ -3,6 +3,8 @@ package ru.dbotthepony.mc.otm.menu.input import ru.dbotthepony.kommons.util.Delegate import ru.dbotthepony.mc.otm.menu.MatteryMenu import java.util.function.BooleanSupplier +import java.util.function.Consumer +import java.util.function.Supplier import kotlin.reflect.KMutableProperty0 class BooleanInputWithFeedback(menu: MatteryMenu, allowSpectators: Boolean = false) : AbstractPlayerInputWithFeedback() { @@ -32,4 +34,28 @@ class BooleanInputWithFeedback(menu: MatteryMenu, allowSpectators: Boolean = fal fun switchValue() { accept(!value) } + + companion object { + fun dispatch(menu: MatteryMenu, property: Delegate, getter: (T) -> Boolean, setter: (T, Boolean) -> T): BooleanInputWithFeedback { + return BooleanInputWithFeedback( + menu, + + Delegate.Of( + { getter(property.get()) }, + { property.accept(setter(property.get(), it)) } + ) + ) + } + + fun dispatch(menu: MatteryMenu, property: KMutableProperty0, getter: (T) -> Boolean, setter: (T, Boolean) -> T): BooleanInputWithFeedback { + return BooleanInputWithFeedback( + menu, + + Delegate.Of( + { getter(property.get()) }, + { property.set(setter(property.get(), it)) } + ) + ) + } + } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/DriveViewerMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/DriveViewerMenu.kt index f45713220..5861fd82d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/DriveViewerMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/DriveViewerMenu.kt @@ -15,7 +15,6 @@ import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage import ru.dbotthepony.mc.otm.container.ItemFilter import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.core.util.ItemStorageStackSorter -import ru.dbotthepony.mc.otm.core.util.computedItem import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu import ru.dbotthepony.mc.otm.menu.MatterySlot @@ -81,23 +80,21 @@ class DriveViewerMenu( return (stack?.item as? PortableCondensationDriveItem)?.getFilterSettings(stack) } + private fun setFilter(value: ItemFilter) { + val stack = (tile as? DriveViewerBlockEntity)?.container?.getItem(0) + (stack?.item as? PortableCondensationDriveItem)?.setFilterSettings(stack, value) + } + val driveFilterSlots = immutableList(PortableCondensationDriveItem.MAX_FILTERS) { i -> Delegate.Of( mSynchronizer.computedItem { getFilter()?.get(i) ?: ItemStack.EMPTY }, - itemStackInput { getFilter()?.set(i, it) } + itemStackInput { getFilter()?.set(i, it) }.filter { drivePresent } ) } - private fun make(mapper: (ItemFilter) -> Delegate): Delegate { - return Delegate.Of( - { getFilter()?.let(mapper)?.get() ?: false }, - { getFilter()?.let(mapper)?.accept(it) } - ) - } - - val isWhitelist = BooleanInputWithFeedback(this, make { Delegate.Of(it::isWhitelist) }).also { it.filter { drivePresent } } - val matchTag = BooleanInputWithFeedback(this, make { Delegate.Of(it::matchTag) }).also { it.filter { drivePresent } } - val matchNBT = BooleanInputWithFeedback(this, make { Delegate.Of(it::matchComponents) }).also { it.filter { drivePresent } } + val isWhitelist = BooleanInputWithFeedback.dispatch(this, Delegate.Of({ getFilter() }, { setFilter(it!!) }), { it?.isWhitelist ?: false }, { it, v -> it?.isWhitelist(v) }).also { it.filter { drivePresent } } + val matchTag = BooleanInputWithFeedback.dispatch(this, Delegate.Of({ getFilter() }, { setFilter(it!!) }), { it?.matchTag ?: false }, { it, v -> it?.matchTag(v) }).also { it.filter { drivePresent } } + val matchComponents = BooleanInputWithFeedback.dispatch(this, Delegate.Of({ getFilter() }, { setFilter(it!!) }), { it?.matchComponents ?: false }, { it, v -> it?.matchComponents(v) }).also { it.filter { drivePresent } } override fun broadcastChanges() { super.broadcastChanges() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/StorageImporterExporterMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/StorageImporterExporterMenu.kt index 4ab3901f6..dcd2671f7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/StorageImporterExporterMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/storage/StorageImporterExporterMenu.kt @@ -2,7 +2,9 @@ package ru.dbotthepony.mc.otm.menu.storage import net.minecraft.world.entity.player.Inventory import ru.dbotthepony.mc.otm.block.entity.storage.AbstractStorageImportExport +import ru.dbotthepony.mc.otm.container.ItemFilter import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu +import ru.dbotthepony.mc.otm.menu.addFilterControls import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget @@ -11,10 +13,7 @@ import ru.dbotthepony.mc.otm.registry.MMenus class StorageImporterExporterMenu( containerId: Int, inventory: Inventory, tile: AbstractStorageImportExport? = null ) : MatteryPoweredMenu(MMenus.STORAGE_IMPORTER_EXPORTER, containerId, inventory, tile) { - val filterSlots = addFilterSlots(tile?.filter, AbstractStorageImportExport.MAX_FILTERS) - val isWhitelist = BooleanInputWithFeedback(this, tile?.let { it.filter::isWhitelist }) - val matchNBT = BooleanInputWithFeedback(this, tile?.let { it.filter::matchComponents }) - val matchTag = BooleanInputWithFeedback(this, tile?.let { it.filter::matchTag }) + val filter = addFilterControls(tile?.let { it::filter }, AbstractStorageImportExport.MAX_FILTERS) val profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.energy, energyWidget) val energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig)