From 2943026dd571d15f2407649a74ab5ce834b5fd6f Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Fri, 14 Mar 2025 19:06:49 +0700 Subject: [PATCH] Add generic param to CombinedContainer --- .../entity/storage/ItemMonitorBlockEntity.kt | 12 ++--- .../mc/otm/container/CombinedContainer.kt | 50 +++++++++---------- .../mc/otm/container/EnhancedContainer.kt | 2 +- .../mc/otm/container/IAutomatedContainer.kt | 2 +- .../mc/otm/container/IEnhancedContainer.kt | 2 +- .../container/IEnhancedCraftingContainer.kt | 4 +- .../mc/otm/container/ISlottedContainer.kt | 2 +- .../ru/dbotthepony/mc/otm/menu/MatteryMenu.kt | 20 ++++---- .../mc/otm/player/MatteryPlayer.kt | 14 +++--- 9 files changed, 53 insertions(+), 55 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/ItemMonitorBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/ItemMonitorBlockEntity.kt index 3098460df..26d051e29 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/ItemMonitorBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/ItemMonitorBlockEntity.kt @@ -96,42 +96,42 @@ class ItemMonitorPlayerSettings : INBTSerializable, IItemMonitorPla enum class IngredientPriority(override val component: Component, icon: Lazy, override val winding: UVWindingOrder = UVWindingOrder.NORMAL) : Setting { // Refill everything from system SYSTEM(TranslatableComponent("otm.gui.item_monitor.refill_source.system"), lazy { Widgets8.WHITE_ARROW_DOWN }, UVWindingOrder.FLIP) { - override fun takeOne(item: ItemStack, view: IStorageProvider?, inventory: CombinedContainer?, id: UUID?): Boolean { + override fun takeOne(item: ItemStack, view: IStorageProvider?, inventory: CombinedContainer<*>?, id: UUID?): Boolean { return takeOne(id, view) } }, // Refill everything from player's inventory INVENTORY(TranslatableComponent("otm.gui.item_monitor.refill_source.inventory"), lazy { Widgets8.WHITE_ARROW_DOWN }) { - override fun takeOne(item: ItemStack, view: IStorageProvider?, inventory: CombinedContainer?, id: UUID?): Boolean { + override fun takeOne(item: ItemStack, view: IStorageProvider?, inventory: CombinedContainer<*>?, id: UUID?): Boolean { return takeOne(inventory, item) } }, // Refill everything from system, if can't refill from player's inventory SYSTEM_FIRST(TranslatableComponent("otm.gui.item_monitor.refill_source.system_first"), lazy { Widgets8.ARROW_SIDEWAYS }, UVWindingOrder.FLIP) { - override fun takeOne(item: ItemStack, view: IStorageProvider?, inventory: CombinedContainer?, id: UUID?): Boolean { + override fun takeOne(item: ItemStack, view: IStorageProvider?, inventory: CombinedContainer<*>?, id: UUID?): Boolean { return takeOne(id, view) || takeOne(inventory, item) } }, // Refill everything from player's inventory, if can't refill from system INVENTORY_FIRST(TranslatableComponent("otm.gui.item_monitor.refill_source.inventory_first"), lazy { Widgets8.ARROW_SIDEWAYS }) { - override fun takeOne(item: ItemStack, view: IStorageProvider?, inventory: CombinedContainer?, id: UUID?): Boolean { + override fun takeOne(item: ItemStack, view: IStorageProvider?, inventory: CombinedContainer<*>?, id: UUID?): Boolean { return takeOne(inventory, item) || takeOne(id, view) } }, // Do not refill (?) DO_NOT(TranslatableComponent("otm.gui.item_monitor.refill_source.do_not"), lazy { Widgets8.MINUS }) { - override fun takeOne(item: ItemStack, view: IStorageProvider?, inventory: CombinedContainer?, id: UUID?): Boolean { + override fun takeOne(item: ItemStack, view: IStorageProvider?, inventory: CombinedContainer<*>?, id: UUID?): Boolean { return false } }; override val icon: IGUIRenderable by icon - abstract fun takeOne(item: ItemStack, view: IStorageProvider?, inventory: CombinedContainer?, id: UUID?): Boolean + abstract fun takeOne(item: ItemStack, view: IStorageProvider?, inventory: CombinedContainer<*>?, id: UUID?): Boolean } enum class ResultTarget(override val component: Component, icon: Lazy, override val winding: UVWindingOrder = UVWindingOrder.NORMAL) : Setting { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/CombinedContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/CombinedContainer.kt index 199414482..0c658349b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/CombinedContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/CombinedContainer.kt @@ -23,20 +23,20 @@ import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.stream import java.util.stream.Stream -class CombinedContainer(containers: Stream, Iterable>>) : ISlottedContainer { - constructor(vararg containers: IEnhancedContainer<*>) : this(containers.stream().map { it to (0 until it.containerSize) }) - constructor(containers: Collection>) : this(containers.stream().map { it to (0 until it.containerSize) }) +class CombinedContainer(containers: Stream, Iterable>>) : ISlottedContainer { + constructor(vararg containers: IEnhancedContainer) : this(containers.stream().map { it to (0 until it.containerSize) }) + constructor(containers: Collection>) : this(containers.stream().map { it to (0 until it.containerSize) }) - private val slots: ImmutableList - private val slotsMap: ImmutableMap> + private val slots: ImmutableList + private val slotsMap: ImmutableMap> private val containers: ImmutableSet private val fullCoverage: ImmutableList - private val notFullCoverage: ImmutableMap> + private val notFullCoverage: ImmutableMap> init { - val list = ImmutableList.Builder() + val list = ImmutableList.Builder() val validationMap = Reference2ObjectOpenHashMap() - val slotsMap = Reference2ObjectOpenHashMap>() + val slotsMap = Reference2ObjectOpenHashMap>() var i = 0 for ((container, slots) in containers) { @@ -116,11 +116,11 @@ class CombinedContainer(containers: Stream, Iterable< ) } - override fun slotIterator(): Iterator { + override fun slotIterator(): Iterator { return slots.iterator() } - override fun containerSlot(slot: Int): IContainerSlot { + override fun containerSlot(slot: Int): S { return slots[slot] } @@ -128,62 +128,62 @@ class CombinedContainer(containers: Stream, Iterable< slots[slot].setChanged() } - class Builder { - private val values = ArrayList, Iterable>>() + class Builder { + private val values = ArrayList, Iterable>>() - fun add(container: Container): Builder { + fun add(container: Container): Builder { return add(IEnhancedContainer.wrap(container)) } - fun add(container: Container, slots: Iterator): Builder { + fun add(container: Container, slots: Iterator): Builder { return add(IEnhancedContainer.wrap(container), slots) } - fun add(container: Container, slot: Int): Builder { + fun add(container: Container, slot: Int): Builder { return add(IEnhancedContainer.wrap(container), slot) } - fun add(container: Container, from: Int, to: Int): Builder { + fun add(container: Container, from: Int, to: Int): Builder { return add(IEnhancedContainer.wrap(container), from, to) } - fun add(container: Container, slots: Iterable): Builder { + fun add(container: Container, slots: Iterable): Builder { return add(IEnhancedContainer.wrap(container), slots) } - fun add(container: IEnhancedContainer<*>): Builder { + fun add(container: IEnhancedContainer): Builder { values.add(container to container.slotRange) return this } - fun add(container: IEnhancedContainer<*>, slots: Iterator): Builder { + fun add(container: IEnhancedContainer, slots: Iterator): Builder { values.add(container to IntArrayList(slots)) return this } - fun add(container: IEnhancedContainer<*>, slot: Int): Builder { + fun add(container: IEnhancedContainer, slot: Int): Builder { values.add(container to intArrayOf(slot).asIterable()) return this } - fun add(container: IEnhancedContainer<*>, from: Int, to: Int): Builder { + fun add(container: IEnhancedContainer, from: Int, to: Int): Builder { values.add(container to (from .. to)) return this } - fun add(container: IEnhancedContainer<*>, slots: Iterable): Builder { + fun add(container: IEnhancedContainer, slots: Iterable): Builder { values.add(container to slots) return this } - fun build(): CombinedContainer { + fun build(): CombinedContainer { return CombinedContainer(values.stream()) } } companion object { - fun fromMenuSlots(slots: Iterator): CombinedContainer { - val builder = Builder() + fun fromMenuSlots(slots: Iterator): CombinedContainer { + val builder = Builder() for (slot in slots) { builder.add(slot.container, slot.slotIndex) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/EnhancedContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/EnhancedContainer.kt index fe1aa25d8..f012f130b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/EnhancedContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/EnhancedContainer.kt @@ -23,7 +23,7 @@ import ru.dbotthepony.mc.otm.core.nbt.set * This is supposed to be counterpart to [SimpleContainer] of Minecraft itself, with more features * and improved performance (inside [IEnhancedContainer] defined methods). */ -abstract class EnhancedContainer(private val size: Int) : IEnhancedContainer, INBTSerializable { +abstract class EnhancedContainer(private val size: Int) : IEnhancedContainer, INBTSerializable { private val items = Array(size) { ItemStack.EMPTY } private val observedItems = Array(size) { ItemStack.EMPTY } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/IAutomatedContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/IAutomatedContainer.kt index f143f30a2..529512d22 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/IAutomatedContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/IAutomatedContainer.kt @@ -10,7 +10,7 @@ import net.neoforged.neoforge.items.IItemHandlerModifiable * Reinforced [ISlottedContainer] which slots are [IAutomatedContainerSlot]s, which * subsequently allow this container to implement [IItemHandler] */ -interface IAutomatedContainer : ISlottedContainer, IItemHandlerModifiable { +interface IAutomatedContainer : ISlottedContainer, IItemHandlerModifiable { override fun canPlaceItem(slot: Int, itemStack: ItemStack): Boolean { return containerSlot(slot).canAutomationPlaceItem(itemStack) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/IEnhancedContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/IEnhancedContainer.kt index f6560d196..d42d54a9b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/IEnhancedContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/IEnhancedContainer.kt @@ -24,7 +24,7 @@ import java.util.stream.StreamSupport * This is useful because it allows to interact with actually enhanced and regular containers through unified interface, * and actual implementations of this interface are likely to provide efficient method implementations in place of derived/emulated ones. */ -interface IEnhancedContainer : Container, RecipeInput, Iterable, StackedContentsCompatible { +interface IEnhancedContainer : Container, RecipeInput, Iterable, StackedContentsCompatible { // https://youtrack.jetbrains.com/issue/KT-55080/Change-the-behavior-of-inheritance-delegation-to-delegates-implementing-Java-interfaces-with-default-methods override fun getMaxStackSize(): Int { return super.getMaxStackSize() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/IEnhancedCraftingContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/IEnhancedCraftingContainer.kt index e7e10a0dd..0866e8172 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/IEnhancedCraftingContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/IEnhancedCraftingContainer.kt @@ -4,7 +4,7 @@ import net.minecraft.world.entity.player.StackedContents import net.minecraft.world.inventory.CraftingContainer import net.minecraft.world.item.ItemStack -interface IEnhancedCraftingContainer : IEnhancedContainer, CraftingContainer { +interface IEnhancedCraftingContainer : IEnhancedContainer, CraftingContainer { override fun getItems(): MutableList { return toList() } @@ -13,7 +13,7 @@ interface IEnhancedCraftingContainer : IEnhancedContainer forEach { contents.accountSimpleStack(it) } } - class Wrapper, S : IContainerSlot>(val parent: C, private val width: Int, private val height: Int) : IEnhancedCraftingContainer, IEnhancedContainer by parent { + class Wrapper, out S : IContainerSlot>(val parent: C, private val width: Int, private val height: Int) : IEnhancedCraftingContainer, IEnhancedContainer by parent { init { require(width * height == parent.containerSize) { "Crafting container dimensions ($width x $height) do not match container size provided (${parent.containerSize})" } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ISlottedContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ISlottedContainer.kt index d6bf3cda9..e3befae6a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ISlottedContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ISlottedContainer.kt @@ -8,7 +8,7 @@ import ru.dbotthepony.kommons.collect.any /** * Skeletal implementation for containers which revolve around [IContainerSlot] */ -interface ISlottedContainer : IEnhancedContainer { +interface ISlottedContainer : IEnhancedContainer { override fun setChanged(slot: Int) { containerSlot(slot).setChanged() } 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 4c2a36e34..eb29aaa04 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt @@ -39,6 +39,7 @@ import ru.dbotthepony.mc.otm.player.matteryPlayer 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.IEnhancedContainer import ru.dbotthepony.mc.otm.container.IFilteredContainerSlot import ru.dbotthepony.mc.otm.container.computeSortedIndices import ru.dbotthepony.mc.otm.container.sortWithIndices @@ -59,6 +60,7 @@ import ru.dbotthepony.mc.otm.network.readByteListUnbounded import ru.dbotthepony.mc.otm.network.syncher.SynchableGroup import ru.dbotthepony.mc.otm.network.wrap import ru.dbotthepony.mc.otm.network.writeByteListUnbounded +import ru.dbotthepony.mc.otm.player.IPlayerInventorySlot import java.util.* import java.util.function.BooleanSupplier import java.util.function.Consumer @@ -225,7 +227,7 @@ abstract class MatteryMenu( protected var inventorySlotIndexStart = 0 protected var inventorySlotIndexEnd = 0 - open inner class InventorySlot(container: Container, index: Int) : UserFilteredMenuSlot(container, index, 0, 0) { + open inner class InventorySlot(container: IEnhancedContainer, index: Int) : UserFilteredMenuSlot(container, index, 0, 0) { override fun mayPlace(itemStack: ItemStack): Boolean { return !isInventorySlotLocked(index) && super.mayPlace(itemStack) } @@ -238,19 +240,15 @@ abstract class MatteryMenu( private set init { - val mattery = player.matteryPlayer - - if (mattery.hasExopack) { - chargeFlag = Delegate.Of( - getter = { slotIndex in mattery.slotsChargeFlag }, - setter = booleanInput(true) { if (mattery.hasExopack) { if (it) mattery.slotsChargeFlag.add(slotIndex) else mattery.slotsChargeFlag.remove(slotIndex) } }::accept - ) + if (player.matteryPlayer.hasExopack) { + val slot = container.containerSlot(index) + chargeFlag = Delegate.Of(slot::shouldCharge) } } } - open inner class EquipmentMenuSlot(container: Container, index: Int, val type: net.minecraft.world.entity.EquipmentSlot) : InventorySlot(container, index) { - constructor(type: net.minecraft.world.entity.EquipmentSlot) : this(inventory, 34 + type.ordinal, type) + open inner class EquipmentMenuSlot(container: IEnhancedContainer, index: Int, val type: net.minecraft.world.entity.EquipmentSlot) : InventorySlot(container, index) { + constructor(type: net.minecraft.world.entity.EquipmentSlot) : this(player.matteryPlayer.wrappedInventory, 34 + type.ordinal, type) override fun setByPlayer(newItem: ItemStack, oldItem: ItemStack) { inventory.player.onEquipItem(type, oldItem, newItem) @@ -280,7 +278,7 @@ abstract class MatteryMenu( autoCreateInventoryFrame = autoFrame - offhandSlot = object : InventorySlot(inventory, 40) { + offhandSlot = object : InventorySlot(player.matteryPlayer.wrappedInventory, 40) { override fun setByPlayer(newItem: ItemStack, oldItem: ItemStack) { inventory.player.onEquipItem(net.minecraft.world.entity.EquipmentSlot.OFFHAND, oldItem, newItem) super.setByPlayer(newItem, oldItem) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/player/MatteryPlayer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/player/MatteryPlayer.kt index 83c7d95bc..f0353e071 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/player/MatteryPlayer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/player/MatteryPlayer.kt @@ -295,9 +295,9 @@ class MatteryPlayer(val ply: Player) { _combinedInventory3 = null } - private var _combinedInventory: CombinedContainer? = null - private var _combinedInventory2: CombinedContainer? = null - private var _combinedInventory3: CombinedContainer? = null + private var _combinedInventory: CombinedContainer? = null + private var _combinedInventory2: CombinedContainer? = null + private var _combinedInventory3: CombinedContainer? = null val wrappedInventory = PlayerInventoryWrapper(this) @@ -307,7 +307,7 @@ class MatteryPlayer(val ply: Player) { } } - val combinedInventory: CombinedContainer + val combinedInventory: CombinedContainer get() { if (_combinedInventory == null) _combinedInventory = CombinedContainer(wrappedInventory, exopackContainer) @@ -315,7 +315,7 @@ class MatteryPlayer(val ply: Player) { return _combinedInventory!! } - val inventoryAndExopack: CombinedContainer + val inventoryAndExopack: CombinedContainer get() { if (_combinedInventory2 == null) _combinedInventory2 = CombinedContainer(wrappedItemInventory, exopackContainer) @@ -323,10 +323,10 @@ class MatteryPlayer(val ply: Player) { return _combinedInventory2!! } - val inventoryAndExopackNoHotbar: CombinedContainer + val inventoryAndExopackNoHotbar: CombinedContainer get() { if (_combinedInventory3 == null) - _combinedInventory3 = CombinedContainer.Builder() + _combinedInventory3 = CombinedContainer.Builder() .add(wrappedItemInventory, 9 .. 35) .add(exopackContainer).build()