Declare IEnhancedContainer as having generic parameter Slot

This commit is contained in:
DBotThePony 2025-03-14 18:29:51 +07:00
parent a2263c5725
commit b076d29560
Signed by: DBot
GPG Key ID: DCC23B5715498507
28 changed files with 73 additions and 80 deletions

View File

@ -30,7 +30,7 @@ class DriveViewerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyUpdated, MachinesConfig.DRIVE_VIEWER)) override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyUpdated, MachinesConfig.DRIVE_VIEWER))
val energyConfig = ConfigurableEnergy(energy) val energyConfig = ConfigurableEnergy(energy)
val container: EnhancedContainer = object : EnhancedContainer(1) { val container: EnhancedContainer.Simple = object : EnhancedContainer.Simple(1) {
override fun notifySlotChanged(slot: Int, old: ItemStack) { override fun notifySlotChanged(slot: Int, old: ItemStack) {
super.notifySlotChanged(slot, old) super.notifySlotChanged(slot, old)
markDirtyFast() markDirtyFast()

View File

@ -219,7 +219,7 @@ class ItemMonitorBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
fun howMuchPlayerCrafted(ply: Player): Int = craftingAmount.getInt(ply) fun howMuchPlayerCrafted(ply: Player): Int = craftingAmount.getInt(ply)
fun lastCraftingRecipe(ply: Player) = lastCraftingRecipe[ply] fun lastCraftingRecipe(ply: Player) = lastCraftingRecipe[ply]
val craftingGrid = IEnhancedCraftingContainer.Wrapper(EnhancedContainer.withListener(3 * 3) { val craftingGrid = IEnhancedCraftingContainer.Wrapper(EnhancedContainer.WithListener(3 * 3) {
markDirtyFast() markDirtyFast()
if (!inProcessOfCraft) { if (!inProcessOfCraft) {

View File

@ -71,7 +71,7 @@ class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma
} }
val capsuleContainer = SlottedContainer.simple(1, ::CapsuleSlot, ::markDirtyFast) val capsuleContainer = SlottedContainer.simple(1, ::CapsuleSlot, ::markDirtyFast)
val servoContainer = EnhancedContainer.withListener(1, ::markDirtyFast) val servoContainer = EnhancedContainer.WithListener(1, ::markDirtyFast)
val mendingContainer = SlottedContainer.simple(1, ::MendingSlot, ::markDirtyFast).also(::addDroppableContainer) val mendingContainer = SlottedContainer.simple(1, ::MendingSlot, ::markDirtyFast).also(::addDroppableContainer)
private var mending: Holder<Enchantment>? = null private var mending: Holder<Enchantment>? = null

View File

@ -11,7 +11,7 @@ import ru.dbotthepony.mc.otm.menu.makeSlots
class MatteryChestMenu( class MatteryChestMenu(
type: MenuType<*>, containerId: Int, type: MenuType<*>, containerId: Int,
inventory: Inventory, override val rows: Int, override val columns: Int, inventory: Inventory, override val rows: Int, override val columns: Int,
container: Container = EnhancedContainer(rows * columns) container: Container = EnhancedContainer.Simple(rows * columns)
) : AbstractVanillaChestMenu(type, containerId, inventory, container) { ) : AbstractVanillaChestMenu(type, containerId, inventory, container) {
override val containerSlots = makeSlots(container, ::MatteryMenuSlot) override val containerSlots = makeSlots(container, ::MatteryMenuSlot)

View File

@ -10,7 +10,7 @@ import ru.dbotthepony.mc.otm.menu.makeSlots
class MatteryShulkerBoxMenu( class MatteryShulkerBoxMenu(
containerId: Int, containerId: Int,
inventory: Inventory, inventory: Inventory,
container: Container = EnhancedContainer(27) container: Container = EnhancedContainer.Simple(27)
) : AbstractVanillaChestMenu(VanillaMenuTypes.SHULKER_BOX, containerId, inventory, container) { ) : AbstractVanillaChestMenu(VanillaMenuTypes.SHULKER_BOX, containerId, inventory, container) {
override val containerSlots = makeSlots(container, ::Slot) override val containerSlots = makeSlots(container, ::Slot)
override val rows: Int override val rows: Int

View File

@ -23,9 +23,9 @@ import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.stream import ru.dbotthepony.mc.otm.core.stream
import java.util.stream.Stream import java.util.stream.Stream
class CombinedContainer(containers: Stream<Pair<IEnhancedContainer, Iterable<Int>>>) : ISlottedContainer, IMatteryContainer { class CombinedContainer(containers: Stream<Pair<IEnhancedContainer<*>, Iterable<Int>>>) : ISlottedContainer<IFilteredContainerSlot>, IMatteryContainer {
constructor(vararg containers: IEnhancedContainer) : this(containers.stream().map { it to (0 until it.containerSize) }) constructor(vararg containers: IEnhancedContainer<*>) : this(containers.stream().map { it to (0 until it.containerSize) })
constructor(containers: Collection<IEnhancedContainer>) : this(containers.stream().map { it to (0 until it.containerSize) }) constructor(containers: Collection<IEnhancedContainer<*>>) : this(containers.stream().map { it to (0 until it.containerSize) })
private val slots: ImmutableList<IContainerSlot> private val slots: ImmutableList<IContainerSlot>
private val slotsMap: ImmutableMap<Container, List<IContainerSlot>> private val slotsMap: ImmutableMap<Container, List<IContainerSlot>>
@ -145,7 +145,7 @@ class CombinedContainer(containers: Stream<Pair<IEnhancedContainer, Iterable<Int
} }
class Builder { class Builder {
private val values = ArrayList<Pair<IEnhancedContainer, Iterable<Int>>>() private val values = ArrayList<Pair<IEnhancedContainer<*>, Iterable<Int>>>()
fun add(container: Container): Builder { fun add(container: Container): Builder {
return add(IEnhancedContainer.wrap(container)) return add(IEnhancedContainer.wrap(container))
@ -167,27 +167,27 @@ class CombinedContainer(containers: Stream<Pair<IEnhancedContainer, Iterable<Int
return add(IEnhancedContainer.wrap(container), slots) return add(IEnhancedContainer.wrap(container), slots)
} }
fun add(container: IEnhancedContainer): Builder { fun add(container: IEnhancedContainer<*>): Builder {
values.add(container to container.slotRange) values.add(container to container.slotRange)
return this return this
} }
fun add(container: IEnhancedContainer, slots: Iterator<Int>): Builder { fun add(container: IEnhancedContainer<*>, slots: Iterator<Int>): Builder {
values.add(container to IntArrayList(slots)) values.add(container to IntArrayList(slots))
return this return this
} }
fun add(container: IEnhancedContainer, slot: Int): Builder { fun add(container: IEnhancedContainer<*>, slot: Int): Builder {
values.add(container to intArrayOf(slot).asIterable()) values.add(container to intArrayOf(slot).asIterable())
return this 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)) values.add(container to (from .. to))
return this return this
} }
fun add(container: IEnhancedContainer, slots: Iterable<Int>): Builder { fun add(container: IEnhancedContainer<*>, slots: Iterable<Int>): Builder {
values.add(container to slots) values.add(container to slots)
return this return this
} }

View File

@ -23,15 +23,9 @@ import ru.dbotthepony.mc.otm.core.nbt.set
* This is supposed to be counterpart to [SimpleContainer] of Minecraft itself, with more features * This is supposed to be counterpart to [SimpleContainer] of Minecraft itself, with more features
* and improved performance (inside [IEnhancedContainer] defined methods). * and improved performance (inside [IEnhancedContainer] defined methods).
*/ */
open class EnhancedContainer(private val size: Int) : IEnhancedContainer, INBTSerializable<CompoundTag> { abstract class EnhancedContainer<S : IContainerSlot>(private val size: Int) : IEnhancedContainer<S>, INBTSerializable<CompoundTag> {
private val items = Array(size) { ItemStack.EMPTY } private val items = Array(size) { ItemStack.EMPTY }
private val observedItems = Array(size) { ItemStack.EMPTY } private val observedItems = Array(size) { ItemStack.EMPTY }
private val slots by lazy(LazyThreadSafetyMode.PUBLICATION) { Array(size) { IContainerSlot.Simple(it, this) } }
// can be safely overridden in subclasses, very little memory will be wasted
override fun containerSlot(slot: Int): IContainerSlot {
return slots[slot]
}
protected open fun notifySlotChanged(slot: Int, old: ItemStack) {} protected open fun notifySlotChanged(slot: Int, old: ItemStack) {}
@ -184,16 +178,22 @@ open class EnhancedContainer(private val size: Int) : IEnhancedContainer, INBTSe
} }
} }
companion object { open class Simple(size: Int) : EnhancedContainer<IContainerSlot>(size) {
private val LOGGER = LogManager.getLogger() private val slots by lazy(LazyThreadSafetyMode.PUBLICATION) { Array(size) { IContainerSlot.Simple(it, this) } }
fun withListener(slots: Int, listener: Runnable): EnhancedContainer { override fun containerSlot(slot: Int): IContainerSlot {
return object : EnhancedContainer(slots) { return slots[slot]
}
}
open class WithListener(size: Int, private val listener: Runnable) : Simple(size) {
override fun notifySlotChanged(slot: Int, old: ItemStack) { override fun notifySlotChanged(slot: Int, old: ItemStack) {
super.notifySlotChanged(slot, old) super.notifySlotChanged(slot, old)
listener.run() listener.run()
} }
} }
}
companion object {
private val LOGGER = LogManager.getLogger()
} }
} }

View File

@ -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, * 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. * and actual implementations of this interface are likely to provide efficient method implementations in place of derived/emulated ones.
*/ */
interface IEnhancedContainer : IContainer, RecipeInput, Iterable<ItemStack>, StackedContentsCompatible { interface IEnhancedContainer<S : IContainerSlot> : IContainer, RecipeInput, Iterable<ItemStack>, StackedContentsCompatible {
// provide non-ambiguous get and set operators // provide non-ambiguous get and set operators
operator fun get(slot: Int): ItemStack { operator fun get(slot: Int): ItemStack {
return getItem(slot) return getItem(slot)
@ -34,9 +34,7 @@ interface IEnhancedContainer : IContainer, RecipeInput, Iterable<ItemStack>, Sta
setItem(slot, value) setItem(slot, value)
} }
fun containerSlot(slot: Int): IContainerSlot { fun containerSlot(slot: Int): S
return IContainerSlot.Simple(slot, this)
}
override fun fillStackedContents(contents: StackedContents) { override fun fillStackedContents(contents: StackedContents) {
forEach { contents.accountStack(it) } forEach { contents.accountStack(it) }
@ -45,11 +43,11 @@ interface IEnhancedContainer : IContainer, RecipeInput, Iterable<ItemStack>, Sta
/** /**
* Returns iterator over **all** slots this container has * Returns iterator over **all** slots this container has
*/ */
fun slotIterator(): Iterator<IContainerSlot> { fun slotIterator(): Iterator<S> {
return (0 until containerSize).iterator().map { containerSlot(it) } return (0 until containerSize).iterator().map { containerSlot(it) }
} }
fun nonEmptySlotIterator(): Iterator<IContainerSlot> { fun nonEmptySlotIterator(): Iterator<S> {
return slotIterator().filter { it.isNotEmpty } return slotIterator().filter { it.isNotEmpty }
} }
@ -307,7 +305,11 @@ interface IEnhancedContainer : IContainer, RecipeInput, Iterable<ItemStack>, Sta
return StreamSupport.stream(spliterator(), false) return StreamSupport.stream(spliterator(), false)
} }
private class Wrapper(private val parent: Container) : IEnhancedContainer { private class Wrapper(private val parent: Container) : IEnhancedContainer<IContainerSlot> {
override fun containerSlot(slot: Int): IContainerSlot {
return IContainerSlot.Simple(slot, parent)
}
override fun clearContent() { override fun clearContent() {
return parent.clearContent() return parent.clearContent()
} }
@ -378,8 +380,8 @@ interface IEnhancedContainer : IContainer, RecipeInput, Iterable<ItemStack>, Sta
} }
companion object { companion object {
fun wrap(other: Container): IEnhancedContainer { fun wrap(other: Container): IEnhancedContainer<*> {
if (other is IEnhancedContainer) if (other is IEnhancedContainer<*>)
return other return other
return Wrapper(other) return Wrapper(other)

View File

@ -4,7 +4,7 @@ import net.minecraft.world.entity.player.StackedContents
import net.minecraft.world.inventory.CraftingContainer import net.minecraft.world.inventory.CraftingContainer
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
interface IEnhancedCraftingContainer : IEnhancedContainer, CraftingContainer { interface IEnhancedCraftingContainer<S : IContainerSlot> : IEnhancedContainer<S>, CraftingContainer {
override fun getItems(): MutableList<ItemStack> { override fun getItems(): MutableList<ItemStack> {
return toList() return toList()
} }
@ -13,7 +13,7 @@ interface IEnhancedCraftingContainer : IEnhancedContainer, CraftingContainer {
forEach { contents.accountSimpleStack(it) } forEach { contents.accountSimpleStack(it) }
} }
class Wrapper<C : IEnhancedContainer>(val parent: C, private val width: Int, private val height: Int) : IEnhancedCraftingContainer, IEnhancedContainer by parent { class Wrapper<C : IEnhancedContainer<S>, S : IContainerSlot>(val parent: C, private val width: Int, private val height: Int) : IEnhancedCraftingContainer<S>, IEnhancedContainer<S> by parent {
init { init {
require(width * height == parent.containerSize) { "Crafting container dimensions ($width x $height) do not match container size provided (${parent.containerSize})" } require(width * height == parent.containerSize) { "Crafting container dimensions ($width x $height) do not match container size provided (${parent.containerSize})" }
} }

View File

@ -9,7 +9,7 @@ import ru.dbotthepony.mc.otm.core.collect.filter
import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.collect.map
import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.isNotEmpty
interface IMatteryContainer : IEnhancedContainer { interface IMatteryContainer : IEnhancedContainer<IFilteredContainerSlot> {
fun getSlotFilter(slot: Int): Item? fun getSlotFilter(slot: Int): Item?
/** /**

View File

@ -8,17 +8,7 @@ import ru.dbotthepony.kommons.collect.any
/** /**
* Skeletal implementation for containers which revolve around [IContainerSlot] * Skeletal implementation for containers which revolve around [IContainerSlot]
*/ */
interface ISlottedContainer<S : IContainerSlot> : IEnhancedContainer { interface ISlottedContainer<S : IContainerSlot> : IEnhancedContainer<S> {
override fun containerSlot(slot: Int): S
override fun slotIterator(): Iterator<S> {
return super.slotIterator() as Iterator<S>
}
override fun nonEmptySlotIterator(): Iterator<S> {
return super.nonEmptySlotIterator() as Iterator<S>
}
override fun setChanged(slot: Int) { override fun setChanged(slot: Int) {
containerSlot(slot).setChanged() containerSlot(slot).setChanged()
} }

View File

@ -17,7 +17,7 @@ class UpgradeContainer(
val allowedUpgrades: Set<UpgradeType> = UpgradeType.ALL, val allowedUpgrades: Set<UpgradeType> = UpgradeType.ALL,
val shouldLockUpgradeSlots: BooleanSupplier = BooleanSupplier { false }, val shouldLockUpgradeSlots: BooleanSupplier = BooleanSupplier { false },
private val listener: Runnable = Runnable {} private val listener: Runnable = Runnable {}
) : EnhancedContainer(slotCount), IMatteryUpgrade { ) : EnhancedContainer.Simple(slotCount), IMatteryUpgrade {
override fun notifySlotChanged(slot: Int, old: ItemStack) { override fun notifySlotChanged(slot: Int, old: ItemStack) {
super.notifySlotChanged(slot, old) super.notifySlotChanged(slot, old)
listener.run() listener.run()

View File

@ -13,7 +13,7 @@ import ru.dbotthepony.mc.otm.core.collect.map
import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.isNotEmpty
fun Container.containerSlot(slot: Int): IContainerSlot { fun Container.containerSlot(slot: Int): IContainerSlot {
if (this is IEnhancedContainer) { if (this is IEnhancedContainer<*>) {
return containerSlot(slot) return containerSlot(slot)
} else { } else {
return IContainerSlot.Simple(slot, this) return IContainerSlot.Simple(slot, this)
@ -24,7 +24,7 @@ fun Container.containerSlot(slot: Int): IContainerSlot {
* Returns [IContainerSlot] only if this container is [IEnhancedContainer] * Returns [IContainerSlot] only if this container is [IEnhancedContainer]
*/ */
fun Container.containerSlotOrNull(slot: Int): IContainerSlot? { fun Container.containerSlotOrNull(slot: Int): IContainerSlot? {
if (this is IEnhancedContainer) { if (this is IEnhancedContainer<*>) {
return containerSlot(slot) return containerSlot(slot)
} else { } else {
return null return null
@ -40,7 +40,7 @@ fun Slot.containerSlotOrNull(): IContainerSlot? {
} }
operator fun Container.iterator(): Iterator<ItemStack> { operator fun Container.iterator(): Iterator<ItemStack> {
if (this is IEnhancedContainer) { if (this is IEnhancedContainer<*>) {
return iterator() return iterator()
} else { } else {
return (0 until containerSize).iterator().map { this[it] }.filter { it.isNotEmpty } return (0 until containerSize).iterator().map { this[it] }.filter { it.isNotEmpty }
@ -48,7 +48,7 @@ operator fun Container.iterator(): Iterator<ItemStack> {
} }
fun Container.slotIterator(): Iterator<IContainerSlot> { fun Container.slotIterator(): Iterator<IContainerSlot> {
if (this is IEnhancedContainer) { if (this is IEnhancedContainer<*>) {
return slotIterator() return slotIterator()
} else { } else {
return (0 until containerSize).iterator().map { IContainerSlot.Simple(it, this) } return (0 until containerSize).iterator().map { IContainerSlot.Simple(it, this) }
@ -56,7 +56,7 @@ fun Container.slotIterator(): Iterator<IContainerSlot> {
} }
fun Container.nonEmptySlotIterator(): Iterator<IContainerSlot> { fun Container.nonEmptySlotIterator(): Iterator<IContainerSlot> {
if (this is IEnhancedContainer) { if (this is IEnhancedContainer<*>) {
return nonEmptySlotIterator() return nonEmptySlotIterator()
} else { } else {
return (0 until containerSize).iterator().filter { this[it].isNotEmpty }.map { IContainerSlot.Simple(it, this) } return (0 until containerSize).iterator().filter { this[it].isNotEmpty }.map { IContainerSlot.Simple(it, this) }

View File

@ -66,7 +66,7 @@ class MatterDustItem : Item(Properties().stacksTo(64)), IMatterItem {
return MatterValue(value, 1.0) return MatterValue(value, 1.0)
} }
fun moveIntoContainer(matterValue: Decimal, container: IEnhancedContainer, mainSlot: Int, stackingSlot: Int): Decimal { fun moveIntoContainer(matterValue: Decimal, container: IEnhancedContainer<*>, mainSlot: Int, stackingSlot: Int): Decimal {
@Suppress("name_shadowing") @Suppress("name_shadowing")
var matterValue = matterValue var matterValue = matterValue

View File

@ -65,8 +65,8 @@ open class MatteryMenuSlot(container: Container, index: Int, x: Int = 0, y: Int
} }
override fun setChanged() { override fun setChanged() {
if (container is IEnhancedContainer) { if (container is IEnhancedContainer<*>) {
(container as IEnhancedContainer).setChanged(containerSlot) (container as IEnhancedContainer<*>).setChanged(containerSlot)
} else { } else {
super.setChanged() super.setChanged()
} }
@ -83,7 +83,7 @@ open class MatteryMenuSlot(container: Container, index: Int, x: Int = 0, y: Int
override fun getMaxStackSize(): Int { override fun getMaxStackSize(): Int {
val container = container val container = container
if (container is IEnhancedContainer) { if (container is IEnhancedContainer<*>) {
return container.getMaxStackSize(slotIndex, ItemStack.EMPTY) return container.getMaxStackSize(slotIndex, ItemStack.EMPTY)
} else { } else {
return super.getMaxStackSize() return super.getMaxStackSize()
@ -93,7 +93,7 @@ open class MatteryMenuSlot(container: Container, index: Int, x: Int = 0, y: Int
override fun getMaxStackSize(itemStack: ItemStack): Int { override fun getMaxStackSize(itemStack: ItemStack): Int {
val container = container val container = container
if (container is IEnhancedContainer) { if (container is IEnhancedContainer<*>) {
return container.getMaxStackSize(slotIndex, itemStack) return container.getMaxStackSize(slotIndex, itemStack)
} else { } else {
return super.getMaxStackSize(itemStack) return super.getMaxStackSize(itemStack)
@ -278,7 +278,7 @@ fun MatteryMenu.makeUpgradeSlots(count: Int, container: UpgradeContainer?): Upgr
allowedTypes[value] = BooleanSupplier { b.get() } allowedTypes[value] = BooleanSupplier { b.get() }
} }
val syncContainer = container ?: EnhancedContainer(count) val syncContainer = container ?: EnhancedContainer.Simple(count)
val isOpen = InstantBooleanInput(this) val isOpen = InstantBooleanInput(this)
return UpgradeSlots( return UpgradeSlots(

View File

@ -21,7 +21,7 @@ class MatterRecyclerMenu @JvmOverloads constructor(
inventory: Inventory, inventory: Inventory,
tile: MatterRecyclerBlockEntity? = null tile: MatterRecyclerBlockEntity? = null
) : MatteryPoweredMenu(MMenus.MATTER_RECYCLER, containerID, inventory, tile) { ) : MatteryPoweredMenu(MMenus.MATTER_RECYCLER, containerID, inventory, tile) {
val input = object : MatteryMenuSlot(tile?.container ?: EnhancedContainer(1), 0) { val input = object : MatteryMenuSlot(tile?.container ?: EnhancedContainer.Simple(1), 0) {
override fun mayPlace(itemStack: ItemStack): Boolean { override fun mayPlace(itemStack: ItemStack): Boolean {
return itemStack.item is MatterDustItem && (itemStack.item as MatterDustItem).getMatterValue(itemStack) != null return itemStack.item is MatterDustItem && (itemStack.item as MatterDustItem).getMatterValue(itemStack) != null
} }

View File

@ -35,7 +35,7 @@ class MatterReplicatorMenu @JvmOverloads constructor(
val upgrades = makeUpgradeSlots(3, tile?.upgrades) val upgrades = makeUpgradeSlots(3, tile?.upgrades)
init { init {
val container = CombinedContainer(tile?.outputContainer ?: EnhancedContainer(3), tile?.dustContainer ?: EnhancedContainer(2)) val container = CombinedContainer(tile?.outputContainer ?: EnhancedContainer.Simple(3), tile?.dustContainer ?: EnhancedContainer.Simple(2))
storageSlots = immutableList(5) { storageSlots = immutableList(5) {
addStorageSlot(OutputMenuSlot(container, it, onTake = { addStorageSlot(OutputMenuSlot(container, it, onTake = {

View File

@ -31,7 +31,7 @@ class MatterScannerMenu(
val upgrades = makeUpgradeSlots(2, tile?.upgrades) val upgrades = makeUpgradeSlots(2, tile?.upgrades)
init { init {
val container = tile?.container ?: EnhancedContainer(1) val container = tile?.container ?: EnhancedContainer.Simple(1)
input = object : MatteryMenuSlot(container, 0, 64, 38) { input = object : MatteryMenuSlot(container, 0, 64, 38) {
override fun mayPlace(itemStack: ItemStack) = MatterManager.canDecompose(itemStack) override fun mayPlace(itemStack: ItemStack) = MatterManager.canDecompose(itemStack)

View File

@ -32,7 +32,7 @@ class PatternStorageMenu @JvmOverloads constructor(
}) })
} }
val patterns = tile?.container ?: EnhancedContainer(2 * 4) val patterns = tile?.container ?: EnhancedContainer.Simple(2 * 4)
storageSlots = immutableList(patterns.containerSize) { storageSlots = immutableList(patterns.containerSize) {
addStorageSlot(PatternMenuSlot(patterns, it)) addStorageSlot(PatternMenuSlot(patterns, it))

View File

@ -19,7 +19,7 @@ class DriveRackMenu @JvmOverloads constructor(
inventory: Inventory, inventory: Inventory,
tile: DriveRackBlockEntity? = null tile: DriveRackBlockEntity? = null
) : MatteryPoweredMenu(MMenus.DRIVE_RACK, containerId, inventory, tile) { ) : MatteryPoweredMenu(MMenus.DRIVE_RACK, containerId, inventory, tile) {
val storageSlots = makeSlots(tile?.container ?: EnhancedContainer(4), ::DriveMenuSlot) val storageSlots = makeSlots(tile?.container ?: EnhancedContainer.Simple(4), ::DriveMenuSlot)
val energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig) val energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig)
val profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.energy, energyWidget) val profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.energy, energyWidget)
val insertPriority = IntInputWithFeedback(this, tile?.let { it::insertPriority }) val insertPriority = IntInputWithFeedback(this, tile?.let { it::insertPriority })

View File

@ -37,7 +37,7 @@ class DriveViewerMenu(
) : MatteryPoweredMenu(MMenus.DRIVE_VIEWER, containerID, inventory, tile), INetworkedItemViewProvider { ) : MatteryPoweredMenu(MMenus.DRIVE_VIEWER, containerID, inventory, tile), INetworkedItemViewProvider {
override val networkedItemView = NetworkedItemView(inventory.player, this, tile == null) override val networkedItemView = NetworkedItemView(inventory.player, this, tile == null)
val driveSlot = object : MatteryMenuSlot(tile?.container ?: EnhancedContainer(1), 0) { val driveSlot = object : MatteryMenuSlot(tile?.container ?: EnhancedContainer.Simple(1), 0) {
override fun mayPlace(itemStack: ItemStack): Boolean { override fun mayPlace(itemStack: ItemStack): Boolean {
return itemStack.getCapability(MatteryCapability.CONDENSATION_DRIVE) != null return itemStack.getCapability(MatteryCapability.CONDENSATION_DRIVE) != null
} }

View File

@ -38,7 +38,7 @@ class ChemicalGeneratorMenu @JvmOverloads constructor(id: Int, inv: Inventory, t
} }
} }
val residueSlot = object : MatteryMenuSlot(tile?.residueContainer ?: EnhancedContainer(1), 0) { val residueSlot = object : MatteryMenuSlot(tile?.residueContainer ?: EnhancedContainer.Simple(1), 0) {
override fun mayPlace(itemStack: ItemStack): Boolean { override fun mayPlace(itemStack: ItemStack): Boolean {
return false return false
} }

View File

@ -17,7 +17,7 @@ class CobblerMenu(
inventory: Inventory, inventory: Inventory,
tile: CobblerBlockEntity? = null tile: CobblerBlockEntity? = null
) : MatteryMenu(MMenus.COBBLESTONE_GENERATOR, p_38852_, inventory, tile) { ) : MatteryMenu(MMenus.COBBLESTONE_GENERATOR, p_38852_, inventory, tile) {
val storageSlots = makeSlots(tile?.container ?: EnhancedContainer(CobblerBlockEntity.CONTAINER_SIZE), ::OutputMenuSlot) val storageSlots = makeSlots(tile?.container ?: EnhancedContainer.Simple(CobblerBlockEntity.CONTAINER_SIZE), ::OutputMenuSlot)
val redstone = EnumInputWithFeedback<RedstoneSetting>(this) val redstone = EnumInputWithFeedback<RedstoneSetting>(this)
val itemConfig = ItemConfigPlayerInput(this) val itemConfig = ItemConfigPlayerInput(this)

View File

@ -34,13 +34,13 @@ class EssenceStorageMenu(
val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig) val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig)
val fluidConfig = FluidConfigPlayerInput(this, tile?.fluidConfig) val fluidConfig = FluidConfigPlayerInput(this, tile?.fluidConfig)
val capsuleSlot = object : MatteryMenuSlot(tile?.capsuleContainer ?: EnhancedContainer(1), 0) { val capsuleSlot = object : MatteryMenuSlot(tile?.capsuleContainer ?: EnhancedContainer.Simple(1), 0) {
override fun mayPlace(itemStack: ItemStack): Boolean { override fun mayPlace(itemStack: ItemStack): Boolean {
return itemStack.item is EssenceCapsuleItem && super.mayPlace(itemStack) return itemStack.item is EssenceCapsuleItem && super.mayPlace(itemStack)
} }
} }
val servoSlot = object : MatteryMenuSlot(tile?.servoContainer ?: EnhancedContainer(1), 0) { val servoSlot = object : MatteryMenuSlot(tile?.servoContainer ?: EnhancedContainer.Simple(1), 0) {
override fun mayPlace(itemStack: ItemStack): Boolean { override fun mayPlace(itemStack: ItemStack): Boolean {
return itemStack.item == MItems.ESSENCE_SERVO && super.mayPlace(itemStack) return itemStack.item == MItems.ESSENCE_SERVO && super.mayPlace(itemStack)
} }

View File

@ -31,7 +31,7 @@ class PlatePressMenu(
isTwin: Boolean isTwin: Boolean
) : AbstractProcessingMachineMenu(type, containerID, inventory, tile) { ) : AbstractProcessingMachineMenu(type, containerID, inventory, tile) {
val inputSlots = makeSlots(tile?.inputContainer ?: SlottedContainer.filtered(if (isTwin) 2 else 1), ::MatteryMenuSlot) val inputSlots = makeSlots(tile?.inputContainer ?: SlottedContainer.filtered(if (isTwin) 2 else 1), ::MatteryMenuSlot)
val outputSlots = makeSlots(tile?.outputContainer ?: EnhancedContainer(if (isTwin) 2 else 1)) { a, b -> OutputMenuSlot(a, b) { tile?.experience?.popExperience(player as ServerPlayer) } } val outputSlots = makeSlots(tile?.outputContainer ?: EnhancedContainer.Simple(if (isTwin) 2 else 1)) { a, b -> OutputMenuSlot(a, b) { tile?.experience?.popExperience(player as ServerPlayer) } }
val gauges = immutableList(if (isTwin) 2 else 1) { ProgressGaugeWidget(this, tile?.jobEventLoops?.get(it)) } val gauges = immutableList(if (isTwin) 2 else 1) { ProgressGaugeWidget(this, tile?.jobEventLoops?.get(it)) }
override val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig, allowPush = true) override val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig, allowPush = true)

View File

@ -40,7 +40,7 @@ class PoweredFurnaceMenu(
// we can't make these slots to reject non-smeltable items // we can't make these slots to reject non-smeltable items
// since mods may add obscure recipes/ingredients which never test true on client // since mods may add obscure recipes/ingredients which never test true on client
val inputSlots = makeSlots(tile?.inputs ?: SlottedContainer.filtered(2), ::UserFilteredMenuSlot) val inputSlots = makeSlots(tile?.inputs ?: SlottedContainer.filtered(2), ::UserFilteredMenuSlot)
val outputSlots = makeSlots(tile?.outputs ?: EnhancedContainer(2)) { c, s -> OutputMenuSlot(c, s) { tile?.experience?.popExperience(player as ServerPlayer) } } val outputSlots = makeSlots(tile?.outputs ?: EnhancedContainer.Simple(2)) { c, s -> OutputMenuSlot(c, s) { tile?.experience?.popExperience(player as ServerPlayer) } }
val progressGauge = immutableList(2) { ProgressGaugeWidget(this, tile?.jobEventLoops?.get(it)) } val progressGauge = immutableList(2) { ProgressGaugeWidget(this, tile?.jobEventLoops?.get(it)) }
override val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig, allowPush = true) override val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig, allowPush = true)

View File

@ -3,8 +3,9 @@ package ru.dbotthepony.mc.otm.player
import net.minecraft.world.item.Item import net.minecraft.world.item.Item
import ru.dbotthepony.mc.otm.container.EnhancedContainer import ru.dbotthepony.mc.otm.container.EnhancedContainer
import ru.dbotthepony.mc.otm.container.IContainerSlot import ru.dbotthepony.mc.otm.container.IContainerSlot
import ru.dbotthepony.mc.otm.container.IEnhancedContainer
class ExopackContainer(size: Int, val player: MatteryPlayer) : EnhancedContainer(size) { class ExopackContainer(size: Int, val player: MatteryPlayer) : EnhancedContainer<IPlayerInventorySlot>(size) {
private inner class Slot(slot: Int) : IContainerSlot.Simple(slot, this@ExopackContainer), IPlayerInventorySlot { private inner class Slot(slot: Int) : IContainerSlot.Simple(slot, this@ExopackContainer), IPlayerInventorySlot {
override var shouldCharge: Boolean override var shouldCharge: Boolean
get() = (PlayerInventoryWrapper.SLOTS + slot) in player.slotsChargeFlag get() = (PlayerInventoryWrapper.SLOTS + slot) in player.slotsChargeFlag

View File

@ -167,7 +167,7 @@ class MatteryPlayer(val ply: Player) {
val level: Level get() = capability.ply.level() val level: Level get() = capability.ply.level()
} }
private inner class PlayerMatteryContainer(size: Int) : EnhancedContainer(size) { private inner class PlayerMatteryContainer(size: Int) : EnhancedContainer.Simple(size) {
override fun notifySlotChanged(slot: Int, old: ItemStack) { override fun notifySlotChanged(slot: Int, old: ItemStack) {
if (ply is ServerPlayer) { if (ply is ServerPlayer) {
val item = this[slot].copy() val item = this[slot].copy()
@ -317,7 +317,7 @@ class MatteryPlayer(val ply: Player) {
val wrappedInventory = PlayerInventoryWrapper(this) val wrappedInventory = PlayerInventoryWrapper(this)
val wrappedItemInventory: IEnhancedContainer = object : IEnhancedContainer by wrappedInventory { val wrappedItemInventory: IEnhancedContainer<IPlayerInventorySlot> = object : IEnhancedContainer<IPlayerInventorySlot> by wrappedInventory {
override fun getContainerSize(): Int { override fun getContainerSize(): Int {
return 36 return 36
} }