diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt index 27eaeb517..7b207ba54 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt @@ -15,8 +15,10 @@ import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.state.BlockState import org.apache.logging.log4j.LogManager import ru.dbotthepony.mc.otm.capability.IMatteryUpgrade +import ru.dbotthepony.mc.otm.capability.UpgradeType import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage +import ru.dbotthepony.mc.otm.container.UpgradeContainer import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.core.nbt.getCompoundList import ru.dbotthepony.mc.otm.core.nbt.set @@ -64,6 +66,10 @@ abstract class MatteryWorkerBlockEntity( open val upgrades: IMatteryUpgrade? get() = null + protected fun makeUpgrades(slotCount: Int, upgradeTypes: Set): UpgradeContainer { + return UpgradeContainer(slotCount, upgradeTypes, ::shouldLockUpgradeSlots, ::markDirtyFast) + } + var balanceInputs = false init { @@ -147,6 +153,9 @@ abstract class MatteryWorkerBlockEntity( hasWorkerState && this.blockState.getValue(WorkerState.WORKER_STATE) == WorkerState.IDLE } + protected open val shouldLockUpgradeSlots: Boolean + get() = jobEventLoops.any { it.currentJob != null } + override fun tick() { super.tick() jobEventLoops.forEach { it.think() } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt index 04843effc..addf25a5c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt @@ -29,11 +29,12 @@ import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode +import java.util.function.BooleanSupplier class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.MATTER_BOTTLER, blockPos, blockState) { - val upgrades = UpgradeContainer(::markDirtyFast, 3, UpgradeType.BASIC_MATTER) + val upgrades = UpgradeContainer(3, UpgradeType.BASIC_MATTER, BooleanSupplier { blockState.getValue(WorkerState.SEMI_WORKER_STATE) !== WorkerState.IDLE }, ::markDirtyFast) override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::markDirtyFast, upgrades.transform(MachinesConfig.MatterBottler.VALUES))) val energyConfig = ConfigurableEnergy(energy) @@ -124,6 +125,7 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) : var workProgress: Float = 0f private set + private var lastTickWorking = false private var initialCapacity: Decimal? = null override fun setLevel(level: Level) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterDecomposerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterDecomposerBlockEntity.kt index f3f5fc62f..d795408ca 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterDecomposerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterDecomposerBlockEntity.kt @@ -32,6 +32,7 @@ import ru.dbotthepony.mc.otm.matter.MatterManager import ru.dbotthepony.mc.otm.menu.matter.MatterDecomposerMenu import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MItems +import java.util.function.BooleanSupplier class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState) : MatteryWorkerBlockEntity(MBlockEntities.MATTER_DECOMPOSER, pos, state, DecomposerJob.CODEC) { @@ -54,7 +55,7 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState) } } - override val upgrades = UpgradeContainer(this::markDirtyFast, 4, UpgradeType.REPLICATOR) + override val upgrades = makeUpgrades(4, UpgradeType.REPLICATOR) override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::markDirtyFast, upgrades.transform(MachinesConfig.MATTER_DECOMPOSER))) val energyConfig = ConfigurableEnergy(energy) 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 6860f13b8..5ecd55358 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 @@ -52,7 +52,7 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M } } - override val upgrades = UpgradeContainer(::markDirtyFast, 3, UpgradeType.BASIC_MATTER) + override val upgrades = makeUpgrades(3, UpgradeType.BASIC_MATTER) override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::energyLevelUpdated, upgrades.transform(MachinesConfig.MATTER_ENTANGLER))) val matter = ProfiledMatterStorage(MatterStorageImpl(::markDirtyFast, FlowDirection.INPUT, upgrades.matterCapacity(MachinesConfig.MATTER_ENTANGLER::matterCapacity))) val node = MatterNode() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReconstructorBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReconstructorBlockEntity.kt index e40fbc5a2..5eaeea296 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReconstructorBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReconstructorBlockEntity.kt @@ -34,6 +34,7 @@ import ru.dbotthepony.mc.otm.matter.IMatterValue import ru.dbotthepony.mc.otm.matter.MatterManager import ru.dbotthepony.mc.otm.menu.matter.MatterReconstructorMenu import ru.dbotthepony.mc.otm.registry.MBlockEntities +import java.util.function.BooleanSupplier class MatterReconstructorBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.MATTER_RECONSTRUCTOR, blockPos, blockState) { val repairContainer = MatteryContainer(::containerChanged, 1).also(::addDroppableContainer) @@ -54,7 +55,7 @@ class MatterReconstructorBlockEntity(blockPos: BlockPos, blockState: BlockState) var isUnableToProcess = false private set - val upgrades = UpgradeContainer(this::markDirtyFast, 3, UpgradeType.REPLICATOR) + val upgrades = UpgradeContainer(3, UpgradeType.REPLICATOR, BooleanSupplier { repairContainer.isEmpty }, ::markDirtyFast) val matter = ProfiledMatterStorage(MatterStorageImpl(::markDirtyFast, FlowDirection.INPUT, upgrades.matterCapacity(MachinesConfig.MatterReconstructor.VALUES::matterCapacity))) override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::markDirtyFast, upgrades.transform(MachinesConfig.MatterReconstructor.VALUES))) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterRecyclerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterRecyclerBlockEntity.kt index e1a4d9e3d..54f6479e1 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterRecyclerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterRecyclerBlockEntity.kt @@ -46,7 +46,7 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState) } } - override val upgrades = UpgradeContainer(this::markDirtyFast, 3, UpgradeType.BASIC_MATTER) + override val upgrades = makeUpgrades(3, UpgradeType.BASIC_MATTER) val matter = ProfiledMatterStorage(MatterStorageImpl(::matterLevelUpdated, FlowDirection.OUTPUT, upgrades.matterCapacity(MachinesConfig.MatterRecycler.VALUES::matterCapacity))) val container = MatteryContainer(::itemContainerUpdated, 1).also(::addDroppableContainer) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt index b6a955837..6e50499f5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt @@ -67,7 +67,7 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : } } - override val upgrades = UpgradeContainer(this::markDirtyFast, 3, UpgradeType.REPLICATOR) + override val upgrades = makeUpgrades(3, UpgradeType.REPLICATOR) override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::energyLevelUpdated, upgrades.transform(MachinesConfig.MATTER_REPLICATOR))) val matter = ProfiledMatterStorage(MatterStorageImpl(::matterLevelUpdated, FlowDirection.INPUT, upgrades.matterCapacity(MachinesConfig.MATTER_REPLICATOR::matterCapacity))) val outputContainer = MatteryContainer(::itemContainerUpdated, 3).also(::addDroppableContainer) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt index 7155a61dd..e87161070 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt @@ -33,7 +33,7 @@ import kotlin.math.pow class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryWorkerBlockEntity(MBlockEntities.MATTER_SCANNER, p_155229_, p_155230_, ItemJob.CODEC) { - override val upgrades = UpgradeContainer(this::markDirtyFast, 2, UpgradeType.BASIC) + override val upgrades = makeUpgrades(2, UpgradeType.BASIC) val container = MatteryContainer(::itemContainerUpdated, 1).also(::addDroppableContainer) override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::energyLevelUpdated, upgrades.transform(MachinesConfig.MATTER_SCANNER))) 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 de349f3e9..20976af69 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 @@ -51,7 +51,7 @@ sealed class AbstractPoweredFurnaceBlockEntity

