Lock upgrade slots when machine is working

This commit is contained in:
DBotThePony 2024-09-01 18:05:34 +07:00
parent d5027981ca
commit 6ce2181a95
Signed by: DBot
GPG Key ID: DCC23B5715498507
25 changed files with 146 additions and 85 deletions

View File

@ -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<JobType : IJob>(
open val upgrades: IMatteryUpgrade? get() = null
protected fun makeUpgrades(slotCount: Int, upgradeTypes: Set<UpgradeType>): UpgradeContainer {
return UpgradeContainer(slotCount, upgradeTypes, ::shouldLockUpgradeSlots, ::markDirtyFast)
}
var balanceInputs = false
init {
@ -147,6 +153,9 @@ abstract class MatteryWorkerBlockEntity<JobType : IJob>(
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() }

View File

@ -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) {

View File

@ -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<MatterDecomposerBlockEntity.DecomposerJob>(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)

View File

@ -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()

View File

@ -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)))

View File

@ -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)

View File

@ -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)

View File

@ -33,7 +33,7 @@ import kotlin.math.pow
class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
MatteryWorkerBlockEntity<ItemJob>(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)))

View File

@ -51,7 +51,7 @@ sealed class AbstractPoweredFurnaceBlockEntity<P : AbstractCookingRecipe, S : Ma
val config: WorkerBalanceValues,
maxJobs: Int = 2
) : MatteryWorkerBlockEntity<ItemJob>(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)

View File

@ -31,7 +31,7 @@ class PlatePressBlockEntity(
blockState: BlockState,
val isTwin: Boolean = false,
) : MatteryWorkerBlockEntity<ItemJob>(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)

View File

@ -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<out S : MatteryScreen<*>>(
val grid = GridPanel(screen, frame, columns = columns, rows = rows)
for (slot in upgrades.slots) {
SlotPanel(screen, grid, slot)
object : SlotPanel<S, MatterySlot>(screen, grid, slot) {
override val cursorType: CursorType
get() = if (upgrades.areLocked.get()) CursorType.NOT_ALLOWED else super.cursorType
}
}
grid.dock = Dock.FILL

View File

@ -69,6 +69,8 @@ abstract class UserFilteredSlotPanel<out S : MatteryScreen<*>, 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 S : MatteryScreen<*>, out T : Slot>(
mouseX.toInt(),
mouseY.toInt()
)
return true
}
return super.innerRenderTooltips(graphics, mouseX, mouseY, partialTick)

View File

@ -48,7 +48,7 @@ import kotlin.collections.ArrayList
@Suppress("UNUSED")
open class MatteryContainer(var listener: ContainerListener, private val size: Int) : IMatteryContainer, INBTSerializable<Tag?>, 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 {

View File

@ -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> = UpgradeType.ALL, listener: ContainerListener = EmptyListener) : MatteryContainer(listener, slotCount), IMatteryUpgrade {
constructor(listener: () -> Unit, slotCount: Int, allowedUpgrades: Set<UpgradeType>) : this(slotCount, allowedUpgrades, { _, _, _ -> listener.invoke() })
final override val upgradeTypes: Set<UpgradeType>
class UpgradeContainer(
slotCount: Int,
val allowedUpgrades: Set<UpgradeType> = UpgradeType.ALL,
val shouldLockUpgradeSlots: BooleanSupplier = BooleanSupplier { false },
listener: Runnable = Runnable {}
) : MatteryContainer(listener, slotCount), IMatteryUpgrade {
override val upgradeTypes: Set<UpgradeType>
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)

View File

@ -76,17 +76,6 @@ data class EquipmentSlots(
val curiosSlots: List<PlayerSlot<Slot, Slot>>
)
/**
* [openState] **is clientside only**, attempting to use it on server will result
* in classloading exceptions.
*/
data class UpgradeSlots(
val slots: List<MatterySlot>,
val allowedTypes: Set<UpgradeType>,
val openState: Delegate<Boolean>,
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 <T : Slot> addStorageSlot(slot: T, addMapping: Boolean = true, prepend: Boolean = false, condition: BooleanSupplier = BooleanSupplier { true }): T {
fun <T : Slot> 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<Slot>, addMapping: Boolean = true, prepend: Boolean = false, condition: BooleanSupplier = BooleanSupplier { true }) {
fun addStorageSlot(slot: Iterable<Slot>, 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<Slot>, prepend: Boolean = false, condition: BooleanSupplier = BooleanSupplier { true }) {
fun mapQuickMove(slot: Slot, target: Collection<Slot>, 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<Slot>) {
fun mapQuickMove(slot: Slot, vararg target: Collection<Slot>) {
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, BooleanSupplier>(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<UpgradeType> = 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<ResourceLocation> = ImmutableList.of(
InventoryMenu.EMPTY_ARMOR_SLOT_BOOTS,

View File

@ -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<ItemFilter>?, amount: Int): Fi
fun MatteryMenu.addFilterControls(slots: KMutableProperty0<ItemFilter>?, 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<MatterySlot>,
val allowedTypes: Set<UpgradeType>,
val openState: Delegate<Boolean>,
val currentStats: IMatteryUpgrade,
val areLocked: Supplier<Boolean>
)
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<Boolean>
val allowedTypes = EnumMap<UpgradeType, BooleanSupplier>(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<UpgradeType> = 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 })
}
)
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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