Unify NBT keys and update block loottables

Fixes #71
This commit is contained in:
DBotThePony 2022-09-08 16:38:09 +07:00
parent 9e649a7c61
commit 1c0530e8dd
Signed by: DBot
GPG Key ID: DCC23B5715498507
37 changed files with 575 additions and 354 deletions

View File

@ -5,6 +5,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArraySet
import net.minecraft.data.DataGenerator import net.minecraft.data.DataGenerator
import net.minecraft.data.loot.LootTableProvider import net.minecraft.data.loot.LootTableProvider
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.level.ItemLike
import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Block
import net.minecraft.world.level.storage.loot.LootPool import net.minecraft.world.level.storage.loot.LootPool
import net.minecraft.world.level.storage.loot.LootTable import net.minecraft.world.level.storage.loot.LootTable
@ -14,6 +15,8 @@ import net.minecraft.world.level.storage.loot.functions.CopyNbtFunction
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSet import net.minecraft.world.level.storage.loot.parameters.LootContextParamSet
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets
import net.minecraft.world.level.storage.loot.providers.nbt.ContextNbtProvider import net.minecraft.world.level.storage.loot.providers.nbt.ContextNbtProvider
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
import java.util.function.BiConsumer import java.util.function.BiConsumer
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Supplier import java.util.function.Supplier
@ -28,7 +31,32 @@ fun singleLootPool(f: (LootPool.Builder) -> Unit): LootTable.Builder {
} }
data class NbtCopy(val source: String, val destination: String, val strategy: CopyNbtFunction.MergeStrategy = CopyNbtFunction.MergeStrategy.REPLACE) data class NbtCopy(val source: String, val destination: String, val strategy: CopyNbtFunction.MergeStrategy = CopyNbtFunction.MergeStrategy.REPLACE)
data class TileNbtCopy(val source: String, val strategy: CopyNbtFunction.MergeStrategy = CopyNbtFunction.MergeStrategy.REPLACE)
fun TileNbtCopy(source: String, strategy: CopyNbtFunction.MergeStrategy = CopyNbtFunction.MergeStrategy.REPLACE): NbtCopy {
return NbtCopy(source, "BlockEntityTag.$source", strategy)
}
private val basicTags = arrayOf(
TileNbtCopy(MatteryBlockEntity.REDSTONE_SIGNAL_KEY),
TileNbtCopy(MatteryBlockEntity.REDSTONE_SETTING_KEY),
)
private val poweredTags = arrayOf(
*basicTags,
TileNbtCopy(MatteryBlockEntity.ENERGY_KEY),
TileNbtCopy(MatteryBlockEntity.BATTERY_KEY),
)
private val workerTags = arrayOf(
*poweredTags,
TileNbtCopy(MatteryWorkerBlockEntity.JOB_KEY),
TileNbtCopy(MatteryWorkerBlockEntity.WORK_TICKS_KEY),
)
private val poweredMatterWorker = arrayOf(
*workerTags,
TileNbtCopy(MatteryBlockEntity.MATTER_STORAGE_KEY),
)
class LootTables(generator: DataGenerator) : LootTableProvider(generator) { class LootTables(generator: DataGenerator) : LootTableProvider(generator) {
private val providers = ArrayList<LootTuple>() private val providers = ArrayList<LootTuple>()
@ -57,6 +85,18 @@ class LootTables(generator: DataGenerator) : LootTableProvider(generator) {
} }
} }
fun dropsOther(block: Block, other: ItemLike) {
if (!seenStuff.add(block)) {
throw IllegalStateException("Already seen $block")
}
block {
it.accept(block.lootTable, singleLootPool {
it.add(LootItem.lootTableItem(other))
})
}
}
fun dropsSelf(vararg blocks: Block) { fun dropsSelf(vararg blocks: Block) {
blocks.forEach(this::dropsSelf) blocks.forEach(this::dropsSelf)
} }
@ -90,7 +130,72 @@ class LootTables(generator: DataGenerator) : LootTableProvider(generator) {
} }
} }
fun tile(block: Block, vararg tags: TileNbtCopy) { fun basicTile(block: Block, vararg tags: NbtCopy) {
tile(block, *tags.map { NbtCopy(it.source, "BlockEntityTag.${it.source}", it.strategy) }.toTypedArray()) tile(block) {
for ((source, destination, strategy) in tags) {
it.copy(source, destination, strategy)
}
for ((source, destination, strategy) in basicTags) {
it.copy(source, destination, strategy)
}
}
}
fun poweredTile(block: Block, vararg tags: NbtCopy) {
tile(block) {
for ((source, destination, strategy) in tags) {
it.copy(source, destination, strategy)
}
for ((source, destination, strategy) in poweredTags) {
it.copy(source, destination, strategy)
}
}
}
fun workerTile(block: Block, vararg tags: NbtCopy) {
tile(block) {
for ((source, destination, strategy) in tags) {
it.copy(source, destination, strategy)
}
for ((source, destination, strategy) in workerTags) {
it.copy(source, destination, strategy)
}
}
}
fun matterWorkerTile(block: Block, vararg tags: NbtCopy) {
tile(block) {
for ((source, destination, strategy) in tags) {
it.copy(source, destination, strategy)
}
for ((source, destination, strategy) in poweredMatterWorker) {
it.copy(source, destination, strategy)
}
}
}
fun tile(block: Block, vararg tags: String) {
tile(block, *tags.map { NbtCopy(it, "BlockEntityTag.$it", CopyNbtFunction.MergeStrategy.REPLACE) }.toTypedArray())
}
// fix overload resolution by adding extra required argument
fun basicTile(block: Block, f: String, vararg tags: String) {
basicTile(block, *tags.map { TileNbtCopy(it) }.toMutableList().also { it.add(TileNbtCopy(f)) }.toTypedArray())
}
fun poweredTile(block: Block, f: String, vararg tags: String) {
poweredTile(block, *tags.map { TileNbtCopy(it) }.toMutableList().also { it.add(TileNbtCopy(f)) }.toTypedArray())
}
fun workerTile(block: Block, f: String, vararg tags: String) {
workerTile(block, *tags.map { TileNbtCopy(it) }.toMutableList().also { it.add(TileNbtCopy(f)) }.toTypedArray())
}
fun matterWorkerTile(block: Block, f: String, vararg tags: String) {
matterWorkerTile(block, *tags.map { TileNbtCopy(it) }.toMutableList().also { it.add(TileNbtCopy(f)) }.toTypedArray())
} }
} }

View File

@ -1,15 +1,22 @@
package ru.dbotthepony.mc.otm.datagen.loot package ru.dbotthepony.mc.otm.datagen.loot
import ru.dbotthepony.mc.otm.block.MatteryBlock
import ru.dbotthepony.mc.otm.block.entity.ChemicalGeneratorBlockEntity
import ru.dbotthepony.mc.otm.block.entity.EnergyCounterBlockEntity
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity.Companion.INVENTORY_KEY
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity.Companion.ENERGY_KEY
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity.Companion.BATTERY_KEY
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity.Companion.MATTER_STORAGE_KEY
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity.Companion.REDSTONE_SETTING_KEY
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity.Companion.REDSTONE_SIGNAL_KEY
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
import ru.dbotthepony.mc.otm.block.entity.matter.MatterBottlerBlockEntity
import ru.dbotthepony.mc.otm.block.entity.storage.AbstractStorageImportExport.Companion.FILTER_KEY
import ru.dbotthepony.mc.otm.block.entity.storage.StoragePowerSupplierBlockEntity
import ru.dbotthepony.mc.otm.registry.MBlocks import ru.dbotthepony.mc.otm.registry.MBlocks
import ru.dbotthepony.mc.otm.registry.MRegistry import ru.dbotthepony.mc.otm.registry.MRegistry
private val workerTags = arrayOf(
TileNbtCopy("work_ticks"),
TileNbtCopy("current_job"),
TileNbtCopy("battery_container"),
TileNbtCopy("energy"),
)
fun addLootTables(lootTables: LootTables) { fun addLootTables(lootTables: LootTables) {
lootTables.dropsSelf(MBlocks.CRATE_LIST) lootTables.dropsSelf(MBlocks.CRATE_LIST)
@ -28,26 +35,40 @@ fun addLootTables(lootTables: LootTables) {
lootTables.dropsSelf(MBlocks.TRITANIUM_STRIPED_BLOCK) lootTables.dropsSelf(MBlocks.TRITANIUM_STRIPED_BLOCK)
lootTables.dropsSelf(MBlocks.MATTER_CABLE) lootTables.dropsSelf(MBlocks.MATTER_CABLE)
lootTables.dropsSelf(MBlocks.GRAVITATION_STABILIZER) lootTables.dropsSelf(MBlocks.GRAVITATION_STABILIZER)
lootTables.dropsOther(MBlocks.GRAVITATION_STABILIZER_LENS, MBlocks.GRAVITATION_STABILIZER)
lootTables.tile(MBlocks.ENERGY_COUNTER, TileNbtCopy("passed"), TileNbtCopy("history"), TileNbtCopy("history_tick")) lootTables.tile(MBlocks.ENERGY_COUNTER,
lootTables.tile(MBlocks.CHEMICAL_GENERATOR, TileNbtCopy("energy"), TileNbtCopy("container"), TileNbtCopy("working_ticks"), TileNbtCopy("working_ticks_total")) EnergyCounterBlockEntity.IO_LIMIT_KEY, EnergyCounterBlockEntity.PASSED_ENERGY_KEY,
EnergyCounterBlockEntity.POWER_HISTORY_KEY, EnergyCounterBlockEntity.POWER_HISTORY_POINTER_KEY)
lootTables.tile(MBlocks.ANDROID_STATION, TileNbtCopy("energy"), TileNbtCopy("battery_container")) lootTables.tile(MBlocks.CHEMICAL_GENERATOR,
lootTables.tile(MBlocks.BATTERY_BANK, TileNbtCopy("container")) ChemicalGeneratorBlockEntity.WORK_TICKS_KEY,
lootTables.tile(MBlocks.DRIVE_VIEWER, TileNbtCopy("energy"), TileNbtCopy("container"), TileNbtCopy("battery_container")) ChemicalGeneratorBlockEntity.WORK_TICKS_TOTAL_KEY,
ENERGY_KEY,
REDSTONE_SIGNAL_KEY,
REDSTONE_SETTING_KEY,
)
lootTables.tile(MBlocks.STORAGE_BUS, TileNbtCopy("energy"), TileNbtCopy("battery_container")) lootTables.dropsSelf(MBlocks.STORAGE_CABLE)
lootTables.tile(MBlocks.STORAGE_IMPORTER, TileNbtCopy("energy"), TileNbtCopy("battery_container")) lootTables.poweredTile(MBlocks.ANDROID_STATION)
lootTables.tile(MBlocks.STORAGE_POWER_SUPPLIER, TileNbtCopy("energy"), TileNbtCopy("battery_container"), TileNbtCopy("power_supplied")) lootTables.basicTile(MBlocks.BATTERY_BANK)
lootTables.poweredTile(MBlocks.DRIVE_VIEWER)
lootTables.tile(MBlocks.MATTER_DECOMPOSER, TileNbtCopy("container"), TileNbtCopy("matter"), *workerTags) lootTables.poweredTile(MBlocks.STORAGE_BUS, TileNbtCopy(FILTER_KEY))
lootTables.tile(MBlocks.MATTER_REPLICATOR, TileNbtCopy("container"), TileNbtCopy("matter"), *workerTags) lootTables.poweredTile(MBlocks.STORAGE_IMPORTER, TileNbtCopy(FILTER_KEY))
lootTables.tile(MBlocks.MATTER_RECYCLER, TileNbtCopy("container"), TileNbtCopy("matter"), *workerTags) lootTables.poweredTile(MBlocks.STORAGE_EXPORTER, TileNbtCopy(FILTER_KEY))
lootTables.tile(MBlocks.MATTER_SCANNER, TileNbtCopy("container"), *workerTags) lootTables.poweredTile(MBlocks.STORAGE_POWER_SUPPLIER, TileNbtCopy(StoragePowerSupplierBlockEntity.POWER_PASSED_KEY))
lootTables.tile(MBlocks.PLATE_PRESS, TileNbtCopy("container"), *workerTags) lootTables.poweredTile(MBlocks.DRIVE_RACK)
lootTables.tile(MBlocks.MATTER_PANEL, TileNbtCopy("tasks")) lootTables.matterWorkerTile(MBlocks.MATTER_DECOMPOSER)
lootTables.tile(MBlocks.PATTERN_STORAGE, TileNbtCopy("patterns")) lootTables.matterWorkerTile(MBlocks.MATTER_REPLICATOR)
lootTables.tile(MBlocks.MATTER_CAPACITOR_BANK, TileNbtCopy("container")) lootTables.matterWorkerTile(MBlocks.MATTER_RECYCLER)
lootTables.tile(MBlocks.MATTER_BOTTLER, TileNbtCopy("energy"), TileNbtCopy("battery_container"), TileNbtCopy("work_slots"), TileNbtCopy("work_flow"), TileNbtCopy("matter")) lootTables.workerTile(MBlocks.MATTER_SCANNER)
lootTables.workerTile(MBlocks.PLATE_PRESS)
lootTables.basicTile(MBlocks.MATTER_PANEL, TileNbtCopy("tasks"))
lootTables.basicTile(MBlocks.PATTERN_STORAGE)
lootTables.basicTile(MBlocks.MATTER_CAPACITOR_BANK)
lootTables.poweredTile(MBlocks.MATTER_BOTTLER,
TileNbtCopy(MATTER_STORAGE_KEY), TileNbtCopy(MatterBottlerBlockEntity.IS_BOTTLING_KEY))
} }

View File

@ -32,25 +32,6 @@ class CargoCrateBlock(val color: DyeColor?) : RotatableMatteryBlock(
return super.getStateForPlacement(context)?.setValue(IS_OPEN, false) return super.getStateForPlacement(context)?.setValue(IS_OPEN, false)
} }
override fun onRemove(
old_block_state: BlockState,
level: Level,
block_pos: BlockPos,
new_block_state: BlockState,
p_51542_: Boolean
) {
if (!old_block_state.`is`(new_block_state.block)) {
val blockentity = level.getBlockEntity(block_pos)
if (blockentity is CargoCrateBlockEntity) {
Containers.dropContents(level, block_pos, blockentity.container);
level.updateNeighbourForOutputSignal(block_pos, this);
}
super.onRemove(old_block_state, level, block_pos, new_block_state, p_51542_)
}
}
override fun hasAnalogOutputSignal(p_60457_: BlockState): Boolean { override fun hasAnalogOutputSignal(p_60457_: BlockState): Boolean {
return true return true
} }

