New graph implementation
This commit is contained in:
parent
ebc41b808a
commit
5f16804feb
@ -11,8 +11,8 @@ import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage;
|
|||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterStorage;
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterStorage;
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IReplicationTaskProvider;
|
import ru.dbotthepony.mc.otm.capability.matter.IReplicationTaskProvider;
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage;
|
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage;
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode;
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNode;
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.IStorageGraphNode;
|
import ru.dbotthepony.mc.otm.graph.storage.StorageNode;
|
||||||
import top.theillusivec4.curios.api.type.capability.ICurio;
|
import top.theillusivec4.curios.api.type.capability.ICurio;
|
||||||
import top.theillusivec4.curios.api.type.capability.ICuriosItemHandler;
|
import top.theillusivec4.curios.api.type.capability.ICuriosItemHandler;
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ public class MatteryCapability {
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final Capability<IMatterGraphNode> MATTER_NODE = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<MatterNode> MATTER_NODE = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@NotNull
|
@NotNull
|
||||||
@ -49,7 +49,7 @@ public class MatteryCapability {
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final Capability<IStorageGraphNode> STORAGE_NODE = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<StorageNode> STORAGE_NODE = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@NotNull
|
@NotNull
|
||||||
@ -67,10 +67,10 @@ public class MatteryCapability {
|
|||||||
event.register(IMatteryEnergyStorage.class);
|
event.register(IMatteryEnergyStorage.class);
|
||||||
event.register(MatteryPlayerCapability.class);
|
event.register(MatteryPlayerCapability.class);
|
||||||
event.register(IMatterStorage.class);
|
event.register(IMatterStorage.class);
|
||||||
event.register(IMatterGraphNode.class);
|
event.register(MatterNode.class);
|
||||||
event.register(IPatternStorage.class);
|
event.register(IPatternStorage.class);
|
||||||
event.register(IReplicationTaskProvider.class);
|
event.register(IReplicationTaskProvider.class);
|
||||||
event.register(IMatteryDrive.class);
|
event.register(IMatteryDrive.class);
|
||||||
event.register(IStorageGraphNode.class);
|
event.register(StorageNode.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import ru.dbotthepony.mc.otm.client.minecraft
|
|||||||
import ru.dbotthepony.mc.otm.core.util.IConditionalTickable
|
import ru.dbotthepony.mc.otm.core.util.IConditionalTickable
|
||||||
import ru.dbotthepony.mc.otm.core.util.ITickable
|
import ru.dbotthepony.mc.otm.core.util.ITickable
|
||||||
import ru.dbotthepony.mc.otm.core.util.TickList
|
import ru.dbotthepony.mc.otm.core.util.TickList
|
||||||
|
import ru.dbotthepony.mc.otm.graph.Abstract6Graph
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
private val preServerTick = TickList()
|
private val preServerTick = TickList()
|
||||||
@ -145,6 +146,8 @@ fun onServerTick(event: ServerTickEvent) {
|
|||||||
preServerTick.tick()
|
preServerTick.tick()
|
||||||
} else {
|
} else {
|
||||||
postServerTick.tick()
|
postServerTick.tick()
|
||||||
|
// чтоб не плодить кучу подписчиков, вызовем напрямую отсюда
|
||||||
|
Abstract6Graph.tick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,135 +2,81 @@ package ru.dbotthepony.mc.otm.block.entity
|
|||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.Block
|
import net.minecraft.world.level.block.Block
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity
|
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
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.SERVER_IS_LIVE
|
import ru.dbotthepony.mc.otm.SERVER_IS_LIVE
|
||||||
import ru.dbotthepony.mc.otm.block.CableBlock
|
import ru.dbotthepony.mc.otm.block.CableBlock
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNode
|
||||||
import ru.dbotthepony.mc.otm.graph.GraphNodeListener
|
import ru.dbotthepony.mc.otm.graph.storage.StorageGraph
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
import ru.dbotthepony.mc.otm.graph.storage.StorageNode
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.IStorageGraphNode
|
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
|
|
||||||
class MatterCableBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
class MatterCableBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryBlockEntity(MBlockEntities.MATTER_CABLE, p_155229_, p_155230_) {
|
||||||
BlockEntity(MBlockEntities.MATTER_CABLE, p_155229_, p_155230_), IMatterGraphNode, GraphNodeListener {
|
val matterNode = object : MatterNode() {
|
||||||
|
override fun onNeighbour(direction: Direction) {
|
||||||
private var valid = true
|
|
||||||
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
|
||||||
private val resolverNode = LazyOptional.of { this }
|
|
||||||
|
|
||||||
override fun invalidateCaps() {
|
|
||||||
super.invalidateCaps()
|
|
||||||
valid = false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun reviveCaps() {
|
|
||||||
super.reviveCaps()
|
|
||||||
valid = true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
|
||||||
if (valid) {
|
|
||||||
if (cap === MatteryCapability.MATTER_NODE)
|
|
||||||
return resolverNode.cast()
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.getCapability(cap, side)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setLevel(p_155231_: Level) {
|
|
||||||
super.setLevel(p_155231_)
|
|
||||||
|
|
||||||
if (p_155231_ is ServerLevel)
|
|
||||||
MatterNetworkGraph.discoverFull(this, matterNode)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onNeighbour(node: Graph6Node<*>, direction: Direction) {
|
|
||||||
val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, true)
|
val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, true)
|
||||||
|
|
||||||
if (newState !== blockState && SERVER_IS_LIVE)
|
if (newState !== blockState && SERVER_IS_LIVE)
|
||||||
level?.setBlock(blockPos, newState, Block.UPDATE_CLIENTS)
|
level?.setBlock(blockPos, newState, Block.UPDATE_CLIENTS)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUnNeighbour(node: Graph6Node<*>, direction: Direction) {
|
override fun onUnNeighbour(direction: Direction) {
|
||||||
val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, false)
|
val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, false)
|
||||||
|
|
||||||
if (newState !== blockState && SERVER_IS_LIVE)
|
if (newState !== blockState && SERVER_IS_LIVE)
|
||||||
level?.setBlock(blockPos, newState, Block.UPDATE_CLIENTS)
|
level?.setBlock(blockPos, newState, Block.UPDATE_CLIENTS)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
exposeGlobally(MatteryCapability.MATTER_NODE, matterNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setLevel(level: Level) {
|
||||||
|
super.setLevel(level)
|
||||||
|
matterNode.discover(this)
|
||||||
|
}
|
||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
matterNode.destroy(::MatterNetworkGraph)
|
matterNode.isValid = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StorageCableBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
class StorageCableBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryBlockEntity(MBlockEntities.STORAGE_CABLE, p_155229_, p_155230_) {
|
||||||
BlockEntity(MBlockEntities.STORAGE_CABLE, p_155229_, p_155230_), IStorageGraphNode, GraphNodeListener {
|
val storageNode = object : StorageNode() {
|
||||||
|
override fun attachComponents(to: StorageGraph) {}
|
||||||
|
override fun removeComponents(from: StorageGraph) {}
|
||||||
|
|
||||||
private var valid = true
|
override fun onNeighbour(direction: Direction) {
|
||||||
private val resolverNode = LazyOptional.of { this }
|
|
||||||
|
|
||||||
override fun attachComponents(to: StorageNetworkGraph) {}
|
|
||||||
override fun removeComponents(from: StorageNetworkGraph) {}
|
|
||||||
override val storageNode = Graph6Node<IStorageGraphNode>(this)
|
|
||||||
|
|
||||||
override fun invalidateCaps() {
|
|
||||||
super.invalidateCaps()
|
|
||||||
valid = false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun reviveCaps() {
|
|
||||||
super.reviveCaps()
|
|
||||||
valid = true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
|
||||||
if (valid) {
|
|
||||||
if (cap === MatteryCapability.STORAGE_NODE)
|
|
||||||
return resolverNode.cast()
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.getCapability(cap, side)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setLevel(p_155231_: Level) {
|
|
||||||
super.setLevel(p_155231_)
|
|
||||||
|
|
||||||
if (p_155231_ is ServerLevel)
|
|
||||||
StorageNetworkGraph.discoverFull(this, storageNode)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onNeighbour(node: Graph6Node<*>, direction: Direction) {
|
|
||||||
val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, true)
|
val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, true)
|
||||||
|
|
||||||
if (newState !== blockState && SERVER_IS_LIVE)
|
if (newState !== blockState && SERVER_IS_LIVE)
|
||||||
level!!.setBlock(blockPos, newState, Block.UPDATE_CLIENTS)
|
level!!.setBlock(blockPos, newState, Block.UPDATE_CLIENTS)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUnNeighbour(node: Graph6Node<*>, direction: Direction) {
|
override fun onUnNeighbour(direction: Direction) {
|
||||||
val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, false)
|
val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, false)
|
||||||
|
|
||||||
if (newState !== blockState && SERVER_IS_LIVE)
|
if (newState !== blockState && SERVER_IS_LIVE)
|
||||||
level!!.setBlock(blockPos, newState, Block.UPDATE_CLIENTS)
|
level!!.setBlock(blockPos, newState, Block.UPDATE_CLIENTS)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
exposeGlobally(MatteryCapability.STORAGE_NODE, storageNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setLevel(level: Level) {
|
||||||
|
super.setLevel(level)
|
||||||
|
storageNode.discover(this)
|
||||||
|
}
|
||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
|
storageNode.isValid = false
|
||||||
val level = level!!
|
|
||||||
|
|
||||||
storageNode.destroy {
|
|
||||||
StorageNetworkGraph(level)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.block.entity.matter
|
|||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.nbt.StringTag
|
import net.minecraft.nbt.StringTag
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
@ -29,16 +28,16 @@ import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
|
|||||||
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
||||||
import ru.dbotthepony.mc.otm.core.registryName
|
import ru.dbotthepony.mc.otm.core.registryName
|
||||||
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNode
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode
|
||||||
import ru.dbotthepony.mc.otm.matter.IMatterValue
|
import ru.dbotthepony.mc.otm.matter.IMatterValue
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterManager
|
import ru.dbotthepony.mc.otm.matter.MatterManager
|
||||||
import ru.dbotthepony.mc.otm.menu.matter.ItemRepairerMenu
|
import ru.dbotthepony.mc.otm.menu.matter.ItemRepairerMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.registry.MNames
|
import ru.dbotthepony.mc.otm.registry.MNames
|
||||||
|
|
||||||
class ItemRepairerBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.ITEM_REPAIRER, blockPos, blockState), IMatterGraphNode {
|
class ItemRepairerBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.ITEM_REPAIRER, blockPos, blockState) {
|
||||||
val repairContainer = MatteryContainer(::containerChanged, 1).also(::addDroppableContainer)
|
val repairContainer = MatteryContainer(::containerChanged, 1).also(::addDroppableContainer)
|
||||||
|
|
||||||
private var matterPerTick = Decimal.ZERO
|
private var matterPerTick = Decimal.ZERO
|
||||||
@ -48,13 +47,13 @@ class ItemRepairerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matt
|
|||||||
|
|
||||||
var canNotWork = false
|
var canNotWork = false
|
||||||
|
|
||||||
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
|
||||||
val matter = MatterStorageImpl(::setChangedLight, FlowDirection.INPUT, ::CAPACITY)
|
val matter = MatterStorageImpl(::setChangedLight, FlowDirection.INPUT, ::CAPACITY)
|
||||||
|
val matterNode = SimpleMatterNode(matter = matter)
|
||||||
val energy = WorkerEnergyStorage(::setChangedLight, ENERGY_VALUES)
|
val energy = WorkerEnergyStorage(::setChangedLight, ENERGY_VALUES)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
exposeGlobally(MatteryCapability.MATTER, matter)
|
exposeGlobally(MatteryCapability.MATTER, matter)
|
||||||
exposeGlobally(MatteryCapability.MATTER_NODE, this)
|
exposeGlobally(MatteryCapability.MATTER_NODE, matterNode)
|
||||||
|
|
||||||
savetables.stateful(::repairContainer)
|
savetables.stateful(::repairContainer)
|
||||||
savetables.stateful(::matter)
|
savetables.stateful(::matter)
|
||||||
@ -83,10 +82,10 @@ class ItemRepairerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (matterNode.graph as MatterNetworkGraph?)
|
return matterNode.graph
|
||||||
?.patterns
|
.patterns
|
||||||
?.filter { stack.item.isValidRepairItem(stack, ItemStack(it.item, 1)) }
|
.filter { stack.item.isValidRepairItem(stack, ItemStack(it.item, 1)) }
|
||||||
?.findFirst()?.orElse(null).let {
|
.findFirst().orElse(null).let {
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
IMatterValue.ZERO
|
IMatterValue.ZERO
|
||||||
} else {
|
} else {
|
||||||
@ -105,20 +104,14 @@ class ItemRepairerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matt
|
|||||||
return ItemRepairerMenu(containerID, inventory, this)
|
return ItemRepairerMenu(containerID, inventory, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMatterHandler(): IMatterStorage {
|
|
||||||
return matter
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
matterNode.destroy(::MatterNetworkGraph)
|
matterNode.isValid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setLevel(level: Level) {
|
override fun setLevel(level: Level) {
|
||||||
super.setLevel(level)
|
super.setLevel(level)
|
||||||
|
matterNode.discover(this)
|
||||||
if (level is ServerLevel)
|
|
||||||
MatterNetworkGraph.discoverFull(this, matterNode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun containerChanged() {
|
private fun containerChanged() {
|
||||||
@ -147,7 +140,7 @@ class ItemRepairerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val found = (matterNode.graph as MatterNetworkGraph?)?.patterns?.filter { item.item.isValidRepairItem(item, ItemStack(it.item, 1)) }?.findFirst()?.orElse(null)
|
val found = matterNode.graph.patterns.filter { item.item.isValidRepairItem(item, ItemStack(it.item, 1)) }.findFirst().orElse(null)
|
||||||
|
|
||||||
if (found != null) {
|
if (found != null) {
|
||||||
@Suppress("name_shadowing")
|
@Suppress("name_shadowing")
|
||||||
@ -187,7 +180,7 @@ class ItemRepairerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matt
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (matter.storedMatter < matterPerTick) {
|
if (matter.storedMatter < matterPerTick) {
|
||||||
val graph = matterNode.graph as MatterNetworkGraph?
|
val graph = matterNode.graph as MatterGraph?
|
||||||
|
|
||||||
if (graph != null) {
|
if (graph != null) {
|
||||||
val toDrain = (matterPerTick * EXTRACT_TICKS.coerceAtMost(item.damageValue)).coerceAtLeast(Decimal.ZERO).coerceAtMost(matter.missingMatter)
|
val toDrain = (matterPerTick * EXTRACT_TICKS.coerceAtMost(item.damageValue)).coerceAtLeast(Decimal.ZERO).coerceAtMost(matter.missingMatter)
|
||||||
|
@ -22,9 +22,7 @@ import ru.dbotthepony.mc.otm.capability.matter.IMatterStorage
|
|||||||
import ru.dbotthepony.mc.otm.capability.matter.MatterStorageImpl
|
import ru.dbotthepony.mc.otm.capability.matter.MatterStorageImpl
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
|
||||||
import ru.dbotthepony.mc.otm.menu.matter.MatterBottlerMenu
|
import ru.dbotthepony.mc.otm.menu.matter.MatterBottlerMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.core.*
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
@ -33,11 +31,12 @@ import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
|||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
|
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
|
||||||
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNode
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode
|
||||||
|
|
||||||
class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
MatteryPoweredBlockEntity(MBlockEntities.MATTER_BOTTLER, p_155229_, p_155230_), IMatterGraphNode {
|
MatteryPoweredBlockEntity(MBlockEntities.MATTER_BOTTLER, p_155229_, p_155230_) {
|
||||||
|
|
||||||
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
|
||||||
val energy = WorkerEnergyStorage(this, ENERGY_VALUES)
|
val energy = WorkerEnergyStorage(this, ENERGY_VALUES)
|
||||||
|
|
||||||
var isBottling: Boolean = true
|
var isBottling: Boolean = true
|
||||||
@ -110,9 +109,11 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val matterNode = SimpleMatterNode(matter = matter)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
exposeGlobally(MatteryCapability.MATTER, matter)
|
exposeGlobally(MatteryCapability.MATTER, matter)
|
||||||
exposeGlobally(MatteryCapability.MATTER_NODE, this)
|
exposeGlobally(MatteryCapability.MATTER_NODE, matterNode)
|
||||||
exposeItemsGlobally(itemHandler)
|
exposeItemsGlobally(itemHandler)
|
||||||
|
|
||||||
savetables.bool(::isBottling)
|
savetables.bool(::isBottling)
|
||||||
@ -126,15 +127,9 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
private var initialCapacity: Decimal? = null
|
private var initialCapacity: Decimal? = null
|
||||||
private var lastWorkStack: ItemStack? = null
|
private var lastWorkStack: ItemStack? = null
|
||||||
|
|
||||||
override fun getMatterHandler(): IMatterStorage {
|
|
||||||
return matter
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setLevel(level: Level) {
|
override fun setLevel(level: Level) {
|
||||||
super.setLevel(level)
|
super.setLevel(level)
|
||||||
|
matterNode.discover(this)
|
||||||
if (level is ServerLevel)
|
|
||||||
MatterNetworkGraph.discoverFull(this, matterNode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||||
@ -163,7 +158,7 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
matterNode.destroy(::MatterNetworkGraph)
|
matterNode.isValid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
@ -212,7 +207,7 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
initialCapacity = capability!!.storedMatter
|
initialCapacity = capability!!.storedMatter
|
||||||
}
|
}
|
||||||
|
|
||||||
val graph = matterNode.graph as MatterNetworkGraph?
|
val graph = matterNode.graph as MatterGraph?
|
||||||
|
|
||||||
if (capability != null) {
|
if (capability != null) {
|
||||||
if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) !== WorkerState.WORKING) {
|
if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) !== WorkerState.WORKING) {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity.matter
|
package ru.dbotthepony.mc.otm.block.entity.matter
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
@ -17,17 +16,15 @@ import ru.dbotthepony.mc.otm.container.MatteryContainer
|
|||||||
import ru.dbotthepony.mc.otm.core.immutableList
|
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.ifPresentK
|
import ru.dbotthepony.mc.otm.core.ifPresentK
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
|
||||||
import ru.dbotthepony.mc.otm.menu.matter.MatterCapacitorBankMenu
|
import ru.dbotthepony.mc.otm.menu.matter.MatterCapacitorBankMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
|
|
||||||
class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.MATTER_CAPACITOR_BANK, p_155229_, p_155230_), IMatterGraphNode, IMatterStorage {
|
class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.MATTER_CAPACITOR_BANK, p_155229_, p_155230_), IMatterStorage {
|
||||||
var gaugeLevel by synchronizer.float().property
|
var gaugeLevel by synchronizer.float().property
|
||||||
private set
|
private set
|
||||||
|
|
||||||
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
val matterNode = SimpleMatterNode(matter = this)
|
||||||
|
|
||||||
override val canSetMatterLevel: Boolean
|
override val canSetMatterLevel: Boolean
|
||||||
get() = false
|
get() = false
|
||||||
@ -137,7 +134,7 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
|
|||||||
init {
|
init {
|
||||||
savetable(::container, INVENTORY_KEY)
|
savetable(::container, INVENTORY_KEY)
|
||||||
exposeGlobally(MatteryCapability.MATTER, this)
|
exposeGlobally(MatteryCapability.MATTER, this)
|
||||||
exposeGlobally(MatteryCapability.MATTER_NODE, this)
|
exposeGlobally(MatteryCapability.MATTER_NODE, matterNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||||
@ -146,17 +143,11 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
|
|||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
matterNode.destroy(::MatterNetworkGraph)
|
matterNode.isValid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setLevel(level: Level) {
|
override fun setLevel(level: Level) {
|
||||||
super.setLevel(level)
|
super.setLevel(level)
|
||||||
|
matterNode.discover(this)
|
||||||
if (level is ServerLevel)
|
|
||||||
MatterNetworkGraph.discoverFull(this, matterNode)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getMatterHandler(): IMatterStorage {
|
|
||||||
return this
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.block.entity.matter
|
|||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
@ -10,32 +9,30 @@ import net.minecraft.world.item.ItemStack
|
|||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraftforge.common.ForgeConfigSpec
|
import net.minecraftforge.common.ForgeConfigSpec
|
||||||
import ru.dbotthepony.mc.otm.config.ConciseBalanceValues
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
|
import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterStorage
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.MatterStorageImpl
|
import ru.dbotthepony.mc.otm.capability.matter.MatterStorageImpl
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.config.ConciseBalanceValues
|
||||||
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
|
||||||
import ru.dbotthepony.mc.otm.item.MatterDustItem
|
|
||||||
import ru.dbotthepony.mc.otm.menu.matter.MatterDecomposerMenu
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MItems
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MNames
|
|
||||||
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
|
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
|
||||||
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
||||||
import ru.dbotthepony.mc.otm.core.math.getDecimal
|
import ru.dbotthepony.mc.otm.core.math.getDecimal
|
||||||
import ru.dbotthepony.mc.otm.core.math.set
|
import ru.dbotthepony.mc.otm.core.math.set
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode
|
||||||
|
import ru.dbotthepony.mc.otm.item.MatterDustItem
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterManager
|
import ru.dbotthepony.mc.otm.matter.MatterManager
|
||||||
|
import ru.dbotthepony.mc.otm.menu.matter.MatterDecomposerMenu
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MItems
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MNames
|
||||||
|
|
||||||
fun moveMatterAsDustIntoContainer(_matterValue: Decimal, container: MatteryContainer, OUTPUT_DUST_MAIN: Int, OUTPUT_DUST_STACKING: Int): Decimal {
|
fun moveMatterAsDustIntoContainer(_matterValue: Decimal, container: MatteryContainer, OUTPUT_DUST_MAIN: Int, OUTPUT_DUST_STACKING: Int): Decimal {
|
||||||
var matterValue = _matterValue
|
var matterValue = _matterValue
|
||||||
@ -91,7 +88,7 @@ fun moveMatterAsDustIntoContainer(_matterValue: Decimal, container: MatteryConta
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
|
class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
|
||||||
: MatteryWorkerBlockEntity<MatterDecomposerBlockEntity.DecomposerJob>(MBlockEntities.MATTER_DECOMPOSER, pos, state, ::DecomposerJob), IMatterGraphNode {
|
: MatteryWorkerBlockEntity<MatterDecomposerBlockEntity.DecomposerJob>(MBlockEntities.MATTER_DECOMPOSER, pos, state, ::DecomposerJob) {
|
||||||
|
|
||||||
class DecomposerJob : Job {
|
class DecomposerJob : Job {
|
||||||
val toDust: Boolean
|
val toDust: Boolean
|
||||||
@ -127,13 +124,12 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
|
|||||||
savetable(::energy, ENERGY_KEY)
|
savetable(::energy, ENERGY_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
|
||||||
|
|
||||||
val matter = MatterStorageImpl(::setChangedLight, FlowDirection.OUTPUT, ::CAPACITY)
|
val matter = MatterStorageImpl(::setChangedLight, FlowDirection.OUTPUT, ::CAPACITY)
|
||||||
|
val matterNode = SimpleMatterNode(matter = matter)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
exposeGlobally(MatteryCapability.MATTER, matter)
|
exposeGlobally(MatteryCapability.MATTER, matter)
|
||||||
exposeGlobally(MatteryCapability.MATTER_NODE, this)
|
exposeGlobally(MatteryCapability.MATTER_NODE, matterNode)
|
||||||
savetable(::matter, MATTER_STORAGE_KEY)
|
savetable(::matter, MATTER_STORAGE_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,24 +195,18 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
|
|||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
matterNode.destroy(::MatterNetworkGraph)
|
matterNode.isValid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setLevel(level: Level) {
|
override fun setLevel(level: Level) {
|
||||||
super.setLevel(level)
|
super.setLevel(level)
|
||||||
|
matterNode.discover(this)
|
||||||
if (level is ServerLevel)
|
|
||||||
MatterNetworkGraph.discoverFull(this, matterNode)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getMatterHandler(): IMatterStorage {
|
|
||||||
return matter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
super.tick()
|
super.tick()
|
||||||
|
|
||||||
val grid = matterNode.graph as MatterNetworkGraph? ?: return
|
val grid = matterNode.graph as MatterGraph? ?: return
|
||||||
|
|
||||||
if (!matter.storedMatter.isZero) {
|
if (!matter.storedMatter.isZero) {
|
||||||
val diff = matter.extractMatterInner(matter.storedMatter, true)
|
val diff = matter.extractMatterInner(matter.storedMatter, true)
|
||||||
|
@ -25,14 +25,15 @@ import ru.dbotthepony.mc.otm.core.nbt.mapString
|
|||||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||||
import ru.dbotthepony.mc.otm.core.util.ItemSorter
|
import ru.dbotthepony.mc.otm.core.util.ItemSorter
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNode
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
|
|
||||||
class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
MatteryDeviceBlockEntity(MBlockEntities.MATTER_PANEL, p_155229_, p_155230_), IMatterGraphNode, IReplicationTaskProvider {
|
MatteryDeviceBlockEntity(MBlockEntities.MATTER_PANEL, p_155229_, p_155230_), IReplicationTaskProvider {
|
||||||
|
|
||||||
class PlayerSettings(var sorter: ItemSorter = ItemSorter.DEFAULT, var ascending: Boolean = true) : INBTSerializable<CompoundTag> {
|
class PlayerSettings(var sorter: ItemSorter = ItemSorter.DEFAULT, var ascending: Boolean = true) : INBTSerializable<CompoundTag> {
|
||||||
override fun serializeNBT(): CompoundTag {
|
override fun serializeNBT(): CompoundTag {
|
||||||
@ -55,7 +56,7 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val listeners = ArrayList<MatterPanelMenu>()
|
private val listeners = ArrayList<MatterPanelMenu>()
|
||||||
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
val matterNode = SimpleMatterNode(tasks = this)
|
||||||
|
|
||||||
fun attachMenu(menu: MatterPanelMenu) {
|
fun attachMenu(menu: MatterPanelMenu) {
|
||||||
listeners.add(menu)
|
listeners.add(menu)
|
||||||
@ -70,24 +71,18 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
exposeGlobally(MatteryCapability.MATTER_NODE, this)
|
exposeGlobally(MatteryCapability.MATTER_NODE, matterNode)
|
||||||
exposeGlobally(MatteryCapability.TASK, this)
|
exposeGlobally(MatteryCapability.TASK, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setLevel(level: Level) {
|
override fun setLevel(level: Level) {
|
||||||
super.setLevel(level)
|
super.setLevel(level)
|
||||||
|
matterNode.discover(this)
|
||||||
if (level is ServerLevel)
|
|
||||||
MatterNetworkGraph.discoverFull(this, matterNode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
matterNode.destroy(::MatterNetworkGraph)
|
matterNode.isValid = false
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTaskHandler(): IReplicationTaskProvider {
|
|
||||||
return this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val _tasks = HashMap<UUID, ReplicationTask>()
|
private val _tasks = HashMap<UUID, ReplicationTask>()
|
||||||
@ -101,7 +96,7 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun allocateTask(simulate: Boolean): ReplicationTaskAllocation? {
|
override fun allocateTask(simulate: Boolean): ReplicationTaskAllocation? {
|
||||||
val graph = matterNode.graph as MatterNetworkGraph? ?: return null
|
val graph = matterNode.graph as MatterGraph? ?: return null
|
||||||
|
|
||||||
for ((key, task) in _tasks) {
|
for ((key, task) in _tasks) {
|
||||||
if (task.required > 0) {
|
if (task.required > 0) {
|
||||||
@ -127,7 +122,7 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
val oldTask = localTask
|
val oldTask = localTask
|
||||||
|
|
||||||
localTask = localTask.finish()
|
localTask = localTask.finish()
|
||||||
val graph = matterNode.graph as MatterNetworkGraph?
|
val graph = matterNode.graph as MatterGraph?
|
||||||
|
|
||||||
// Задача полностью выполнена
|
// Задача полностью выполнена
|
||||||
if (localTask.required <= 0 && localTask.inProgress <= 0) {
|
if (localTask.required <= 0 && localTask.inProgress <= 0) {
|
||||||
@ -196,7 +191,7 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
val task = _tasks[id] ?: return
|
val task = _tasks[id] ?: return
|
||||||
_tasks.remove(id)
|
_tasks.remove(id)
|
||||||
|
|
||||||
(matterNode.graph as MatterNetworkGraph?)?.onMatterTaskRemoved(task)
|
(matterNode.graph as MatterGraph?)?.onMatterTaskRemoved(task)
|
||||||
|
|
||||||
listeners.forEach { it.taskRemoved(task) }
|
listeners.forEach { it.taskRemoved(task) }
|
||||||
setChanged()
|
setChanged()
|
||||||
@ -206,7 +201,7 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
val task = ReplicationTask(UUID.randomUUID(), state.id, state.item, 0, 0, count)
|
val task = ReplicationTask(UUID.randomUUID(), state.id, state.item, 0, 0, count)
|
||||||
_tasks[task.id] = task
|
_tasks[task.id] = task
|
||||||
|
|
||||||
(matterNode.graph as MatterNetworkGraph?)?.onMatterTaskCreated(task)
|
(matterNode.graph as MatterGraph?)?.onMatterTaskCreated(task)
|
||||||
|
|
||||||
listeners.forEach { it.taskUpdated(task) }
|
listeners.forEach { it.taskUpdated(task) }
|
||||||
setChanged()
|
setChanged()
|
||||||
@ -215,7 +210,7 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun dropAllTasks() {
|
override fun dropAllTasks() {
|
||||||
val graph = matterNode.graph as MatterNetworkGraph?
|
val graph = matterNode.graph as MatterGraph?
|
||||||
|
|
||||||
for (task in _tasks.values) {
|
for (task in _tasks.values) {
|
||||||
graph?.onMatterTaskRemoved(task)
|
graph?.onMatterTaskRemoved(task)
|
||||||
|
@ -23,8 +23,7 @@ import ru.dbotthepony.mc.otm.container.MatteryContainer
|
|||||||
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
|
||||||
import ru.dbotthepony.mc.otm.item.MatterDustItem
|
import ru.dbotthepony.mc.otm.item.MatterDustItem
|
||||||
import ru.dbotthepony.mc.otm.menu.matter.MatterRecyclerMenu
|
import ru.dbotthepony.mc.otm.menu.matter.MatterRecyclerMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
@ -34,9 +33,10 @@ import ru.dbotthepony.mc.otm.registry.MNames
|
|||||||
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
||||||
import ru.dbotthepony.mc.otm.core.math.getDecimal
|
import ru.dbotthepony.mc.otm.core.math.getDecimal
|
||||||
import ru.dbotthepony.mc.otm.core.math.set
|
import ru.dbotthepony.mc.otm.core.math.set
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode
|
||||||
|
|
||||||
class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
||||||
: MatteryWorkerBlockEntity<MatterRecyclerBlockEntity.RecyclerJob>(MBlockEntities.MATTER_RECYCLER, blockPos, blockState, ::RecyclerJob), IMatterGraphNode {
|
: MatteryWorkerBlockEntity<MatterRecyclerBlockEntity.RecyclerJob>(MBlockEntities.MATTER_RECYCLER, blockPos, blockState, ::RecyclerJob) {
|
||||||
|
|
||||||
class RecyclerJob : Job {
|
class RecyclerJob : Job {
|
||||||
var totalMatter: Decimal
|
var totalMatter: Decimal
|
||||||
@ -72,13 +72,9 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
|
|
||||||
val container = MatteryContainer(this::itemContainerUpdated, 1).also(::addDroppableContainer)
|
val container = MatteryContainer(this::itemContainerUpdated, 1).also(::addDroppableContainer)
|
||||||
|
|
||||||
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
val matterNode = SimpleMatterNode(matter = matter)
|
||||||
val energy = WorkerEnergyStorage(this::powerLevelUpdated, ENERGY_CONFIG)
|
val energy = WorkerEnergyStorage(this::powerLevelUpdated, ENERGY_CONFIG)
|
||||||
|
|
||||||
override fun getMatterHandler(): IMatterStorage {
|
|
||||||
return matter
|
|
||||||
}
|
|
||||||
|
|
||||||
private val itemHandler = container.handler(object : HandlerFilter {
|
private val itemHandler = container.handler(object : HandlerFilter {
|
||||||
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||||
return stack.item is MatterDustItem
|
return stack.item is MatterDustItem
|
||||||
@ -93,7 +89,7 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
exposeItemsGlobally(itemHandler)
|
exposeItemsGlobally(itemHandler)
|
||||||
exposeEnergyGlobally(energy)
|
exposeEnergyGlobally(energy)
|
||||||
exposeGlobally(MatteryCapability.MATTER, matter)
|
exposeGlobally(MatteryCapability.MATTER, matter)
|
||||||
exposeGlobally(MatteryCapability.MATTER_NODE, this)
|
exposeGlobally(MatteryCapability.MATTER_NODE, matterNode)
|
||||||
savetable(::energy, ENERGY_KEY)
|
savetable(::energy, ENERGY_KEY)
|
||||||
savetable(::container, INVENTORY_KEY)
|
savetable(::container, INVENTORY_KEY)
|
||||||
savetable(::matter, MATTER_STORAGE_KEY)
|
savetable(::matter, MATTER_STORAGE_KEY)
|
||||||
@ -101,14 +97,12 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
matterNode.destroy(::MatterNetworkGraph)
|
matterNode.isValid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setLevel(level: Level) {
|
override fun setLevel(level: Level) {
|
||||||
super.setLevel(level)
|
super.setLevel(level)
|
||||||
|
matterNode.discover(this)
|
||||||
if (level is ServerLevel)
|
|
||||||
MatterNetworkGraph.discoverFull(this, matterNode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||||
@ -155,7 +149,7 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
override fun tick() {
|
override fun tick() {
|
||||||
super.tick()
|
super.tick()
|
||||||
|
|
||||||
val graph = matterNode.graph as MatterNetworkGraph? ?: return
|
val graph = matterNode.graph as MatterGraph? ?: return
|
||||||
val received = graph.receiveMatter(matter.storedMatter, false)
|
val received = graph.receiveMatter(matter.storedMatter, false)
|
||||||
|
|
||||||
if (!received.isZero) {
|
if (!received.isZero) {
|
||||||
|
@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.block.entity.matter
|
|||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
@ -10,22 +9,20 @@ import net.minecraft.world.item.ItemStack
|
|||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraftforge.common.ForgeConfigSpec
|
import net.minecraftforge.common.ForgeConfigSpec
|
||||||
import ru.dbotthepony.mc.otm.config.ConciseBalanceValues
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
|
import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.*
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterStorage
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.capability.matter.IPatternState
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.IReplicationTask
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.MatterStorageImpl
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.PatternState
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.ReplicationTask
|
||||||
|
import ru.dbotthepony.mc.otm.config.ConciseBalanceValues
|
||||||
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
|
||||||
import ru.dbotthepony.mc.otm.menu.matter.MatterReplicatorMenu
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MNames
|
|
||||||
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
|
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
|
||||||
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
||||||
@ -33,7 +30,12 @@ import ru.dbotthepony.mc.otm.core.math.getDecimal
|
|||||||
import ru.dbotthepony.mc.otm.core.math.set
|
import ru.dbotthepony.mc.otm.core.math.set
|
||||||
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
|
||||||
|
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNode
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterManager
|
import ru.dbotthepony.mc.otm.matter.MatterManager
|
||||||
|
import ru.dbotthepony.mc.otm.menu.matter.MatterReplicatorMenu
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MNames
|
||||||
|
|
||||||
class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
MatteryWorkerBlockEntity<MatterReplicatorBlockEntity.ReplicatorJob>(MBlockEntities.MATTER_REPLICATOR, p_155229_, p_155230_, {
|
MatteryWorkerBlockEntity<MatterReplicatorBlockEntity.ReplicatorJob>(MBlockEntities.MATTER_REPLICATOR, p_155229_, p_155230_, {
|
||||||
@ -42,7 +44,7 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
} catch(err: NoSuchElementException) {
|
} catch(err: NoSuchElementException) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}), IMatterGraphNode {
|
}) {
|
||||||
|
|
||||||
class ReplicatorJob : ItemJob {
|
class ReplicatorJob : ItemJob {
|
||||||
val matterPerTick: Decimal
|
val matterPerTick: Decimal
|
||||||
@ -98,44 +100,13 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
val energy = WorkerEnergyStorage(this::powerLevelUpdated, ENERGY_VALUES)
|
val energy = WorkerEnergyStorage(this::powerLevelUpdated, ENERGY_VALUES)
|
||||||
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
|
||||||
val matter = MatterStorageImpl(this::matterLevelUpdated, FlowDirection.INPUT, ::MATTER_CAPACITY)
|
val matter = MatterStorageImpl(this::matterLevelUpdated, FlowDirection.INPUT, ::MATTER_CAPACITY)
|
||||||
val container = MatteryContainer(this::itemContainerUpdated, 5).also(::addDroppableContainer)
|
val container = MatteryContainer(this::itemContainerUpdated, 5).also(::addDroppableContainer)
|
||||||
val itemHandler = container.handler(HandlerFilter.OnlyOut)
|
val itemHandler = container.handler(HandlerFilter.OnlyOut)
|
||||||
|
|
||||||
init {
|
val matterNode = object : MatterNode() {
|
||||||
exposeEnergyGlobally(energy)
|
override fun getMatterHandler(): IMatterStorage {
|
||||||
exposeItemsGlobally(itemHandler)
|
return matter
|
||||||
exposeGlobally(MatteryCapability.MATTER, matter)
|
|
||||||
exposeGlobally(MatteryCapability.MATTER_NODE, this)
|
|
||||||
|
|
||||||
savetable(::energy, ENERGY_KEY)
|
|
||||||
savetable(::matter, MATTER_STORAGE_KEY)
|
|
||||||
savetable(::container, INVENTORY_KEY)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
|
||||||
return MatterReplicatorMenu(containerID, inventory, this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onJobFinish(job: ReplicatorJob): Status {
|
|
||||||
if (job.asDust) {
|
|
||||||
job.matterValue = moveMatterAsDustIntoContainer(job.matterValue, container, OUTPUT_DUST_MAIN, OUTPUT_DUST_STACKING)
|
|
||||||
|
|
||||||
if (!job.matterValue.isZero) {
|
|
||||||
return Status.FAILURE_WAIT
|
|
||||||
}
|
|
||||||
|
|
||||||
(matterNode.graph as MatterNetworkGraph?)?.notifyTaskCompletion(job.task.id)
|
|
||||||
return Status.SUCCESS
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!container.fullyAddItem(job.itemStack, FIRST_ACTUAL_OUTPUT_SLOT .. LAST_ACTUAL_OUTPUT_SLOT)) {
|
|
||||||
return Status.FAILURE_ITEM
|
|
||||||
}
|
|
||||||
|
|
||||||
(matterNode.graph as MatterNetworkGraph?)?.notifyTaskCompletion(job.task.id)
|
|
||||||
return Status.SUCCESS
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMatterTaskCreated(task: IReplicationTask<*>) {
|
override fun onMatterTaskCreated(task: IReplicationTask<*>) {
|
||||||
@ -155,17 +126,51 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
isIdling = false
|
isIdling = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
exposeEnergyGlobally(energy)
|
||||||
|
exposeItemsGlobally(itemHandler)
|
||||||
|
exposeGlobally(MatteryCapability.MATTER, matter)
|
||||||
|
exposeGlobally(MatteryCapability.MATTER_NODE, matterNode)
|
||||||
|
|
||||||
|
savetable(::energy, ENERGY_KEY)
|
||||||
|
savetable(::matter, MATTER_STORAGE_KEY)
|
||||||
|
savetable(::container, INVENTORY_KEY)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||||
|
return MatterReplicatorMenu(containerID, inventory, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onJobFinish(job: ReplicatorJob): Status {
|
||||||
|
if (job.asDust) {
|
||||||
|
job.matterValue = moveMatterAsDustIntoContainer(job.matterValue, container, OUTPUT_DUST_MAIN, OUTPUT_DUST_STACKING)
|
||||||
|
|
||||||
|
if (!job.matterValue.isZero) {
|
||||||
|
return Status.FAILURE_WAIT
|
||||||
|
}
|
||||||
|
|
||||||
|
matterNode.graph.notifyTaskCompletion(job.task.id)
|
||||||
|
return Status.SUCCESS
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!container.fullyAddItem(job.itemStack, FIRST_ACTUAL_OUTPUT_SLOT .. LAST_ACTUAL_OUTPUT_SLOT)) {
|
||||||
|
return Status.FAILURE_ITEM
|
||||||
|
}
|
||||||
|
|
||||||
|
matterNode.graph.notifyTaskCompletion(job.task.id)
|
||||||
|
return Status.SUCCESS
|
||||||
|
}
|
||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
matterNode.destroy(::MatterNetworkGraph)
|
matterNode.isValid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setLevel(level: Level) {
|
override fun setLevel(level: Level) {
|
||||||
super.setLevel(level)
|
super.setLevel(level)
|
||||||
|
matterNode.discover(this)
|
||||||
if (level is ServerLevel)
|
|
||||||
MatterNetworkGraph.discoverFull(this, matterNode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun jobUpdated(oldJob: ReplicatorJob?, newJob: ReplicatorJob?) {
|
override fun jobUpdated(oldJob: ReplicatorJob?, newJob: ReplicatorJob?) {
|
||||||
@ -176,7 +181,7 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
var visualItemStack by synchronizer.item(observe = false)
|
var visualItemStack by synchronizer.item(observe = false)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
var visualProgress by synchronizer.float()
|
var visualProgress by synchronizer.float().property
|
||||||
private set
|
private set
|
||||||
|
|
||||||
var renderRotation = 0f
|
var renderRotation = 0f
|
||||||
@ -188,8 +193,7 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
return null to IdleReason.POWER
|
return null to IdleReason.POWER
|
||||||
}
|
}
|
||||||
|
|
||||||
val graph = matterNode.graph as MatterNetworkGraph? ?: return null to null
|
val allocation = matterNode.graph.allocateTask(simulate = false) ?: return null to IdleReason.OBSERVING
|
||||||
val allocation = graph.allocateTask(simulate = false) ?: return null to IdleReason.OBSERVING
|
|
||||||
val stack = allocation.task.stack(1)
|
val stack = allocation.task.stack(1)
|
||||||
val matter = MatterManager.get(stack)
|
val matter = MatterManager.get(stack)
|
||||||
|
|
||||||
@ -211,7 +215,6 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
override fun onWorkTick(requiredPower: Decimal, extractedPower: Decimal, ticksAdvanced: Double, job: ReplicatorJob): Status {
|
override fun onWorkTick(requiredPower: Decimal, extractedPower: Decimal, ticksAdvanced: Double, job: ReplicatorJob): Status {
|
||||||
val drainPerTick = job.matterPerTick * ticksAdvanced
|
val drainPerTick = job.matterPerTick * ticksAdvanced
|
||||||
val graph = matterNode.graph as MatterNetworkGraph? ?: return Status.FAILURE_WAIT_FAST
|
|
||||||
|
|
||||||
if (matter.extractMatterInner(drainPerTick, true) < drainPerTick) {
|
if (matter.extractMatterInner(drainPerTick, true) < drainPerTick) {
|
||||||
// в машине недостаточно материи
|
// в машине недостаточно материи
|
||||||
@ -219,7 +222,7 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
if (drainPerTick > matter.maxStoredMatter) {
|
if (drainPerTick > matter.maxStoredMatter) {
|
||||||
// в тик требуется больше материи, чем её может хранить репликатор
|
// в тик требуется больше материи, чем её может хранить репликатор
|
||||||
val toExtract = drainPerTick - matter.extractMatterInner(drainPerTick, true)
|
val toExtract = drainPerTick - matter.extractMatterInner(drainPerTick, true)
|
||||||
val drain = graph.extractMatter(toExtract, true)
|
val drain = matterNode.graph.extractMatter(toExtract, true)
|
||||||
|
|
||||||
if (drain != toExtract) {
|
if (drain != toExtract) {
|
||||||
// недостаточно материи в сети
|
// недостаточно материи в сети
|
||||||
@ -228,12 +231,12 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
// достаточно материи в сети + внутри машины
|
// достаточно материи в сети + внутри машины
|
||||||
matter.extractMatterInner(drainPerTick, false)
|
matter.extractMatterInner(drainPerTick, false)
|
||||||
graph.extractMatter(drain, false)
|
matterNode.graph.extractMatter(drain, false)
|
||||||
return Status.SUCCESS
|
return Status.SUCCESS
|
||||||
} else {
|
} else {
|
||||||
// в тик требуется меньше материи, чем её может хранить репликатор
|
// в тик требуется меньше материи, чем её может хранить репликатор
|
||||||
// примем из сети недостающее количество бака материи, или 200 тиков репликации, что меньше
|
// примем из сети недостающее количество бака материи, или 200 тиков репликации, что меньше
|
||||||
val drain = graph.extractMatter((drainPerTick * DRAIN_MULT)
|
val drain = matterNode.graph.extractMatter((drainPerTick * DRAIN_MULT)
|
||||||
.coerceAtMost(job.matterPerTick * (job.ticks - workTicks - ticksAdvanced))
|
.coerceAtMost(job.matterPerTick * (job.ticks - workTicks - ticksAdvanced))
|
||||||
.coerceAtLeast(Decimal.ONE)
|
.coerceAtLeast(Decimal.ONE)
|
||||||
.coerceAtMost(matter.missingMatter), false)
|
.coerceAtMost(matter.missingMatter), false)
|
||||||
|
@ -22,18 +22,18 @@ import ru.dbotthepony.mc.otm.core.math.Decimal
|
|||||||
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
|
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
|
||||||
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
|
||||||
import ru.dbotthepony.mc.otm.menu.matter.MatterScannerMenu
|
import ru.dbotthepony.mc.otm.menu.matter.MatterScannerMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.registry.MNames
|
import ru.dbotthepony.mc.otm.registry.MNames
|
||||||
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNode
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterManager
|
import ru.dbotthepony.mc.otm.matter.MatterManager
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
MatteryWorkerBlockEntity<MatteryWorkerBlockEntity.ItemJob>(MBlockEntities.MATTER_SCANNER, p_155229_, p_155230_, ::ItemJob), IMatterGraphNode {
|
MatteryWorkerBlockEntity<MatteryWorkerBlockEntity.ItemJob>(MBlockEntities.MATTER_SCANNER, p_155229_, p_155230_, ::ItemJob) {
|
||||||
|
|
||||||
val container = MatteryContainer(this::itemContainerUpdated, 1).also(::addDroppableContainer)
|
val container = MatteryContainer(this::itemContainerUpdated, 1).also(::addDroppableContainer)
|
||||||
val energy = WorkerEnergyStorage(this::powerLevelUpdated, ENERGY_VALUES)
|
val energy = WorkerEnergyStorage(this::powerLevelUpdated, ENERGY_VALUES)
|
||||||
@ -47,16 +47,7 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
init {
|
val matterNode = object : MatterNode() {
|
||||||
exposeItemsGlobally(itemHandler)
|
|
||||||
exposeEnergyGlobally(energy)
|
|
||||||
exposeGlobally(MatteryCapability.MATTER_NODE, this)
|
|
||||||
|
|
||||||
savetable(::container, INVENTORY_KEY)
|
|
||||||
savetable(::energy, ENERGY_KEY)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IMatterGraphNode
|
|
||||||
override fun onPatternAdded(state: IPatternState) {
|
override fun onPatternAdded(state: IPatternState) {
|
||||||
if (idleReason == IdleReason.OBSERVING) {
|
if (idleReason == IdleReason.OBSERVING) {
|
||||||
isIdling = false
|
isIdling = false
|
||||||
@ -74,18 +65,25 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
isIdling = false
|
isIdling = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// /IMatterGraphNode
|
}
|
||||||
|
|
||||||
override val matterNode: Graph6Node<IMatterGraphNode> = Graph6Node(this)
|
init {
|
||||||
|
exposeItemsGlobally(itemHandler)
|
||||||
|
exposeEnergyGlobally(energy)
|
||||||
|
exposeGlobally(MatteryCapability.MATTER_NODE, matterNode)
|
||||||
|
|
||||||
|
savetable(::container, INVENTORY_KEY)
|
||||||
|
savetable(::energy, ENERGY_KEY)
|
||||||
|
}
|
||||||
|
|
||||||
override fun invalidateCaps() {
|
override fun invalidateCaps() {
|
||||||
super.invalidateCaps()
|
super.invalidateCaps()
|
||||||
matterNode.destroy(::MatterNetworkGraph)
|
matterNode.isValid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
matterNode.destroy(::MatterNetworkGraph)
|
matterNode.isValid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||||
@ -93,14 +91,12 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onJobFinish(job: ItemJob): Status {
|
override fun onJobFinish(job: ItemJob): Status {
|
||||||
val grid = matterNode.graph as MatterNetworkGraph? ?: return Status.FAILURE_WAIT
|
|
||||||
|
|
||||||
val stack = job.itemStack
|
val stack = job.itemStack
|
||||||
if (stack.isEmpty || !MatterManager.hasMatterValue(stack)) return Status.SUCCESS
|
if (stack.isEmpty || !MatterManager.hasMatterValue(stack)) return Status.SUCCESS
|
||||||
|
|
||||||
var findState: IPatternState? = null
|
var findState: IPatternState? = null
|
||||||
|
|
||||||
for (state in grid.patterns.filter { it.item === stack.item }) {
|
for (state in matterNode.graph.patterns.filter { it.item === stack.item }) {
|
||||||
if (findState == null && state.researchPercent < 1.0) {
|
if (findState == null && state.researchPercent < 1.0) {
|
||||||
findState = state
|
findState = state
|
||||||
} else if (findState != null && findState.researchPercent < state.researchPercent && state.researchPercent < 1.0) {
|
} else if (findState != null && findState.researchPercent < state.researchPercent && state.researchPercent < 1.0) {
|
||||||
@ -117,7 +113,7 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
PatternState(UUID.randomUUID(), stack.item, researchAdvance)
|
PatternState(UUID.randomUUID(), stack.item, researchAdvance)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!grid.insertPattern(new, onlyUpdate = false, simulate = false).isFailed) {
|
if (!matterNode.graph.insertPattern(new, onlyUpdate = false, simulate = false).isFailed) {
|
||||||
return Status.SUCCESS
|
return Status.SUCCESS
|
||||||
} else {
|
} else {
|
||||||
return Status.FAILURE_WAIT
|
return Status.FAILURE_WAIT
|
||||||
@ -129,14 +125,12 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
return null to IdleReason.POWER
|
return null to IdleReason.POWER
|
||||||
}
|
}
|
||||||
|
|
||||||
val grid = matterNode.graph as MatterNetworkGraph? ?: return null to null
|
|
||||||
|
|
||||||
val stack = container.getItem(0)
|
val stack = container.getItem(0)
|
||||||
if (stack.isEmpty || !MatterManager.canDecompose(stack)) return null to IdleReason.ITEM
|
if (stack.isEmpty || !MatterManager.canDecompose(stack)) return null to IdleReason.ITEM
|
||||||
|
|
||||||
var findState: IPatternState? = null
|
var findState: IPatternState? = null
|
||||||
|
|
||||||
for (state in grid.patterns.filter { it.item === stack.item }) {
|
for (state in matterNode.graph.patterns.filter { it.item === stack.item }) {
|
||||||
if (state.researchPercent < 1.0) {
|
if (state.researchPercent < 1.0) {
|
||||||
findState = state
|
findState = state
|
||||||
} else if (state.researchPercent >= 1.0) {
|
} else if (state.researchPercent >= 1.0) {
|
||||||
@ -155,7 +149,7 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
PatternState(UUID.randomUUID(), stack.item, researchAdvance)
|
PatternState(UUID.randomUUID(), stack.item, researchAdvance)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!grid.insertPattern(new, onlyUpdate = false, simulate = true).isFailed) {
|
if (!matterNode.graph.insertPattern(new, onlyUpdate = false, simulate = true).isFailed) {
|
||||||
val copy = stack.copy().also { it.count = 1 }
|
val copy = stack.copy().also { it.count = 1 }
|
||||||
stack.shrink(1)
|
stack.shrink(1)
|
||||||
container.setChanged()
|
container.setChanged()
|
||||||
@ -168,10 +162,7 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
override fun setLevel(level: Level) {
|
override fun setLevel(level: Level) {
|
||||||
super.setLevel(level)
|
super.setLevel(level)
|
||||||
|
matterNode.discover(this)
|
||||||
if (level is ServerLevel) {
|
|
||||||
MatterNetworkGraph.discoverFull(this, matterNode)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -20,8 +20,8 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
|
|||||||
import ru.dbotthepony.mc.otm.capability.matter.*
|
import ru.dbotthepony.mc.otm.capability.matter.*
|
||||||
import ru.dbotthepony.mc.otm.core.collect.iterator
|
import ru.dbotthepony.mc.otm.core.collect.iterator
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
@ -29,24 +29,22 @@ import java.util.stream.Stream
|
|||||||
@MethodsReturnNonnullByDefault
|
@MethodsReturnNonnullByDefault
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
MatteryDeviceBlockEntity(MBlockEntities.PATTERN_STORAGE, p_155229_, p_155230_), IMatterGraphNode, IPatternStorage {
|
MatteryDeviceBlockEntity(MBlockEntities.PATTERN_STORAGE, p_155229_, p_155230_), IPatternStorage {
|
||||||
|
|
||||||
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
val matterNode = SimpleMatterNode(patterns = this)
|
||||||
|
|
||||||
val container: MatteryContainer = object : MatteryContainer(this::setChanged, 8) {
|
val container: MatteryContainer = object : MatteryContainer(this::setChanged, 8) {
|
||||||
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
||||||
val grid = matterNode.graph as MatterNetworkGraph?
|
if (!ItemStack.isSameItemSameTags(new, old)) {
|
||||||
|
|
||||||
if (grid != null && !ItemStack.isSameItemSameTags(new, old)) {
|
|
||||||
if (!old.isEmpty) {
|
if (!old.isEmpty) {
|
||||||
old.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
old.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
||||||
cap.patterns.forEach { grid.onPatternRemoved(it) }
|
cap.patterns.forEach { matterNode.graph.onPatternRemoved(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!new.isEmpty) {
|
if (!new.isEmpty) {
|
||||||
new.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
new.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
||||||
cap.patterns.forEach { grid.onPatternAdded(it) }
|
cap.patterns.forEach { matterNode.graph.onPatternAdded(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,23 +80,17 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
override fun setLevel(level: Level) {
|
override fun setLevel(level: Level) {
|
||||||
super.setLevel(level)
|
super.setLevel(level)
|
||||||
|
matterNode.discover(this)
|
||||||
if (level is ServerLevel)
|
|
||||||
MatterNetworkGraph.discoverFull(this, matterNode)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getPatternHandler(): IPatternStorage {
|
|
||||||
return this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invalidateCaps() {
|
override fun invalidateCaps() {
|
||||||
super.invalidateCaps()
|
super.invalidateCaps()
|
||||||
matterNode.destroy(::MatterNetworkGraph)
|
matterNode.isValid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
exposeGlobally(MatteryCapability.PATTERN, this)
|
exposeGlobally(MatteryCapability.PATTERN, this)
|
||||||
exposeGlobally(MatteryCapability.MATTER_NODE, this)
|
exposeGlobally(MatteryCapability.MATTER_NODE, matterNode)
|
||||||
exposeItemsGlobally(itemHandler)
|
exposeItemsGlobally(itemHandler)
|
||||||
|
|
||||||
savetable(::container, INVENTORY_KEY)
|
savetable(::container, INVENTORY_KEY)
|
||||||
@ -138,7 +130,7 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
matterNode.destroy(::MatterNetworkGraph)
|
matterNode.isValid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun insertPattern(pattern: IPatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus {
|
override fun insertPattern(pattern: IPatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus {
|
||||||
@ -149,14 +141,10 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
setChanged()
|
setChanged()
|
||||||
|
|
||||||
val graph = matterNode.graph as MatterNetworkGraph?
|
|
||||||
|
|
||||||
if (graph != null) {
|
|
||||||
if (status.isInserted) {
|
if (status.isInserted) {
|
||||||
graph.onPatternAdded(status.newState!!)
|
matterNode.graph.onPatternAdded(status.newState!!)
|
||||||
} else {
|
} else {
|
||||||
graph.onPatternUpdated(status.newState!!, status.oldState!!)
|
matterNode.graph.onPatternUpdated(status.newState!!, status.oldState!!)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,13 +9,13 @@ import net.minecraft.world.item.ItemStack
|
|||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
import ru.dbotthepony.mc.otm.graph.storage.StorageNode
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.menu.storage.DriveRackMenu
|
import ru.dbotthepony.mc.otm.menu.storage.DriveRackMenu
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.storage.StorageGraph
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.storage.*
|
import ru.dbotthepony.mc.otm.storage.*
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ class DriveRackBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
}.also(::addDroppableContainer)
|
}.also(::addDroppableContainer)
|
||||||
|
|
||||||
val cell = BasicStorageGraphNode(energy)
|
val cell = StorageNode(energy)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
savetable(::energy, ENERGY_KEY)
|
savetable(::energy, ENERGY_KEY)
|
||||||
@ -52,9 +52,7 @@ class DriveRackBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
override fun setLevel(level: Level) {
|
override fun setLevel(level: Level) {
|
||||||
super.setLevel(level)
|
super.setLevel(level)
|
||||||
|
cell.discover(this)
|
||||||
if (level is ServerLevel)
|
|
||||||
StorageNetworkGraph.discoverFull(this, cell.storageNode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
@ -68,6 +66,6 @@ class DriveRackBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
cell.destroy(level)
|
cell.isValid = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,8 @@ import ru.dbotthepony.mc.otm.client.minecraft
|
|||||||
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.container.get
|
import ru.dbotthepony.mc.otm.container.get
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
import ru.dbotthepony.mc.otm.graph.storage.StorageNode
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.storage.StorageGraph
|
||||||
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.container.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
@ -188,13 +188,13 @@ class ItemMonitorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
var poweredView: PoweredVirtualComponent<ItemStackWrapper>? = null
|
var poweredView: PoweredVirtualComponent<ItemStackWrapper>? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
val cell = object : BasicStorageGraphNode(energy) {
|
val cell = object : StorageNode(energy) {
|
||||||
override fun attachComponents(to: StorageNetworkGraph) {
|
override fun attachComponents(to: StorageGraph) {
|
||||||
super.attachComponents(to)
|
super.attachComponents(to)
|
||||||
poweredView = PoweredVirtualComponent(to.getVirtualComponent(ITEM_STORAGE), energy)
|
poweredView = PoweredVirtualComponent(to.getVirtualComponent(ITEM_STORAGE), energy)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun removeComponents(from: StorageNetworkGraph) {
|
override fun removeComponents(from: StorageGraph) {
|
||||||
super.removeComponents(from)
|
super.removeComponents(from)
|
||||||
poweredView?.removeListeners()
|
poweredView?.removeListeners()
|
||||||
poweredView = null
|
poweredView = null
|
||||||
@ -499,13 +499,11 @@ class ItemMonitorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
override fun setLevel(level: Level) {
|
override fun setLevel(level: Level) {
|
||||||
super.setLevel(level)
|
super.setLevel(level)
|
||||||
|
cell.discover(this)
|
||||||
if (level is ServerLevel)
|
|
||||||
StorageNetworkGraph.discoverFull(this, cell.storageNode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
cell.destroy(level)
|
cell.isValid = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
|||||||
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet
|
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet
|
||||||
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.server.level.ServerLevel
|
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
@ -31,21 +29,14 @@ import ru.dbotthepony.mc.otm.core.math.getCapability
|
|||||||
import ru.dbotthepony.mc.otm.core.math.isPositive
|
import ru.dbotthepony.mc.otm.core.math.isPositive
|
||||||
import ru.dbotthepony.mc.otm.core.math.isZero
|
import ru.dbotthepony.mc.otm.core.math.isZero
|
||||||
import ru.dbotthepony.mc.otm.core.math.plus
|
import ru.dbotthepony.mc.otm.core.math.plus
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.storage.StorageNode
|
||||||
import ru.dbotthepony.mc.otm.graph.GraphNodeListener
|
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
|
|
||||||
import ru.dbotthepony.mc.otm.menu.storage.StorageBusMenu
|
import ru.dbotthepony.mc.otm.menu.storage.StorageBusMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlocks
|
|
||||||
import ru.dbotthepony.mc.otm.storage.*
|
import ru.dbotthepony.mc.otm.storage.*
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
import kotlin.NoSuchElementException
|
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
import kotlin.collections.HashMap
|
|
||||||
|
|
||||||
private class SlotTuple(val slot: Int, val stack: ItemStack)
|
private class SlotTuple(val slot: Int, val stack: ItemStack)
|
||||||
private class TrackedTuple(override val stack: ItemStackWrapper, override val id: UUID) : IStorageTuple<ItemStackWrapper> {
|
private class TrackedTuple(override val stack: ItemStackWrapper, override val id: UUID) : IStorageTuple<ItemStackWrapper> {
|
||||||
@ -77,15 +68,15 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
|
|||||||
savetable(::energy, ENERGY_KEY)
|
savetable(::energy, ENERGY_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
val cell: BasicStorageGraphNode = object : BasicStorageGraphNode(energy), GraphNodeListener {
|
val cell: StorageNode = object : StorageNode(energy) {
|
||||||
override fun onNeighbour(node: Graph6Node<*>, direction: Direction) {
|
override fun onNeighbour(direction: Direction) {
|
||||||
val newState = this@StorageBusBlockEntity.blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, true)
|
val newState = this@StorageBusBlockEntity.blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, true)
|
||||||
|
|
||||||
if (newState !== this@StorageBusBlockEntity.blockState && SERVER_IS_LIVE)
|
if (newState !== this@StorageBusBlockEntity.blockState && SERVER_IS_LIVE)
|
||||||
level?.setBlock(blockPos, newState, Block.UPDATE_CLIENTS)
|
level?.setBlock(blockPos, newState, Block.UPDATE_CLIENTS)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUnNeighbour(node: Graph6Node<*>, direction: Direction) {
|
override fun onUnNeighbour(direction: Direction) {
|
||||||
val newState = this@StorageBusBlockEntity.blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, false)
|
val newState = this@StorageBusBlockEntity.blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, false)
|
||||||
|
|
||||||
if (newState !== this@StorageBusBlockEntity.blockState && SERVER_IS_LIVE)
|
if (newState !== this@StorageBusBlockEntity.blockState && SERVER_IS_LIVE)
|
||||||
@ -109,11 +100,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
|
|||||||
|
|
||||||
override fun setLevel(level: Level) {
|
override fun setLevel(level: Level) {
|
||||||
super.setLevel(level)
|
super.setLevel(level)
|
||||||
|
cell.discover(this)
|
||||||
if (level is ServerLevel) {
|
|
||||||
StorageNetworkGraph.discoverFull(this, cell.storageNode)
|
|
||||||
}
|
|
||||||
|
|
||||||
tickList.once(this::checkSurroundings)
|
tickList.once(this::checkSurroundings)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +115,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
|
|||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
cell.destroy(level)
|
cell.isValid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkSurroundings() {
|
fun checkSurroundings() {
|
||||||
|
@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.block.entity.storage
|
|||||||
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
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
@ -26,14 +25,10 @@ import ru.dbotthepony.mc.otm.config.ConciseBalanceValues
|
|||||||
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||||
import ru.dbotthepony.mc.otm.container.ItemFilter
|
import ru.dbotthepony.mc.otm.container.ItemFilter
|
||||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
|
||||||
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
||||||
import ru.dbotthepony.mc.otm.core.math.toIntSafe
|
import ru.dbotthepony.mc.otm.core.math.toIntSafe
|
||||||
import ru.dbotthepony.mc.otm.core.orNull
|
import ru.dbotthepony.mc.otm.core.orNull
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.storage.StorageNode
|
||||||
import ru.dbotthepony.mc.otm.graph.GraphNodeListener
|
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
|
|
||||||
import ru.dbotthepony.mc.otm.menu.storage.StorageExporterMenu
|
import ru.dbotthepony.mc.otm.menu.storage.StorageExporterMenu
|
||||||
import ru.dbotthepony.mc.otm.menu.storage.StorageImporterMenu
|
import ru.dbotthepony.mc.otm.menu.storage.StorageImporterMenu
|
||||||
import ru.dbotthepony.mc.otm.once
|
import ru.dbotthepony.mc.otm.once
|
||||||
@ -62,8 +57,8 @@ abstract class AbstractStorageImportExport<T>(
|
|||||||
savetable(::energy, ENERGY_KEY)
|
savetable(::energy, ENERGY_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
val cell: BasicStorageGraphNode = object : BasicStorageGraphNode(energy), GraphNodeListener {
|
val cell: StorageNode = object : StorageNode(energy) {
|
||||||
override fun onNeighbour(node: Graph6Node<*>, direction: Direction) {
|
override fun onNeighbour(direction: Direction) {
|
||||||
level?.once {
|
level?.once {
|
||||||
if (!isRemoved) {
|
if (!isRemoved) {
|
||||||
val newState = this@AbstractStorageImportExport.blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, true)
|
val newState = this@AbstractStorageImportExport.blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, true)
|
||||||
@ -74,7 +69,7 @@ abstract class AbstractStorageImportExport<T>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUnNeighbour(node: Graph6Node<*>, direction: Direction) {
|
override fun onUnNeighbour(direction: Direction) {
|
||||||
level?.once {
|
level?.once {
|
||||||
if (!isRemoved) {
|
if (!isRemoved) {
|
||||||
val newState = this@AbstractStorageImportExport.blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, false)
|
val newState = this@AbstractStorageImportExport.blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[direction]!!, false)
|
||||||
@ -93,15 +88,12 @@ abstract class AbstractStorageImportExport<T>(
|
|||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
cell.destroy(level)
|
cell.isValid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setLevel(level: Level) {
|
override fun setLevel(level: Level) {
|
||||||
super.setLevel(level)
|
super.setLevel(level)
|
||||||
|
cell.discover(this)
|
||||||
if (level is ServerLevel) {
|
|
||||||
StorageNetworkGraph.discoverFull(this, cell.storageNode)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract val targetCapability: Capability<T>
|
protected abstract val targetCapability: Capability<T>
|
||||||
@ -117,7 +109,6 @@ abstract class AbstractStorageImportExport<T>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val MAX_POWER = Decimal(10_000)
|
|
||||||
const val FILTER_KEY = "filter"
|
const val FILTER_KEY = "filter"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,7 +146,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : A
|
|||||||
if (redstoneControl.isBlockedByRedstone || !filter.match(stack))
|
if (redstoneControl.isBlockedByRedstone || !filter.match(stack))
|
||||||
return stack
|
return stack
|
||||||
|
|
||||||
val view = cell.storageGraph?.getVirtualComponent(ITEM_STORAGE) ?: return stack
|
val view = cell.graph.getVirtualComponent(ITEM_STORAGE)
|
||||||
val maxMove = energy.extractEnergyExact(ITEM_STORAGE.energyPerOperation, stack.count.toBigInteger(), true)
|
val maxMove = energy.extractEnergyExact(ITEM_STORAGE.energyPerOperation, stack.count.toBigInteger(), true)
|
||||||
|
|
||||||
if (maxMove == BigInteger.ZERO)
|
if (maxMove == BigInteger.ZERO)
|
||||||
@ -195,8 +186,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : A
|
|||||||
val target = target.get().orNull()
|
val target = target.get().orNull()
|
||||||
|
|
||||||
if (nextTick <= 0 && target != null && enoughEnergy) {
|
if (nextTick <= 0 && target != null && enoughEnergy) {
|
||||||
val graph = cell.storageGraph ?: return
|
val items = cell.graph.getVirtualComponent(ITEM_STORAGE)
|
||||||
val items = graph.getVirtualComponent(ITEM_STORAGE)
|
|
||||||
|
|
||||||
if (lastSlot >= target.slots) {
|
if (lastSlot >= target.slots) {
|
||||||
lastSlot = 0
|
lastSlot = 0
|
||||||
@ -227,7 +217,6 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : A
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val MAX_MOVE_PER_OPERATION = 4
|
const val MAX_MOVE_PER_OPERATION = 4
|
||||||
private val MACHINE_NAME = TranslatableComponent("block.${OverdriveThatMatters.MOD_ID}.${MNames.STORAGE_IMPORTER}")
|
|
||||||
private const val INTERVAL = 5
|
private const val INTERVAL = 5
|
||||||
const val MAX_FILTERS = 6 * 3
|
const val MAX_FILTERS = 6 * 3
|
||||||
}
|
}
|
||||||
@ -271,7 +260,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
|||||||
override val filter = ItemFilter(MAX_FILTERS) { _, _, _ ->
|
override val filter = ItemFilter(MAX_FILTERS) { _, _, _ ->
|
||||||
relevantTuples.clear()
|
relevantTuples.clear()
|
||||||
|
|
||||||
val component = cell.storageGraph?.getVirtualComponent(ITEM_STORAGE) ?: return@ItemFilter
|
val component = cell.graph.getVirtualComponent(ITEM_STORAGE)
|
||||||
|
|
||||||
for (tuple in component.stacks) {
|
for (tuple in component.stacks) {
|
||||||
addStack(tuple, component)
|
addStack(tuple, component)
|
||||||
@ -291,7 +280,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
|||||||
|
|
||||||
private val exportStacks: Stream<Pair<UUID, ItemStackWrapper>>
|
private val exportStacks: Stream<Pair<UUID, ItemStackWrapper>>
|
||||||
get() {
|
get() {
|
||||||
val view = cell.storageGraph?.getVirtualComponent(ITEM_STORAGE) ?: return Stream.empty()
|
val view = cell.graph.getVirtualComponent(ITEM_STORAGE)
|
||||||
return relevantTuples.stream().map { it to view[it] }
|
return relevantTuples.stream().map { it to view[it] }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,8 +297,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
|||||||
val target = target.get().orNull()
|
val target = target.get().orNull()
|
||||||
|
|
||||||
if (nextTick <= 0 && target != null && enoughEnergy) {
|
if (nextTick <= 0 && target != null && enoughEnergy) {
|
||||||
val graph = cell.storageGraph ?: return
|
val items = cell.graph.getVirtualComponent(ITEM_STORAGE)
|
||||||
val items = graph.getVirtualComponent(ITEM_STORAGE)
|
|
||||||
|
|
||||||
if (lastSlot >= target.slots) {
|
if (lastSlot >= target.slots) {
|
||||||
lastSlot = 0
|
lastSlot = 0
|
||||||
|
@ -13,8 +13,8 @@ import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
|||||||
import ru.dbotthepony.mc.otm.capability.energy.transferChecked
|
import ru.dbotthepony.mc.otm.capability.energy.transferChecked
|
||||||
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
import ru.dbotthepony.mc.otm.graph.storage.StorageNode
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.storage.StorageGraph
|
||||||
import ru.dbotthepony.mc.otm.menu.storage.StoragePowerSupplierMenu
|
import ru.dbotthepony.mc.otm.menu.storage.StoragePowerSupplierMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState
|
|||||||
return StoragePowerSupplierMenu(containerID, inventory, this)
|
return StoragePowerSupplierMenu(containerID, inventory, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
val cell = BasicStorageGraphNode()
|
val cell = StorageNode()
|
||||||
val energy = WorkerEnergyStorage(this, MachinesConfig.STORAGE_POWER_SUPPLIER)
|
val energy = WorkerEnergyStorage(this, MachinesConfig.STORAGE_POWER_SUPPLIER)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -42,15 +42,12 @@ class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState
|
|||||||
|
|
||||||
override fun setLevel(level: Level) {
|
override fun setLevel(level: Level) {
|
||||||
super.setLevel(level)
|
super.setLevel(level)
|
||||||
|
cell.discover(this)
|
||||||
if (level is ServerLevel) {
|
|
||||||
StorageNetworkGraph.discoverFull(this, cell.storageNode)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
cell.destroy(level)
|
cell.isValid = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
@ -62,9 +59,7 @@ class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState
|
|||||||
if (energy.batteryLevel.isZero)
|
if (energy.batteryLevel.isZero)
|
||||||
return
|
return
|
||||||
|
|
||||||
val graph = cell.storageGraph ?: return
|
if (cell.graph.powerDemandingNodes.isEmpty())
|
||||||
|
|
||||||
if (graph.powerDemandingNodes.isEmpty())
|
|
||||||
return
|
return
|
||||||
|
|
||||||
var demand = Decimal.ZERO
|
var demand = Decimal.ZERO
|
||||||
@ -72,7 +67,7 @@ class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState
|
|||||||
|
|
||||||
val available = energy.batteryLevel.coerceAtMost(MachinesConfig.STORAGE_POWER_SUPPLIER.throughput)
|
val available = energy.batteryLevel.coerceAtMost(MachinesConfig.STORAGE_POWER_SUPPLIER.throughput)
|
||||||
|
|
||||||
for (demanding in graph.powerDemandingNodes) {
|
for (demanding in cell.graph.powerDemandingNodes) {
|
||||||
val received = demanding.receiveEnergy(available, true)
|
val received = demanding.receiveEnergy(available, true)
|
||||||
|
|
||||||
if (received.isPositive) {
|
if (received.isPositive) {
|
||||||
@ -84,13 +79,13 @@ class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState
|
|||||||
if (demand.isZero) {
|
if (demand.isZero) {
|
||||||
return
|
return
|
||||||
} else if (demand < available) {
|
} else if (demand < available) {
|
||||||
for (demanding in graph.powerDemandingNodes) {
|
for (demanding in cell.graph.powerDemandingNodes) {
|
||||||
powerPassed += energy.transferChecked(demanding, available, false)
|
powerPassed += energy.transferChecked(demanding, available, false)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val forEach = available / i
|
val forEach = available / i
|
||||||
|
|
||||||
for (demanding in graph.powerDemandingNodes) {
|
for (demanding in cell.graph.powerDemandingNodes) {
|
||||||
powerPassed += energy.transferChecked(demanding, forEach, false)
|
powerPassed += energy.transferChecked(demanding, forEach, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,9 @@ import ru.dbotthepony.mc.otm.onceServer
|
|||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.isMekanismLoaded
|
import ru.dbotthepony.mc.otm.capability.isMekanismLoaded
|
||||||
import ru.dbotthepony.mc.otm.core.math.isPositive
|
import ru.dbotthepony.mc.otm.core.math.isPositive
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
import ru.dbotthepony.mc.otm.core.util.LOHolder
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.storage.StorageNode
|
||||||
|
import ru.dbotthepony.mc.otm.graph.storage.StorageGraph
|
||||||
import ru.dbotthepony.mc.otm.storage.*
|
import ru.dbotthepony.mc.otm.storage.*
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@ -206,14 +207,14 @@ private class QIOStorage(private val tile: TileEntityQIODriveArray) : ICapabilit
|
|||||||
private var frequencyAccess: QIOFrequencyAccess? = null
|
private var frequencyAccess: QIOFrequencyAccess? = null
|
||||||
private var wasAttached = false
|
private var wasAttached = false
|
||||||
|
|
||||||
val cell: BasicStorageGraphNode = object : BasicStorageGraphNode(), ITickable {
|
val cell: StorageNode = object : StorageNode(), ITickable {
|
||||||
init {
|
init {
|
||||||
manualAttaching = true
|
manualAttaching = true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
if (tile.isRemoved) {
|
if (tile.isRemoved) {
|
||||||
destroy(tile.level)
|
isValid = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,9 +226,7 @@ private class QIOStorage(private val tile: TileEntityQIODriveArray) : ICapabilit
|
|||||||
|
|
||||||
val lastFrequency = lastFrequency ?: throw IllegalStateException("lastFrequency is null")
|
val lastFrequency = lastFrequency ?: throw IllegalStateException("lastFrequency is null")
|
||||||
|
|
||||||
checkNotNull(storageGraph) {
|
graph.userData.remove(key(lastFrequency))
|
||||||
"Unexpected internal state (expected storage graph to be present, something detached $this from storage grid, but did not call removeComponents())"
|
|
||||||
}.userData.remove(key(lastFrequency))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
frequencyAccess?.let(this::removeStorageComponent)
|
frequencyAccess?.let(this::removeStorageComponent)
|
||||||
@ -240,17 +239,16 @@ private class QIOStorage(private val tile: TileEntityQIODriveArray) : ICapabilit
|
|||||||
|
|
||||||
val frequencyAccess = frequencyAccess ?: return
|
val frequencyAccess = frequencyAccess ?: return
|
||||||
frequencyAccess.scan()
|
frequencyAccess.scan()
|
||||||
val storageGraph = storageGraph ?: return
|
|
||||||
val key = key(frequencyAccess.parent)
|
val key = key(frequencyAccess.parent)
|
||||||
|
|
||||||
if (!storageGraph.userData.containsKey(key)) {
|
if (!graph.userData.containsKey(key)) {
|
||||||
storageGraph.userData[key] = true
|
graph.userData[key] = true
|
||||||
wasAttached = true
|
wasAttached = true
|
||||||
storageGraph.add(frequencyAccess)
|
graph.add(frequencyAccess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun removeComponents(from: StorageNetworkGraph) {
|
override fun removeComponents(from: StorageGraph) {
|
||||||
super.removeComponents(from)
|
super.removeComponents(from)
|
||||||
|
|
||||||
if (wasAttached) {
|
if (wasAttached) {
|
||||||
@ -259,11 +257,23 @@ private class QIOStorage(private val tile: TileEntityQIODriveArray) : ICapabilit
|
|||||||
wasAttached = false
|
wasAttached = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun invalidate() {
|
||||||
|
super.invalidate()
|
||||||
|
holder.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun revive() {
|
||||||
|
super.revive()
|
||||||
|
holder.revive()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val holder = LOHolder(cell)
|
||||||
|
|
||||||
override fun <T : Any> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
override fun <T : Any> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
if (cap === MatteryCapability.STORAGE_NODE)
|
if (cap === MatteryCapability.STORAGE_NODE)
|
||||||
return cell.get().cast()
|
return holder.get()
|
||||||
|
|
||||||
return LazyOptional.empty()
|
return LazyOptional.empty()
|
||||||
}
|
}
|
||||||
@ -286,8 +296,8 @@ fun attachCapabilities(event: AttachCapabilitiesEvent<BlockEntity>) {
|
|||||||
event.addCapability(QIO_LOCATION, capability)
|
event.addCapability(QIO_LOCATION, capability)
|
||||||
|
|
||||||
onceServer {
|
onceServer {
|
||||||
if (!event.`object`.isRemoved && event.`object`.level?.isClientSide == false) {
|
if (!event.`object`.isRemoved) {
|
||||||
StorageNetworkGraph.discoverFull(event.`object`, capability.cell.storageNode)
|
capability.cell.discover(event.`object`, MatteryCapability.STORAGE_NODE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
20
src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LOHolder.kt
Normal file
20
src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LOHolder.kt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.core.util
|
||||||
|
|
||||||
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
|
|
||||||
|
class LOHolder<T : Any>(val value: T) {
|
||||||
|
private var lazyOptional: LazyOptional<T> = LazyOptional.of { value }
|
||||||
|
|
||||||
|
fun invalidate() {
|
||||||
|
lazyOptional.invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun revive() {
|
||||||
|
lazyOptional.invalidate()
|
||||||
|
lazyOptional = LazyOptional.of { value }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> get(): LazyOptional<T> {
|
||||||
|
return lazyOptional.cast()
|
||||||
|
}
|
||||||
|
}
|
@ -1,178 +1,172 @@
|
|||||||
package ru.dbotthepony.mc.otm.graph
|
package ru.dbotthepony.mc.otm.graph
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
|
||||||
import net.minecraft.core.Direction
|
|
||||||
import net.minecraft.core.SectionPos
|
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity
|
|
||||||
import ru.dbotthepony.mc.otm.core.util.IConditionalTickable
|
import ru.dbotthepony.mc.otm.core.util.IConditionalTickable
|
||||||
import ru.dbotthepony.mc.otm.core.math.plus
|
import ru.dbotthepony.mc.otm.core.util.ITickable
|
||||||
import ru.dbotthepony.mc.otm.addTicker
|
import java.lang.ref.WeakReference
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
import kotlin.collections.HashMap
|
|
||||||
|
|
||||||
abstract class Abstract6Graph<T> : IConditionalTickable {
|
open class Abstract6Graph<N : Graph6Node<N, G>, G : Abstract6Graph<N, G>> : IConditionalTickable {
|
||||||
protected val nodes = ArrayList<Graph6Node<T>>()
|
private val nodesInternal = ArrayList<N>()
|
||||||
fun size() = nodes.size
|
private val conditional = ArrayList<IConditionalTickable>()
|
||||||
private val tickable = ArrayList<Graph6Node<T>>()
|
private val always = ArrayList<ITickable>()
|
||||||
val nodeList: Collection<Graph6Node<T>> = Collections.unmodifiableCollection(nodes)
|
|
||||||
|
protected val nodes: List<N> = Collections.unmodifiableList(nodesInternal)
|
||||||
|
|
||||||
|
val size get() = nodesInternal.size
|
||||||
|
|
||||||
|
var isMerged = false
|
||||||
|
private set
|
||||||
|
|
||||||
|
private var isTicking = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows storing arbitrary data by external code
|
* Allows storing arbitrary data by external code
|
||||||
*/
|
*/
|
||||||
@JvmField
|
|
||||||
val userData = HashMap<UUID, Any>()
|
val userData = HashMap<UUID, Any>()
|
||||||
|
|
||||||
abstract fun onNodeRemoved(node: Graph6Node<T>)
|
open fun onNodeRemoved(node: N) {}
|
||||||
abstract fun onNodeAdded(node: Graph6Node<T>)
|
open fun onNodeAdded(node: N) {}
|
||||||
|
open fun onMergedInto(other: G) {}
|
||||||
|
|
||||||
override fun tick(): Boolean {
|
protected open fun innerTick(): Boolean {
|
||||||
for (i in tickable.size - 1 downTo 0) {
|
return false
|
||||||
val node = tickable[i]
|
}
|
||||||
|
|
||||||
|
final override fun tick(): Boolean {
|
||||||
|
if (isMerged)
|
||||||
|
return false
|
||||||
|
|
||||||
|
// позволяет вершинам изменять список тикающих вершин
|
||||||
|
for (i in conditional.size - 1 downTo 0) {
|
||||||
|
val node = conditional[i]
|
||||||
|
|
||||||
if (!node.tick()) {
|
if (!node.tick()) {
|
||||||
tickable.removeAt(i)
|
conditional.removeAt(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodes.size > 0
|
// позволяет вершинам изменять список тикающих вершин
|
||||||
|
for (node in always.size - 1 downTo 0) {
|
||||||
|
always[node].tick()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeNode(node: Graph6Node<T>) {
|
return innerTick() || always.isNotEmpty() || conditional.isNotEmpty()
|
||||||
if (!nodes.remove(node))
|
|
||||||
throw IllegalStateException("Not containing node $node")
|
|
||||||
|
|
||||||
node.graph = null
|
|
||||||
onNodeRemoved(node)
|
|
||||||
tickable.remove(node)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addNode(node: Graph6Node<T>) {
|
fun addNode(node: N): Boolean {
|
||||||
if (nodes.contains(node))
|
if (node in nodesInternal)
|
||||||
throw IllegalStateException("Already containing node $node")
|
return false
|
||||||
|
|
||||||
|
nodesInternal.add(node)
|
||||||
|
|
||||||
|
if (node is IConditionalTickable) {
|
||||||
|
conditional.add(node)
|
||||||
|
|
||||||
|
if (!isTicking) {
|
||||||
|
isTicking = true
|
||||||
|
next.add(WeakReference(this))
|
||||||
|
}
|
||||||
|
} else if (node is ITickable) {
|
||||||
|
always.add(node)
|
||||||
|
|
||||||
|
if (!isTicking) {
|
||||||
|
isTicking = true
|
||||||
|
next.add(WeakReference(this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nodes.add(node)
|
|
||||||
node.graph = this
|
|
||||||
onNodeAdded(node)
|
onNodeAdded(node)
|
||||||
tickable.add(node)
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun merge(other: Abstract6Graph<T>): Abstract6Graph<T> {
|
fun removeNode(node: N): Boolean {
|
||||||
|
if (!nodesInternal.remove(node))
|
||||||
|
return false
|
||||||
|
|
||||||
|
nodesInternal.remove(node)
|
||||||
|
|
||||||
|
if (node is IConditionalTickable)
|
||||||
|
conditional.remove(node)
|
||||||
|
else if (node is ITickable)
|
||||||
|
always.remove(node)
|
||||||
|
|
||||||
|
onNodeRemoved(node)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun retain(nodes: Set<N>) {
|
||||||
|
for (i in this.nodesInternal.size - 1 downTo 0) {
|
||||||
|
if (this.nodesInternal[i] !in nodes) {
|
||||||
|
val node = this.nodesInternal[i]
|
||||||
|
|
||||||
|
this.nodesInternal.removeAt(i)
|
||||||
|
|
||||||
|
if (node is IConditionalTickable)
|
||||||
|
conditional.remove(node)
|
||||||
|
else if (node is ITickable)
|
||||||
|
always.remove(node)
|
||||||
|
|
||||||
|
onNodeRemoved(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun merge(other: G, setter: (N, G) -> Unit): G {
|
||||||
if (other === this)
|
if (other === this)
|
||||||
return this
|
return this
|
||||||
|
|
||||||
if (size() >= other.size()) {
|
if (size >= other.size) {
|
||||||
for (node in other.nodes) {
|
for (node in other.nodesInternal) {
|
||||||
nodes.add(node)
|
nodesInternal.add(node)
|
||||||
node.graph = this
|
setter.invoke(node, this as G)
|
||||||
onNodeAdded(node)
|
onNodeAdded(node)
|
||||||
|
|
||||||
|
if (node is IConditionalTickable) {
|
||||||
|
conditional.add(node)
|
||||||
|
|
||||||
|
if (!isTicking) {
|
||||||
|
isTicking = true
|
||||||
|
next.add(WeakReference(this))
|
||||||
|
}
|
||||||
|
} else if (node is ITickable) {
|
||||||
|
always.add(node)
|
||||||
|
|
||||||
|
if (!isTicking) {
|
||||||
|
isTicking = true
|
||||||
|
next.add(WeakReference(this))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
other.isMerged = true
|
||||||
|
other.onMergedInto(this as G)
|
||||||
return this
|
return this
|
||||||
} else {
|
} else {
|
||||||
return other.merge(this)
|
return other.merge(this as G, setter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun <T> discoverFull(
|
private val graphs = ArrayList<WeakReference<Abstract6Graph<*, *>>>()
|
||||||
level: ServerLevel,
|
private val next = ArrayList<WeakReference<Abstract6Graph<*, *>>>()
|
||||||
blockPos: BlockPos,
|
|
||||||
node: Graph6Node<T>,
|
fun tick() {
|
||||||
nodeGetter: (BlockEntity) -> Graph6Node<T>?,
|
if (next.isNotEmpty()) {
|
||||||
factory: () -> Abstract6Graph<T>
|
graphs.addAll(next)
|
||||||
) {
|
next.clear()
|
||||||
level.addTicker {
|
|
||||||
!discover(level, blockPos, node, nodeGetter, factory) && node.valid
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
val iterator = graphs.iterator()
|
||||||
fun <T> discover(
|
|
||||||
level: ServerLevel,
|
|
||||||
blockPos: BlockPos,
|
|
||||||
node: Graph6Node<T>,
|
|
||||||
nodeGetter: (BlockEntity) -> Graph6Node<T>?,
|
|
||||||
factory: () -> Abstract6Graph<T>
|
|
||||||
): Boolean {
|
|
||||||
var fullDiscovery = true
|
|
||||||
|
|
||||||
node.nullifyConnections()
|
for (value in iterator) {
|
||||||
|
val graph = value.get()
|
||||||
|
|
||||||
var _graph = node.graph
|
if (graph == null || !graph.tick()) {
|
||||||
|
graph?.isTicking = false
|
||||||
// для начала найдем граф к которому будем принадлежать
|
iterator.remove()
|
||||||
if (_graph == null) {
|
|
||||||
for (dir in Direction.values()) {
|
|
||||||
val offset = blockPos + dir
|
|
||||||
val chunk = level.chunkSource.getChunkNow(SectionPos.blockToSectionCoord(offset.x), SectionPos.blockToSectionCoord(offset.z))
|
|
||||||
|
|
||||||
if (chunk == null) {
|
|
||||||
fullDiscovery = false
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
val entity = chunk.getBlockEntity(offset)
|
|
||||||
|
|
||||||
if (entity != null) {
|
|
||||||
val getNode = nodeGetter(entity)
|
|
||||||
|
|
||||||
if (getNode?.graph != null) {
|
|
||||||
_graph = getNode.graph
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// мы нашли граф рядом
|
|
||||||
if (_graph != null) {
|
|
||||||
node.graph = _graph
|
|
||||||
_graph.addNode(node)
|
|
||||||
} else {
|
|
||||||
// графов рядом нет, создаем свой
|
|
||||||
_graph = factory()
|
|
||||||
node.graph = _graph
|
|
||||||
_graph.addNode(node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// теперь снова смотрим на соседей, если у них нет графа - присоединяем к своему
|
|
||||||
// если у них есть граф - слияем его со своим или свой с его
|
|
||||||
for (dir in Direction.values()) {
|
|
||||||
val offset = blockPos + dir
|
|
||||||
val chunk = level.chunkSource.getChunkNow(SectionPos.blockToSectionCoord(offset.x), SectionPos.blockToSectionCoord(offset.z))
|
|
||||||
|
|
||||||
if (chunk == null) {
|
|
||||||
fullDiscovery = false
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
val entity = chunk.getBlockEntity(offset)
|
|
||||||
|
|
||||||
if (entity != null) {
|
|
||||||
val getNode = nodeGetter(entity)
|
|
||||||
|
|
||||||
if (getNode != null) {
|
|
||||||
// у вершины нет своего графа
|
|
||||||
// добавляем в свой граф
|
|
||||||
if (getNode.graph == null) {
|
|
||||||
getNode.graph = node.graph!!
|
|
||||||
node.graph!!.addNode(getNode)
|
|
||||||
} else if (getNode.graph != node.graph) {
|
|
||||||
// у вершины уже есть свой граф, и он не наш
|
|
||||||
// произведём слияние графов
|
|
||||||
val merged = getNode.graph!!.merge(node.graph!!)
|
|
||||||
getNode.graph = merged
|
|
||||||
node.graph = merged
|
|
||||||
}
|
|
||||||
|
|
||||||
node.setToNeightbour(getNode, dir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fullDiscovery
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,313 +1,268 @@
|
|||||||
package ru.dbotthepony.mc.otm.graph
|
package ru.dbotthepony.mc.otm.graph
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import ru.dbotthepony.mc.otm.core.util.IConditionalTickable
|
import net.minecraft.core.SectionPos
|
||||||
import ru.dbotthepony.mc.otm.core.util.ITickable
|
import net.minecraft.server.level.ServerLevel
|
||||||
import ru.dbotthepony.mc.otm.SERVER_IS_LIVE
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import ru.dbotthepony.mc.otm.addTicker
|
||||||
|
import ru.dbotthepony.mc.otm.core.math.plus
|
||||||
|
import ru.dbotthepony.mc.otm.core.math.unaryMinus
|
||||||
|
import ru.dbotthepony.mc.otm.core.orNull
|
||||||
|
import java.util.EnumMap
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
|
||||||
interface GraphNodeListener {
|
open class Graph6Node<N : Graph6Node<N, G>, G : Abstract6Graph<N, G>>(val graphFactory: () -> G) {
|
||||||
fun onNeighbourTop(node: Graph6Node<*>) = onNeighbour(node, Direction.UP)
|
private val neighbours = EnumMap<Direction, N>(Direction::class.java)
|
||||||
fun onNeighbourBottom(node: Graph6Node<*>) = onNeighbour(node, Direction.DOWN)
|
|
||||||
fun onNeighbourLeft(node: Graph6Node<*>) = onNeighbour(node, Direction.WEST)
|
|
||||||
fun onNeighbourRight(node: Graph6Node<*>) = onNeighbour(node, Direction.EAST)
|
|
||||||
fun onNeighbourFront(node: Graph6Node<*>) = onNeighbour(node, Direction.SOUTH)
|
|
||||||
fun onNeighbourBack(node: Graph6Node<*>) = onNeighbour(node, Direction.NORTH)
|
|
||||||
|
|
||||||
fun onNeighbour(node: Graph6Node<*>, direction: Direction)
|
var graph: G = graphFactory.invoke()
|
||||||
|
|
||||||
fun onUnNeighbourTop(node: Graph6Node<*>) = onUnNeighbour(node, Direction.UP)
|
|
||||||
fun onUnNeighbourBottom(node: Graph6Node<*>) = onUnNeighbour(node, Direction.DOWN)
|
|
||||||
fun onUnNeighbourLeft(node: Graph6Node<*>) = onUnNeighbour(node, Direction.WEST)
|
|
||||||
fun onUnNeighbourRight(node: Graph6Node<*>) = onUnNeighbour(node, Direction.EAST)
|
|
||||||
fun onUnNeighbourFront(node: Graph6Node<*>) = onUnNeighbour(node, Direction.SOUTH)
|
|
||||||
fun onUnNeighbourBack(node: Graph6Node<*>) = onUnNeighbour(node, Direction.NORTH)
|
|
||||||
|
|
||||||
fun onUnNeighbour(node: Graph6Node<*>, direction: Direction)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Вершина графа, содержит то, к какому графу принадлежит, соседей и своё "значение"
|
|
||||||
class Graph6Node<T>(@JvmField val value: T, graph: Abstract6Graph<T>? = null) : IConditionalTickable {
|
|
||||||
var graph: Abstract6Graph<T>? = null
|
|
||||||
|
|
||||||
init {
|
|
||||||
this.graph = graph
|
|
||||||
}
|
|
||||||
|
|
||||||
var top: Graph6Node<T>? = null
|
|
||||||
set(value) {
|
|
||||||
if (value != null && (graph == null || value.graph !== graph)) throw IllegalStateException("Can not be neighbour with node from different graph")
|
|
||||||
|
|
||||||
if (field != value && this.value is GraphNodeListener) {
|
|
||||||
if (field != null) {
|
|
||||||
this.value.onUnNeighbourTop(field!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value != null) {
|
|
||||||
this.value.onNeighbourTop(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
field = value
|
|
||||||
}
|
|
||||||
|
|
||||||
var bottom: Graph6Node<T>? = null
|
|
||||||
set(value) {
|
|
||||||
if (value != null && (graph == null || value.graph !== graph)) throw IllegalStateException("Can not be neighbour with node from different graph")
|
|
||||||
|
|
||||||
if (field != value && this.value is GraphNodeListener) {
|
|
||||||
if (field != null) {
|
|
||||||
this.value.onUnNeighbourBottom(field!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value != null) {
|
|
||||||
this.value.onNeighbourBottom(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
field = value
|
|
||||||
}
|
|
||||||
|
|
||||||
var left: Graph6Node<T>? = null
|
|
||||||
set(value) {
|
|
||||||
if (value != null && (graph == null || value.graph !== graph)) throw IllegalStateException("Can not be neighbour with node from different graph")
|
|
||||||
|
|
||||||
if (field != value && this.value is GraphNodeListener) {
|
|
||||||
if (field != null) {
|
|
||||||
this.value.onUnNeighbourLeft(field!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value != null) {
|
|
||||||
this.value.onNeighbourLeft(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
field = value
|
|
||||||
}
|
|
||||||
|
|
||||||
var right: Graph6Node<T>? = null
|
|
||||||
set(value) {
|
|
||||||
if (value != null && (graph == null || value.graph !== graph)) throw IllegalStateException("Can not be neighbour with node from different graph")
|
|
||||||
|
|
||||||
if (field != value && this.value is GraphNodeListener) {
|
|
||||||
if (field != null) {
|
|
||||||
this.value.onUnNeighbourRight(field!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value != null) {
|
|
||||||
this.value.onNeighbourRight(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
field = value
|
|
||||||
}
|
|
||||||
|
|
||||||
var front: Graph6Node<T>? = null
|
|
||||||
set(value) {
|
|
||||||
if (value != null && (graph == null || value.graph !== graph)) throw IllegalStateException("Can not be neighbour with node from different graph")
|
|
||||||
|
|
||||||
if (field != value && this.value is GraphNodeListener) {
|
|
||||||
if (field != null) {
|
|
||||||
this.value.onUnNeighbourFront(field!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value != null) {
|
|
||||||
this.value.onNeighbourFront(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
field = value
|
|
||||||
}
|
|
||||||
|
|
||||||
var back: Graph6Node<T>? = null
|
|
||||||
set(value) {
|
|
||||||
if (value != null && (graph == null || value.graph !== graph)) throw IllegalStateException("Can not be neighbour with node from different graph")
|
|
||||||
|
|
||||||
if (field != value && this.value is GraphNodeListener) {
|
|
||||||
if (field != null) {
|
|
||||||
this.value.onUnNeighbourBack(field!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value != null) {
|
|
||||||
this.value.onNeighbourBack(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
field = value
|
|
||||||
}
|
|
||||||
|
|
||||||
fun nullifyConnections() {
|
|
||||||
top?.bottom = null
|
|
||||||
bottom?.top = null
|
|
||||||
left?.right = null
|
|
||||||
right?.left = null
|
|
||||||
front?.back = null
|
|
||||||
back?.front = null
|
|
||||||
|
|
||||||
top = null
|
|
||||||
bottom = null
|
|
||||||
left = null
|
|
||||||
right = null
|
|
||||||
front = null
|
|
||||||
back = null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setToNeightbour(node: Graph6Node<T>, direction: Direction) {
|
|
||||||
when (direction) {
|
|
||||||
Direction.DOWN -> {
|
|
||||||
node.top = this
|
|
||||||
bottom = node
|
|
||||||
}
|
|
||||||
|
|
||||||
Direction.UP -> {
|
|
||||||
node.bottom = this
|
|
||||||
top = node
|
|
||||||
}
|
|
||||||
|
|
||||||
Direction.NORTH -> {
|
|
||||||
node.front = this
|
|
||||||
back = node
|
|
||||||
}
|
|
||||||
|
|
||||||
Direction.SOUTH -> {
|
|
||||||
node.back = this
|
|
||||||
front = node
|
|
||||||
}
|
|
||||||
|
|
||||||
Direction.WEST -> {
|
|
||||||
node.right = this
|
|
||||||
left = node
|
|
||||||
}
|
|
||||||
|
|
||||||
Direction.EAST -> {
|
|
||||||
node.left = this
|
|
||||||
right = node
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun tick(): Boolean {
|
|
||||||
if (value is IConditionalTickable) {
|
|
||||||
return value.tick()
|
|
||||||
} else if (value is ITickable) {
|
|
||||||
value.tick()
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var seen: Int = 0
|
|
||||||
|
|
||||||
private fun _flood(): List<GraphFlooder<T>> {
|
|
||||||
val list = ArrayList<GraphFlooder<T>>()
|
|
||||||
var seen = Int.MAX_VALUE
|
|
||||||
|
|
||||||
GraphFlooder.floodIf(top, seen) {
|
|
||||||
seen = it.seen
|
|
||||||
list.add(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
GraphFlooder.floodIf(bottom, seen) {
|
|
||||||
seen = it.seen
|
|
||||||
list.add(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
GraphFlooder.floodIf(left, seen) {
|
|
||||||
seen = it.seen
|
|
||||||
list.add(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
GraphFlooder.floodIf(right, seen) {
|
|
||||||
seen = it.seen
|
|
||||||
list.add(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
GraphFlooder.floodIf(front, seen) {
|
|
||||||
seen = it.seen
|
|
||||||
list.add(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
GraphFlooder.floodIf(back, seen) {
|
|
||||||
seen = it.seen
|
|
||||||
list.add(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
fun flood(): List<GraphFlooder<T>> {
|
|
||||||
top?.bottom = null
|
|
||||||
bottom?.top = null
|
|
||||||
left?.right = null
|
|
||||||
right?.left = null
|
|
||||||
front?.back = null
|
|
||||||
back?.front = null
|
|
||||||
|
|
||||||
val list = _flood()
|
|
||||||
|
|
||||||
top?.bottom = this
|
|
||||||
bottom?.top = this
|
|
||||||
left?.right = this
|
|
||||||
right?.left = this
|
|
||||||
front?.back = this
|
|
||||||
back?.front = this
|
|
||||||
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
var valid = true
|
|
||||||
private set
|
private set
|
||||||
|
|
||||||
fun destroy(factory: () -> Abstract6Graph<T>): List<GraphFlooder<T>> {
|
init {
|
||||||
if (!valid || !SERVER_IS_LIVE) return emptyList()
|
graph.addNode(this as N)
|
||||||
|
|
||||||
top?.bottom = null
|
|
||||||
bottom?.top = null
|
|
||||||
left?.right = null
|
|
||||||
right?.left = null
|
|
||||||
front?.back = null
|
|
||||||
back?.front = null
|
|
||||||
|
|
||||||
graph?.removeNode(this)
|
|
||||||
|
|
||||||
var num = 0
|
|
||||||
|
|
||||||
if (top != null) num++
|
|
||||||
if (bottom != null) num++
|
|
||||||
if (left != null) num++
|
|
||||||
if (right != null) num++
|
|
||||||
if (front != null) num++
|
|
||||||
if (back != null) num++
|
|
||||||
|
|
||||||
if (num < 2) {
|
|
||||||
return emptyList()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val paths = _flood()
|
private var seen: Int = 0
|
||||||
|
|
||||||
if (paths.size < 2) {
|
operator fun get(direction: Direction): N? = neighbours[direction]
|
||||||
return paths
|
|
||||||
|
operator fun set(direction: Direction, node: N?) {
|
||||||
|
set(direction, node, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
var biggest = paths[0]
|
fun set(direction: Direction, node: N?, allowReplacement: Boolean) {
|
||||||
|
check(isValid) { "Can not neighbour any node while this node is invalid" }
|
||||||
|
|
||||||
for (i in 1 until paths.size) {
|
val old = neighbours[direction]
|
||||||
if (biggest.size() < paths[i].size()) {
|
if (old === node) return
|
||||||
biggest = paths[i]
|
|
||||||
|
if (old != null)
|
||||||
|
breakConnection(this as N, old, direction)
|
||||||
|
|
||||||
|
if (node != null) {
|
||||||
|
require(node.isValid) { "Can not neighbour invalid node" }
|
||||||
|
|
||||||
|
val opposite = -direction
|
||||||
|
|
||||||
|
if (allowReplacement) {
|
||||||
|
node.neighbours[opposite]?.let {
|
||||||
|
breakConnection(node, it, opposite)
|
||||||
|
}
|
||||||
|
|
||||||
|
check(node.neighbours[opposite] == null) { "$node didn't break connection at direction $opposite" }
|
||||||
|
} else {
|
||||||
|
check(node.neighbours[opposite] == null) { "Trying to form connection from $this to $node at direction $direction, but $node already has neighbour at $opposite (${node.neighbours[opposite]})!" }
|
||||||
|
}
|
||||||
|
|
||||||
|
node.neighbours[opposite] = this as N
|
||||||
|
neighbours[direction] = node
|
||||||
|
node.graph.merge(graph, setter)
|
||||||
|
node.onNeighbour(opposite)
|
||||||
|
onNeighbour(direction)
|
||||||
|
} else {
|
||||||
|
neighbours.remove(direction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (flooder in paths) {
|
var top: N?
|
||||||
if (flooder == biggest) continue
|
get() = neighbours[Direction.UP]
|
||||||
|
set(value) {
|
||||||
|
set(Direction.UP, value)
|
||||||
|
}
|
||||||
|
|
||||||
val graph = factory()
|
var bottom: N?
|
||||||
|
get() = neighbours[Direction.DOWN]
|
||||||
|
set(value) {
|
||||||
|
set(Direction.DOWN, value)
|
||||||
|
}
|
||||||
|
|
||||||
for (node in flooder.nodes) {
|
var south: N?
|
||||||
node.graph?.removeNode(node)
|
get() = neighbours[Direction.SOUTH]
|
||||||
graph.addNode(node)
|
set(value) {
|
||||||
|
set(Direction.SOUTH, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
var north: N?
|
||||||
|
get() = neighbours[Direction.NORTH]
|
||||||
|
set(value) {
|
||||||
|
set(Direction.NORTH, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
var west: N?
|
||||||
|
get() = neighbours[Direction.WEST]
|
||||||
|
set(value) {
|
||||||
|
set(Direction.WEST, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
var east: N?
|
||||||
|
get() = neighbours[Direction.EAST]
|
||||||
|
set(value) {
|
||||||
|
set(Direction.EAST, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun onNeighbour(direction: Direction) {}
|
||||||
|
open fun onUnNeighbour(direction: Direction) {}
|
||||||
|
|
||||||
|
protected open fun invalidate() {}
|
||||||
|
protected open fun revive() {}
|
||||||
|
|
||||||
|
var isValid: Boolean = true
|
||||||
|
set(value) {
|
||||||
|
if (value == field) return
|
||||||
|
field = value
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
val neighbours = ArrayList(neighbours.entries)
|
||||||
|
|
||||||
|
for ((dir, node) in neighbours) {
|
||||||
|
breakConnection(this as N, node, dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
graph.removeNode(this as N)
|
||||||
|
invalidate()
|
||||||
|
} else {
|
||||||
|
revive()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return paths
|
fun discover(
|
||||||
|
level: ServerLevel,
|
||||||
|
blockPos: BlockPos,
|
||||||
|
nodeGetter: (BlockEntity) -> N?
|
||||||
|
) {
|
||||||
|
if (!isValid) return
|
||||||
|
|
||||||
|
level.addTicker {
|
||||||
|
isValid && !discoverStep(level, blockPos, nodeGetter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun discover(
|
||||||
|
level: ServerLevel,
|
||||||
|
blockPos: BlockPos,
|
||||||
|
capability: Capability<out N>
|
||||||
|
) {
|
||||||
|
if (!isValid) return
|
||||||
|
|
||||||
|
level.addTicker {
|
||||||
|
isValid && !discoverStep(level, blockPos) { it.getCapability(capability).orNull() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun discover(blockEntity: BlockEntity, nodeGetter: (BlockEntity) -> N?) {
|
||||||
|
discover(blockEntity.level as? ServerLevel ?: return, blockEntity.blockPos, nodeGetter)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun discover(blockEntity: BlockEntity, capability: Capability<out N>) {
|
||||||
|
discover(blockEntity.level as? ServerLevel ?: return, blockEntity.blockPos, capability)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun discoverStep(
|
||||||
|
level: ServerLevel,
|
||||||
|
blockPos: BlockPos,
|
||||||
|
nodeGetter: (BlockEntity) -> N?,
|
||||||
|
): Boolean {
|
||||||
|
if (!isValid) return false
|
||||||
|
var fullDiscovery = true
|
||||||
|
|
||||||
|
for (dir in directions) {
|
||||||
|
val offset = blockPos + dir
|
||||||
|
val chunk = level.chunkSource.getChunkNow(SectionPos.blockToSectionCoord(offset.x), SectionPos.blockToSectionCoord(offset.z))
|
||||||
|
|
||||||
|
if (chunk == null) {
|
||||||
|
fullDiscovery = false
|
||||||
|
set(dir, null)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val entity = chunk.getBlockEntity(offset)
|
||||||
|
|
||||||
|
if (entity != null) {
|
||||||
|
set(dir, nodeGetter(entity))
|
||||||
|
} else {
|
||||||
|
set(dir, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullDiscovery
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val setter = Graph6Node<*, *>::graph::set
|
||||||
|
private val nextSeen = AtomicInteger()
|
||||||
|
private val directions = Direction.values()
|
||||||
|
|
||||||
|
private fun <N : Graph6Node<N, G>, G : Abstract6Graph<N, G>> breakConnection(a: N, b: N, direction: Direction) {
|
||||||
|
val opposite = -direction
|
||||||
|
|
||||||
|
require(a.neighbours[direction] === b) { "$a does not neighbour with $b at direction $direction (forward)" }
|
||||||
|
require(b.neighbours[opposite] === a) { "$b does not neighbour with $a at direction $opposite (backward)" }
|
||||||
|
require(a.graph === b.graph) { "$a and $b belong to different graphs (${a.graph} vs ${b.graph})" }
|
||||||
|
|
||||||
|
a.neighbours.remove(direction)
|
||||||
|
b.neighbours.remove(opposite)
|
||||||
|
|
||||||
|
val seen = nextSeen.incrementAndGet()
|
||||||
|
val flood1 = flood(a, seen)
|
||||||
|
|
||||||
|
if (b.seen != seen) {
|
||||||
|
val flood2 = flood(b, seen)
|
||||||
|
|
||||||
|
val big: ArrayList<N>
|
||||||
|
val small: ArrayList<N>
|
||||||
|
|
||||||
|
if (flood1.size >= flood2.size) {
|
||||||
|
big = flood1
|
||||||
|
small = flood2
|
||||||
|
} else {
|
||||||
|
big = flood2
|
||||||
|
small = flood1
|
||||||
|
}
|
||||||
|
|
||||||
|
a.graph.retain(ReferenceOpenHashSet(big))
|
||||||
|
val newGraph = a.graphFactory.invoke()
|
||||||
|
|
||||||
|
for (node in small) {
|
||||||
|
node.graph = newGraph
|
||||||
|
}
|
||||||
|
|
||||||
|
for (node in small) {
|
||||||
|
if (node.isValid) {
|
||||||
|
newGraph.addNode(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.isValid)
|
||||||
|
a.onUnNeighbour(direction)
|
||||||
|
|
||||||
|
if (b.isValid)
|
||||||
|
b.onUnNeighbour(opposite)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <N : Graph6Node<N, G>, G : Abstract6Graph<N, G>> flood(startingNode: N, seen: Int): ArrayList<N> {
|
||||||
|
val unopen = ArrayList<N>()
|
||||||
|
val result = ArrayList<N>()
|
||||||
|
unopen.add(startingNode)
|
||||||
|
|
||||||
|
while (unopen.isNotEmpty()) {
|
||||||
|
val last = unopen.removeLast()
|
||||||
|
|
||||||
|
if (last.seen < seen) {
|
||||||
|
result.add(last)
|
||||||
|
last.seen = seen
|
||||||
|
|
||||||
|
for (node in last.neighbours.values) {
|
||||||
|
if (node.seen < seen) {
|
||||||
|
unopen.add(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.graph
|
|
||||||
|
|
||||||
import java.util.*
|
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
|
|
||||||
class GraphFlooder<T>(val startNode: Graph6Node<T>, @JvmField val seen: Int = nextSeen++) {
|
|
||||||
var flooded = false
|
|
||||||
private set
|
|
||||||
|
|
||||||
private val _nodes = ArrayList<Graph6Node<T>>()
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
val nodes = Collections.unmodifiableCollection(_nodes)!!
|
|
||||||
|
|
||||||
fun size() = _nodes.size
|
|
||||||
|
|
||||||
private fun flood(node: Graph6Node<T>) {
|
|
||||||
if (node.seen >= seen) return
|
|
||||||
|
|
||||||
_nodes.add(node)
|
|
||||||
node.seen = seen
|
|
||||||
|
|
||||||
if (node.top != null) flood(node.top!!)
|
|
||||||
if (node.bottom != null) flood(node.bottom!!)
|
|
||||||
if (node.left != null) flood(node.left!!)
|
|
||||||
if (node.right != null) flood(node.right!!)
|
|
||||||
if (node.front != null) flood(node.front!!)
|
|
||||||
if (node.back != null) flood(node.back!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun flood() {
|
|
||||||
if (flooded) throw IllegalStateException("Already flooded")
|
|
||||||
|
|
||||||
flooded = true
|
|
||||||
|
|
||||||
_nodes.add(startNode)
|
|
||||||
startNode.seen = seen
|
|
||||||
|
|
||||||
if (startNode.top != null) flood(startNode.top!!)
|
|
||||||
if (startNode.bottom != null) flood(startNode.bottom!!)
|
|
||||||
if (startNode.left != null) flood(startNode.left!!)
|
|
||||||
if (startNode.right != null) flood(startNode.right!!)
|
|
||||||
if (startNode.front != null) flood(startNode.front!!)
|
|
||||||
if (startNode.back != null) flood(startNode.back!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private var nextSeen = 0
|
|
||||||
|
|
||||||
fun <T> floodIf(node: Graph6Node<T>?, seen: Int, runnable: (GraphFlooder<T>) -> Unit) {
|
|
||||||
if (node != null && node.seen < seen) {
|
|
||||||
if (seen == Int.MAX_VALUE) {
|
|
||||||
val flooder = GraphFlooder(node)
|
|
||||||
flooder.flood()
|
|
||||||
runnable(flooder)
|
|
||||||
} else {
|
|
||||||
val flooder = GraphFlooder(node, seen)
|
|
||||||
flooder.flood()
|
|
||||||
runnable(flooder)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
package ru.dbotthepony.mc.otm.graph.matter
|
package ru.dbotthepony.mc.otm.graph.matter
|
||||||
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.*
|
import ru.dbotthepony.mc.otm.capability.matter.*
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
|
||||||
|
|
||||||
interface IMatterGraphListener {
|
interface IMatterGraphListener {
|
||||||
fun onPatternAdded(state: IPatternState) {}
|
fun onPatternAdded(state: IPatternState) {}
|
||||||
@ -13,12 +12,3 @@ interface IMatterGraphListener {
|
|||||||
fun onMatterTaskFinished(state: IReplicationTask<*>) {}
|
fun onMatterTaskFinished(state: IReplicationTask<*>) {}
|
||||||
fun onMatterTaskRemoved(state: IReplicationTask<*>) {}
|
fun onMatterTaskRemoved(state: IReplicationTask<*>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IMatterGraphNode : IMatterGraphListener {
|
|
||||||
fun getMatterHandler(): IMatterStorage? = null
|
|
||||||
fun getPatternHandler(): IPatternStorage? = null
|
|
||||||
fun getTaskHandler(): IReplicationTaskProvider? = null
|
|
||||||
|
|
||||||
val matterNode: Graph6Node<IMatterGraphNode>
|
|
||||||
val matterGraph: MatterNetworkGraph? get() = matterNode.graph as MatterNetworkGraph?
|
|
||||||
}
|
|
@ -1,30 +1,25 @@
|
|||||||
package ru.dbotthepony.mc.otm.graph.matter
|
package ru.dbotthepony.mc.otm.graph.matter
|
||||||
|
|
||||||
import com.google.common.collect.Streams
|
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.world.item.Item
|
import net.minecraft.world.item.Item
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity
|
|
||||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.*
|
import ru.dbotthepony.mc.otm.capability.matter.*
|
||||||
import ru.dbotthepony.mc.otm.core.filterNotNull
|
import ru.dbotthepony.mc.otm.core.filterNotNull
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.graph.Abstract6Graph
|
import ru.dbotthepony.mc.otm.graph.Abstract6Graph
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.function.Predicate
|
import java.util.function.Predicate
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
import kotlin.collections.HashSet
|
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListener {
|
class MatterGraph : Abstract6Graph<MatterNode, MatterGraph>(), IMatterGraphListener {
|
||||||
private val listeners = HashSet<IMatterGraphListener>()
|
private val listeners = ObjectOpenHashSet<IMatterGraphListener>()
|
||||||
|
|
||||||
fun addListener(listener: IMatterGraphListener) = listeners.add(listener)
|
fun addListener(listener: IMatterGraphListener) = listeners.add(listener)
|
||||||
fun removeListener(listener: IMatterGraphListener) = listeners.remove(listener)
|
fun removeListener(listener: IMatterGraphListener) = listeners.remove(listener)
|
||||||
|
|
||||||
override fun onNodeRemoved(node: Graph6Node<IMatterGraphNode>) {
|
override fun onNodeRemoved(node: MatterNode) {
|
||||||
val patterns = node.value.getPatternHandler()
|
val patterns = node.getPatternHandler()
|
||||||
|
|
||||||
if (patterns != null) {
|
if (patterns != null) {
|
||||||
for (pattern in patterns.patterns) {
|
for (pattern in patterns.patterns) {
|
||||||
@ -32,7 +27,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val tasks = node.value.getTaskHandler()
|
val tasks = node.getTaskHandler()
|
||||||
|
|
||||||
if (tasks != null) {
|
if (tasks != null) {
|
||||||
for (task in tasks.replicationTasks) {
|
for (task in tasks.replicationTasks) {
|
||||||
@ -41,24 +36,24 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (pattern in this.patterns) {
|
for (pattern in this.patterns) {
|
||||||
node.value.onPatternRemoved(pattern)
|
node.onPatternRemoved(pattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (task in this.tasks) {
|
for (task in this.tasks) {
|
||||||
node.value.onMatterTaskRemoved(task)
|
node.onMatterTaskRemoved(task)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNodeAdded(node: Graph6Node<IMatterGraphNode>) {
|
override fun onNodeAdded(node: MatterNode) {
|
||||||
for (pattern in this.patterns) {
|
for (pattern in this.patterns) {
|
||||||
node.value.onPatternAdded(pattern)
|
node.onPatternAdded(pattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (task in this.tasks) {
|
for (task in this.tasks) {
|
||||||
node.value.onMatterTaskCreated(task)
|
node.onMatterTaskCreated(task)
|
||||||
}
|
}
|
||||||
|
|
||||||
val patterns = node.value.getPatternHandler()
|
val patterns = node.getPatternHandler()
|
||||||
|
|
||||||
if (patterns != null) {
|
if (patterns != null) {
|
||||||
for (pattern in patterns.patterns) {
|
for (pattern in patterns.patterns) {
|
||||||
@ -66,7 +61,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val tasks = node.value.getTaskHandler()
|
val tasks = node.getTaskHandler()
|
||||||
|
|
||||||
if (tasks != null) {
|
if (tasks != null) {
|
||||||
for (task in tasks.replicationTasks) {
|
for (task in tasks.replicationTasks) {
|
||||||
@ -79,7 +74,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
var level = Decimal.ZERO
|
var level = Decimal.ZERO
|
||||||
|
|
||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
val matter = node.value.getMatterHandler()
|
val matter = node.getMatterHandler()
|
||||||
|
|
||||||
if (matter != null && matter.matterFlow == FlowDirection.BI_DIRECTIONAL) {
|
if (matter != null && matter.matterFlow == FlowDirection.BI_DIRECTIONAL) {
|
||||||
level += matter.storedMatter
|
level += matter.storedMatter
|
||||||
@ -93,7 +88,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
var level = Decimal.ZERO
|
var level = Decimal.ZERO
|
||||||
|
|
||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
val matter = node.value.getMatterHandler()
|
val matter = node.getMatterHandler()
|
||||||
|
|
||||||
if (matter != null && matter.matterFlow == FlowDirection.BI_DIRECTIONAL) {
|
if (matter != null && matter.matterFlow == FlowDirection.BI_DIRECTIONAL) {
|
||||||
level += matter.maxStoredMatter
|
level += matter.maxStoredMatter
|
||||||
@ -112,7 +107,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
var extracted = Decimal.ZERO
|
var extracted = Decimal.ZERO
|
||||||
|
|
||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
val matter = node.value.getMatterHandler()
|
val matter = node.getMatterHandler()
|
||||||
|
|
||||||
if (matter != null) {
|
if (matter != null) {
|
||||||
val value = matter.extractMatter(howMuch, simulate)
|
val value = matter.extractMatter(howMuch, simulate)
|
||||||
@ -136,7 +131,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
var received = Decimal.ZERO
|
var received = Decimal.ZERO
|
||||||
|
|
||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
val matter = node.value.getMatterHandler()
|
val matter = node.getMatterHandler()
|
||||||
|
|
||||||
if (matter != null && matter.matterFlow == FlowDirection.BI_DIRECTIONAL) {
|
if (matter != null && matter.matterFlow == FlowDirection.BI_DIRECTIONAL) {
|
||||||
val value = matter.receiveMatter(howMuch, simulate)
|
val value = matter.receiveMatter(howMuch, simulate)
|
||||||
@ -160,7 +155,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
var received = Decimal.ZERO
|
var received = Decimal.ZERO
|
||||||
|
|
||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
val matter = node.value.getMatterHandler()
|
val matter = node.getMatterHandler()
|
||||||
|
|
||||||
if (matter != null && matter.matterFlow != FlowDirection.OUTPUT) {
|
if (matter != null && matter.matterFlow != FlowDirection.OUTPUT) {
|
||||||
val value = matter.receiveMatter(howMuch, simulate)
|
val value = matter.receiveMatter(howMuch, simulate)
|
||||||
@ -177,7 +172,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
|
|
||||||
private fun doInsertPattern(state: IPatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus {
|
private fun doInsertPattern(state: IPatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus {
|
||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
val storage = node.value.getPatternHandler()
|
val storage = node.getPatternHandler()
|
||||||
|
|
||||||
if (storage != null) {
|
if (storage != null) {
|
||||||
val status = storage.insertPattern(state, onlyUpdate, simulate)
|
val status = storage.insertPattern(state, onlyUpdate, simulate)
|
||||||
@ -198,23 +193,23 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
return doInsertPattern(state, false, simulate)
|
return doInsertPattern(state, false, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
val tasks: Stream<out IReplicationTask<*>> get() {
|
val tasks: Stream<IReplicationTask<*>> get() {
|
||||||
return Streams.concat(*nodes.mapNotNull { it.value.getTaskHandler()?.replicationTasks }.toTypedArray())
|
return nodes.stream().map { it.getTaskHandler()?.replicationTasks }.filterNotNull().flatMap { it }
|
||||||
}
|
}
|
||||||
|
|
||||||
val allTasks: Stream<out IReplicationTask<*>> get() {
|
val allTasks: Stream<IReplicationTask<*>> get() {
|
||||||
return Streams.concat(*nodes.mapNotNull { it.value.getTaskHandler()?.allReplicationTasks }.toTypedArray())
|
return nodes.stream().map { it.getTaskHandler()?.allReplicationTasks }.filterNotNull().flatMap { it }
|
||||||
}
|
}
|
||||||
|
|
||||||
val patterns: Stream<out IPatternState> get() {
|
val patterns: Stream<IPatternState> get() {
|
||||||
return nodes.stream().map { it.value.getPatternHandler()?.patterns }.filterNotNull().flatMap { it }
|
return nodes.stream().map { it.getPatternHandler()?.patterns }.filterNotNull().flatMap { it }
|
||||||
}
|
}
|
||||||
|
|
||||||
val patternCount: Long get() {
|
val patternCount: Long get() {
|
||||||
var value = 0L
|
var value = 0L
|
||||||
|
|
||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
val storage = node.value.getPatternHandler()
|
val storage = node.getPatternHandler()
|
||||||
|
|
||||||
if (storage != null) {
|
if (storage != null) {
|
||||||
value += storage.storedPatterns
|
value += storage.storedPatterns
|
||||||
@ -228,7 +223,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
var value = 0L
|
var value = 0L
|
||||||
|
|
||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
val storage = node.value.getPatternHandler()
|
val storage = node.getPatternHandler()
|
||||||
|
|
||||||
if (storage != null) {
|
if (storage != null) {
|
||||||
value += storage.patternCapacity
|
value += storage.patternCapacity
|
||||||
@ -240,7 +235,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
|
|
||||||
fun getPattern(id: UUID): IPatternState? {
|
fun getPattern(id: UUID): IPatternState? {
|
||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
val storage = node.value.getPatternHandler()
|
val storage = node.getPatternHandler()
|
||||||
|
|
||||||
if (storage != null) {
|
if (storage != null) {
|
||||||
val get = storage.getPattern(id)
|
val get = storage.getPattern(id)
|
||||||
@ -260,7 +255,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
|
|
||||||
fun findPattern(predicate: Predicate<IPatternState>): IPatternState? {
|
fun findPattern(predicate: Predicate<IPatternState>): IPatternState? {
|
||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
val storage = node.value.getPatternHandler()
|
val storage = node.getPatternHandler()
|
||||||
|
|
||||||
if (storage != null) {
|
if (storage != null) {
|
||||||
val find = storage.patterns.filter(predicate).findAny()
|
val find = storage.patterns.filter(predicate).findAny()
|
||||||
@ -284,7 +279,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
|
|
||||||
fun allocateTask(simulate: Boolean): ReplicationTaskAllocation? {
|
fun allocateTask(simulate: Boolean): ReplicationTaskAllocation? {
|
||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
val tasks = node.value.getTaskHandler()
|
val tasks = node.getTaskHandler()
|
||||||
|
|
||||||
if (tasks != null) {
|
if (tasks != null) {
|
||||||
val allocated = tasks.allocateTask(simulate)
|
val allocated = tasks.allocateTask(simulate)
|
||||||
@ -299,87 +294,41 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun notifyTaskCompletion(taskId: UUID): Boolean {
|
fun notifyTaskCompletion(taskId: UUID): Boolean {
|
||||||
return nodes.any { it.value.getTaskHandler()?.notifyTaskCompletion(taskId) == true }
|
return nodes.any { it.getTaskHandler()?.notifyTaskCompletion(taskId) == true }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPatternAdded(state: IPatternState) {
|
override fun onPatternAdded(state: IPatternState) {
|
||||||
for (node in nodes) node.value.onPatternAdded(state)
|
for (node in nodes) node.onPatternAdded(state)
|
||||||
for (node in listeners) node.onPatternAdded(state)
|
for (node in listeners) node.onPatternAdded(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPatternRemoved(state: IPatternState) {
|
override fun onPatternRemoved(state: IPatternState) {
|
||||||
for (node in nodes) node.value.onPatternRemoved(state)
|
for (node in nodes) node.onPatternRemoved(state)
|
||||||
for (node in listeners) node.onPatternRemoved(state)
|
for (node in listeners) node.onPatternRemoved(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPatternUpdated(newState: IPatternState, oldState: IPatternState) {
|
override fun onPatternUpdated(newState: IPatternState, oldState: IPatternState) {
|
||||||
for (node in nodes) node.value.onPatternUpdated(newState, oldState)
|
for (node in nodes) node.onPatternUpdated(newState, oldState)
|
||||||
for (node in listeners) node.onPatternUpdated(newState, oldState)
|
for (node in listeners) node.onPatternUpdated(newState, oldState)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMatterTaskCreated(task: IReplicationTask<*>) {
|
override fun onMatterTaskCreated(task: IReplicationTask<*>) {
|
||||||
for (node in nodes) node.value.onMatterTaskCreated(task)
|
for (node in nodes) node.onMatterTaskCreated(task)
|
||||||
for (node in listeners) node.onMatterTaskCreated(task)
|
for (node in listeners) node.onMatterTaskCreated(task)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <T : IReplicationTask<*>> onMatterTaskUpdated(newState: T, oldState: T) {
|
override fun <T : IReplicationTask<*>> onMatterTaskUpdated(newState: T, oldState: T) {
|
||||||
for (node in nodes) node.value.onMatterTaskUpdated(newState, oldState)
|
for (node in nodes) node.onMatterTaskUpdated(newState, oldState)
|
||||||
for (node in listeners) node.onMatterTaskUpdated(newState, oldState)
|
for (node in listeners) node.onMatterTaskUpdated(newState, oldState)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMatterTaskFinished(state: IReplicationTask<*>) {
|
override fun onMatterTaskFinished(state: IReplicationTask<*>) {
|
||||||
for (node in nodes) node.value.onMatterTaskFinished(state)
|
for (node in nodes) node.onMatterTaskFinished(state)
|
||||||
for (node in listeners) node.onMatterTaskFinished(state)
|
for (node in listeners) node.onMatterTaskFinished(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMatterTaskRemoved(state: IReplicationTask<*>) {
|
override fun onMatterTaskRemoved(state: IReplicationTask<*>) {
|
||||||
for (node in nodes) node.value.onMatterTaskRemoved(state)
|
for (node in nodes) node.onMatterTaskRemoved(state)
|
||||||
for (node in listeners) node.onMatterTaskRemoved(state)
|
for (node in listeners) node.onMatterTaskRemoved(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
@JvmStatic
|
|
||||||
fun discoverFull(tile: BlockEntity, node: Graph6Node<IMatterGraphNode>) {
|
|
||||||
if (tile.level !is ServerLevel)
|
|
||||||
return
|
|
||||||
|
|
||||||
return discoverFull(
|
|
||||||
tile.level!! as ServerLevel,
|
|
||||||
tile.blockPos,
|
|
||||||
node,
|
|
||||||
fun(_tile): Graph6Node<IMatterGraphNode>? {
|
|
||||||
val resolve = _tile.getCapability(MatteryCapability.MATTER_NODE)
|
|
||||||
|
|
||||||
return if (resolve.isPresent) {
|
|
||||||
resolve.resolve().get().matterNode
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
::MatterNetworkGraph
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun discover(tile: BlockEntity, node: Graph6Node<IMatterGraphNode>): Boolean {
|
|
||||||
if (tile.level !is ServerLevel)
|
|
||||||
return false
|
|
||||||
|
|
||||||
return discover(
|
|
||||||
tile.level!! as ServerLevel,
|
|
||||||
tile.blockPos,
|
|
||||||
node,
|
|
||||||
fun(_tile): Graph6Node<IMatterGraphNode>? {
|
|
||||||
val resolve = _tile.getCapability(MatteryCapability.MATTER_NODE)
|
|
||||||
|
|
||||||
return if (resolve.isPresent) {
|
|
||||||
resolve.resolve().get().matterNode
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
::MatterNetworkGraph
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.graph.matter
|
||||||
|
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterStorage
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.IReplicationTaskProvider
|
||||||
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
|
|
||||||
|
open class MatterNode : Graph6Node<MatterNode, MatterGraph>(::MatterGraph), IMatterGraphListener {
|
||||||
|
open fun getMatterHandler(): IMatterStorage? = null
|
||||||
|
open fun getPatternHandler(): IPatternStorage? = null
|
||||||
|
open fun getTaskHandler(): IReplicationTaskProvider? = null
|
||||||
|
|
||||||
|
fun discover(blockEntity: BlockEntity) {
|
||||||
|
discover(blockEntity, MatteryCapability.MATTER_NODE)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.graph.matter
|
||||||
|
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterStorage
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.IReplicationTaskProvider
|
||||||
|
|
||||||
|
open class SimpleMatterNode(
|
||||||
|
private val matter: IMatterStorage? = null,
|
||||||
|
private val patterns: IPatternStorage? = null,
|
||||||
|
private val tasks: IReplicationTaskProvider? = null,
|
||||||
|
) : MatterNode() {
|
||||||
|
override fun getMatterHandler(): IMatterStorage? {
|
||||||
|
return matter
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPatternHandler(): IPatternStorage? {
|
||||||
|
return patterns
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTaskHandler(): IReplicationTaskProvider? {
|
||||||
|
return tasks
|
||||||
|
}
|
||||||
|
}
|
@ -1,22 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.graph.storage
|
|
||||||
|
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
|
||||||
import ru.dbotthepony.mc.otm.storage.IStorage
|
|
||||||
|
|
||||||
interface IStorageGraphNode {
|
|
||||||
/**
|
|
||||||
* Called by storage graph on node being attached to it
|
|
||||||
*/
|
|
||||||
fun attachComponents(to: StorageNetworkGraph)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called by storage graph on node being detached from it
|
|
||||||
*
|
|
||||||
* This is NOT called when graph is being destroyed (e.g. even by merging
|
|
||||||
* with another graph).
|
|
||||||
*/
|
|
||||||
fun removeComponents(from: StorageNetworkGraph)
|
|
||||||
|
|
||||||
val storageNode: Graph6Node<IStorageGraphNode>
|
|
||||||
val storageGraph: StorageNetworkGraph? get() = storageNode.graph as StorageNetworkGraph?
|
|
||||||
}
|
|
@ -14,8 +14,9 @@ import ru.dbotthepony.mc.otm.core.orNull
|
|||||||
import ru.dbotthepony.mc.otm.storage.*
|
import ru.dbotthepony.mc.otm.storage.*
|
||||||
import java.util.LinkedList
|
import java.util.LinkedList
|
||||||
|
|
||||||
class StorageNetworkGraph(private val level: Level) : Abstract6Graph<IStorageGraphNode>() {
|
class StorageGraph : Abstract6Graph<StorageNode, StorageGraph>() {
|
||||||
private val virtualComponents = Object2ObjectArrayMap<StorageStackType<*>, VirtualComponent<*>>()
|
private val virtualComponents = Object2ObjectArrayMap<StorageStackType<*>, VirtualComponent<*>>()
|
||||||
|
val powerDemandingNodes = LinkedList<IMatteryEnergyStorage>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a [VirtualComponent] representing [type] storage
|
* Returns a [VirtualComponent] representing [type] storage
|
||||||
@ -31,8 +32,6 @@ class StorageNetworkGraph(private val level: Level) : Abstract6Graph<IStorageGra
|
|||||||
return virtualComponents.computeIfAbsent(StorageRegistry.get(type), Object2ObjectFunction { VirtualComponent(type) }) as VirtualComponent<T>
|
return virtualComponents.computeIfAbsent(StorageRegistry.get(type), Object2ObjectFunction { VirtualComponent(type) }) as VirtualComponent<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
private var addedTicker = false
|
|
||||||
|
|
||||||
fun <T : IStorageStack> add(storage: IStorage<T>) {
|
fun <T : IStorageStack> add(storage: IStorage<T>) {
|
||||||
getVirtualComponent(storage.storageType).add(storage)
|
getVirtualComponent(storage.storageType).add(storage)
|
||||||
}
|
}
|
||||||
@ -46,50 +45,12 @@ class StorageNetworkGraph(private val level: Level) : Abstract6Graph<IStorageGra
|
|||||||
return (virtual as VirtualComponent<T>).contains(storage)
|
return (virtual as VirtualComponent<T>).contains(storage)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNodeAdded(node: Graph6Node<IStorageGraphNode>) {
|
override fun onNodeAdded(node: StorageNode) {
|
||||||
node.value.attachComponents(this)
|
node.attachComponents(this)
|
||||||
|
|
||||||
if (!addedTicker) {
|
|
||||||
addedTicker = true
|
|
||||||
level.addTickerPre(this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNodeRemoved(node: Graph6Node<IStorageGraphNode>) {
|
override fun onNodeRemoved(node: StorageNode) {
|
||||||
node.value.removeComponents(this)
|
node.removeComponents(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
val powerDemandingNodes = LinkedList<IMatteryEnergyStorage>()
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@JvmStatic
|
|
||||||
fun discoverFull(tile: BlockEntity, node: Graph6Node<IStorageGraphNode>) {
|
|
||||||
if (tile.level !is ServerLevel)
|
|
||||||
return
|
|
||||||
|
|
||||||
return discoverFull(
|
|
||||||
tile.level as ServerLevel,
|
|
||||||
tile.blockPos,
|
|
||||||
node,
|
|
||||||
fun(_tile): Graph6Node<IStorageGraphNode>? {
|
|
||||||
return _tile.getCapability(MatteryCapability.STORAGE_NODE).orNull()?.storageNode
|
|
||||||
}
|
|
||||||
) { StorageNetworkGraph(tile.level!!) }
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun discover(tile: BlockEntity, node: Graph6Node<IStorageGraphNode>): Boolean {
|
|
||||||
if (tile.level !is ServerLevel)
|
|
||||||
return false
|
|
||||||
|
|
||||||
return discover(
|
|
||||||
tile.level as ServerLevel,
|
|
||||||
tile.blockPos,
|
|
||||||
node,
|
|
||||||
fun(_tile): Graph6Node<IStorageGraphNode>? {
|
|
||||||
return _tile.getCapability(MatteryCapability.STORAGE_NODE).orNull()?.storageNode
|
|
||||||
},
|
|
||||||
) { StorageNetworkGraph(tile.level!!) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package ru.dbotthepony.mc.otm.graph.storage
|
package ru.dbotthepony.mc.otm.graph.storage
|
||||||
|
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.energy.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
|
||||||
@ -9,9 +9,7 @@ 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(private val energyDemander: IMatteryEnergyStorage? = null) : IStorageGraphNode {
|
open class StorageNode(private val energyDemander: IMatteryEnergyStorage? = null) : Graph6Node<StorageNode, StorageGraph>(::StorageGraph) {
|
||||||
private var resolver = LazyOptional.of<IStorageGraphNode> { this }
|
|
||||||
private var valid = true
|
|
||||||
protected val components = ArrayList<IStorage<*>>()
|
protected val components = ArrayList<IStorage<*>>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,13 +20,12 @@ open class BasicStorageGraphNode(private val energyDemander: IMatteryEnergyStora
|
|||||||
* [invalidate] and [removeComponents] still detach all components
|
* [invalidate] and [removeComponents] still detach all components
|
||||||
*/
|
*/
|
||||||
protected var manualAttaching = false
|
protected var manualAttaching = false
|
||||||
|
|
||||||
@Suppress("LeakingThis")
|
|
||||||
final override val storageNode = Graph6Node<IStorageGraphNode>(this)
|
|
||||||
|
|
||||||
private var demandingEnergy = false
|
private var demandingEnergy = false
|
||||||
|
|
||||||
override fun attachComponents(to: StorageNetworkGraph) {
|
/**
|
||||||
|
* Called by storage graph on node being attached to it
|
||||||
|
*/
|
||||||
|
open fun attachComponents(to: StorageGraph) {
|
||||||
if (energyDemander != null) {
|
if (energyDemander != null) {
|
||||||
if (energyDemander.missingPower.isPositive) {
|
if (energyDemander.missingPower.isPositive) {
|
||||||
demandingEnergy = true
|
demandingEnergy = true
|
||||||
@ -45,19 +42,13 @@ open class BasicStorageGraphNode(private val energyDemander: IMatteryEnergyStora
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun tickEnergyDemanding() {
|
/**
|
||||||
energyDemander ?: throw IllegalStateException("No energy demander")
|
* Called by storage graph on node being detached from it
|
||||||
|
*
|
||||||
if (!demandingEnergy && storageGraph != null && energyDemander.missingPower.isPositive) {
|
* This is NOT called when graph is being destroyed (e.g. even by merging
|
||||||
demandingEnergy = true
|
* with another graph).
|
||||||
storageGraph!!.powerDemandingNodes.add(energyDemander)
|
*/
|
||||||
} else if (demandingEnergy && storageGraph != null && !energyDemander.missingPower.isPositive) {
|
open fun removeComponents(from: StorageGraph) {
|
||||||
demandingEnergy = false
|
|
||||||
storageGraph!!.powerDemandingNodes.remove(energyDemander)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun removeComponents(from: StorageNetworkGraph) {
|
|
||||||
for (component in components) {
|
for (component in components) {
|
||||||
from.remove(component)
|
from.remove(component)
|
||||||
}
|
}
|
||||||
@ -68,6 +59,18 @@ open class BasicStorageGraphNode(private val energyDemander: IMatteryEnergyStora
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun tickEnergyDemanding() {
|
||||||
|
energyDemander ?: throw IllegalStateException("No energy demander")
|
||||||
|
|
||||||
|
if (!demandingEnergy && energyDemander.missingPower.isPositive) {
|
||||||
|
demandingEnergy = true
|
||||||
|
graph.powerDemandingNodes.add(energyDemander)
|
||||||
|
} else if (demandingEnergy && !energyDemander.missingPower.isPositive) {
|
||||||
|
demandingEnergy = false
|
||||||
|
graph.powerDemandingNodes.remove(energyDemander)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("unchecked_cast")
|
@Suppress("unchecked_cast")
|
||||||
fun <T : IStorageStack, U : IStorage<T>> computeIfAbsent(identity: StorageStackType<T>, provider: (StorageStackType<T>) -> U): U {
|
fun <T : IStorageStack, U : IStorage<T>> computeIfAbsent(identity: StorageStackType<T>, provider: (StorageStackType<T>) -> U): U {
|
||||||
for (component in components) {
|
for (component in components) {
|
||||||
@ -90,8 +93,8 @@ open class BasicStorageGraphNode(private val energyDemander: IMatteryEnergyStora
|
|||||||
|
|
||||||
components.add(component)
|
components.add(component)
|
||||||
|
|
||||||
if (valid && !manualAttaching)
|
if (isValid && !manualAttaching)
|
||||||
storageGraph?.add(component)
|
graph.add(component)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeStorageComponent(component: IStorage<*>) {
|
fun removeStorageComponent(component: IStorage<*>) {
|
||||||
@ -111,8 +114,8 @@ open class BasicStorageGraphNode(private val energyDemander: IMatteryEnergyStora
|
|||||||
val self = components[indexOf]
|
val self = components[indexOf]
|
||||||
components.removeAt(indexOf)
|
components.removeAt(indexOf)
|
||||||
|
|
||||||
if (valid)
|
if (isValid)
|
||||||
storageGraph?.remove(self)
|
graph.remove(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeStorageComponent(component: StorageStackType<*>) {
|
fun removeStorageComponent(component: StorageStackType<*>) {
|
||||||
@ -132,47 +135,25 @@ open class BasicStorageGraphNode(private val energyDemander: IMatteryEnergyStora
|
|||||||
val self = components[indexOf]
|
val self = components[indexOf]
|
||||||
components.removeAt(indexOf)
|
components.removeAt(indexOf)
|
||||||
|
|
||||||
if (valid && !manualAttaching)
|
if (isValid && !manualAttaching)
|
||||||
storageGraph?.remove(self)
|
graph.remove(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun invalidate() {
|
override fun invalidate() {
|
||||||
if (!valid) return
|
|
||||||
valid = false
|
|
||||||
resolver.invalidate()
|
|
||||||
|
|
||||||
val storageGraph = storageGraph
|
|
||||||
|
|
||||||
if (storageGraph != null) {
|
|
||||||
for (component in components) {
|
for (component in components) {
|
||||||
storageGraph.remove(component)
|
graph.remove(component)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun revive() {
|
override fun revive() {
|
||||||
if (valid) return
|
if (!manualAttaching) {
|
||||||
valid = true
|
|
||||||
resolver = LazyOptional.of { this }
|
|
||||||
|
|
||||||
val storageGraph = storageGraph
|
|
||||||
|
|
||||||
if (storageGraph != null && !manualAttaching) {
|
|
||||||
for (component in components) {
|
for (component in components) {
|
||||||
storageGraph.add(component)
|
graph.add(component)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun get(): LazyOptional<IStorageGraphNode> {
|
fun discover(blockEntity: BlockEntity) {
|
||||||
return if (valid) resolver else LazyOptional.empty()
|
discover(blockEntity, MatteryCapability.STORAGE_NODE)
|
||||||
}
|
|
||||||
|
|
||||||
fun destroy(level: Level?) {
|
|
||||||
if (level != null) {
|
|
||||||
storageNode.destroy { StorageNetworkGraph(level) }
|
|
||||||
} else {
|
|
||||||
storageGraph?.removeNode(storageNode)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -45,8 +45,8 @@ class MatterBottlerMenu @JvmOverloads constructor(
|
|||||||
|
|
||||||
storageSlots = immutableList(6) { index ->
|
storageSlots = immutableList(6) { index ->
|
||||||
object : MatterySlot(container, index) {
|
object : MatterySlot(container, index) {
|
||||||
override fun mayPlace(p_40231_: ItemStack): Boolean {
|
override fun mayPlace(itemStack: ItemStack): Boolean {
|
||||||
val cap = p_40231_.getCapability(MatteryCapability.MATTER).orNull() ?: return false
|
val cap = itemStack.getCapability(MatteryCapability.MATTER).orNull() ?: return false
|
||||||
|
|
||||||
if (workFlow.value) {
|
if (workFlow.value) {
|
||||||
return index < 3 && cap.canReceiveMatter
|
return index < 3 && cap.canReceiveMatter
|
||||||
|
@ -29,9 +29,9 @@ class MatterCapacitorBankMenu @JvmOverloads constructor(
|
|||||||
} else {
|
} else {
|
||||||
matterGauge = LevelGaugeWidget(this, tile)
|
matterGauge = LevelGaugeWidget(this, tile)
|
||||||
totalMatterGauge = LevelGaugeWidget(this, {
|
totalMatterGauge = LevelGaugeWidget(this, {
|
||||||
tile.matterGraph?.getMatterStorageLevel() ?: Decimal.ZERO
|
tile.matterNode.graph.getMatterStorageLevel()
|
||||||
}, {
|
}, {
|
||||||
tile.matterGraph?.getMatterStorageMaxLevel() ?: Decimal.ZERO
|
tile.matterNode.graph.getMatterStorageMaxLevel()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ import ru.dbotthepony.mc.otm.core.util.DecimalValueCodec
|
|||||||
import ru.dbotthepony.mc.otm.core.util.ItemSorter
|
import ru.dbotthepony.mc.otm.core.util.ItemSorter
|
||||||
import ru.dbotthepony.mc.otm.core.util.codec
|
import ru.dbotthepony.mc.otm.core.util.codec
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphListener
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphListener
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
|
||||||
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
||||||
import ru.dbotthepony.mc.otm.network.*
|
import ru.dbotthepony.mc.otm.network.*
|
||||||
import ru.dbotthepony.mc.otm.registry.MMenus
|
import ru.dbotthepony.mc.otm.registry.MMenus
|
||||||
@ -176,7 +176,7 @@ class MatterPanelMenu @JvmOverloads constructor(
|
|||||||
})
|
})
|
||||||
|
|
||||||
val totalMatterStored: Decimal by mSynchronizer.ComputedField(
|
val totalMatterStored: Decimal by mSynchronizer.ComputedField(
|
||||||
getter = { tile?.matterGraph?.getMatterStorageLevel() ?: Decimal.ZERO },
|
getter = { tile?.matterNode?.graph?.getMatterStorageLevel() ?: Decimal.ZERO },
|
||||||
codec = DecimalValueCodec,
|
codec = DecimalValueCodec,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -278,8 +278,7 @@ class MatterPanelMenu @JvmOverloads constructor(
|
|||||||
|
|
||||||
val tile = tile as MatterPanelBlockEntity? ?: return
|
val tile = tile as MatterPanelBlockEntity? ?: return
|
||||||
|
|
||||||
val graph = tile.matterGraph ?: return
|
val state = tile.matterNode.graph.getPattern(id)
|
||||||
val state = graph.getPattern(id)
|
|
||||||
|
|
||||||
if (state == null) {
|
if (state == null) {
|
||||||
LOGGER.error("Received replication request from {} of {}, but it is not found in grid", ply, id)
|
LOGGER.error("Received replication request from {} of {}, but it is not found in grid", ply, id)
|
||||||
@ -312,14 +311,13 @@ class MatterPanelMenu @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var initialSend = false
|
private var initialSend = false
|
||||||
|
private var listeningGrid: MatterGraph? = null
|
||||||
private var listeningGrid: MatterNetworkGraph? = null
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (tile != null) {
|
if (tile != null) {
|
||||||
listeningGrid = tile.matterGraph
|
listeningGrid = tile.matterNode.graph
|
||||||
tile.attachMenu(this)
|
tile.attachMenu(this)
|
||||||
listeningGrid?.addListener(this)
|
listeningGrid!!.addListener(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,13 +345,9 @@ class MatterPanelMenu @JvmOverloads constructor(
|
|||||||
val tile = tile as MatterPanelBlockEntity?
|
val tile = tile as MatterPanelBlockEntity?
|
||||||
|
|
||||||
if (tile != null) {
|
if (tile != null) {
|
||||||
val grid = tile.matterGraph
|
val grid = tile.matterNode.graph
|
||||||
|
|
||||||
if (grid != null) {
|
|
||||||
initialSend = true
|
initialSend = true
|
||||||
sendNetwork(PatternsChangePacket(true, grid.patterns.toList()))
|
sendNetwork(PatternsChangePacket(true, grid.patterns.toList()))
|
||||||
}
|
|
||||||
|
|
||||||
sendNetwork(TasksChangePacket(true, tile.allReplicationTasks.toList()))
|
sendNetwork(TasksChangePacket(true, tile.allReplicationTasks.toList()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package ru.dbotthepony.mc.otm.menu.matter
|
package ru.dbotthepony.mc.otm.menu.matter
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList
|
|
||||||
import net.minecraft.world.SimpleContainer
|
import net.minecraft.world.SimpleContainer
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.inventory.Slot
|
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import ru.dbotthepony.mc.otm.block.entity.matter.MatterRecyclerBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.matter.MatterRecyclerBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.item.MatterDustItem
|
import ru.dbotthepony.mc.otm.item.MatterDustItem
|
||||||
@ -26,8 +24,8 @@ class MatterRecyclerMenu @JvmOverloads constructor(
|
|||||||
val container = tile?.container ?: SimpleContainer(1)
|
val container = tile?.container ?: SimpleContainer(1)
|
||||||
|
|
||||||
input = object : MatterySlot(container, 0) {
|
input = object : MatterySlot(container, 0) {
|
||||||
override fun mayPlace(p_40231_: ItemStack): Boolean {
|
override fun mayPlace(itemStack: ItemStack): Boolean {
|
||||||
return p_40231_.item is MatterDustItem && (p_40231_.item as MatterDustItem).getMatterValue(p_40231_) != null
|
return itemStack.item is MatterDustItem && (itemStack.item as MatterDustItem).getMatterValue(itemStack) != null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@ class MatterScannerMenu @JvmOverloads constructor(
|
|||||||
if (tile != null) {
|
if (tile != null) {
|
||||||
progress = ProgressGaugeWidget(this, tile::workProgress, tile::isUnableToProcess)
|
progress = ProgressGaugeWidget(this, tile::workProgress, tile::isUnableToProcess)
|
||||||
patterns = LevelGaugeWidget(this,
|
patterns = LevelGaugeWidget(this,
|
||||||
{ Decimal(tile.matterGraph?.patternCount ?: 0L) },
|
{ Decimal(tile.matterNode.graph.patternCount) },
|
||||||
{ Decimal(tile.matterGraph?.patternCapacity ?: 0L) })
|
{ Decimal(tile.matterNode.graph.patternCapacity) })
|
||||||
} else {
|
} else {
|
||||||
progress = ProgressGaugeWidget(this)
|
progress = ProgressGaugeWidget(this)
|
||||||
patterns = LevelGaugeWidget(this)
|
patterns = LevelGaugeWidget(this)
|
||||||
|
@ -29,9 +29,9 @@ class PatternStorageMenu @JvmOverloads constructor(
|
|||||||
} else {
|
} else {
|
||||||
storedThis = LevelGaugeWidget(this, tile)
|
storedThis = LevelGaugeWidget(this, tile)
|
||||||
storedGrid = LevelGaugeWidget(this, {
|
storedGrid = LevelGaugeWidget(this, {
|
||||||
Decimal(tile.matterGraph?.patternCount ?: 0)
|
Decimal(tile.matterNode.graph.patternCount)
|
||||||
}, {
|
}, {
|
||||||
Decimal(tile.matterGraph?.patternCapacity ?: 0)
|
Decimal(tile.matterNode.graph.patternCapacity)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ class StoragePowerSupplierMenu @JvmOverloads constructor(
|
|||||||
override fun broadcastChanges() {
|
override fun broadcastChanges() {
|
||||||
if (tile is StoragePowerSupplierBlockEntity) {
|
if (tile is StoragePowerSupplierBlockEntity) {
|
||||||
totalTransferred = tile.powerPassed
|
totalTransferred = tile.powerPassed
|
||||||
activeNodes = tile.cell.storageGraph?.powerDemandingNodes?.size ?: 0
|
activeNodes = tile.cell.graph.powerDemandingNodes.size
|
||||||
}
|
}
|
||||||
|
|
||||||
super.broadcastChanges()
|
super.broadcastChanges()
|
||||||
|
Loading…
Reference in New Issue
Block a user