(type, blockPos, blockState, ItemJob.CODEC, maxJobs) { - final override val upgrades = UpgradeContainer(this::markDirtyFast, 2, UpgradeType.BASIC_PROCESSING) + 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) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PlatePressBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PlatePressBlockEntity.kt index 74e72acef..b2faa5912 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PlatePressBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PlatePressBlockEntity.kt @@ -31,7 +31,7 @@ class PlatePressBlockEntity( blockState: BlockState, val isTwin: Boolean = false, ) : MatteryWorkerBlockEntity(if (isTwin) MBlockEntities.TWIN_PLATE_PRESS else MBlockEntities.PLATE_PRESS, blockPos, blockState, ItemJob.CODEC, if (isTwin) 2 else 1) { - override val upgrades = UpgradeContainer(this::markDirtyFast, 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))) val inputContainer = MatteryContainer(this::itemContainerUpdated, if (isTwin) 2 else 1).also(::addDroppableContainer) val outputContainer = MatteryContainer(this::itemContainerUpdated, if (isTwin) 2 else 1).also(::addDroppableContainer) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt index 46201392c..1935cfd62 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt @@ -11,6 +11,7 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.capability.addUpgradeTooltipLines +import ru.dbotthepony.mc.otm.client.CursorType import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.isCtrlDown import ru.dbotthepony.mc.otm.client.isShiftDown @@ -32,6 +33,7 @@ import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.core.math.RelativeSide import ru.dbotthepony.mc.otm.core.util.ItemStackSorter import ru.dbotthepony.mc.otm.menu.MatteryMenu +import ru.dbotthepony.mc.otm.menu.MatterySlot import ru.dbotthepony.mc.otm.menu.UpgradeSlots import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput @@ -527,7 +529,10 @@ class DeviceControls>( val grid = GridPanel(screen, frame, columns = columns, rows = rows) for (slot in upgrades.slots) { - SlotPanel(screen, grid, slot) + object : SlotPanel(screen, grid, slot) { + override val cursorType: CursorType + get() = if (upgrades.areLocked.get()) CursorType.NOT_ALLOWED else super.cursorType + } } grid.dock = Dock.FILL diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/UserFilteredSlotPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/UserFilteredSlotPanel.kt index 9130dd5f5..86c93d76a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/UserFilteredSlotPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/UserFilteredSlotPanel.kt @@ -69,6 +69,8 @@ abstract class UserFilteredSlotPanel, out T : Slot>( mouseY.toInt(), itemstack ) + + return true } else if (isHovered && slotFilter === Items.AIR && itemStack.isEmpty) { graphics.renderComponentTooltip( font, @@ -79,6 +81,8 @@ abstract class UserFilteredSlotPanel, out T : Slot>( mouseX.toInt(), mouseY.toInt() ) + + return true } return super.innerRenderTooltips(graphics, mouseX, mouseY, partialTick) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt index d82b9bf50..a9dd72df3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt @@ -48,7 +48,7 @@ import kotlin.collections.ArrayList @Suppress("UNUSED") open class MatteryContainer(var listener: ContainerListener, private val size: Int) : IMatteryContainer, INBTSerializable, StackedContentsCompatible { - constructor(watcher: () -> Unit, size: Int) : this({ _, _, _ -> watcher.invoke() }, size) + constructor(watcher: Runnable, size: Int) : this({ _, _, _ -> watcher.run() }, size) constructor(size: Int) : this(EmptyListener, size) fun interface ContainerListener { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt index df8109ef5..e15f0ce64 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt @@ -8,21 +8,25 @@ import ru.dbotthepony.mc.otm.config.VerboseEnergyBalanceValues import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.collect.reduce import ru.dbotthepony.mc.otm.core.math.Decimal +import java.util.function.BooleanSupplier import kotlin.math.pow -open class UpgradeContainer(slotCount: Int, open val allowedUpgrades: Set = UpgradeType.ALL, listener: ContainerListener = EmptyListener) : MatteryContainer(listener, slotCount), IMatteryUpgrade { - constructor(listener: () -> Unit, slotCount: Int, allowedUpgrades: Set) : this(slotCount, allowedUpgrades, { _, _, _ -> listener.invoke() }) - - final override val upgradeTypes: Set +class UpgradeContainer( + slotCount: Int, + val allowedUpgrades: Set = UpgradeType.ALL, + val shouldLockUpgradeSlots: BooleanSupplier = BooleanSupplier { false }, + listener: Runnable = Runnable {} +) : MatteryContainer(listener, slotCount), IMatteryUpgrade { + override val upgradeTypes: Set get() = setOf() - protected fun positiveDecimals(fn: (IMatteryUpgrade) -> Decimal, reducer: (Decimal, Decimal) -> Decimal): Decimal { + private fun positiveDecimals(fn: (IMatteryUpgrade) -> Decimal, reducer: (Decimal, Decimal) -> Decimal): Decimal { return iterator() .map { (it.getCapability(MatteryCapability.UPGRADE)?.let(fn) ?: Decimal.ZERO).moreThanZero() * it.count } .reduce(Decimal.ZERO, reducer) } - protected fun anyDecimals(fn: (IMatteryUpgrade) -> Decimal, reducer: (Decimal, Decimal) -> Decimal): Decimal { + private fun anyDecimals(fn: (IMatteryUpgrade) -> Decimal, reducer: (Decimal, Decimal) -> Decimal): Decimal { return iterator() .map { (it.getCapability(MatteryCapability.UPGRADE)?.let(fn) ?: Decimal.ZERO) * it.count } .reduce(Decimal.ZERO, reducer) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt index 380a1014e..28d5e053a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt @@ -76,17 +76,6 @@ data class EquipmentSlots( val curiosSlots: List> ) -/** - * [openState] **is clientside only**, attempting to use it on server will result - * in classloading exceptions. - */ -data class UpgradeSlots( - val slots: List, - val allowedTypes: Set, - val openState: Delegate, - val currentStats: IMatteryUpgrade -) - abstract class MatteryMenu( menuType: MenuType<*>?, containerId: Int, @@ -433,7 +422,7 @@ abstract class MatteryMenu( * * [condition] allows to specify when slot is invisible on GUI (hence being ignored by quick move) */ - protected fun addStorageSlot(slot: T, addMapping: Boolean = true, prepend: Boolean = false, condition: BooleanSupplier = BooleanSupplier { true }): T { + fun addStorageSlot(slot: T, addMapping: Boolean = true, prepend: Boolean = false, condition: BooleanSupplier = BooleanSupplier { true }): T { if (!externalSlots.actuallyContains(slot)) { addSlot(slot) @@ -451,7 +440,7 @@ abstract class MatteryMenu( return slot } - protected fun addStorageSlot(slot: Iterable, addMapping: Boolean = true, prepend: Boolean = false, condition: BooleanSupplier = BooleanSupplier { true }) { + fun addStorageSlot(slot: Iterable, addMapping: Boolean = true, prepend: Boolean = false, condition: BooleanSupplier = BooleanSupplier { true }) { for (value in slot) addStorageSlot(value, addMapping, prepend, condition) } @@ -459,18 +448,18 @@ abstract class MatteryMenu( /** * Marks slot as "storage" - shift clicking it will move its contents to Player's inventory */ - protected fun mapQuickMoveToInventory(slot: Slot, prepend: Boolean = false) { + fun mapQuickMoveToInventory(slot: Slot, prepend: Boolean = false) { mapQuickMove(slot, playerInventorySlots, prepend = prepend) } /** * Marks slot as "inventory" - shift clicking it will move its contents to menu's storage slots */ - protected fun mapQuickMoveToExternal(slot: Slot, prepend: Boolean = false) { + fun mapQuickMoveToExternal(slot: Slot, prepend: Boolean = false) { mapQuickMove(slot, externalSlots, prepend = prepend) } - protected fun mapQuickMove(slot: Slot, target: Collection, prepend: Boolean = false, condition: BooleanSupplier = BooleanSupplier { true }) { + fun mapQuickMove(slot: Slot, target: Collection, prepend: Boolean = false, condition: BooleanSupplier = BooleanSupplier { true }) { val listing = quickMoveMapping.computeIfAbsent(slot, Reference2ObjectFunction { ReferenceArrayList(1) /* ReferenceArrayList ибо мы используем его в некотором смысле как множество */ }) listing.remove(target) @@ -480,7 +469,7 @@ abstract class MatteryMenu( listing.add(target) } - protected fun mapQuickMove(slot: Slot, vararg target: Collection) { + fun mapQuickMove(slot: Slot, vararg target: Collection) { for (value in target) { mapQuickMove(slot, value) } @@ -743,56 +732,6 @@ abstract class MatteryMenu( ) } - fun makeUpgradeSlots(count: Int, container: UpgradeContainer?): UpgradeSlots { - if (container != null) { - require(count == container.containerSize) { "Upgrade container size ${container.containerSize} does not match with provided size $count" } - } - - val allowedTypes = EnumMap(UpgradeType::class.java) - - for (value in UpgradeType.ALL) { - val b = mSynchronizer.boolean().delegate.also { - if (container != null) { - it.accept(value in container.allowedUpgrades) - } - } - - allowedTypes[value] = BooleanSupplier { b.get() } - } - - val syncContainer = container ?: SimpleContainer(count) - - val isOpen = InstantBooleanInput(this) - - return UpgradeSlots( - slots = immutableList(count) { - object : MatterySlot(syncContainer, it) { - init { - mapQuickMoveToInventory(this) - } - - override fun mayPlace(itemStack: ItemStack): Boolean { - return super.mayPlace(itemStack) && (itemStack.getCapability(MatteryCapability.UPGRADE)?.let { it.upgradeTypes.any { allowedTypes[it]!!.asBoolean } } == true) - } - } - }.also { for (i in it.indices.reversed()) addStorageSlot(it[i], prepend = true, condition = isOpen) }, - - allowedTypes = ConditionalEnumSet(allowedTypes), - openState = isOpen, - currentStats = object : IMatteryUpgrade { - override val upgradeTypes: Set = setOf() - override val speedBonus: Double by mSynchronizer.computedDouble(DoubleSupplier { container?.speedBonus ?: 0.0 }) - override val processingItems: Int by mSynchronizer.computedInt(IntSupplier { container?.processingItems ?: 0 }) - override val energyStorageFlat: Decimal by mSynchronizer.computedDecimal { container?.energyStorageFlat ?: Decimal.ZERO } - override val energyStorage: Decimal by mSynchronizer.computedDecimal { container?.energyStorage ?: Decimal.ZERO } - override val energyConsumed: Decimal by mSynchronizer.computedDecimal { container?.energyConsumed ?: Decimal.ZERO } - override val energyThroughputFlat: Decimal by mSynchronizer.computedDecimal { container?.energyThroughputFlat ?: Decimal.ZERO } - override val energyThroughput: Decimal by mSynchronizer.computedDecimal { container?.energyThroughput ?: Decimal.ZERO } - override val failureMultiplier: Double by mSynchronizer.computedDouble(DoubleSupplier { container?.failureMultiplier ?: 1.0 }) - } - ) - } - companion object { val TEXTURE_EMPTY_SLOTS: List = ImmutableList.of( InventoryMenu.EMPTY_ARMOR_SLOT_BOOTS, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt index 940a3f7cf..1205e3699 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt @@ -9,18 +9,29 @@ import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.neoforged.neoforge.capabilities.Capabilities import ru.dbotthepony.kommons.util.Delegate +import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.value import ru.dbotthepony.mc.otm.capability.FlowDirection +import ru.dbotthepony.mc.otm.capability.IMatteryUpgrade import ru.dbotthepony.mc.otm.capability.MatteryCapability +import ru.dbotthepony.mc.otm.capability.UpgradeType import ru.dbotthepony.mc.otm.capability.energy import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.container.IMatteryContainer import ru.dbotthepony.mc.otm.container.ItemFilter +import ru.dbotthepony.mc.otm.container.UpgradeContainer +import ru.dbotthepony.mc.otm.core.collect.ConditionalEnumSet import ru.dbotthepony.mc.otm.core.immutableList +import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback +import ru.dbotthepony.mc.otm.menu.input.InstantBooleanInput import ru.dbotthepony.mc.otm.runOnClient -import java.util.ArrayList +import java.util.* +import java.util.function.BooleanSupplier +import java.util.function.DoubleSupplier +import java.util.function.IntSupplier import java.util.function.Predicate +import java.util.function.Supplier import kotlin.reflect.KMutableProperty0 /** @@ -223,3 +234,79 @@ fun MatteryMenu.addFilterControls(slots: Delegate?, amount: Int): Fi fun MatteryMenu.addFilterControls(slots: KMutableProperty0?, amount: Int): FilterControls { return addFilterControls(slots?.let { Delegate.Of(it) }, amount) } + +/** + * [openState] **is clientside only**, attempting to use it on server will result + * in classloading exceptions. + */ +data class UpgradeSlots( + val slots: List, + val allowedTypes: Set, + val openState: Delegate, + val currentStats: IMatteryUpgrade, + val areLocked: Supplier +) + +fun MatteryMenu.makeUpgradeSlots(count: Int, container: UpgradeContainer?): UpgradeSlots { + if (container != null) { + require(count == container.containerSize) { "Upgrade container size ${container.containerSize} does not match with provided size $count" } + } + + val shouldLockUpgradeSlots: Supplier + val allowedTypes = EnumMap(UpgradeType::class.java) + + if (container == null) { + shouldLockUpgradeSlots = mSynchronizer.boolean() + } else { + shouldLockUpgradeSlots = mSynchronizer.computedBoolean(container.shouldLockUpgradeSlots) + } + + for (value in UpgradeType.ALL) { + val b = mSynchronizer.boolean().delegate.also { + if (container != null) { + it.accept(value in container.allowedUpgrades) + } + } + + allowedTypes[value] = BooleanSupplier { b.get() } + } + + val syncContainer = container ?: SimpleContainer(count) + val isOpen = InstantBooleanInput(this) + + return UpgradeSlots( + slots = immutableList(count) { + object : MatterySlot(syncContainer, it) { + init { + mapQuickMoveToInventory(this) + } + + override fun mayPlace(itemStack: ItemStack): Boolean { + return super.mayPlace(itemStack) && + (itemStack.getCapability(MatteryCapability.UPGRADE)?.let { it.upgradeTypes.any { allowedTypes[it]!!.asBoolean } } == true) && + !shouldLockUpgradeSlots.get() + } + + override fun mayPickup(player: Player): Boolean { + return super.mayPickup(player) && !shouldLockUpgradeSlots.get() + } + } + }.also { for (i in it.indices.reversed()) addStorageSlot(it[i], prepend = true, condition = isOpen) }, + + areLocked = shouldLockUpgradeSlots, + + allowedTypes = ConditionalEnumSet(allowedTypes), + openState = isOpen, + currentStats = object : IMatteryUpgrade { + override val upgradeTypes: Set = setOf() + override val speedBonus: Double by mSynchronizer.computedDouble(DoubleSupplier { container?.speedBonus ?: 0.0 }) + override val processingItems: Int by mSynchronizer.computedInt(IntSupplier { container?.processingItems ?: 0 }) + override val energyStorageFlat: Decimal by mSynchronizer.computedDecimal { container?.energyStorageFlat ?: Decimal.ZERO } + override val energyStorage: Decimal by mSynchronizer.computedDecimal { container?.energyStorage ?: Decimal.ZERO } + override val energyConsumed: Decimal by mSynchronizer.computedDecimal { container?.energyConsumed ?: Decimal.ZERO } + override val energyThroughputFlat: Decimal by mSynchronizer.computedDecimal { container?.energyThroughputFlat ?: Decimal.ZERO } + override val energyThroughput: Decimal by mSynchronizer.computedDecimal { container?.energyThroughput ?: Decimal.ZERO } + override val failureMultiplier: Double by mSynchronizer.computedDouble(DoubleSupplier { container?.failureMultiplier ?: 1.0 }) + } + ) +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterBottlerMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterBottlerMenu.kt index 016d0824e..aa6cb7219 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterBottlerMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterBottlerMenu.kt @@ -16,6 +16,7 @@ import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu import ru.dbotthepony.mc.otm.menu.MatterySlot import ru.dbotthepony.mc.otm.menu.makeSlots +import ru.dbotthepony.mc.otm.menu.makeUpgradeSlots import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget import ru.dbotthepony.mc.otm.registry.MMenus diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterDecomposerMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterDecomposerMenu.kt index f2eb883a4..ff49f8ad5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterDecomposerMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterDecomposerMenu.kt @@ -13,6 +13,7 @@ import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu import ru.dbotthepony.mc.otm.menu.MatterySlot import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput +import ru.dbotthepony.mc.otm.menu.makeUpgradeSlots import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget import ru.dbotthepony.mc.otm.registry.MMenus 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 e3ebd7ebd..81291e26e 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 @@ -22,6 +22,7 @@ import ru.dbotthepony.mc.otm.menu.MatterySlot import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput import ru.dbotthepony.mc.otm.menu.makeSlots +import ru.dbotthepony.mc.otm.menu.makeUpgradeSlots import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterReconstructorMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterReconstructorMenu.kt index f019cbbea..06d83d85c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterReconstructorMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterReconstructorMenu.kt @@ -8,6 +8,7 @@ import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu import ru.dbotthepony.mc.otm.menu.MatterySlot import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput +import ru.dbotthepony.mc.otm.menu.makeUpgradeSlots import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterRecyclerMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterRecyclerMenu.kt index c374abe83..af956911d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterRecyclerMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterRecyclerMenu.kt @@ -9,6 +9,7 @@ import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu import ru.dbotthepony.mc.otm.menu.MatterySlot import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput +import ru.dbotthepony.mc.otm.menu.makeUpgradeSlots import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterReplicatorMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterReplicatorMenu.kt index 8c50152b7..c484335a6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterReplicatorMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterReplicatorMenu.kt @@ -14,6 +14,7 @@ import ru.dbotthepony.mc.otm.menu.OutputSlot import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput +import ru.dbotthepony.mc.otm.menu.makeUpgradeSlots import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget import ru.dbotthepony.mc.otm.registry.MMenus import ru.dbotthepony.mc.otm.triggers.TakeItemOutOfReplicatorTrigger diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterScannerMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterScannerMenu.kt index 48c500c0d..3010b4c1c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterScannerMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterScannerMenu.kt @@ -13,6 +13,7 @@ import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu import ru.dbotthepony.mc.otm.menu.MatterySlot import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput +import ru.dbotthepony.mc.otm.menu.makeUpgradeSlots import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget import ru.dbotthepony.mc.otm.registry.MMenus diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PlatePressMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PlatePressMenu.kt index 72a1c768c..42cc23a25 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PlatePressMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PlatePressMenu.kt @@ -16,6 +16,7 @@ import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput import ru.dbotthepony.mc.otm.menu.makeSlots +import ru.dbotthepony.mc.otm.menu.makeUpgradeSlots import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget import ru.dbotthepony.mc.otm.registry.MMenus 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 3a7eadedf..36ca763d9 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 @@ -20,6 +20,7 @@ import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput import ru.dbotthepony.mc.otm.menu.makeSlots +import ru.dbotthepony.mc.otm.menu.makeUpgradeSlots import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget import ru.dbotthepony.mc.otm.registry.MMenus