Lock upgrade slots when machine is working
This commit is contained in:
parent
d5027981ca
commit
6ce2181a95
@ -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() }
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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)))
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)))
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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 })
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user