From b3651b1f863809bb3078903967d331ac7cf05a71 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 4 Jan 2024 16:22:12 +0700 Subject: [PATCH] Powered furnace cleanup --- .../mc/otm/shapes/BlockShapes.java | 2 +- ...t => AbstractPoweredFurnaceBlockEntity.kt} | 51 +++++++++++-------- ...lock.kt => AbstractPoweredFurnaceBlock.kt} | 28 +++++----- .../mc/otm/menu/tech/PoweredFurnaceMenu.kt | 9 ++-- .../mc/otm/registry/MBlockEntities.kt | 9 ++-- .../ru/dbotthepony/mc/otm/registry/MBlocks.kt | 23 +++------ 6 files changed, 63 insertions(+), 59 deletions(-) rename src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/{PoweredFurnaceBlockEntity.kt => AbstractPoweredFurnaceBlockEntity.kt} (69%) rename src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/{PoweredFurnaceBlock.kt => AbstractPoweredFurnaceBlock.kt} (62%) diff --git a/src/main/java/ru/dbotthepony/mc/otm/shapes/BlockShapes.java b/src/main/java/ru/dbotthepony/mc/otm/shapes/BlockShapes.java index a0bf71844..1bc232038 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/shapes/BlockShapes.java +++ b/src/main/java/ru/dbotthepony/mc/otm/shapes/BlockShapes.java @@ -785,7 +785,7 @@ public class BlockShapes { new SimpleCuboid(0.3125d, 1.000625d, 0.125d, 0.6875d, 1.000625d, 0.1875d) ); - public static final BlockShape POWERED_SMOKER_IDLE = new BlockShape( + public static final BlockShape POWERED_SMOKER = new BlockShape( new SimpleCuboid(0.0625d, 0d, 0.5d, 0.9375d, 0.25d, 0.9375d), new SimpleCuboid(0d, 0d, 0d, 1d, 0.25d, 0.5d), new SimpleCuboid(0d, 0.25d, 0d, 0.3125d, 1d, 1d), diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PoweredFurnaceBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt similarity index 69% rename from src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PoweredFurnaceBlockEntity.kt rename to src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt index b1c6c4abe..b8ea06589 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PoweredFurnaceBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt @@ -1,15 +1,15 @@ package ru.dbotthepony.mc.otm.block.entity.tech import net.minecraft.core.BlockPos -import net.minecraft.core.Direction import net.minecraft.server.level.ServerLevel -import net.minecraft.server.level.ServerPlayer -import net.minecraft.world.entity.ExperienceOrb 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.crafting.AbstractCookingRecipe +import net.minecraft.world.item.crafting.BlastingRecipe import net.minecraft.world.item.crafting.RecipeType +import net.minecraft.world.item.crafting.SmeltingRecipe +import net.minecraft.world.item.crafting.SmokingRecipe import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.state.BlockState import net.minecraftforge.common.capabilities.ForgeCapabilities @@ -34,18 +34,20 @@ import ru.dbotthepony.mc.otm.core.collect.maybe import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.menu.tech.PoweredFurnaceMenu import ru.dbotthepony.mc.otm.recipe.MatteryCookingRecipe +import ru.dbotthepony.mc.otm.recipe.MicrowaveRecipe import ru.dbotthepony.mc.otm.registry.MBlockEntities +import ru.dbotthepony.mc.otm.registry.MRecipes -class PoweredFurnaceBlockEntity( - type: BlockEntityType, +sealed class AbstractPoweredFurnaceBlockEntity

( + type: BlockEntityType<*>, blockPos: BlockPos, blockState: BlockState, - val recipeType: RecipeType, - val secondaryRecipeType: (() -> RecipeType)?, + val recipeType: RecipeType

, + val secondaryRecipeType: RecipeType?, val config: WorkerBalanceValues ) : MatteryWorkerBlockEntity(type, blockPos, blockState, ItemJob.CODEC, 2) { - override val upgrades = UpgradeContainer(this::markDirtyFast, 2, UpgradeType.BASIC_PROCESSING) - override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyLevelUpdated, upgrades.transform(config))) + final override val upgrades = UpgradeContainer(this::markDirtyFast, 2, UpgradeType.BASIC_PROCESSING) + final override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyLevelUpdated, upgrades.transform(config))) val inputs = immutableList(2) { MatteryContainer(this::itemContainerUpdated, 1) } val outputs = immutableList(2) { MatteryContainer(this::itemContainerUpdated, 1) } @@ -85,15 +87,6 @@ class PoweredFurnaceBlockEntity( super.tick() } - override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? { - return when (type) { - MBlockEntities.POWERED_FURNACE -> PoweredFurnaceMenu.furnace(containerID, inventory, this) - MBlockEntities.POWERED_BLAST_FURNACE -> PoweredFurnaceMenu.blasting(containerID, inventory, this) - MBlockEntities.POWERED_SMOKER -> PoweredFurnaceMenu.smoking(containerID, inventory, this) - else -> null - } - } - override fun onJobFinish(status: JobStatus, id: Int) { if (outputs[id].fullyAddItem(status.job.itemStack)) { experience.storeExperience(status.experience, this) @@ -113,7 +106,7 @@ class PoweredFurnaceBlockEntity( if (secondaryRecipeType != null) { val recipe = level.recipeManager - .byType(secondaryRecipeType.invoke() as RecipeType) + .byType(secondaryRecipeType) .values .iterator() .filter { it.value.matches(inputs[id], 0) } @@ -134,7 +127,7 @@ class PoweredFurnaceBlockEntity( } } - return level.recipeManager.getRecipeFor(recipeType as RecipeType, inputs[id], level).map { + return level.recipeManager.getRecipeFor(recipeType, inputs[id], level).map { val output = it.value.assemble(inputs[id], level.registryAccess()) val toProcess = inputs[id][0].count.coerceAtMost(upgrades.processingItems + 1) inputs[id][0].shrink(toProcess) @@ -145,3 +138,21 @@ class PoweredFurnaceBlockEntity( }.orElse(JobContainer.noItem()) } } + +class PoweredFurnaceBlockEntity(blockPos: BlockPos, blockState: BlockState) : AbstractPoweredFurnaceBlockEntity(MBlockEntities.POWERED_FURNACE, blockPos, blockState, RecipeType.SMELTING, null, MachinesConfig.POWERED_FURNACE) { + override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu { + return PoweredFurnaceMenu.furnace(containerID, inventory, this) + } +} + +class PoweredBlastFurnaceBlockEntity(blockPos: BlockPos, blockState: BlockState) : AbstractPoweredFurnaceBlockEntity(MBlockEntities.POWERED_BLAST_FURNACE, blockPos, blockState, RecipeType.BLASTING, null, MachinesConfig.POWERED_FURNACE) { + override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu { + return PoweredFurnaceMenu.blasting(containerID, inventory, this) + } +} + +class PoweredSmokerBlockEntity(blockPos: BlockPos, blockState: BlockState) : AbstractPoweredFurnaceBlockEntity(MBlockEntities.POWERED_SMOKER, blockPos, blockState, RecipeType.SMOKING, MRecipes.MICROWAVE, MachinesConfig.POWERED_FURNACE) { + override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu { + return PoweredFurnaceMenu.smoking(containerID, inventory, this) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/PoweredFurnaceBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/AbstractPoweredFurnaceBlock.kt similarity index 62% rename from src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/PoweredFurnaceBlock.kt rename to src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/AbstractPoweredFurnaceBlock.kt index 54eda35b1..d6ed29b73 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/PoweredFurnaceBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/AbstractPoweredFurnaceBlock.kt @@ -1,8 +1,7 @@ package ru.dbotthepony.mc.otm.block.tech import net.minecraft.core.BlockPos -import net.minecraft.world.item.crafting.AbstractCookingRecipe -import net.minecraft.world.item.crafting.RecipeType +import net.minecraft.world.item.DyeColor import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.Level import net.minecraft.world.level.block.Block @@ -17,23 +16,22 @@ import net.minecraft.world.phys.shapes.Shapes import net.minecraft.world.phys.shapes.VoxelShape import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.entity.WorkerState -import ru.dbotthepony.mc.otm.block.entity.tech.EssenceStorageBlockEntity +import ru.dbotthepony.mc.otm.block.entity.tech.AbstractPoweredFurnaceBlockEntity +import ru.dbotthepony.mc.otm.block.entity.tech.PoweredBlastFurnaceBlockEntity import ru.dbotthepony.mc.otm.block.entity.tech.PoweredFurnaceBlockEntity +import ru.dbotthepony.mc.otm.block.entity.tech.PoweredSmokerBlockEntity import ru.dbotthepony.mc.otm.block.getShapeForEachState -import ru.dbotthepony.mc.otm.config.WorkerBalanceValues import ru.dbotthepony.mc.otm.core.get -import ru.dbotthepony.mc.otm.recipe.MatteryCookingRecipe import ru.dbotthepony.mc.otm.shapes.BlockShape +import ru.dbotthepony.mc.otm.shapes.BlockShapes -class PoweredFurnaceBlock( - val type: () -> BlockEntityType, - val recipeType: RecipeType, - val secondaryRecipeType: (() -> RecipeType)?, - val config: WorkerBalanceValues, +sealed class AbstractPoweredFurnaceBlock>( + val color: DyeColor?, + val factory: (BlockPos, BlockState) -> T, shape: BlockShape? ) : RotatableMatteryBlock(DEFAULT_MACHINE_PROPERTIES), EntityBlock { - override fun newBlockEntity(p_153215_: BlockPos, p_153216_: BlockState): PoweredFurnaceBlockEntity { - return PoweredFurnaceBlockEntity(type.invoke(), p_153215_, p_153216_, recipeType, secondaryRecipeType, config) + override fun newBlockEntity(p_153215_: BlockPos, p_153216_: BlockState): T { + return factory(p_153215_, p_153216_) } override fun createBlockStateDefinition(builder: StateDefinition.Builder) { @@ -59,6 +57,10 @@ class PoweredFurnaceBlock( if (p_153212_.isClientSide) return null - return BlockEntityTicker { _, _, _, tile -> if (tile is PoweredFurnaceBlockEntity) tile.tick() } + return BlockEntityTicker { _, _, _, tile -> if (tile is AbstractPoweredFurnaceBlockEntity<*, *>) tile.tick() } } } + +class PoweredFurnaceBlock(color: DyeColor?) : AbstractPoweredFurnaceBlock(color, ::PoweredFurnaceBlockEntity, BlockShapes.POWERED_FURNACE) +class PoweredBlastFurnaceBlock(color: DyeColor?) : AbstractPoweredFurnaceBlock(color, ::PoweredBlastFurnaceBlockEntity, BlockShapes.POWERED_BLAST_FURNACE) +class PoweredSmokerBlock(color: DyeColor?) : AbstractPoweredFurnaceBlock(color, ::PoweredSmokerBlockEntity, BlockShapes.POWERED_SMOKER) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PoweredFurnaceMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PoweredFurnaceMenu.kt index e547464ab..8f4f57e8e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PoweredFurnaceMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PoweredFurnaceMenu.kt @@ -3,7 +3,10 @@ package ru.dbotthepony.mc.otm.menu.tech import net.minecraft.server.level.ServerPlayer import net.minecraft.world.entity.player.Inventory import net.minecraft.world.inventory.MenuType +import ru.dbotthepony.mc.otm.block.entity.tech.AbstractPoweredFurnaceBlockEntity +import ru.dbotthepony.mc.otm.block.entity.tech.PoweredBlastFurnaceBlockEntity import ru.dbotthepony.mc.otm.block.entity.tech.PoweredFurnaceBlockEntity +import ru.dbotthepony.mc.otm.block.entity.tech.PoweredSmokerBlockEntity import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.menu.OutputSlot import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu @@ -20,7 +23,7 @@ class PoweredFurnaceMenu( type: MenuType, containerID: Int, inventory: Inventory, - tile: PoweredFurnaceBlockEntity? = null + tile: AbstractPoweredFurnaceBlockEntity<*, *>? = null ) : MatteryPoweredMenu(type, containerID, inventory, tile) { val inputSlots = makeSlots(tile?.inputs, 2, ::MatterySlot) val outputSlots = makeSlots(tile?.outputs, 2) { c, s -> OutputSlot(c, s) { tile?.experience?.popExperience(player as ServerPlayer) } } @@ -53,7 +56,7 @@ class PoweredFurnaceMenu( fun blasting( containerID: Int, inventory: Inventory, - tile: PoweredFurnaceBlockEntity? = null + tile: PoweredBlastFurnaceBlockEntity? = null ) : PoweredFurnaceMenu { return PoweredFurnaceMenu(MMenus.POWERED_BLAST_FURNACE, containerID, inventory, tile) } @@ -61,7 +64,7 @@ class PoweredFurnaceMenu( fun smoking( containerID: Int, inventory: Inventory, - tile: PoweredFurnaceBlockEntity? = null + tile: PoweredSmokerBlockEntity? = null ) : PoweredFurnaceMenu { return PoweredFurnaceMenu(MMenus.POWERED_SMOKER, containerID, inventory, tile) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt index e92c1a96c..37a6b2d81 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt @@ -79,16 +79,16 @@ object MBlockEntities { val PAINTER by register(MNames.PAINTER, ::PainterBlockEntity, MBlocks::PAINTER) val MATTER_ENTANGLER by register(MNames.MATTER_ENTANGLER, ::MatterEntanglerBlockEntity, MBlocks::MATTER_ENTANGLER) + val POWERED_FURNACE by register(MNames.POWERED_FURNACE, ::PoweredFurnaceBlockEntity, *MBlocks.POWERED_FURNACE.asSupplierArray()) + val POWERED_BLAST_FURNACE by register(MNames.POWERED_BLAST_FURNACE, ::PoweredBlastFurnaceBlockEntity, *MBlocks.POWERED_BLAST_FURNACE.asSupplierArray()) + val POWERED_SMOKER by register(MNames.POWERED_SMOKER, ::PoweredSmokerBlockEntity, *MBlocks.POWERED_SMOKER.asSupplierArray()) + val ENERGY_CABLES: Map> = SupplierMap(CablesConfig.E.entries.map { conf -> var selfFeed: Supplier> = Supplier { TODO() } selfFeed = register("${conf.name.lowercase()}_energy_cable", { a, b -> SimpleEnergyCableBlockEntity(selfFeed.get(), a, b, conf) }) as Supplier> conf to selfFeed }) - val POWERED_FURNACE: BlockEntityType by registry.register(MNames.POWERED_FURNACE) { BlockEntityType.Builder.of({ a, b -> MBlocks.POWERED_FURNACE[null]!!.newBlockEntity(a, b) }, *MBlocks.POWERED_FURNACE.values.toTypedArray()).build(null) } - val POWERED_BLAST_FURNACE: BlockEntityType by registry.register(MNames.POWERED_BLAST_FURNACE) { BlockEntityType.Builder.of({ a, b -> MBlocks.POWERED_BLAST_FURNACE[null]!!.newBlockEntity(a, b) }, *MBlocks.POWERED_BLAST_FURNACE.values.toTypedArray()).build(null) } - val POWERED_SMOKER: BlockEntityType by registry.register(MNames.POWERED_SMOKER) { BlockEntityType.Builder.of({ a, b -> MBlocks.POWERED_SMOKER[null]!!.newBlockEntity(a, b) }, *MBlocks.POWERED_SMOKER.values.toTypedArray()).build(null) } - val STORAGE_BUS: BlockEntityType by registry.register(MNames.STORAGE_BUS) { BlockEntityType.Builder.of(::StorageBusBlockEntity, MBlocks.STORAGE_BUS).build(null) } val STORAGE_IMPORTER: BlockEntityType by registry.register(MNames.STORAGE_IMPORTER) { BlockEntityType.Builder.of(::StorageImporterBlockEntity, MBlocks.STORAGE_IMPORTER).build(null) } val STORAGE_EXPORTER: BlockEntityType by registry.register(MNames.STORAGE_EXPORTER) { BlockEntityType.Builder.of(::StorageExporterBlockEntity, MBlocks.STORAGE_EXPORTER).build(null) } @@ -104,7 +104,6 @@ object MBlockEntities { bus.addListener(this::registerClient) } - @Suppress("unchecked_cast") private fun registerClient(event: FMLClientSetupEvent) { event.enqueueWork { BlockEntityRenderers.register(BLACK_HOLE, ::BlackHoleRenderer) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt index 9e55611f0..89ad44bb2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt @@ -1,20 +1,10 @@ package ru.dbotthepony.mc.otm.registry -import net.minecraft.ChatFormatting -import net.minecraft.core.BlockPos -import net.minecraft.network.chat.Component import net.minecraft.util.valueproviders.UniformInt -import net.minecraft.world.entity.Entity -import net.minecraft.world.entity.EntityType -import net.minecraft.world.entity.monster.Zombie import net.minecraft.world.item.DyeColor -import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.TooltipFlag import net.minecraft.world.item.crafting.RecipeType -import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.block.AnvilBlock import net.minecraft.world.level.block.Block -import net.minecraft.world.level.block.DoorBlock import net.minecraft.world.level.block.DropExperienceBlock import net.minecraft.world.level.block.IronBarsBlock import net.minecraft.world.level.block.LiquidBlock @@ -22,11 +12,8 @@ import net.minecraft.world.level.block.RotatedPillarBlock import net.minecraft.world.level.block.SlabBlock import net.minecraft.world.level.block.SoundType import net.minecraft.world.level.block.StairBlock -import net.minecraft.world.level.block.TrapDoorBlock import net.minecraft.world.level.block.WallBlock import net.minecraft.world.level.block.state.BlockBehaviour -import net.minecraft.world.level.block.state.BlockState -import net.minecraft.world.level.block.state.properties.BlockSetType import net.minecraft.world.level.block.state.properties.NoteBlockInstrument import net.minecraft.world.level.material.MapColor import net.minecraft.world.level.material.PushReaction @@ -81,10 +68,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.TranslatableComponent import ru.dbotthepony.mc.otm.core.collect.SupplierList import ru.dbotthepony.mc.otm.core.collect.SupplierMap import ru.dbotthepony.mc.otm.shapes.BlockShapes @@ -112,9 +101,9 @@ object MBlocks { val CHEMICAL_GENERATOR: Block by registry.register(MNames.CHEMICAL_GENERATOR) { ChemicalGeneratorBlock() } val PLATE_PRESS = registry.coloredWithBase(MNames.PLATE_PRESS) { color, _ -> PlatePressBlock(color) } val TWIN_PLATE_PRESS = registry.coloredWithBase(MNames.TWIN_PLATE_PRESS) { color, _ -> PlatePressBlock(color, isTwin = true) } - val POWERED_FURNACE = registry.coloredWithBase(MNames.POWERED_FURNACE) { color, _ -> PoweredFurnaceBlock(MBlockEntities::POWERED_FURNACE, RecipeType.SMELTING, null, MachinesConfig.POWERED_FURNACE, BlockShapes.POWERED_FURNACE) } - val POWERED_BLAST_FURNACE = registry.coloredWithBase(MNames.POWERED_BLAST_FURNACE) { color, _ -> PoweredFurnaceBlock(MBlockEntities::POWERED_BLAST_FURNACE, RecipeType.BLASTING, null, MachinesConfig.POWERED_BLAST_FURNACE, BlockShapes.POWERED_BLAST_FURNACE) } - val POWERED_SMOKER = registry.coloredWithBase(MNames.POWERED_SMOKER) { color, _ -> PoweredFurnaceBlock(MBlockEntities::POWERED_SMOKER, RecipeType.SMOKING, MRecipes::MICROWAVE, MachinesConfig.POWERED_SMOKER, BlockShapes.POWERED_SMOKER_IDLE) } + val POWERED_FURNACE = registry.coloredWithBase(MNames.POWERED_FURNACE) { color, _ -> PoweredFurnaceBlock(color) } + val POWERED_BLAST_FURNACE = registry.coloredWithBase(MNames.POWERED_BLAST_FURNACE) { color, _ -> PoweredBlastFurnaceBlock(color) } + val POWERED_SMOKER = registry.coloredWithBase(MNames.POWERED_SMOKER) { color, _ -> PoweredSmokerBlock(color) } val MATTER_RECYCLER = registry.coloredWithBase(MNames.MATTER_RECYCLER) { color, _ -> MatterRecyclerBlock(color) } val ENERGY_SERVO: Block by registry.register(MNames.ENERGY_SERVO) { EnergyServoBlock() } val COBBLESTONE_GENERATOR = registry.coloredWithBase(MNames.COBBLESTONE_GENERATOR) { color, _ -> CobblerBlock(color) }