diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt
index 6defd22b6..8afae2f5c 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt
@@ -29,33 +29,60 @@ import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.config.WorkerBalanceValues
import ru.dbotthepony.mc.otm.container.CombinedContainer
-import ru.dbotthepony.mc.otm.container.HandlerFilter
-import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.balance
-import ru.dbotthepony.mc.otm.core.collect.filter
-import ru.dbotthepony.mc.otm.core.collect.maybe
+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.immutableList
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.PoweredFurnaceMenu
import ru.dbotthepony.mc.otm.recipe.MatteryCookingRecipe
import ru.dbotthepony.mc.otm.recipe.MicrowaveRecipe
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
import ru.dbotthepony.mc.otm.registry.game.MRecipes
+import java.time.Duration
sealed class AbstractPoweredFurnaceBlockEntity
(
type: BlockEntityType<*>,
blockPos: BlockPos,
blockState: BlockState,
- val recipeType: RecipeType
,
- val secondaryRecipeType: RecipeType?,
- val config: WorkerBalanceValues,
maxJobs: Int = 2
) : MatteryWorkerBlockEntity(type, blockPos, blockState, ItemJob.CODEC, maxJobs) {
+ abstract val recipeType: RecipeType
+ abstract val secondaryRecipeType: RecipeType?
+ abstract val config: WorkerBalanceValues
+
final override val upgrades = makeUpgrades(2, UpgradeType.BASIC_PROCESSING)
final override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyLevelUpdated, upgrades.transform(config)))
- val inputs = MatteryContainer(this::itemContainerUpdated, maxJobs)
- val outputs = MatteryContainer(this::itemContainerUpdated, maxJobs)
+ 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
+
+ return acceptableItems.get(itemStack.asKey()) {
+ val input = SingleRecipeInput(itemStack)
+ val secondaryRecipeType = secondaryRecipeType
+
+ if (secondaryRecipeType != null && level.recipeManager.byType(secondaryRecipeType).any { it.value.matches(input, level) })
+ return@get true
+
+ return@get level.recipeManager.byType(recipeType).any { it.value.matches(input, level) }
+ }
+ }
+
+ override fun canAutomationTakeItem(desired: Int): Boolean {
+ return false
+ }
+ }
+
+ val inputs = SlottedContainer.simple(maxJobs, ::InputSlot, ::itemContainerUpdated)
+ val outputs = SlottedContainer.simple(maxJobs, AutomationFilters.ONLY_OUT.simpleProvider, ::itemContainerUpdated)
init {
addDroppableContainer(inputs)
@@ -76,8 +103,8 @@ sealed class AbstractPoweredFurnaceBlockEntity
(16384L, Duration.ofMinutes(1))
+ }
}
-class PoweredFurnaceBlockEntity(blockPos: BlockPos, blockState: BlockState) : AbstractPoweredFurnaceBlockEntity(
- MBlockEntities.POWERED_FURNACE, blockPos, blockState, RecipeType.SMELTING, null, MachinesConfig.POWERED_FURNACE) {
+class PoweredFurnaceBlockEntity(blockPos: BlockPos, blockState: BlockState) : AbstractPoweredFurnaceBlockEntity(MBlockEntities.POWERED_FURNACE, blockPos, blockState) {
+ override val recipeType: RecipeType
+ get() = RecipeType.SMELTING
+ override val secondaryRecipeType: RecipeType?
+ get() = null
+ override val config: WorkerBalanceValues
+ get() = MachinesConfig.POWERED_FURNACE
+
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
return PoweredFurnaceMenu.furnace(containerID, inventory, this)
}
}
-class PoweredBlastFurnaceBlockEntity(blockPos: BlockPos, blockState: BlockState) : AbstractPoweredFurnaceBlockEntity(
- MBlockEntities.POWERED_BLAST_FURNACE, blockPos, blockState, RecipeType.BLASTING, null, MachinesConfig.POWERED_FURNACE) {
+class PoweredBlastFurnaceBlockEntity(blockPos: BlockPos, blockState: BlockState) : AbstractPoweredFurnaceBlockEntity(MBlockEntities.POWERED_BLAST_FURNACE, blockPos, blockState) {
+ override val recipeType: RecipeType
+ get() = RecipeType.BLASTING
+ override val secondaryRecipeType: RecipeType?
+ get() = null
+ override val config: WorkerBalanceValues
+ get() = MachinesConfig.POWERED_FURNACE
+
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
return PoweredFurnaceMenu.blasting(containerID, inventory, this)
}
}
-class PoweredSmokerBlockEntity(blockPos: BlockPos, blockState: BlockState) : AbstractPoweredFurnaceBlockEntity(
- MBlockEntities.POWERED_SMOKER, blockPos, blockState, RecipeType.SMOKING, MRecipes.MICROWAVE, MachinesConfig.POWERED_FURNACE) {
+class PoweredSmokerBlockEntity(blockPos: BlockPos, blockState: BlockState) : AbstractPoweredFurnaceBlockEntity(MBlockEntities.POWERED_SMOKER, blockPos, blockState) {
+ override val recipeType: RecipeType
+ get() = RecipeType.SMOKING
+ override val secondaryRecipeType: RecipeType
+ get() = MRecipes.MICROWAVE
+ override val config: WorkerBalanceValues
+ get() = MachinesConfig.POWERED_FURNACE
+
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
return PoweredFurnaceMenu.smoking(containerID, inventory, this)
}
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PoweredFurnaceMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PoweredFurnaceMenu.kt
index 85739a185..f66e42b08 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PoweredFurnaceMenu.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PoweredFurnaceMenu.kt
@@ -1,19 +1,24 @@
package ru.dbotthepony.mc.otm.menu.tech
+import com.google.common.collect.ImmutableList
import mezz.jei.api.constants.RecipeTypes
import mezz.jei.api.recipe.RecipeType
import net.minecraft.server.level.ServerPlayer
-import net.minecraft.world.SimpleContainer
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.inventory.MenuType
+import net.minecraft.world.item.crafting.Recipe
+import net.minecraft.world.item.crafting.SingleRecipeInput
import ru.dbotthepony.mc.otm.block.entity.tech.AbstractPoweredFurnaceBlockEntity
import ru.dbotthepony.mc.otm.block.entity.tech.PoweredBlastFurnaceBlockEntity
import ru.dbotthepony.mc.otm.block.entity.tech.PoweredFurnaceBlockEntity
import ru.dbotthepony.mc.otm.block.entity.tech.PoweredSmokerBlockEntity
import ru.dbotthepony.mc.otm.compat.jei.MicrowaveRecipeCategory
+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.menu.OutputMenuSlot
import ru.dbotthepony.mc.otm.menu.MatteryMenuSlot
+import ru.dbotthepony.mc.otm.menu.UserFilteredMenuSlot
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput
import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput
@@ -23,6 +28,7 @@ import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.TakeExperienceWidget
import ru.dbotthepony.mc.otm.registry.game.MMenus
+import ru.dbotthepony.mc.otm.registry.game.MRecipes
import java.util.function.Supplier
class PoweredFurnaceMenu(
@@ -31,8 +37,10 @@ class PoweredFurnaceMenu(
inventory: Inventory,
tile: AbstractPoweredFurnaceBlockEntity<*, *>? = null
) : AbstractProcessingMachineMenu(type, containerID, inventory, tile) {
- val inputSlots = makeSlots(tile?.inputs ?: SimpleContainer(2), ::MatteryMenuSlot)
- val outputSlots = makeSlots(tile?.outputs ?: SimpleContainer(2)) { c, s -> OutputMenuSlot(c, s) { tile?.experience?.popExperience(player as ServerPlayer) } }
+ // we can't make these slots to reject non-smeltable items
+ // since mods may add obscure recipes/ingredients which never test true on client
+ 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 progressGauge = immutableList(2) { ProgressGaugeWidget(this, tile?.jobEventLoops?.get(it)) }
override val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig, allowPush = true)