View File

@ -2,6 +2,8 @@ package ru.dbotthepony.mc.otm.block
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.world.Container
import net.minecraft.world.Containers
import net.minecraft.world.InteractionHand import net.minecraft.world.InteractionHand
import net.minecraft.world.InteractionResult import net.minecraft.world.InteractionResult
import net.minecraft.world.MenuProvider import net.minecraft.world.MenuProvider
@ -20,6 +22,10 @@ import net.minecraft.world.level.material.MaterialColor
import net.minecraft.world.phys.BlockHitResult import net.minecraft.world.phys.BlockHitResult
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
interface IDroppableContainer {
val droppableContainer: Container
}
abstract class MatteryBlock @JvmOverloads constructor( abstract class MatteryBlock @JvmOverloads constructor(
properties: Properties = DEFAULT_PROPERTIES properties: Properties = DEFAULT_PROPERTIES
) : Block(properties) { ) : Block(properties) {
@ -82,8 +88,27 @@ abstract class MatteryBlock @JvmOverloads constructor(
} }
} }
@Suppress("OVERRIDE_DEPRECATION")
override fun onRemove(
oldBlockState: BlockState,
level: Level,
blockPos: BlockPos,
newBlockState: BlockState,
movedByPiston: Boolean
) {
if (!oldBlockState.`is`(newBlockState.block)) {
val blockentity = level.getBlockEntity(blockPos)
if (blockentity is IDroppableContainer) {
Containers.dropContents(level, blockPos, blockentity.droppableContainer)
level.updateNeighbourForOutputSignal(blockPos, this)
}
}
super.onRemove(oldBlockState, level, blockPos, newBlockState, movedByPiston)
}
companion object { companion object {
@JvmField
val DEFAULT_PROPERTIES: Properties = Properties.of(Material.STONE, MaterialColor.METAL).requiresCorrectToolForDrops().strength(1.5f, 25.0f) val DEFAULT_PROPERTIES: Properties = Properties.of(Material.STONE, MaterialColor.METAL).requiresCorrectToolForDrops().strength(1.5f, 25.0f)
} }
} }
@ -120,7 +145,6 @@ abstract class RotatableMatteryBlock @JvmOverloads constructor(properties: Prope
open val hasFreeRotation get() = false open val hasFreeRotation get() = false
companion object { companion object {
@JvmField
val FACING: EnumProperty<Direction> = EnumProperty.create( val FACING: EnumProperty<Direction> = EnumProperty.create(
"facing", "facing",
Direction::class.java, Direction::class.java,
@ -130,7 +154,6 @@ abstract class RotatableMatteryBlock @JvmOverloads constructor(properties: Prope
Direction.EAST Direction.EAST
) )
@JvmField
val FACING_FULL: EnumProperty<Direction> = EnumProperty.create("facing", Direction::class.java) val FACING_FULL: EnumProperty<Direction> = EnumProperty.create("facing", Direction::class.java)
} }
} }

View File

@ -6,6 +6,7 @@ import net.minecraft.core.Direction
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
import net.minecraft.world.Container
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
@ -20,9 +21,11 @@ import net.minecraftforge.energy.IEnergyStorage
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.* import ru.dbotthepony.mc.otm.*
import ru.dbotthepony.mc.otm.block.BatteryBankBlock import ru.dbotthepony.mc.otm.block.BatteryBankBlock
import ru.dbotthepony.mc.otm.block.IDroppableContainer
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.capability.* import ru.dbotthepony.mc.otm.capability.*
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.menu.BatteryBankMenu import ru.dbotthepony.mc.otm.menu.BatteryBankMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
@ -30,7 +33,7 @@ import javax.annotation.ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryBlockEntity(MBlockEntities.BATTERY_BANK, p_155229_, p_155230_) { class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryBlockEntity(MBlockEntities.BATTERY_BANK, p_155229_, p_155230_), IDroppableContainer {
// 6 на 2 // 6 на 2
val container: MatteryContainer = object : MatteryContainer(this::setChanged, CAPACITY) { val container: MatteryContainer = object : MatteryContainer(this::setChanged, CAPACITY) {
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) { override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
@ -51,9 +54,18 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
} }
} }
override val droppableContainer: Container
get() = container
private val itemHandler = container.handler( private val itemHandler = container.handler(
{ slot: Int, stack: ItemStack -> stack.getCapability(ForgeCapabilities.ENERGY).isPresent }, object : MatteryContainerFilter {
{ slot: Int, amount: Int, stack: ItemStack? -> true } override fun canInsert(slot: Int, stack: ItemStack): Boolean {
return stack.getCapability(ForgeCapabilities.ENERGY).isPresent
}
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
return true
}
}
) )
private data class BatteryBankDistribution(val distribution: Array<ImpreciseFraction>, val maxThroughput: ImpreciseFraction) private data class BatteryBankDistribution(val distribution: Array<ImpreciseFraction>, val maxThroughput: ImpreciseFraction)
@ -200,11 +212,11 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["container"] = container.serializeNBT() nbt[INVENTORY_KEY] = container.serializeNBT()
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
container.deserializeNBT(nbt["container"]) container.deserializeNBT(nbt[INVENTORY_KEY])
super.load(nbt) super.load(nbt)
} }

View File

