idling machines are now faster than ever
Rotate faaaster banan-a
This commit is contained in:
parent
a6eb0ca7f1
commit
90348d5789
@ -54,6 +54,7 @@ import ru.dbotthepony.mc.otm.core.math.BlockRotation
|
|||||||
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
||||||
import ru.dbotthepony.mc.otm.core.math.minus
|
import ru.dbotthepony.mc.otm.core.math.minus
|
||||||
import ru.dbotthepony.mc.otm.core.math.plus
|
import ru.dbotthepony.mc.otm.core.math.plus
|
||||||
|
import ru.dbotthepony.mc.otm.core.util.IntCounter
|
||||||
import ru.dbotthepony.mc.otm.core.util.Savetables
|
import ru.dbotthepony.mc.otm.core.util.Savetables
|
||||||
import ru.dbotthepony.mc.otm.core.util.TickList
|
import ru.dbotthepony.mc.otm.core.util.TickList
|
||||||
import ru.dbotthepony.mc.otm.network.BlockEntitySyncPacket
|
import ru.dbotthepony.mc.otm.network.BlockEntitySyncPacket
|
||||||
@ -106,6 +107,8 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
|
|||||||
private data class SidelessCap<T : Any>(val cap: T, var optional: LazyOptional<T>)
|
private data class SidelessCap<T : Any>(val cap: T, var optional: LazyOptional<T>)
|
||||||
private val sidelessCaps = Reference2ObjectOpenHashMap<Capability<*>, SidelessCap<*>>()
|
private val sidelessCaps = Reference2ObjectOpenHashMap<Capability<*>, SidelessCap<*>>()
|
||||||
protected val tickList = TickList()
|
protected val tickList = TickList()
|
||||||
|
protected val blockStateChangesCounter = IntCounter()
|
||||||
|
protected val dirtyListeners = ISubscriptable.Impl<Unit>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shared savetables, written both to level storage and to item tag
|
* Shared savetables, written both to level storage and to item tag
|
||||||
@ -484,6 +487,7 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
|
|||||||
|
|
||||||
@Suppress("OVERRIDE_DEPRECATION")
|
@Suppress("OVERRIDE_DEPRECATION")
|
||||||
override fun setBlockState(pBlockState: BlockState) {
|
override fun setBlockState(pBlockState: BlockState) {
|
||||||
|
blockStateChangesCounter.increment()
|
||||||
val old = blockRotation
|
val old = blockRotation
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
super.setBlockState(pBlockState)
|
super.setBlockState(pBlockState)
|
||||||
@ -513,14 +517,23 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun setChanged() {
|
||||||
|
super.setChanged()
|
||||||
|
|
||||||
|
dirtyListeners.accept(Unit)
|
||||||
|
}
|
||||||
|
|
||||||
// Just to mark chunk unsaved
|
// Just to mark chunk unsaved
|
||||||
open fun setChangedLight() {
|
open fun markDirtyFast() {
|
||||||
val level = level
|
val level = level
|
||||||
|
|
||||||
if (level is ServerLevel) {
|
if (level is ServerLevel) {
|
||||||
level.chunkSource.getChunkNow(
|
level.chunkSource.getChunkNow(
|
||||||
SectionPos.blockToSectionCoord(blockPos.x),
|
SectionPos.blockToSectionCoord(blockPos.x),
|
||||||
SectionPos.blockToSectionCoord(blockPos.z))?.isUnsaved = true
|
SectionPos.blockToSectionCoord(blockPos.z))?.isUnsaved = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dirtyListeners.accept(Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
val synchronizer = FieldSynchronizer {
|
val synchronizer = FieldSynchronizer {
|
||||||
|
@ -44,7 +44,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
|||||||
var customDisplayName: Component? = null
|
var customDisplayName: Component? = null
|
||||||
|
|
||||||
override val redstoneControl: AbstractRedstoneControl = RedstoneControl { new, old ->
|
override val redstoneControl: AbstractRedstoneControl = RedstoneControl { new, old ->
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
|
|
||||||
if (new != old)
|
if (new != old)
|
||||||
redstoneStatusUpdated(new, old)
|
redstoneStatusUpdated(new, old)
|
||||||
@ -149,7 +149,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
|||||||
|
|
||||||
if (access.read() != value) {
|
if (access.read() != value) {
|
||||||
access.write(value)
|
access.write(value)
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
|
|
||||||
if (value == FlowDirection.NONE) {
|
if (value == FlowDirection.NONE) {
|
||||||
controller.close()
|
controller.close()
|
||||||
@ -166,7 +166,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
|||||||
var automatePull = false
|
var automatePull = false
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
updateTickerState()
|
updateTickerState()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
|||||||
var automatePush = false
|
var automatePush = false
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
updateTickerState()
|
updateTickerState()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,6 +281,11 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
|||||||
val rightDefault: FlowDirection = modesRight,
|
val rightDefault: FlowDirection = modesRight,
|
||||||
val topDefault: FlowDirection = modesTop,
|
val topDefault: FlowDirection = modesTop,
|
||||||
val bottomDefault: FlowDirection = modesBottom,
|
val bottomDefault: FlowDirection = modesBottom,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If battery level can update without calling [markDirtyFast]/[setChanged]
|
||||||
|
*/
|
||||||
|
val volatileEnergyValues: Boolean = false
|
||||||
) {
|
) {
|
||||||
constructor(
|
constructor(
|
||||||
energy: T,
|
energy: T,
|
||||||
@ -291,6 +296,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
|||||||
rightDefault: FlowDirection = possibleModes,
|
rightDefault: FlowDirection = possibleModes,
|
||||||
topDefault: FlowDirection = possibleModes,
|
topDefault: FlowDirection = possibleModes,
|
||||||
bottomDefault: FlowDirection = possibleModes,
|
bottomDefault: FlowDirection = possibleModes,
|
||||||
|
volatileEnergyValues: Boolean = false
|
||||||
) : this(
|
) : this(
|
||||||
energy,
|
energy,
|
||||||
modesFront = possibleModes, frontDefault = frontDefault,
|
modesFront = possibleModes, frontDefault = frontDefault,
|
||||||
@ -299,6 +305,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
|||||||
modesRight = possibleModes, rightDefault = rightDefault,
|
modesRight = possibleModes, rightDefault = rightDefault,
|
||||||
modesTop = possibleModes, topDefault = topDefault,
|
modesTop = possibleModes, topDefault = topDefault,
|
||||||
modesBottom = possibleModes, bottomDefault = bottomDefault,
|
modesBottom = possibleModes, bottomDefault = bottomDefault,
|
||||||
|
volatileEnergyValues = volatileEnergyValues,
|
||||||
)
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -349,14 +356,18 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
|||||||
private val ticker = tickList.Ticker(this)
|
private val ticker = tickList.Ticker(this)
|
||||||
|
|
||||||
private fun updateTickerState() {
|
private fun updateTickerState() {
|
||||||
ticker.isEnabled = (automatePull || automatePush) && energyFlow != FlowDirection.NONE && !redstoneControl.isBlockedByRedstone && neighbour.get().isPresent
|
ticker.isEnabled = (automatePull || automatePush) &&
|
||||||
|
energyFlow != FlowDirection.NONE &&
|
||||||
|
!redstoneControl.isBlockedByRedstone &&
|
||||||
|
neighbour.get().isPresent &&
|
||||||
|
(volatileEnergyValues || energy.batteryLevel.isPositive)
|
||||||
}
|
}
|
||||||
|
|
||||||
// var automatePull by synchronizer.bool().property
|
// var automatePull by synchronizer.bool().property
|
||||||
var automatePull = false
|
var automatePull = false
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
updateTickerState()
|
updateTickerState()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,7 +375,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
|||||||
var automatePush = false
|
var automatePush = false
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
updateTickerState()
|
updateTickerState()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,6 +384,10 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
|||||||
savetables.bool(::automatePull, "energy_${side}_pull")
|
savetables.bool(::automatePull, "energy_${side}_pull")
|
||||||
savetables.bool(::automatePush, "energy_${side}_push")
|
savetables.bool(::automatePush, "energy_${side}_push")
|
||||||
|
|
||||||
|
dirtyListeners.addListener {
|
||||||
|
updateTickerState()
|
||||||
|
}
|
||||||
|
|
||||||
tickList.once {
|
tickList.once {
|
||||||
redstoneControl.addListener {
|
redstoneControl.addListener {
|
||||||
updateTickerState()
|
updateTickerState()
|
||||||
@ -417,9 +432,6 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
if (energyFlow == FlowDirection.NONE || !automatePull && !automatePush || redstoneControl.isBlockedByRedstone)
|
|
||||||
return
|
|
||||||
|
|
||||||
neighbour.get().ifPresentK {
|
neighbour.get().ifPresentK {
|
||||||
if (energyFlow.input && automatePull) {
|
if (energyFlow.input && automatePull) {
|
||||||
moveEnergy(source = it, destination = energy, simulate = false)
|
moveEnergy(source = it, destination = energy, simulate = false)
|
||||||
@ -436,7 +448,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
|||||||
|
|
||||||
if (access.read() != value) {
|
if (access.read() != value) {
|
||||||
access.write(value)
|
access.write(value)
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
|
|
||||||
if (value == FlowDirection.NONE) {
|
if (value == FlowDirection.NONE) {
|
||||||
for (controller in capControllers)
|
for (controller in capControllers)
|
||||||
@ -604,7 +616,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
|||||||
|
|
||||||
if (access.read() != value) {
|
if (access.read() != value) {
|
||||||
access.write(value)
|
access.write(value)
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
|
|
||||||
if (value == ItemHandlerMode.DISABLED) {
|
if (value == ItemHandlerMode.DISABLED) {
|
||||||
capController.close()
|
capController.close()
|
||||||
@ -627,7 +639,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
|||||||
set(value) {
|
set(value) {
|
||||||
if (field != value) {
|
if (field != value) {
|
||||||
field = value
|
field = value
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
innerSlotPush = 0
|
innerSlotPush = 0
|
||||||
@ -642,7 +654,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
|||||||
set(value) {
|
set(value) {
|
||||||
if (field != value) {
|
if (field != value) {
|
||||||
field = value
|
field = value
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
innerSlotPush = 0
|
innerSlotPush = 0
|
||||||
|
@ -12,6 +12,7 @@ import net.minecraft.world.level.block.entity.BlockEntityType
|
|||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
import ru.dbotthepony.mc.otm.capability.*
|
import ru.dbotthepony.mc.otm.capability.*
|
||||||
|
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.ItemEnergyStorageImpl
|
import ru.dbotthepony.mc.otm.capability.energy.ItemEnergyStorageImpl
|
||||||
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
@ -21,8 +22,10 @@ import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
|||||||
import ru.dbotthepony.mc.otm.core.nbt.map
|
import ru.dbotthepony.mc.otm.core.nbt.map
|
||||||
|
|
||||||
abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : MatteryDeviceBlockEntity(p_155228_, p_155229_, p_155230_) {
|
abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : MatteryDeviceBlockEntity(p_155228_, p_155229_, p_155230_) {
|
||||||
val batteryContainer = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
|
val batteryContainer = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer)
|
||||||
val batteryItemHandler = batteryContainer.handler(HandlerFilter.Dischargeable)
|
val batteryItemHandler = batteryContainer.handler(HandlerFilter.Dischargeable)
|
||||||
|
open val energy: IMatteryEnergyStorage?
|
||||||
|
get() = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
savetables.stateful(::batteryContainer, BATTERY_KEY)
|
savetables.stateful(::batteryContainer, BATTERY_KEY)
|
||||||
@ -31,10 +34,9 @@ abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229
|
|||||||
override fun tick() {
|
override fun tick() {
|
||||||
super.tick()
|
super.tick()
|
||||||
|
|
||||||
val energy = matteryEnergy
|
if (batteryContainer.isEmpty) return
|
||||||
if (energy == null || batteryContainer.isEmpty)
|
|
||||||
return
|
|
||||||
|
|
||||||
|
val energy = energy ?: return
|
||||||
var demand = energy.receiveEnergy(energy.missingPower, true)
|
var demand = energy.receiveEnergy(energy.missingPower, true)
|
||||||
if (demand.isZero) return
|
if (demand.isZero) return
|
||||||
|
|
||||||
|
@ -16,10 +16,10 @@ import org.apache.logging.log4j.LogManager
|
|||||||
import ru.dbotthepony.mc.otm.capability.IMatteryUpgrade
|
import ru.dbotthepony.mc.otm.capability.IMatteryUpgrade
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.matteryEnergy
|
|
||||||
import ru.dbotthepony.mc.otm.core.immutableList
|
import ru.dbotthepony.mc.otm.core.immutableList
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.getCompoundList
|
import ru.dbotthepony.mc.otm.core.nbt.getCompoundList
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.util.countingLazy
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple machine, which can work on only one job type.
|
* Simple machine, which can work on only one job type.
|
||||||
@ -36,7 +36,7 @@ abstract class MatteryWorkerBlockEntity<JobType : IJob>(
|
|||||||
val jobEventLoops: ImmutableList<MachineJobEventLoop<JobType>> = immutableList(maxJobs) { id ->
|
val jobEventLoops: ImmutableList<MachineJobEventLoop<JobType>> = immutableList(maxJobs) { id ->
|
||||||
object : MachineJobEventLoop<JobType>(jobCodec) {
|
object : MachineJobEventLoop<JobType>(jobCodec) {
|
||||||
override val energy: IMatteryEnergyStorage?
|
override val energy: IMatteryEnergyStorage?
|
||||||
get() = matteryEnergy
|
get() = this@MatteryWorkerBlockEntity.energy
|
||||||
override val isBlockedByRedstone: Boolean
|
override val isBlockedByRedstone: Boolean
|
||||||
get() = redstoneControl.isBlockedByRedstone
|
get() = redstoneControl.isBlockedByRedstone
|
||||||
override val upgrades: IMatteryUpgrade?
|
override val upgrades: IMatteryUpgrade?
|
||||||
@ -55,7 +55,7 @@ abstract class MatteryWorkerBlockEntity<JobType : IJob>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onJobTick(status: JobStatus<JobType>) {
|
override fun onJobTick(status: JobStatus<JobType>) {
|
||||||
super@MatteryWorkerBlockEntity.setChangedLight()
|
super@MatteryWorkerBlockEntity.markDirtyFast()
|
||||||
return this@MatteryWorkerBlockEntity.onJobTick(status, id)
|
return this@MatteryWorkerBlockEntity.onJobTick(status, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,13 +105,13 @@ abstract class MatteryWorkerBlockEntity<JobType : IJob>(
|
|||||||
jobEventLoops.forEach { it.isIdling = false }
|
jobEventLoops.forEach { it.isIdling = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setChangedLight() {
|
override fun markDirtyFast() {
|
||||||
super.setChangedLight()
|
super.markDirtyFast()
|
||||||
jobEventLoops.forEach { it.isIdling = false }
|
jobEventLoops.forEach { it.isIdling = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun energyLevelUpdated() {
|
protected fun energyLevelUpdated() {
|
||||||
super.setChangedLight()
|
super.markDirtyFast()
|
||||||
jobEventLoops.forEach { it.notify(MachineJobEventLoop.IdleReason.POWER) }
|
jobEventLoops.forEach { it.notify(MachineJobEventLoop.IdleReason.POWER) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ abstract class MatteryWorkerBlockEntity<JobType : IJob>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected fun matterLevelUpdated() {
|
protected fun matterLevelUpdated() {
|
||||||
super.setChangedLight()
|
super.markDirtyFast()
|
||||||
jobEventLoops.forEach { it.notify(MachineJobEventLoop.IdleReason.MATTER) }
|
jobEventLoops.forEach { it.notify(MachineJobEventLoop.IdleReason.MATTER) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,18 +130,36 @@ abstract class MatteryWorkerBlockEntity<JobType : IJob>(
|
|||||||
jobEventLoops.forEach { it.isIdling = newBlocked }
|
jobEventLoops.forEach { it.isIdling = newBlocked }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val hasWorkerState by countingLazy(blockStateChangesCounter) {
|
||||||
|
this.blockState.hasProperty(WorkerState.WORKER_STATE)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val isWorkingState by countingLazy(blockStateChangesCounter) {
|
||||||
|
hasWorkerState && this.blockState.getValue(WorkerState.WORKER_STATE) == WorkerState.WORKING
|
||||||
|
}
|
||||||
|
|
||||||
|
private val isErrorState by countingLazy(blockStateChangesCounter) {
|
||||||
|
hasWorkerState && this.blockState.getValue(WorkerState.WORKER_STATE) == WorkerState.ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
private val isIdleState by countingLazy(blockStateChangesCounter) {
|
||||||
|
hasWorkerState && this.blockState.getValue(WorkerState.WORKER_STATE) == WorkerState.IDLE
|
||||||
|
}
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
super.tick()
|
super.tick()
|
||||||
jobEventLoops.forEach { it.think() }
|
jobEventLoops.forEach { it.think() }
|
||||||
|
|
||||||
if (jobEventLoops.any { it.workingTicksAnim > 20 } && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.WORKING) {
|
if (hasWorkerState) {
|
||||||
|
if (jobEventLoops.any { it.workingTicksAnim > 20 } && !isWorkingState) {
|
||||||
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS)
|
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS)
|
||||||
} else if (jobEventLoops.any { it.errorTicksAnim > 20 } && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.ERROR) {
|
} else if (jobEventLoops.any { it.errorTicksAnim > 20 } && !isErrorState) {
|
||||||
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.ERROR), Block.UPDATE_CLIENTS)
|
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.ERROR), Block.UPDATE_CLIENTS)
|
||||||
} else if (jobEventLoops.all { it.idleTicksAnim > 20 } && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.IDLE) {
|
} else if (jobEventLoops.all { it.idleTicksAnim > 20 } && !isIdleState) {
|
||||||
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS)
|
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val LOGGER = LogManager.getLogger()
|
private val LOGGER = LogManager.getLogger()
|
||||||
|
@ -34,9 +34,9 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery
|
|||||||
level?.lightEngine?.checkBlock(blockPos)
|
level?.lightEngine?.checkBlock(blockPos)
|
||||||
})
|
})
|
||||||
|
|
||||||
val fillInput = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
|
val fillInput = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer)
|
||||||
val drainInput = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
|
val drainInput = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer)
|
||||||
val output = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
|
val output = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer)
|
||||||
|
|
||||||
val itemConfig = ConfigurableItemHandler(
|
val itemConfig = ConfigurableItemHandler(
|
||||||
input = CombinedItemHandler(
|
input = CombinedItemHandler(
|
||||||
@ -75,7 +75,7 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery
|
|||||||
|
|
||||||
private fun onChanged(new: FluidStack, old: FluidStack) {
|
private fun onChanged(new: FluidStack, old: FluidStack) {
|
||||||
synchronizedFluid = new.copy()
|
synchronizedFluid = new.copy()
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drainItem() {
|
private fun drainItem() {
|
||||||
|
@ -26,7 +26,7 @@ class PainterBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDe
|
|||||||
return PainterMenu(containerID, inventory, this)
|
return PainterMenu(containerID, inventory, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
val dyeInput = MatteryContainer(this::setChangedLight, 1)
|
val dyeInput = MatteryContainer(this::markDirtyFast, 1)
|
||||||
private val dyeStored = EnumMap<DyeColor, Int>(DyeColor::class.java)
|
private val dyeStored = EnumMap<DyeColor, Int>(DyeColor::class.java)
|
||||||
val dyeStoredView: Map<DyeColor, Int> = Collections.unmodifiableMap(dyeStored)
|
val dyeStoredView: Map<DyeColor, Int> = Collections.unmodifiableMap(dyeStored)
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ class PainterBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
|
|
||||||
val config = ConfigurableItemHandler(input = dyeInput.handler(object : HandlerFilter {
|
val config = ConfigurableItemHandler(input = dyeInput.handler(object : HandlerFilter {
|
||||||
|
@ -31,7 +31,7 @@ import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode
|
|||||||
class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
||||||
MatteryPoweredBlockEntity(MBlockEntities.MATTER_BOTTLER, blockPos, blockState) {
|
MatteryPoweredBlockEntity(MBlockEntities.MATTER_BOTTLER, blockPos, blockState) {
|
||||||
|
|
||||||
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::setChangedLight, MachinesConfig.MatterBottler.VALUES))
|
override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::markDirtyFast, MachinesConfig.MatterBottler.VALUES))
|
||||||
val energyConfig = ConfigurableEnergy(energy)
|
val energyConfig = ConfigurableEnergy(energy)
|
||||||
|
|
||||||
private inner class Container : MatteryContainer(3) {
|
private inner class Container : MatteryContainer(3) {
|
||||||
@ -44,7 +44,7 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
updateBlockState()
|
updateBlockState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
|||||||
field = value
|
field = value
|
||||||
initialCapacity = null
|
initialCapacity = null
|
||||||
workProgress = 0f
|
workProgress = 0f
|
||||||
this.setChangedLight()
|
this.markDirtyFast()
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
inputHandler.parent = bottlingHandler
|
inputHandler.parent = bottlingHandler
|
||||||
@ -73,7 +73,7 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
|||||||
var spitItemsWhenCantWork = false
|
var spitItemsWhenCantWork = false
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
this.setChangedLight()
|
this.markDirtyFast()
|
||||||
}
|
}
|
||||||
|
|
||||||
val bottlingHandler = bottling.handler(object : HandlerFilter {
|
val bottlingHandler = bottling.handler(object : HandlerFilter {
|
||||||
@ -97,7 +97,7 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
|||||||
battery = batteryItemHandler
|
battery = batteryItemHandler
|
||||||
)
|
)
|
||||||
|
|
||||||
val matter: ProfiledMatterStorage<MatterStorageImpl> = ProfiledMatterStorage(object : MatterStorageImpl(this::setChangedLight, FlowDirection.BI_DIRECTIONAL, MachinesConfig.MatterBottler.VALUES::matterCapacity) {
|
val matter: ProfiledMatterStorage<MatterStorageImpl> = ProfiledMatterStorage(object : MatterStorageImpl(this::markDirtyFast, FlowDirection.BI_DIRECTIONAL, MachinesConfig.MatterBottler.VALUES::matterCapacity) {
|
||||||
override val matterFlow: FlowDirection get() {
|
override val matterFlow: FlowDirection get() {
|
||||||
return if (this@MatterBottlerBlockEntity.isBottling) FlowDirection.INPUT else FlowDirection.OUTPUT
|
return if (this@MatterBottlerBlockEntity.isBottling) FlowDirection.INPUT else FlowDirection.OUTPUT
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
|
|||||||
override val matterFlow: FlowDirection
|
override val matterFlow: FlowDirection
|
||||||
get() = FlowDirection.BI_DIRECTIONAL
|
get() = FlowDirection.BI_DIRECTIONAL
|
||||||
|
|
||||||
val container = object : MatteryContainer(this::setChangedLight, BatteryBankBlockEntity.CAPACITY) {
|
val container = object : MatteryContainer(this::markDirtyFast, BatteryBankBlockEntity.CAPACITY) {
|
||||||
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
||||||
super.setChanged(slot, new, old)
|
super.setChanged(slot, new, old)
|
||||||
capacitorStatus[slot].boolean = new.getCapability(MatteryCapability.MATTER).isPresent
|
capacitorStatus[slot].boolean = new.getCapability(MatteryCapability.MATTER).isPresent
|
||||||
|
@ -54,15 +54,15 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val upgrades = UpgradeContainer(this::setChangedLight, 4, UpgradeType.REPLICATOR)
|
override val upgrades = UpgradeContainer(this::markDirtyFast, 4, UpgradeType.REPLICATOR)
|
||||||
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::setChangedLight, upgrades.transform(MachinesConfig.MATTER_DECOMPOSER)))
|
override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::markDirtyFast, upgrades.transform(MachinesConfig.MATTER_DECOMPOSER)))
|
||||||
val energyConfig = ConfigurableEnergy(energy)
|
val energyConfig = ConfigurableEnergy(energy)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
savetables.stateful(::energy, ENERGY_KEY)
|
savetables.stateful(::energy, ENERGY_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
val matter = ProfiledMatterStorage(MatterStorageImpl(::setChangedLight, FlowDirection.OUTPUT, upgrades.matterCapacity(MachinesConfig.MATTER_DECOMPOSER::matterCapacity)))
|
val matter = ProfiledMatterStorage(MatterStorageImpl(::markDirtyFast, FlowDirection.OUTPUT, upgrades.matterCapacity(MachinesConfig.MATTER_DECOMPOSER::matterCapacity)))
|
||||||
val matterNode = SimpleMatterNode(matter = matter)
|
val matterNode = SimpleMatterNode(matter = matter)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -72,8 +72,8 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// вход, выход
|
// вход, выход
|
||||||
val inputContainer = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
|
val inputContainer = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer)
|
||||||
val outputContainer = MatteryContainer(::setChangedLight, 2).also(::addDroppableContainer)
|
val outputContainer = MatteryContainer(::markDirtyFast, 2).also(::addDroppableContainer)
|
||||||
|
|
||||||
val itemConfig = ConfigurableItemHandler(
|
val itemConfig = ConfigurableItemHandler(
|
||||||
input = inputContainer.handler(object : HandlerFilter {
|
input = inputContainer.handler(object : HandlerFilter {
|
||||||
|
@ -52,9 +52,9 @@ class MatterReconstructorBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
var isUnableToProcess = false
|
var isUnableToProcess = false
|
||||||
private set
|
private set
|
||||||
|
|
||||||
val upgrades = UpgradeContainer(this::setChangedLight, 3, UpgradeType.REPLICATOR)
|
val upgrades = UpgradeContainer(this::markDirtyFast, 3, UpgradeType.REPLICATOR)
|
||||||
val matter = ProfiledMatterStorage(MatterStorageImpl(::setChangedLight, FlowDirection.INPUT, upgrades.matterCapacity(MachinesConfig.MatterReconstructor.VALUES::matterCapacity)))
|
val matter = ProfiledMatterStorage(MatterStorageImpl(::markDirtyFast, FlowDirection.INPUT, upgrades.matterCapacity(MachinesConfig.MatterReconstructor.VALUES::matterCapacity)))
|
||||||
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::setChangedLight, upgrades.transform(MachinesConfig.MatterReconstructor.VALUES)))
|
override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::markDirtyFast, upgrades.transform(MachinesConfig.MatterReconstructor.VALUES)))
|
||||||
|
|
||||||
val matterNode = object : MatterNode() {
|
val matterNode = object : MatterNode() {
|
||||||
override fun getMatterHandler(): IMatterStorage {
|
override fun getMatterHandler(): IMatterStorage {
|
||||||
|
@ -48,7 +48,7 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
val container = MatteryContainer(::itemContainerUpdated, 1).also(::addDroppableContainer)
|
val container = MatteryContainer(::itemContainerUpdated, 1).also(::addDroppableContainer)
|
||||||
|
|
||||||
val matterNode = SimpleMatterNode(matter = matter)
|
val matterNode = SimpleMatterNode(matter = matter)
|
||||||
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::energyLevelUpdated, MachinesConfig.MatterRecycler.VALUES))
|
override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::energyLevelUpdated, MachinesConfig.MatterRecycler.VALUES))
|
||||||
|
|
||||||
val itemConfig = ConfigurableItemHandler(input = container.handler(object : HandlerFilter {
|
val itemConfig = ConfigurableItemHandler(input = container.handler(object : HandlerFilter {
|
||||||
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||||
|
@ -65,8 +65,8 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val upgrades = UpgradeContainer(this::setChangedLight, 3, UpgradeType.REPLICATOR)
|
override val upgrades = UpgradeContainer(this::markDirtyFast, 3, UpgradeType.REPLICATOR)
|
||||||
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::energyLevelUpdated, upgrades.transform(MachinesConfig.MATTER_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 matter = ProfiledMatterStorage(MatterStorageImpl(::matterLevelUpdated, FlowDirection.INPUT, upgrades.matterCapacity(MachinesConfig.MATTER_REPLICATOR::matterCapacity)))
|
||||||
val outputContainer = MatteryContainer(::itemContainerUpdated, 3).also(::addDroppableContainer)
|
val outputContainer = MatteryContainer(::itemContainerUpdated, 3).also(::addDroppableContainer)
|
||||||
val dustContainer = MatteryContainer(::itemContainerUpdated, 2).also(::addDroppableContainer)
|
val dustContainer = MatteryContainer(::itemContainerUpdated, 2).also(::addDroppableContainer)
|
||||||
|
@ -31,9 +31,9 @@ import kotlin.math.pow
|
|||||||
class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
MatteryWorkerBlockEntity<ItemJob>(MBlockEntities.MATTER_SCANNER, p_155229_, p_155230_, ItemJob.CODEC) {
|
MatteryWorkerBlockEntity<ItemJob>(MBlockEntities.MATTER_SCANNER, p_155229_, p_155230_, ItemJob.CODEC) {
|
||||||
|
|
||||||
override val upgrades = UpgradeContainer(this::setChangedLight, 2, UpgradeType.BASIC)
|
override val upgrades = UpgradeContainer(this::markDirtyFast, 2, UpgradeType.BASIC)
|
||||||
val container = MatteryContainer(::itemContainerUpdated, 1).also(::addDroppableContainer)
|
val container = MatteryContainer(::itemContainerUpdated, 1).also(::addDroppableContainer)
|
||||||
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::energyLevelUpdated, upgrades.transform(MachinesConfig.MATTER_SCANNER)))
|
override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::energyLevelUpdated, upgrades.transform(MachinesConfig.MATTER_SCANNER)))
|
||||||
|
|
||||||
val itemConfig = ConfigurableItemHandler(inputOutput = container.handler(object : HandlerFilter {
|
val itemConfig = ConfigurableItemHandler(inputOutput = container.handler(object : HandlerFilter {
|
||||||
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||||
|
@ -23,26 +23,26 @@ import ru.dbotthepony.mc.otm.storage.optics.powered
|
|||||||
import ru.dbotthepony.mc.otm.storage.optics.flow
|
import ru.dbotthepony.mc.otm.storage.optics.flow
|
||||||
|
|
||||||
class DriveRackBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.DRIVE_RACK, blockPos, blockState) {
|
class DriveRackBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.DRIVE_RACK, blockPos, blockState) {
|
||||||
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::setChangedLight, MachinesConfig.DRIVE_RACK))
|
override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::markDirtyFast, MachinesConfig.DRIVE_RACK))
|
||||||
val cell = StorageNode(energy)
|
val cell = StorageNode(energy)
|
||||||
val energyConfig = ConfigurableEnergy(energy)
|
val energyConfig = ConfigurableEnergy(energy)
|
||||||
|
|
||||||
var insertPriority = 0
|
var insertPriority = 0
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
|
|
||||||
var extractPriority = 0
|
var extractPriority = 0
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
|
|
||||||
var mode = FlowDirection.BI_DIRECTIONAL
|
var mode = FlowDirection.BI_DIRECTIONAL
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
|
|
||||||
val container: MatteryContainer = object : MatteryContainer(this::setChanged, 4) {
|
val container: MatteryContainer = object : MatteryContainer(this::setChanged, 4) {
|
||||||
|
@ -26,10 +26,10 @@ import ru.dbotthepony.mc.otm.menu.storage.DriveViewerMenu
|
|||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
class DriveViewerBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.DRIVE_VIEWER, blockPos, blockState) {
|
class DriveViewerBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.DRIVE_VIEWER, blockPos, blockState) {
|
||||||
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyUpdated, MachinesConfig.DRIVE_VIEWER))
|
override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyUpdated, MachinesConfig.DRIVE_VIEWER))
|
||||||
val energyConfig = ConfigurableEnergy(energy)
|
val energyConfig = ConfigurableEnergy(energy)
|
||||||
|
|
||||||
val container: MatteryContainer = object : MatteryContainer(this::setChangedLight, 1) {
|
val container: MatteryContainer = object : MatteryContainer(this::markDirtyFast, 1) {
|
||||||
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
||||||
super.setChanged(slot, new, old)
|
super.setChanged(slot, new, old)
|
||||||
|
|
||||||
@ -63,13 +63,13 @@ class DriveViewerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
|
|||||||
override var sorting: ItemStorageStackSorter = ItemStorageStackSorter.DEFAULT
|
override var sorting: ItemStorageStackSorter = ItemStorageStackSorter.DEFAULT
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
|
|
||||||
override var isAscending: Boolean = true
|
override var isAscending: Boolean = true
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ class DriveViewerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
|
|||||||
if (state != blockState) {
|
if (state != blockState) {
|
||||||
level?.setBlock(blockPos, state, Block.UPDATE_CLIENTS)
|
level?.setBlock(blockPos, state, Block.UPDATE_CLIENTS)
|
||||||
} else {
|
} else {
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,6 @@ import ru.dbotthepony.mc.otm.client.render.Widgets8
|
|||||||
import ru.dbotthepony.mc.otm.container.CombinedContainer
|
import ru.dbotthepony.mc.otm.container.CombinedContainer
|
||||||
import ru.dbotthepony.mc.otm.container.addItem
|
import ru.dbotthepony.mc.otm.container.addItem
|
||||||
import ru.dbotthepony.mc.otm.container.fullIterator
|
import ru.dbotthepony.mc.otm.container.fullIterator
|
||||||
import ru.dbotthepony.mc.otm.container.iterator
|
|
||||||
import ru.dbotthepony.mc.otm.core.collect.map
|
import ru.dbotthepony.mc.otm.core.collect.map
|
||||||
import ru.dbotthepony.mc.otm.core.collect.toList
|
import ru.dbotthepony.mc.otm.core.collect.toList
|
||||||
import ru.dbotthepony.mc.otm.core.isNotEmpty
|
import ru.dbotthepony.mc.otm.core.isNotEmpty
|
||||||
@ -173,7 +172,7 @@ class ItemMonitorPlayerSettings : INBTSerializable<CompoundTag>, IItemMonitorPla
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ItemMonitorBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.ITEM_MONITOR, blockPos, blockState), IStorageEventConsumer<ItemStorageStack> {
|
class ItemMonitorBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.ITEM_MONITOR, blockPos, blockState), IStorageEventConsumer<ItemStorageStack> {
|
||||||
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::setChangedLight, MachinesConfig.ITEM_MONITOR))
|
override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::markDirtyFast, MachinesConfig.ITEM_MONITOR))
|
||||||
val energyConfig = ConfigurableEnergy(energy)
|
val energyConfig = ConfigurableEnergy(energy)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -213,7 +212,7 @@ class ItemMonitorBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
|
|||||||
// hence we are forced to work around this by providing proxy container
|
// hence we are forced to work around this by providing proxy container
|
||||||
val craftingGrid = object : MatteryContainer(3 * 3) {
|
val craftingGrid = object : MatteryContainer(3 * 3) {
|
||||||
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
craftingGridVanilla[slot] = new
|
craftingGridVanilla[slot] = new
|
||||||
|
|
||||||
if (!inProcessOfCraft) {
|
if (!inProcessOfCraft) {
|
||||||
|
@ -52,7 +52,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
|
|||||||
return StorageBusMenu(containerID, inventory, this)
|
return StorageBusMenu(containerID, inventory, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::setChangedLight, MachinesConfig.STORAGE_INTERFACES))
|
override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::markDirtyFast, MachinesConfig.STORAGE_INTERFACES))
|
||||||
val energyConfig = ConfigurableEnergy(energy, modesFront = FlowDirection.NONE)
|
val energyConfig = ConfigurableEnergy(energy, modesFront = FlowDirection.NONE)
|
||||||
|
|
||||||
val cell: StorageNode = object : StorageNode(energy) {
|
val cell: StorageNode = object : StorageNode(energy) {
|
||||||
@ -80,19 +80,19 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
|
|||||||
var insertPriority = 0
|
var insertPriority = 0
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
|
|
||||||
var extractPriority = 0
|
var extractPriority = 0
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
|
|
||||||
var mode: FlowDirection = FlowDirection.BI_DIRECTIONAL
|
var mode: FlowDirection = FlowDirection.BI_DIRECTIONAL
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -123,7 +123,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
|
|||||||
|
|
||||||
val filter = ItemFilter(MAX_FILTERS) {
|
val filter = ItemFilter(MAX_FILTERS) {
|
||||||
component?.scan()
|
component?.scan()
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -47,7 +47,7 @@ abstract class AbstractStorageImportExport(
|
|||||||
blockState: BlockState,
|
blockState: BlockState,
|
||||||
energyValues: EnergyBalanceValues = MachinesConfig.STORAGE_INTERFACES
|
energyValues: EnergyBalanceValues = MachinesConfig.STORAGE_INTERFACES
|
||||||
) : MatteryPoweredBlockEntity(blockType, blockPos, blockState) {
|
) : MatteryPoweredBlockEntity(blockType, blockPos, blockState) {
|
||||||
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::setChangedLight, energyValues))
|
final override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::markDirtyFast, energyValues))
|
||||||
val energyConfig = ConfigurableEnergy(energy, modesFront = FlowDirection.NONE)
|
val energyConfig = ConfigurableEnergy(energy, modesFront = FlowDirection.NONE)
|
||||||
|
|
||||||
val cell: StorageNode = object : StorageNode(energy) {
|
val cell: StorageNode = object : StorageNode(energy) {
|
||||||
@ -115,7 +115,7 @@ class StorageImporterBlockEntity(
|
|||||||
blockPos: BlockPos, blockState: BlockState
|
blockPos: BlockPos, blockState: BlockState
|
||||||
) : AbstractStorageImportExport(MBlockEntities.STORAGE_IMPORTER, blockPos, blockState), IItemHandler {
|
) : AbstractStorageImportExport(MBlockEntities.STORAGE_IMPORTER, blockPos, blockState), IItemHandler {
|
||||||
override val filter = ItemFilter(MAX_FILTERS) {
|
override val filter = ItemFilter(MAX_FILTERS) {
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
|
|
||||||
private var lastSlot = 0
|
private var lastSlot = 0
|
||||||
@ -264,7 +264,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
|||||||
|
|
||||||
lastSlot = 0
|
lastSlot = 0
|
||||||
|
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
}.also { it.isWhitelist = true }
|
}.also { it.isWhitelist = true }
|
||||||
|
|
||||||
private var lastSlot = 0
|
private var lastSlot = 0
|
||||||
|
@ -22,7 +22,7 @@ class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState
|
|||||||
}
|
}
|
||||||
|
|
||||||
val cell = StorageNode()
|
val cell = StorageNode()
|
||||||
val energy = WorkerEnergyStorage(this::setChangedLight, MachinesConfig.STORAGE_POWER_SUPPLIER)
|
override val energy = WorkerEnergyStorage(this::markDirtyFast, MachinesConfig.STORAGE_POWER_SUPPLIER)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
savetable(::energy, ENERGY_KEY)
|
savetable(::energy, ENERGY_KEY)
|
||||||
|
@ -25,7 +25,7 @@ class AndroidChargerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma
|
|||||||
return AndroidChargerMenu(containerID, inventory, this)
|
return AndroidChargerMenu(containerID, inventory, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
val energyConfig = ConfigurableEnergy(ProfiledEnergyStorage(WorkerEnergyStorage(this::setChangedLight, MachinesConfig.ANDROID_CHARGER)), modesTop = FlowDirection.NONE)
|
val energyConfig = ConfigurableEnergy(ProfiledEnergyStorage(WorkerEnergyStorage(this::markDirtyFast, MachinesConfig.ANDROID_CHARGER)), modesTop = FlowDirection.NONE)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
savetables.stateful(energyConfig::energy, ENERGY_KEY)
|
savetables.stateful(energyConfig::energy, ENERGY_KEY)
|
||||||
|
@ -28,7 +28,7 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
return AndroidStationMenu(containerID, inventory, this)
|
return AndroidStationMenu(containerID, inventory, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
val energy: ProfiledEnergyStorage<WorkerEnergyStorage> = ProfiledEnergyStorage(object : WorkerEnergyStorage(::setChangedLight, MachinesConfig.AndroidStation.VALUES) {
|
override val energy: ProfiledEnergyStorage<WorkerEnergyStorage> = ProfiledEnergyStorage(object : WorkerEnergyStorage(::markDirtyFast, MachinesConfig.AndroidStation.VALUES) {
|
||||||
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||||
return super.extractEnergy(howMuch, simulate).also {
|
return super.extractEnergy(howMuch, simulate).also {
|
||||||
if (!simulate && this.batteryLevel.isZero) {
|
if (!simulate && this.batteryLevel.isZero) {
|
||||||
|
@ -88,7 +88,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!simulate && !summ.isZero) {
|
if (!simulate && !summ.isZero) {
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
gaugeLevel = batteryLevel.percentage(maxBatteryLevel)
|
gaugeLevel = batteryLevel.percentage(maxBatteryLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,15 +24,15 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryDe
|
|||||||
return ChemicalGeneratorMenu(containerID, inventory, this)
|
return ChemicalGeneratorMenu(containerID, inventory, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
val batteryContainer = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
|
val batteryContainer = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer)
|
||||||
val residueContainer = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
|
val residueContainer = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer)
|
||||||
val fuelContainer = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
|
val fuelContainer = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer)
|
||||||
|
|
||||||
val batteryItemHandler = batteryContainer.handler(HandlerFilter.Chargeable)
|
val batteryItemHandler = batteryContainer.handler(HandlerFilter.Chargeable)
|
||||||
val residueItemHandler = residueContainer.handler(HandlerFilter.OnlyOut)
|
val residueItemHandler = residueContainer.handler(HandlerFilter.OnlyOut)
|
||||||
val fuelItemHandler = fuelContainer.handler(HandlerFilter.ChemicalFuel)
|
val fuelItemHandler = fuelContainer.handler(HandlerFilter.ChemicalFuel)
|
||||||
|
|
||||||
val energy = ProfiledEnergyStorage(GeneratorEnergyStorage(::setChangedLight, MachinesConfig.ChemicalGenerator.VALUES::energyCapacity, MachinesConfig.ChemicalGenerator.VALUES::energyThroughput))
|
val energy = ProfiledEnergyStorage(GeneratorEnergyStorage(::markDirtyFast, MachinesConfig.ChemicalGenerator.VALUES::energyCapacity, MachinesConfig.ChemicalGenerator.VALUES::energyThroughput))
|
||||||
|
|
||||||
val itemConfig = ConfigurableItemHandler(
|
val itemConfig = ConfigurableItemHandler(
|
||||||
input = fuelItemHandler,
|
input = fuelItemHandler,
|
||||||
@ -55,8 +55,8 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryDe
|
|||||||
savetables.int(::workTicksTotal)
|
savetables.int(::workTicksTotal)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setChangedLight() {
|
override fun markDirtyFast() {
|
||||||
super.setChangedLight()
|
super.markDirtyFast()
|
||||||
checkFuelSlot = true
|
checkFuelSlot = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,9 +106,7 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryDe
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (energy.batteryLevel.isPositive) {
|
if (energy.batteryLevel.isPositive) {
|
||||||
val item = batteryContainer[0]
|
for (item in batteryContainer) {
|
||||||
|
|
||||||
if (!item.isEmpty) {
|
|
||||||
item.energy?.also {
|
item.energy?.also {
|
||||||
moveEnergy(energy, it, MachinesConfig.ChemicalGenerator.VALUES.energyThroughput, simulate = false)
|
moveEnergy(energy, it, MachinesConfig.ChemicalGenerator.VALUES.energyThroughput, simulate = false)
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,8 @@ import ru.dbotthepony.mc.otm.menu.tech.EnergyServoMenu
|
|||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
|
|
||||||
class EnergyServoBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.ENERGY_SERVO, blockPos, blockState) {
|
class EnergyServoBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.ENERGY_SERVO, blockPos, blockState) {
|
||||||
val discharge = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
|
val discharge = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer)
|
||||||
val charge = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
|
val charge = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer)
|
||||||
|
|
||||||
val energy: ProfiledEnergyStorage<IMatteryEnergyStorage> = ProfiledEnergyStorage(object : IMatteryEnergyStorage {
|
val energy: ProfiledEnergyStorage<IMatteryEnergyStorage> = ProfiledEnergyStorage(object : IMatteryEnergyStorage {
|
||||||
override val energyFlow: FlowDirection get() {
|
override val energyFlow: FlowDirection get() {
|
||||||
|
@ -18,11 +18,11 @@ class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma
|
|||||||
set(value) {
|
set(value) {
|
||||||
require(value >= 0L) { "Negative experience: $value" }
|
require(value >= 0L) { "Negative experience: $value" }
|
||||||
field = value
|
field = value
|
||||||
setChangedLight()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
|
|
||||||
val capsuleContainer = MatteryContainer(::setChangedLight, 1)
|
val capsuleContainer = MatteryContainer(::markDirtyFast, 1)
|
||||||
val servoContainer = MatteryContainer(::setChangedLight, 1)
|
val servoContainer = MatteryContainer(::markDirtyFast, 1)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
savetables.long(::experienceStored)
|
savetables.long(::experienceStored)
|
||||||
|
@ -21,7 +21,6 @@ import ru.dbotthepony.mc.otm.container.HandlerFilter
|
|||||||
import ru.dbotthepony.mc.otm.container.UpgradeContainer
|
import ru.dbotthepony.mc.otm.container.UpgradeContainer
|
||||||
import ru.dbotthepony.mc.otm.container.balance
|
import ru.dbotthepony.mc.otm.container.balance
|
||||||
import ru.dbotthepony.mc.otm.core.collect.filter
|
import ru.dbotthepony.mc.otm.core.collect.filter
|
||||||
import ru.dbotthepony.mc.otm.core.collect.find
|
|
||||||
import ru.dbotthepony.mc.otm.core.collect.maybe
|
import ru.dbotthepony.mc.otm.core.collect.maybe
|
||||||
import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu
|
import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu
|
||||||
import ru.dbotthepony.mc.otm.menu.tech.TwinPlatePressMenu
|
import ru.dbotthepony.mc.otm.menu.tech.TwinPlatePressMenu
|
||||||
@ -29,12 +28,12 @@ import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
|||||||
import ru.dbotthepony.mc.otm.registry.MRecipes
|
import ru.dbotthepony.mc.otm.registry.MRecipes
|
||||||
|
|
||||||
class PlatePressBlockEntity(
|
class PlatePressBlockEntity(
|
||||||
p_155229_: BlockPos,
|
blockPos: BlockPos,
|
||||||
p_155230_: BlockState,
|
blockState: BlockState,
|
||||||
val isTwin: Boolean = false,
|
val isTwin: Boolean = false,
|
||||||
) : MatteryWorkerBlockEntity<ItemJob>(if (isTwin) MBlockEntities.TWIN_PLATE_PRESS else MBlockEntities.PLATE_PRESS, p_155229_, p_155230_, ItemJob.CODEC, if (isTwin) 2 else 1) {
|
) : 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::setChangedLight, if (isTwin) 4 else 3, UpgradeType.BASIC_PROCESSING)
|
override val upgrades = UpgradeContainer(this::markDirtyFast, if (isTwin) 4 else 3, UpgradeType.BASIC_PROCESSING)
|
||||||
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyLevelUpdated, upgrades.transform(MachinesConfig.PLATE_PRESS)))
|
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 inputContainer = MatteryContainer(this::itemContainerUpdated, if (isTwin) 2 else 1).also(::addDroppableContainer)
|
||||||
val outputContainer = MatteryContainer(this::itemContainerUpdated, if (isTwin) 2 else 1).also(::addDroppableContainer)
|
val outputContainer = MatteryContainer(this::itemContainerUpdated, if (isTwin) 2 else 1).also(::addDroppableContainer)
|
||||||
|
|
||||||
|
@ -35,8 +35,8 @@ class PoweredFurnaceBlockEntity(
|
|||||||
val recipeType: RecipeType<out AbstractCookingRecipe>,
|
val recipeType: RecipeType<out AbstractCookingRecipe>,
|
||||||
val config: WorkerBalanceValues
|
val config: WorkerBalanceValues
|
||||||
) : MatteryWorkerBlockEntity<ItemJob>(type, blockPos, blockState, ItemJob.CODEC, 2) {
|
) : MatteryWorkerBlockEntity<ItemJob>(type, blockPos, blockState, ItemJob.CODEC, 2) {
|
||||||
override val upgrades = UpgradeContainer(this::setChangedLight, 2, UpgradeType.BASIC_PROCESSING)
|
override val upgrades = UpgradeContainer(this::markDirtyFast, 2, UpgradeType.BASIC_PROCESSING)
|
||||||
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyLevelUpdated, upgrades.transform(config)))
|
override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyLevelUpdated, upgrades.transform(config)))
|
||||||
|
|
||||||
val inputs = immutableList(2) { MatteryContainer(this::itemContainerUpdated, 1) }
|
val inputs = immutableList(2) { MatteryContainer(this::itemContainerUpdated, 1) }
|
||||||
val outputs = immutableList(2) { MatteryContainer(this::itemContainerUpdated, 1) }
|
val outputs = immutableList(2) { MatteryContainer(this::itemContainerUpdated, 1) }
|
||||||
|
@ -15,13 +15,18 @@ import java.util.*
|
|||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
abstract class AbstractProfiledStorage<out P>(val parent: P) : INBTSerializable<CompoundTag?> {
|
abstract class AbstractProfiledStorage<out P>(val parent: P) : INBTSerializable<CompoundTag?> {
|
||||||
init {
|
|
||||||
storages.add(WeakReference(this))
|
|
||||||
}
|
|
||||||
|
|
||||||
private val historyReceiveInternal = ArrayList<Decimal>(HISTORY_SIZE)
|
private val historyReceiveInternal = ArrayList<Decimal>(HISTORY_SIZE)
|
||||||
private val historyTransferInternal = ArrayList<Decimal>(HISTORY_SIZE)
|
private val historyTransferInternal = ArrayList<Decimal>(HISTORY_SIZE)
|
||||||
|
|
||||||
|
private var isTicking = false
|
||||||
|
|
||||||
|
private fun startTicking() {
|
||||||
|
if (!isTicking) {
|
||||||
|
isTicking = true
|
||||||
|
storages.add(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val historyReceive: List<Decimal> = Collections.unmodifiableList(historyReceiveInternal)
|
val historyReceive: List<Decimal> = Collections.unmodifiableList(historyReceiveInternal)
|
||||||
val historyTransfer: List<Decimal> = Collections.unmodifiableList(historyTransferInternal)
|
val historyTransfer: List<Decimal> = Collections.unmodifiableList(historyTransferInternal)
|
||||||
|
|
||||||
@ -47,6 +52,7 @@ abstract class AbstractProfiledStorage<out P>(val parent: P) : INBTSerializable<
|
|||||||
protected fun recordTransfer(value: Decimal, simulate: Boolean): Decimal {
|
protected fun recordTransfer(value: Decimal, simulate: Boolean): Decimal {
|
||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
thisTickTransfer += value
|
thisTickTransfer += value
|
||||||
|
if (!value.isZero) startTicking()
|
||||||
}
|
}
|
||||||
|
|
||||||
return value
|
return value
|
||||||
@ -55,19 +61,23 @@ abstract class AbstractProfiledStorage<out P>(val parent: P) : INBTSerializable<
|
|||||||
protected fun recordReceive(value: Decimal, simulate: Boolean): Decimal {
|
protected fun recordReceive(value: Decimal, simulate: Boolean): Decimal {
|
||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
thisTickReceive += value
|
thisTickReceive += value
|
||||||
|
if (!value.isZero) startTicking()
|
||||||
}
|
}
|
||||||
|
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tick() {
|
private fun tick(): Boolean {
|
||||||
tick = (tick + 1) % HISTORY_SIZE
|
tick = (tick + 1) % HISTORY_SIZE
|
||||||
|
|
||||||
historyReceiveInternal[tick] = thisTickReceive
|
historyReceiveInternal[tick] = thisTickReceive
|
||||||
historyTransferInternal[tick] = thisTickTransfer
|
historyTransferInternal[tick] = thisTickTransfer
|
||||||
|
isTicking = !thisTickReceive.isZero || !thisTickTransfer.isZero || historyReceiveInternal.any { !it.isZero } || historyTransferInternal.any { !it.isZero }
|
||||||
|
|
||||||
thisTickReceive = Decimal.ZERO
|
thisTickReceive = Decimal.ZERO
|
||||||
thisTickTransfer = Decimal.ZERO
|
thisTickTransfer = Decimal.ZERO
|
||||||
|
|
||||||
|
return isTicking
|
||||||
}
|
}
|
||||||
|
|
||||||
val savedata: INBTSerializable<CompoundTag?> = object : INBTSerializable<CompoundTag?> {
|
val savedata: INBTSerializable<CompoundTag?> = object : INBTSerializable<CompoundTag?> {
|
||||||
@ -155,7 +165,7 @@ abstract class AbstractProfiledStorage<out P>(val parent: P) : INBTSerializable<
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val HISTORY_SIZE = 20
|
const val HISTORY_SIZE = 20
|
||||||
private val storages = ObjectArrayList<WeakReference<AbstractProfiledStorage<*>>>()
|
private val storages = ObjectArrayList<AbstractProfiledStorage<*>>()
|
||||||
|
|
||||||
val HISTORY_WEIGHTERS: ImmutableList<Decimal> = ImmutableList.of(
|
val HISTORY_WEIGHTERS: ImmutableList<Decimal> = ImmutableList.of(
|
||||||
Decimal("0.313335967"),
|
Decimal("0.313335967"),
|
||||||
@ -201,7 +211,7 @@ abstract class AbstractProfiledStorage<out P>(val parent: P) : INBTSerializable<
|
|||||||
// разумеется, такое решение может несколько снизить производительность сервера,
|
// разумеется, такое решение может несколько снизить производительность сервера,
|
||||||
// но ничего страшного произойти не должно
|
// но ничего страшного произойти не должно
|
||||||
internal fun onServerPostTick() {
|
internal fun onServerPostTick() {
|
||||||
storages.forValidRefs { it.tick() }
|
storages.removeIf { !it.tick() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,14 @@ package ru.dbotthepony.mc.otm.core.util
|
|||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import java.util.concurrent.locks.ReentrantLock
|
import java.util.concurrent.locks.ReentrantLock
|
||||||
|
import java.util.function.IntSupplier
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If synchronization is not required, [CounterInvalidatedLazy] should be used instead.
|
||||||
|
*/
|
||||||
|
class AtomicallyInvalidatedLazy<V>(private val invalidator: IntSupplier, private val initializer: () -> V) : Lazy<V> {
|
||||||
|
constructor(invalidator: AtomicInteger, initializer: () -> V) : this(invalidator::get, initializer)
|
||||||
|
|
||||||
class AtomicallyInvalidatedLazy<V>(private val invalidator: AtomicInteger, private val initializer: () -> V) : Lazy<V> {
|
|
||||||
@Volatile
|
@Volatile
|
||||||
private var thisCounter = -1
|
private var thisCounter = -1
|
||||||
@Volatile
|
@Volatile
|
||||||
@ -11,10 +17,10 @@ class AtomicallyInvalidatedLazy<V>(private val invalidator: AtomicInteger, priva
|
|||||||
private val lock = ReentrantLock()
|
private val lock = ReentrantLock()
|
||||||
|
|
||||||
override val value: V get() {
|
override val value: V get() {
|
||||||
if (thisCounter != invalidator.get()) {
|
if (thisCounter != invalidator.asInt) {
|
||||||
lock.lock()
|
lock.lock()
|
||||||
this.stored = Companion
|
this.stored = Companion
|
||||||
thisCounter = invalidator.get()
|
thisCounter = invalidator.asInt
|
||||||
lock.unlock()
|
lock.unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +41,7 @@ class AtomicallyInvalidatedLazy<V>(private val invalidator: AtomicInteger, priva
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun isInitialized(): Boolean {
|
override fun isInitialized(): Boolean {
|
||||||
return stored !== Companion && thisCounter == invalidator.get()
|
return stored !== Companion && thisCounter == invalidator.asInt
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object
|
private companion object
|
||||||
|
@ -0,0 +1,80 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.core.util
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
import java.util.function.IntConsumer
|
||||||
|
import java.util.function.IntSupplier
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This lazy is not synchronized, so in event of two or more threads accessing value behavior of this implementation is undefined
|
||||||
|
*
|
||||||
|
* For synchronized use case, [AtomicallyInvalidatedLazy] should be used
|
||||||
|
*/
|
||||||
|
fun <V> countingLazy(invalidator: IntSupplier, initializer: () -> V): Lazy<V> {
|
||||||
|
if (invalidator is IntCounter) {
|
||||||
|
return SmartCounterInvalidatedLazy(invalidator, initializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
return CounterInvalidatedLazy(invalidator, initializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This lazy is not synchronized, so in event of two or more threads accessing value behavior of this implementation is undefined
|
||||||
|
*
|
||||||
|
* For synchronized use case, [AtomicallyInvalidatedLazy] should be used
|
||||||
|
*/
|
||||||
|
class CounterInvalidatedLazy<V>(private val invalidator: IntSupplier, private val initializer: () -> V) : Lazy<V> {
|
||||||
|
constructor(invalidator: AtomicInteger, initializer: () -> V) : this(invalidator::get, initializer)
|
||||||
|
|
||||||
|
private var thisCounter = -1
|
||||||
|
private var stored: Any? = Companion
|
||||||
|
|
||||||
|
override val value: V get() {
|
||||||
|
var stored = stored
|
||||||
|
|
||||||
|
if (stored !== Companion && thisCounter == invalidator.asInt)
|
||||||
|
return stored as V
|
||||||
|
|
||||||
|
stored = initializer.invoke()
|
||||||
|
this.stored = stored
|
||||||
|
this.thisCounter = invalidator.asInt
|
||||||
|
return stored
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isInitialized(): Boolean {
|
||||||
|
return stored !== Companion && thisCounter == invalidator.asInt
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This lazy is not synchronized, so in event of two or more threads accessing value behavior of this implementation is undefined
|
||||||
|
*
|
||||||
|
* For synchronized use case, [AtomicallyInvalidatedLazy] should be used
|
||||||
|
*/
|
||||||
|
class SmartCounterInvalidatedLazy<V>(invalidator: IntCounter, private val initializer: () -> V) : Lazy<V> {
|
||||||
|
init {
|
||||||
|
invalidator.addListener(IntConsumer {
|
||||||
|
stored = Companion
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private var stored: Any? = Companion
|
||||||
|
|
||||||
|
override val value: V get() {
|
||||||
|
var stored = stored
|
||||||
|
|
||||||
|
if (stored !== Companion)
|
||||||
|
return stored as V
|
||||||
|
|
||||||
|
stored = initializer.invoke()
|
||||||
|
this.stored = stored
|
||||||
|
return stored
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isInitialized(): Boolean {
|
||||||
|
return stored !== Companion
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.core.util
|
||||||
|
|
||||||
|
import ru.dbotthepony.mc.otm.core.IIntSubcripable
|
||||||
|
import ru.dbotthepony.mc.otm.core.ISubscriptable
|
||||||
|
import java.util.function.BooleanSupplier
|
||||||
|
import java.util.function.IntConsumer
|
||||||
|
import java.util.function.IntSupplier
|
||||||
|
|
||||||
|
class IntCounter : IntSupplier, IIntSubcripable {
|
||||||
|
/**
|
||||||
|
* Doesn't subscribe to counter (counter does not reference this invalidator)
|
||||||
|
*/
|
||||||
|
inner class WeakInvalidator : BooleanSupplier {
|
||||||
|
private var thisValue = value
|
||||||
|
|
||||||
|
override fun getAsBoolean(): Boolean {
|
||||||
|
if (thisValue != value) {
|
||||||
|
thisValue = value
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscribes to counter (counter references this invalidator, can be removed using [remove])
|
||||||
|
*/
|
||||||
|
inner class StrongInvalidator : BooleanSupplier, ISubscriptable.L {
|
||||||
|
private var isValid = true
|
||||||
|
private val l = listeners.addListener(IntConsumer { isValid = false })
|
||||||
|
|
||||||
|
override fun getAsBoolean(): Boolean {
|
||||||
|
val isValid = isValid
|
||||||
|
this.isValid = true
|
||||||
|
return isValid
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove() {
|
||||||
|
l.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val listeners = IIntSubcripable.Impl()
|
||||||
|
private var value = 0
|
||||||
|
|
||||||
|
fun increment() {
|
||||||
|
value++
|
||||||
|
listeners.accept(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addListener(listener: IntConsumer): ISubscriptable.L {
|
||||||
|
return listeners.addListener(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getAsInt(): Int {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,8 @@ class TickList : ITickable {
|
|||||||
private val timers = ArrayDeque<Timer>()
|
private val timers = ArrayDeque<Timer>()
|
||||||
private val namedTimers = Object2ObjectOpenHashMap<Any, Timer>(0)
|
private val namedTimers = Object2ObjectOpenHashMap<Any, Timer>(0)
|
||||||
|
|
||||||
|
private var shouldTick = false
|
||||||
|
|
||||||
var inTicker = false
|
var inTicker = false
|
||||||
private set
|
private set
|
||||||
var ticks = 0
|
var ticks = 0
|
||||||
@ -92,6 +94,8 @@ class TickList : ITickable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun <T : Any> add(value: T, regular: MutableList<T>, queue: MutableList<T>) {
|
private fun <T : Any> add(value: T, regular: MutableList<T>, queue: MutableList<T>) {
|
||||||
|
shouldTick = true
|
||||||
|
|
||||||
if (inTicker) {
|
if (inTicker) {
|
||||||
queue.add(value)
|
queue.add(value)
|
||||||
} else {
|
} else {
|
||||||
@ -148,10 +152,14 @@ class TickList : ITickable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ticks++
|
ticks++
|
||||||
|
if (!shouldTick) return
|
||||||
|
|
||||||
inTicker = true
|
inTicker = true
|
||||||
|
shouldTick = timers.isNotEmpty()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (conditional.isNotEmpty()) {
|
if (conditional.isNotEmpty()) {
|
||||||
|
shouldTick = true
|
||||||
val iterator = conditional.iterator()
|
val iterator = conditional.iterator()
|
||||||
|
|
||||||
for (ticker in iterator) {
|
for (ticker in iterator) {
|
||||||
@ -162,6 +170,8 @@ class TickList : ITickable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (once.isNotEmpty()) {
|
if (once.isNotEmpty()) {
|
||||||
|
shouldTick = true
|
||||||
|
|
||||||
for (ticker in once) {
|
for (ticker in once) {
|
||||||
ticker.tick()
|
ticker.tick()
|
||||||
}
|
}
|
||||||
@ -170,23 +180,31 @@ class TickList : ITickable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (toRemoveFromAlways.isNotEmpty()) {
|
if (toRemoveFromAlways.isNotEmpty()) {
|
||||||
|
shouldTick = true
|
||||||
|
|
||||||
for (v in toRemoveFromAlways) always.remove(v)
|
for (v in toRemoveFromAlways) always.remove(v)
|
||||||
toRemoveFromAlways.clear()
|
toRemoveFromAlways.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (always.isNotEmpty()) {
|
if (always.isNotEmpty()) {
|
||||||
|
shouldTick = true
|
||||||
|
|
||||||
for (ticker in always) {
|
for (ticker in always) {
|
||||||
ticker.tick()
|
ticker.tick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alwaysQueued.isNotEmpty()) {
|
if (alwaysQueued.isNotEmpty()) {
|
||||||
|
shouldTick = true
|
||||||
|
|
||||||
always.ensureCapacity(always.size + alwaysQueued.size)
|
always.ensureCapacity(always.size + alwaysQueued.size)
|
||||||
for (v in alwaysQueued) always.add(v) // avoid toArray()
|
for (v in alwaysQueued) always.add(v) // avoid toArray()
|
||||||
alwaysQueued.clear()
|
alwaysQueued.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conditionalQueued.isNotEmpty()) {
|
if (conditionalQueued.isNotEmpty()) {
|
||||||
|
shouldTick = true
|
||||||
|
|
||||||
for (ticker in conditionalQueued) {
|
for (ticker in conditionalQueued) {
|
||||||
conditional.addFirst(ticker)
|
conditional.addFirst(ticker)
|
||||||
}
|
}
|
||||||
@ -195,6 +213,8 @@ class TickList : ITickable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (onceQueued.isNotEmpty()) {
|
if (onceQueued.isNotEmpty()) {
|
||||||
|
shouldTick = true
|
||||||
|
|
||||||
for (ticker in onceQueued) {
|
for (ticker in onceQueued) {
|
||||||
once.addFirst(ticker)
|
once.addFirst(ticker)
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
|||||||
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
|
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
|
||||||
import net.minecraft.world.SimpleContainer
|
import net.minecraft.world.SimpleContainer
|
||||||
import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting
|
import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting
|
||||||
import ru.dbotthepony.mc.otm.capability.matteryEnergy
|
|
||||||
import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback
|
import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback
|
||||||
|
|
||||||
abstract class MatteryPoweredMenu protected constructor(
|
abstract class MatteryPoweredMenu protected constructor(
|
||||||
@ -15,7 +14,7 @@ abstract class MatteryPoweredMenu protected constructor(
|
|||||||
inventory: Inventory,
|
inventory: Inventory,
|
||||||
tile: MatteryPoweredBlockEntity? = null
|
tile: MatteryPoweredBlockEntity? = null
|
||||||
) : MatteryMenu(menuType, containerID, inventory, tile) {
|
) : MatteryMenu(menuType, containerID, inventory, tile) {
|
||||||
val energyWidget = LevelGaugeWidget(this, tile?.matteryEnergy)
|
val energyWidget = LevelGaugeWidget(this, tile?.energy)
|
||||||
val batterySlot = BatterySlot(tile?.batteryContainer ?: SimpleContainer(1), 0)
|
val batterySlot = BatterySlot(tile?.batteryContainer ?: SimpleContainer(1), 0)
|
||||||
val redstoneConfig = EnumInputWithFeedback<RedstoneSetting>(this)
|
val redstoneConfig = EnumInputWithFeedback<RedstoneSetting>(this)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user