diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterEntanglerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterEntanglerBlockEntity.kt index a09006236..e66525d66 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterEntanglerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterEntanglerBlockEntity.kt @@ -24,9 +24,10 @@ import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage import ru.dbotthepony.mc.otm.capability.matter.MatterStorageImpl import ru.dbotthepony.mc.otm.capability.matter.ProfiledMatterStorage import ru.dbotthepony.mc.otm.config.MachinesConfig -import ru.dbotthepony.mc.otm.container.MatteryCraftingContainer -import ru.dbotthepony.mc.otm.container.HandlerFilter -import ru.dbotthepony.mc.otm.container.MatteryContainer +import ru.dbotthepony.mc.otm.container.IEnhancedCraftingContainer +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.math.Decimal import ru.dbotthepony.mc.otm.data.codec.DecimalCodec import ru.dbotthepony.mc.otm.data.codec.minRange @@ -35,8 +36,7 @@ import ru.dbotthepony.mc.otm.menu.matter.MatterEntanglerMenu import ru.dbotthepony.mc.otm.registry.game.MBlockEntities import ru.dbotthepony.mc.otm.registry.game.MRecipes -class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryWorkerBlockEntity( - MBlockEntities.MATTER_ENTANGLER, blockPos, blockState, Job.CODEC) { +class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryWorkerBlockEntity(MBlockEntities.MATTER_ENTANGLER, blockPos, blockState, Job.CODEC) { class Job(itemStack: ItemStack, val matter: Decimal, ticks: Double, experience: Float) : ItemJob(itemStack, ticks, MachinesConfig.MATTER_ENTANGLER.energyConsumption, experience = experience) { val matterPerTick = matter / ticks @@ -60,36 +60,36 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M val experience = ExperienceStorage(MachinesConfig.MATTER_ENTANGLER::maxExperienceStored).also(::addNeighbourListener) val energyConfig = ConfigurableEnergy(energy) - val inputs = object : MatteryCraftingContainer(::itemContainerUpdated, 3, 3) { - override fun getMaxStackSize(): Int { - return 1 + 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 false + val list = container.toList() + list[slot] = itemStack + val shadow = CraftingInput.ofPositioned(3, 3, list) + + return level + .recipeManager + .byType(MRecipes.MATTER_ENTANGLER) + .any { it.value.preemptivelyMatches(shadow, level, 3, 3) } } + + override fun canAutomationTakeItem(desired: Int): Boolean { + return false + } + + override val maxStackSize: Int + get() = 1 } - val output = object : MatteryContainer(::itemContainerUpdated, 1) { - override fun getMaxStackSize(slot: Int, itemStack: ItemStack): Int { - return Int.MAX_VALUE - } - } + val inputs = IEnhancedCraftingContainer.Wrapper(SlottedContainer.simple(3 * 3, ::InputSlot, ::setChanged), 3, 3) + val output = SlottedContainer.simple(1, AutomationFilters.ONLY_OUT.unlimitedSimpleProvider, ::markDirtyFast) val itemConfig = ConfigurableItemHandler( - input = inputs.handler(object : HandlerFilter { - override fun canInsert(slot: Int, stack: ItemStack): Boolean { - val list = inputs.toList() - list[slot] = stack - val shadow = CraftingInput.ofPositioned(3, 3, list) - - return (level ?: return false) - .recipeManager - .byType(MRecipes.MATTER_ENTANGLER) - .any { it.value.preemptivelyMatches(shadow, level!!, 3, 3) } - } - - override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { - return false - } - }), - output = output.handler(HandlerFilter.OnlyOut) + input = inputs.parent, + output = output ) init { @@ -98,7 +98,7 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M savetables.stateful(::energy, ENERGY_KEY) savetables.stateful(::matter, MATTER_STORAGE_KEY) savetables.stateful(::upgrades) - savetables.stateful(::inputs) + savetables.stateful(inputs::parent, "inputs") savetables.stateful(::output) savetables.stateful(::experience) @@ -124,7 +124,7 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M val required = status.job.matterPerTick * status.ticksAdvanced if (matter.storedMatter < required) { - matter.receiveMatter(node.graph.extractMatter(status.job.matterPerTick.coerceAtLeast(Decimal.TEN).coerceAtMost(matter.missingMatter), false), false) + matter.receiveMatter(node.graph.extractMatter(status.job.matterPerTick.coerceIn(Decimal.TEN, matter.missingMatter), false), false) } status.scale(matter.extractMatter(required, false) / required) @@ -150,7 +150,7 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M if (!energy.batteryLevel.isPositive) return JobContainer.noEnergy() - val inputs = CraftingInput.of(3, 3, inputs.toList()) + val inputs = this.inputs.asCraftInput() val recipe = (level ?: return JobContainer.failure()) .recipeManager diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/AutomationFilters.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/AutomationFilters.kt index 46dd44472..702cd4a54 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/AutomationFilters.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/AutomationFilters.kt @@ -136,11 +136,27 @@ enum class AutomationFilters : AutomationFilter { } }; - val simpleProvider: SlottedContainer.SlotProvider by lazy { + val simpleProvider: SlottedContainer.SlotProvider by lazy(LazyThreadSafetyMode.PUBLICATION) { ContainerSlot.Simple(filter = this) } - val filteredProvider: SlottedContainer.SlotProvider by lazy { + val filteredProvider: SlottedContainer.SlotProvider by lazy(LazyThreadSafetyMode.PUBLICATION) { FilteredContainerSlot.Simple(filter = this) } + + val unlimitedSimpleProvider: SlottedContainer.SlotProvider by lazy(LazyThreadSafetyMode.PUBLICATION) { + ContainerSlot.Simple(filter = this, maxStackSize = Int.MAX_VALUE) + } + + val unlimitedFilteredProvider: SlottedContainer.SlotProvider by lazy(LazyThreadSafetyMode.PUBLICATION) { + FilteredContainerSlot.Simple(filter = this, maxStackSize = Int.MAX_VALUE) + } + + val limitedSimpleProvider: SlottedContainer.SlotProvider by lazy(LazyThreadSafetyMode.PUBLICATION) { + ContainerSlot.Simple(filter = this, maxStackSize = 1) + } + + val limitedFilteredProvider: SlottedContainer.SlotProvider by lazy(LazyThreadSafetyMode.PUBLICATION) { + FilteredContainerSlot.Simple(filter = this, maxStackSize = 1) + } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterEntanglerMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterEntanglerMenu.kt index 9ecd5d33d..62eaf1120 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterEntanglerMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterEntanglerMenu.kt @@ -1,22 +1,19 @@ package ru.dbotthepony.mc.otm.menu.matter import net.minecraft.server.level.ServerPlayer -import net.minecraft.world.Container -import net.minecraft.world.SimpleContainer import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.item.ItemStack import net.minecraft.world.item.crafting.CraftingInput import ru.dbotthepony.mc.otm.block.entity.matter.MatterEntanglerBlockEntity -import ru.dbotthepony.mc.otm.container.MatteryContainer -import ru.dbotthepony.mc.otm.container.MatteryCraftingContainer -import ru.dbotthepony.mc.otm.container.get import ru.dbotthepony.mc.otm.container.set +import ru.dbotthepony.mc.otm.container.slotted.AutomationFilters +import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.item.IQuantumLinked -import ru.dbotthepony.mc.otm.menu.OutputMenuSlot -import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu import ru.dbotthepony.mc.otm.menu.MatteryMenuSlot +import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu +import ru.dbotthepony.mc.otm.menu.OutputMenuSlot import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput import ru.dbotthepony.mc.otm.menu.makeSlots @@ -39,11 +36,7 @@ class MatterEntanglerMenu( val progress = ProgressGaugeWidget(this, tile?.jobEventLoops?.get(0)) - val inputs: List = makeSlots(tile?.inputs ?: object : MatteryCraftingContainer(3, 3) { - override fun getMaxStackSize(): Int { - return 1 - } - }) { it, i -> + val inputs: List = makeSlots(tile?.inputs ?: SlottedContainer.simple(3 * 3, AutomationFilters.ALLOW.limitedFilteredProvider)) { it, i -> object : MatteryMenuSlot(it, i) { override fun mayPlace(itemStack: ItemStack): Boolean { val list = it.toList() @@ -59,21 +52,15 @@ class MatterEntanglerMenu( } } - val outputs = makeSlots(tile?.output ?: SimpleContainer(1)) { a, b -> OutputMenuSlot(a, b) { tile?.experience?.popExperience(player as ServerPlayer) } } + val outputs = makeSlots(tile?.output ?: SlottedContainer.simple(1, AutomationFilters.ONLY_OUT.unlimitedSimpleProvider)) { a, b -> OutputMenuSlot(a, b) { tile?.experience?.popExperience(player as ServerPlayer) } } val upgrades = makeUpgradeSlots(3, tile?.upgrades) val experience = TakeExperienceWidget(this, tile?.experience) - private val entangling: Container = if (tile == null) object : SimpleContainer(2) { - override fun getMaxStackSize(): Int { - return 1 - } - } else object : MatteryContainer(::rescan, 2) { - override fun getMaxStackSize(slot: Int, itemStack: ItemStack): Int { - return 1 - } - } + private val entangling = SlottedContainer.simple(2, AutomationFilters.ALLOW.limitedSimpleProvider) private fun rescan() { + if (tile == null) return + if (player is ServerPlayer && entangling[0].item is IQuantumLinked && entangling[1].item == entangling[0].item && entangling[0].isNotEmpty && entangling[1].isNotEmpty) { val result = (entangling[0].item as IQuantumLinked).merge(entangling[0], entangling[1]) entanglingC.container[0] = result @@ -90,7 +77,7 @@ class MatterEntanglerMenu( val entanglingA: MatteryMenuSlot = EntanglingInputMenuSlot(0) val entanglingB: MatteryMenuSlot = EntanglingInputMenuSlot(1) - val entanglingC: MatteryMenuSlot = object : MatteryMenuSlot(MatteryContainer(1), 0) { + val entanglingC: MatteryMenuSlot = object : MatteryMenuSlot(SlottedContainer.simple(1), 0) { override fun mayPlace(itemStack: ItemStack): Boolean { return false }