@ -4,6 +4,7 @@ import net.minecraft.core.BlockPos
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.world.Container
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
@ -14,6 +15,7 @@ import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.block.CargoCrateBlock import ru.dbotthepony.mc.otm.block.CargoCrateBlock
import ru.dbotthepony.mc.otm.block.IDroppableContainer
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.menu.CargoCrateMenu import ru.dbotthepony.mc.otm.menu.CargoCrateMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
@ -23,11 +25,14 @@ import ru.dbotthepony.mc.otm.core.set
class CargoCrateBlockEntity( class CargoCrateBlockEntity(
p_155229_: BlockPos, p_155229_: BlockPos,
p_155230_: BlockState p_155230_: BlockState
) : MatteryBlockEntity(MBlockEntities.CARGO_CRATE, p_155229_, p_155230_) { ) : MatteryBlockEntity(MBlockEntities.CARGO_CRATE, p_155229_, p_155230_), IDroppableContainer {
val container = MatteryContainer(this::setChanged, CAPACITY) val container = MatteryContainer(this::setChanged, CAPACITY)
private var interactingPlayers = 0 private var interactingPlayers = 0
val handler = container.handler() val handler = container.handler()
override val droppableContainer: Container
get() = container
fun onPlayerOpen() { fun onPlayerOpen() {
if (interactingPlayers++ == 0) { if (interactingPlayers++ == 0) {
level?.setBlock(blockPos, blockState.setValue(CargoCrateBlock.IS_OPEN, true), Block.UPDATE_CLIENTS) level?.setBlock(blockPos, blockState.setValue(CargoCrateBlock.IS_OPEN, true), Block.UPDATE_CLIENTS)
@ -59,12 +64,12 @@ class CargoCrateBlockEntity(
public override fun saveAdditional(nbt: CompoundTag) { public override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["slots"] = container.serializeNBT() nbt[INVENTORY_KEY] = container.serializeNBT()
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
super.load(nbt) super.load(nbt)
container.deserializeNBT(nbt["slots"]) container.deserializeNBT(nbt[INVENTORY_KEY])
} }
override val defaultDisplayName: Component override val defaultDisplayName: Component

View File

@ -5,6 +5,7 @@ import net.minecraft.core.Direction
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.IntTag import net.minecraft.nbt.IntTag
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.world.Container
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
@ -18,15 +19,17 @@ import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.energy.IEnergyStorage import net.minecraftforge.energy.IEnergyStorage
import ru.dbotthepony.mc.otm.* import ru.dbotthepony.mc.otm.*
import ru.dbotthepony.mc.otm.block.IDroppableContainer
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.capability.* import ru.dbotthepony.mc.otm.capability.*
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.menu.ChemicalGeneratorMenu import ru.dbotthepony.mc.otm.menu.ChemicalGeneratorMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBlockEntity(MBlockEntities.CHEMICAL_GENERATOR, pos, state) { class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBlockEntity(MBlockEntities.CHEMICAL_GENERATOR, pos, state), IDroppableContainer {
override val defaultDisplayName: Component override val defaultDisplayName: Component
get() = MACHINE_NAME get() = MACHINE_NAME
@ -35,10 +38,13 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBl
} }
private var valid = true private var valid = true
val container = MatteryContainer(this::setChangedLight, 3)
@JvmField override val droppableContainer: Container
get() = container
val energy = GeneratorEnergyStorage(this::setChangedLight, MAX_ENERGY, THROUGHPUT) val energy = GeneratorEnergyStorage(this::setChangedLight, MAX_ENERGY, THROUGHPUT)
private val consumers = ArrayList<LazyOptional<IEnergyStorage>>()
override fun setChangedLight() { override fun setChangedLight() {
super.setChangedLight() super.setChangedLight()
check = true check = true
@ -76,31 +82,21 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBl
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["energy"] = energy.serializeNBT() nbt[ENERGY_KEY] = energy.serializeNBT()
nbt["container"] = container.serializeNBT() nbt[INVENTORY_KEY] = container.serializeNBT()
nbt["working_ticks"] = workingTicks nbt[WORK_TICKS_KEY] = workTicks
nbt["working_ticks_total"] = workingTicksTotal nbt[WORK_TICKS_TOTAL_KEY] = workTicksTotal
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
super.load(nbt) super.load(nbt)
nbt.ifHas("energy", CompoundTag::class.java, energy::deserializeNBT) nbt.map(ENERGY_KEY, energy::deserializeNBT)
container.deserializeNBT(nbt["container"]) container.deserializeNBT(nbt[INVENTORY_KEY])
workTicks = nbt.getInt(WORK_TICKS_KEY)
nbt.ifHas("working_ticks") { workTicksTotal = nbt.getInt(WORK_TICKS_TOTAL_KEY)
if (it is IntTag)
workingTicks = it.asInt
}
nbt.ifHas("working_ticks_total") {
if (it is IntTag)
workingTicksTotal = it.asInt
}
} }
private val consumers = ArrayList<LazyOptional<IEnergyStorage>>()
fun checkSurroundings() { fun checkSurroundings() {
if (!valid) if (!valid)
return return
@ -131,21 +127,23 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBl
} }
} }
val container = MatteryContainer(this::setChangedLight, 3) val itemHandler = container.handler(object : MatteryContainerFilter {
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
if (slot == SLOT_INPUT)
return ForgeHooks.getBurnTime(stack, null) > 0
val itemHandler = container.handler(fun (slot, stack): Boolean { if (slot == SLOT_RESIDUE)
if (slot == SLOT_INPUT) return false
return ForgeHooks.getBurnTime(stack, null) > 0
if (slot == SLOT_RESIDUE) return stack.getCapability(ForgeCapabilities.ENERGY).isPresent
return false }
return stack.getCapability(ForgeCapabilities.ENERGY).isPresent override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
}, fun (slot, _, stack): Boolean { if (slot == SLOT_RESIDUE) return true
if (slot == SLOT_RESIDUE) return true
return slot == SLOT_BATTERY && return slot == SLOT_BATTERY &&
(!stack.getCapability(ForgeCapabilities.ENERGY).isPresent || stack.getCapability(ForgeCapabilities.ENERGY).resolve().get().receiveEnergy(Int.MAX_VALUE, true) <= 0) (!stack.getCapability(ForgeCapabilities.ENERGY).isPresent || stack.getCapability(ForgeCapabilities.ENERGY).resolve().get().receiveEnergy(Int.MAX_VALUE, true) <= 0)
}
}) })
override fun setBlockState(p_155251_: BlockState) { override fun setBlockState(p_155251_: BlockState) {
@ -155,10 +153,10 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBl
tickOnceServer(this::checkSurroundings) tickOnceServer(this::checkSurroundings)
} }
var workingTicks = 0 var workTicks = 0
private set private set
var workingTicksTotal = 0 var workTicksTotal = 0
private set private set
private var check = true private var check = true
@ -173,12 +171,12 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBl
} }
fun tick() { fun tick() {
if (workingTicks > 0 && !isBlockedByRedstone) { if (workTicks > 0) {
workingTicks-- workTicks--
energy.receiveEnergyInner(GENERATION_SPEED, false) energy.receiveEnergyInner(GENERATION_SPEED, false)
if (workingTicks == 0) { if (workTicks == 0) {
workingTicksTotal = 0 workTicksTotal = 0
check = true check = true
} }
@ -189,15 +187,15 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBl
level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS) level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS)
} }
if (workingTicks == 0 && !isBlockedByRedstone && check) { if (workTicks == 0 && !isBlockedByRedstone && check) {
if (!container[SLOT_INPUT].isEmpty) { if (!container[SLOT_INPUT].isEmpty) {
val ticks = ForgeHooks.getBurnTime(container[SLOT_INPUT], null) val ticks = ForgeHooks.getBurnTime(container[SLOT_INPUT], null)
val residue = container[SLOT_INPUT].item.getCraftingRemainingItem(container[SLOT_INPUT].copy().also { it.count = 1 }) val residue = container[SLOT_INPUT].item.getCraftingRemainingItem(container[SLOT_INPUT].copy().also { it.count = 1 })
val canPutResidue = residue.isEmpty || container[SLOT_RESIDUE].isEmpty || ItemStack.isSameItemSameTags(container[SLOT_RESIDUE], residue) && container[SLOT_RESIDUE].count < container[2].maxStackSize val canPutResidue = residue.isEmpty || container[SLOT_RESIDUE].isEmpty || ItemStack.isSameItemSameTags(container[SLOT_RESIDUE], residue) && container[SLOT_RESIDUE].count < container[2].maxStackSize
if (canPutResidue && ticks >= 4 && (energy.batteryLevel < ImpreciseFraction.ONE || GENERATION_SPEED * (ticks / 4) + energy.batteryLevel <= energy.maxBatteryLevel)) { if (canPutResidue && ticks >= 4 && (energy.batteryLevel < ImpreciseFraction.ONE || GENERATION_SPEED * (ticks / 4) + energy.batteryLevel <= energy.maxBatteryLevel)) {
workingTicksTotal = ticks / 4 workTicksTotal = ticks / 4
workingTicks = ticks / 4 workTicks = ticks / 4
container[SLOT_INPUT].shrink(1) container[SLOT_INPUT].shrink(1)
if (!residue.isEmpty) { if (!residue.isEmpty) {
@ -239,5 +237,8 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBl
const val SLOT_INPUT = 0 const val SLOT_INPUT = 0
const val SLOT_BATTERY = 1 const val SLOT_BATTERY = 1
const val SLOT_RESIDUE = 2 const val SLOT_RESIDUE = 2
const val WORK_TICKS_KEY = "workTicks"
const val WORK_TICKS_TOTAL_KEY = "workTicksTotal"
} }
} }

View File

@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.block.entity
import net.minecraft.client.Minecraft import net.minecraft.client.Minecraft
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.nbt.ByteArrayTag
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.IntTag import net.minecraft.nbt.IntTag
import net.minecraft.nbt.ListTag import net.minecraft.nbt.ListTag
@ -128,38 +127,32 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["passed"] = passed.serializeNBT() nbt[PASSED_ENERGY_KEY] = passed.serializeNBT()
val list = ListTag() val list = ListTag()
nbt["history"] = list nbt[POWER_HISTORY_KEY] = list
nbt["history_tick"] = historyTick nbt[POWER_HISTORY_POINTER_KEY] = historyTick
for (num in history) for (num in history)
list.add(num.serializeNBT()) list.add(num.serializeNBT())
ioLimit?.let { nbt["io_limit"] = it.serializeNBT() } ioLimit?.let { nbt[IO_LIMIT_KEY] = it.serializeNBT() }
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
super.load(nbt) super.load(nbt)
nbt.ifHas(("passed")) { passed = nbt.getImpreciseFraction(PASSED_ENERGY_KEY)
passed = ImpreciseFraction.deserializeNBT(it) ioLimit = nbt.map(IO_LIMIT_KEY, ImpreciseFraction.Companion::deserializeNBT)
}
nbt.ifHas(("io_limit")) { nbt.ifHas(POWER_HISTORY_POINTER_KEY, IntTag::class.java) {
ioLimit = ImpreciseFraction.deserializeNBT(it)
}
nbt.ifHas(("history_tick"), IntTag::class.java) {
historyTick = it.asInt historyTick = it.asInt
} }
nbt.ifHas("history", ListTag::class.java) { Arrays.fill(history, ImpreciseFraction.ZERO)
for (i in it.indices) {
val bytes = it[i] as? ByteArrayTag for ((i, bytes) in nbt.getByteArrayList(POWER_HISTORY_KEY).withIndex()) {
history[i] = if (bytes != null) ImpreciseFraction.deserializeNBT(bytes) else ImpreciseFraction.ZERO history[i] = ImpreciseFraction.deserializeNBT(bytes)
}
} }
} }
@ -468,5 +461,9 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
companion object { companion object {
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.energy_counter") private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.energy_counter")
const val PASSED_ENERGY_KEY = "passedEnergy"
const val IO_LIMIT_KEY = "IOLimit"
const val POWER_HISTORY_KEY = "passHistory"
const val POWER_HISTORY_POINTER_KEY = "passHistoryPointer"
} }
} }

View File

@ -18,7 +18,6 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.StringTag import net.minecraft.nbt.StringTag
import net.minecraft.nbt.ByteTag
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.Capability
@ -126,7 +125,7 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
return customDisplayName ?: defaultDisplayName return customDisplayName ?: defaultDisplayName
} }
protected open fun redstoneStatusUpdated(new_blocked: Boolean, old_blocked: Boolean) {} protected open fun redstoneStatusUpdated(newBlocked: Boolean, oldBlocked: Boolean) {}
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
@ -135,8 +134,8 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
if (customDisplayName != null) if (customDisplayName != null)
nbt.putString("Name", Component.Serializer.toJson(customDisplayName)) nbt.putString("Name", Component.Serializer.toJson(customDisplayName))
nbt["redstone"] = redstoneSetting.ordinal.toByte() nbt[REDSTONE_SETTING_KEY] = redstoneSetting.ordinal.toByte()
nbt["redstone_signal"] = redstoneSignal.toByte() nbt[REDSTONE_SIGNAL_KEY] = redstoneSignal.toByte()
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
@ -146,13 +145,8 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
customDisplayName = Component.Serializer.fromJson(it.asString) customDisplayName = Component.Serializer.fromJson(it.asString)
} }
nbt.ifHas("redstone", ByteTag::class.java) { redstoneSetting = RedstoneSetting[nbt.getByte(REDSTONE_SETTING_KEY).toInt()]
redstoneSetting = RedstoneSetting.get(it.asInt) redstoneSignal = nbt.getByte(REDSTONE_SIGNAL_KEY).toInt()
}
nbt.ifHas("redstone_signal", ByteTag::class.java) {
redstoneSignal = it.asInt
}
} }
// Just to mark chunk unsaved // Just to mark chunk unsaved
@ -164,4 +158,13 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
SectionPos.blockToSectionCoord(blockPos.z))?.isUnsaved = true SectionPos.blockToSectionCoord(blockPos.z))?.isUnsaved = true
} }
} }
companion object {
const val REDSTONE_SETTING_KEY = "redstoneSetting"
const val REDSTONE_SIGNAL_KEY = "redstoneSignal"
const val INVENTORY_KEY = "container"
const val MATTER_STORAGE_KEY = "matterStorage"
const val ENERGY_KEY = "energyStorage"
const val BATTERY_KEY = "batteryInventory"
}
} }

View File

@ -79,13 +79,13 @@ abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229
public override fun saveAdditional(nbt: CompoundTag) { public override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["energy"] = energy.serializeNBT() nbt[ENERGY_KEY] = energy.serializeNBT()
nbt["battery_container"] = batteryContainer.serializeNBT() nbt[BATTERY_KEY] = batteryContainer.serializeNBT()
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
nbt.ifHas("energy", CompoundTag::class.java, energy::deserializeNBT) nbt.ifHas(ENERGY_KEY, CompoundTag::class.java, energy::deserializeNBT)
batteryContainer.deserializeNBT(nbt["battery_container"]) batteryContainer.deserializeNBT(nbt[BATTERY_KEY])
super.load(nbt) super.load(nbt)
} }
} }

View File

