Move Matter Entangler to Slotted container

This commit is contained in:
DBotThePony 2025-03-05 13:17:57 +07:00
parent 5942ab2126
commit 3910e38add
Signed by: DBot
GPG Key ID: DCC23B5715498507
3 changed files with 61 additions and 58 deletions

View File

@ -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<MatterEntanglerBlockEntity.Job>(
MBlockEntities.MATTER_ENTANGLER, blockPos, blockState, Job.CODEC) {
class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryWorkerBlockEntity<MatterEntanglerBlockEntity.Job>(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

View File

@ -136,11 +136,27 @@ enum class AutomationFilters : AutomationFilter<ContainerSlot> {
}
};
val simpleProvider: SlottedContainer.SlotProvider<ContainerSlot> by lazy {
val simpleProvider: SlottedContainer.SlotProvider<ContainerSlot> by lazy(LazyThreadSafetyMode.PUBLICATION) {
ContainerSlot.Simple(filter = this)
}
val filteredProvider: SlottedContainer.SlotProvider<FilteredContainerSlot> by lazy {
val filteredProvider: SlottedContainer.SlotProvider<FilteredContainerSlot> by lazy(LazyThreadSafetyMode.PUBLICATION) {
FilteredContainerSlot.Simple(filter = this)
}
val unlimitedSimpleProvider: SlottedContainer.SlotProvider<ContainerSlot> by lazy(LazyThreadSafetyMode.PUBLICATION) {
ContainerSlot.Simple(filter = this, maxStackSize = Int.MAX_VALUE)
}
val unlimitedFilteredProvider: SlottedContainer.SlotProvider<FilteredContainerSlot> by lazy(LazyThreadSafetyMode.PUBLICATION) {
FilteredContainerSlot.Simple(filter = this, maxStackSize = Int.MAX_VALUE)
}
val limitedSimpleProvider: SlottedContainer.SlotProvider<ContainerSlot> by lazy(LazyThreadSafetyMode.PUBLICATION) {
ContainerSlot.Simple(filter = this, maxStackSize = 1)
}
val limitedFilteredProvider: SlottedContainer.SlotProvider<FilteredContainerSlot> by lazy(LazyThreadSafetyMode.PUBLICATION) {
FilteredContainerSlot.Simple(filter = this, maxStackSize = 1)
}
}

View File

@ -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<MatteryMenuSlot> = makeSlots(tile?.inputs ?: object : MatteryCraftingContainer(3, 3) {
override fun getMaxStackSize(): Int {
return 1
}
}) { it, i ->
val inputs: List<MatteryMenuSlot> = 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
}