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
|
||||
|
||||
import com.google.common.collect.ImmutableList
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.ItemStack
|
||||
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.WorkerEnergyStorage
|
||||
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.nbt.getCompoundList
|
||||
import ru.dbotthepony.mc.otm.core.nbt.map
|
||||
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].
|
||||
*/
|
||||
@ -25,32 +29,35 @@ abstract class MatteryWorkerBlockEntity<JobType : IMachineJob>(
|
||||
type: BlockEntityType<*>,
|
||||
blockPos: BlockPos,
|
||||
blockState: BlockState,
|
||||
val jobDeserializer: (tag: CompoundTag) -> JobType?
|
||||
val jobDeserializer: (tag: CompoundTag) -> JobType?,
|
||||
maxJobs: Int = 1
|
||||
) : MatteryPoweredBlockEntity(type, blockPos, blockState) {
|
||||
val jobEventLoop = object : MachineJobEventLoop<JobType>() {
|
||||
override val energy: IMatteryEnergyStorage?
|
||||
get() = matteryEnergy
|
||||
override val isBlockedByRedstone: Boolean
|
||||
get() = redstoneControl.isBlockedByRedstone
|
||||
val jobEventLoops: ImmutableList<MachineJobEventLoop<JobType>> = immutableList(maxJobs) {
|
||||
object : MachineJobEventLoop<JobType>() {
|
||||
override val energy: IMatteryEnergyStorage?
|
||||
get() = matteryEnergy
|
||||
override val isBlockedByRedstone: Boolean
|
||||
get() = redstoneControl.isBlockedByRedstone
|
||||
|
||||
override fun deserializeJob(nbt: CompoundTag): JobType? {
|
||||
return jobDeserializer.invoke(nbt)
|
||||
}
|
||||
override fun deserializeJob(nbt: CompoundTag): JobType? {
|
||||
return jobDeserializer.invoke(nbt)
|
||||
}
|
||||
|
||||
override fun onJobFinish(job: JobType): JobStatus {
|
||||
return this@MatteryWorkerBlockEntity.onJobFinish(job)
|
||||
}
|
||||
override fun onJobFinish(job: JobType): JobStatus {
|
||||
return this@MatteryWorkerBlockEntity.onJobFinish(job)
|
||||
}
|
||||
|
||||
override fun computeNextJob(): JobContainer<JobType> {
|
||||
return this@MatteryWorkerBlockEntity.computeNextJob()
|
||||
}
|
||||
override fun computeNextJob(): JobContainer<JobType> {
|
||||
return this@MatteryWorkerBlockEntity.computeNextJob()
|
||||
}
|
||||
|
||||
override fun jobUpdated(new: JobType?, old: JobType?) {
|
||||
this@MatteryWorkerBlockEntity.jobUpdated(new, old)
|
||||
}
|
||||
override fun jobUpdated(new: JobType?, old: JobType?) {
|
||||
this@MatteryWorkerBlockEntity.jobUpdated(new, old)
|
||||
}
|
||||
|
||||
override fun onWorkTick(requiredPower: Decimal, extractedPower: Decimal, ticksAdvanced: Double, job: JobType): JobStatus {
|
||||
return this@MatteryWorkerBlockEntity.onWorkTick(requiredPower, extractedPower, ticksAdvanced, job)
|
||||
override fun onWorkTick(requiredPower: Decimal, extractedPower: Decimal, ticksAdvanced: Double, job: JobType): JobStatus {
|
||||
return this@MatteryWorkerBlockEntity.onWorkTick(requiredPower, extractedPower, ticksAdvanced, job)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,53 +71,68 @@ abstract class MatteryWorkerBlockEntity<JobType : IMachineJob>(
|
||||
|
||||
override fun saveShared(nbt: CompoundTag) {
|
||||
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) {
|
||||
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() {
|
||||
super.setChanged()
|
||||
jobEventLoop.isIdling = false
|
||||
jobEventLoops.forEach { it.isIdling = false }
|
||||
}
|
||||
|
||||
override fun setChangedLight() {
|
||||
super.setChangedLight()
|
||||
jobEventLoop.isIdling = false
|
||||
jobEventLoops.forEach { it.isIdling = false }
|
||||
}
|
||||
|
||||
protected fun powerLevelUpdated() {
|
||||
super.setChangedLight()
|
||||
jobEventLoop.notify(MachineJobEventLoop.IdleReason.POWER)
|
||||
jobEventLoops.forEach { it.notify(MachineJobEventLoop.IdleReason.POWER) }
|
||||
}
|
||||
|
||||
protected fun itemContainerUpdated() {
|
||||
super.setChanged()
|
||||
jobEventLoop.notify(MachineJobEventLoop.IdleReason.ITEM)
|
||||
jobEventLoops.forEach { it.notify(MachineJobEventLoop.IdleReason.ITEM) }
|
||||
}
|
||||
|
||||
protected fun matterLevelUpdated() {
|
||||
super.setChangedLight()
|
||||
jobEventLoop.notify(MachineJobEventLoop.IdleReason.MATTER)
|
||||
jobEventLoops.forEach { it.notify(MachineJobEventLoop.IdleReason.MATTER) }
|
||||
}
|
||||
|
||||
override fun redstoneStatusUpdated(newBlocked: Boolean, oldBlocked: Boolean) {
|
||||
super.redstoneStatusUpdated(newBlocked, oldBlocked)
|
||||
jobEventLoop.isIdling = newBlocked
|
||||
jobEventLoops.forEach { it.isIdling = newBlocked }
|
||||
}
|
||||
|
||||
override fun 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) {
|
||||
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) {
|
||||
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.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)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user