⚙ SHOCKY — Сегодня, в 19:53
не могу мультиблок влепить текстуры что есть ибо мультиблок ещё на машине Дбота
This commit is contained in:
parent
c3c43d7af6
commit
da13d77af3
@ -19,7 +19,7 @@ forge_version=21.1.21
|
||||
mixingradle_version=0.7.33
|
||||
mixin_version=0.8.5
|
||||
|
||||
kommons_version=3.1.2
|
||||
kommons_version=3.1.3
|
||||
|
||||
jei_version=19.16.4.171
|
||||
jupiter_version=5.9.2
|
||||
|
@ -34,6 +34,7 @@ import ru.dbotthepony.mc.otm.datagen.items.MatteryItemModelProvider
|
||||
import ru.dbotthepony.mc.otm.datagen.lang.AddEnglishLanguage
|
||||
import ru.dbotthepony.mc.otm.datagen.models.MatteryBlockModelProvider
|
||||
import ru.dbotthepony.mc.otm.core.registryName
|
||||
import ru.dbotthepony.mc.otm.data.FlywheelMaterialDataProvider
|
||||
import ru.dbotthepony.mc.otm.datagen.advancements.addAdvancements
|
||||
import ru.dbotthepony.mc.otm.datagen.advancements.addAndroidAdvancements
|
||||
import ru.dbotthepony.mc.otm.datagen.blocks.addBlockModels
|
||||
@ -85,6 +86,8 @@ object DataGen {
|
||||
private set
|
||||
var matterData: MatterDataProvider by WriteOnce()
|
||||
private set
|
||||
var flywheelData: FlywheelMaterialDataProvider by WriteOnce()
|
||||
private set
|
||||
|
||||
fun decorativeCubeAll(vararg blocks: Block) {
|
||||
blockModelProvider.decorativeCubeAll(*blocks)
|
||||
@ -510,6 +513,7 @@ object DataGen {
|
||||
this.languageProvider = languageProvider
|
||||
this.researchProvider = researchProvider
|
||||
this.matterData = matterData
|
||||
this.flywheelData = FlywheelMaterialDataProvider(event)
|
||||
|
||||
val tagsProvider = TagsProvider(event)
|
||||
val advancementProvider = object : AdvancementProvider(event.generator.packOutput, event.lookupProvider, event.existingFileHelper, listOf(
|
||||
@ -542,6 +546,7 @@ object DataGen {
|
||||
event.generator.addProvider(event.includeServer(), researchProvider)
|
||||
event.generator.addProvider(event.includeServer(), advancementProvider)
|
||||
event.generator.addProvider(event.includeServer(), matterData)
|
||||
event.generator.addProvider(event.includeServer(), flywheelData)
|
||||
|
||||
val registrySetBuilder = RegistrySetBuilder()
|
||||
.add(Registries.DAMAGE_TYPE, ::registerDamageTypes)
|
||||
@ -603,6 +608,7 @@ object DataGen {
|
||||
languageProvider.registerProviders()
|
||||
|
||||
addMatterData(matterData)
|
||||
addFlywheelMaterials(flywheelData)
|
||||
|
||||
tagsProvider.register()
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
package ru.dbotthepony.mc.otm.datagen
|
||||
|
||||
import net.neoforged.neoforge.common.Tags
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.data.FlywheelMaterialDataProvider
|
||||
import ru.dbotthepony.mc.otm.registry.MBlockTags
|
||||
|
||||
fun addFlywheelMaterials(provider: FlywheelMaterialDataProvider) {
|
||||
provider.add(Tags.Blocks.STORAGE_BLOCKS_DIAMOND, Decimal(1_000_000))
|
||||
provider.add(Tags.Blocks.STORAGE_BLOCKS_COPPER, Decimal(3_500_000))
|
||||
provider.add(Tags.Blocks.STORAGE_BLOCKS_IRON, Decimal(3_000_000))
|
||||
provider.add(Tags.Blocks.STORAGE_BLOCKS_GOLD, Decimal(18_000_000))
|
||||
provider.add(MBlockTags.TRITANIUM_BLOCKS, Decimal(9_000_000))
|
||||
}
|
@ -543,6 +543,30 @@ private fun blocks(provider: MatteryLanguageProvider) {
|
||||
add(MBlocks.BLACK_HOLE, "Local Anomalous Spacetime Dilation Singular Point")
|
||||
add(MBlocks.BLACK_HOLE_GENERATOR, "Matter Acceleration Power Generator")
|
||||
|
||||
add(MBlocks.FLYWHEEL_SHAFT, "Flywheel Shaft")
|
||||
add(MBlocks.FLYWHEEL_SHAFT, "desc", "Placed between bearings, safe for decoration")
|
||||
|
||||
add(MBlocks.FLYWHEEL_BEARING, "Flywheel Bearing")
|
||||
add(MBlocks.FLYWHEEL_BEARING, "desc", "Replaces center block of housing at bottom and top, safe for decoration")
|
||||
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "Flywheel Controller")
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "desc", "Multiblock controller, requires housing, bearing, shaft, generator and core material of choice")
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "desc2", "Can have arbitrary height, with bottom limit of 4 blocks tall")
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "desc3", "Built as rectangular shape, with base surface of 5 by 5 blocks")
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "desc4", "Uses Energy *Interface*s as I/O ports, which must be put at same level as generator blocks inside structure,")
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "desc5", "replacing housing blocks")
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "desc6", "Important: must replace housing block in wall in middle at same level where flywheel material start,")
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "desc7", "in other words, controller is put one block above absolute bottom of structure")
|
||||
|
||||
add(MBlocks.FLYWHEEL_HOUSING, "Flywheel Housing")
|
||||
add(MBlocks.FLYWHEEL_HOUSING, "desc", "5xNx5 multiblock casing, safe for decoration")
|
||||
|
||||
add(MBlocks.GENERATOR_BLOCK, "Generator Block")
|
||||
add(MBlocks.GENERATOR_BLOCK, "desc", "Part of multiblock, safe for decoration")
|
||||
|
||||
add(MBlocks.ENERGY_INPUT_INTERFACE, "Energy Input Interface")
|
||||
add(MBlocks.ENERGY_OUTPUT_INTERFACE, "Energy Output Interface")
|
||||
|
||||
add(MBlocks.ENERGY_INPUT_HATCH, "Energy Input Hatch")
|
||||
add(MBlocks.ITEM_INPUT_HATCH, "Item Input Hatch")
|
||||
add(MBlocks.MATTER_INPUT_HATCH, "Matter Input Hatch")
|
||||
|
@ -542,6 +542,30 @@ private fun blocks(provider: MatteryLanguageProvider) {
|
||||
add(MBlocks.BLACK_HOLE, "Локализированная сингулярная точка аномального искажения пространства-времени")
|
||||
add(MBlocks.BLACK_HOLE_GENERATOR, "Генератор энергии ускорением материи")
|
||||
|
||||
add(MBlocks.FLYWHEEL_SHAFT, "Маховый вал")
|
||||
add(MBlocks.FLYWHEEL_SHAFT, "desc", "Устанавливается между подшипников")
|
||||
|
||||
add(MBlocks.FLYWHEEL_BEARING, "Маховый подшипник")
|
||||
add(MBlocks.FLYWHEEL_BEARING, "desc", "Заменяет центральный блок корпуса снизу и сверху")
|
||||
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "Блок управления маховым хранилищем энергии")
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "desc", "Мультиблок, который требует подшипники, корпус, вал, блоки генераторов и ядро из материала на ваше усмотрение")
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "desc2", "Имеет неограниченную высоту, с нижним порогом в 4 блока")
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "desc3", "Строится как параллелепипед с основной в 5 на 5 блоков")
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "desc4", "Использует энергетические *интерфейсы* как порты ввода вывода, и они должны быть установлены на том же")
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "desc5", "уровне, что и блоки генераторов")
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "desc6", "Важно: должен быть установлен в стене по середине на том же уровне, где находится ядро,")
|
||||
add(MBlocks.FLYWHEEL_BATTERY, "desc7", "иначе говоря, он заменяет блок корпуса на высоте одного блока относительно 'пола' структуры")
|
||||
|
||||
add(MBlocks.FLYWHEEL_HOUSING, "Корпус махового хранилища энергии")
|
||||
add(MBlocks.FLYWHEEL_HOUSING, "desc", "Мультиблок структура с размерностью 5xNx5")
|
||||
|
||||
add(MBlocks.GENERATOR_BLOCK, "Generator Block")
|
||||
add(MBlocks.GENERATOR_BLOCK, "desc", "Part of multiblock, safe for decoration")
|
||||
|
||||
add(MBlocks.ENERGY_INPUT_INTERFACE, "Входной энергетический интерфейс")
|
||||
add(MBlocks.ENERGY_OUTPUT_INTERFACE, "Выходной энергетический интерфейс")
|
||||
|
||||
add(MBlocks.ENERGY_INPUT_HATCH, "Входной энергетический клапан")
|
||||
add(MBlocks.ITEM_INPUT_HATCH, "Входной предметный клапан")
|
||||
add(MBlocks.MATTER_INPUT_HATCH, "Входной клапан материи")
|
||||
|
@ -45,6 +45,11 @@ fun addDecorativeLoot(lootTables: LootTables) {
|
||||
lootTables.dropsSelf(MBlocks.TRITANIUM_INGOT_BLOCK) { condition(ExplosionCondition.survivesExplosion()) }
|
||||
lootTables.dropsSelf(MBlocks.TRITANIUM_BARS) { condition(ExplosionCondition.survivesExplosion()) }
|
||||
|
||||
lootTables.dropsSelf(MBlocks.GENERATOR_BLOCK) { condition(ExplosionCondition.survivesExplosion()) }
|
||||
lootTables.dropsSelf(MBlocks.FLYWHEEL_SHAFT) { condition(ExplosionCondition.survivesExplosion()) }
|
||||
lootTables.dropsSelf(MBlocks.FLYWHEEL_HOUSING) { condition(ExplosionCondition.survivesExplosion()) }
|
||||
lootTables.dropsSelf(MBlocks.FLYWHEEL_BEARING) { condition(ExplosionCondition.survivesExplosion()) }
|
||||
|
||||
lootTables.dropsSelf(MBlocks.ENGINE) { condition(ExplosionCondition.survivesExplosion()) }
|
||||
|
||||
for (block in MBlocks.TRITANIUM_ANVIL)
|
||||
|
@ -59,6 +59,14 @@ fun addMachineLoot(lootTables: LootTables) {
|
||||
lootTables.tile(MBlocks.MATTER_BOTTLER.values)
|
||||
|
||||
lootTables.tile(MBlocks.BLACK_HOLE_GENERATOR)
|
||||
lootTables.tile(MBlocks.FLYWHEEL_BATTERY)
|
||||
|
||||
lootTables.tile(MBlocks.ITEM_INPUT_HATCH)
|
||||
lootTables.tile(MBlocks.ITEM_OUTPUT_HATCH)
|
||||
lootTables.tile(MBlocks.ENERGY_INPUT_HATCH)
|
||||
lootTables.tile(MBlocks.ENERGY_OUTPUT_HATCH)
|
||||
lootTables.tile(MBlocks.MATTER_INPUT_HATCH)
|
||||
lootTables.tile(MBlocks.MATTER_OUTPUT_HATCH)
|
||||
lootTables.tile(MBlocks.ENERGY_INPUT_INTERFACE)
|
||||
lootTables.tile(MBlocks.ENERGY_OUTPUT_INTERFACE)
|
||||
}
|
||||
|
@ -67,6 +67,12 @@ fun addMineableTags(tagsProvider: TagsProvider) {
|
||||
MBlocks.BLACK_HOLE_GENERATOR,
|
||||
MBlocks.ITEM_INPUT_HATCH,
|
||||
MBlocks.ITEM_OUTPUT_HATCH,
|
||||
MBlocks.ENERGY_INPUT_HATCH,
|
||||
MBlocks.ENERGY_OUTPUT_HATCH,
|
||||
MBlocks.MATTER_INPUT_HATCH,
|
||||
MBlocks.MATTER_OUTPUT_HATCH,
|
||||
MBlocks.ENERGY_INPUT_INTERFACE,
|
||||
MBlocks.ENERGY_OUTPUT_INTERFACE,
|
||||
), Tiers.IRON)
|
||||
|
||||
tagsProvider.requiresPickaxe(listOf(
|
||||
|
@ -35,9 +35,6 @@ fun addTags(tagsProvider: TagsProvider) {
|
||||
|
||||
tagsProvider.items.Appender(MItemTags.MINECART_CARGO_CRATES).add(MItems.CARGO_CRATE_MINECARTS.values)
|
||||
|
||||
tagsProvider.items.Appender(MItemTags.MACHINES).add(MItems.MACHINES)
|
||||
tagsProvider.blocks.Appender(MBlockTags.MACHINES).add(MItems.MACHINES.stream().map { it!!.block })
|
||||
|
||||
tagsProvider.blocks.Appender(BlockTags.ANVIL).add(MBlocks.TRITANIUM_ANVIL)
|
||||
tagsProvider.items.Appender(ItemTags.ANVIL).add(MItems.TRITANIUM_ANVIL)
|
||||
|
||||
|
@ -51,6 +51,7 @@ import ru.dbotthepony.mc.otm.config.ItemsConfig
|
||||
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||
import ru.dbotthepony.mc.otm.config.ServerConfig
|
||||
import ru.dbotthepony.mc.otm.config.ToolsConfig
|
||||
import ru.dbotthepony.mc.otm.data.FlywheelMaterials
|
||||
import ru.dbotthepony.mc.otm.data.world.DecimalProvider
|
||||
import ru.dbotthepony.mc.otm.item.ChestUpgraderItem
|
||||
import ru.dbotthepony.mc.otm.item.tool.ExplosiveHammerItem
|
||||
@ -204,6 +205,8 @@ object OverdriveThatMatters {
|
||||
FORGE_BUS.addListener(EventPriority.NORMAL, AndroidResearchManager::reloadEvent)
|
||||
FORGE_BUS.addListener(EventPriority.NORMAL, AndroidResearchManager::syncEvent)
|
||||
|
||||
FORGE_BUS.addListener(EventPriority.NORMAL, FlywheelMaterials::reloadEvent)
|
||||
|
||||
FORGE_BUS.addListener(EventPriority.NORMAL, MatterManager::reloadEvent)
|
||||
FORGE_BUS.addListener(EventPriority.NORMAL, MatterManager::onServerStarted)
|
||||
FORGE_BUS.addListener(EventPriority.NORMAL, MatterManager::onDataPackSync)
|
||||
|
@ -55,6 +55,7 @@ class BlackHoleGeneratorBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
||||
field.accept(value)
|
||||
} else if (value != field.value) {
|
||||
multiblockSyncher?.close()
|
||||
multiblock?.close()
|
||||
multiblock = CONFIGURATIONS[value - 5].value.create(blockPos)
|
||||
multiblockSyncher = syncher.add0(multiblock!!)
|
||||
field.accept(value)
|
||||
@ -67,13 +68,13 @@ class BlackHoleGeneratorBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
||||
val energy = CombinedProfiledEnergyStorage(
|
||||
FlowDirection.NONE,
|
||||
{ multiblock?.blockEntities(EnergyHatchBlockEntity.OUTPUT_TAG)?.iterator()?.map { it.energy } ?: ObjectIterators.emptyIterator() },
|
||||
{ level?.random?.let { RandomSource2Generator(it) } }
|
||||
{ level?.random }
|
||||
)
|
||||
|
||||
val matter = CombinedProfiledMatterStorage(
|
||||
FlowDirection.NONE,
|
||||
{ multiblock?.blockEntities(MatterHatchBlockEntity.INPUT_TAG)?.iterator()?.map { it.matter } ?: ObjectIterators.emptyIterator() },
|
||||
{ level?.random?.let { RandomSource2Generator(it) } }
|
||||
{ level?.random }
|
||||
)
|
||||
|
||||
enum class Mode(val label: Component, val tooltip: Component) {
|
||||
@ -133,6 +134,13 @@ class BlackHoleGeneratorBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
||||
return -1
|
||||
}
|
||||
|
||||
override fun setRemoved() {
|
||||
super.setRemoved()
|
||||
|
||||
multiblock?.close()
|
||||
multiblock = null
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
|
||||
|
@ -8,6 +8,7 @@ import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.neoforged.neoforge.capabilities.Capabilities
|
||||
import net.neoforged.neoforge.energy.IEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||
import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl
|
||||
@ -17,6 +18,7 @@ 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.math.RelativeSide
|
||||
import ru.dbotthepony.mc.otm.core.multiblock.BlockEntityTag
|
||||
import ru.dbotthepony.mc.otm.menu.tech.EnergyHatchMenu
|
||||
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
||||
@ -37,14 +39,21 @@ class EnergyHatchBlockEntity(
|
||||
}.also(::addDroppableContainer)
|
||||
|
||||
val itemHandler = container.handler(if (isInput) HandlerFilter.Dischargeable else HandlerFilter.Chargeable)
|
||||
private val neighbours = ArrayList<CapabilityCache<IEnergyStorage>>()
|
||||
|
||||
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(Capabilities.EnergyStorage.BLOCK, energy)
|
||||
exposeEnergyGlobally(energy)
|
||||
exposeGlobally(Capabilities.ItemHandler.BLOCK, itemHandler)
|
||||
|
||||
if (!isInput) {
|
||||
for (side in RelativeSide.entries) {
|
||||
neighbours.add(CapabilityCache(side, Capabilities.EnergyStorage.BLOCK))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
@ -60,6 +69,16 @@ class EnergyHatchBlockEntity(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isInput) {
|
||||
neighbours.forEach {
|
||||
val get = it.get()
|
||||
|
||||
if (get != null) {
|
||||
moveEnergy(energy, get, simulate = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,123 @@
|
||||
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.neoforged.neoforge.capabilities.Capabilities
|
||||
import net.neoforged.neoforge.energy.IEnergyStorage
|
||||
import ru.dbotthepony.kommons.collect.flatMap
|
||||
import ru.dbotthepony.kommons.collect.map
|
||||
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||
import ru.dbotthepony.mc.otm.capability.energy.CombinedProfiledEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.capability.moveEnergy
|
||||
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
||||
import ru.dbotthepony.mc.otm.core.multiblock.BlockEntityTag
|
||||
import ru.dbotthepony.mc.otm.core.multiblock.IMultiblockAccess
|
||||
import ru.dbotthepony.mc.otm.core.multiblock.IMultiblockListener
|
||||
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
||||
|
||||
class EnergyInterfaceBlockEntity(
|
||||
val isInput: Boolean,
|
||||
type: BlockEntityType<*>,
|
||||
blockPos: BlockPos,
|
||||
blockState: BlockState
|
||||
) : MatteryDeviceBlockEntity(type, blockPos, blockState), IMultiblockListener {
|
||||
interface Target {
|
||||
val energyInterfaceTarget: ProfiledEnergyStorage<*>
|
||||
}
|
||||
|
||||
private val multiblocks = LinkedHashSet<IMultiblockAccess>()
|
||||
|
||||
val energy = CombinedProfiledEnergyStorage(
|
||||
FlowDirection.input(isInput),
|
||||
{ multiblocks.iterator().flatMap { it.blockEntities(TARGET).iterator() }.map { it.energyInterfaceTarget } },
|
||||
{ level?.random }
|
||||
)
|
||||
|
||||
override fun onAddedToMultiblock(multiblock: IMultiblockAccess) {
|
||||
check(multiblocks.add(multiblock)) { "$this already tracks $multiblock" }
|
||||
}
|
||||
|
||||
override fun onRemovedFromMultiblock(multiblock: IMultiblockAccess) {
|
||||
check(multiblocks.remove(multiblock)) { "$this does not track $multiblock" }
|
||||
}
|
||||
|
||||
val container = object : MatteryContainer(::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)
|
||||
private val neighbours = ArrayList<CapabilityCache<IEnergyStorage>>()
|
||||
|
||||
init {
|
||||
savetables.stateful(::container, BATTERY_KEY)
|
||||
|
||||
// it would cause a lot of frustration if hatches accept stuff only though one face
|
||||
exposeEnergyGlobally(energy)
|
||||
exposeGlobally(Capabilities.ItemHandler.BLOCK, itemHandler)
|
||||
|
||||
if (!isInput) {
|
||||
for (side in RelativeSide.entries) {
|
||||
neighbours.add(CapabilityCache(side, Capabilities.EnergyStorage.BLOCK))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
energy.tick()
|
||||
|
||||
if (!redstoneControl.isBlockedByRedstone) {
|
||||
container.forEach {
|
||||
it.getCapability(Capabilities.EnergyStorage.ITEM)?.let {
|
||||
if (isInput) {
|
||||
moveEnergy(it, energy, simulate = false)
|
||||
} else {
|
||||
moveEnergy(energy, it, simulate = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isInput) {
|
||||
neighbours.forEach {
|
||||
val get = it.get()
|
||||
|
||||
if (get != null) {
|
||||
moveEnergy(energy, get, simulate = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? {
|
||||
return null
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val CAPACITY = 1
|
||||
|
||||
val TARGET = BlockEntityTag(Target::class)
|
||||
|
||||
val INPUT_TAG = BlockEntityTag(EnergyInterfaceBlockEntity::class) { it.isInput }
|
||||
val OUTPUT_TAG = BlockEntityTag(EnergyInterfaceBlockEntity::class) { !it.isInput }
|
||||
|
||||
fun input(blockPos: BlockPos, blockState: BlockState): EnergyInterfaceBlockEntity {
|
||||
return EnergyInterfaceBlockEntity(true, MBlockEntities.ENERGY_INPUT_INTERFACE, blockPos, blockState)
|
||||
}
|
||||
|
||||
fun output(blockPos: BlockPos, blockState: BlockState): EnergyInterfaceBlockEntity {
|
||||
return EnergyInterfaceBlockEntity(false, MBlockEntities.ENERGY_OUTPUT_INTERFACE, blockPos, blockState)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,229 @@
|
||||
package ru.dbotthepony.mc.otm.block.entity.tech
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Vec3i
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.core.getBlockStateNow
|
||||
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.multiblock.ShapedMultiblock
|
||||
import ru.dbotthepony.mc.otm.core.multiblock.ShapedMultiblockFactory
|
||||
import ru.dbotthepony.mc.otm.core.multiblock.Strategy
|
||||
import ru.dbotthepony.mc.otm.core.multiblock.shapedMultiblock
|
||||
import ru.dbotthepony.mc.otm.data.FlywheelMaterials
|
||||
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
||||
import ru.dbotthepony.mc.otm.registry.game.MBlocks
|
||||
|
||||
class FlywheelBatteryBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryBlockEntity(MBlockEntities.FLYWHEEL_BATTERY, blockPos, blockState), EnergyInterfaceBlockEntity.Target {
|
||||
private var multiblock: ShapedMultiblock? = null
|
||||
private var lastHeight = -1
|
||||
var batteryLevel = Decimal.ZERO
|
||||
private var cachedChargeEfficiency = Decimal.ONE
|
||||
|
||||
private inner class Storage : IMatteryEnergyStorage {
|
||||
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||
if (batteryLevel <= Decimal.ZERO) {
|
||||
return Decimal.ZERO
|
||||
}
|
||||
|
||||
val new = maxOf(batteryLevel - howMuch, Decimal.ZERO)
|
||||
val diff = batteryLevel - new
|
||||
|
||||
if (!simulate)
|
||||
batteryLevel = new
|
||||
|
||||
return diff
|
||||
}
|
||||
|
||||
override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||
if (batteryLevel >= maxBatteryLevel) {
|
||||
return Decimal.ZERO
|
||||
}
|
||||
|
||||
val new = minOf(batteryLevel + howMuch * cachedChargeEfficiency, maxBatteryLevel)
|
||||
val diff = new - batteryLevel
|
||||
|
||||
if (!simulate)
|
||||
batteryLevel = new
|
||||
|
||||
return diff
|
||||
}
|
||||
|
||||
override var batteryLevel: Decimal by this@FlywheelBatteryBlockEntity::batteryLevel
|
||||
override var maxBatteryLevel: Decimal = Decimal.ZERO
|
||||
override val energyFlow: FlowDirection
|
||||
get() = FlowDirection.BI_DIRECTIONAL
|
||||
|
||||
override val canSetBatteryLevel: Boolean
|
||||
get() = true
|
||||
}
|
||||
|
||||
private val energy = ProfiledEnergyStorage(Storage())
|
||||
|
||||
override val energyInterfaceTarget: ProfiledEnergyStorage<*>
|
||||
get() = energy
|
||||
|
||||
init {
|
||||
savetables.stateful(::energy, "energy")
|
||||
savetablesLevel.decimal(::batteryLevel, "battery")
|
||||
|
||||
exposeEnergySideless(energy)
|
||||
}
|
||||
|
||||
override fun setRemoved() {
|
||||
super.setRemoved()
|
||||
|
||||
lastHeight = -1
|
||||
multiblock?.close()
|
||||
multiblock = null
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
|
||||
val level = level!!
|
||||
|
||||
if (multiblock == null || !multiblock!!.update(level, blockRotation.front)) {
|
||||
var height = 0
|
||||
val base = blockPos + blockRotation.back.normal * 2
|
||||
|
||||
while (level.getBlockStateNow(base.atY(blockPos.y + height)).block == MBlocks.FLYWHEEL_SHAFT) {
|
||||
height++
|
||||
}
|
||||
|
||||
if (height <= 1) {
|
||||
lastHeight = 0
|
||||
multiblock?.close()
|
||||
multiblock = null
|
||||
} else if (multiblock == null || lastHeight != height) {
|
||||
lastHeight = height
|
||||
multiblock?.close()
|
||||
multiblock = getConfiguration(height).create(blockPos)
|
||||
}
|
||||
}
|
||||
|
||||
if (multiblock?.isValid == true) {
|
||||
// energy.parent.batteryLevel *= Decimal("0.99994")
|
||||
// this way energy loss is recorded in graph
|
||||
val entry = multiblock!!.blocks(FLYWHEEL_MATERIAL).reference2IntEntrySet().first()
|
||||
val material = FlywheelMaterials[entry.key]!!
|
||||
energy.parent.maxBatteryLevel = material.storage * entry.intValue
|
||||
cachedChargeEfficiency = material.receiveEfficiency
|
||||
energy.extractEnergy(energy.parent.batteryLevel * Decimal("0.000004") * material.momentumLossSpeed, false)
|
||||
} else {
|
||||
energy.parent.maxBatteryLevel = Decimal.ZERO
|
||||
energy.extractEnergy(energy.parent.batteryLevel * Decimal("0.0004"), false)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val FLYWHEEL_MATERIAL = Any()
|
||||
private val outerRing = listOf(
|
||||
// front
|
||||
BlockPos(-1, 0, 0),
|
||||
BlockPos(-2, 0, 0),
|
||||
BlockPos( 0, 0, 0),
|
||||
BlockPos( 1, 0, 0),
|
||||
BlockPos( 2, 0, 0),
|
||||
|
||||
// back
|
||||
BlockPos(-1, 0, 4),
|
||||
BlockPos(-2, 0, 4),
|
||||
BlockPos( 0, 0, 4),
|
||||
BlockPos( 1, 0, 4),
|
||||
BlockPos( 2, 0, 4),
|
||||
|
||||
// right side
|
||||
BlockPos(-2, 0, 1),
|
||||
BlockPos(-2, 0, 2),
|
||||
BlockPos(-2, 0, 3),
|
||||
|
||||
// left side
|
||||
BlockPos( 2, 0, 1),
|
||||
BlockPos( 2, 0, 2),
|
||||
BlockPos( 2, 0, 3),
|
||||
)
|
||||
|
||||
private val configCache = Int2ObjectOpenHashMap<ShapedMultiblockFactory>()
|
||||
|
||||
private fun getConfiguration(height: Int): ShapedMultiblockFactory {
|
||||
return configCache.computeIfAbsent(height, Int2ObjectFunction { createConfiguration(it) })
|
||||
}
|
||||
|
||||
private fun createConfiguration(height: Int): ShapedMultiblockFactory {
|
||||
return shapedMultiblock {
|
||||
strategy = Strategy.AND
|
||||
block(MBlocks.FLYWHEEL_BATTERY)
|
||||
tag(EnergyInterfaceBlockEntity.TARGET)
|
||||
|
||||
builder.customCheck {
|
||||
it.blocks(FLYWHEEL_MATERIAL).size == 1
|
||||
}
|
||||
|
||||
for (x in -2 .. 2) {
|
||||
for (z in 0 .. 4) {
|
||||
relative(Vec3i(x, -1, z)) {
|
||||
if (x == 0 && z == 2) {
|
||||
block(MBlocks.FLYWHEEL_BEARING)
|
||||
} else {
|
||||
block(MBlocks.FLYWHEEL_HOUSING)
|
||||
}
|
||||
}
|
||||
|
||||
relative(Vec3i(x, height, z)) {
|
||||
if (x == 0 && z == 2) {
|
||||
block(MBlocks.FLYWHEEL_BEARING)
|
||||
} else {
|
||||
block(MBlocks.FLYWHEEL_HOUSING)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (y in 0 until height) {
|
||||
for (x in -1 .. 1) {
|
||||
for (z in 1 .. 3) {
|
||||
relative(Vec3i(x, y, z)) {
|
||||
if (z == 2 && x == 0) {
|
||||
block(MBlocks.FLYWHEEL_SHAFT)
|
||||
} else {
|
||||
if (y == height - 1) {
|
||||
block(MBlocks.GENERATOR_BLOCK)
|
||||
} else {
|
||||
predicate { pos, access, blockState, blockEntity ->
|
||||
blockState in FlywheelMaterials
|
||||
}
|
||||
|
||||
tagBlock(FLYWHEEL_MATERIAL)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (rPos in outerRing) {
|
||||
if (y == 0 && rPos.x == 0) continue
|
||||
|
||||
relative(rPos.atY(y)) {
|
||||
block(MBlocks.FLYWHEEL_HOUSING)
|
||||
|
||||
if (y == height - 1) {
|
||||
block(MBlocks.ENERGY_INPUT_INTERFACE)
|
||||
block(MBlocks.ENERGY_OUTPUT_INTERFACE)
|
||||
tag(EnergyInterfaceBlockEntity.INPUT_TAG)
|
||||
tag(EnergyInterfaceBlockEntity.OUTPUT_TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package ru.dbotthepony.mc.otm.block.tech
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
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 ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||
import ru.dbotthepony.mc.otm.block.addSimpleDescription
|
||||
import ru.dbotthepony.mc.otm.block.entity.tech.FlywheelBatteryBlockEntity
|
||||
|
||||
class FlywheelBatteryBlock : RotatableMatteryBlock(), EntityBlock {
|
||||
init {
|
||||
addSimpleDescription()
|
||||
|
||||
for (i in 2 .. 7)
|
||||
addSimpleDescription(i.toString())
|
||||
}
|
||||
|
||||
override fun newBlockEntity(pos: BlockPos, state: BlockState): BlockEntity {
|
||||
return FlywheelBatteryBlockEntity(pos, state)
|
||||
}
|
||||
|
||||
override fun <T : BlockEntity?> getTicker(
|
||||
level: Level,
|
||||
p_153213_: BlockState,
|
||||
p_153214_: BlockEntityType<T>
|
||||
): BlockEntityTicker<T>? {
|
||||
if (level.isClientSide)
|
||||
return null
|
||||
|
||||
return BlockEntityTicker { _, _, _, t -> if (t is FlywheelBatteryBlockEntity) t.tick() }
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import com.google.common.collect.Streams
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
@ -45,7 +46,7 @@ private val LOGGER = LogManager.getLogger()
|
||||
val Player.matteryPlayer: MatteryPlayer get() = (this as IMatteryPlayer).otmPlayer
|
||||
val LivingEntity.matteryPlayer: MatteryPlayer? get() = (this as? IMatteryPlayer)?.otmPlayer
|
||||
|
||||
fun <T> Supplier<out Iterator<T>>.iterateProviders(random: RandomGenerator?, value: Decimal, simulate: Boolean, walker: T.(Decimal, Boolean) -> Decimal): Decimal {
|
||||
fun <T> Supplier<out Iterator<T>>.iterateProviders(random: RandomSource?, value: Decimal, simulate: Boolean, walker: T.(Decimal, Boolean) -> Decimal): Decimal {
|
||||
val providers = get()
|
||||
val iteratorProvider: () -> Iterator<T>
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.capability.energy
|
||||
|
||||
import net.minecraft.util.RandomSource
|
||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||
import ru.dbotthepony.mc.otm.capability.iterateProviders
|
||||
import ru.dbotthepony.mc.otm.core.collect.map
|
||||
@ -11,7 +12,7 @@ import java.util.random.RandomGenerator
|
||||
open class CombinedEnergyStorage(
|
||||
final override val energyFlow: FlowDirection,
|
||||
val provider: Supplier<out Iterator<IMatteryEnergyStorage>>,
|
||||
val random: Supplier<RandomGenerator?> = Supplier { null }
|
||||
val random: Supplier<RandomSource?> = Supplier { null }
|
||||
) : IMatteryEnergyStorage {
|
||||
final override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||
return provider.iterateProviders(random.get(), howMuch, simulate, IMatteryEnergyStorage::extractEnergy)
|
||||
|
@ -1,5 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.capability.energy
|
||||
|
||||
import net.minecraft.util.RandomSource
|
||||
import ru.dbotthepony.mc.otm.capability.AbstractProfiledStorage
|
||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||
import ru.dbotthepony.mc.otm.capability.IProfiledStorage
|
||||
@ -14,7 +15,7 @@ import java.util.random.RandomGenerator
|
||||
class CombinedProfiledEnergyStorage(
|
||||
energyFlow: FlowDirection,
|
||||
provider: Supplier<out Iterator<ProfiledEnergyStorage<*>>>,
|
||||
random: Supplier<RandomGenerator?> = Supplier { null }
|
||||
random: Supplier<RandomSource?> = Supplier { null }
|
||||
) : CombinedEnergyStorage(energyFlow, provider, random), IProfiledMatteryEnergyStorage, IProfiledStorage.Combined, ITickable {
|
||||
override val received = CombinedDecimalHistoryChart(Supplier { this.provider.get().map { (it as ProfiledEnergyStorage<*>).received } }, ticks = AbstractProfiledStorage.HISTORY_SIZE)
|
||||
override val transferred = CombinedDecimalHistoryChart(Supplier { this.provider.get().map { (it as ProfiledEnergyStorage<*>).transferred } }, ticks = AbstractProfiledStorage.HISTORY_SIZE)
|
||||
|
@ -1,5 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.capability.matter
|
||||
|
||||
import net.minecraft.util.RandomSource
|
||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||
import ru.dbotthepony.mc.otm.capability.iterateProviders
|
||||
import ru.dbotthepony.mc.otm.core.collect.map
|
||||
@ -11,7 +12,7 @@ import java.util.random.RandomGenerator
|
||||
open class CombinedMatterStorage(
|
||||
final override val matterFlow: FlowDirection,
|
||||
val provider: Supplier<out Iterator<IMatterStorage>>,
|
||||
val random: Supplier<RandomGenerator?> = Supplier { null }
|
||||
val random: Supplier<RandomSource?> = Supplier { null }
|
||||
) : IMatterStorage {
|
||||
final override var storedMatter: Decimal
|
||||
get() = provider.get().map { it.storedMatter }.reduce(Decimal.ZERO, Decimal::plus)
|
||||
|
@ -1,5 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.capability.matter
|
||||
|
||||
import net.minecraft.util.RandomSource
|
||||
import ru.dbotthepony.mc.otm.capability.AbstractProfiledStorage
|
||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||
import ru.dbotthepony.mc.otm.capability.IProfiledStorage
|
||||
@ -14,7 +15,7 @@ import java.util.random.RandomGenerator
|
||||
class CombinedProfiledMatterStorage(
|
||||
matterFlow: FlowDirection,
|
||||
provider: Supplier<out Iterator<ProfiledMatterStorage<*>>>,
|
||||
random: Supplier<RandomGenerator?> = Supplier { null }
|
||||
random: Supplier<RandomSource?> = Supplier { null }
|
||||
) : CombinedMatterStorage(matterFlow, provider, random), IProfiledMatterStorage, IProfiledStorage.Combined, ITickable {
|
||||
override val received = CombinedDecimalHistoryChart(Supplier { this.provider.get().map { (it as ProfiledMatterStorage<*>).received } }, ticks = AbstractProfiledStorage.HISTORY_SIZE)
|
||||
override val transferred = CombinedDecimalHistoryChart(Supplier { this.provider.get().map { (it as ProfiledMatterStorage<*>).transferred } }, ticks = AbstractProfiledStorage.HISTORY_SIZE)
|
||||
|
@ -4,7 +4,7 @@ import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import java.util.Collections
|
||||
|
||||
class BlockEntitySet<T : BlockEntity>(private val listener: GlobalBlockEntityRemovalListener, val tag: BlockEntityTag<T>) {
|
||||
class BlockEntitySet<T : Any>(private val listener: GlobalBlockEntityRemovalListener, val tag: BlockEntityTag<T>) {
|
||||
private val items = Reference2IntOpenHashMap<T>()
|
||||
val set: Set<T> = Collections.unmodifiableSet(items.keys)
|
||||
|
||||
@ -38,7 +38,7 @@ class BlockEntitySet<T : BlockEntity>(private val listener: GlobalBlockEntityRem
|
||||
|
||||
fun clear() {
|
||||
items.keys.forEach {
|
||||
GlobalBlockEntityRemovalListener.stopListening(it, listener)
|
||||
GlobalBlockEntityRemovalListener.stopListening(it as BlockEntity, listener)
|
||||
}
|
||||
|
||||
items.clear()
|
||||
|
@ -13,9 +13,8 @@ inline fun <reified T : BlockEntity> multiblockEntity(): BlockEntityTag<T> {
|
||||
*
|
||||
* Optionally, can have [predicate] specified, which narrows which block entities can be accepted by this tag
|
||||
*/
|
||||
class BlockEntityTag<T : BlockEntity>(val clazz: KClass<T>, val predicate: Predicate<in T> = Predicate { true }) :
|
||||
Predicate<BlockEntity> {
|
||||
override fun test(t: BlockEntity): Boolean {
|
||||
class BlockEntityTag<T : Any>(val clazz: KClass<T>, val predicate: Predicate<in T> = Predicate { true }) : Predicate<Any?> {
|
||||
override fun test(t: Any?): Boolean {
|
||||
return clazz.isInstance(t) && predicate.test(t as T)
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ interface IMultiblockAccess {
|
||||
return blockStates(GLOBAL_BLOCK_TAG)
|
||||
}
|
||||
|
||||
fun <T : BlockEntity> blockEntities(tag: BlockEntityTag<T>): Set<T>
|
||||
fun <T : Any> blockEntities(tag: BlockEntityTag<T>): Set<T>
|
||||
|
||||
companion object {
|
||||
val GLOBAL_BLOCK_TAG = Any()
|
||||
|
@ -0,0 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.core.multiblock
|
||||
|
||||
interface IMultiblockListener {
|
||||
fun onAddedToMultiblock(multiblock: IMultiblockAccess)
|
||||
fun onRemovedFromMultiblock(multiblock: IMultiblockAccess)
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package ru.dbotthepony.mc.otm.core.multiblock
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
|
||||
|
||||
class MultiblockListenerSet(val parent: IMultiblockAccess) {
|
||||
private val referencedListeners = Object2IntOpenHashMap<IMultiblockListener>()
|
||||
|
||||
fun reference(value: IMultiblockListener) {
|
||||
val i = referencedListeners.computeInt(value, { _, int -> (int ?: 0) + 1 })
|
||||
|
||||
if (i == 1) {
|
||||
value.onAddedToMultiblock(parent)
|
||||
}
|
||||
}
|
||||
|
||||
fun dereference(value: IMultiblockListener) {
|
||||
val i = referencedListeners.computeInt(value, { _, int -> (int ?: 0) - 1 })
|
||||
|
||||
if (i <= 0) {
|
||||
referencedListeners.removeInt(value)
|
||||
value.onRemovedFromMultiblock(parent)
|
||||
}
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
referencedListeners.keys.forEach { it.onRemovedFromMultiblock(parent) }
|
||||
referencedListeners.clear()
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.core.multiblock
|
||||
import com.google.common.collect.ImmutableList
|
||||
import com.google.common.collect.ImmutableMap
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
|
||||
import it.unimi.dsi.fastutil.objects.Reference2IntMap
|
||||
import it.unimi.dsi.fastutil.objects.Reference2IntMaps
|
||||
import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap
|
||||
@ -35,7 +36,7 @@ import kotlin.collections.ArrayList
|
||||
import kotlin.collections.HashMap
|
||||
|
||||
/**
|
||||
* [close] is not required to be explicitly called, but it will help in freeing allocated memory faster
|
||||
* [close] MUST be called when multiblock goes out of scope
|
||||
*/
|
||||
class ShapedMultiblock(pos: BlockPos, factory: ShapedMultiblockFactory) : IMultiblockAccess, ISynchable, Closeable, GlobalBlockEntityRemovalListener {
|
||||
override var isValid: Boolean = false
|
||||
@ -147,10 +148,16 @@ class ShapedMultiblock(pos: BlockPos, factory: ShapedMultiblockFactory) : IMulti
|
||||
|
||||
if (be1 != be2) {
|
||||
if (be1 != null) {
|
||||
if (be1 is IMultiblockListener)
|
||||
referencedListeners.dereference(be1)
|
||||
|
||||
assignedBlockEntityLists.forEach { it.remove(be1) }
|
||||
}
|
||||
|
||||
if (be2 != null) {
|
||||
if (be2 is IMultiblockListener)
|
||||
referencedListeners.reference(be2)
|
||||
|
||||
assignedBlockEntityLists.forEach { it.add(be2) }
|
||||
}
|
||||
|
||||
@ -212,6 +219,9 @@ class ShapedMultiblock(pos: BlockPos, factory: ShapedMultiblockFactory) : IMulti
|
||||
val blockEntity = blockEntity
|
||||
|
||||
if (blockEntity != null) {
|
||||
if (blockEntity is IMultiblockListener)
|
||||
referencedListeners.dereference(blockEntity)
|
||||
|
||||
assignedBlockEntityLists.forEach { it.remove(blockEntity) }
|
||||
}
|
||||
|
||||
@ -241,7 +251,13 @@ class ShapedMultiblock(pos: BlockPos, factory: ShapedMultiblockFactory) : IMulti
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
blockEntity = null
|
||||
val blockEntity = blockEntity
|
||||
|
||||
if (blockEntity != null) {
|
||||
assignedBlockEntityLists.forEach { it.remove(blockEntity) }
|
||||
}
|
||||
|
||||
this.blockEntity = null
|
||||
blockState = null
|
||||
|
||||
lastSuccessfulPathPredicate = -1
|
||||
@ -251,6 +267,8 @@ class ShapedMultiblock(pos: BlockPos, factory: ShapedMultiblockFactory) : IMulti
|
||||
}
|
||||
}
|
||||
|
||||
private val referencedListeners = MultiblockListenerSet(this)
|
||||
|
||||
val index = when (currentDirection) {
|
||||
Direction.NORTH -> 0
|
||||
Direction.SOUTH -> 1
|
||||
@ -284,7 +302,7 @@ class ShapedMultiblock(pos: BlockPos, factory: ShapedMultiblockFactory) : IMulti
|
||||
private val globalBlocksView = tag2BlockViews[IMultiblockAccess.GLOBAL_BLOCK_TAG]!!
|
||||
private val globalBlockStatesView = tag2BlockStateViews[IMultiblockAccess.GLOBAL_BLOCK_TAG]!!
|
||||
|
||||
private fun <T : BlockEntity> getBlockEntityList(tag: BlockEntityTag<T>): BlockEntitySet<T> {
|
||||
private fun <T : Any> getBlockEntityList(tag: BlockEntityTag<T>): BlockEntitySet<T> {
|
||||
val existing = tag2BlockEntity[tag]
|
||||
|
||||
if (existing != null)
|
||||
@ -331,6 +349,7 @@ class ShapedMultiblock(pos: BlockPos, factory: ShapedMultiblockFactory) : IMulti
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
referencedListeners.clear()
|
||||
tag2BlockEntity.values.forEach { it.clear() }
|
||||
tag2BlockState.values.forEach { it.clear() }
|
||||
tag2Block.values.forEach { it.clear() }
|
||||
@ -397,23 +416,28 @@ class ShapedMultiblock(pos: BlockPos, factory: ShapedMultiblockFactory) : IMulti
|
||||
return isValid
|
||||
}
|
||||
|
||||
override fun <T : BlockEntity> blockEntities(tag: BlockEntityTag<T>): Set<T> {
|
||||
override fun <T : Any> blockEntities(tag: BlockEntityTag<T>): Set<T> {
|
||||
checkAccess()
|
||||
return (tag2BlockEntity[tag]?.set ?: setOf()) as Set<T>
|
||||
}
|
||||
|
||||
override fun blocks(tag: Any): Reference2IntMap<Block> {
|
||||
checkAccess()
|
||||
return tag2BlockViews[tag] ?: Reference2IntMaps.emptyMap()
|
||||
}
|
||||
|
||||
override fun blockStates(tag: Any): Reference2IntMap<BlockState> {
|
||||
checkAccess()
|
||||
return tag2BlockStateViews[tag] ?: Reference2IntMaps.emptyMap()
|
||||
}
|
||||
|
||||
override fun blocks(): Reference2IntMap<Block> {
|
||||
checkAccess()
|
||||
return globalBlocksView
|
||||
}
|
||||
|
||||
override fun blockStates(): Reference2IntMap<BlockState> {
|
||||
checkAccess()
|
||||
return globalBlockStatesView
|
||||
}
|
||||
|
||||
@ -491,11 +515,19 @@ class ShapedMultiblock(pos: BlockPos, factory: ShapedMultiblockFactory) : IMulti
|
||||
override fun createRemoteState(listener: Runnable): IRemoteState {
|
||||
return RemoteState(listener)
|
||||
}
|
||||
|
||||
private fun checkAccess() {
|
||||
if (!isUpdating && activeConfig !== this) {
|
||||
throw IllegalStateException("ShapedMultiblock configuration leaked! $this of ${this@ShapedMultiblock}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override var isRemote: Boolean = false
|
||||
private set
|
||||
|
||||
private var isUpdating = false
|
||||
|
||||
override fun read(stream: RegistryFriendlyByteBuf) {
|
||||
isRemote = true
|
||||
isValid = stream.readBoolean()
|
||||
@ -543,7 +575,7 @@ class ShapedMultiblock(pos: BlockPos, factory: ShapedMultiblockFactory) : IMulti
|
||||
override val currentNodes: Map<BlockPos, IMultiblockNode>
|
||||
get() = activeConfig.parts
|
||||
|
||||
override fun <T : BlockEntity> blockEntities(tag: BlockEntityTag<T>): Set<T> {
|
||||
override fun <T : Any> blockEntities(tag: BlockEntityTag<T>): Set<T> {
|
||||
if (!isValid) return setOf()
|
||||
return activeConfig.blockEntities(tag)
|
||||
}
|
||||
@ -573,66 +605,78 @@ class ShapedMultiblock(pos: BlockPos, factory: ShapedMultiblockFactory) : IMulti
|
||||
}
|
||||
|
||||
fun update(levelAccessor: LevelAccessor): Boolean {
|
||||
val configurations = LinkedList<Config>()
|
||||
val configurations0 = ArrayList(this.configurations)
|
||||
isUpdating = true
|
||||
|
||||
while (configurations0.isNotEmpty()) {
|
||||
val max = configurations0.max()
|
||||
configurations0.remove(max)
|
||||
configurations.add(max)
|
||||
}
|
||||
try {
|
||||
val configurations = LinkedList<Config>()
|
||||
val configurations0 = ArrayList(this.configurations)
|
||||
|
||||
isValid = false
|
||||
while (configurations0.isNotEmpty()) {
|
||||
val max = configurations0.max()
|
||||
configurations0.remove(max)
|
||||
configurations.add(max)
|
||||
}
|
||||
|
||||
while (configurations.isNotEmpty()) {
|
||||
val config = configurations.removeFirst()
|
||||
isValid = false
|
||||
|
||||
if (config.update(levelAccessor)) {
|
||||
if (customChecks.all { it.test(config) }) {
|
||||
activeConfig = config
|
||||
isValid = true
|
||||
remotes.forEach { it.listener.run() }
|
||||
return true
|
||||
} else {
|
||||
config.clear()
|
||||
while (configurations.isNotEmpty()) {
|
||||
val config = configurations.removeFirst()
|
||||
|
||||
if (config.update(levelAccessor)) {
|
||||
if (customChecks.all { it.test(config) }) {
|
||||
activeConfig = config
|
||||
isValid = true
|
||||
remotes.forEach { it.listener.run() }
|
||||
return true
|
||||
} else {
|
||||
config.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return false
|
||||
} finally {
|
||||
isUpdating = false
|
||||
}
|
||||
}
|
||||
|
||||
fun update(levelAccessor: LevelAccessor, direction: Direction): Boolean {
|
||||
var changes = false
|
||||
isUpdating = true
|
||||
|
||||
if (activeConfig.currentDirection != direction && isValid) {
|
||||
activeConfig.clear()
|
||||
isValid = false
|
||||
changes = true
|
||||
try {
|
||||
var changes = false
|
||||
|
||||
if (activeConfig.currentDirection != direction && isValid) {
|
||||
activeConfig.clear()
|
||||
isValid = false
|
||||
changes = true
|
||||
}
|
||||
|
||||
val config = when (direction) {
|
||||
Direction.NORTH -> north
|
||||
Direction.SOUTH -> south
|
||||
Direction.WEST -> west
|
||||
Direction.EAST -> east
|
||||
else -> throw IllegalArgumentException(direction.name)
|
||||
}
|
||||
|
||||
changes = changes || activeConfig != config
|
||||
activeConfig = config
|
||||
isValid = config.update(levelAccessor)
|
||||
|
||||
if (isValid) {
|
||||
isValid = customChecks.all { it.test(config) }
|
||||
if (!isValid) config.clear()
|
||||
}
|
||||
|
||||
if (changes) {
|
||||
remotes.forEach { it.listener.run() }
|
||||
}
|
||||
|
||||
return isValid
|
||||
} finally {
|
||||
isUpdating = false
|
||||
}
|
||||
|
||||
val config = when (direction) {
|
||||
Direction.NORTH -> north
|
||||
Direction.SOUTH -> south
|
||||
Direction.WEST -> west
|
||||
Direction.EAST -> east
|
||||
else -> throw IllegalArgumentException(direction.name)
|
||||
}
|
||||
|
||||
changes = changes || activeConfig != config
|
||||
activeConfig = config
|
||||
isValid = config.update(levelAccessor)
|
||||
|
||||
if (isValid) {
|
||||
isValid = customChecks.all { it.test(config) }
|
||||
if (!isValid) config.clear()
|
||||
}
|
||||
|
||||
if (changes) {
|
||||
remotes.forEach { it.listener.run() }
|
||||
}
|
||||
|
||||
return isValid
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
|
@ -56,7 +56,7 @@ class ShapedMultiblockBuilder {
|
||||
/**
|
||||
* Marks this node report its block in [ShapedMultiblock.blockStates] method when called with specified [value]
|
||||
*
|
||||
* [value] is searched using "value" semantics (`==`)
|
||||
* [value] is searched using "value" semantics (`==` / `equals`)
|
||||
*/
|
||||
fun tagBlockState(value: Any): T {
|
||||
blockStateTags.add(value)
|
||||
@ -74,7 +74,7 @@ class ShapedMultiblockBuilder {
|
||||
/**
|
||||
* Marks this node report its block in [ShapedMultiblock.blocks] method when called with specified [value]
|
||||
*
|
||||
* [value] is searched for using "value" semantics (`==`)
|
||||
* [value] is searched for using "value" semantics (`==` / `equals`)
|
||||
*/
|
||||
fun tagBlock(value: Any): T {
|
||||
blockTags.add(value)
|
||||
@ -92,7 +92,7 @@ class ShapedMultiblockBuilder {
|
||||
/**
|
||||
* Marks this node to report block entities put at its position when called [ShapedMultiblock.blockEntities] with specified [value]
|
||||
*
|
||||
* [value] is searched for using "identity" semantics (`===`)
|
||||
* [value] is searched for using "identity" semantics (`===` / Java's `==`)
|
||||
*/
|
||||
fun tag(value: BlockEntityTag<*>): T {
|
||||
blockEntityTags.add(value)
|
||||
|
@ -0,0 +1,109 @@
|
||||
package ru.dbotthepony.mc.otm.data
|
||||
|
||||
import com.google.gson.JsonArray
|
||||
import net.minecraft.data.CachedOutput
|
||||
import net.minecraft.data.DataProvider
|
||||
import net.minecraft.data.PackOutput
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.neoforged.neoforge.data.event.GatherDataEvent
|
||||
import ru.dbotthepony.mc.otm.core.ResourceLocation
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.registryName
|
||||
import ru.dbotthepony.mc.otm.core.toJsonStrict
|
||||
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
||||
import ru.dbotthepony.mc.otm.matter.AbstractRegistryAction
|
||||
import ru.dbotthepony.mc.otm.matter.MatterManager
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
open class FlywheelMaterialDataProvider(val modid: String, val location: String? = null) : DataProvider {
|
||||
private val entries = ArrayList<FlywheelMaterials.Entry>()
|
||||
|
||||
var pathProvider: PackOutput.PathProvider by WriteOnce("You need to call bindPackOutput before registering this data provider")
|
||||
private set
|
||||
|
||||
constructor(output: PackOutput, modid: String, location: String? = null) : this(modid, location) {
|
||||
bindPackOutput(output)
|
||||
}
|
||||
|
||||
constructor(event: GatherDataEvent, location: String? = null) : this(event.generator.packOutput, event.modContainer.namespace, location)
|
||||
|
||||
fun bindPackOutput(output: PackOutput) {
|
||||
pathProvider = output.createPathProvider(PackOutput.Target.DATA_PACK, "otm_flywheel_materials")
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun add(block: Block, storage: Decimal, priority: Int = 0) {
|
||||
entries.add(FlywheelMaterials.Entry(block, storage, priority))
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun add(block: TagKey<Block>, storage: Decimal, priority: Int = 0) {
|
||||
entries.add(FlywheelMaterials.Entry(block, storage, priority))
|
||||
}
|
||||
|
||||
@JvmName("addBlocks")
|
||||
@JvmOverloads
|
||||
fun add(blocks: Collection<Block>, storage: Decimal, priority: Int = 0) {
|
||||
for (block in blocks)
|
||||
entries.add(FlywheelMaterials.Entry(block, storage, priority))
|
||||
}
|
||||
|
||||
@JvmName("addBlocks")
|
||||
@JvmOverloads
|
||||
fun add(blocks: Array<out Block>, storage: Decimal, priority: Int = 0) {
|
||||
for (block in blocks)
|
||||
entries.add(FlywheelMaterials.Entry(block, storage, priority))
|
||||
}
|
||||
|
||||
@JvmName("addTags")
|
||||
@JvmOverloads
|
||||
fun add(blocks: Array<out TagKey<Block>>, storage: Decimal, priority: Int = 0) {
|
||||
for (block in blocks)
|
||||
entries.add(FlywheelMaterials.Entry(block, storage, priority))
|
||||
}
|
||||
|
||||
@JvmName("addBlocks")
|
||||
fun add(storage: Decimal, vararg blocks: Block) {
|
||||
return add(blocks, storage)
|
||||
}
|
||||
|
||||
@JvmName("addBlocks")
|
||||
fun add(storage: Decimal, priority: Int, vararg blocks: Block) {
|
||||
return add(blocks, storage, priority)
|
||||
}
|
||||
|
||||
@JvmName("addTags")
|
||||
fun add(storage: Decimal, vararg blocks: TagKey<Block>) {
|
||||
return add(blocks, storage)
|
||||
}
|
||||
|
||||
@JvmName("addTags")
|
||||
fun add(storage: Decimal, priority: Int, vararg blocks: TagKey<Block>) {
|
||||
return add(blocks, storage, priority)
|
||||
}
|
||||
|
||||
override fun run(output: CachedOutput): CompletableFuture<*> {
|
||||
if (location == null) {
|
||||
val futures = ArrayList<CompletableFuture<*>>()
|
||||
|
||||
for (entry in entries) {
|
||||
val path = ResourceLocation(modid, entry.id.map({ "tag/${it.location.namespace}/${it.location.path}" }, { "block/${it.registryName!!.namespace}/${it.registryName!!.path}" }))
|
||||
futures.add(DataProvider.saveStable(output, FlywheelMaterials.CODEC.toJsonStrict(entry), pathProvider.json(path)))
|
||||
}
|
||||
|
||||
return CompletableFuture.allOf(*futures.toTypedArray())
|
||||
} else {
|
||||
val result = JsonArray()
|
||||
|
||||
for (entry in entries)
|
||||
result.add(FlywheelMaterials.CODEC.toJsonStrict(entry))
|
||||
|
||||
return DataProvider.saveStable(output, result, pathProvider.json(ResourceLocation(modid, location)))
|
||||
}
|
||||
}
|
||||
|
||||
override fun getName(): String {
|
||||
return "Flywheel Materials for $modid"
|
||||
}
|
||||
}
|
153
src/main/kotlin/ru/dbotthepony/mc/otm/data/FlywheelMaterials.kt
Normal file
153
src/main/kotlin/ru/dbotthepony/mc/otm/data/FlywheelMaterials.kt
Normal file
@ -0,0 +1,153 @@
|
||||
package ru.dbotthepony.mc.otm.data
|
||||
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import com.mojang.datafixers.util.Either
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.JsonOps
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.packs.resources.ResourceManager
|
||||
import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.util.profiling.ProfilerFiller
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.neoforged.neoforge.event.AddReloadListenerEvent
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.registryName
|
||||
import ru.dbotthepony.mc.otm.data.codec.DecimalCodec
|
||||
import ru.dbotthepony.mc.otm.data.codec.minRange
|
||||
|
||||
object FlywheelMaterials : SimpleJsonResourceReloadListener(GsonBuilder().setPrettyPrinting().create(), "otm_flywheel_materials") {
|
||||
data class Entry(
|
||||
val id: Either<TagKey<Block>, Block>,
|
||||
val storage: Decimal,
|
||||
val priority: Int = 0,
|
||||
val receiveEfficiency: Decimal = Decimal.ONE,
|
||||
val momentumLossSpeed: Decimal = Decimal.ONE
|
||||
) : Comparable<Entry> {
|
||||
constructor(id: Block, storage: Decimal, priority: Int = 0, windUpEfficiency: Decimal = Decimal.ONE, windDownEfficiency: Decimal = Decimal.ONE) : this(Either.right(id), storage, priority, windUpEfficiency, windDownEfficiency)
|
||||
constructor(id: TagKey<Block>, storage: Decimal, priority: Int = 0, windUpEfficiency: Decimal = Decimal.ONE, windDownEfficiency: Decimal = Decimal.ONE) : this(Either.left(id), storage, priority, windUpEfficiency, windDownEfficiency)
|
||||
|
||||
override fun compareTo(other: Entry): Int {
|
||||
val selfLeft = id.left().isPresent
|
||||
val otherLeft = other.id.left().isPresent
|
||||
|
||||
if (selfLeft && otherLeft || !selfLeft && !otherLeft) {
|
||||
val cmp = priority.compareTo(other.priority)
|
||||
|
||||
if (cmp == 0) {
|
||||
if (selfLeft) {
|
||||
return id.left().get().location.compareTo(other.id.left().get().location)
|
||||
} else {
|
||||
return id.right().get().registryName!!.compareTo(other.id.right().get().registryName!!)
|
||||
}
|
||||
}
|
||||
|
||||
return cmp
|
||||
} else if (selfLeft) {
|
||||
return -1
|
||||
} else {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var elements = ArrayList<Entry>()
|
||||
private var mapped = HashMap<Block, Entry>()
|
||||
private var mappingChanged = false
|
||||
|
||||
private fun mapping(): Map<Block, Entry> {
|
||||
var mapped = mapped
|
||||
|
||||
if (mappingChanged) {
|
||||
mapped = HashMap()
|
||||
|
||||
for (element in elements) {
|
||||
element.id
|
||||
.ifLeft {
|
||||
for (b in BuiltInRegistries.BLOCK.getTagOrEmpty(it)) {
|
||||
mapped[b.value()] = element
|
||||
}
|
||||
}
|
||||
.ifRight {
|
||||
mapped[it] = element
|
||||
}
|
||||
}
|
||||
|
||||
this.mapped = mapped
|
||||
this.mappingChanged = false
|
||||
return mapped
|
||||
}
|
||||
|
||||
return mapped
|
||||
}
|
||||
|
||||
operator fun get(index: Block): Entry? {
|
||||
return mapping()[index]
|
||||
}
|
||||
|
||||
operator fun get(index: BlockState): Entry? {
|
||||
return this[index.block]
|
||||
}
|
||||
|
||||
operator fun contains(value: Block): Boolean {
|
||||
return value in mapping()
|
||||
}
|
||||
|
||||
operator fun contains(value: BlockState): Boolean {
|
||||
return value.block in mapping()
|
||||
}
|
||||
|
||||
override fun apply(
|
||||
map: MutableMap<ResourceLocation, JsonElement>,
|
||||
manager: ResourceManager,
|
||||
profiler: ProfilerFiller
|
||||
) {
|
||||
val elements = ArrayList<Entry>()
|
||||
|
||||
for ((path, element) in map.entries) {
|
||||
if (element is JsonObject) {
|
||||
CODEC.decode(JsonOps.INSTANCE, element)
|
||||
.ifError { LOGGER.error("Unable to deserialize flywheel material entry at $path: $it") }
|
||||
.ifSuccess { elements.add(it.first) }
|
||||
} else if (element is JsonArray) {
|
||||
for ((i, elem) in element.withIndex()) {
|
||||
CODEC.decode(JsonOps.INSTANCE, elem)
|
||||
.ifError { LOGGER.error("Unable to deserialize flywheel material entry at $path, offset $i: $it") }
|
||||
.ifSuccess { elements.add(it.first) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elements.sortDescending()
|
||||
|
||||
this.elements = elements
|
||||
this.mappingChanged = true
|
||||
}
|
||||
|
||||
val CODEC: Codec<Entry> = RecordCodecBuilder.create {
|
||||
it.group(
|
||||
Codec.either(
|
||||
TagKey.hashedCodec(Registries.BLOCK),
|
||||
BuiltInRegistries.BLOCK.byNameCodec()
|
||||
).fieldOf("id").forGetter(Entry::id),
|
||||
DecimalCodec.minRange(Decimal.ONE).fieldOf("storage").forGetter(Entry::storage),
|
||||
Codec.INT.optionalFieldOf("priority", 0).forGetter(Entry::priority),
|
||||
DecimalCodec.minRange(Decimal.ZERO).optionalFieldOf("receive_efficiency", Decimal.ONE).forGetter(Entry::receiveEfficiency),
|
||||
DecimalCodec.minRange(Decimal.ZERO).optionalFieldOf("momentum_loss_speed", Decimal.ONE).forGetter(Entry::momentumLossSpeed),
|
||||
).apply(it, ::Entry)
|
||||
}
|
||||
|
||||
fun reloadEvent(event: AddReloadListenerEvent) {
|
||||
event.addListener(this)
|
||||
}
|
||||
|
||||
private val LOGGER = LogManager.getLogger()
|
||||
}
|
@ -1247,19 +1247,10 @@ open class MatterDataProvider(val modid: String? = null) : DataProvider {
|
||||
@JvmOverloads
|
||||
fun insert(name: TagKey<Item>, matterValue: Decimal, complexity: Double, priority: Int, configurator: Consumer<InsertConfiguration> = Consumer { }) = insert(name, matterValue, complexity, priority, configurator::accept)
|
||||
|
||||
/**
|
||||
* Override this if you prefer The Mundane Way™ instead of calling [insert], [delete] and [update] directly
|
||||
*
|
||||
* Called inside [run]
|
||||
*/
|
||||
protected open fun addActions() {}
|
||||
|
||||
protected val added = ArrayList<AbstractRegistryAction>()
|
||||
val addedView: List<AbstractRegistryAction> = Collections.unmodifiableList(added)
|
||||
|
||||
final override fun run(output: CachedOutput): CompletableFuture<*> {
|
||||
addActions()
|
||||
|
||||
override fun run(output: CachedOutput): CompletableFuture<*> {
|
||||
val promises = ArrayList<CompletableFuture<*>>()
|
||||
|
||||
for ((key, value) in actions) {
|
||||
|
@ -17,6 +17,8 @@ object MBlockTags {
|
||||
|
||||
val REQUIRES_TRITANIUM_TOOL: TagKey<Block> = BlockTags.create(ResourceLocation("minecraft", "requires_tritanium_tool"))
|
||||
|
||||
val TRITANIUM_BLOCKS: TagKey<Block> = BlockTags.create(ResourceLocation("c", "storage_blocks/tritanium"))
|
||||
|
||||
val DILITHIUM_ORES: TagKey<Block> = BlockTags.create(ResourceLocation("c", "ores/dilithium"))
|
||||
|
||||
val HARDENED_GLASS_PANES: TagKey<Block> = BlockTags.create(ResourceLocation("c", "hardened_glass_panes"))
|
||||
@ -57,7 +59,6 @@ object MBlockTags {
|
||||
val HARDENED_GLASS_WHITE: TagKey<Block> = BlockTags.create(ResourceLocation("c", "hardened_glass/white"))
|
||||
val HARDENED_GLASS_YELLOW: TagKey<Block> = BlockTags.create(ResourceLocation("c", "hardened_glass/yellow"))
|
||||
|
||||
val MACHINES: TagKey<Block> = BlockTags.create(ResourceLocation(OverdriveThatMatters.MOD_ID, "machines"))
|
||||
val MULTIBLOCK_STRUCTURE: TagKey<Block> = BlockTags.create(ResourceLocation(OverdriveThatMatters.MOD_ID, "multiblock_structure"))
|
||||
val MULTIBLOCK_HARD_STRUCTURE: TagKey<Block> = BlockTags.create(ResourceLocation(OverdriveThatMatters.MOD_ID, "multiblock_hard_structure"))
|
||||
val MULTIBLOCK_SOFT_STRUCTURE: TagKey<Block> = BlockTags.create(ResourceLocation(OverdriveThatMatters.MOD_ID, "multiblock_soft_structure"))
|
||||
|
@ -83,8 +83,6 @@ object MItemTags {
|
||||
val HARDENED_GLASS_WHITE: TagKey<Item> = ItemTags.create(ResourceLocation("c", "hardened_glass/white"))
|
||||
val HARDENED_GLASS_YELLOW: TagKey<Item> = ItemTags.create(ResourceLocation("c", "hardened_glass/yellow"))
|
||||
|
||||
val MACHINES: TagKey<Item> = ItemTags.create(modLoc("machines"))
|
||||
|
||||
val NO_DECOMPOSING: TagKey<Item> = ItemTags.create(modLoc("matter/no_decomposing"))
|
||||
val NO_REPLICATION: TagKey<Item> = ItemTags.create(modLoc("matter/no_replication"))
|
||||
val NO_REPAIR: TagKey<Item> = ItemTags.create(modLoc("matter/no_repair"))
|
||||
|
@ -23,6 +23,8 @@ object MNames {
|
||||
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 ENERGY_INPUT_INTERFACE = "energy_input_interface"
|
||||
const val ENERGY_OUTPUT_INTERFACE = "energy_output_interface"
|
||||
const val MATTER_INPUT_HATCH = "matter_input_hatch"
|
||||
const val MATTER_OUTPUT_HATCH = "matter_output_hatch"
|
||||
const val PAINTER = "painter"
|
||||
@ -56,6 +58,12 @@ object MNames {
|
||||
const val ESSENCE_STORAGE = "essence_storage"
|
||||
const val TRITANIUM_ANVIL = "tritanium_anvil"
|
||||
|
||||
const val FLYWHEEL_BATTERY = "flywheel_battery"
|
||||
const val FLYWHEEL_BEARING = "flywheel_bearing"
|
||||
const val FLYWHEEL_SHAFT = "flywheel_shaft"
|
||||
const val FLYWHEEL_HOUSING = "flywheel_housing"
|
||||
const val GENERATOR_BLOCK = "generator_block"
|
||||
|
||||
const val STORAGE_CABLE = "storage_cable" // нужен рецепт
|
||||
const val STORAGE_POWER_SUPPLIER = "storage_power_supplier" // нужен рецепт
|
||||
const val GRILL = "grill"
|
||||
|
@ -92,11 +92,15 @@ object MBlockEntities {
|
||||
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 ENERGY_INPUT_INTERFACE by register(MNames.ENERGY_INPUT_INTERFACE, EnergyInterfaceBlockEntity::input, MBlocks::ENERGY_INPUT_INTERFACE)
|
||||
val ENERGY_OUTPUT_INTERFACE by register(MNames.ENERGY_OUTPUT_INTERFACE, EnergyInterfaceBlockEntity::output, MBlocks::ENERGY_OUTPUT_INTERFACE)
|
||||
|
||||
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)
|
||||
val POWERED_SMOKER by register(MNames.POWERED_SMOKER, ::PoweredSmokerBlockEntity, MBlocks.POWERED_SMOKER)
|
||||
|
||||
val FLYWHEEL_BATTERY by register(MNames.FLYWHEEL_BATTERY, ::FlywheelBatteryBlockEntity, MBlocks::FLYWHEEL_BATTERY)
|
||||
|
||||
val MULTIBLOCK_TEST by register("multiblock_test", ::MultiblockTestBlockEntity, MBlocks::MULTIBLOCK_TEST)
|
||||
|
||||
val ENERGY_CABLES: Map<CablesConfig.E, BlockEntityType<SimpleEnergyCableBlockEntity>> = SupplierMap(CablesConfig.E.entries.map { conf ->
|
||||
|
@ -45,6 +45,7 @@ import ru.dbotthepony.mc.otm.block.decorative.TritaniumDoorBlock
|
||||
import ru.dbotthepony.mc.otm.block.decorative.TritaniumTrapdoorBlock
|
||||
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.tech.EnergyHatchBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.tech.EnergyInterfaceBlockEntity
|
||||
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
|
||||
@ -76,6 +77,7 @@ import ru.dbotthepony.mc.otm.block.tech.CobblerBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.EnergyCounterBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.EnergyServoBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.EssenceStorageBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.FlywheelBatteryBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.PhantomAttractorBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.PlatePressBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.PoweredBlastFurnaceBlock
|
||||
@ -160,6 +162,13 @@ object MBlocks {
|
||||
conf to registry.register("${conf.name.lowercase()}_energy_cable") { EnergyCableBlock { a, b -> MBlockEntities.ENERGY_CABLES[conf]!!.create(a, b)!! } }
|
||||
})
|
||||
|
||||
val FLYWHEEL_BATTERY by registry.register(MNames.FLYWHEEL_BATTERY) { FlywheelBatteryBlock() }
|
||||
val FLYWHEEL_BEARING by registry.register(MNames.FLYWHEEL_BEARING) { MatteryBlock().addSimpleDescription() }
|
||||
val FLYWHEEL_SHAFT by registry.register(MNames.FLYWHEEL_SHAFT) { MatteryBlock().addSimpleDescription() }
|
||||
val FLYWHEEL_HOUSING by registry.register(MNames.FLYWHEEL_HOUSING) { MatteryBlock().addSimpleDescription() }
|
||||
|
||||
val GENERATOR_BLOCK by registry.register(MNames.GENERATOR_BLOCK) { MatteryBlock().addSimpleDescription() }
|
||||
|
||||
val STORAGE_BUS: Block by registry.register(MNames.STORAGE_BUS, ::StorageBusBlock)
|
||||
val STORAGE_IMPORTER: Block by registry.register(MNames.STORAGE_IMPORTER, ::StorageImporterBlock)
|
||||
val STORAGE_EXPORTER: Block by registry.register(MNames.STORAGE_EXPORTER, ::StorageExporterBlock)
|
||||
@ -190,6 +199,8 @@ object MBlocks {
|
||||
val ENERGY_OUTPUT_HATCH by registry.register(MNames.ENERGY_OUTPUT_HATCH) { HatchBlock(EnergyHatchBlockEntity::output, true) }
|
||||
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 ENERGY_INPUT_INTERFACE by registry.register(MNames.ENERGY_INPUT_INTERFACE) { HatchBlock(EnergyInterfaceBlockEntity::input, true) }
|
||||
val ENERGY_OUTPUT_INTERFACE by registry.register(MNames.ENERGY_OUTPUT_INTERFACE) { HatchBlock(EnergyInterfaceBlockEntity::output, true) }
|
||||
|
||||
val LIQUID_XP: LiquidBlock by registry.register("liquid_xp") { LiquidBlock(MFluids.LIQUID_XP_FLOWING, BlockBehaviour.Properties.of().mapColor(MapColor.EMERALD).replaceable().noCollission().strength(100.0f).pushReaction(PushReaction.DESTROY).noLootTable().liquid().sound(SoundType.EMPTY)) }
|
||||
|
||||
|
@ -134,12 +134,75 @@ private fun CreativeModeTab.Output.fluids(value: Item) {
|
||||
private fun addMainCreativeTabItems(consumer: CreativeModeTab.Output) {
|
||||
with(consumer) {
|
||||
accept(MItems.ENERGY_CABLES.values)
|
||||
accept(MItems.MACHINES)
|
||||
|
||||
// machines
|
||||
accept(MItems.TWIN_PLATE_PRESS.values)
|
||||
accept(MItems.POWERED_FURNACE.values)
|
||||
accept(MItems.POWERED_BLAST_FURNACE.values)
|
||||
accept(MItems.POWERED_SMOKER.values)
|
||||
|
||||
accept(MItems.ANDROID_STATION.values)
|
||||
accept(MItems.ANDROID_CHARGER.values)
|
||||
accept(MItems.BATTERY_BANK.values)
|
||||
accept(MItems.ENERGY_COUNTER.values)
|
||||
accept(MItems.CHEMICAL_GENERATOR.values)
|
||||
accept(MItems.ENERGY_SERVO.values)
|
||||
|
||||
accept(MItems.PHANTOM_ATTRACTOR)
|
||||
accept(MItems.PAINTER)
|
||||
accept(MItems.COBBLESTONE_GENERATOR.values)
|
||||
accept(MItems.ESSENCE_STORAGE.values)
|
||||
|
||||
accept(MItems.MATTER_DECOMPOSER.values)
|
||||
accept(MItems.MATTER_CAPACITOR_BANK.values)
|
||||
accept(MItems.MATTER_CABLE)
|
||||
accept(MItems.PATTERN_STORAGE)
|
||||
accept(MItems.MATTER_SCANNER.values)
|
||||
accept(MItems.MATTER_PANEL.values)
|
||||
accept(MItems.MATTER_REPLICATOR.values)
|
||||
accept(MItems.MATTER_BOTTLER.values)
|
||||
accept(MItems.MATTER_ENTANGLER)
|
||||
accept(MItems.MATTER_RECYCLER.values)
|
||||
accept(MItems.MATTER_RECONSTRUCTOR.values)
|
||||
|
||||
accept(MItems.GRAVITATION_STABILIZER)
|
||||
|
||||
// storage
|
||||
accept(MItems.STORAGE_BUS)
|
||||
accept(MItems.STORAGE_IMPORTER)
|
||||
accept(MItems.STORAGE_EXPORTER)
|
||||
accept(MItems.DRIVE_VIEWER.values)
|
||||
accept(MItems.DRIVE_RACK)
|
||||
accept(MItems.ITEM_MONITOR.values)
|
||||
accept(MItems.STORAGE_CABLE)
|
||||
accept(MItems.STORAGE_POWER_SUPPLIER.values)
|
||||
|
||||
// multiblock parts
|
||||
accept(MItems.FLYWHEEL_BATTERY)
|
||||
accept(MItems.FLYWHEEL_HOUSING)
|
||||
accept(MItems.FLYWHEEL_SHAFT)
|
||||
accept(MItems.FLYWHEEL_BEARING)
|
||||
|
||||
accept(MItems.GENERATOR_BLOCK)
|
||||
|
||||
accept(MItems.BLACK_HOLE_GENERATOR)
|
||||
|
||||
accept(MItems.ITEM_INPUT_HATCH)
|
||||
accept(MItems.ITEM_OUTPUT_HATCH)
|
||||
accept(MItems.ENERGY_INPUT_HATCH)
|
||||
accept(MItems.ENERGY_OUTPUT_HATCH)
|
||||
accept(MItems.ENERGY_INPUT_INTERFACE)
|
||||
accept(MItems.ENERGY_OUTPUT_INTERFACE)
|
||||
accept(MItems.MATTER_INPUT_HATCH)
|
||||
accept(MItems.MATTER_OUTPUT_HATCH)
|
||||
|
||||
// upgrades
|
||||
accept(MItems.MachineUpgrades.Basic.LIST)
|
||||
accept(MItems.MachineUpgrades.Normal.LIST)
|
||||
accept(MItems.MachineUpgrades.Advanced.LIST)
|
||||
accept(MItems.MachineUpgrades.Creative.LIST)
|
||||
|
||||
// misc
|
||||
accept(MRegistry.CARGO_CRATES.item)
|
||||
accept(MItems.DEV_CHEST)
|
||||
accept(MItems.HOLO_SIGN)
|
||||
|
@ -26,6 +26,9 @@ import net.minecraft.world.item.crafting.Ingredient
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.neoforged.bus.api.IEventBus
|
||||
import net.neoforged.neoforge.common.SimpleTier
|
||||
import ru.dbotthepony.mc.otm.block.MatteryBlock
|
||||
import ru.dbotthepony.mc.otm.block.addSimpleDescription
|
||||
import ru.dbotthepony.mc.otm.block.tech.FlywheelBatteryBlock
|
||||
import ru.dbotthepony.mc.otm.capability.ITieredUpgradeSet
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayer
|
||||
import ru.dbotthepony.mc.otm.capability.UpgradeType
|
||||
@ -134,6 +137,7 @@ object MItems {
|
||||
val PHANTOM_ATTRACTOR: DoubleHighBlockItem by registry.register(MNames.PHANTOM_ATTRACTOR) { DoubleHighBlockItem(
|
||||
MBlocks.PHANTOM_ATTRACTOR, DEFAULT_PROPERTIES
|
||||
) }
|
||||
|
||||
val ENERGY_SERVO = register(MNames.ENERGY_SERVO, MBlocks.ENERGY_SERVO)
|
||||
val COBBLESTONE_GENERATOR = register(MNames.COBBLESTONE_GENERATOR, MBlocks.COBBLESTONE_GENERATOR)
|
||||
|
||||
@ -141,6 +145,13 @@ object MItems {
|
||||
val ESSENCE_STORAGE = register(MNames.ESSENCE_STORAGE, MBlocks.ESSENCE_STORAGE)
|
||||
val MATTER_RECONSTRUCTOR = register(MNames.MATTER_RECONSTRUCTOR, MBlocks.MATTER_RECONSTRUCTOR)
|
||||
|
||||
val FLYWHEEL_BATTERY by registry.register(MNames.FLYWHEEL_BATTERY) { BlockItem(MBlocks.FLYWHEEL_BATTERY, DEFAULT_PROPERTIES) }
|
||||
val FLYWHEEL_BEARING by registry.register(MNames.FLYWHEEL_BEARING) { BlockItem(MBlocks.FLYWHEEL_BEARING, DEFAULT_PROPERTIES) }
|
||||
val FLYWHEEL_SHAFT by registry.register(MNames.FLYWHEEL_SHAFT) { BlockItem(MBlocks.FLYWHEEL_SHAFT, DEFAULT_PROPERTIES) }
|
||||
val FLYWHEEL_HOUSING by registry.register(MNames.FLYWHEEL_HOUSING) { BlockItem(MBlocks.FLYWHEEL_HOUSING, DEFAULT_PROPERTIES) }
|
||||
|
||||
val GENERATOR_BLOCK by registry.register(MNames.GENERATOR_BLOCK) { BlockItem(MBlocks.GENERATOR_BLOCK, DEFAULT_PROPERTIES) }
|
||||
|
||||
val DEV_CHEST: BlockItem by registry.register(MNames.DEV_CHEST) { BlockItem(MBlocks.DEV_CHEST, DEFAULT_PROPERTIES) }
|
||||
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) }
|
||||
@ -155,62 +166,8 @@ object MItems {
|
||||
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 {
|
||||
val machines = ArrayList<Supplier<BlockItem>>()
|
||||
|
||||
machines.addAll(TWIN_PLATE_PRESS.asSupplierArray())
|
||||
machines.addAll(POWERED_FURNACE.asSupplierArray())
|
||||
machines.addAll(POWERED_BLAST_FURNACE.asSupplierArray())
|
||||
machines.addAll(POWERED_SMOKER.asSupplierArray())
|
||||
|
||||
machines.addAll(ANDROID_STATION.asSupplierArray())
|
||||
machines.addAll(ANDROID_CHARGER.asSupplierArray())
|
||||
machines.addAll(BATTERY_BANK.asSupplierArray())
|
||||
machines.addAll(ENERGY_COUNTER.asSupplierArray())
|
||||
machines.addAll(CHEMICAL_GENERATOR.asSupplierArray())
|
||||
machines.addAll(ENERGY_SERVO.asSupplierArray())
|
||||
|
||||
machines.add(MItems::PHANTOM_ATTRACTOR)
|
||||
machines.add(MItems::PAINTER)
|
||||
machines.addAll(COBBLESTONE_GENERATOR.asSupplierArray().iterator())
|
||||
machines.addAll(ESSENCE_STORAGE.asSupplierArray().iterator())
|
||||
|
||||
machines.addAll(MATTER_DECOMPOSER.asSupplierArray().iterator())
|
||||
machines.addAll(MATTER_CAPACITOR_BANK.asSupplierArray().iterator())
|
||||
machines.add(MItems::MATTER_CABLE)
|
||||
machines.add(MItems::PATTERN_STORAGE)
|
||||
machines.addAll(MATTER_SCANNER.asSupplierArray().iterator())
|
||||
machines.addAll(MATTER_PANEL.asSupplierArray().iterator())
|
||||
machines.addAll(MATTER_REPLICATOR.asSupplierArray().iterator())
|
||||
machines.addAll(MATTER_BOTTLER.asSupplierArray().iterator())
|
||||
machines.add(MItems::MATTER_ENTANGLER)
|
||||
machines.addAll(MATTER_RECYCLER.asSupplierArray().iterator())
|
||||
machines.addAll(MATTER_RECONSTRUCTOR.asSupplierArray().iterator())
|
||||
|
||||
machines.add(MItems::GRAVITATION_STABILIZER)
|
||||
|
||||
machines.add(MItems::BLACK_HOLE_GENERATOR)
|
||||
machines.add(MItems::ITEM_INPUT_HATCH)
|
||||
machines.add(MItems::ITEM_OUTPUT_HATCH)
|
||||
machines.add(MItems::ENERGY_INPUT_HATCH)
|
||||
machines.add(MItems::ENERGY_OUTPUT_HATCH)
|
||||
machines.add(MItems::MATTER_INPUT_HATCH)
|
||||
machines.add(MItems::MATTER_OUTPUT_HATCH)
|
||||
|
||||
machines.add(MItems::STORAGE_BUS)
|
||||
machines.add(MItems::STORAGE_IMPORTER)
|
||||
machines.add(MItems::STORAGE_EXPORTER)
|
||||
machines.addAll(DRIVE_VIEWER.asSupplierArray().iterator())
|
||||
machines.add(MItems::DRIVE_RACK)
|
||||
machines.addAll(ITEM_MONITOR.asSupplierArray().iterator())
|
||||
machines.add(MItems::STORAGE_CABLE)
|
||||
machines.addAll(STORAGE_POWER_SUPPLIER.asSupplierArray().iterator())
|
||||
|
||||
MACHINES = SupplierList(machines)
|
||||
}
|
||||
val ENERGY_INPUT_INTERFACE by registry.register(MNames.ENERGY_INPUT_INTERFACE) { BlockItem(MBlocks.ENERGY_INPUT_INTERFACE, DEFAULT_PROPERTIES) }
|
||||
val ENERGY_OUTPUT_INTERFACE by registry.register(MNames.ENERGY_OUTPUT_INTERFACE) { BlockItem(MBlocks.ENERGY_OUTPUT_INTERFACE, DEFAULT_PROPERTIES) }
|
||||
|
||||
val MULTIBLOCK_TEST by registry.register("multiblock_test") { BlockItem(MBlocks.MULTIBLOCK_TEST, Properties().stacksTo(64)) }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user