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

@ -198,12 +198,12 @@ fun InputStream.readLong(): Long {
}
return (read().toLong() shl 48) or
(read().toLong() shl 40) or
(read().toLong() shl 32) or
(read().toLong() shl 24) or
(read().toLong() shl 16) or
(read().toLong() shl 8) or
read().toLong()
(read().toLong() shl 40) or
(read().toLong() shl 32) or
(read().toLong() shl 24) or
(read().toLong() shl 16) or
(read().toLong() shl 8) or
read().toLong()
}
fun OutputStream.writeFloat(value: Float) = writeInt(value.toBits())

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"