Update Plate press to use SlottedContainer

This commit is contained in:
DBotThePony 2025-03-11 16:50:48 +07:00
parent a2b2acd3f0
commit 1f8cd2cfe3
Signed by: DBot
GPG Key ID: DCC23B5715498507
3 changed files with 49 additions and 12 deletions

View File

@ -11,6 +11,8 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
import ru.dbotthepony.mc.otm.block.entity.decorative.CargoCrateBlockEntity import ru.dbotthepony.mc.otm.block.entity.decorative.CargoCrateBlockEntity
import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.slotted.AutomationFilters
import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer
import ru.dbotthepony.mc.otm.core.multiblock.BlockEntityTag import ru.dbotthepony.mc.otm.core.multiblock.BlockEntityTag
import ru.dbotthepony.mc.otm.menu.tech.ItemHatchMenu import ru.dbotthepony.mc.otm.menu.tech.ItemHatchMenu
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
@ -21,12 +23,11 @@ class ItemHatchBlockEntity(
blockPos: BlockPos, blockPos: BlockPos,
blockState: BlockState blockState: BlockState
) : MatteryDeviceBlockEntity(type, blockPos, blockState) { ) : MatteryDeviceBlockEntity(type, blockPos, blockState) {
val container = MatteryContainer(this::markDirtyFast, CAPACITY).also(::addDroppableContainer) val container = SlottedContainer.simple(CAPACITY, if (isInput) AutomationFilters.ONLY_IN.filteredProvider else AutomationFilters.ONLY_OUT.filteredProvider, this::markDirtyFast).also(::addDroppableContainer)
val itemHandler = container.handler(if (isInput) HandlerFilter.OnlyIn else HandlerFilter.OnlyOut)
init { init {
savetables.stateful(::container, INVENTORY_KEY) savetables.stateful(::container, INVENTORY_KEY)
exposeGlobally(Capabilities.ItemHandler.BLOCK, itemHandler) exposeGlobally(Capabilities.ItemHandler.BLOCK, container)
} }
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu { override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {

View File

@ -5,6 +5,8 @@ import net.minecraft.core.BlockPos
import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.crafting.SingleRecipeInput
import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.BlockState
import net.neoforged.neoforge.capabilities.Capabilities import net.neoforged.neoforge.capabilities.Capabilities
import ru.dbotthepony.mc.otm.block.entity.ExperienceStorage import ru.dbotthepony.mc.otm.block.entity.ExperienceStorage
@ -19,12 +21,20 @@ import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.container.balance import ru.dbotthepony.mc.otm.container.balance
import ru.dbotthepony.mc.otm.container.slotted.AutomationFilters
import ru.dbotthepony.mc.otm.container.slotted.FilteredContainerSlot
import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer
import ru.dbotthepony.mc.otm.core.SimpleCache
import ru.dbotthepony.mc.otm.core.collect.any
import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.collect.filter
import ru.dbotthepony.mc.otm.core.collect.maybe import ru.dbotthepony.mc.otm.core.collect.maybe
import ru.dbotthepony.mc.otm.core.otmRandom import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.util.ItemStackKey
import ru.dbotthepony.mc.otm.core.util.asKey
import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
import ru.dbotthepony.mc.otm.registry.game.MRecipes import ru.dbotthepony.mc.otm.registry.game.MRecipes
import java.time.Duration
class PlatePressBlockEntity( class PlatePressBlockEntity(
blockPos: BlockPos, blockPos: BlockPos,
@ -33,14 +43,36 @@ class PlatePressBlockEntity(
) : MatteryWorkerBlockEntity<ItemJob>(if (isTwin) MBlockEntities.TWIN_PLATE_PRESS else MBlockEntities.PLATE_PRESS, blockPos, blockState, ItemJob.CODEC, if (isTwin) 2 else 1) { ) : MatteryWorkerBlockEntity<ItemJob>(if (isTwin) MBlockEntities.TWIN_PLATE_PRESS else MBlockEntities.PLATE_PRESS, blockPos, blockState, ItemJob.CODEC, if (isTwin) 2 else 1) {
override val upgrades = makeUpgrades(if (isTwin) 4 else 3, UpgradeType.BASIC_PROCESSING) override val upgrades = makeUpgrades(if (isTwin) 4 else 3, UpgradeType.BASIC_PROCESSING)
override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyLevelUpdated, upgrades.transform(MachinesConfig.PLATE_PRESS))) override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyLevelUpdated, upgrades.transform(MachinesConfig.PLATE_PRESS)))
val inputContainer = MatteryContainer(this::itemContainerUpdated, if (isTwin) 2 else 1).also(::addDroppableContainer)
val outputContainer = MatteryContainer(this::itemContainerUpdated, if (isTwin) 2 else 1).also(::addDroppableContainer) private inner class InputSlot(container: SlottedContainer, slot: Int) : FilteredContainerSlot(container, slot) {
override fun canAutomationPlaceItem(itemStack: ItemStack): Boolean {
if (!super.canAutomationPlaceItem(itemStack))
return false
val level = level ?: return true
val input = SingleRecipeInput(itemStack)
return cache.get(itemStack.asKey()) {
return@get level.recipeManager
.byType(MRecipes.PLATE_PRESS)
.any { it.value.matches(input, level) }
}
}
override fun canAutomationTakeItem(desired: Int): Boolean {
return false
}
}
val inputContainer = SlottedContainer.simple(if (isTwin) 2 else 1, ::InputSlot, this::itemContainerUpdated).also(::addDroppableContainer)
val outputContainer = SlottedContainer.simple(if (isTwin) 2 else 1, AutomationFilters.ONLY_OUT.simpleProvider, this::itemContainerUpdated).also(::addDroppableContainer)
val experience = ExperienceStorage(MachinesConfig.PLATE_PRESS::maxExperienceStored).also(::addNeighbourListener) val experience = ExperienceStorage(MachinesConfig.PLATE_PRESS::maxExperienceStored).also(::addNeighbourListener)
val energyConfig = ConfigurableEnergy(energy) val energyConfig = ConfigurableEnergy(energy)
val itemConfig = ConfigurableItemHandler( val itemConfig = ConfigurableItemHandler(
input = inputContainer.handler(HandlerFilter.OnlyIn), input = inputContainer,
output = outputContainer.handler(HandlerFilter.OnlyOut), output = outputContainer,
) )
init { init {
@ -76,9 +108,7 @@ class PlatePressBlockEntity(
val recipe = level.recipeManager val recipe = level.recipeManager
.byType(MRecipes.PLATE_PRESS) .byType(MRecipes.PLATE_PRESS)
.iterator() .firstOrNull { it.value.matches(inputContainer, id) }?.value ?: return JobContainer.noItem()
.filter { it.value.matches(inputContainer, id) }
.maybe()?.value ?: return JobContainer.noItem()
val toProcess = inputContainer[id].count.coerceAtMost(1 + upgrades.processingItems) val toProcess = inputContainer[id].count.coerceAtMost(1 + upgrades.processingItems)
@ -100,4 +130,8 @@ class PlatePressBlockEntity(
super.tick() super.tick()
} }
companion object {
private val cache = SimpleCache<ItemStackKey, Boolean>(16384L, Duration.ofMinutes(1L))
}
} }

View File

@ -7,6 +7,8 @@ import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.inventory.MenuType import net.minecraft.world.inventory.MenuType
import ru.dbotthepony.mc.otm.block.entity.tech.PlatePressBlockEntity import ru.dbotthepony.mc.otm.block.entity.tech.PlatePressBlockEntity
import ru.dbotthepony.mc.otm.compat.jei.PlatePressRecipeCategory import ru.dbotthepony.mc.otm.compat.jei.PlatePressRecipeCategory
import ru.dbotthepony.mc.otm.container.EnhancedContainer
import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer
import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.core.immutableList
import ru.dbotthepony.mc.otm.menu.OutputMenuSlot import ru.dbotthepony.mc.otm.menu.OutputMenuSlot
import ru.dbotthepony.mc.otm.menu.MatteryMenuSlot import ru.dbotthepony.mc.otm.menu.MatteryMenuSlot
@ -28,8 +30,8 @@ class PlatePressMenu(
tile: PlatePressBlockEntity? = null, tile: PlatePressBlockEntity? = null,
isTwin: Boolean isTwin: Boolean
) : AbstractProcessingMachineMenu(type, containerID, inventory, tile) { ) : AbstractProcessingMachineMenu(type, containerID, inventory, tile) {
val inputSlots = makeSlots(tile?.inputContainer ?: SimpleContainer(if (isTwin) 2 else 1), ::MatteryMenuSlot) val inputSlots = makeSlots(tile?.inputContainer ?: SlottedContainer.filtered(if (isTwin) 2 else 1), ::MatteryMenuSlot)
val outputSlots = makeSlots(tile?.outputContainer ?: SimpleContainer(if (isTwin) 2 else 1)) { a, b -> OutputMenuSlot(a, b) { tile?.experience?.popExperience(player as ServerPlayer) } } val outputSlots = makeSlots(tile?.outputContainer ?: EnhancedContainer(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)