Storage power supplier block
This commit is contained in:
parent
45f63d4702
commit
ba17a812e3
@ -360,6 +360,9 @@ object DataGen {
|
|||||||
tile(MBlocks.BATTERY_BANK, TileNbtCopy("container"))
|
tile(MBlocks.BATTERY_BANK, TileNbtCopy("container"))
|
||||||
tile(MBlocks.DRIVE_VIEWER, TileNbtCopy("energy"), TileNbtCopy("container"), TileNbtCopy("battery_container"))
|
tile(MBlocks.DRIVE_VIEWER, TileNbtCopy("energy"), TileNbtCopy("container"), TileNbtCopy("battery_container"))
|
||||||
|
|
||||||
|
tile(MBlocks.STORAGE_BUS, TileNbtCopy("energy"), TileNbtCopy("battery_container"))
|
||||||
|
tile(MBlocks.STORAGE_POWER_SUPPLIER, TileNbtCopy("energy"), TileNbtCopy("battery_container"), TileNbtCopy("power_supplied"))
|
||||||
|
|
||||||
tile(MBlocks.MATTER_DECOMPOSER, TileNbtCopy("container"), TileNbtCopy("matter"), *workerTags)
|
tile(MBlocks.MATTER_DECOMPOSER, TileNbtCopy("container"), TileNbtCopy("matter"), *workerTags)
|
||||||
tile(MBlocks.MATTER_REPLICATOR, TileNbtCopy("container"), TileNbtCopy("matter"), *workerTags)
|
tile(MBlocks.MATTER_REPLICATOR, TileNbtCopy("container"), TileNbtCopy("matter"), *workerTags)
|
||||||
tile(MBlocks.MATTER_RECYCLER, TileNbtCopy("container"), TileNbtCopy("matter"), *workerTags)
|
tile(MBlocks.MATTER_RECYCLER, TileNbtCopy("container"), TileNbtCopy("matter"), *workerTags)
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.block
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
import net.minecraft.world.level.block.EntityBlock
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||||
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import ru.dbotthepony.mc.otm.block.entity.StoragePowerSupplierBlockEntity
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
|
|
||||||
|
class StoragePowerSupplierBlock : RotatableMatteryBlock(), EntityBlock {
|
||||||
|
override fun newBlockEntity(p_153215_: BlockPos, p_153216_: BlockState): BlockEntity {
|
||||||
|
return StoragePowerSupplierBlockEntity(p_153215_, p_153216_)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T : BlockEntity?> getTicker(
|
||||||
|
p_153212_: Level,
|
||||||
|
p_153213_: BlockState,
|
||||||
|
p_153214_: BlockEntityType<T>
|
||||||
|
): BlockEntityTicker<T>? {
|
||||||
|
if (p_153212_.isClientSide || p_153214_ !== MBlockEntities.STORAGE_POWER_SUPPLIER)
|
||||||
|
return null
|
||||||
|
|
||||||
|
return BlockEntityTicker { _, _, _, tile -> if (tile is StoragePowerSupplierBlockEntity) tile.tick() }
|
||||||
|
}
|
||||||
|
}
|
@ -49,7 +49,7 @@ class DriveRackBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val cell = BasicStorageGraphNode()
|
val cell = BasicStorageGraphNode(energy)
|
||||||
|
|
||||||
override fun load(nbt: CompoundTag) {
|
override fun load(nbt: CompoundTag) {
|
||||||
super.load(nbt)
|
super.load(nbt)
|
||||||
@ -73,6 +73,7 @@ class DriveRackBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
fun tick() {
|
fun tick() {
|
||||||
batteryChargeLoop()
|
batteryChargeLoop()
|
||||||
|
cell.tickEnergyDemanding()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val defaultDisplayName: Component
|
override val defaultDisplayName: Component
|
||||||
|
@ -22,11 +22,12 @@ import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
|||||||
class ItemMonitorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
class ItemMonitorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
MatteryPoweredBlockEntity(MBlockEntities.ITEM_MONITOR, p_155229_, p_155230_) {
|
MatteryPoweredBlockEntity(MBlockEntities.ITEM_MONITOR, p_155229_, p_155230_) {
|
||||||
|
|
||||||
val cell = BasicStorageGraphNode()
|
|
||||||
override val energy = WorkerEnergyStorage(this)
|
override val energy = WorkerEnergyStorage(this)
|
||||||
|
val cell = BasicStorageGraphNode(energy)
|
||||||
|
|
||||||
fun tick() {
|
fun tick() {
|
||||||
batteryChargeLoop()
|
batteryChargeLoop()
|
||||||
|
cell.tickEnergyDemanding()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val defaultDisplayName: Component
|
override val defaultDisplayName: Component
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectAVLTreeMap
|
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
@ -50,7 +49,99 @@ private fun Long.clamp(): Int {
|
|||||||
return this.toInt()
|
return this.toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ItemHandlerComponent(private val parent: IItemHandler) : IStorageComponent<ItemStackWrapper> {
|
class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.STORAGE_BUS, blockPos, blockState) {
|
||||||
|
override val defaultDisplayName: Component
|
||||||
|
get() = MACHINE_NAME
|
||||||
|
|
||||||
|
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override val energy = WorkerEnergyStorage(this)
|
||||||
|
|
||||||
|
val cell = BasicStorageGraphNode(energy)
|
||||||
|
|
||||||
|
override fun setLevel(p_155231_: Level) {
|
||||||
|
super.setLevel(p_155231_)
|
||||||
|
|
||||||
|
if (p_155231_ is ServerLevel) {
|
||||||
|
StorageNetworkGraph.discoverFull(this, cell.storageNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
tickOnceServer(this::checkSurroundings)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var valid = true
|
||||||
|
|
||||||
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
|
return if (valid && cap === MatteryCapability.STORAGE_NODE) {
|
||||||
|
cell.get().cast()
|
||||||
|
} else super.getCapability(cap, side)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun invalidateCaps() {
|
||||||
|
super.invalidateCaps()
|
||||||
|
cell.invalidate()
|
||||||
|
valid = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun reviveCaps() {
|
||||||
|
super.reviveCaps()
|
||||||
|
cell.revive()
|
||||||
|
valid = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private var neighbour: LazyOptional<IItemHandler>? = null
|
||||||
|
private var component: ItemHandlerComponent? = null
|
||||||
|
|
||||||
|
fun tick() {
|
||||||
|
batteryChargeLoop()
|
||||||
|
component?.scan()
|
||||||
|
cell.tickEnergyDemanding()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setRemoved() {
|
||||||
|
super.setRemoved()
|
||||||
|
cell.destroy(level)
|
||||||
|
valid = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkSurroundings() {
|
||||||
|
if (isRemoved)
|
||||||
|
return
|
||||||
|
|
||||||
|
val front = blockPos + blockState.getValue(RotatableMatteryBlock.FACING_FULL)
|
||||||
|
val storage = level?.getBlockEntity(front)?.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)?.let { if (it.isPresent) it else null }
|
||||||
|
|
||||||
|
if (neighbour != storage) {
|
||||||
|
neighbour = storage
|
||||||
|
|
||||||
|
if (storage != null) {
|
||||||
|
val ref = WeakReference(this)
|
||||||
|
|
||||||
|
storage.addListener {
|
||||||
|
val self = ref.get() ?: return@addListener
|
||||||
|
|
||||||
|
if (self.neighbour === it && !SERVER_IS_DYING) {
|
||||||
|
self.checkSurroundings()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component?.let(cell::removeStorageComponent)
|
||||||
|
component = ItemHandlerComponent(storage.orThrow())
|
||||||
|
component!!.let(cell::addStorageComponent)
|
||||||
|
} else {
|
||||||
|
component?.let(cell::removeStorageComponent)
|
||||||
|
component = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val MACHINE_NAME = TranslatableComponent("block.${OverdriveThatMatters.MOD_ID}.${MNames.STORAGE_BUS}")
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class ItemHandlerComponent(private val parent: IItemHandler) : IStorageComponent<ItemStackWrapper> {
|
||||||
override val storageType: StorageStackType<ItemStackWrapper>
|
override val storageType: StorageStackType<ItemStackWrapper>
|
||||||
get() = OverdriveThatMatters.INSTANCE.ITEM_STORAGE()
|
get() = OverdriveThatMatters.INSTANCE.ITEM_STORAGE()
|
||||||
|
|
||||||
@ -207,13 +298,28 @@ private class ItemHandlerComponent(private val parent: IItemHandler) : IStorageC
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun insertStack(stack: ItemStackWrapper, simulate: Boolean): ItemStackWrapper {
|
override fun insertStack(stack: ItemStackWrapper, simulate: Boolean): ItemStackWrapper {
|
||||||
var leftover = stack.copy()
|
if (energy.batteryLevel.isZero)
|
||||||
|
return stack
|
||||||
|
|
||||||
|
val maxPossibleDemand = stack.count * OverdriveThatMatters.INSTANCE.ITEM_STORAGE().energyPerOperation
|
||||||
|
val maxExtractEnergy = energy.extractEnergyInner(maxPossibleDemand, true)
|
||||||
|
|
||||||
|
var leftover: ItemStackWrapper
|
||||||
|
|
||||||
|
if (maxExtractEnergy == maxPossibleDemand) {
|
||||||
|
leftover = stack.copy()
|
||||||
|
} else {
|
||||||
|
leftover = stack.copy().also {
|
||||||
|
it.count = (maxExtractEnergy / OverdriveThatMatters.INSTANCE.ITEM_STORAGE().energyPerOperation).floor()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (slot in 0 until parent.slots) {
|
for (slot in 0 until parent.slots) {
|
||||||
val oldCount = leftover.count
|
val oldCount = leftover.count
|
||||||
leftover = ItemStackWrapper(parent.insertItem(slot, leftover.stack, simulate))
|
leftover = ItemStackWrapper(parent.insertItem(slot, leftover.stack, simulate))
|
||||||
|
|
||||||
if (oldCount != leftover.count && !simulate) {
|
if (oldCount != leftover.count && !simulate) {
|
||||||
|
energy.extractEnergyInner((oldCount - leftover.count) * OverdriveThatMatters.INSTANCE.ITEM_STORAGE().energyPerOperation, false)
|
||||||
scan(slot)
|
scan(slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,11 +337,18 @@ private class ItemHandlerComponent(private val parent: IItemHandler) : IStorageC
|
|||||||
|
|
||||||
override fun extractStack(id: UUID, amount: ImpreciseFraction, simulate: Boolean): ItemStackWrapper {
|
override fun extractStack(id: UUID, amount: ImpreciseFraction, simulate: Boolean): ItemStackWrapper {
|
||||||
@Suppress("NAME_SHADOWING")
|
@Suppress("NAME_SHADOWING")
|
||||||
val amount = amount.floor()
|
var amount = amount.floor()
|
||||||
|
|
||||||
if (!amount.isPositive)
|
if (!amount.isPositive)
|
||||||
return ItemStackWrapper.EMPTY
|
return ItemStackWrapper.EMPTY
|
||||||
|
|
||||||
|
val maxPossibleDemand = amount * OverdriveThatMatters.INSTANCE.ITEM_STORAGE().energyPerOperation
|
||||||
|
val maxExtractEnergy = energy.extractEnergyInner(maxPossibleDemand, true)
|
||||||
|
|
||||||
|
if (maxPossibleDemand != maxExtractEnergy) {
|
||||||
|
amount = (maxExtractEnergy / OverdriveThatMatters.INSTANCE.ITEM_STORAGE().energyPerOperation).floor()
|
||||||
|
}
|
||||||
|
|
||||||
val intAmount = amount.toLong()
|
val intAmount = amount.toLong()
|
||||||
val tuple = index[id] ?: return ItemStackWrapper.EMPTY
|
val tuple = index[id] ?: return ItemStackWrapper.EMPTY
|
||||||
var totalExtracted = 0L
|
var totalExtracted = 0L
|
||||||
@ -255,13 +368,14 @@ private class ItemHandlerComponent(private val parent: IItemHandler) : IStorageC
|
|||||||
continue
|
continue
|
||||||
} else if (tuple.stack.sameItem(extracted)) {
|
} else if (tuple.stack.sameItem(extracted)) {
|
||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
parent.extractItem(stack.slot, stack.stack.count.coerceAtMost((intAmount - totalExtracted).clamp()), false)
|
parent.extractItem(stack.slot, extracted.count, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
totalExtracted += extracted.count
|
totalExtracted += extracted.count
|
||||||
|
|
||||||
if (extracted.count != 0 && !simulate) {
|
if (extracted.count != 0 && !simulate) {
|
||||||
scan(stack.slot)
|
scan(stack.slot)
|
||||||
|
energy.extractEnergyInner(OverdriveThatMatters.INSTANCE.ITEM_STORAGE().energyPerOperation * extracted.count, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalExtracted >= intAmount) {
|
if (totalExtracted >= intAmount) {
|
||||||
@ -290,90 +404,5 @@ private class ItemHandlerComponent(private val parent: IItemHandler) : IStorageC
|
|||||||
|
|
||||||
return listing
|
return listing
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.STORAGE_BUS, blockPos, blockState) {
|
|
||||||
override val defaultDisplayName: Component
|
|
||||||
get() = MACHINE_NAME
|
|
||||||
|
|
||||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override val energy = WorkerEnergyStorage(this)
|
|
||||||
|
|
||||||
val cell = BasicStorageGraphNode()
|
|
||||||
|
|
||||||
override fun setLevel(p_155231_: Level) {
|
|
||||||
super.setLevel(p_155231_)
|
|
||||||
|
|
||||||
if (p_155231_ is ServerLevel) {
|
|
||||||
StorageNetworkGraph.discoverFull(this, cell.storageNode)
|
|
||||||
}
|
|
||||||
|
|
||||||
tickOnceServer(this::checkSurroundings)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
|
||||||
return if (cap === MatteryCapability.STORAGE_NODE) {
|
|
||||||
cell.get().cast()
|
|
||||||
} else super.getCapability(cap, side)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun invalidateCaps() {
|
|
||||||
super.invalidateCaps()
|
|
||||||
cell.invalidate()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun reviveCaps() {
|
|
||||||
super.reviveCaps()
|
|
||||||
cell.revive()
|
|
||||||
}
|
|
||||||
|
|
||||||
private var neighbour: LazyOptional<IItemHandler>? = null
|
|
||||||
private var component: ItemHandlerComponent? = null
|
|
||||||
|
|
||||||
fun tick() {
|
|
||||||
component?.scan()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setRemoved() {
|
|
||||||
super.setRemoved()
|
|
||||||
cell.destroy(level)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun checkSurroundings() {
|
|
||||||
if (isRemoved)
|
|
||||||
return
|
|
||||||
|
|
||||||
val front = blockPos + blockState.getValue(RotatableMatteryBlock.FACING_FULL)
|
|
||||||
val storage = level?.getBlockEntity(front)?.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)?.let { if (it.isPresent) it else null }
|
|
||||||
|
|
||||||
if (neighbour != storage) {
|
|
||||||
neighbour = storage
|
|
||||||
|
|
||||||
if (storage != null) {
|
|
||||||
val ref = WeakReference(this)
|
|
||||||
|
|
||||||
storage.addListener {
|
|
||||||
val self = ref.get() ?: return@addListener
|
|
||||||
|
|
||||||
if (self.neighbour === it && !SERVER_IS_DYING) {
|
|
||||||
self.checkSurroundings()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
component?.let(cell::removeStorageComponent)
|
|
||||||
component = ItemHandlerComponent(storage.orThrow())
|
|
||||||
component!!.let(cell::addStorageComponent)
|
|
||||||
} else {
|
|
||||||
component?.let(cell::removeStorageComponent)
|
|
||||||
component = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val MACHINE_NAME = TranslatableComponent("block.${OverdriveThatMatters.MOD_ID}.${MNames.STORAGE_BUS}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,130 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.core.Direction
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import net.minecraft.network.chat.TranslatableComponent
|
||||||
|
import net.minecraft.server.level.ServerLevel
|
||||||
|
import net.minecraft.world.entity.player.Inventory
|
||||||
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
|
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||||
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
|
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
||||||
|
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MNames
|
||||||
|
import ru.dbotthepony.mc.otm.set
|
||||||
|
|
||||||
|
class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.STORAGE_POWER_SUPPLIER, blockPos, blockState) {
|
||||||
|
override val defaultDisplayName: Component
|
||||||
|
get() = MACHINE_NAME
|
||||||
|
|
||||||
|
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val cell = BasicStorageGraphNode()
|
||||||
|
|
||||||
|
var powerSupplied = ImpreciseFraction.ZERO
|
||||||
|
private set
|
||||||
|
|
||||||
|
override fun setLevel(p_155231_: Level) {
|
||||||
|
super.setLevel(p_155231_)
|
||||||
|
|
||||||
|
if (p_155231_ is ServerLevel) {
|
||||||
|
StorageNetworkGraph.discoverFull(this, cell.storageNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var valid = true
|
||||||
|
|
||||||
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
|
return if (valid && cap === MatteryCapability.STORAGE_NODE) {
|
||||||
|
cell.get().cast()
|
||||||
|
} else super.getCapability(cap, side)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun invalidateCaps() {
|
||||||
|
super.invalidateCaps()
|
||||||
|
cell.invalidate()
|
||||||
|
valid = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun reviveCaps() {
|
||||||
|
super.reviveCaps()
|
||||||
|
cell.revive()
|
||||||
|
valid = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setRemoved() {
|
||||||
|
super.setRemoved()
|
||||||
|
cell.destroy(level)
|
||||||
|
valid = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tick() {
|
||||||
|
batteryChargeLoop()
|
||||||
|
|
||||||
|
if (energy.batteryLevel.isZero)
|
||||||
|
return
|
||||||
|
|
||||||
|
val graph = cell.storageGraph ?: return
|
||||||
|
|
||||||
|
if (graph.powerDemandingNodes.isEmpty())
|
||||||
|
return
|
||||||
|
|
||||||
|
var demand = ImpreciseFraction.ZERO
|
||||||
|
var i = 0
|
||||||
|
|
||||||
|
val available = energy.batteryLevel.coerceAtMost(MAX_IO)
|
||||||
|
|
||||||
|
for (demanding in graph.powerDemandingNodes) {
|
||||||
|
val received = demanding.receiveEnergyOuter(available, true)
|
||||||
|
|
||||||
|
if (received.isPositive) {
|
||||||
|
demand += received
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (demand.isZero) {
|
||||||
|
return
|
||||||
|
} else if (demand < available) {
|
||||||
|
for (demanding in graph.powerDemandingNodes) {
|
||||||
|
powerSupplied += energy.transferInner(demanding, available, false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val forEach = available / i
|
||||||
|
|
||||||
|
for (demanding in graph.powerDemandingNodes) {
|
||||||
|
powerSupplied += energy.transferInner(demanding, forEach, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val energy = WorkerEnergyStorage(this, MAX_POWER, MAX_IO)
|
||||||
|
|
||||||
|
override fun saveAdditional(nbt: CompoundTag) {
|
||||||
|
super.saveAdditional(nbt)
|
||||||
|
nbt["power_supplied"] = powerSupplied.serializeNBT()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun load(nbt: CompoundTag) {
|
||||||
|
super.load(nbt)
|
||||||
|
nbt["power_supplied"]?.let { powerSupplied = ImpreciseFraction.deserializeNBT(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val MACHINE_NAME = TranslatableComponent("block.${OverdriveThatMatters.MOD_ID}.${MNames.STORAGE_POWER_SUPPLIER}")
|
||||||
|
private val MAX_POWER = ImpreciseFraction(100_000)
|
||||||
|
private val MAX_IO = ImpreciseFraction(320)
|
||||||
|
}
|
||||||
|
}
|
@ -179,4 +179,30 @@ interface IMatteryEnergyStorage : IEnergyStorage {
|
|||||||
override fun canReceive(): Boolean {
|
override fun canReceive(): Boolean {
|
||||||
return receiveEnergyOuter(ImpreciseFraction.ONE, true) > ImpreciseFraction.ZERO
|
return receiveEnergyOuter(ImpreciseFraction.ONE, true) > ImpreciseFraction.ZERO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun transferInner(other: IMatteryEnergyStorage, amount: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||||
|
if (!amount.isPositive)
|
||||||
|
return ImpreciseFraction.ZERO
|
||||||
|
|
||||||
|
val extracted = extractEnergyInner(amount, true)
|
||||||
|
val received = other.receiveEnergyOuter(extracted, simulate)
|
||||||
|
|
||||||
|
if (!simulate)
|
||||||
|
extractEnergyInner(received, false)
|
||||||
|
|
||||||
|
return received
|
||||||
|
}
|
||||||
|
|
||||||
|
fun transferOuter(other: IMatteryEnergyStorage, amount: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||||
|
if (!amount.isPositive)
|
||||||
|
return ImpreciseFraction.ZERO
|
||||||
|
|
||||||
|
val extracted = extractEnergyOuter(amount, true)
|
||||||
|
val received = other.receiveEnergyOuter(extracted, simulate)
|
||||||
|
|
||||||
|
if (!simulate)
|
||||||
|
extractEnergyInner(received, false)
|
||||||
|
|
||||||
|
return received
|
||||||
|
}
|
||||||
}
|
}
|
@ -2,13 +2,14 @@ package ru.dbotthepony.mc.otm.graph.storage
|
|||||||
|
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
|
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.storage.IStorage
|
import ru.dbotthepony.mc.otm.storage.IStorage
|
||||||
import ru.dbotthepony.mc.otm.storage.IStorageStack
|
import ru.dbotthepony.mc.otm.storage.IStorageStack
|
||||||
import ru.dbotthepony.mc.otm.storage.StorageStackType
|
import ru.dbotthepony.mc.otm.storage.StorageStackType
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
open class BasicStorageGraphNode : IStorageGraphNode {
|
open class BasicStorageGraphNode(private val energyDemander: IMatteryEnergyStorage? = null) : IStorageGraphNode {
|
||||||
private var resolver = LazyOptional.of<IStorageGraphNode> { this }
|
private var resolver = LazyOptional.of<IStorageGraphNode> { this }
|
||||||
private var valid = true
|
private var valid = true
|
||||||
protected val components = ArrayList<IStorage<*>>()
|
protected val components = ArrayList<IStorage<*>>()
|
||||||
@ -25,7 +26,16 @@ open class BasicStorageGraphNode : IStorageGraphNode {
|
|||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
final override val storageNode = Graph6Node<IStorageGraphNode>(this)
|
final override val storageNode = Graph6Node<IStorageGraphNode>(this)
|
||||||
|
|
||||||
|
private var demandingEnergy = false
|
||||||
|
|
||||||
override fun attachComponents(to: StorageNetworkGraph) {
|
override fun attachComponents(to: StorageNetworkGraph) {
|
||||||
|
if (energyDemander != null) {
|
||||||
|
if (!demandingEnergy && energyDemander.missingPower.isPositive) {
|
||||||
|
demandingEnergy = true
|
||||||
|
to.powerDemandingNodes.add(energyDemander)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (manualAttaching) {
|
if (manualAttaching) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -35,10 +45,27 @@ open class BasicStorageGraphNode : IStorageGraphNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun tickEnergyDemanding() {
|
||||||
|
energyDemander ?: throw IllegalStateException("No energy demander")
|
||||||
|
|
||||||
|
if (!demandingEnergy && storageGraph != null && energyDemander.missingPower.isPositive) {
|
||||||
|
demandingEnergy = true
|
||||||
|
storageGraph!!.powerDemandingNodes.add(energyDemander)
|
||||||
|
} else if (demandingEnergy && storageGraph != null && !energyDemander.missingPower.isPositive) {
|
||||||
|
demandingEnergy = false
|
||||||
|
storageGraph!!.powerDemandingNodes.remove(energyDemander)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun removeComponents(from: StorageNetworkGraph) {
|
override fun removeComponents(from: StorageNetworkGraph) {
|
||||||
for (component in components) {
|
for (component in components) {
|
||||||
from.remove(component)
|
from.remove(component)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (energyDemander != null) {
|
||||||
|
from.powerDemandingNodes.remove(energyDemander)
|
||||||
|
demandingEnergy = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unchecked_cast")
|
@Suppress("unchecked_cast")
|
||||||
|
@ -7,11 +7,13 @@ import net.minecraft.world.level.Level
|
|||||||
import net.minecraft.world.level.block.entity.BlockEntity
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
import ru.dbotthepony.mc.otm.addPreServerTicker
|
import ru.dbotthepony.mc.otm.addPreServerTicker
|
||||||
import ru.dbotthepony.mc.otm.addPreWorldTicker
|
import ru.dbotthepony.mc.otm.addPreWorldTicker
|
||||||
|
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.graph.Abstract6Graph
|
import ru.dbotthepony.mc.otm.graph.Abstract6Graph
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.orNull
|
import ru.dbotthepony.mc.otm.orNull
|
||||||
import ru.dbotthepony.mc.otm.storage.*
|
import ru.dbotthepony.mc.otm.storage.*
|
||||||
|
import java.util.LinkedList
|
||||||
|
|
||||||
class StorageNetworkGraph(private val level: Level) : Abstract6Graph<IStorageGraphNode>() {
|
class StorageNetworkGraph(private val level: Level) : Abstract6Graph<IStorageGraphNode>() {
|
||||||
private val virtualComponents = Object2ObjectArrayMap<StorageStackType<*>, VirtualComponent<*>>()
|
private val virtualComponents = Object2ObjectArrayMap<StorageStackType<*>, VirtualComponent<*>>()
|
||||||
@ -58,6 +60,8 @@ class StorageNetworkGraph(private val level: Level) : Abstract6Graph<IStorageGra
|
|||||||
node.value.removeComponents(this)
|
node.value.removeComponents(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val powerDemandingNodes = LinkedList<IMatteryEnergyStorage>()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun discoverFull(tile: BlockEntity, node: Graph6Node<IStorageGraphNode>) {
|
fun discoverFull(tile: BlockEntity, node: Graph6Node<IStorageGraphNode>) {
|
||||||
|
@ -40,6 +40,7 @@ object MBlockEntities {
|
|||||||
val MATTER_RECYCLER: BlockEntityType<*> by registry.register(MNames.MATTER_RECYCLER) { BlockEntityType.Builder.of(::MatterRecyclerBlockEntity, MBlocks.MATTER_RECYCLER).build(null) }
|
val MATTER_RECYCLER: BlockEntityType<*> by registry.register(MNames.MATTER_RECYCLER) { BlockEntityType.Builder.of(::MatterRecyclerBlockEntity, MBlocks.MATTER_RECYCLER).build(null) }
|
||||||
|
|
||||||
val STORAGE_BUS: BlockEntityType<*> by registry.register(MNames.STORAGE_BUS) { BlockEntityType.Builder.of(::StorageBusBlockEntity, MBlocks.STORAGE_BUS).build(null) }
|
val STORAGE_BUS: BlockEntityType<*> by registry.register(MNames.STORAGE_BUS) { BlockEntityType.Builder.of(::StorageBusBlockEntity, MBlocks.STORAGE_BUS).build(null) }
|
||||||
|
val STORAGE_POWER_SUPPLIER: BlockEntityType<*> by registry.register(MNames.STORAGE_POWER_SUPPLIER) { BlockEntityType.Builder.of(::StoragePowerSupplierBlockEntity, MBlocks.STORAGE_POWER_SUPPLIER).build(null) }
|
||||||
|
|
||||||
val DEBUG_EXPLOSION_SMALL: BlockEntityType<*> by registry.register(MNames.DEBUG_EXPLOSION_SMALL) { BlockEntityType.Builder.of(::BlockEntityExplosionDebugger, MBlocks.DEBUG_EXPLOSION_SMALL).build(null) }
|
val DEBUG_EXPLOSION_SMALL: BlockEntityType<*> by registry.register(MNames.DEBUG_EXPLOSION_SMALL) { BlockEntityType.Builder.of(::BlockEntityExplosionDebugger, MBlocks.DEBUG_EXPLOSION_SMALL).build(null) }
|
||||||
val DEBUG_SPHERE_POINTS: BlockEntityType<*> by registry.register(MNames.DEBUG_SPHERE_POINTS) { BlockEntityType.Builder.of(::BlockEntitySphereDebugger, MBlocks.DEBUG_SPHERE_POINTS).build(null) }
|
val DEBUG_SPHERE_POINTS: BlockEntityType<*> by registry.register(MNames.DEBUG_SPHERE_POINTS) { BlockEntityType.Builder.of(::BlockEntitySphereDebugger, MBlocks.DEBUG_SPHERE_POINTS).build(null) }
|
||||||
|
@ -57,6 +57,7 @@ object MBlocks {
|
|||||||
val DRIVE_RACK: Block by registry.register(MNames.DRIVE_RACK) { DriveRackBlock() }
|
val DRIVE_RACK: Block by registry.register(MNames.DRIVE_RACK) { DriveRackBlock() }
|
||||||
val ITEM_MONITOR: Block by registry.register(MNames.ITEM_MONITOR) { ItemMonitorBlock() }
|
val ITEM_MONITOR: Block by registry.register(MNames.ITEM_MONITOR) { ItemMonitorBlock() }
|
||||||
val STORAGE_CABLE: Block by registry.register(MNames.STORAGE_CABLE) { StorageCableBlock() }
|
val STORAGE_CABLE: Block by registry.register(MNames.STORAGE_CABLE) { StorageCableBlock() }
|
||||||
|
val STORAGE_POWER_SUPPLIER: Block by registry.register(MNames.STORAGE_POWER_SUPPLIER) { StoragePowerSupplierBlock() }
|
||||||
|
|
||||||
val DEBUG_EXPLOSION_SMALL: Block by registry.register(MNames.DEBUG_EXPLOSION_SMALL) { BlockExplosionDebugger() }
|
val DEBUG_EXPLOSION_SMALL: Block by registry.register(MNames.DEBUG_EXPLOSION_SMALL) { BlockExplosionDebugger() }
|
||||||
val DEBUG_SPHERE_POINTS: Block by registry.register(MNames.DEBUG_SPHERE_POINTS) { BlockSphereDebugger() }
|
val DEBUG_SPHERE_POINTS: Block by registry.register(MNames.DEBUG_SPHERE_POINTS) { BlockSphereDebugger() }
|
||||||
|
@ -51,6 +51,7 @@ object MItems {
|
|||||||
val DRIVE_RACK: Item by registry.register(MNames.DRIVE_RACK) { BlockItem(MBlocks.DRIVE_RACK, DEFAULT_PROPERTIES) }
|
val DRIVE_RACK: Item by registry.register(MNames.DRIVE_RACK) { BlockItem(MBlocks.DRIVE_RACK, DEFAULT_PROPERTIES) }
|
||||||
val ITEM_MONITOR: Item by registry.register(MNames.ITEM_MONITOR) { BlockItem(MBlocks.ITEM_MONITOR, DEFAULT_PROPERTIES) }
|
val ITEM_MONITOR: Item by registry.register(MNames.ITEM_MONITOR) { BlockItem(MBlocks.ITEM_MONITOR, DEFAULT_PROPERTIES) }
|
||||||
val STORAGE_CABLE: Item by registry.register(MNames.STORAGE_CABLE) { BlockItem(MBlocks.STORAGE_CABLE, DEFAULT_PROPERTIES) }
|
val STORAGE_CABLE: Item by registry.register(MNames.STORAGE_CABLE) { BlockItem(MBlocks.STORAGE_CABLE, DEFAULT_PROPERTIES) }
|
||||||
|
val STORAGE_POWER_SUPPLIER: Item by registry.register(MNames.STORAGE_POWER_SUPPLIER) { BlockItem(MBlocks.STORAGE_POWER_SUPPLIER, DEFAULT_PROPERTIES) }
|
||||||
|
|
||||||
val GRAVITATION_STABILIZER: Item by registry.register(MNames.GRAVITATION_STABILIZER) {
|
val GRAVITATION_STABILIZER: Item by registry.register(MNames.GRAVITATION_STABILIZER) {
|
||||||
object : BlockItem(MBlocks.GRAVITATION_STABILIZER, DEFAULT_PROPERTIES) {
|
object : BlockItem(MBlocks.GRAVITATION_STABILIZER, DEFAULT_PROPERTIES) {
|
||||||
|
@ -24,6 +24,7 @@ object MNames {
|
|||||||
const val MATTER_RECYCLER = "matter_recycler" // нужен рецепт
|
const val MATTER_RECYCLER = "matter_recycler" // нужен рецепт
|
||||||
|
|
||||||
const val STORAGE_CABLE = "storage_cable" // нужен рецепт
|
const val STORAGE_CABLE = "storage_cable" // нужен рецепт
|
||||||
|
const val STORAGE_POWER_SUPPLIER = "storage_power_supplier" // нужен рецепт
|
||||||
|
|
||||||
const val DEBUG_EXPLOSION_SMALL = "debug_explosion_small"
|
const val DEBUG_EXPLOSION_SMALL = "debug_explosion_small"
|
||||||
const val DEBUG_SPHERE_POINTS = "debug_sphere_points"
|
const val DEBUG_SPHERE_POINTS = "debug_sphere_points"
|
||||||
|
@ -236,6 +236,8 @@
|
|||||||
"block.overdrive_that_matters.tritanium_raw_block": "Raw Tritanium Block",
|
"block.overdrive_that_matters.tritanium_raw_block": "Raw Tritanium Block",
|
||||||
|
|
||||||
"block.overdrive_that_matters.storage_cable": "Storage Cable",
|
"block.overdrive_that_matters.storage_cable": "Storage Cable",
|
||||||
|
"block.overdrive_that_matters.storage_power_supplier": "Storage Power Supplier",
|
||||||
|
"block.overdrive_that_matters.storage_bus": "Storage Bus",
|
||||||
|
|
||||||
"item.overdrive_that_matters.pill_android": "Android Pill",
|
"item.overdrive_that_matters.pill_android": "Android Pill",
|
||||||
"item.overdrive_that_matters.pill_humane": "Humane Pill",
|
"item.overdrive_that_matters.pill_humane": "Humane Pill",
|
||||||
|
Loading…
Reference in New Issue
Block a user