Allow MatteryWorkerBlockEntity to have multiple job event loops
This commit is contained in:
parent
4e62b47f84
commit
97d3a07065
@ -1,7 +1,9 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.nbt.ListTag
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.item.TooltipFlag
|
import net.minecraft.world.item.TooltipFlag
|
||||||
@ -12,12 +14,14 @@ import net.minecraft.world.level.block.state.BlockState
|
|||||||
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.capability.matteryEnergy
|
||||||
|
import ru.dbotthepony.mc.otm.core.immutableList
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
|
import ru.dbotthepony.mc.otm.core.nbt.getCompoundList
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.map
|
import ru.dbotthepony.mc.otm.core.nbt.map
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple machine, which can work on only one job at time.
|
* Simple machine, which can work on only one job type.
|
||||||
*
|
*
|
||||||
* From technical point, this is a specialized use case of [MachineJobEventLoop].
|
* From technical point, this is a specialized use case of [MachineJobEventLoop].
|
||||||
*/
|
*/
|
||||||
@ -25,32 +29,35 @@ abstract class MatteryWorkerBlockEntity<JobType : IMachineJob>(
|
|||||||
type: BlockEntityType<*>,
|
type: BlockEntityType<*>,
|
||||||
blockPos: BlockPos,
|
blockPos: BlockPos,
|
||||||
blockState: BlockState,
|
blockState: BlockState,
|
||||||
val jobDeserializer: (tag: CompoundTag) -> JobType?
|
val jobDeserializer: (tag: CompoundTag) -> JobType?,
|
||||||
|
maxJobs: Int = 1
|
||||||
) : MatteryPoweredBlockEntity(type, blockPos, blockState) {
|
) : MatteryPoweredBlockEntity(type, blockPos, blockState) {
|
||||||
val jobEventLoop = object : MachineJobEventLoop<JobType>() {
|
val jobEventLoops: ImmutableList<MachineJobEventLoop<JobType>> = immutableList(maxJobs) {
|
||||||
override val energy: IMatteryEnergyStorage?
|
object : MachineJobEventLoop<JobType>() {
|
||||||
get() = matteryEnergy
|
override val energy: IMatteryEnergyStorage?
|
||||||
override val isBlockedByRedstone: Boolean
|
get() = matteryEnergy
|
||||||
get() = redstoneControl.isBlockedByRedstone
|
override val isBlockedByRedstone: Boolean
|
||||||
|
get() = redstoneControl.isBlockedByRedstone
|
||||||
|
|
||||||
override fun deserializeJob(nbt: CompoundTag): JobType? {
|
override fun deserializeJob(nbt: CompoundTag): JobType? {
|
||||||
return jobDeserializer.invoke(nbt)
|
return jobDeserializer.invoke(nbt)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onJobFinish(job: JobType): JobStatus {
|
override fun onJobFinish(job: JobType): JobStatus {
|
||||||
return this@MatteryWorkerBlockEntity.onJobFinish(job)
|
return this@MatteryWorkerBlockEntity.onJobFinish(job)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computeNextJob(): JobContainer<JobType> {
|
override fun computeNextJob(): JobContainer<JobType> {
|
||||||
return this@MatteryWorkerBlockEntity.computeNextJob()
|
return this@MatteryWorkerBlockEntity.computeNextJob()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun jobUpdated(new: JobType?, old: JobType?) {
|
override fun jobUpdated(new: JobType?, old: JobType?) {
|
||||||
this@MatteryWorkerBlockEntity.jobUpdated(new, old)
|
this@MatteryWorkerBlockEntity.jobUpdated(new, old)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onWorkTick(requiredPower: Decimal, extractedPower: Decimal, ticksAdvanced: Double, job: JobType): JobStatus {
|
override fun onWorkTick(requiredPower: Decimal, extractedPower: Decimal, ticksAdvanced: Double, job: JobType): JobStatus {
|
||||||
return this@MatteryWorkerBlockEntity.onWorkTick(requiredPower, extractedPower, ticksAdvanced, job)
|
return this@MatteryWorkerBlockEntity.onWorkTick(requiredPower, extractedPower, ticksAdvanced, job)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,53 +71,68 @@ abstract class MatteryWorkerBlockEntity<JobType : IMachineJob>(
|
|||||||
|
|
||||||
override fun saveShared(nbt: CompoundTag) {
|
override fun saveShared(nbt: CompoundTag) {
|
||||||
super.saveShared(nbt)
|
super.saveShared(nbt)
|
||||||
nbt["JobLoop"] = jobEventLoop.serializeNBT()
|
nbt["jobs"] = ListTag().also {
|
||||||
|
for ((i, job) in jobEventLoops.withIndex()) {
|
||||||
|
it.add(job.serializeNBT().also {
|
||||||
|
it["_id"] = i
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load(nbt: CompoundTag) {
|
override fun load(nbt: CompoundTag) {
|
||||||
super.load(nbt)
|
super.load(nbt)
|
||||||
nbt.map("JobLoop", jobEventLoop::deserializeNBT)
|
|
||||||
|
for (v in nbt.getCompoundList("jobs")) {
|
||||||
|
if ("_id" in v) {
|
||||||
|
val id = v.getInt("_id")
|
||||||
|
|
||||||
|
if (id in jobEventLoops.indices) {
|
||||||
|
jobEventLoops[id].deserializeNBT(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setChanged() {
|
override fun setChanged() {
|
||||||
super.setChanged()
|
super.setChanged()
|
||||||
jobEventLoop.isIdling = false
|
jobEventLoops.forEach { it.isIdling = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setChangedLight() {
|
override fun setChangedLight() {
|
||||||
super.setChangedLight()
|
super.setChangedLight()
|
||||||
jobEventLoop.isIdling = false
|
jobEventLoops.forEach { it.isIdling = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun powerLevelUpdated() {
|
protected fun powerLevelUpdated() {
|
||||||
super.setChangedLight()
|
super.setChangedLight()
|
||||||
jobEventLoop.notify(MachineJobEventLoop.IdleReason.POWER)
|
jobEventLoops.forEach { it.notify(MachineJobEventLoop.IdleReason.POWER) }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun itemContainerUpdated() {
|
protected fun itemContainerUpdated() {
|
||||||
super.setChanged()
|
super.setChanged()
|
||||||
jobEventLoop.notify(MachineJobEventLoop.IdleReason.ITEM)
|
jobEventLoops.forEach { it.notify(MachineJobEventLoop.IdleReason.ITEM) }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun matterLevelUpdated() {
|
protected fun matterLevelUpdated() {
|
||||||
super.setChangedLight()
|
super.setChangedLight()
|
||||||
jobEventLoop.notify(MachineJobEventLoop.IdleReason.MATTER)
|
jobEventLoops.forEach { it.notify(MachineJobEventLoop.IdleReason.MATTER) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun redstoneStatusUpdated(newBlocked: Boolean, oldBlocked: Boolean) {
|
override fun redstoneStatusUpdated(newBlocked: Boolean, oldBlocked: Boolean) {
|
||||||
super.redstoneStatusUpdated(newBlocked, oldBlocked)
|
super.redstoneStatusUpdated(newBlocked, oldBlocked)
|
||||||
jobEventLoop.isIdling = newBlocked
|
jobEventLoops.forEach { it.isIdling = newBlocked }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
super.tick()
|
super.tick()
|
||||||
jobEventLoop.think()
|
jobEventLoops.forEach { it.think() }
|
||||||
|
|
||||||
if (jobEventLoop.errorTicksAnim > 20 && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.ERROR) {
|
if (jobEventLoops.any { it.workingTicksAnim > 20 } && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.WORKING) {
|
||||||
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.ERROR), Block.UPDATE_CLIENTS)
|
|
||||||
} else if (jobEventLoop.workingTicksAnim > 20 && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.WORKING) {
|
|
||||||
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 (jobEventLoop.idleTicksAnim > 20 && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.IDLE) {
|
} else if (jobEventLoops.any { it.errorTicksAnim > 20 } && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.ERROR) {
|
||||||
|
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) {
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user