Add lots of multiblock related stuff, more blackhole generator multiblock testcode

This commit is contained in:
DBotThePony 2024-02-15 18:47:06 +07:00
parent 3ddb4d3d83
commit 059270a2ec
Signed by: DBot
GPG Key ID: DCC23B5715498507
26 changed files with 1007 additions and 24 deletions

View File

@ -479,6 +479,14 @@ private fun blocks(provider: MatteryLanguageProvider) {
addBlock(MBlocks.DRIVE_VIEWER.values, "Drive Viewer")
add(MBlocks.BLACK_HOLE, "Local Anomalous Spacetime Dilation Singular Point")
add(MBlocks.BLACK_HOLE_GENERATOR, "Matter Acceleration Power Generator")
add(MBlocks.ENERGY_INPUT_HATCH, "Energy Input Hatch")
add(MBlocks.ITEM_INPUT_HATCH, "Item Input Hatch")
add(MBlocks.MATTER_INPUT_HATCH, "Matter Input Hatch")
add(MBlocks.ENERGY_OUTPUT_HATCH, "Energy Output Hatch")
add(MBlocks.ITEM_OUTPUT_HATCH, "Item Output Hatch")
add(MBlocks.MATTER_OUTPUT_HATCH, "Matter Output Hatch")
addBlock(MBlocks.COBBLESTONE_GENERATOR.values, "Cobblestone Generator")
add(MBlocks.INFINITE_WATER_SOURCE, "Infinite Water Source")
@ -810,6 +818,7 @@ private fun androidFeatures(provider: MatteryLanguageProvider) {
private fun gui(provider: MatteryLanguageProvider) {
with(provider.english) {
gui("part_of_multiblock", "Part of multiblock structure, useless on its own")
gui("quicksearch", "Quick search...")
gui("painter.is_bulk", "Bulk painting")

View File

@ -484,7 +484,16 @@ private fun blocks(provider: MatteryLanguageProvider) {
addBlock(MBlocks.COBBLESTONE_GENERATOR.values, "Генератор булыжника")
add(MBlocks.INFINITE_WATER_SOURCE, "Неиссякаемый источник воды")
add(MBlocks.INFINITE_WATER_SOURCE, "desc", "Выталкивает воду в соседние блоки автоматически")
add(MBlocks.BLACK_HOLE, "Локализированная сингулярная точка аномального искажения пространства-времени")
add(MBlocks.BLACK_HOLE_GENERATOR, "Генератор энергии ускорением материи")
add(MBlocks.ENERGY_INPUT_HATCH, "Входной энергетический клапан")
add(MBlocks.ITEM_INPUT_HATCH, "Входной предметный клапан")
add(MBlocks.MATTER_INPUT_HATCH, "Входной клапан материи")
add(MBlocks.ENERGY_OUTPUT_HATCH, "Выходной энергетический клапан")
add(MBlocks.ITEM_OUTPUT_HATCH, "Выходной предметный клапан")
add(MBlocks.MATTER_OUTPUT_HATCH, "Выходной клапан материи")
add(MBlocks.DEV_CHEST, "Сундук разработчика")
add(MBlocks.DEV_CHEST, "desc", "Хранит все предметы, которые есть в игре")
@ -814,6 +823,7 @@ private fun androidFeatures(provider: MatteryLanguageProvider) {
private fun gui(provider: MatteryLanguageProvider) {
with(provider.russian) {
gui("part_of_multiblock", "Часть мультиблока, бесполезен сам по себе")
gui("quicksearch", "Быстрый поиск...")
gui("painter.is_bulk", "Массовая покраска")

View File

@ -169,4 +169,8 @@ fun addLootTables(lootTables: LootTables) {
lootTables.tile(MBlocks.PATTERN_STORAGE)
lootTables.tile(MBlocks.MATTER_CAPACITOR_BANK.values)
lootTables.tile(MBlocks.MATTER_BOTTLER.values)
lootTables.tile(MBlocks.BLACK_HOLE_GENERATOR)
lootTables.tile(MBlocks.ITEM_INPUT_HATCH)
lootTables.tile(MBlocks.ITEM_OUTPUT_HATCH)
}

View File

@ -229,6 +229,10 @@ fun addTags(tagsProvider: TagsProvider) {
*MBlocks.MATTER_RECONSTRUCTOR.values.toTypedArray(),
MBlocks.FLUID_TANK,
*MBlocks.ANDROID_CHARGER.values.toTypedArray(),
MBlocks.BLACK_HOLE_GENERATOR,
MBlocks.ITEM_INPUT_HATCH,
MBlocks.ITEM_OUTPUT_HATCH,
), Tiers.IRON)
tagsProvider.requiresPickaxe(MBlocks.TRITANIUM_ANVIL, Tiers.IRON)

View File

@ -0,0 +1,239 @@
package ru.dbotthepony.mc.otm.block.entity.tech
import it.unimi.dsi.fastutil.objects.ObjectArrayList
import it.unimi.dsi.fastutil.objects.ObjectArraySet
import net.minecraft.core.BlockPos
import net.minecraft.core.SectionPos
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.level.block.state.BlockState
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.core.Multiblock
import ru.dbotthepony.mc.otm.core.MultiblockBuilder
import ru.dbotthepony.mc.otm.core.getBlockStateNow
import ru.dbotthepony.mc.otm.core.immutableList
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.plus
import ru.dbotthepony.mc.otm.core.math.times
import ru.dbotthepony.mc.otm.core.multiblockConfiguration
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.registry.MBlocks
class BlackHoleGeneratorBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.BLACK_HOLE_GENERATOR, blockPos, blockState) {
private var multiblock: Multiblock? = null
private var lastRange = -1
private fun findBlackHoleRange(): Int {
val normal = blockRotation.normal
val level = level!!
if (lastRange != -1) {
val pos = blockPos + normal * lastRange
if (level.getBlockStateNow(pos).block == MBlocks.BLACK_HOLE) {
return lastRange
}
}
for (i in 5 until 64) {
val pos = blockPos + normal * i
if (level.getBlockStateNow(pos).block == MBlocks.BLACK_HOLE) {
return i
}
}
return -1
}
override fun tick() {
super.tick()
val level = level!!
if (lastRange == -1) {
val found = findBlackHoleRange()
if (found != -1) {
lastRange = found
multiblock = CONFIGURATIONS[found - 5].value.create(blockPos)
} else {
multiblock = null
}
}
val multiblock = multiblock
if (multiblock != null) {
if (!multiblock.update(level, blockRotation.front)) {
val found = findBlackHoleRange()
if (found == -1) {
this.multiblock = null
} else if (found != lastRange) {
lastRange = found
this.multiblock = CONFIGURATIONS[found - 5].value.create(blockPos)
}
} else {
val blackHole = multiblock.blockEntities(BLACK_HOLE).first()
val matterHatches = multiblock.blockEntities(MatterHatchBlockEntity.INPUT_TAG)
val energyHatches = multiblock.blockEntities(EnergyHatchBlockEntity.OUTPUT_TAG)
if (matterHatches.isEmpty() || energyHatches.isEmpty()) return
var required = MachinesConfig.BlackHoleGenerator.MATTER_RATE
for (hatch in matterHatches) {
required -= hatch.matter.extractMatter(required, true)
if (required <= Decimal.ZERO) break
}
if (required > Decimal.ZERO) return
var energyLeftover = blackHole.mass / MachinesConfig.BlackHoleGenerator.MASS_DIVISOR
for (hatch in energyHatches) {
energyLeftover -= hatch.energy.receiveEnergy(energyLeftover, true)
if (energyLeftover <= Decimal.ZERO) break
}
if (energyLeftover > Decimal.ZERO) return
required = MachinesConfig.BlackHoleGenerator.MATTER_RATE
for (hatch in matterHatches) {
required -= hatch.matter.extractMatter(required, false)
if (required <= Decimal.ZERO) break
}
energyLeftover = blackHole.mass / MachinesConfig.BlackHoleGenerator.MASS_DIVISOR
for (hatch in energyHatches) {
energyLeftover -= hatch.energy.receiveEnergy(energyLeftover, false)
if (energyLeftover <= Decimal.ZERO) break
}
blackHole.mass += MachinesConfig.BlackHoleGenerator.MASS_FEEDING_RATIO * MachinesConfig.BlackHoleGenerator.MATTER_RATE
}
}
}
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? {
return null
}
companion object {
val BLACK_HOLE = MultiblockBuilder.EntityTag(BlackHoleBlockEntity::class)
private fun points(x: Int, z: Int, result: ObjectArraySet<BlockPos>) {
if (x == 0) {
result.add(BlockPos(0, 0, z))
result.add(BlockPos(0, 0, -z))
result.add(BlockPos(z, 0, 0))
result.add(BlockPos(-z, 0, 0))
} else if (x == z) {
result.add(BlockPos(x, 0, z))
result.add(BlockPos(-x, 0, z))
result.add(BlockPos(x, 0, -z))
result.add(BlockPos(-x, 0, -z))
} else if (x < z) {
result.add(BlockPos(x, 0, z))
result.add(BlockPos(-x, 0, z))
result.add(BlockPos(x, 0, -z))
result.add(BlockPos(-x, 0, -z))
result.add(BlockPos(z, 0, x))
result.add(BlockPos(-z, 0, x))
result.add(BlockPos(z, 0, -x))
result.add(BlockPos(-z, 0, -x))
}
}
private fun ring(size: Int): ObjectArrayList<BlockPos> {
val positions = ObjectArraySet<BlockPos>()
var x = 0
var y = size
var p = (5 - size * 4) / 4
points(x, y, positions)
while (x < y) {
x++
if (p < 0) {
p += x * 2 + 1
} else {
y--
p += (x - y) * 2 + 1
}
points(x, y, positions)
}
val result = ObjectArrayList<BlockPos>(positions.size)
for (pos in positions) {
if (pos.x == 0 && pos.z + size == 0) continue
result.add(BlockPos(pos.x, 0, pos.z + size))
}
return result
}
val CONFIGURATIONS = immutableList {
for (i2 in 0 until 59) {
val i = i2 + 5
accept(lazy {
multiblockConfiguration {
builder.customCheck {
val blocks = it.blocks()
blocks.getInt(MBlocks.MATTER_INJECTOR) == 1 &&
blocks.getInt(MBlocks.ANTIMATTER_INJECTOR) == 1 &&
blocks.getInt(MBlocks.HIGH_ENERGY_PARTICLE_COLLECTOR) == 1
}
block(MBlocks.BLACK_HOLE_GENERATOR)
relative(BlockPos(0, 0, i)) {
block(MBlocks.BLACK_HOLE)
tag(BLACK_HOLE)
}
val ring = ring(i)
for (pos in ring) {
val node = relative(pos)
if ((pos.x == i || pos.x == -i) && pos.z == i) {
node.block(MBlocks.MATTER_INJECTOR)
node.block(MBlocks.ANTIMATTER_INJECTOR)
node.tagBlock()
} else if (pos.x == 0 && pos.z == i * 2) {
node.block(MBlocks.HIGH_ENERGY_PARTICLE_COLLECTOR)
node.tagBlock()
} else if (pos.x == i || pos.x == -i || pos.z == i * 2 || pos.z == 0) {
node.or {
block(MBlocks.ENERGY_OUTPUT_HATCH)
tag(EnergyHatchBlockEntity.OUTPUT_TAG)
}
node.or {
block(MBlocks.MATTER_INPUT_HATCH)
tag(MatterHatchBlockEntity.INPUT_TAG)
}
node.block(MBlocks.MULTIBLOCK_STRUCTURE)
} else {
node.block(MBlocks.MULTIBLOCK_STRUCTURE)
}
}
}
})
}
}
}
}

View File

@ -0,0 +1,87 @@
package ru.dbotthepony.mc.otm.block.entity.tech
import net.minecraft.core.BlockPos
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.common.capabilities.ForgeCapabilities
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
import ru.dbotthepony.mc.otm.capability.FlowDirection
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl
import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage
import ru.dbotthepony.mc.otm.capability.moveEnergy
import ru.dbotthepony.mc.otm.config.EnergyBalanceValues
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.MultiblockBuilder
import ru.dbotthepony.mc.otm.core.ifPresentK
import ru.dbotthepony.mc.otm.menu.tech.EnergyHatchMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities
class EnergyHatchBlockEntity(
val isInput: Boolean,
capacity: EnergyBalanceValues,
type: BlockEntityType<*>,
blockPos: BlockPos,
blockState: BlockState
) : MatteryDeviceBlockEntity(type, blockPos, blockState) {
val energy = ProfiledEnergyStorage(BlockEnergyStorageImpl(this::markDirtyFast, FlowDirection.input(isInput), capacity))
val container = object : MatteryContainer(this::markDirtyFast, CAPACITY) {
override fun getMaxStackSize(slot: Int, itemStack: ItemStack): Int {
return 1
}
}.also(::addDroppableContainer)
val itemHandler = container.handler(if (isInput) HandlerFilter.Dischargeable else HandlerFilter.Chargeable)
init {
savetables.stateful(::energy, ENERGY_KEY)
savetables.stateful(::container, BATTERY_KEY)
// it would cause a lot of frustration if hatches accept stuff only though one face
exposeGlobally(ForgeCapabilities.ENERGY, energy)
exposeGlobally(MatteryCapability.ENERGY, energy)
exposeGlobally(ForgeCapabilities.ITEM_HANDLER, itemHandler)
}
override fun tick() {
super.tick()
if (!redstoneControl.isBlockedByRedstone) {
container.forEach {
it.getCapability(ForgeCapabilities.ENERGY).ifPresentK {
if (isInput) {
moveEnergy(it, energy, simulate = false)
} else {
moveEnergy(energy, it, simulate = false)
}
}
}
}
}
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
return EnergyHatchMenu(isInput, containerID, inventory, this)
}
companion object {
const val CAPACITY = 1
val INPUT_TAG = MultiblockBuilder.EntityTag(EnergyHatchBlockEntity::class) { it.isInput }
val OUTPUT_TAG = MultiblockBuilder.EntityTag(EnergyHatchBlockEntity::class) { !it.isInput }
fun input(blockPos: BlockPos, blockState: BlockState): EnergyHatchBlockEntity {
return EnergyHatchBlockEntity(true, MachinesConfig.ENERGY_HATCH, MBlockEntities.ENERGY_INPUT_HATCH, blockPos, blockState)
}
fun output(blockPos: BlockPos, blockState: BlockState): EnergyHatchBlockEntity {
return EnergyHatchBlockEntity(false, MachinesConfig.ENERGY_HATCH, MBlockEntities.ENERGY_OUTPUT_HATCH, blockPos, blockState)
}
}
}

View File

@ -0,0 +1,50 @@
package ru.dbotthepony.mc.otm.block.entity.tech
import net.minecraft.core.BlockPos
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.common.capabilities.ForgeCapabilities
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
import ru.dbotthepony.mc.otm.block.entity.decorative.CargoCrateBlockEntity
import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.MultiblockBuilder
import ru.dbotthepony.mc.otm.menu.tech.ItemHatchMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities
class ItemHatchBlockEntity(
val isInput: Boolean,
type: BlockEntityType<*>,
blockPos: BlockPos,
blockState: BlockState
) : MatteryDeviceBlockEntity(type, blockPos, blockState) {
val container = MatteryContainer(this::markDirtyFast, CAPACITY).also(::addDroppableContainer)
val itemHandler = container.handler(if (isInput) HandlerFilter.OnlyIn else HandlerFilter.OnlyOut)
init {
savetables.stateful(::container, INVENTORY_KEY)
exposeGlobally(ForgeCapabilities.ITEM_HANDLER, itemHandler)
}
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
return ItemHatchMenu(isInput, containerID, inventory, this)
}
companion object {
const val CAPACITY = CargoCrateBlockEntity.CAPACITY
val INPUT_TAG = MultiblockBuilder.EntityTag(ItemHatchBlockEntity::class) { it.isInput }
val OUTPUT_TAG = MultiblockBuilder.EntityTag(ItemHatchBlockEntity::class) { !it.isInput }
fun input(blockPos: BlockPos, blockState: BlockState): ItemHatchBlockEntity {
return ItemHatchBlockEntity(true, MBlockEntities.ITEM_INPUT_HATCH, blockPos, blockState)
}
fun output(blockPos: BlockPos, blockState: BlockState): ItemHatchBlockEntity {
return ItemHatchBlockEntity(false, MBlockEntities.ITEM_OUTPUT_HATCH, blockPos, blockState)
}
}
}

View File

@ -0,0 +1,89 @@
package ru.dbotthepony.mc.otm.block.entity.tech
import net.minecraft.core.BlockPos
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.common.capabilities.ForgeCapabilities
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
import ru.dbotthepony.mc.otm.capability.FlowDirection
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.matter.MatterStorageImpl
import ru.dbotthepony.mc.otm.capability.matter.ProfiledMatterStorage
import ru.dbotthepony.mc.otm.capability.moveMatter
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.MultiblockBuilder
import ru.dbotthepony.mc.otm.core.ifPresentK
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.menu.tech.MatterHatchMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities
class MatterHatchBlockEntity(
val isInput: Boolean,
type: BlockEntityType<*>,
blockPos: BlockPos,
blockState: BlockState
) : MatteryDeviceBlockEntity(type, blockPos, blockState) {
val container = object : MatteryContainer(this::markDirtyFast, CAPACITY) {
override fun getMaxStackSize(slot: Int, itemStack: ItemStack): Int {
return 1
}
}.also(::addDroppableContainer)
val matter = ProfiledMatterStorage(MatterStorageImpl(this::markDirtyFast, FlowDirection.input(isInput), MachinesConfig::MATTER_HATCH))
val itemHandler = if (isInput) {
container.handler(HandlerFilter.MatterProviders)
} else {
container.handler(HandlerFilter.MatterConsumers)
}
init {
savetables.stateful(::container, INVENTORY_KEY)
savetables.stateful(::matter, MATTER_STORAGE_KEY)
// it would cause a lot of frustration if hatches accept stuff only though one face
exposeGlobally(ForgeCapabilities.ITEM_HANDLER, itemHandler)
exposeGlobally(MatteryCapability.MATTER, matter)
}
override fun tick() {
super.tick()
if (!redstoneControl.isBlockedByRedstone && matter.missingMatter > Decimal.ZERO) {
container.forEach {
it.getCapability(MatteryCapability.MATTER).ifPresentK {
if (isInput) {
moveMatter(it, matter, simulate = false)
} else {
moveMatter(matter, it, simulate = false)
}
}
}
}
}
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
return MatterHatchMenu(isInput, containerID, inventory, this)
}
companion object {
const val CAPACITY = 1
val INPUT_TAG = MultiblockBuilder.EntityTag(MatterHatchBlockEntity::class) { it.isInput }
val OUTPUT_TAG = MultiblockBuilder.EntityTag(MatterHatchBlockEntity::class) { !it.isInput }
fun input(blockPos: BlockPos, blockState: BlockState): MatterHatchBlockEntity {
return MatterHatchBlockEntity(true, MBlockEntities.ITEM_INPUT_HATCH, blockPos, blockState)
}
fun output(blockPos: BlockPos, blockState: BlockState): MatterHatchBlockEntity {
return MatterHatchBlockEntity(false, MBlockEntities.ITEM_OUTPUT_HATCH, blockPos, blockState)
}
}
}

View File

@ -0,0 +1,56 @@
package ru.dbotthepony.mc.otm.block.tech
import net.minecraft.core.BlockPos
import net.minecraft.core.SectionPos
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.BlockEntityTicker
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.material.MapColor
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
import ru.dbotthepony.mc.otm.block.entity.tech.BlackHoleGeneratorBlockEntity
import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom
import ru.dbotthepony.mc.otm.core.math.plus
import ru.dbotthepony.mc.otm.core.math.times
class BlackHoleGeneratorBlock : RotatableMatteryBlock(Properties.of().mapColor(MapColor.METAL).requiresCorrectToolForDrops().destroyTime(2.5f).explosionResistance(160.0f)), EntityBlock {
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity {
return BlackHoleGeneratorBlockEntity(blockPos, blockState)
}
override fun <T : BlockEntity?> getTicker(level: Level, blockState: BlockState, blockEntityType: BlockEntityType<T>): BlockEntityTicker<T>? {
if (level.isClientSide)
return null
return BlockEntityTicker { _, _, _, tile -> if (tile is BlackHoleGeneratorBlockEntity) tile.tick() }
}
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
var state = super.getStateForPlacement(context) ?: return null
val blockPos = context.clickedPos
val level = context.level
for (face in BlockRotationFreedom.HORIZONTAL.possibleValues) {
val dir = face.normal
for (i in 4 ..64) {
val pos = blockPos + dir * i
val chunk = level.chunkSource.getChunkNow(SectionPos.blockToSectionCoord(pos.x), SectionPos.blockToSectionCoord(pos.z)) ?: continue
val getState = chunk.getBlockState(pos)
if (!getState.isAir) {
if (chunk.getBlockEntity(pos) is BlackHoleBlockEntity) {
state = state.setValue(BlockRotationFreedom.HORIZONTAL.property, face)
break
}
}
}
}
return state
}
}

View File

@ -0,0 +1,37 @@
package ru.dbotthepony.mc.otm.block.tech
import net.minecraft.ChatFormatting
import net.minecraft.core.BlockPos
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.BlockEntityTicker
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.material.MapColor
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
import ru.dbotthepony.mc.otm.core.TranslatableComponent
class HatchBlock(val factory: BlockEntityType.BlockEntitySupplier<out MatteryBlockEntity>, val needsTicking: Boolean = false) : RotatableMatteryBlock(Properties.of().mapColor(MapColor.METAL).requiresCorrectToolForDrops().destroyTime(2.5f).explosionResistance(80.0f)), EntityBlock {
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity {
return factory.create(blockPos, blockState)
}
override fun <T : BlockEntity?> getTicker(level: Level, blockState: BlockState, type: BlockEntityType<T>): BlockEntityTicker<T>? {
if (needsTicking && !level.isClientSide) {
return BlockEntityTicker { _, _, _, tile -> if (tile is MatteryBlockEntity) tile.tick() }
}
return null
}
override fun faceToPlayer(context: BlockPlaceContext): Boolean {
return true
}
init {
tooltips.add(TranslatableComponent("otm.gui.part_of_multiblock").withStyle(ChatFormatting.GRAY))
}
}

View File

@ -15,6 +15,7 @@ import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.capability.fluid.iterator
import ru.dbotthepony.mc.otm.capability.fluid.stream
import ru.dbotthepony.mc.otm.capability.matter.IMatterStorage
import ru.dbotthepony.mc.otm.client.ShiftPressedCond
import ru.dbotthepony.mc.otm.compat.cos.cosmeticArmorAwareStream
import ru.dbotthepony.mc.otm.compat.cos.cosmeticArmorStream
@ -289,6 +290,30 @@ fun moveEnergy(source: IEnergyStorage, destination: IEnergyStorage, amount: Deci
return Decimal.ZERO
}
@Suppress("name_shadowing")
fun moveMatter(source: IMatterStorage, destination: IMatterStorage, amount: Decimal = Decimal.LONG_MAX_VALUE.coerceAtLeast(source.storedMatter), simulate: Boolean, ignoreFlowRestrictions: Boolean = false): Decimal {
val extracted = if (ignoreFlowRestrictions) source.extractMatter(amount, true) else source.extractMatterChecked(amount, true)
if (extracted.isPositive) {
val received = destination.receiveMatterChecked(extracted, true)
if (received.isPositive) {
val extracted = if (ignoreFlowRestrictions) source.extractMatter(received, true) else source.extractMatterChecked(received, true)
if (extracted.isPositive) {
if (simulate) {
return extracted
}
val extracted = if (ignoreFlowRestrictions) source.extractMatter(received, false) else source.extractMatterChecked(received, false)
return destination.receiveMatterChecked(extracted, false)
}
}
}
return Decimal.ZERO
}
internal fun IFluidHandler.fluidLevel(tooltips: (Component) -> Unit) {
val fluid = getFluidInTank(0)

View File

@ -0,0 +1,48 @@
package ru.dbotthepony.mc.otm.client.screen.tech
import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
import ru.dbotthepony.mc.otm.client.screen.panels.DockResizeMode
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.SpritePanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.MatterCapacitorSlotPanel
import ru.dbotthepony.mc.otm.client.screen.widget.HorizontalProfiledPowerGaugePanel
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
import ru.dbotthepony.mc.otm.menu.tech.EnergyHatchMenu
import ru.dbotthepony.mc.otm.menu.tech.MatterHatchMenu
class EnergyHatchScreen(menu: EnergyHatchMenu, inventory: Inventory, title: Component) : MatteryScreen<EnergyHatchMenu>(menu, inventory, title) {
override fun makeMainFrame(): FramePanel<MatteryScreen<*>> {
val frame = FramePanel(this, null, 0f, 0f, INVENTORY_FRAME_WIDTH, AbstractSlotPanel.SIZE, getTitle())
frame.makeCloseButton()
frame.onClose { onClose() }
for (slot in menu.inputSlots) {
val panel = MatterCapacitorSlotPanel(this, frame, slot)
panel.dock = Dock.LEFT
panel.dockResize = DockResizeMode.NONE
}
val arrow = SpritePanel(this, frame, ProgressGaugePanel.GAUGE_BACKGROUND)
arrow.dockLeft = 2f
arrow.dockRight = 2f
arrow.dock = Dock.LEFT
arrow.dockResize = DockResizeMode.NONE
if (!menu.isInput)
arrow.winding = UVWindingOrder.FLOP
val gauge = HorizontalProfiledPowerGaugePanel(this, frame, menu.gauge)
gauge.dock = Dock.RIGHT
DeviceControls(this, frame, redstoneConfig = menu.redstone)
return frame
}
}

View File

@ -0,0 +1,32 @@
package ru.dbotthepony.mc.otm.client.screen.tech
import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.util.GridPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.UserFilteredSlotPanel
import ru.dbotthepony.mc.otm.menu.tech.ItemHatchMenu
class ItemHatchScreen(menu: ItemHatchMenu, inventory: Inventory, title: Component) : MatteryScreen<ItemHatchMenu>(menu, inventory, title) {
override fun makeMainFrame(): FramePanel<MatteryScreen<*>> {
val frame = FramePanel(this, null, 0f, 0f, INVENTORY_FRAME_WIDTH, 22f + 4f + 6f * 18f, getTitle())
frame.makeCloseButton()
frame.onClose { onClose() }
frame.makeHelpButton().addSlotFiltersHelp()
val grid = GridPanel(this, frame, 8f, 18f, 9f * 18f, 6f * 18f, 9, 6)
for (slot in menu.storageSlots)
UserFilteredSlotPanel.of(this, grid, slot)
if (menu.isInput) {
val controls = DeviceControls(this, frame)
controls.sortingButtons(menu.sort)
}
return frame
}
}

View File

@ -0,0 +1,43 @@
package ru.dbotthepony.mc.otm.client.screen.tech
import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
import ru.dbotthepony.mc.otm.client.screen.panels.DockResizeMode
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.SpritePanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.MatterCapacitorSlotPanel
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
import ru.dbotthepony.mc.otm.menu.tech.MatterHatchMenu
class MatterHatchScreen(menu: MatterHatchMenu, inventory: Inventory, title: Component) : MatteryScreen<MatterHatchMenu>(menu, inventory, title) {
override fun makeMainFrame(): FramePanel<MatteryScreen<*>> {
val frame = FramePanel(this, null, 0f, 0f, INVENTORY_FRAME_WIDTH, AbstractSlotPanel.SIZE, getTitle())
frame.makeCloseButton()
frame.onClose { onClose() }
for (slot in menu.inputSlots) {
val panel = MatterCapacitorSlotPanel(this, frame, slot)
panel.dock = Dock.LEFT
panel.dockResize = DockResizeMode.NONE
}
val arrow = SpritePanel(this, frame, ProgressGaugePanel.GAUGE_BACKGROUND)
arrow.dockLeft = 2f
arrow.dockRight = 2f
arrow.dock = Dock.LEFT
arrow.dockResize = DockResizeMode.NONE
if (!menu.isInput)
arrow.winding = UVWindingOrder.FLOP
DeviceControls(this, frame, redstoneConfig = menu.redstone)
return frame
}
}

View File

@ -1,6 +1,5 @@
package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal
import ru.dbotthepony.mc.otm.registry.MNames
@ -193,6 +192,39 @@ object MachinesConfig : AbstractConfig("machines") {
maxExperience = 200.0
)
val ENERGY_HATCH = conciseValues(
"ENERGY_HATCH",
storage = Decimal(6_000_000),
throughput = Decimal(200_000)
)
val MATTER_HATCH by builder
.comment("Internal buffer of matter hatch")
.defineDecimal("MATTER_HATCH", Decimal(200), Decimal.ONE)
object BlackHoleGenerator {
init {
builder.push("BLACK_HOLE_GENERATOR")
}
val MATTER_RATE: Decimal
get() = Decimal("0.25")
val MASS_DIVISOR: Decimal
get() = Decimal.TEN
val MASS_FEEDING_RATIO: Decimal
get() = Decimal("0.1")
init {
builder.pop()
}
}
init {
BlackHoleGenerator
}
object Upgrades {
init {
builder.push("UPGRADES")

View File

@ -13,6 +13,7 @@ import com.google.gson.JsonPrimitive
import it.unimi.dsi.fastutil.objects.ObjectComparators
import net.minecraft.Util
import net.minecraft.core.BlockPos
import net.minecraft.core.SectionPos
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.NbtAccounter
import net.minecraft.network.FriendlyByteBuf
@ -26,6 +27,7 @@ import net.minecraft.world.item.Items
import net.minecraft.world.item.crafting.Ingredient
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.state.BlockState
@ -104,6 +106,10 @@ operator fun JsonObject.set(s: String, value: String) = add(s, JsonPrimitive(val
operator fun JsonObject.set(s: String, value: Number) = add(s, JsonPrimitive(value))
operator fun JsonObject.set(s: String, value: Boolean) = add(s, JsonPrimitive(value))
fun LevelAccessor.getBlockStateNow(pos: BlockPos): BlockState {
return chunkSource.getChunkNow(SectionPos.blockToSectionCoord(pos.x), SectionPos.blockToSectionCoord(pos.z))?.getBlockState(pos) ?: Blocks.AIR.defaultBlockState()
}
fun <T> LazyOptional<T>.orNull(): T? {
if (!isPresent) {
return null

View File

@ -189,7 +189,7 @@ class MultiblockBuilder {
fun block(block: Block): T {
predicates.add { pos, access ->
// use getChunk directly because we don't want to chunkload
(access.getChunk(SectionPos.blockToSectionCoord(pos.x), SectionPos.blockToSectionCoord(pos.z), ChunkStatus.FULL, false)?.getBlockState(pos) ?: Blocks.AIR.defaultBlockState()).`is`(block)
access.getBlockStateNow(pos).block == block
}
return this as T
@ -198,7 +198,7 @@ class MultiblockBuilder {
fun block(block: TagKey<Block>): T {
predicates.add { pos, access ->
// use getChunk directly because we don't want to chunkload
(access.getChunk(SectionPos.blockToSectionCoord(pos.x), SectionPos.blockToSectionCoord(pos.z), ChunkStatus.FULL, false)?.getBlockState(pos) ?: Blocks.AIR.defaultBlockState()).`is`(block)
access.getBlockStateNow(pos).`is`(block)
}
return this as T

View File

@ -0,0 +1,52 @@
package ru.dbotthepony.mc.otm.menu.tech
import net.minecraft.world.Container
import net.minecraft.world.SimpleContainer
import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting
import ru.dbotthepony.mc.otm.block.entity.tech.EnergyHatchBlockEntity
import ru.dbotthepony.mc.otm.block.entity.tech.MatterHatchBlockEntity
import ru.dbotthepony.mc.otm.capability.FlowDirection
import ru.dbotthepony.mc.otm.menu.BatterySlot
import ru.dbotthepony.mc.otm.menu.EnergyContainerInputSlot
import ru.dbotthepony.mc.otm.menu.MatterContainerInputSlot
import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback
import ru.dbotthepony.mc.otm.menu.makeSlots
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
import ru.dbotthepony.mc.otm.registry.MMenus
class EnergyHatchMenu(
val isInput: Boolean,
containerId: Int,
inventory: Inventory,
tile: EnergyHatchBlockEntity? = null
) : MatteryMenu(if (isInput) MMenus.ENERGY_INPUT_HATCH else MMenus.ENERGY_OUTPUT_HATCH, containerId, inventory, tile) {
val container: Container = tile?.container ?: SimpleContainer(EnergyHatchBlockEntity.CAPACITY)
val inputSlots = makeSlots(container) { a, b ->
EnergyContainerInputSlot(a, b, direction = FlowDirection.input(isInput))
}
val gauge = ProfiledLevelGaugeWidget(this, tile?.energy)
val redstone = EnumInputWithFeedback<RedstoneSetting>(this)
init {
if (tile != null)
redstone.with(tile.redstoneControl::redstoneSetting)
addStorageSlot(inputSlots)
addInventorySlots()
}
companion object {
fun input(containerId: Int, inventory: Inventory, tile: EnergyHatchBlockEntity? = null): EnergyHatchMenu {
return EnergyHatchMenu(true, containerId, inventory, tile)
}
fun output(containerId: Int, inventory: Inventory, tile: EnergyHatchBlockEntity? = null): EnergyHatchMenu {
return EnergyHatchMenu(false, containerId, inventory, tile)
}
}
}

View File

@ -0,0 +1,52 @@
package ru.dbotthepony.mc.otm.menu.tech
import com.google.common.collect.ImmutableList
import net.minecraft.world.Container
import net.minecraft.world.SimpleContainer
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting
import ru.dbotthepony.mc.otm.block.entity.tech.ItemHatchBlockEntity
import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.menu.UserFilteredSlot
import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback
import ru.dbotthepony.mc.otm.menu.makeSlots
import ru.dbotthepony.mc.otm.registry.MMenus
class ItemHatchMenu(
val isInput: Boolean,
containerId: Int,
inventory: Inventory,
tile: ItemHatchBlockEntity? = null
) : MatteryMenu(if (isInput) MMenus.ITEM_INPUT_HATCH else MMenus.ITEM_OUTPUT_HATCH, containerId, inventory, tile) {
val actualContainer: Container = tile?.container ?: SimpleContainer(ItemHatchBlockEntity.CAPACITY)
val storageSlots: ImmutableList<UserFilteredSlot> = makeSlots(actualContainer) { a, b ->
object : UserFilteredSlot(a, b) {
override fun mayPlace(itemStack: ItemStack): Boolean {
return isInput && super.mayPlace(itemStack)
}
}
}
val sort = SortInput(actualContainer, playerSortSettings)
val redstone = EnumInputWithFeedback<RedstoneSetting>(this)
init {
if (tile != null)
redstone.with(tile.redstoneControl::redstoneSetting)
sort.input.filter { isInput }
addStorageSlot(storageSlots)
addInventorySlots()
}
companion object {
fun input(containerId: Int, inventory: Inventory, tile: ItemHatchBlockEntity? = null): ItemHatchMenu {
return ItemHatchMenu(true, containerId, inventory, tile)
}
fun output(containerId: Int, inventory: Inventory, tile: ItemHatchBlockEntity? = null): ItemHatchMenu {
return ItemHatchMenu(false, containerId, inventory, tile)
}
}
}

View File

@ -0,0 +1,49 @@
package ru.dbotthepony.mc.otm.menu.tech
import net.minecraft.world.Container
import net.minecraft.world.SimpleContainer
import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting
import ru.dbotthepony.mc.otm.block.entity.tech.MatterHatchBlockEntity
import ru.dbotthepony.mc.otm.capability.FlowDirection
import ru.dbotthepony.mc.otm.menu.MatterContainerInputSlot
import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback
import ru.dbotthepony.mc.otm.menu.makeSlots
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
import ru.dbotthepony.mc.otm.registry.MMenus
class MatterHatchMenu(
val isInput: Boolean,
containerId: Int,
inventory: Inventory,
tile: MatterHatchBlockEntity? = null
) : MatteryMenu(if (isInput) MMenus.MATTER_INPUT_HATCH else MMenus.MATTER_OUTPUT_HATCH, containerId, inventory, tile) {
val container: Container = tile?.container ?: SimpleContainer(MatterHatchBlockEntity.CAPACITY)
val inputSlots = makeSlots(container) { a, b ->
MatterContainerInputSlot(a, b, direction = FlowDirection.input(isInput))
}
val gauge = ProfiledLevelGaugeWidget(this, tile?.matter)
val redstone = EnumInputWithFeedback<RedstoneSetting>(this)
init {
if (tile != null)
redstone.with(tile.redstoneControl::redstoneSetting)
addStorageSlot(inputSlots)
addInventorySlots()
}
companion object {
fun input(containerId: Int, inventory: Inventory, tile: MatterHatchBlockEntity? = null): MatterHatchMenu {
return MatterHatchMenu(true, containerId, inventory, tile)
}
fun output(containerId: Int, inventory: Inventory, tile: MatterHatchBlockEntity? = null): MatterHatchMenu {
return MatterHatchMenu(false, containerId, inventory, tile)
}
}
}

View File

@ -6,10 +6,7 @@ import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraftforge.eventbus.api.IEventBus
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent
import net.minecraftforge.registries.DeferredRegister
import net.minecraftforge.registries.ForgeRegistries
import net.minecraftforge.registries.RegistryObject
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.block.entity.*
import ru.dbotthepony.mc.otm.block.entity.tech.*
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
@ -23,6 +20,7 @@ import ru.dbotthepony.mc.otm.block.entity.decorative.HoloSignBlockEntity
import ru.dbotthepony.mc.otm.block.entity.decorative.InfiniteWaterSourceBlockEntity
import ru.dbotthepony.mc.otm.block.entity.decorative.PainterBlockEntity
import ru.dbotthepony.mc.otm.block.entity.matter.*
import ru.dbotthepony.mc.otm.block.entity.tech.ItemHatchBlockEntity
import ru.dbotthepony.mc.otm.block.entity.storage.*
import ru.dbotthepony.mc.otm.block.entity.tech.AndroidStationBlockEntity
import ru.dbotthepony.mc.otm.block.entity.tech.BatteryBankBlockEntity
@ -31,9 +29,7 @@ import ru.dbotthepony.mc.otm.block.entity.tech.GravitationStabilizerBlockEntity
import ru.dbotthepony.mc.otm.block.entity.tech.PlatePressBlockEntity
import ru.dbotthepony.mc.otm.client.render.blockentity.*
import ru.dbotthepony.mc.otm.config.CablesConfig
import ru.dbotthepony.mc.otm.core.asSupplierArray
import ru.dbotthepony.mc.otm.core.collect.SupplierMap
import ru.dbotthepony.mc.otm.core.getValue
import java.util.function.Supplier
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS") // Type<*> is unused in BlockEntityType.Builder
@ -86,6 +82,13 @@ object MBlockEntities {
val DEV_CHEST by register(MNames.DEV_CHEST, ::DevChestBlockEntity, MBlocks::DEV_CHEST)
val PAINTER by register(MNames.PAINTER, ::PainterBlockEntity, MBlocks::PAINTER)
val MATTER_ENTANGLER by register(MNames.MATTER_ENTANGLER, ::MatterEntanglerBlockEntity, MBlocks::MATTER_ENTANGLER)
val BLACK_HOLE_GENERATOR by register(MNames.BLACK_HOLE_GENERATOR, ::BlackHoleGeneratorBlockEntity, MBlocks::BLACK_HOLE_GENERATOR)
val ITEM_INPUT_HATCH by register(MNames.ITEM_INPUT_HATCH, ItemHatchBlockEntity::input, MBlocks::ITEM_INPUT_HATCH)
val ITEM_OUTPUT_HATCH by register(MNames.ITEM_OUTPUT_HATCH, ItemHatchBlockEntity::output, MBlocks::ITEM_OUTPUT_HATCH)
val ENERGY_INPUT_HATCH by register(MNames.ENERGY_INPUT_HATCH, EnergyHatchBlockEntity::input, MBlocks::ENERGY_INPUT_HATCH)
val ENERGY_OUTPUT_HATCH by register(MNames.ENERGY_OUTPUT_HATCH, EnergyHatchBlockEntity::output, MBlocks::ENERGY_OUTPUT_HATCH)
val MATTER_INPUT_HATCH by register(MNames.MATTER_INPUT_HATCH, MatterHatchBlockEntity::input, MBlocks::MATTER_INPUT_HATCH)
val MATTER_OUTPUT_HATCH by register(MNames.MATTER_OUTPUT_HATCH, MatterHatchBlockEntity::output, MBlocks::MATTER_OUTPUT_HATCH)
val POWERED_FURNACE by register(MNames.POWERED_FURNACE, ::PoweredFurnaceBlockEntity, MBlocks.POWERED_FURNACE)
val POWERED_BLAST_FURNACE by register(MNames.POWERED_BLAST_FURNACE, ::PoweredBlastFurnaceBlockEntity, MBlocks.POWERED_BLAST_FURNACE)
@ -93,9 +96,9 @@ object MBlockEntities {
val MULTIBLOCK_TEST by register("multiblock_test", ::MultiblockTestBlockEntity, MBlocks::MULTIBLOCK_TEST)
val ENERGY_CABLES: Map<CablesConfig.E, BlockEntityType<*>> = SupplierMap(CablesConfig.E.entries.map { conf ->
var selfFeed: Supplier<BlockEntityType<*>> = Supplier { TODO() }
selfFeed = register("${conf.name.lowercase()}_energy_cable", { a, b -> SimpleEnergyCableBlockEntity(selfFeed.get(), a, b, conf) }) as Supplier<BlockEntityType<*>>
val ENERGY_CABLES: Map<CablesConfig.E, BlockEntityType<SimpleEnergyCableBlockEntity>> = SupplierMap(CablesConfig.E.entries.map { conf ->
var selfFeed: Supplier<BlockEntityType<SimpleEnergyCableBlockEntity>> = Supplier { TODO() }
selfFeed = register("${conf.name.lowercase()}_energy_cable", { a, b -> SimpleEnergyCableBlockEntity(selfFeed.get(), a, b, conf) })
conf to selfFeed
})

View File

@ -1,8 +1,6 @@
package ru.dbotthepony.mc.otm.registry
import net.minecraft.util.valueproviders.UniformInt
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.crafting.RecipeType
import net.minecraft.world.level.block.AnvilBlock
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.DropExperienceBlock
@ -18,9 +16,7 @@ import net.minecraft.world.level.block.state.properties.NoteBlockInstrument
import net.minecraft.world.level.material.MapColor
import net.minecraft.world.level.material.PushReaction
import net.minecraftforge.eventbus.api.IEventBus
import net.minecraftforge.registries.DeferredRegister
import net.minecraftforge.registries.ForgeRegistries
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.block.BlackHoleBlock
import ru.dbotthepony.mc.otm.block.BlockExplosionDebugger
import ru.dbotthepony.mc.otm.block.BlockSphereDebugger
@ -28,6 +24,7 @@ import ru.dbotthepony.mc.otm.block.EnergyCableBlock
import ru.dbotthepony.mc.otm.block.MatterCableBlock
import ru.dbotthepony.mc.otm.block.MatteryBlock
import ru.dbotthepony.mc.otm.block.MultiblockTestBlock
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.StorageCableBlock
import ru.dbotthepony.mc.otm.block.addSimpleDescription
import ru.dbotthepony.mc.otm.block.decorative.DevChestBlock
@ -40,6 +37,9 @@ import ru.dbotthepony.mc.otm.block.decorative.LaboratoryLampLight
import ru.dbotthepony.mc.otm.block.decorative.PainterBlock
import ru.dbotthepony.mc.otm.block.decorative.TritaniumDoorBlock
import ru.dbotthepony.mc.otm.block.decorative.TritaniumTrapdoorBlock
import ru.dbotthepony.mc.otm.block.entity.tech.EnergyHatchBlockEntity
import ru.dbotthepony.mc.otm.block.entity.tech.ItemHatchBlockEntity
import ru.dbotthepony.mc.otm.block.entity.tech.MatterHatchBlockEntity
import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock
import ru.dbotthepony.mc.otm.block.matter.MatterCapacitorBankBlock
import ru.dbotthepony.mc.otm.block.matter.MatterDecomposerBlock
@ -50,6 +50,7 @@ import ru.dbotthepony.mc.otm.block.matter.MatterRecyclerBlock
import ru.dbotthepony.mc.otm.block.matter.MatterReplicatorBlock
import ru.dbotthepony.mc.otm.block.matter.MatterScannerBlock
import ru.dbotthepony.mc.otm.block.matter.PatternStorageBlock
import ru.dbotthepony.mc.otm.block.tech.HatchBlock
import ru.dbotthepony.mc.otm.block.storage.DriveRackBlock
import ru.dbotthepony.mc.otm.block.storage.DriveViewerBlock
import ru.dbotthepony.mc.otm.block.storage.ItemMonitorBlock
@ -60,6 +61,7 @@ import ru.dbotthepony.mc.otm.block.storage.StoragePowerSupplierBlock
import ru.dbotthepony.mc.otm.block.tech.AndroidChargerBlock
import ru.dbotthepony.mc.otm.block.tech.AndroidStationBlock
import ru.dbotthepony.mc.otm.block.tech.BatteryBankBlock
import ru.dbotthepony.mc.otm.block.tech.BlackHoleGeneratorBlock
import ru.dbotthepony.mc.otm.block.tech.BlockGravitationStabilizer
import ru.dbotthepony.mc.otm.block.tech.BlockGravitationStabilizerLens
import ru.dbotthepony.mc.otm.block.tech.ChemicalGeneratorBlock
@ -69,15 +71,12 @@ import ru.dbotthepony.mc.otm.block.tech.EnergyServoBlock
import ru.dbotthepony.mc.otm.block.tech.EssenceStorageBlock
import ru.dbotthepony.mc.otm.block.tech.PhantomAttractorBlock
import ru.dbotthepony.mc.otm.block.tech.PlatePressBlock
import ru.dbotthepony.mc.otm.block.tech.AbstractPoweredFurnaceBlock
import ru.dbotthepony.mc.otm.block.tech.PoweredBlastFurnaceBlock
import ru.dbotthepony.mc.otm.block.tech.PoweredFurnaceBlock
import ru.dbotthepony.mc.otm.block.tech.PoweredSmokerBlock
import ru.dbotthepony.mc.otm.config.CablesConfig
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.core.collect.SupplierList
import ru.dbotthepony.mc.otm.core.collect.SupplierMap
import ru.dbotthepony.mc.otm.shapes.BlockShapes
import java.util.function.Supplier
object MBlocks {
@ -139,6 +138,18 @@ object MBlocks {
val FLUID_TANK: FluidTankBlock by registry.register(MNames.FLUID_TANK) { FluidTankBlock() }
val DEV_CHEST: DevChestBlock by registry.register(MNames.DEV_CHEST) { DevChestBlock() }
val MULTIBLOCK_STRUCTURE by registry.register(MNames.MULTIBLOCK_STRUCTURE) { MatteryBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).requiresCorrectToolForDrops().destroyTime(2.5f).explosionResistance(160.0f)) }
val BLACK_HOLE_GENERATOR by registry.register(MNames.BLACK_HOLE_GENERATOR) { BlackHoleGeneratorBlock() }
val MATTER_INJECTOR by registry.register(MNames.MATTER_INJECTOR) { RotatableMatteryBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).requiresCorrectToolForDrops().destroyTime(2.5f).explosionResistance(160.0f)) }
val ANTIMATTER_INJECTOR by registry.register(MNames.ANTIMATTER_INJECTOR) { RotatableMatteryBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).requiresCorrectToolForDrops().destroyTime(2.5f).explosionResistance(160.0f)) }
val HIGH_ENERGY_PARTICLE_COLLECTOR by registry.register(MNames.HIGH_ENERGY_PARTICLE_COLLECTOR) { RotatableMatteryBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).requiresCorrectToolForDrops().destroyTime(2.5f).explosionResistance(160.0f)) }
val ITEM_INPUT_HATCH by registry.register(MNames.ITEM_INPUT_HATCH) { HatchBlock(ItemHatchBlockEntity::input) }
val ITEM_OUTPUT_HATCH by registry.register(MNames.ITEM_OUTPUT_HATCH) { HatchBlock(ItemHatchBlockEntity::output) }
val ENERGY_INPUT_HATCH by registry.register(MNames.ENERGY_INPUT_HATCH) { HatchBlock(EnergyHatchBlockEntity::input) }
val ENERGY_OUTPUT_HATCH by registry.register(MNames.ENERGY_OUTPUT_HATCH) { HatchBlock(EnergyHatchBlockEntity::output) }
val MATTER_INPUT_HATCH by registry.register(MNames.MATTER_INPUT_HATCH) { HatchBlock(MatterHatchBlockEntity::input, true) }
val MATTER_OUTPUT_HATCH by registry.register(MNames.MATTER_OUTPUT_HATCH) { HatchBlock(MatterHatchBlockEntity::output, true) }
val LIQUID_XP: LiquidBlock by registry.register("liquid_xp") { LiquidBlock(MFluids::LIQUID_XP, BlockBehaviour.Properties.of().mapColor(MapColor.EMERALD).replaceable().noCollission().strength(100.0f).pushReaction(PushReaction.DESTROY).noLootTable().liquid().sound(SoundType.EMPTY)) }
val TRITANIUM_ORE: Block by registry.register(MNames.TRITANIUM_ORE) { DropExperienceBlock(

View File

@ -110,6 +110,14 @@ object MItems {
val PAINTER: BlockItem by registry.register(MNames.PAINTER) { BlockItem(MBlocks.PAINTER, DEFAULT_PROPERTIES) }
val MATTER_ENTANGLER: BlockItem by registry.register(MNames.MATTER_ENTANGLER) { BlockItem(MBlocks.MATTER_ENTANGLER, DEFAULT_PROPERTIES) }
val BLACK_HOLE_GENERATOR by registry.register(MNames.BLACK_HOLE_GENERATOR) { BlockItem(MBlocks.BLACK_HOLE_GENERATOR, DEFAULT_PROPERTIES) }
val ITEM_INPUT_HATCH by registry.register(MNames.ITEM_INPUT_HATCH) { BlockItem(MBlocks.ITEM_INPUT_HATCH, DEFAULT_PROPERTIES) }
val ITEM_OUTPUT_HATCH by registry.register(MNames.ITEM_OUTPUT_HATCH) { BlockItem(MBlocks.ITEM_OUTPUT_HATCH, DEFAULT_PROPERTIES) }
val ENERGY_INPUT_HATCH by registry.register(MNames.ENERGY_INPUT_HATCH) { BlockItem(MBlocks.ENERGY_INPUT_HATCH, DEFAULT_PROPERTIES) }
val ENERGY_OUTPUT_HATCH by registry.register(MNames.ENERGY_OUTPUT_HATCH) { BlockItem(MBlocks.ENERGY_OUTPUT_HATCH, DEFAULT_PROPERTIES) }
val MATTER_INPUT_HATCH by registry.register(MNames.MATTER_INPUT_HATCH) { BlockItem(MBlocks.MATTER_INPUT_HATCH, DEFAULT_PROPERTIES) }
val MATTER_OUTPUT_HATCH by registry.register(MNames.MATTER_OUTPUT_HATCH) { BlockItem(MBlocks.MATTER_OUTPUT_HATCH, DEFAULT_PROPERTIES) }
val MACHINES: List<BlockItem>
init {
@ -146,6 +154,14 @@ object MItems {
machines.add(::GRAVITATION_STABILIZER)
machines.add(::BLACK_HOLE_GENERATOR)
machines.add(::ITEM_INPUT_HATCH)
machines.add(::ITEM_OUTPUT_HATCH)
machines.add(::ENERGY_INPUT_HATCH)
machines.add(::ENERGY_OUTPUT_HATCH)
machines.add(::MATTER_INPUT_HATCH)
machines.add(::MATTER_OUTPUT_HATCH)
machines.add(::STORAGE_BUS)
machines.add(::STORAGE_IMPORTER)
machines.add(::STORAGE_EXPORTER)

View File

@ -37,6 +37,9 @@ import ru.dbotthepony.mc.otm.client.screen.tech.EnergyServoScreen
import ru.dbotthepony.mc.otm.client.screen.tech.EssenceStorageScreen
import ru.dbotthepony.mc.otm.client.screen.decorative.PainterScreen
import ru.dbotthepony.mc.otm.client.screen.tech.AbstractProcessingMachineScreen
import ru.dbotthepony.mc.otm.client.screen.tech.EnergyHatchScreen
import ru.dbotthepony.mc.otm.client.screen.tech.ItemHatchScreen
import ru.dbotthepony.mc.otm.client.screen.tech.MatterHatchScreen
import ru.dbotthepony.mc.otm.menu.decorative.CargoCrateMenu
import ru.dbotthepony.mc.otm.menu.decorative.FluidTankMenu
import ru.dbotthepony.mc.otm.menu.decorative.HoloSignMenu
@ -66,6 +69,9 @@ import ru.dbotthepony.mc.otm.menu.tech.EnergyCounterMenu
import ru.dbotthepony.mc.otm.menu.tech.EnergyServoMenu
import ru.dbotthepony.mc.otm.menu.tech.EssenceStorageMenu
import ru.dbotthepony.mc.otm.menu.decorative.PainterMenu
import ru.dbotthepony.mc.otm.menu.tech.EnergyHatchMenu
import ru.dbotthepony.mc.otm.menu.tech.ItemHatchMenu
import ru.dbotthepony.mc.otm.menu.tech.MatterHatchMenu
import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu
import ru.dbotthepony.mc.otm.menu.tech.PoweredFurnaceMenu
@ -103,6 +109,12 @@ object MMenus {
val FLUID_TANK by registry.register(MNames.FLUID_TANK) { MenuType(::FluidTankMenu, FeatureFlags.VANILLA_SET) }
val PAINTER by registry.register(MNames.PAINTER) { MenuType(::PainterMenu, FeatureFlags.VANILLA_SET) }
val MATTER_ENTANGLER by registry.register(MNames.MATTER_ENTANGLER) { MenuType(::MatterEntanglerMenu, FeatureFlags.VANILLA_SET) }
val ITEM_INPUT_HATCH by registry.register(MNames.ITEM_INPUT_HATCH) { MenuType(ItemHatchMenu::input, FeatureFlags.VANILLA_SET) }
val ITEM_OUTPUT_HATCH by registry.register(MNames.ITEM_OUTPUT_HATCH) { MenuType(ItemHatchMenu::output, FeatureFlags.VANILLA_SET) }
val MATTER_INPUT_HATCH by registry.register(MNames.MATTER_INPUT_HATCH) { MenuType(MatterHatchMenu::input, FeatureFlags.VANILLA_SET) }
val MATTER_OUTPUT_HATCH by registry.register(MNames.MATTER_OUTPUT_HATCH) { MenuType(MatterHatchMenu::output, FeatureFlags.VANILLA_SET) }
val ENERGY_INPUT_HATCH by registry.register(MNames.ENERGY_INPUT_HATCH) { MenuType(EnergyHatchMenu::input, FeatureFlags.VANILLA_SET) }
val ENERGY_OUTPUT_HATCH by registry.register(MNames.ENERGY_OUTPUT_HATCH) { MenuType(EnergyHatchMenu::output, FeatureFlags.VANILLA_SET) }
val STORAGE_BUS by registry.register(MNames.STORAGE_BUS) { MenuType(::StorageBusMenu, FeatureFlags.VANILLA_SET) }
val STORAGE_IMPORTER_EXPORTER by registry.register(MNames.STORAGE_IMPORTER) { MenuType(::StorageImporterExporterMenu, FeatureFlags.VANILLA_SET) }
@ -149,6 +161,12 @@ object MMenus {
MenuScreens.register(POWERED_SMOKER, ::AbstractProcessingMachineScreen)
MenuScreens.register(PAINTER, ::PainterScreen)
MenuScreens.register(MATTER_ENTANGLER, ::MatterEntanglerScreen)
MenuScreens.register(ITEM_INPUT_HATCH, ::ItemHatchScreen)
MenuScreens.register(ITEM_OUTPUT_HATCH, ::ItemHatchScreen)
MenuScreens.register(MATTER_INPUT_HATCH, ::MatterHatchScreen)
MenuScreens.register(MATTER_OUTPUT_HATCH, ::MatterHatchScreen)
MenuScreens.register(ENERGY_INPUT_HATCH, ::EnergyHatchScreen)
MenuScreens.register(ENERGY_OUTPUT_HATCH, ::EnergyHatchScreen)
}
}
}

View File

@ -15,6 +15,17 @@ object MNames {
const val ANDROID_CHARGER = "android_charger"
const val INFINITE_WATER_SOURCE = "infinite_water_source"
const val DEV_CHEST = "dev_chest"
const val MULTIBLOCK_STRUCTURE = "black_hole_generator"
const val BLACK_HOLE_GENERATOR = "black_hole_generator"
const val MATTER_INJECTOR = "matter_injector"
const val ANTIMATTER_INJECTOR = "antimatter_injector"
const val HIGH_ENERGY_PARTICLE_COLLECTOR = "high_energy_particle_collector"
const val ITEM_INPUT_HATCH = "item_input_hatch"
const val ITEM_OUTPUT_HATCH = "item_output_hatch"
const val ENERGY_INPUT_HATCH = "energy_input_hatch"
const val ENERGY_OUTPUT_HATCH = "energy_output_hatch"
const val MATTER_INPUT_HATCH = "matter_input_hatch"
const val MATTER_OUTPUT_HATCH = "matter_output_hatch"
const val PAINTER = "painter"
const val MATTER_ENTANGLER = "matter_entangler"