Storage import bus

This commit is contained in:
DBotThePony 2022-05-14 18:38:30 +07:00
parent cd622b0708
commit 3e66862de8
Signed by: DBot
GPG Key ID: DCC23B5715498507
9 changed files with 207 additions and 1 deletions

View File

@ -361,6 +361,7 @@ object DataGen {
tile(MBlocks.DRIVE_VIEWER, TileNbtCopy("energy"), TileNbtCopy("container"), TileNbtCopy("battery_container")) tile(MBlocks.DRIVE_VIEWER, TileNbtCopy("energy"), TileNbtCopy("container"), TileNbtCopy("battery_container"))
tile(MBlocks.STORAGE_BUS, TileNbtCopy("energy"), TileNbtCopy("battery_container")) tile(MBlocks.STORAGE_BUS, TileNbtCopy("energy"), TileNbtCopy("battery_container"))
tile(MBlocks.STORAGE_IMPORTER, TileNbtCopy("energy"), TileNbtCopy("battery_container"))
tile(MBlocks.STORAGE_POWER_SUPPLIER, TileNbtCopy("energy"), TileNbtCopy("battery_container"), TileNbtCopy("power_supplied")) tile(MBlocks.STORAGE_POWER_SUPPLIER, TileNbtCopy("energy"), TileNbtCopy("battery_container"), TileNbtCopy("power_supplied"))
tile(MBlocks.MATTER_DECOMPOSER, TileNbtCopy("container"), TileNbtCopy("matter"), *workerTags) tile(MBlocks.MATTER_DECOMPOSER, TileNbtCopy("container"), TileNbtCopy("matter"), *workerTags)

View File

@ -0,0 +1,59 @@
package ru.dbotthepony.mc.otm.block
import net.minecraft.core.BlockPos
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.BlockEntityTicker
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.state.BlockState
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
import ru.dbotthepony.mc.otm.block.entity.StorageImporterBlockEntity
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.unaryMinus
class StorageImporterBlock : RotatableMatteryBlock(), EntityBlock {
override val hasFreeRotation: Boolean get() = true
override fun newBlockEntity(p_153215_: BlockPos, p_153216_: BlockState): BlockEntity {
return StorageImporterBlockEntity(p_153215_, p_153216_)
}
override fun <T : BlockEntity?> getTicker(
p_153212_: Level,
p_153213_: BlockState,
p_153214_: BlockEntityType<T>
): BlockEntityTicker<T>? {
if (p_153212_.isClientSide || p_153214_ !== MBlockEntities.STORAGE_IMPORTER)
return null
return BlockEntityTicker { _, _, _, tile -> if (tile is StorageImporterBlockEntity) tile.tick() }
}
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
return super.getStateForPlacement(context)?.setValue(FACING_FULL, -context.clickedFace)
}
override fun neighborChanged(
state: BlockState,
level: Level,
pos: BlockPos,
sender: Block,
sender_pos: BlockPos,
flag: Boolean
) {
super.neighborChanged(state, level, pos, sender, sender_pos, flag)
if (!level.isClientSide) {
val tile = level.getBlockEntity(pos)
if (tile is StorageImporterBlockEntity) {
addPreWorldTickerOnce(level) {
tile.checkSurroundings()
}
}
}
}
}

View File

@ -0,0 +1,137 @@
package ru.dbotthepony.mc.otm.block.entity
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.TranslatableComponent
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.items.CapabilityItemHandler
import net.minecraftforge.items.IItemHandler
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.capability.extractStepInner
import ru.dbotthepony.mc.otm.core.plus
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
import ru.dbotthepony.mc.otm.orThrow
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.registry.MNames
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper
import ru.dbotthepony.mc.otm.unaryMinus
class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.STORAGE_IMPORTER, blockPos, blockState) {
override val defaultDisplayName: Component
get() = MACHINE_NAME
override val energy = WorkerEnergyStorage(this)
val cell = BasicStorageGraphNode(energy)
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? {
return null
}
private var valid = true
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
return if (valid && cap === MatteryCapability.STORAGE_NODE) {
cell.get().cast()
} else super.getCapability(cap, side)
}
override fun invalidateCaps() {
super.invalidateCaps()
cell.invalidate()
valid = false
}
override fun reviveCaps() {
super.reviveCaps()
cell.revive()
valid = true
}
private var target: LazyOptional<IItemHandler> = LazyOptional.empty()
private var lastSlot = 0
private var nextTick = INTERVAL
private val enoughEnergy get() = energy.batteryLevel >= OverdriveThatMatters.INSTANCE.ITEM_STORAGE().energyPerOperation
override fun setRemoved() {
super.setRemoved()
cell.destroy(level)
valid = false
}
override fun setLevel(p_155231_: Level) {
super.setLevel(p_155231_)
if (p_155231_ is ServerLevel) {
StorageNetworkGraph.discoverFull(this, cell.storageNode)
}
tickOnceServer(this::checkSurroundings)
}
fun tick() {
batteryChargeLoop()
cell.tickEnergyDemanding()
nextTick--
if (nextTick <= 0 && target.isPresent && enoughEnergy) {
val graph = cell.storageGraph ?: return
val items = graph.getVirtualComponent(OverdriveThatMatters.INSTANCE.ITEM_STORAGE())
val resolved = target.orThrow()
if (lastSlot >= resolved.slots) {
lastSlot = 0
}
val maxMove = energy.extractStepInner(OverdriveThatMatters.INSTANCE.ITEM_STORAGE().energyPerOperation, MAX_MOVE_PER_OPERATION, true)
var extracted = resolved.extractItem(lastSlot, maxMove, true)
if (extracted.isEmpty) {
lastSlot++
} else {
val leftOver = items.insertStack(ItemStackWrapper(extracted), true)
if (leftOver.count.toInt() != extracted.count) {
extracted = resolved.extractItem(lastSlot, extracted.count - leftOver.count.toInt(), false)
energy.extractStepInner(OverdriveThatMatters.INSTANCE.ITEM_STORAGE().energyPerOperation, extracted.count, false)
items.insertStack(ItemStackWrapper(extracted), false)
} else {
nextTick += INTERVAL * 4
}
}
}
if (nextTick <= 0) {
nextTick = INTERVAL
}
}
fun checkSurroundings() {
target = getAndBind(
target,
level?.getBlockEntity(blockPos + blockState.getValue(RotatableMatteryBlock.FACING_FULL).normal),
CapabilityItemHandler.ITEM_HANDLER_CAPABILITY,
-blockState.getValue(RotatableMatteryBlock.FACING_FULL),
) { tickOnceServer(this::checkSurroundings) }
}
companion object {
private val MACHINE_NAME = TranslatableComponent("block.${OverdriveThatMatters.MOD_ID}.${MNames.STORAGE_IMPORTER}")
private const val INTERVAL = 5
private const val MAX_MOVE_PER_OPERATION = 4
}
}

View File