@ -23,14 +23,19 @@ abstract class MatteryWorkerBlockEntity<JobType : MatteryWorkerBlockEntity.Job>(
) { ) {
constructor( constructor(
tag: CompoundTag tag: CompoundTag
) : this(tag.getDouble("ticks"), tag.getImpreciseFraction("power")) ) : this(tag.getDouble(TICKS_KEY), tag.getImpreciseFraction(POWER_KEY))
open fun serializeNBT(): CompoundTag { open fun serializeNBT(): CompoundTag {
return CompoundTag().also { return CompoundTag().also {
it["ticks"] = ticks it[TICKS_KEY] = ticks
it["power"] = powerUsage it[POWER_KEY] = powerUsage
} }
} }
companion object {
const val TICKS_KEY = "ticks"
const val POWER_KEY = "power"
}
} }
@Suppress("LeakingThis") @Suppress("LeakingThis")
@ -53,9 +58,13 @@ abstract class MatteryWorkerBlockEntity<JobType : MatteryWorkerBlockEntity.Job>(
override fun serializeNBT(): CompoundTag { override fun serializeNBT(): CompoundTag {
return super.serializeNBT().also { return super.serializeNBT().also {
it["item"] = itemStack.serializeNBT() it[ITEM_KEY] = itemStack.serializeNBT()
} }
} }
companion object {
const val ITEM_KEY = "item"
}
} }
enum class IdleReason { enum class IdleReason {
@ -108,15 +117,15 @@ abstract class MatteryWorkerBlockEntity<JobType : MatteryWorkerBlockEntity.Job>(
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["work_ticks"] = workTicks nbt[WORK_TICKS_KEY] = workTicks
currentJob?.let { nbt["job"] = it.serializeNBT() } currentJob?.let { nbt[JOB_KEY] = it.serializeNBT() }
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
super.load(nbt) super.load(nbt)
workTicks = nbt.getDouble("work_ticks") workTicks = nbt.getDouble(WORK_TICKS_KEY)
currentJob = nbt.map("job", jobDeserializer::invoke) currentJob = nbt.map(JOB_KEY, jobDeserializer::invoke)
if (currentJob == null) if (currentJob == null)
workTicks = 0.0 workTicks = 0.0
@ -179,9 +188,9 @@ abstract class MatteryWorkerBlockEntity<JobType : MatteryWorkerBlockEntity.Job>(
private var workingTicksAnim = 0 private var workingTicksAnim = 0
private var errorTicksAnim = 0 private var errorTicksAnim = 0
override fun redstoneStatusUpdated(new_blocked: Boolean, old_blocked: Boolean) { override fun redstoneStatusUpdated(newBlocked: Boolean, oldBlocked: Boolean) {
super.redstoneStatusUpdated(new_blocked, old_blocked) super.redstoneStatusUpdated(newBlocked, oldBlocked)
isIdling = new_blocked isIdling = newBlocked
} }
protected fun workerLoop() { protected fun workerLoop() {
@ -339,4 +348,9 @@ abstract class MatteryWorkerBlockEntity<JobType : MatteryWorkerBlockEntity.Job>(
batteryChargeLoop() batteryChargeLoop()
workerLoop() workerLoop()
} }
companion object {
const val WORK_TICKS_KEY = "workTicks"
const val JOB_KEY = "job"
}
} }

View File

@ -4,6 +4,7 @@ import net.minecraft.core.BlockPos
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.world.Container
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
@ -12,6 +13,7 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.capabilities.ForgeCapabilities import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
import ru.dbotthepony.mc.otm.block.IDroppableContainer
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
@ -21,15 +23,18 @@ import ru.dbotthepony.mc.otm.menu.PlatePressMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.registry.MRecipes import ru.dbotthepony.mc.otm.registry.MRecipes
import ru.dbotthepony.mc.otm.container.set import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.core.map
import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.set
class PlatePressBlockEntity( class PlatePressBlockEntity(
p_155229_: BlockPos, p_155229_: BlockPos,
p_155230_: BlockState p_155230_: BlockState
) : MatteryWorkerBlockEntity<MatteryWorkerBlockEntity.ItemJob>(MBlockEntities.PLATE_PRESS, p_155229_, p_155230_, ::ItemJob) { ) : MatteryWorkerBlockEntity<MatteryWorkerBlockEntity.ItemJob>(MBlockEntities.PLATE_PRESS, p_155229_, p_155230_, ::ItemJob), IDroppableContainer {
val container = MatteryContainer(this::setChangedLight, 2) val container = MatteryContainer(this::setChangedLight, 2)
override val energy = WorkerEnergyStorage(this::setChangedLight) override val energy = WorkerEnergyStorage(this::setChangedLight)
override val droppableContainer: Container
get() = container
val itemHandler = container.handler(object : MatteryContainerFilter { val itemHandler = container.handler(object : MatteryContainerFilter {
override fun canInsert(slot: Int, stack: ItemStack): Boolean { override fun canInsert(slot: Int, stack: ItemStack): Boolean {
return slot != SLOT_OUTPUT return slot != SLOT_OUTPUT
@ -59,12 +64,12 @@ class PlatePressBlockEntity(
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["container"] = container.serializeNBT() nbt[INVENTORY_KEY] = container.serializeNBT()
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
super.load(nbt) super.load(nbt)
container.deserializeNBT(nbt["container"]) nbt.map(INVENTORY_KEY, container::deserializeNBT)
} }
override val defaultDisplayName: Component override val defaultDisplayName: Component

View File

@ -15,7 +15,6 @@ enum class RedstoneSetting(val label: Component, val description: Component) {
companion object { companion object {
private val values = values() private val values = values()
@JvmStatic
operator fun get(index: Int): RedstoneSetting { operator fun get(index: Int): RedstoneSetting {
if (index !in 0 .. 2) if (index !in 0 .. 2)
return LOW return LOW

View File

@ -5,6 +5,7 @@ import net.minecraft.core.Direction
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
import net.minecraft.world.Container
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
@ -13,8 +14,10 @@ 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.state.BlockState import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.items.CapabilityItemHandler import net.minecraftforge.items.CapabilityItemHandler
import ru.dbotthepony.mc.otm.block.IDroppableContainer
import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.block.entity.WorkerState import ru.dbotthepony.mc.otm.block.entity.WorkerState
@ -24,31 +27,29 @@ import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
import ru.dbotthepony.mc.otm.capability.matter.MatterDirection import ru.dbotthepony.mc.otm.capability.matter.MatterDirection
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerImpl import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerImpl
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
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.IMatterGraphNode
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu
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.core.* import ru.dbotthepony.mc.otm.core.*
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_), IMatterGraphNode, IDroppableContainer {
override val matterNode = Graph6Node<IMatterGraphNode>(this) override val matterNode = Graph6Node<IMatterGraphNode>(this)
private val resolverNode = LazyOptional.of { this } private val resolverNode = LazyOptional.of { this }
override val energy = WorkerEnergyStorage(this) override val energy = WorkerEnergyStorage(this)
// true - bottling var isBottling: Boolean = true
// false - unbottling
var workFlow: Boolean = true
set(value) { set(value) {
field = value field = value
this.setChangedLight() this.setChangedLight()
} }
fun switchWorkFlow() { fun switchWorkFlow() {
workFlow = !workFlow isBottling = !isBottling
updateBlockState() updateBlockState()
} }
@ -56,7 +57,7 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
val level = level as? ServerLevel ?: return val level = level as? ServerLevel ?: return
var state = blockState var state = blockState
val initial = if (workFlow) 0 else 3 val initial = if (isBottling) 0 else 3
for (i in initial .. initial + 2) { for (i in initial .. initial + 2) {
val desired = !container.getItem(i).isEmpty && container.getItem(i).getCapability(MatteryCapability.MATTER).isPresent val desired = !container.getItem(i).isEmpty && container.getItem(i).getCapability(MatteryCapability.MATTER).isPresent
@ -76,7 +77,6 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
// false - spit into output slot // false - spit into output slot
//private var work_behavior = true //private var work_behavior = true
@JvmField
val container: MatteryContainer = object : MatteryContainer(this::setChangedLight, 6) { val container: MatteryContainer = object : MatteryContainer(this::setChangedLight, 6) {
override fun getMaxStackSize(slot: Int): Int { override fun getMaxStackSize(slot: Int): Int {
return 1 return 1
@ -88,25 +88,32 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
} }
} }
val itemHandler = container.handler({ slot: Int, stack: ItemStack -> override val droppableContainer: Container
if (this.workFlow) { get() = container
return@handler slot < 3 && stack.getCapability(MatteryCapability.MATTER).isPresent
val itemHandler = container.handler(object : MatteryContainerFilter {
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
if (isBottling) {
return slot < 3 && stack.getCapability(MatteryCapability.MATTER).isPresent
}
return slot >= 3 && stack.getCapability(MatteryCapability.MATTER).isPresent
} }
slot >= 3 && stack.getCapability(MatteryCapability.MATTER).isPresent
}, { slot: Int, amount: Int, stack: ItemStack? -> override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
if (this.workFlow) { if (isBottling) {
return@handler slot >= 3 return slot >= 3
}
return slot < 3
} }
slot < 3
}) })
@JvmField val matter: MatterHandlerImpl = object : MatterHandlerImpl(this::setChangedLight, MatterDirection.BIDIRECTIONAL, CAPACITY) {
val matter: MatterHandlerImpl = override val direction: MatterDirection get() {
object : MatterHandlerImpl(this::setChangedLight, MatterDirection.BIDIRECTIONAL, CAPACITY) { return if (this@MatterBottlerBlockEntity.isBottling) MatterDirection.RECEIVE else MatterDirection.EXTRACT
override val direction: MatterDirection get() {
return if (this@MatterBottlerBlockEntity.workFlow) MatterDirection.RECEIVE else MatterDirection.EXTRACT
}
} }
}
private var initialCapacity: ImpreciseFraction? = null private var initialCapacity: ImpreciseFraction? = null
private var lastWorkStack: ItemStack? = null private var lastWorkStack: ItemStack? = null
@ -140,15 +147,15 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> { override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
if (valid) { if (valid) {
if (cap === MatteryCapability.MATTER) { if (cap == MatteryCapability.MATTER) {
return matter.get().cast() return matter.get().cast()
} }
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { if (cap == ForgeCapabilities.ITEM_HANDLER) {
return itemHandler.get().cast() return itemHandler.get().cast()
} }
if (cap === MatteryCapability.MATTER_NODE) { if (cap == MatteryCapability.MATTER_NODE) {
return resolverNode.cast() return resolverNode.cast()
} }
} }
@ -165,16 +172,16 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["work_slots"] = container.serializeNBT() nbt[INVENTORY_KEY] = container.serializeNBT()
nbt["work_flow"] = this.workFlow nbt[IS_BOTTLING_KEY] = isBottling
nbt["matter"] = matter.serializeNBT() nbt[MATTER_STORAGE_KEY] = matter.serializeNBT()
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
super.load(nbt) super.load(nbt)
container.deserializeNBT(nbt["work_slots"]) isBottling = nbt.getBoolean(IS_BOTTLING_KEY)
workFlow = nbt.getBoolean("work_flow") nbt.map(MATTER_STORAGE_KEY, matter::deserializeNBT)
nbt.ifHas("matter", CompoundTag::class.java, matter::deserializeNBT) nbt.map(INVENTORY_KEY, container::deserializeNBT)
} }
fun getWorkProgress(): Float { fun getWorkProgress(): Float {
@ -182,7 +189,7 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
val initialCapacity = initialCapacity ?: return 0f val initialCapacity = initialCapacity ?: return 0f
val cap = lastWorkStack.getCapability(MatteryCapability.MATTER).orNull() ?: return 0f val cap = lastWorkStack.getCapability(MatteryCapability.MATTER).orNull() ?: return 0f
if (this.workFlow) { if (this.isBottling) {
if (cap.maxStoredMatter - initialCapacity <= ImpreciseFraction.ZERO) { if (cap.maxStoredMatter - initialCapacity <= ImpreciseFraction.ZERO) {
return 0f return 0f
} }
@ -219,9 +226,9 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
var work_stack: ItemStack? = null var work_stack: ItemStack? = null
var capability: IMatterHandler? = null var capability: IMatterHandler? = null
val align = if (workFlow) 0 else 3 val align = if (isBottling) 0 else 3
var work_slot = -1 var work_slot = -1
val unexpectedDirection = if (workFlow) MatterDirection.EXTRACT else MatterDirection.RECEIVE val unexpectedDirection = if (isBottling) MatterDirection.EXTRACT else MatterDirection.RECEIVE
for (i in align until align + 3) { for (i in align until align + 3) {
val itemStack = container.getItem(i) val itemStack = container.getItem(i)
@ -230,7 +237,7 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
val cap = itemStack.getCapability(MatteryCapability.MATTER).orNull() ?: continue val cap = itemStack.getCapability(MatteryCapability.MATTER).orNull() ?: continue
if (cap.direction !== unexpectedDirection) { if (cap.direction !== unexpectedDirection) {
if (this.workFlow && cap.missingMatter > ImpreciseFraction.ZERO || !this.workFlow && cap.storedMatter > ImpreciseFraction.ZERO) { if (this.isBottling && cap.missingMatter > ImpreciseFraction.ZERO || !this.isBottling && cap.storedMatter > ImpreciseFraction.ZERO) {
work_stack = itemStack work_stack = itemStack
capability = cap capability = cap
work_slot = i work_slot = i
@ -255,7 +262,7 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS) level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS)
} }
if (workFlow) { if (isBottling) {
if (matter.storedMatter < MATTER_EXCHANGE_RATE && graph != null) { if (matter.storedMatter < MATTER_EXCHANGE_RATE && graph != null) {
val extracted = graph.extractMatter( val extracted = graph.extractMatter(
matter.missingMatter.coerceAtMost(MATTER_EXCHANGE_RATE * EXTRACTION_TICKS).coerceAtMost(capability.missingMatter - matter.storedMatter), true matter.missingMatter.coerceAtMost(MATTER_EXCHANGE_RATE * EXTRACTION_TICKS).coerceAtMost(capability.missingMatter - matter.storedMatter), true
@ -319,7 +326,7 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
level!!.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS) level!!.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS)
} }
if (!workFlow && !matter.storedMatter.isZero && graph != null) { if (!isBottling && !matter.storedMatter.isZero && graph != null) {
val diff = matter.extractMatterInner(matter.storedMatter, true) val diff = matter.extractMatterInner(matter.storedMatter, true)
val diff2 = graph.receiveMatter(diff, true) val diff2 = graph.receiveMatter(diff, true)
matter.extractMatterInner(diff2, false) matter.extractMatterInner(diff2, false)
@ -333,5 +340,7 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
private val ENERGY_CONSUMPTION = ImpreciseFraction(20) private val ENERGY_CONSUMPTION = ImpreciseFraction(20)
private val EXTRACTION_TICKS = ImpreciseFraction(200) private val EXTRACTION_TICKS = ImpreciseFraction(200)
private val CAPACITY = ImpreciseFraction(4) private val CAPACITY = ImpreciseFraction(4)
const val IS_BOTTLING_KEY = "isBottling"
} }
} }

View File

@ -6,6 +6,7 @@ import net.minecraft.core.Direction
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
import net.minecraft.world.Container
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,6 +18,7 @@ import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.block.BatteryBankBlock import ru.dbotthepony.mc.otm.block.BatteryBankBlock
import ru.dbotthepony.mc.otm.block.IDroppableContainer
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
@ -29,13 +31,12 @@ import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
import ru.dbotthepony.mc.otm.menu.MatterCapacitorBankMenu import ru.dbotthepony.mc.otm.menu.MatterCapacitorBankMenu
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
import ru.dbotthepony.mc.otm.core.map
import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.set
import javax.annotation.ParametersAreNonnullByDefault import javax.annotation.ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
MatteryBlockEntity(MBlockEntities.MATTER_CAPACITOR_BANK, p_155229_, p_155230_), IMatterGraphNode, IMatterHandler { MatteryBlockEntity(MBlockEntities.MATTER_CAPACITOR_BANK, p_155229_, p_155230_), IMatterGraphNode, IMatterHandler, IDroppableContainer {
override val matterNode = Graph6Node<IMatterGraphNode>(this) override val matterNode = Graph6Node<IMatterGraphNode>(this)
private val resolverNode = LazyOptional.of { this } private val resolverNode = LazyOptional.of { this }
@ -69,7 +70,8 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
} }
override fun receiveMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { override fun receiveMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
@Suppress("NAME_SHADOWING") var howMuch = howMuch @Suppress("NAME_SHADOWING")
var howMuch = howMuch
var summ = ImpreciseFraction.ZERO var summ = ImpreciseFraction.ZERO
for (stack in container) { for (stack in container) {
@ -94,7 +96,8 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
} }
override fun extractMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { override fun extractMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
@Suppress("NAME_SHADOWING") var howMuch = howMuch @Suppress("NAME_SHADOWING")
var howMuch = howMuch
var summ = ImpreciseFraction.ZERO var summ = ImpreciseFraction.ZERO
for (stack in container) { for (stack in container) {
@ -119,7 +122,6 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
private var resolver = LazyOptional.of { this } private var resolver = LazyOptional.of { this }
@JvmField
val container = object : MatteryContainer(this::setChangedLight, 6 * 2) { val container = object : MatteryContainer(this::setChangedLight, 6 * 2) {
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) { override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
super.setChanged(slot, new, old) super.setChanged(slot, new, old)
@ -142,21 +144,19 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
} }
} }
companion object { override val droppableContainer: Container
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.matter_capacitor_bank") get() = container
}
override val defaultDisplayName: Component override val defaultDisplayName: Component
get() = MACHINE_NAME get() = MACHINE_NAME
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["container"] = container.serializeNBT() nbt[INVENTORY_KEY] = container.serializeNBT()
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
container.deserializeNBT(nbt["container"])
super.load(nbt) super.load(nbt)
nbt.map(INVENTORY_KEY, container::deserializeNBT)
} }
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu { override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
@ -201,4 +201,8 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
override fun getMatterHandler(): IMatterHandler { override fun getMatterHandler(): IMatterHandler {
return this return this
} }
companion object {
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.matter_capacitor_bank")
}
} }

View File

@ -5,6 +5,7 @@ import net.minecraft.core.Direction
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
import net.minecraft.world.Container
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
@ -15,6 +16,7 @@ import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.capabilities.ForgeCapabilities import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.items.IItemHandler import net.minecraftforge.items.IItemHandler
import ru.dbotthepony.mc.otm.block.IDroppableContainer
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
@ -90,15 +92,15 @@ fun moveMatterAsDustIntoContainer(_matterValue: ImpreciseFraction, container: Ma
} }
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), IMatterGraphNode, IDroppableContainer {
class DecomposerJob : Job { class DecomposerJob : Job {
val toDust: Boolean val toDust: Boolean
var matterValue: ImpreciseFraction var matterValue: ImpreciseFraction
constructor(tag: CompoundTag) : super(tag) { constructor(tag: CompoundTag) : super(tag) {
toDust = tag.getBoolean("to_dust") toDust = tag.getBoolean(TO_DUST_KEY)
matterValue = tag.getImpreciseFraction("value") matterValue = tag.getImpreciseFraction(MATTER_VALUE_KEY)
} }
constructor(toDust: Boolean, matterValue: ImpreciseFraction, ticks: Double) : super(ticks, BASE_CONSUMPTION) { constructor(toDust: Boolean, matterValue: ImpreciseFraction, ticks: Double) : super(ticks, BASE_CONSUMPTION) {
@ -108,22 +110,22 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
override fun serializeNBT(): CompoundTag { override fun serializeNBT(): CompoundTag {
return super.serializeNBT().also { return super.serializeNBT().also {
it["to_dust"] = toDust it[TO_DUST_KEY] = toDust
it["value"] = matterValue it[MATTER_VALUE_KEY] = matterValue
} }
} }
companion object {
const val TO_DUST_KEY = "toDust"
const val MATTER_VALUE_KEY = "matterValue"
}
} }
override val energy = WorkerEnergyStorage(this, ENERGY_STORAGE, MAX_IO) override val energy = WorkerEnergyStorage(this, ENERGY_STORAGE, MAX_IO)
private var valid = true private var valid = true
override val matterNode = Graph6Node<IMatterGraphNode>(this) override val matterNode = Graph6Node<IMatterGraphNode>(this)
@JvmField val matter = MatterHandlerImpl(this::setChangedLight, MatterDirection.EXTRACT, CAPACITY)
val matter = MatterHandlerImpl(
this::setChangedLight,
MatterDirection.EXTRACT,
CAPACITY
)
private var resolverMatter = LazyOptional.of { matter } private var resolverMatter = LazyOptional.of { matter }
private var resolverNode = LazyOptional.of { this } private var resolverNode = LazyOptional.of { this }
@ -131,6 +133,9 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
// вход, выход // вход, выход
val container = MatteryContainer(this::setChangedLight, 3) val container = MatteryContainer(this::setChangedLight, 3)
override val droppableContainer: Container
get() = container
private val itemHandler = LazyOptional.of<IItemHandler> { private val itemHandler = LazyOptional.of<IItemHandler> {
container.handler(object : MatteryContainerFilter { container.handler(object : MatteryContainerFilter {
override fun canInsert(slot: Int, stack: ItemStack): Boolean { override fun canInsert(slot: Int, stack: ItemStack): Boolean {
@ -152,18 +157,14 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["container"] = container.serializeNBT() nbt[INVENTORY_KEY] = container.serializeNBT()
nbt["matter"] = matter.serializeNBT() nbt[MATTER_STORAGE_KEY] = matter.serializeNBT()
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
super.load(nbt) super.load(nbt)
nbt.map(INVENTORY_KEY, container::deserializeNBT)
nbt.ifHas("matter", CompoundTag::class.java) { nbt.map(MATTER_STORAGE_KEY, matter::deserializeNBT)
matter.deserializeNBT(it)
}
container.deserializeNBT(nbt["container"])
} }
override fun reviveCaps() { override fun reviveCaps() {

View File

@ -5,6 +5,7 @@ import net.minecraft.core.Direction
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
import net.minecraft.world.Container
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
@ -14,6 +15,7 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.capabilities.ForgeCapabilities import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
import ru.dbotthepony.mc.otm.block.IDroppableContainer
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
@ -35,7 +37,7 @@ import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.set
class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState) class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
: MatteryWorkerBlockEntity<MatteryWorkerBlockEntity.Job>(MBlockEntities.MATTER_RECYCLER, blockPos, blockState, ::Job), IMatterGraphNode { : MatteryWorkerBlockEntity<MatteryWorkerBlockEntity.Job>(MBlockEntities.MATTER_RECYCLER, blockPos, blockState, ::Job), IMatterGraphNode, IDroppableContainer {
val matter = MatterHandlerImpl( val matter = MatterHandlerImpl(
this::matterLevelUpdated, this::matterLevelUpdated,
@ -44,6 +46,9 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
) )
val container = MatteryContainer(this::itemContainerUpdated, 1) val container = MatteryContainer(this::itemContainerUpdated, 1)
override val droppableContainer: Container
get() = container
override val matterNode = Graph6Node<IMatterGraphNode>(this) override val matterNode = Graph6Node<IMatterGraphNode>(this)
private var resolverNode = LazyOptional.of { this } private var resolverNode = LazyOptional.of { this }
private var valid = true private var valid = true
@ -91,14 +96,14 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["matter"] = matter.serializeNBT() nbt[MATTER_STORAGE_KEY] = matter.serializeNBT()
nbt["container"] = container.serializeNBT() nbt[INVENTORY_KEY] = container.serializeNBT()
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
super.load(nbt) super.load(nbt)
nbt.map("matter", matter::deserializeNBT) nbt.map(MATTER_STORAGE_KEY, matter::deserializeNBT)
container.deserializeNBT(nbt["container"]) nbt.map(INVENTORY_KEY, container::deserializeNBT)
} }
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> { override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {

View File

@ -5,6 +5,7 @@ import net.minecraft.core.Direction
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
import net.minecraft.world.Container
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
@ -14,6 +15,7 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.capabilities.ForgeCapabilities import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
import ru.dbotthepony.mc.otm.block.IDroppableContainer
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
@ -37,7 +39,7 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
} catch(err: NoSuchElementException) { } catch(err: NoSuchElementException) {
null null
} }
}), IMatterGraphNode { }), IMatterGraphNode, IDroppableContainer {
class ReplicatorJob : ItemJob { class ReplicatorJob : ItemJob {
val matterPerTick: ImpreciseFraction val matterPerTick: ImpreciseFraction
@ -47,11 +49,11 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
val asDust: Boolean val asDust: Boolean
constructor(tag: CompoundTag) : super(tag) { constructor(tag: CompoundTag) : super(tag) {
matterPerTick = tag.getImpreciseFraction("matterPerTick") matterPerTick = tag.getImpreciseFraction(MATTER_PER_TICK_KEY)
matterValue = tag.getImpreciseFraction("matterValue") matterValue = tag.getImpreciseFraction(MATTER_VALUE_KEY)
pattern = tag.map("pattern", PatternState::deserializeNBT) pattern = tag.map(PATTERN_KEY, PatternState::deserializeNBT)
asDust = tag.getBoolean("asDust") asDust = tag.getBoolean(AS_DUST_KEY)
task = tag.map("task", ReplicationTask::deserializeNBT) ?: throw NoSuchElementException("Unable to deserialize matter task") task = tag.map(TASK_KEY, ReplicationTask::deserializeNBT) ?: throw NoSuchElementException("Unable to deserialize matter task")
} }
constructor( constructor(
@ -72,16 +74,24 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
override fun serializeNBT(): CompoundTag { override fun serializeNBT(): CompoundTag {
return super.serializeNBT().also { return super.serializeNBT().also {
it["matterPerTick"] = this.matterPerTick it[MATTER_PER_TICK_KEY] = this.matterPerTick
it["task"] = this.task.serializeNBT() it[TASK_KEY] = this.task.serializeNBT()
it["matterValue"] = this.matterValue it[MATTER_VALUE_KEY] = this.matterValue
if (this.pattern != null) if (this.pattern != null)
it["pattern"] = this.pattern.serializeNBT() it[PATTERN_KEY] = this.pattern.serializeNBT()
it["asDust"] = this.asDust it[AS_DUST_KEY] = this.asDust
} }
} }
companion object {
const val MATTER_PER_TICK_KEY = "matterPerTick"
const val MATTER_VALUE_KEY = "matterValue"
const val PATTERN_KEY = "pattern"
const val AS_DUST_KEY = "asDust"
const val TASK_KEY = "task"
}
} }
override val energy = WorkerEnergyStorage(this::powerLevelUpdated, STORAGE, MAX_IO) override val energy = WorkerEnergyStorage(this::powerLevelUpdated, STORAGE, MAX_IO)
@ -100,6 +110,9 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
override val defaultDisplayName: Component override val defaultDisplayName: Component
get() = MACHINE_NAME get() = MACHINE_NAME
override val droppableContainer: Container
get() = container
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu { override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
return MatterReplicatorMenu(containerID, inventory, this) return MatterReplicatorMenu(containerID, inventory, this)
} }
@ -232,14 +245,14 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["container"] = container.serializeNBT() nbt[INVENTORY_KEY] = container.serializeNBT()
nbt["matter"] = matter.serializeNBT() nbt[MATTER_STORAGE_KEY] = matter.serializeNBT()
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
super.load(nbt) super.load(nbt)
container.deserializeNBT(nbt["container"]) nbt.map(INVENTORY_KEY, container::deserializeNBT)
nbt.map("matter", matter::deserializeNBT) nbt.map(MATTER_STORAGE_KEY, matter::deserializeNBT)
} }
private var valid = true private var valid = true

View File

@ -5,6 +5,7 @@ import net.minecraft.core.Direction
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
import net.minecraft.world.Container
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
@ -14,6 +15,7 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.capabilities.ForgeCapabilities import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
import ru.dbotthepony.mc.otm.block.IDroppableContainer
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
@ -23,6 +25,7 @@ import ru.dbotthepony.mc.otm.capability.matter.PatternState
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.map
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.IMatterGraphNode
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
@ -32,7 +35,7 @@ import ru.dbotthepony.mc.otm.registry.MBlockEntities
import java.util.* import java.util.*
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), IMatterGraphNode, IDroppableContainer {
val container = MatteryContainer(this::itemContainerUpdated, 1) val container = MatteryContainer(this::itemContainerUpdated, 1)
override val energy = WorkerEnergyStorage(this::powerLevelUpdated, STORAGE, MAX_IO) override val energy = WorkerEnergyStorage(this::powerLevelUpdated, STORAGE, MAX_IO)
@ -47,6 +50,9 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
} }
}) })
override val droppableContainer: Container
get() = container
// IMatterGraphNode // IMatterGraphNode
override fun onPatternAdded(state: IPatternState) { override fun onPatternAdded(state: IPatternState) {
if (idleReason == IdleReason.OBSERVING) { if (idleReason == IdleReason.OBSERVING) {
@ -109,12 +115,12 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt.put("container", container.serializeNBT()) nbt.put(INVENTORY_KEY, container.serializeNBT())
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
container.deserializeNBT(nbt["container"])
super.load(nbt) super.load(nbt)
nbt.map(INVENTORY_KEY, container::deserializeNBT)
} }
override fun onJobFinish(job: ItemJob): Status { override fun onJobFinish(job: ItemJob): Status {

View File

@ -1,4 +1,4 @@
package ru.dbotthepony.mc.otm.block.entity package ru.dbotthepony.mc.otm.block.entity.matter
import com.google.common.collect.Streams import com.google.common.collect.Streams
import javax.annotation.ParametersAreNonnullByDefault import javax.annotation.ParametersAreNonnullByDefault
@ -18,17 +18,20 @@ import net.minecraft.MethodsReturnNonnullByDefault
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.server.level.ServerLevel
import net.minecraft.world.Container
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.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.capabilities.ForgeCapabilities import net.minecraftforge.common.capabilities.ForgeCapabilities
import ru.dbotthepony.mc.otm.block.IDroppableContainer
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.capability.matter.* import ru.dbotthepony.mc.otm.capability.matter.*
import ru.dbotthepony.mc.otm.core.iterator import ru.dbotthepony.mc.otm.core.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.IMatterGraphNode
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
import ru.dbotthepony.mc.otm.core.ifHas import ru.dbotthepony.mc.otm.core.map
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.set
import java.util.ArrayList import java.util.ArrayList
@ -37,7 +40,7 @@ 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) :
MatteryBlockEntity(MBlockEntities.PATTERN_STORAGE, p_155229_, p_155230_), IMatterGraphNode, IPatternStorage { MatteryBlockEntity(MBlockEntities.PATTERN_STORAGE, p_155229_, p_155230_), IMatterGraphNode, IPatternStorage, IDroppableContainer {
override val matterNode = Graph6Node<IMatterGraphNode>(this) override val matterNode = Graph6Node<IMatterGraphNode>(this)
private val resolverPatterns = LazyOptional.of { this } private val resolverPatterns = LazyOptional.of { this }
@ -89,21 +92,21 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
} }
private val resolverItem = private val resolverItem =
this.patternContainer.handler { slot: Int, stack: ItemStack -> stack.getCapability(MatteryCapability.PATTERN).isPresent } patternContainer.handler { slot: Int, stack: ItemStack -> stack.getCapability(MatteryCapability.PATTERN).isPresent }
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["patterns"] = this.patternContainer.serializeNBT() nbt[INVENTORY_KEY] = patternContainer.serializeNBT()
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
super.load(nbt) super.load(nbt)
nbt.map(INVENTORY_KEY, patternContainer::deserializeNBT)
nbt.ifHas("patterns") {
this.patternContainer.deserializeNBT(it)
}
} }
override val droppableContainer: Container
get() = patternContainer
override fun setLevel(p_155231_: Level) { override fun setLevel(p_155231_: Level) {
super.setLevel(p_155231_) super.setLevel(p_155231_)

View File

@ -20,9 +20,8 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.ifHas
import ru.dbotthepony.mc.otm.menu.DriveRackMenu import ru.dbotthepony.mc.otm.menu.DriveRackMenu
import ru.dbotthepony.mc.otm.container.set import ru.dbotthepony.mc.otm.core.map
import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
@ -32,8 +31,7 @@ class DriveRackBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
MatteryPoweredBlockEntity(MBlockEntities.DRIVE_RACK, p_155229_, p_155230_) { MatteryPoweredBlockEntity(MBlockEntities.DRIVE_RACK, p_155229_, p_155230_) {
override val energy = WorkerEnergyStorage(this, STORAGE) override val energy = WorkerEnergyStorage(this, STORAGE)
@JvmField val container: MatteryContainer = object : MatteryContainer(this::setChanged, 4) {
val drives: MatteryContainer = object : MatteryContainer(this::setChanged, 4) {
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) { override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
super.setChanged(slot, new, old) super.setChanged(slot, new, old)
@ -55,15 +53,12 @@ class DriveRackBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
super.load(nbt) super.load(nbt)
nbt.map(INVENTORY_KEY, container::deserializeNBT)
nbt.ifHas("drives", CompoundTag::class.java) {
drives.deserializeNBT(it)
}
} }
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["drives"] = drives.serializeNBT() nbt[INVENTORY_KEY] = container.serializeNBT()
} }
override fun setLevel(p_155231_: Level) { override fun setLevel(p_155231_: Level) {

View File

@ -4,6 +4,7 @@ import net.minecraft.MethodsReturnNonnullByDefault
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.world.Container
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
@ -11,6 +12,7 @@ import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.BlockState
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.block.IDroppableContainer
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.block.storage.DriveViewerBlock import ru.dbotthepony.mc.otm.block.storage.DriveViewerBlock
@ -21,12 +23,11 @@ import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.menu.DriveViewerMenu import ru.dbotthepony.mc.otm.menu.DriveViewerMenu
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
import ru.dbotthepony.mc.otm.core.map
import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.set
import javax.annotation.ParametersAreNonnullByDefault import javax.annotation.ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault class DriveViewerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.DRIVE_VIEWER, p_155229_, p_155230_), IDroppableContainer {
@ParametersAreNonnullByDefault
class DriveViewerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.DRIVE_VIEWER, p_155229_, p_155230_) {
override fun setChanged() { override fun setChanged() {
super.setChanged() super.setChanged()
@ -47,7 +48,6 @@ class DriveViewerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
override val energy = WorkerEnergyStorage(this) override val energy = WorkerEnergyStorage(this)
@JvmField
val container: MatteryContainer = object : MatteryContainer(this::setChanged, 1) { val container: MatteryContainer = object : MatteryContainer(this::setChanged, 1) {
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) { override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
super.setChanged(slot, new, old) super.setChanged(slot, new, old)
@ -70,6 +70,8 @@ class DriveViewerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
} }
} }
override val droppableContainer: Container
get() = container
override val defaultDisplayName: Component override val defaultDisplayName: Component
get() = MACHINE_NAME get() = MACHINE_NAME
@ -79,13 +81,12 @@ class DriveViewerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["container"] = container.serializeNBT() nbt[INVENTORY_KEY] = container.serializeNBT()
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
super.load(nbt) super.load(nbt)
nbt.map(INVENTORY_KEY, container::deserializeNBT)
container.deserializeNBT(nbt["container"])
} }
fun tick() { fun tick() {

View File

@ -40,6 +40,7 @@ import ru.dbotthepony.mc.otm.menu.ItemMonitorMenu
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
import ru.dbotthepony.mc.otm.core.getEnum
import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.storage.* import ru.dbotthepony.mc.otm.storage.*
import java.math.BigInteger import java.math.BigInteger
@ -48,7 +49,7 @@ import java.util.function.Supplier
import kotlin.collections.HashMap import kotlin.collections.HashMap
class ItemMonitorPlayerSettings : INBTSerializable<CompoundTag>, MatteryPacket { class ItemMonitorPlayerSettings : INBTSerializable<CompoundTag>, MatteryPacket {
enum class RefillSource(val component: Component) { enum class IngredientPriority(val component: Component) {
// Refill everything from system // Refill everything from system
SYSTEM(TranslatableComponent("otm.gui.item_monitor.refill_source.system")), SYSTEM(TranslatableComponent("otm.gui.item_monitor.refill_source.system")),
@ -83,38 +84,38 @@ class ItemMonitorPlayerSettings : INBTSerializable<CompoundTag>, MatteryPacket {
FULL(TranslatableComponent("otm.gui.item_monitor.amount.full")) FULL(TranslatableComponent("otm.gui.item_monitor.amount.full"))
} }
var refillSource = RefillSource.SYSTEM var ingredientPriority = IngredientPriority.SYSTEM
var resultTarget = ResultTarget.MIXED var resultTarget = ResultTarget.MIXED
var craftingAmount = Amount.STACK var craftingAmount = Amount.STACK
override fun serializeNBT(): CompoundTag { override fun serializeNBT(): CompoundTag {
return CompoundTag().also { return CompoundTag().also {
it["ingredientPriority"] = refillSource.name it[INGREDIENT_PRIORITY_KEY] = ingredientPriority.name
it["resultTarget"] = resultTarget.name it[RESULT_TARGET_KEY] = resultTarget.name
it["craftingAmount"] = craftingAmount.name it[QUICK_CRAFT_AMOUNT_KEY] = craftingAmount.name
} }
} }
override fun deserializeNBT(nbt: CompoundTag) { override fun deserializeNBT(nbt: CompoundTag) {
nbt.ifHas("ingredientPriority", StringTag::class.java) { refillSource = RefillSource.valueOf(it.asString) } ingredientPriority = nbt.getEnum(INGREDIENT_PRIORITY_KEY)
nbt.ifHas("resultTarget", StringTag::class.java) { resultTarget = ResultTarget.valueOf(it.asString) } resultTarget = nbt.getEnum(RESULT_TARGET_KEY)
nbt.ifHas("craftingAmount", StringTag::class.java) { craftingAmount = Amount.valueOf(it.asString) } craftingAmount = nbt.getEnum(QUICK_CRAFT_AMOUNT_KEY)
} }
fun read(buff: FriendlyByteBuf) { fun read(buff: FriendlyByteBuf) {
refillSource = buff.readEnum(RefillSource::class.java) ingredientPriority = buff.readEnum(IngredientPriority::class.java)
resultTarget = buff.readEnum(ResultTarget::class.java) resultTarget = buff.readEnum(ResultTarget::class.java)
craftingAmount = buff.readEnum(Amount::class.java) craftingAmount = buff.readEnum(Amount::class.java)
} }
fun read(other: ItemMonitorPlayerSettings) { fun read(other: ItemMonitorPlayerSettings) {
refillSource = other.refillSource ingredientPriority = other.ingredientPriority
resultTarget = other.resultTarget resultTarget = other.resultTarget
craftingAmount = other.craftingAmount craftingAmount = other.craftingAmount
} }
override fun write(buff: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buff.writeEnum(refillSource) buff.writeEnum(ingredientPriority)
buff.writeEnum(resultTarget) buff.writeEnum(resultTarget)
buff.writeEnum(craftingAmount) buff.writeEnum(craftingAmount)
} }
@ -149,6 +150,9 @@ class ItemMonitorPlayerSettings : INBTSerializable<CompoundTag>, MatteryPacket {
} }
private val LOGGER = LogManager.getLogger() private val LOGGER = LogManager.getLogger()
const val INGREDIENT_PRIORITY_KEY = "ingredientPriority"
const val RESULT_TARGET_KEY = "resultTarget"
const val QUICK_CRAFT_AMOUNT_KEY = "quickCraftAmount"
} }
} }
@ -336,22 +340,22 @@ class ItemMonitorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
var newItem = craftingGrid[slot] var newItem = craftingGrid[slot]
if (newItem.isEmpty) { if (newItem.isEmpty) {
when (settings.refillSource) { when (settings.ingredientPriority) {
ItemMonitorPlayerSettings.RefillSource.SYSTEM -> { ItemMonitorPlayerSettings.IngredientPriority.SYSTEM -> {
if (poweredView != null && takeOne(craftingGridTuples[slot], poweredView!!)) { if (poweredView != null && takeOne(craftingGridTuples[slot], poweredView!!)) {
newItem = oldItem newItem = oldItem
craftingGrid[slot] = newItem craftingGrid[slot] = newItem
} }
} }
ItemMonitorPlayerSettings.RefillSource.INVENTORY -> { ItemMonitorPlayerSettings.IngredientPriority.INVENTORY -> {
if (takeOne(craftingPlayer.inventory, oldItem)) { if (takeOne(craftingPlayer.inventory, oldItem)) {
newItem = oldItem newItem = oldItem
craftingGrid[slot] = newItem craftingGrid[slot] = newItem
} }
} }
ItemMonitorPlayerSettings.RefillSource.SYSTEM_FIRST -> { ItemMonitorPlayerSettings.IngredientPriority.SYSTEM_FIRST -> {
if (poweredView != null && takeOne(craftingGridTuples[slot], poweredView!!)) { if (poweredView != null && takeOne(craftingGridTuples[slot], poweredView!!)) {
newItem = oldItem newItem = oldItem
craftingGrid[slot] = newItem craftingGrid[slot] = newItem
@ -363,7 +367,7 @@ class ItemMonitorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
} }
} }
ItemMonitorPlayerSettings.RefillSource.INVENTORY_FIRST -> { ItemMonitorPlayerSettings.IngredientPriority.INVENTORY_FIRST -> {
if (takeOne(craftingPlayer.inventory, oldItem)) { if (takeOne(craftingPlayer.inventory, oldItem)) {
newItem = oldItem newItem = oldItem
craftingGrid[slot] = newItem craftingGrid[slot] = newItem
@ -373,7 +377,7 @@ class ItemMonitorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
} }
} }
ItemMonitorPlayerSettings.RefillSource.DO_NOT -> { /* no op */ } ItemMonitorPlayerSettings.IngredientPriority.DO_NOT -> { /* no op */ }
} }
} }

View File

@ -15,13 +15,14 @@ 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.state.BlockState import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.items.CapabilityItemHandler
import net.minecraftforge.items.IItemHandler import net.minecraftforge.items.IItemHandler
import ru.dbotthepony.mc.otm.* import ru.dbotthepony.mc.otm.*
import ru.dbotthepony.mc.otm.block.CableBlock import ru.dbotthepony.mc.otm.block.CableBlock
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.block.entity.storage.AbstractStorageImportExport.Companion.FILTER_KEY
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.container.ItemFilter import ru.dbotthepony.mc.otm.container.ItemFilter
@ -137,14 +138,12 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt[FILTER_KEY] = filter.serializeNBT()
nbt["filter"] = filter.serializeNBT()
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
super.load(nbt) super.load(nbt)
nbt.map(FILTER_KEY, filter::deserializeNBT)
nbt.ifHas("filter", CompoundTag::class.java, filter::deserializeNBT)
} }
fun checkSurroundings() { fun checkSurroundings() {
@ -152,7 +151,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
return return
val front = blockPos + blockState.getValue(RotatableMatteryBlock.FACING_FULL) val front = blockPos + blockState.getValue(RotatableMatteryBlock.FACING_FULL)
val storage = level?.getBlockEntity(front)?.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, -blockState.getValue(RotatableMatteryBlock.FACING_FULL))?.let { if (it.isPresent) it else null } val storage = level?.getBlockEntity(front)?.getCapability(ForgeCapabilities.ITEM_HANDLER, -blockState.getValue(RotatableMatteryBlock.FACING_FULL))?.let { if (it.isPresent) it else null }
if (neighbour != storage) { if (neighbour != storage) {
neighbour = storage neighbour = storage

View File

@ -14,6 +14,7 @@ import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.entity.BlockEntityType
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.capabilities.Capability
import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.items.CapabilityItemHandler import net.minecraftforge.items.CapabilityItemHandler
import net.minecraftforge.items.IItemHandler import net.minecraftforge.items.IItemHandler
@ -112,8 +113,21 @@ abstract class AbstractStorageImportExport<T>(
) { tickOnceServer(this::checkSurroundings) } ) { tickOnceServer(this::checkSurroundings) }
} }
abstract val filter: ItemFilter
override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt)
nbt[FILTER_KEY] = filter.serializeNBT()
}
override fun load(nbt: CompoundTag) {
super.load(nbt)
nbt.map(FILTER_KEY, filter::deserializeNBT)
}
companion object { companion object {
val MAX_POWER = ImpreciseFraction(10_000) val MAX_POWER = ImpreciseFraction(10_000)
const val FILTER_KEY = "filter"
} }
} }
@ -123,7 +137,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState)
override val defaultDisplayName: Component override val defaultDisplayName: Component
get() = MACHINE_NAME get() = MACHINE_NAME
val filter = ItemFilter(MAX_FILTERS) { _, _, _ -> override val filter = ItemFilter(MAX_FILTERS) { _, _, _ ->
setChangedLight() setChangedLight()
} }
@ -137,19 +151,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState)
private val enoughEnergy get() = energy.batteryLevel >= ITEM_STORAGE.energyPerOperation private val enoughEnergy get() = energy.batteryLevel >= ITEM_STORAGE.energyPerOperation
override val targetCapability: Capability<IItemHandler> override val targetCapability: Capability<IItemHandler>
get() = CapabilityItemHandler.ITEM_HANDLER_CAPABILITY get() = ForgeCapabilities.ITEM_HANDLER
override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt)
nbt["filter"] = filter.serializeNBT()
}
override fun load(nbt: CompoundTag) {
super.load(nbt)
nbt.ifHas("filter", CompoundTag::class.java, filter::deserializeNBT)
}
private var valid = true private var valid = true
private var resolverItemHandler = LazyOptional.of<IItemHandler> { this } private var resolverItemHandler = LazyOptional.of<IItemHandler> { this }
@ -167,7 +169,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState)
} }
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> { override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
if (valid && cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY && side == blockState.getValue(RotatableMatteryBlock.FACING_FULL)) { if (valid && cap == ForgeCapabilities.ITEM_HANDLER && side == blockState.getValue(RotatableMatteryBlock.FACING_FULL)) {
return resolverItemHandler.cast() return resolverItemHandler.cast()
} }
@ -295,7 +297,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
relevantTuples.remove(id) relevantTuples.remove(id)
} }
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.storageGraph?.getVirtualComponent(ITEM_STORAGE) ?: return@ItemFilter
@ -314,7 +316,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
private val enoughEnergy get() = energy.batteryLevel >= ITEM_STORAGE.energyPerOperation private val enoughEnergy get() = energy.batteryLevel >= ITEM_STORAGE.energyPerOperation
override val targetCapability: Capability<IItemHandler> override val targetCapability: Capability<IItemHandler>
get() = CapabilityItemHandler.ITEM_HANDLER_CAPABILITY get() = ForgeCapabilities.ITEM_HANDLER
private val exportStacks: Stream<Pair<UUID, ItemStackWrapper>> private val exportStacks: Stream<Pair<UUID, ItemStackWrapper>>
get() { get() {
@ -322,18 +324,6 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
return relevantTuples.stream().map { it to view[it] } return relevantTuples.stream().map { it to view[it] }
} }
override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt)
nbt["filter"] = filter.serializeNBT()
}
override fun load(nbt: CompoundTag) {
super.load(nbt)
nbt.ifHas("filter", CompoundTag::class.java, filter::deserializeNBT)
}
fun tick() { fun tick() {
batteryChargeLoop() batteryChargeLoop()
cell.tickEnergyDemanding() cell.tickEnergyDemanding()

View File

@ -24,7 +24,7 @@ import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
import ru.dbotthepony.mc.otm.menu.StoragePowerSupplierMenu import ru.dbotthepony.mc.otm.menu.StoragePowerSupplierMenu
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.container.set import ru.dbotthepony.mc.otm.core.getImpreciseFraction
import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.set
class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.STORAGE_POWER_SUPPLIER, blockPos, blockState) { class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.STORAGE_POWER_SUPPLIER, blockPos, blockState) {
@ -37,7 +37,7 @@ class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState
val cell = BasicStorageGraphNode() val cell = BasicStorageGraphNode()
var powerSupplied = ImpreciseFraction.ZERO var powerPassed = ImpreciseFraction.ZERO
private set private set
override fun setLevel(p_155231_: Level) { override fun setLevel(p_155231_: Level) {
@ -103,13 +103,13 @@ class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState
return return
} else if (demand < available) { } else if (demand < available) {
for (demanding in graph.powerDemandingNodes) { for (demanding in graph.powerDemandingNodes) {
powerSupplied += energy.transferInner(demanding, available, false) powerPassed += energy.transferInner(demanding, available, false)
} }
} else { } else {
val forEach = available / i val forEach = available / i
for (demanding in graph.powerDemandingNodes) { for (demanding in graph.powerDemandingNodes) {
powerSupplied += energy.transferInner(demanding, forEach, false) powerPassed += energy.transferInner(demanding, forEach, false)
} }
} }
} }
@ -118,17 +118,18 @@ class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState
override fun saveAdditional(nbt: CompoundTag) { override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt) super.saveAdditional(nbt)
nbt["power_supplied"] = powerSupplied.serializeNBT() nbt[POWER_PASSED_KEY] = powerPassed.serializeNBT()
} }
override fun load(nbt: CompoundTag) { override fun load(nbt: CompoundTag) {
super.load(nbt) super.load(nbt)
nbt["power_supplied"]?.let { powerSupplied = ImpreciseFraction.deserializeNBT(it) } powerPassed = nbt.getImpreciseFraction(POWER_PASSED_KEY)
} }
companion object { companion object {
private val MACHINE_NAME = TranslatableComponent("block.${OverdriveThatMatters.MOD_ID}.${MNames.STORAGE_POWER_SUPPLIER}") private val MACHINE_NAME = TranslatableComponent("block.${OverdriveThatMatters.MOD_ID}.${MNames.STORAGE_POWER_SUPPLIER}")
private val MAX_POWER = ImpreciseFraction(100_000) private val MAX_POWER = ImpreciseFraction(100_000)
private val MAX_IO = ImpreciseFraction(320) private val MAX_IO = ImpreciseFraction(320)
const val POWER_PASSED_KEY = "powerPassed"
} }
} }