@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.graph
import net.minecraft.core.Direction import net.minecraft.core.Direction
import ru.dbotthepony.mc.otm.IConditionalTickable import ru.dbotthepony.mc.otm.IConditionalTickable
import ru.dbotthepony.mc.otm.ITickable import ru.dbotthepony.mc.otm.ITickable
import ru.dbotthepony.mc.otm.SERVER_IS_DYING
interface GraphNodeListener { interface GraphNodeListener {
fun onNeighbourTop(node: Graph6Node<*>) = onNeighbour(node, Direction.UP) fun onNeighbourTop(node: Graph6Node<*>) = onNeighbour(node, Direction.UP)
@ -264,7 +265,7 @@ class Graph6Node<T>(@JvmField val value: T, graph: Abstract6Graph<T>? = null) :
private set private set
fun destroy(factory: () -> Abstract6Graph<T>): List<GraphFlooder<T>> { fun destroy(factory: () -> Abstract6Graph<T>): List<GraphFlooder<T>> {
if (!valid) return emptyList() if (!valid || SERVER_IS_DYING) return emptyList()
top?.bottom = null top?.bottom = null
bottom?.top = null bottom?.top = null

View File

@ -41,6 +41,7 @@ object MBlockEntities {
val MATTER_RECYCLER: BlockEntityType<*> by registry.register(MNames.MATTER_RECYCLER) { BlockEntityType.Builder.of(::MatterRecyclerBlockEntity, MBlocks.MATTER_RECYCLER).build(null) } val MATTER_RECYCLER: BlockEntityType<*> by registry.register(MNames.MATTER_RECYCLER) { BlockEntityType.Builder.of(::MatterRecyclerBlockEntity, MBlocks.MATTER_RECYCLER).build(null) }
val STORAGE_BUS: BlockEntityType<*> by registry.register(MNames.STORAGE_BUS) { BlockEntityType.Builder.of(::StorageBusBlockEntity, MBlocks.STORAGE_BUS).build(null) } val STORAGE_BUS: BlockEntityType<*> by registry.register(MNames.STORAGE_BUS) { BlockEntityType.Builder.of(::StorageBusBlockEntity, MBlocks.STORAGE_BUS).build(null) }
val STORAGE_IMPORTER: BlockEntityType<*> by registry.register(MNames.STORAGE_IMPORTER) { BlockEntityType.Builder.of(::StorageImporterBlockEntity, MBlocks.STORAGE_IMPORTER).build(null) }
val STORAGE_POWER_SUPPLIER: BlockEntityType<*> by registry.register(MNames.STORAGE_POWER_SUPPLIER) { BlockEntityType.Builder.of(::StoragePowerSupplierBlockEntity, MBlocks.STORAGE_POWER_SUPPLIER).build(null) } val STORAGE_POWER_SUPPLIER: BlockEntityType<*> by registry.register(MNames.STORAGE_POWER_SUPPLIER) { BlockEntityType.Builder.of(::StoragePowerSupplierBlockEntity, MBlocks.STORAGE_POWER_SUPPLIER).build(null) }
val DEBUG_EXPLOSION_SMALL: BlockEntityType<*> by registry.register(MNames.DEBUG_EXPLOSION_SMALL) { BlockEntityType.Builder.of(::BlockEntityExplosionDebugger, MBlocks.DEBUG_EXPLOSION_SMALL).build(null) } val DEBUG_EXPLOSION_SMALL: BlockEntityType<*> by registry.register(MNames.DEBUG_EXPLOSION_SMALL) { BlockEntityType.Builder.of(::BlockEntityExplosionDebugger, MBlocks.DEBUG_EXPLOSION_SMALL).build(null) }

View File

@ -53,6 +53,8 @@ object MBlocks {
val MATTER_RECYCLER: Block by registry.register(MNames.MATTER_RECYCLER) { MatterRecyclerBlock() } val MATTER_RECYCLER: Block by registry.register(MNames.MATTER_RECYCLER) { MatterRecyclerBlock() }
val STORAGE_BUS: Block by registry.register(MNames.STORAGE_BUS) { StorageBusBlock() } val STORAGE_BUS: Block by registry.register(MNames.STORAGE_BUS) { StorageBusBlock() }
val STORAGE_IMPORTER: Block by registry.register(MNames.STORAGE_IMPORTER) { StorageImporterBlock() }
val DRIVE_VIEWER: Block by registry.register(MNames.DRIVE_VIEWER) { DriveViewerBlock() } val DRIVE_VIEWER: Block by registry.register(MNames.DRIVE_VIEWER) { DriveViewerBlock() }
val DRIVE_RACK: Block by registry.register(MNames.DRIVE_RACK) { DriveRackBlock() } val DRIVE_RACK: Block by registry.register(MNames.DRIVE_RACK) { DriveRackBlock() }
val ITEM_MONITOR: Block by registry.register(MNames.ITEM_MONITOR) { ItemMonitorBlock() } val ITEM_MONITOR: Block by registry.register(MNames.ITEM_MONITOR) { ItemMonitorBlock() }

View File

@ -47,6 +47,7 @@ object MItems {
val MATTER_RECYCLER: Item by registry.register(MNames.MATTER_RECYCLER) { BlockItem(MBlocks.MATTER_RECYCLER, DEFAULT_PROPERTIES) } val MATTER_RECYCLER: Item by registry.register(MNames.MATTER_RECYCLER) { BlockItem(MBlocks.MATTER_RECYCLER, DEFAULT_PROPERTIES) }
val STORAGE_BUS: Item by registry.register(MNames.STORAGE_BUS) { BlockItem(MBlocks.STORAGE_BUS, DEFAULT_PROPERTIES) } val STORAGE_BUS: Item by registry.register(MNames.STORAGE_BUS) { BlockItem(MBlocks.STORAGE_BUS, DEFAULT_PROPERTIES) }
val STORAGE_IMPORTER: Item by registry.register(MNames.STORAGE_IMPORTER) { BlockItem(MBlocks.STORAGE_IMPORTER, DEFAULT_PROPERTIES) }
val DRIVE_VIEWER: Item by registry.register(MNames.DRIVE_VIEWER) { BlockItem(MBlocks.DRIVE_VIEWER, DEFAULT_PROPERTIES) } val DRIVE_VIEWER: Item by registry.register(MNames.DRIVE_VIEWER) { BlockItem(MBlocks.DRIVE_VIEWER, DEFAULT_PROPERTIES) }
val DRIVE_RACK: Item by registry.register(MNames.DRIVE_RACK) { BlockItem(MBlocks.DRIVE_RACK, DEFAULT_PROPERTIES) } val DRIVE_RACK: Item by registry.register(MNames.DRIVE_RACK) { BlockItem(MBlocks.DRIVE_RACK, DEFAULT_PROPERTIES) }
val ITEM_MONITOR: Item by registry.register(MNames.ITEM_MONITOR) { BlockItem(MBlocks.ITEM_MONITOR, DEFAULT_PROPERTIES) } val ITEM_MONITOR: Item by registry.register(MNames.ITEM_MONITOR) { BlockItem(MBlocks.ITEM_MONITOR, DEFAULT_PROPERTIES) }

View File

@ -35,6 +35,9 @@ object MNames {
const val CARGO_CRATE = "cargo_crate" // нужен рецепт? const val CARGO_CRATE = "cargo_crate" // нужен рецепт?
const val STORAGE_BUS = "storage_bus" const val STORAGE_BUS = "storage_bus"
const val STORAGE_IMPORTER = "storage_importer"
const val STORAGE_EXPORTER = "storage_exporter"
const val STORAGE_INTERFACE = "storage_interface"
// building blocks // building blocks
const val TRITANIUM_BLOCK = "tritanium_block" const val TRITANIUM_BLOCK = "tritanium_block"

View File

@ -238,6 +238,7 @@
"block.overdrive_that_matters.storage_cable": "Storage Cable", "block.overdrive_that_matters.storage_cable": "Storage Cable",
"block.overdrive_that_matters.storage_power_supplier": "Storage Power Supplier", "block.overdrive_that_matters.storage_power_supplier": "Storage Power Supplier",
"block.overdrive_that_matters.storage_bus": "Storage Bus", "block.overdrive_that_matters.storage_bus": "Storage Bus",
"block.overdrive_that_matters.storage_importer": "Storage Importer",
"item.overdrive_that_matters.pill_android": "Android Pill", "item.overdrive_that_matters.pill_android": "Android Pill",
"item.overdrive_that_matters.pill_humane": "Humane Pill", "item.overdrive_that_matters.pill_humane": "Humane Pill",