View File

@ -1,30 +1,26 @@
package ru.dbotthepony.mc.otm.block.matter package ru.dbotthepony.mc.otm.block.matter
import net.minecraft.MethodsReturnNonnullByDefault
import javax.annotation.ParametersAreNonnullByDefault
import net.minecraft.world.level.block.EntityBlock
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.world.item.context.BlockPlaceContext import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.BlockGetter
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.state.BlockState import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.block.entity.BlockEntity
import ru.dbotthepony.mc.otm.block.entity.matter.MatterBottlerBlockEntity
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.entity.BlockEntityTicker 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 net.minecraft.world.level.block.state.StateDefinition import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BooleanProperty import net.minecraft.world.level.block.state.properties.BooleanProperty
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.WorkerState import ru.dbotthepony.mc.otm.block.entity.WorkerState
import ru.dbotthepony.mc.otm.block.entity.matter.MatterBottlerBlockEntity
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
class MatterBottlerBlock : RotatableMatteryBlock(), EntityBlock { class MatterBottlerBlock : RotatableMatteryBlock(), EntityBlock {
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity? { override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity? {
return MatterBottlerBlockEntity(blockPos, blockState) return MatterBottlerBlockEntity(blockPos, blockState)

View File

@ -2,8 +2,10 @@ package ru.dbotthepony.mc.otm.block.matter
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.world.Containers
import net.minecraft.world.item.context.BlockPlaceContext import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.BlockGetter
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.EntityBlock import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.block.entity.BlockEntity
@ -13,7 +15,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.PatternStorageBlockEntity import ru.dbotthepony.mc.otm.block.entity.matter.PatternStorageBlockEntity
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
class PatternStorageBlock : RotatableMatteryBlock(), EntityBlock { class PatternStorageBlock : RotatableMatteryBlock(), EntityBlock {
@ -35,6 +37,25 @@ class PatternStorageBlock : RotatableMatteryBlock(), EntityBlock {
return state return state
} }
override fun onRemove(
oldBlockState: BlockState,
level: Level,
blockPos: BlockPos,
newBlockState: BlockState,
movedByPiston: Boolean
) {
if (!oldBlockState.`is`(newBlockState.block)) {
val blockentity = level.getBlockEntity(blockPos)
if (blockentity is PatternStorageBlockEntity) {
Containers.dropContents(level, blockPos, blockentity.patternContainer)
level.updateNeighbourForOutputSignal(blockPos, this)
}
}
super.onRemove(oldBlockState, level, blockPos, newBlockState, movedByPiston)
}
override fun getShape( override fun getShape(
p_60555_: BlockState, p_60555_: BlockState,
p_60556_: BlockGetter, p_60556_: BlockGetter,

View File

@ -126,17 +126,17 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
val arrowLine = EditablePanel(this, arrowAndButtons, y = 38f, height = 8f, width = arrowAndButtons.width) val arrowLine = EditablePanel(this, arrowAndButtons, y = 38f, height = 8f, width = arrowAndButtons.width)
val refillPriority = SmallEnumSquareButtonPanel(this, arrowLine, val refillPriority = SmallEnumSquareButtonPanel(this, arrowLine,
enum = ItemMonitorPlayerSettings.RefillSource::class.java, enum = ItemMonitorPlayerSettings.IngredientPriority::class.java,
prop = menu.settings::refillSource, prop = menu.settings::ingredientPriority,
defaultValue = ItemMonitorPlayerSettings.RefillSource.SYSTEM, defaultValue = ItemMonitorPlayerSettings.IngredientPriority.SYSTEM,
onChange = { menu.sendSettingsToServer() }) onChange = { menu.sendSettingsToServer() })
refillPriority.mainTooltip = TranslatableComponent("otm.gui.item_monitor.refill_source.desc") refillPriority.mainTooltip = TranslatableComponent("otm.gui.item_monitor.refill_source.desc")
refillPriority.add(ItemMonitorPlayerSettings.RefillSource.SYSTEM, ItemMonitorPlayerSettings.RefillSource.SYSTEM.component, Widgets8.WHITE_ARROW_DOWN, UVWindingOrder.FLIP) refillPriority.add(ItemMonitorPlayerSettings.IngredientPriority.SYSTEM, ItemMonitorPlayerSettings.IngredientPriority.SYSTEM.component, Widgets8.WHITE_ARROW_DOWN, UVWindingOrder.FLIP)
refillPriority.add(ItemMonitorPlayerSettings.RefillSource.INVENTORY, ItemMonitorPlayerSettings.RefillSource.INVENTORY.component, Widgets8.WHITE_ARROW_DOWN) refillPriority.add(ItemMonitorPlayerSettings.IngredientPriority.INVENTORY, ItemMonitorPlayerSettings.IngredientPriority.INVENTORY.component, Widgets8.WHITE_ARROW_DOWN)
refillPriority.add(ItemMonitorPlayerSettings.RefillSource.INVENTORY_FIRST, ItemMonitorPlayerSettings.RefillSource.INVENTORY_FIRST.component, Widgets8.ARROW_SIDEWAYS, UVWindingOrder.FLIP) refillPriority.add(ItemMonitorPlayerSettings.IngredientPriority.INVENTORY_FIRST, ItemMonitorPlayerSettings.IngredientPriority.INVENTORY_FIRST.component, Widgets8.ARROW_SIDEWAYS, UVWindingOrder.FLIP)
refillPriority.add(ItemMonitorPlayerSettings.RefillSource.SYSTEM_FIRST, ItemMonitorPlayerSettings.RefillSource.SYSTEM_FIRST.component, Widgets8.ARROW_SIDEWAYS) refillPriority.add(ItemMonitorPlayerSettings.IngredientPriority.SYSTEM_FIRST, ItemMonitorPlayerSettings.IngredientPriority.SYSTEM_FIRST.component, Widgets8.ARROW_SIDEWAYS)
refillPriority.add(ItemMonitorPlayerSettings.RefillSource.DO_NOT, ItemMonitorPlayerSettings.RefillSource.DO_NOT.component, Widgets8.MINUS) refillPriority.add(ItemMonitorPlayerSettings.IngredientPriority.DO_NOT, ItemMonitorPlayerSettings.IngredientPriority.DO_NOT.component, Widgets8.MINUS)
refillPriority.dock = Dock.LEFT refillPriority.dock = Dock.LEFT

View File

@ -41,8 +41,8 @@ fun CompoundTag.contains(vararg keys: String): Boolean {
return true return true
} }
inline fun <R, reified T : Tag> CompoundTag.map(s: String, consumer: (T) -> R): R? { inline fun <R, reified T : Tag> CompoundTag.map(key: String, consumer: (T) -> R): R? {
val tag = get(s) val tag = get(key)
if (tag is T) { if (tag is T) {
return consumer(tag) return consumer(tag)
@ -51,6 +51,16 @@ inline fun <R, reified T : Tag> CompoundTag.map(s: String, consumer: (T) -> R):
return null return null
} }
inline fun <reified R : Enum<R>> CompoundTag.getEnum(key: String): R {
val tag = get(key)
if (tag is StringTag) {
return R::class.java.enumConstants.first { it.name == tag.asString }
}
return R::class.java.enumConstants[0]
}
fun CompoundTag.getItemStack(key: String): ItemStack = map(key, ItemStack::of) ?: ItemStack.EMPTY fun CompoundTag.getItemStack(key: String): ItemStack = map(key, ItemStack::of) ?: ItemStack.EMPTY
inline fun CompoundTag.ifHas(s: String, consumer: (Tag) -> Unit) { inline fun CompoundTag.ifHas(s: String, consumer: (Tag) -> Unit) {

View File

@ -33,7 +33,7 @@ class ChemicalGeneratorMenu @JvmOverloads constructor(id: Int, inv: Inventory, t
} }
} }
val progress = ProgressGaugeWidget(this) { 1f - tile!!.workingTicks.toFloat() / tile.workingTicksTotal } val progress = ProgressGaugeWidget(this) { 1f - tile!!.workTicks.toFloat() / tile.workTicksTotal }
val energy = LevelGaugeWidget(this, tile?.energy) val energy = LevelGaugeWidget(this, tile?.energy)
var burnTime by mSynchronizer.int() var burnTime by mSynchronizer.int()
@ -50,6 +50,6 @@ class ChemicalGeneratorMenu @JvmOverloads constructor(id: Int, inv: Inventory, t
override fun broadcastChanges() { override fun broadcastChanges() {
super.broadcastChanges() super.broadcastChanges()
progress.updateServer() progress.updateServer()
burnTime = (tile as ChemicalGeneratorBlockEntity).workingTicks burnTime = (tile as ChemicalGeneratorBlockEntity).workTicks
} }
} }

View File

@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.menu
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 ru.dbotthepony.mc.otm.core.ImmutableList import ru.dbotthepony.mc.otm.core.ImmutableList
import ru.dbotthepony.mc.otm.block.entity.storage.DriveRackBlockEntity import ru.dbotthepony.mc.otm.block.entity.storage.DriveRackBlockEntity
import ru.dbotthepony.mc.otm.registry.MMenus import ru.dbotthepony.mc.otm.registry.MMenus
@ -15,7 +14,7 @@ class DriveRackMenu @JvmOverloads constructor(
override val storageSlots: List<MatterySlot> override val storageSlots: List<MatterySlot>
init { init {
val container = tile?.drives ?: SimpleContainer(4) val container = tile?.container ?: SimpleContainer(4)
storageSlots = ImmutableList(4) { storageSlots = ImmutableList(4) {
val slot = DriveSlot(container, it) val slot = DriveSlot(container, it)

View File

@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.menu
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.core.ImmutableList import ru.dbotthepony.mc.otm.core.ImmutableList
import ru.dbotthepony.mc.otm.block.entity.matter.MatterBottlerBlockEntity import ru.dbotthepony.mc.otm.block.entity.matter.MatterBottlerBlockEntity
@ -37,7 +36,7 @@ class MatterBottlerMenu @JvmOverloads constructor(
} else { } else {
progressWidget = ProgressGaugeWidget(this) { tile.getWorkProgress() } progressWidget = ProgressGaugeWidget(this) { tile.getWorkProgress() }
matterWidget = LevelGaugeWidget(this, tile.matter) matterWidget = LevelGaugeWidget(this, tile.matter)
workFlow = BooleanPlayerInputWidget(this, tile::workFlow) workFlow = BooleanPlayerInputWidget(this, tile::isBottling)
} }
storageSlots = ImmutableList(6) { index -> storageSlots = ImmutableList(6) { index ->
@ -60,6 +59,6 @@ class MatterBottlerMenu @JvmOverloads constructor(
override fun broadcastChanges() { override fun broadcastChanges() {
super.broadcastChanges() super.broadcastChanges()
workFlow.value = (tile as MatterBottlerBlockEntity).workFlow workFlow.value = (tile as MatterBottlerBlockEntity).isBottling
} }
} }

View File

@ -3,7 +3,7 @@ package ru.dbotthepony.mc.otm.menu
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 ru.dbotthepony.mc.otm.core.ImmutableList import ru.dbotthepony.mc.otm.core.ImmutableList
import ru.dbotthepony.mc.otm.block.entity.PatternStorageBlockEntity import ru.dbotthepony.mc.otm.block.entity.matter.PatternStorageBlockEntity
import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
import ru.dbotthepony.mc.otm.registry.MMenus import ru.dbotthepony.mc.otm.registry.MMenus

View File

@ -19,7 +19,7 @@ class StoragePowerSupplierMenu @JvmOverloads constructor(
override fun broadcastChanges() { override fun broadcastChanges() {
if (tile is StoragePowerSupplierBlockEntity) { if (tile is StoragePowerSupplierBlockEntity) {
totalTransferred = tile.powerSupplied totalTransferred = tile.powerPassed
activeNodes = tile.cell.storageGraph?.powerDemandingNodes?.size ?: 0 activeNodes = tile.cell.storageGraph?.powerDemandingNodes?.size ?: 0
} }

View File

@ -4,7 +4,6 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRenderers
import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraftforge.eventbus.api.IEventBus import net.minecraftforge.eventbus.api.IEventBus
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext
import net.minecraftforge.registries.DeferredRegister import net.minecraftforge.registries.DeferredRegister
import net.minecraftforge.registries.ForgeRegistries import net.minecraftforge.registries.ForgeRegistries
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters