// priority: 0
// Visit the wiki for more info - https://kubejs.com/
console.info('Hello, World! (Loaded CUSTOM MULTIBLOCKS.js)')


const CoilWorkableElectricMultiblockMachine = Java.loadClass("com.gregtechceu.gtceu.api.machine.multiblock.CoilWorkableElectricMultiblockMachine")
const RelativeDirection = Java.loadClass("com.gregtechceu.gtceu.api.pattern.util.RelativeDirection")
const $SteamMulti = Java.loadClass('com.gregtechceu.gtceu.common.machine.multiblock.steam.SteamParallelMultiblockMachine')
const $Tags = Java.loadClass("dev.latvian.mods.kubejs.util.Tags")

/*
// This is literally just an out dated example taken from ATM and should be deleted anytime now
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('star_forge')
        // .category('gregstar')
        .setEUIO('in')
        .setMaxIOSize(15, 5, 5, 0)
        .setSlotOverlay(false, false, GuiTextures.SOLIDIFIER_OVERLAY)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.ARC);
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('star_forge', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeTypes('star_forge')
        .recipeModifier(GTRecipeModifiers.PARALLEL_HATCH.apply(OverclockingLogic.NON_PERFECT_OVERCLOCK, GTRecipeModifiers.ELECTRIC_OVERCLOCK))
        .appearanceBlock(GCyMBlocks.CASING_ATOMIC)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle("               ", "               ", "               ", "               ", "               ", "      W W      ", "     CWEWC     ", "      W W      ", "               ", "               ", "               ", "               ", "               ")
            .aisle("               ", "               ", "               ", "               ", "      GCG      ", "     CWCWC     ", "   CCPPPPPCC   ", "     CWCWC     ", "      GCG      ", "               ", "               ", "               ", "               ")
            .aisle("               ", "               ", "      GCG      ", "     GGCGG     ", "    GG   GG    ", "   CC WCW CC   ", "  CPPCWCWCPPC  ", "   CC WCW CC   ", "    GG   GG    ", "     GGCGG     ", "      GCG      ", "               ", "               ")
            .aisle("               ", "      GCG      ", "    GG   GG    ", "   GG     GG   ", "   G       G   ", "  C         C  ", " CPCC  S  CCPC ", "  C         C  ", "   G       G   ", "   GG     GG   ", "    GG   GG    ", "      GCG      ", "               ")
            .aisle("               ", "     GGCGG     ", "   GG     GG   ", "   G       G   ", "  G         G  ", "  C         C  ", " CPC       CPC ", "  C         C  ", "  G         G  ", "   G       G   ", "   GG     GG   ", "     GGCGG     ", "               ")
            .aisle("      CCC      ", "    GG C GG    ", "   G       G   ", "  G         G  ", "  G         G  ", " C           C ", "CPC         CPC", " C           C ", "  G         G  ", "  G         G  ", "   G       G   ", "    GG C GG    ", "      CCC      ")
            .aisle("     CFCFC     ", "   GG CCC GG   ", "  G    C    G  ", "  G         G  ", " G           G ", "WWW         WWW", "WPW         WPW", "WWW         WWW", " G           G ", "  G         G  ", "  G    C    G  ", "   GG CCC GG   ", "     CFCFC     ")
            .aisle("     CCFCC     ", "   CCCCPCCCC   ", "  C   CCC   C  ", "  C    S    C  ", " C           C ", " CC         CC ", "EPCS   I   SCPE", " CC         CC ", " C           C ", "  C    S    C  ", "  C   CCC   C  ", "   CCCCPCCCC   ", "     CCFCC     ")
            .aisle("     CFCFC     ", "   GG CCC GG   ", "  G    C    G  ", "  G         G  ", " G           G ", "WWW         WWW", "WPW         WPW", "WWW         WWW", " G           G ", "  G         G  ", "  G    C    G  ", "   GG CCC GG   ", "     CFCFC     ")
            .aisle("      CCC      ", "    GG C GG    ", "   G       G   ", "  G         G  ", "  G         G  ", " C           C ", "CPC         CPC", " C           C ", "  G         G  ", "  G         G  ", "   G       G   ", "    GG C GG    ", "      CCC      ")
            .aisle("               ", "     GGCGG     ", "   GG     GG   ", "   G       G   ", "  G         G  ", "  C         C  ", " CPC       CPC ", "  C         C  ", "  G         G  ", "   G       G   ", "   GG     GG   ", "     GGCGG     ", "               ")
            .aisle("               ", "      GCG      ", "    GG   GG    ", "   GG     GG   ", "   G       G   ", "  C         C  ", " CPCC  S  CCPC ", "  C         C  ", "   G       G   ", "   GG     GG   ", "    GG   GG    ", "      GCG      ", "               ")
            .aisle("               ", "               ", "      GCG      ", "     GGCGG     ", "    GG   GG    ", "   CC WCW CC   ", "  CPPCWCWCPPC  ", "   CC WCW CC   ", "    GG   GG    ", "     GGCGG     ", "      GCG      ", "               ", "               ")
            .aisle("               ", "               ", "               ", "               ", "      GCG      ", "     CWCWC     ", "   CCPPPPPCC   ", "     CWCWC     ", "      GCG      ", "               ", "               ", "               ", "               ")
            .aisle("               ", "               ", "               ", "               ", "               ", "      W W      ", "     AWMWA     ", "      W W      ", "               ", "               ", "               ", "               ", "               ")
            .where('M', Predicates.controller(Predicates.blocks(definition.get())))
            .where('W', Predicates.blocks(GTBlocks.COIL_TRINIUM.get()))
            .where("P", Predicates.blocks(GTBlocks.SUPERCONDUCTING_COIL.get()))
            .where('G', Predicates.blocks("minecraft:glass"))
            .where('I', Predicates.blocks("minecraft:stone"))
            .where('S', Predicates.blocks("minecraft:dropper"))
            .where('E', Predicates.abilities(PartAbility.INPUT_ENERGY).setMinGlobalLimited(2)
                .or(Predicates.blocks('gtceu:atomic_casing'))) 
            .where('C', Predicates.blocks('gtceu:atomic_casing')
                .or(Predicates.abilities(PartAbility.PARALLEL_HATCH).setExactLimit(1))) 
            .where('F', Predicates.abilities(PartAbility.IMPORT_FLUIDS).setMaxGlobalLimited(5)
                .or(Predicates.blocks('gtceu:atomic_casing'))) 
            .where('A', Predicates.abilities(PartAbility.IMPORT_ITEMS).setExactLimit(1)
                .or(Predicates.abilities(PartAbility.EXPORT_ITEMS)).setExactLimit(1)
                .or(Predicates.blocks('gtceu:atomic_casing'))) 
            .where(' ', Predicates.any())
            .build())
        .shapeInfo(controller => MultiblockShapeInfo.builder()
            .aisle("               ", "               ", "               ", "               ", "               ", "      W W      ", "     CWCWC     ", "      W W      ", "               ", "               ", "               ", "               ", "               ")
            .aisle("               ", "               ", "               ", "               ", "      GCG      ", "     CWCWC     ", "   CCPPPPPCC   ", "     CWCWC     ", "      GCG      ", "               ", "               ", "               ", "               ")
            .aisle("               ", "               ", "      GCG      ", "     GGCGG     ", "    GG   GG    ", "   CC WCW CC   ", "  CPPCWCWCPPC  ", "   CC WCW CC   ", "    GG   GG    ", "     GGCGG     ", "      GCG      ", "               ", "               ")
            .aisle("               ", "      GCG      ", "    GG   GG    ", "   GG     GG   ", "   G       G   ", "  C         C  ", " CPCC  R  CCPC ", "  C         C  ", "   G       G   ", "   GG     GG   ", "    GG   GG    ", "      GCG      ", "               ")
            .aisle("               ", "     GGCGG     ", "   GG     GG   ", "   G       G   ", "  G         G  ", "  C         C  ", " CPC       CPC ", "  C         C  ", "  G         G  ", "   G       G   ", "   GG     GG   ", "     GGCGG     ", "               ")
            .aisle("      CCC      ", "    GG C GG    ", "   G       G   ", "  G         G  ", "  G         G  ", " C           C ", "CPC         CPC", " C           C ", "  G         G  ", "  G         G  ", "   G       G   ", "    GG C GG    ", "      CCC      ")
            .aisle("     CCCCC     ", "   GG CCC GG   ", "  G    C    G  ", "  G         G  ", " G           G ", "WWW         WWW", "WPW         WPW", "WWW         WWW", " G           G ", "  G         G  ", "  G    C    G  ", "   GG CCC GG   ", "     CFCFC     ")
            .aisle("     CCCCC     ", "   CCCCPCCCC   ", "  C   CCC   C  ", "  C    s    C  ", " C           C ", " CC         CC ", "EPCQ   I   qCPe", " CC         CC ", " C           C ", "  C    S    C  ", "  C   CCC   C  ", "   CCCCPCCCC   ", "     CCFCC     ")
            .aisle("     CCCCC     ", "   GG CCC GG   ", "  G    C    G  ", "  G         G  ", " G           G ", "WWW         WWW", "WPW         WPW", "WWW         WWW", " G           G ", "  G         G  ", "  G    C    G  ", "   GG CCC GG   ", "     CFCFC     ")
            .aisle("      CCC      ", "    GG C GG    ", "   G       G   ", "  G         G  ", "  G         G  ", " C           C ", "CPC         CPC", " C           C ", "  G         G  ", "  G         G  ", "   G       G   ", "    GG C GG    ", "      CCC      ")
            .aisle("               ", "     GGCGG     ", "   GG     GG   ", "   G       G   ", "  G         G  ", "  C         C  ", " CPC       CPC ", "  C         C  ", "  G         G  ", "   G       G   ", "   GG     GG   ", "     GGCGG     ", "               ")
            .aisle("               ", "      GCG      ", "    GG   GG    ", "   GG     GG   ", "   G       G   ", "  C         C  ", " CPCC  r  CCPC ", "  C         C  ", "   G       G   ", "   GG     GG   ", "    GG   GG    ", "      GCG      ", "               ")
            .aisle("               ", "               ", "      GCG      ", "     GGCGG     ", "    GG   GG    ", "   CC WCW CC   ", "  CPPCWCWCPPC  ", "   CC WCW CC   ", "    GG   GG    ", "     GGCGG     ", "      GCG      ", "               ", "               ")
            .aisle("               ", "               ", "               ", "               ", "      GCG      ", "     CWCWC     ", "   CCPPPPPCC   ", "     CWHWC     ", "      GCG      ", "               ", "               ", "               ", "               ")
            .aisle("               ", "               ", "               ", "               ", "               ", "      W W      ", "     AWMWB     ", "      W W      ", "               ", "               ", "               ", "               ", "               ")
            .where('M', controller, Direction.SOUTH)
            .where('W', GTBlocks.COIL_TRINIUM.get())
            .where("P", GTBlocks.SUPERCONDUCTING_COIL.get())
            .where('G', Block.getBlock("minecraft:glass"))
            .where('I', Block.getBlock("minecraft:stone"))
            ["where(char,net.minecraft.world.level.block.state.BlockState)"]('Q', Block.getBlock("minecraft:dropper").defaultBlockState().setValue(BlockProperties.FACING, Direction.EAST))
            ["where(char,net.minecraft.world.level.block.state.BlockState)"]('q', Block.getBlock("minecraft:dropper").defaultBlockState().setValue(BlockProperties.FACING, Direction.WEST))
            ["where(char,net.minecraft.world.level.block.state.BlockState)"]('R', Block.getBlock("minecraft:dropper").defaultBlockState().setValue(BlockProperties.FACING, Direction.SOUTH))
            ["where(char,net.minecraft.world.level.block.state.BlockState)"]('r', Block.getBlock("minecraft:dropper").defaultBlockState().setValue(BlockProperties.FACING, Direction.NORTH))
            ["where(char,net.minecraft.world.level.block.state.BlockState)"]('S', Block.getBlock("minecraft:dropper").defaultBlockState().setValue(BlockProperties.FACING, Direction.DOWN))
            ["where(char,net.minecraft.world.level.block.state.BlockState)"]('s', Block.getBlock("minecraft:dropper").defaultBlockState().setValue(BlockProperties.FACING, Direction.UP))
            ["where(char,net.minecraft.world.level.block.state.BlockState)"]('H', Block.getBlock('gtceu:uv_parallel_hatch').defaultBlockState().setValue(BlockProperties.FACING, Direction.SOUTH))
            .where('E', GTMachines.ENERGY_INPUT_HATCH[6], Direction.WEST)
            .where('e', GTMachines.ENERGY_INPUT_HATCH[6], Direction.EAST)
            .where('C', Block.getBlock("gtceu:atomic_casing"))
            .where('F', GTMachines.FLUID_IMPORT_HATCH[6], Direction.UP)
            .where('A', GTMachines.ITEM_IMPORT_BUS[6], Direction.SOUTH)
            .where('B', GTMachines.ITEM_EXPORT_BUS[6], Direction.SOUTH)
            .where(' ', Block.getBlock("minecraft:air"))
            .build())
        .workableCasingRenderer("gtceu:block/casings/gcym/atomic_casing", 
            "gtceu:block/multiblock/implosion_compressor", false)
})
*/


// *************************** // // *************************** //
// ***** STANDARD MULTIS ***** // // ***** STANDARD MULTIS ***** //
// *************************** // // *************************** //
//#region STANDARD MULTIS

// **** glass_box **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('glass_box')
        .setEUIO('in')
        .setMaxIOSize(6, 1, 1, 1)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.BATH)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('glass_box', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('glass_box')
        .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.OC_NON_PERFECT])
        .appearanceBlock(GTBlocks.CASING_STAINLESS_CLEAN)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('CCC', 'CGC', 'CGC', 'CCC')
            .aisle('CCC', 'GSG', 'GMG', 'CCC')
            .aisle('CKC', 'CXC', 'CXC', 'CCC')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('M', Predicates.blocks('gtceu:hv_hermetic_casing'))
            .where('G', Predicates.blocks('gtceu:laminated_glass'))
            .where('X', Predicates.blocks('ae2:quartz_vibrant_glass'))
            // .where('Z', Predicates.blocks('gtceu:plascrete'))
            .where('S', Predicates.blocks('gtceu:filter_casing'))
            .where('C', Predicates.blocks(GTBlocks.CASING_STAINLESS_CLEAN.get())
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
                .or(Predicates.abilities(PartAbility.MUFFLER).setExactLimit(1))
                .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1))
                .or(Predicates.abilities(PartAbility.PARALLEL_HATCH).setExactLimit(1))
            )
            .build()
        )
        .workableCasingModel('gtceu:block/casings/solid/machine_casing_clean_stainless_steel', 'gtceu:block/multiblock/evaporation_plant')
})


// **** desulfurizer **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('desulfurizer')
        .setEUIO('in')
        .setMaxIOSize(2, 1, 1, 1)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.BATH)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('desulfurizer', 'multiblock')
        .machine((holder) => new CoilWorkableElectricMultiblockMachine(holder))
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('desulfurizer')
        .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, (machine, recipe) => GTRecipeModifiers.crackerOverclock(machine, recipe)])
        .appearanceBlock(GTBlocks.CASING_TITANIUM_STABLE)
        .pattern(definition => FactoryBlockPattern.start(RelativeDirection.BACK, RelativeDirection.UP, RelativeDirection.LEFT)
            .aisle('  DDD       ', '  DDD       ', '  DDD       ', '  DDD       ', '  DDD       ', '  DDD       ')
            .aisle('CCDPDCLCLCLC', 'CCDPDCLCLCLC', 'CCDPD L L L ', '  DPD       ', '  DPD       ', '  DDD       ')
            .aisle('CCDDDCLCLCLC', 'CGDDDXXXXXXX', 'CCDDDCLCLCLC', '  DDD L L L ', '  DDD L L L ', '  DDD       ')
            .aisle('CCCCCCLCLCLC', 'KGGGCCLCLCLC', 'CCCCCCLCLCLC', '   XXXXXXXX ', '      L L L ', '            ')
            .aisle('CCDDDCLCLCLC', 'CGDDDXXXXXXX', 'CCDDDCLCLCLC', '  DDD L L L ', '  DDD L L L ', '  DDD       ')
            .aisle('CCDPDCLCLCLC', 'CCDPDCLCLCLC', 'CCDPD L L L ', '  DPD       ', '  DPD       ', '  DDD       ')
            .aisle('  DDD       ', '  DDD       ', '  DDD       ', '  DDD       ', '  DDD       ', '  DDD       ')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('X', Predicates.blocks('gtceu:tempered_glass'))
            .where('P', Predicates.blocks('gtceu:titanium_pipe_casing'))
            .where('G', Predicates.blocks('gtceu:titanium_gearbox'))
            .where('D', Predicates.blocks('gtceu:clean_machine_casing'))
            .where('L', Predicates.heatingCoils())
            .where('C', Predicates.blocks(GTBlocks.CASING_TITANIUM_STABLE.get())
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
                .or(Predicates.abilities(PartAbility.MUFFLER).setExactLimit(1))
                .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1))
            )
            .where(' ', Predicates.any())
            .build()
        )
        .workableCasingModel('gtceu:block/casings/solid/machine_casing_stable_titanium', 'gtceu:block/multiblock/large_chemical_reactor')
})


// // **** desulfurizer **** //
// GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
//     event.create('desulfurizer')
//         .setEUIO('in')
//         .setMaxIOSize(2, 1, 1, 1)
//         .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
//         .setSound(GTSoundEntries.BATH)
// })

// GTCEuStartupEvents.registry('gtceu:machine', event => {
//     event.create('desulfurizer', 'multiblock')
//         .rotationState(RotationState.NON_Y_AXIS)
//         .recipeType('desulfurizer')
//         .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.OC_NON_PERFECT])
//         .appearanceBlock(GTBlocks.CASING_TITANIUM_STABLE)
//         .pattern(definition => FactoryBlockPattern.start()
//             .aisle('  DDD       ', '  DDD       ', '  DDD       ', '  DDD       ', '  DDD       ', '  DDD       ')
//             .aisle('CCDPDCLCLCLC', 'CCDPDCLCLCLC', 'CCDPD L L L ', '  DPD       ', '  DPD       ', '  DDD       ')
//             .aisle('CCDDDCLCLCLC', 'CGDDDXXXXXXX', 'CCDDDCLCLCLC', '  DDD L L L ', '  DDD L L L ', '  DDD       ')
//             .aisle('CCCCCCLCLCLC', 'CGGGCCLCLCLC', 'CCCCCCLCLCLC', '   XXXXXXXX ', '      L L L ', '            ')
//             .aisle('CCDDDCLCLCLC', 'CGDDDXXXXXXX', 'CCDDDCLCLCLC', '  DDD L L L ', '  DDD L L L ', '  DDD       ')
//             .aisle('CCDPDCLCLCLC', 'CKDPDCLCLCLC', 'CCDPD L L L ', '  DPD       ', '  DPD       ', '  DDD       ')
//             .aisle('  DDD       ', '  DDD       ', '  DDD       ', '  DDD       ', '  DDD       ', '  DDD       ')
//             .where('K', Predicates.controller(Predicates.blocks(definition.get())))
//             .where('X', Predicates.blocks('gtceu:tempered_glass'))
//             .where('P', Predicates.blocks('gtceu:titanium_pipe_casing'))
//             .where('G', Predicates.blocks('gtceu:titanium_gearbox'))
//             .where('D', Predicates.blocks('gtceu:clean_machine_casing'))
//             .where('L', Predicates.blocks(GTBlocks.COIL_NICHROME.get()))
//             .where('C', Predicates.blocks(GTBlocks.CASING_TITANIUM_STABLE.get())
//                 .or(Predicates.autoAbilities(definition.getRecipeTypes()))
//             )
//             .where('O', Predicates.abilities(PartAbility.MUFFLER)
//                 .setExactLimit(1)
//             )
//             .where('N', Predicates.abilities(PartAbility.MAINTENANCE)
//                 .setExactLimit(1)
//             )
//             .where(' ', Predicates.any())
//             .build()
//         )
//         .workableCasingModel('gtceu:block/casings/solid/machine_casing_stable_titanium', 'gtceu:block/multiblock/large_chemical_reactor')
// })


// **** large_gas_collector **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('large_gas_collector')
        .setEUIO('in')
        .setMaxIOSize(1, 0, 0, 1)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.BATH)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('large_gas_collector', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('gtceu:gas_collector')
        .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.OC_NON_PERFECT])
        .appearanceBlock(GCYMBlocks.CASING_WATERTIGHT)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle(' CCC ', ' CCC ', ' CCC ', ' CCC ', ' CCC ')
            .aisle('CCCCC', 'CGPGC', 'CGPGC', 'CGPGC', 'CCCCC')
            .aisle('CCCCC', 'CPPPC', 'CPPPC', 'CPPPC', 'CCOCC')
            .aisle('CCCCC', 'CGPGC', 'CGPGC', 'CGPGC', 'CCCCC')
            .aisle(' CCC ', ' CKC ', ' CCC ', ' CCC ', ' CNC ')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('P', Predicates.blocks('gtceu:tungstensteel_pipe_casing'))
            .where('G', Predicates.blocks('gtceu:tungstensteel_gearbox'))
            .where('C', Predicates.blocks(GCYMBlocks.CASING_WATERTIGHT.get())
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
            )
            .where('O', Predicates.abilities(PartAbility.MUFFLER)
                .setExactLimit(1)
            )
            .where('N', Predicates.abilities(PartAbility.MAINTENANCE)
                .setExactLimit(1)
            )
            .where(' ', Predicates.any())
            .build()
        )
        .workableCasingModel('gtceu:block/casings/gcym/watertight_casing', 'gtceu:block/multiblock/distillation_tower')
})


// **** certus_quartz_charger **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('certus_quartz_charger')
        .setEUIO('in')
        .setMaxIOSize(2, 1, 1, 0)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.ELECTROLYZER)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('certus_quartz_charger', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('certus_quartz_charger')
        .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.OC_NON_PERFECT])
        .appearanceBlock(GTBlocks.CASING_STEEL_SOLID)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('CCC', 'CCC', 'CCC')
            .aisle('CCC', 'CSC', 'COC')
            .aisle('CKC', 'CXC', 'CNC')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('X', Predicates.blocks('ae2:quartz_vibrant_glass'))
            .where('S', Predicates.blocks('ae2:charger'))
            .where('C', Predicates.blocks(GTBlocks.CASING_STEEL_SOLID.get())
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
            )
            .where('O', Predicates.abilities(PartAbility.MUFFLER)
                .setExactLimit(1)
            )
            .where('N', Predicates.abilities(PartAbility.MAINTENANCE)
                .setExactLimit(1)
            )
            .build()
        )
        .workableCasingModel('gtceu:block/casings/solid/machine_casing_solid_steel', 'gtceu:block/multiblock/cracking_unit')
})


// **** large_inscriber **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('large_inscriber')
        .setEUIO('in')
        .setMaxIOSize(4, 1, 1, 0)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.ELECTROLYZER)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('large_inscriber', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('large_inscriber')
        .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.OC_PERFECT])
        .appearanceBlock(GTBlocks.CASING_STEEL_SOLID)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('CCC', 'CCC', 'CCC', 'CCC')
            .aisle('CCC', 'CSC', 'CZC', 'COC')
            .aisle('CKC', 'CXC', 'CXC', 'CNC')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('X', Predicates.blocks('ae2:quartz_glass'))
            .where('S', Predicates.blocks('ae2:inscriber'))
            .where('Z', Predicates.blocks('gtceu:mv_forming_press'))
            .where('C', Predicates.blocks(GTBlocks.CASING_STEEL_SOLID.get())
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
            )
            .where('O', Predicates.abilities(PartAbility.MUFFLER)
                .setExactLimit(1)
            )
            .where('N', Predicates.abilities(PartAbility.MAINTENANCE)
                .setExactLimit(1)
            )
            .build()
        )
        .workableCasingModel('gtceu:block/casings/solid/machine_casing_solid_steel', 'gtceu:block/multiblock/network_switch')
})


// **** meat_box **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('meat_box')
        .setEUIO('in')
        .setMaxIOSize(2, 1, 1, 0)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.ELECTROLYZER)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('meat_box', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('meat_box')
        .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.OC_NON_PERFECT])
        .appearanceBlock(GTBlocks.CASING_STEEL_SOLID)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('CCC', 'CCC', 'CCC', 'CCC')
            .aisle('CCC', 'CSC', 'CZC', 'COC')
            .aisle('CKC', 'CXC', 'CXC', 'CNC')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('X', Predicates.blocks('mob_grinding_utils:tinted_glass'))
            .where('S', Predicates.blocks('mob_grinding_utils:spikes'))
            .where('Z', Predicates.blocks('easy_villagers:breeder'))
            .where('C', Predicates.blocks(GTBlocks.CASING_STEEL_SOLID.get())
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
            )
            .where('O', Predicates.abilities(PartAbility.MUFFLER)
                .setExactLimit(1)
            )
            .where('N', Predicates.abilities(PartAbility.MAINTENANCE)
                .setExactLimit(1)
            )
            .build()
        )
        .workableCasingModel('gtceu:block/casings/solid/machine_casing_solid_steel', 'gtceu:block/multiblock/implosion_compressor')
})


// **** auto_cutting_board **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('auto_cutting_board')
        .setEUIO('in')
        .setMaxIOSize(2, 3, 0, 0)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.ELECTROLYZER)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('auto_cutting_board', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('auto_cutting_board')
        .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.OC_NON_PERFECT])
        .appearanceBlock(GTBlocks.CASING_STEEL_SOLID)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('CCC', 'CCC', 'CCC', 'CCC')
            .aisle('CCC', 'CSC', 'CZC', 'COC')
            .aisle('CKC', 'CXC', 'CXC', 'CNC')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('X', Predicates.blocks('ae2:quartz_glass'))
            .where('S', Predicates.blocks('farmersdelight:cutting_board'))
            .where('Z', Predicates.blocks('factory_blocks:gears'))
            .where('C', Predicates.blocks(GTBlocks.CASING_STEEL_SOLID.get())
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
            )
            .where('O', Predicates.abilities(PartAbility.MUFFLER)
                .setExactLimit(1)
            )
            .where('N', Predicates.abilities(PartAbility.MAINTENANCE)
                .setExactLimit(1)
            )
            .build()
        )
        .workableCasingModel('gtceu:block/casings/solid/machine_casing_solid_steel', 'gtceu:block/multiblock/assembly_line')
})


// **** auto_cooking_pot **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('auto_cooking_pot')
        .setEUIO('in')
        .setMaxIOSize(8, 2, 0, 0)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.BATH)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('auto_cooking_pot', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('auto_cooking_pot')
        .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.OC_NON_PERFECT])
        .appearanceBlock(GTBlocks.CASING_INVAR_HEATPROOF)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('CCC', 'CCC', 'CCC', 'CCC')
            .aisle('CCC', 'CSC', 'CZC', 'COC')
            .aisle('CKC', 'CXC', 'CXC', 'CNC')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('X', Predicates.blocks('ae2:quartz_glass'))
            .where('S', Predicates.blocks('farmersdelight:stove'))
            .where('Z', Predicates.blocks('farmersdelight:cooking_pot'))
            .where('C', Predicates.blocks(GTBlocks.CASING_INVAR_HEATPROOF.get())
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
            )
            .where('O', Predicates.abilities(PartAbility.MUFFLER)
                .setExactLimit(1)
            )
            .where('N', Predicates.abilities(PartAbility.MAINTENANCE)
                .setExactLimit(1)
            )
            .build()
        )
        .workableCasingModel('gtceu:block/casings/solid/machine_casing_heatproof', 'gtceu:block/multiblock/pyrolyse_oven')
})


// **** big_test **** //
// // (unused, uncraftable, is a macerator and compressor currently apparently)
// // looks cool, should use for something at some point
// GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
//     event.create('big_test')
//         .setEUIO('in')
//         .setMaxIOSize(4, 4, 4, 4)
//         .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
//         .setSound(GTSoundEntries.COMPRESSOR)
// })

// GTCEuStartupEvents.registry('gtceu:machine', event => {
//     event.create('big_test', 'multiblock')
//         .rotationState(RotationState.NON_Y_AXIS)
//         .recipeTypes(['gtceu:macerator', 'gtceu:compressor'])
//         .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.OC_NON_PERFECT])
//         .appearanceBlock(GTBlocks.CASING_TITANIUM_STABLE)
//         .pattern(definition => FactoryBlockPattern.start()
//             .aisle(' CCC ', ' CCC ', ' CCC ', ' CCC ', ' CCC ')
//             .aisle('CCCCC', 'C   C', 'C   C', 'CTTTC', 'CCCCC')
//             .aisle('CCCCC', 'CBIBC', 'CZYZC', 'CTTTC', 'CCOCC')
//             .aisle('CCCCC', 'C   C', 'C   C', 'CTTTC', 'CCCCC')
//             .aisle(' CKC ', ' XXX ', ' XXX ', ' XXX ', ' CNC ')
//             .where('K', Predicates.controller(Predicates.blocks(definition.get())))
//             .where('X', Predicates.blocks('gtceu:laminated_glass'))
//             .where('Z', Predicates.blocks('gtceu:molybdenum_disilicide_coil_block'))
//             .where('C', Predicates.blocks(GTBlocks.CASING_TITANIUM_STABLE.get())
//                 .or(Predicates.autoAbilities(definition.getRecipeTypes()))
//             )
//             .where('O', Predicates.abilities(PartAbility.MUFFLER)
//                 .setExactLimit(1)
//             )
//             .where('N', Predicates.abilities(PartAbility.MAINTENANCE)
//                 .setExactLimit(1)
//             )
//             .where('I', Predicates.blocks("davebuildingmod:isolinear_middle_blue"))
//             .where('B', Predicates.blocks("gtceu:empty_tier_i_battery"))
//             .where('Y', Predicates.blocks("tesseract:tesseract"))
//             .where('T', Predicates.blocks("gtceu:assembly_line_grating"))
//             .where(' ', Predicates.any())
//             .build()
//         )
//         .workableCasingModel('gtceu:block/casings/solid/machine_casing_stable_titanium', 'gtceu:block/multiblock/large_chemical_reactor')
// })


// **** large_resource_generator **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('large_resource_generator')
        .setEUIO('in')
        .setMaxIOSize(1, 6, 1, 0)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.COMPRESSOR)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('large_resource_generator', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('large_resource_generator')
        .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.OC_NON_PERFECT])
        .appearanceBlock(GTBlocks.CASING_TITANIUM_STABLE)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('CCC', ' T ', ' T ', ' T ', '   ', '   ', ' T ')
            .aisle('CCC', 'TCT', 'TCT', 'TCT', ' T ', ' T ', 'TTT')
            .aisle('CKC', ' T ', ' T ', ' T ', '   ', '   ', ' T ')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('C', Predicates.blocks(GTBlocks.CASING_TITANIUM_STABLE.get())
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
            )
            .where('T', Predicates.blocks("gtceu:tungsten_frame"))
            .where(' ', Predicates.any())
            .build()
        )
        .workableCasingModel('gtceu:block/casings/solid/machine_casing_stable_titanium', 'gtceu:block/multiblock/bedrock_ore_miner')
})


// **** natural_fluid_generator **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('natural_fluid_generator')
        .setEUIO('in')
        .setMaxIOSize(1, 0, 1, 1)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.COMPRESSOR)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('natural_fluid_generator', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('natural_fluid_generator')
        .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.OC_NON_PERFECT])
        .appearanceBlock(GTBlocks.CASING_STEEL_SOLID)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('CCC', ' T ', ' T ', ' T ', '   ', '   ', ' T ')
            .aisle('CCC', 'TPT', 'TPT', 'TET', ' T ', ' T ', 'TTT')
            .aisle('CKC', ' T ', ' T ', ' T ', '   ', '   ', ' T ')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('C', Predicates.blocks(GTBlocks.CASING_STEEL_SOLID.get())
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
            )
            .where('T', Predicates.blocks("gtceu:steel_frame"))
            .where('E', Predicates.blocks("tesseract:tesseract"))
            .where('P', Predicates.blocks("gtceu:steel_pipe_casing"))
            .where(' ', Predicates.any())
            .build()
        )
        .workableCasingModel('gtceu:block/casings/solid/machine_casing_solid_steel', 'gtceu:block/multiblock/fluid_drilling_rig')
})


// **** fusion_assembler **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('fusion_assembler')
        .setEUIO('in')
        .setMaxIOSize(12, 1, 6, 0)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.ELECTROLYZER)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('fusion_assembler', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('fusion_assembler')
        .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.OC_NON_PERFECT])
        .appearanceBlock(GCYMBlocks.CASING_ATOMIC)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('CCCCCCCCCCCCCCC', 'CCCCCCCCCCCCCCC', '   C       C   ', '   C       C   ', '   C  SSS  C   ', '   MMMSUSMMM   ', '   GGGSSSGGG   ', '   GGGSSSGGG   ', '   MMMSUSMMM   ', '      SSS      ', '               ', '               ')
            .aisle('CCCCCCCCCCCCCCC', 'CCCCCCCCCCCCCCC', ' C           C ', ' C           C ', ' C           C ', ' MMM       MMM ', ' GGG       GGG ', ' GGG       GGG ', ' MMM       MMM ', '               ', '               ', '               ')
            .aisle('CCCCCCCCCCCCCCC', 'CCHHHHHHHHHHHCC', '  FFFFFFFFFFF  ', '  F         F  ', '  F         F  ', ' MF         FM ', ' GF         FG ', ' GF         FG ', ' MF         FM ', '  F         F  ', '  F         F  ', '  FF       FF  ')
            .aisle('CCCCCCCCCCCCCCC', 'CCHHHHHHHHHHHCC', 'C F         F C', 'C             C', 'C             C', 'MM           MM', 'GG           GG', 'GG           GG', 'MM           MM', '               ', '               ', '  FFF     FFF  ')
            .aisle('CCCCCCCCCCCCCCC', 'CCHHHHHHHHHHHCC', '  F         F  ', '               ', '               ', 'M             M', 'G             G', 'G             G', 'M             M', '               ', '               ', '   FFFFFFFFF   ')
            .aisle('CCCCCCCCCCCCCCC', 'CCHHHHHHHHHHHCC', '  F  GGGGG  F  ', '     GGGGG     ', '     GGGGG     ', 'M    GGGGG    M', 'G    GGGGG    G', 'G    GGGGG    G', 'M    GGGGG    M', '     GGGGG     ', '     GGGGG     ', '    FGGGGGF    ')
            .aisle('CCCCCCCCCCCCCCC', 'CCHHHHHHHHHHHCC', '  F  GBBBG  F  ', '     GBBBG     ', 'S    GBBBG    S', 'S    GBBBG    S', 'S    GBBBG    S', 'S    GBBBG    S', 'S    GBBBG    S', 'S    GBBBG    S', '     GHHHG     ', '    FGGGGGF    ')
            .aisle('CCCCCCCCCCCCCCC', 'CCHHHHHHHHHHHCC', '  F  GBPBG  F  ', '     GBPBG     ', 'S    GBPBG    S', 'U    GBPBG    U', 'S    GBPBG    S', 'S    GBPBG    S', 'U    GBPBG    U', 'S    GBPBG    S', '     GHHHG     ', '    FGGGGGF    ')
            .aisle('CCCCCCCCCCCCCCC', 'CCHHHHHHHHHHHCC', '  F  GBBBG  F  ', '     GBBBG     ', 'S    GBBBG    S', 'S    GBBBG    S', 'S    GBBBG    S', 'S    GBBBG    S', 'S    GBBBG    S', 'S    GBBBG    S', '     GHHHG     ', '    FGGGGGF    ')
            .aisle('CCCCCCCCCCCCCCC', 'CCHHHHHHHHHHHCC', '  F  GGGGG  F  ', '     GGGGG     ', '     GGGGG     ', 'M    GGGGG    M', 'G    GGGGG    G', 'G    GGGGG    G', 'M    GGGGG    M', '     GGGGG     ', '     GGGGG     ', '    FGGGGGF    ')
            .aisle('CCCCCCCCCCCCCCC', 'CCHHHHHHHHHHHCC', '  F         F  ', '               ', '               ', 'M             M', 'G             G', 'G             G', 'M             M', '               ', '               ', '   FFFFFFFFF   ')
            .aisle('CCCCCCCCCCCCCCC', 'CCHHHHHHHHHHHCC', 'C F         F C', 'C             C', 'C             C', 'MM           MM', 'GG           GG', 'GG           GG', 'MM           MM', '               ', '               ', '  FFF     FFF  ')
            .aisle('CCCCCCCCCCCCCCC', 'CCHHHHHHHHHHHCC', '  FFFFFFFFFFF  ', '  F         F  ', '  F         F  ', ' MF         FM ', ' GF         FG ', ' GF         FG ', ' MF         FM ', '  F         F  ', '  F         F  ', '  FF       FF  ')
            .aisle('CCCCCCCCCCCCCCC', 'CCCCCCCCCCCCCCC', ' C           C ', ' C           C ', ' C           C ', ' MMM       MMM ', ' GGG       GGG ', ' GGG       GGG ', ' MMM       MMM ', '               ', '               ', '               ')
            .aisle('CCCCCCCCCCCCCCC', 'CCCCCCCKCCCCCCC', '   C       C   ', '   C       C   ', '   C  SSS  C   ', '   MMMSUSMMM   ', '   GGGSSSGGG   ', '   GGGSSSGGG   ', '   MMMSUSMMM   ', '      SSS      ', '               ', '               ')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('C', Predicates.blocks(GCYMBlocks.CASING_ATOMIC.get())
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
            )
            .where('H', Predicates.blocks("gtceu:uhv_hermetic_casing"))
            .where('F', Predicates.blocks("gtceu:neutronium_frame"))
            .where('P', Predicates.blocks("gtceu:ptfe_pipe_casing"))
            .where('B', Predicates.blocks("gtceu:uhv_ultimate_battery"))
            .where('G', Predicates.blocks("gtceu:fusion_glass"))
            .where('S', Predicates.blocks(GTBlocks.COIL_TRITANIUM.get()))
            .where('U', Predicates.blocks("gtceu:fusion_coil"))
            .where('M', Predicates.blocks("gtceu:fusion_casing_mk3"))
            .where(' ', Predicates.any())
            .build()
        )
        .workableCasingModel('gtceu:block/casings/gcym/atomic_casing', 'gtceu:block/multiblock/fusion_reactor')
})


// **** greenhouse **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('greenhouse')
        .category('drack')
        .setEUIO('in')
        .setMaxIOSize(3, 4, 1, 0)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.BATH)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('greenhouse', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('greenhouse')
        .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.OC_NON_PERFECT])
        .appearanceBlock(GTBlocks.CASING_STEEL_SOLID)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('CCC', 'CGC', 'CGC', 'CLC', 'CCC')
            .aisle('CMC', 'G G', 'G G', 'LIL', 'COC')
            .aisle('CKC', 'CGC', 'CGC', 'CLC', 'CNC')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('M', Predicates.blocks('moss_block')
                .or(Predicates.blocks('dirt'))
                .or(Predicates.blocks('grass_block'))
            )
            .where('G', Predicates.blocks('ae2:quartz_glass'))
            .where('I', Predicates.blocks('glowstone'))
            .where('L', Predicates.blocks(GTBlocks.CASING_GRATE.get()))
            .where('C', Predicates.blocks(GTBlocks.CASING_STEEL_SOLID.get())
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
            )
            .where('O', Predicates.abilities(PartAbility.MUFFLER)
                .setExactLimit(1)
            )
            .where('N', Predicates.abilities(PartAbility.MAINTENANCE))
            .where(' ', Predicates.any())
            .build()
        )
        .workableCasingModel('gtceu:block/casings/solid/machine_casing_solid_steel', 'gtceu:block/multiblock/implosion_compressor')
})


// **** simulation_arena **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('simulation_arena')
        .setEUIO('in')
        .setMaxIOSize(3, 9, 1, 1)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.ELECTROLYZER)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('simulation_arena', 'multiblock')
        .machine((holder) => new CoilWorkableElectricMultiblockMachine(holder))
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('simulation_arena')
        .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, (machine, recipe) => GTRecipeModifiers.crackerOverclock(machine, recipe)])
        .appearanceBlock(GTBlocks.CASING_TUNGSTENSTEEL_ROBUST)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('CCCCCCCCCCCCC', 'CXXXXXXXXXXXC', 'CXXXXXXXXXXXC', 'CXXXXXXXXXXXC', 'CCCCCCCCCCCCC')
            .aisle('CLLLCCCCCLLLC', 'X           X', 'X           X', 'X           X', 'CDDDDDDDDDDDC')
            .aisle('CLCLLLLLLLCLC', 'X L       L X', 'X L       L X', 'X L       L X', 'CDPDDDDDDDPDC')
            .aisle('CLLLCCCCCLLLC', 'X   LLLLL   X', 'X   LLLLL   X', 'X   LLLLL   X', 'CDDDPPPPPDDDC')
            .aisle('CLCLLLLLLLCLC', 'X L       L X', 'X L       L X', 'X L       L X', 'CDPDDDDDDDPDC')
            .aisle('CLLLCCCCCLLLC', 'X           X', 'X           X', 'X           X', 'CDDDDDDDDDDDC')
            .aisle('CCCCCCCCCCCCC', 'CXXXXCKCXXXXC', 'CXXXXCCCXXXXC', 'CXXXXXXXXXXXC', 'CCCCCCCCCCCCC')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('X', Predicates.blocks('gtceu:cleanroom_glass'))
            .where('P', Predicates.blocks('gtceu:tungstensteel_pipe_casing'))
            .where('D', Predicates.blocks('gtceu:robust_machine_casing'))
            .where('L', Predicates.heatingCoils())
            .where('C', Predicates.blocks(GTBlocks.CASING_TUNGSTENSTEEL_ROBUST.get())
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
                .or(Predicates.abilities(PartAbility.MUFFLER).setExactLimit(1))
                .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1))
                .or(Predicates.abilities(PartAbility.PARALLEL_HATCH).setExactLimit(1))
            )
            .where(' ', Predicates.any())
            .build()
        )
        .workableCasingModel('gtceu:block/casings/solid/machine_casing_robust_tungstensteel', 'gtceu:block/multiblock/assembly_line')
})


// **** apothic_condenser **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('apothic_condenser')
        .setEUIO('in')
        .setMaxIOSize(6, 6, 2, 0)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.COMPUTATION)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('apothic_condenser', 'multiblock')
        .machine((holder) => new CoilWorkableElectricMultiblockMachine(holder))
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('apothic_condenser')
        .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, (machine, recipe) => GTRecipeModifiers.crackerOverclock(machine, recipe)])
        .appearanceBlock(GTBlocks.CASING_STEEL_TURBINE)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('   C   ', '       ', '       ', '       ', '       ', '       ', '       ', '       ', '   C   ')
            .aisle('  CCC  ', '   C   ', '       ', '       ', '       ', '       ', '       ', '   L   ', '  CCC  ')
            .aisle(' CCCCC ', '  CCC  ', '   C   ', '   C   ', '  QQQ  ', '   C   ', '   C   ', '  LCL  ', ' CCCCC ')
            .aisle('CCCCCCC', ' CCPCC ', '  CPC  ', '  CPC  ', '  QNQ  ', '  CPC  ', '  CPC  ', ' LCPCL ', 'CCCCCCC')
            .aisle(' CCCCC ', '  CCC  ', '   C   ', '   C   ', '  QQQ  ', '   C   ', '   C   ', '  LCL  ', ' CCCCC ')
            .aisle('  CCC  ', '   K   ', '       ', '       ', '       ', '       ', '       ', '   L   ', '  CCC  ')
            .aisle('   C   ', '       ', '       ', '       ', '       ', '       ', '       ', '       ', '   C   ')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('P', Predicates.blocks('gtceu:mv_hermetic_casing'))
            .where('U', Predicates.blocks('gtceu:steel_pipe_casing'))
            .where('Q', Predicates.blocks('ae2:quantum_ring'))
            .where('N', Predicates.blocks('ae2:quantum_link'))
            .where('L', Predicates.heatingCoils())
            .where('C', Predicates.blocks(GTBlocks.CASING_STEEL_TURBINE.get())
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
                .or(Predicates.abilities(PartAbility.MUFFLER).setExactLimit(1))
                .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1))
                .or(Predicates.abilities(PartAbility.PARALLEL_HATCH).setExactLimit(1))
            )
            .where(' ', Predicates.any())
            .build()
        )
        .workableCasingModel('gtceu:block/casings/mechanic/machine_casing_turbine_steel', 'gtceu:block/multiblock/data_bank')
})


// super_extruder
GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('super_extruder', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType(GTRecipeTypes.EXTRUDER_RECIPES)
        .recipeModifiers([GTRecipeModifiers.OC_NON_PERFECT])
        .appearanceBlock(() => new Block.getBlock("kubejs:solid_aluminium_casing"))
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('VVV', 'CCC', 'CCC', 'CCC', 'CCC')
            .aisle('VVV', 'CVC', 'C C', 'CGC', 'CCC')
            .aisle('VVV', 'CKC', 'CCC', 'CCC', 'CCC')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('G', Predicates.blocks('gtceu:steel_gearbox'))
            .where('V', Predicates.blocks('gtceu:black_steel_block'))
            .where('C', Predicates.blocks('kubejs:solid_aluminium_casing')
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
                .or(Predicates.abilities(PartAbility.MUFFLER).setExactLimit(1))
                .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1))
            )
            .where(' ', Predicates.any())
            .build()
        )
        .workableCasingModel('kubejs:block/custom_casings/solid_aluminium_casing/solid_aluminium_casing', 'gtceu:block/multiblock/gcym/large_extruder')
})


// powered_enchanter
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('powered_enchanter')
        .setEUIO('in')
        .setMaxIOSize(6, 1, 0, 0)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.COMPUTATION)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('powered_enchanter', 'multiblock')
        .machine((holder) => new CoilWorkableElectricMultiblockMachine(holder))
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('powered_enchanter')
        .recipeModifiers([GTRecipeModifiers.OC_NON_PERFECT, (machine, recipe) => GTRecipeModifiers.crackerOverclock(machine, recipe)])
        .appearanceBlock(() => new Block.getBlock("xtonesreworked:zion_block_9"))
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('CCCCCCC', '       ', '       ')
            .aisle('COOOOOC', '  BBB  ', '  SSS  ')
            .aisle('COOOOOC', ' B   B ', ' B   B ')
            .aisle('COOOOOC', ' B K B ', ' S   S ')
            .aisle('COOOOOC', ' B   B ', ' S   S ')
            .aisle('COOOOOC', ' B   B ', ' B   B ')
            .aisle('CCCCCCC', '       ', '       ')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('B', Predicates.heatingCoils())
            .where('S', Predicates.blockTag($Tags.block("forge:bookshelves")))
            .where('O', Predicates.blocks('minecraft:obsidian'))
            .where('C', Predicates.blocks('minecraft:obsidian')
                .or(Predicates.autoAbilities(definition.getRecipeTypes()))
            )
            .where(' ', Predicates.any())
            .build()
        )
        .workableCasingModel('minecraft:block/obsidian', 'gtceu:block/multiblock/gcym/large_extruder')
})


//#endregion

// **************************** // // **************************** //
// ***** GENERATOR MULTIS ***** // // ***** GENERATOR MULTIS ***** //
// **************************** // // **************************** //
//#region GENERATOR MULTIS

// **** hydrovolcanism_generator **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('hydrovolcanism_generator')
        .setEUIO('out')
        .setMaxIOSize(0, 0, 2, 1)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.BATH)
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('hydrovolcanism_generator', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('hydrovolcanism_generator')
        .noRecipeModifier()
        .appearanceBlock(GTBlocks.CASING_STAINLESS_CLEAN)
        .generator(true)
        .regressWhenWaiting(false)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('  BBB  ', '  CCC  ', '  CCC  ', '  CCC  ', '  CCC  ', '  CCC  ', '  CCC  ')
            .aisle(' BBBBB ', ' C   C ', ' C   C ', ' C P C ', ' C P C ', ' C P C ', ' CGVGC ')
            .aisle('BBBBBBB', 'C     C', 'C     C', 'C  P  C', 'C     C', 'C     C', 'CGGGGGC')
            .aisle('BBBBBBB', 'IH   HI', 'CP   PC', 'CPPHPPC', 'C  H  C', 'C  H  C', 'CGGOGGC')
            .aisle('BBBBBBB', 'C     C', 'C     C', 'C  P  C', 'C     C', 'C     C', 'CGGGGGC')
            .aisle(' BBBBB ', ' C   C ', ' C   C ', ' C P C ', ' C P C ', ' C P C ', ' CGVGC ')
            .aisle('  BBB  ', '  CKC  ', '  CCC  ', '  CCC  ', '  CCC  ', '  CCC  ', '  CCC  ')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('G', Predicates.blocks('ae2:quartz_vibrant_glass')
                .or(Predicates.blocks('ae2:quartz_glass'))
            )
            .where('V', Predicates.blocks('gtceu:filter_casing'))
            .where('P', Predicates.blocks('gtceu:steel_pipe_casing'))
            .where('B', Predicates.blocks('gtceu:stainless_steel_turbine_casing'))
            .where('H', Predicates.blocks('gtceu:hv_hermetic_casing'))
            .where('I', Predicates.abilities(PartAbility.IMPORT_FLUIDS).setMaxGlobalLimited(2))
            .where('O', Predicates.abilities(PartAbility.EXPORT_FLUIDS).setMaxGlobalLimited(1))
            .where('C', Predicates.blocks(GTBlocks.CASING_STAINLESS_CLEAN.get())
                .or(Predicates.blocks(PartAbility.OUTPUT_ENERGY.getBlocks(GTValues.HV).toArray()).setMaxGlobalLimited(4))
                .or(Predicates.abilities(PartAbility.MUFFLER).setExactLimit(1))
                .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1))
            )
            .where(' ', Predicates.any())
            .build()
        )
        .workableCasingModel('gtceu:block/casings/solid/machine_casing_clean_stainless_steel', 'gtceu:block/multiblock/generator/large_steam_turbine')
})


// **** solar_test **** //
// GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
//     event.create('solar_test')
//         .setEUIO('out')
//         .setMaxIOSize(1, 0, 0, 0)
//         .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
//         .setSound(GTSoundEntries.ELECTROLYZER)
// })

// GTCEuStartupEvents.registry('gtceu:machine', event => {
//     event.create('solar_test', 'multiblock')
//         .rotationState(RotationState.NON_Y_AXIS)
//         .recipeType('solar_test')
//         .noRecipeModifier()
//         .appearanceBlock(GTBlocks.CASING_STEEL_SOLID)
//         .generator(true)
//         .regressWhenWaiting(false)
//         .pattern(definition => FactoryBlockPattern.start()
//             .aisle('BB', 'CC', '  ')
//             .aisle('BB', 'CK', 'RD')
//             .where('K', Predicates.controller(Predicates.blocks(definition.get())))
//             .where('B', Predicates.blocks('gtceu:steel_block'))
//             .where('R', Predicates.blocks('rainshield:rain_shield'))
//             .where('D', Predicates.blocks('minecraft:daylight_detector'))
//             .where('C', Predicates.blocks(GTBlocks.CASING_STEEL_SOLID.get())
//                 .or(Predicates.blocks(PartAbility.OUTPUT_ENERGY.getBlocks(GTValues.LV).toArray()).setMaxGlobalLimited(1))
//                 .or(Predicates.abilities(PartAbility.IMPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
//             )
//             .where(' ', Predicates.any())
//             .build()
//         )
//         .workableCasingModel('gtceu:block/casings/solid/machine_casing_solid_steel', 'gtceu:block/machines/wiremill')
// })


//#endregion

// ***************************** // // ***************************** //
// ***** EV PERFECT MULTIS ***** // // ***** EV PERFECT MULTIS ***** //
// ***************************** // // ***************************** //
//#region EV PERFECT MULTIS

// needs different casing, was test run
// // **** ev_perfect_wiremill **** //
// GTCEuStartupEvents.registry('gtceu:machine', event => {
//     event.create('ev_perfect_wiremill', 'multiblock')
//         .rotationState(RotationState.NON_Y_AXIS)
//         .recipeType(GTRecipeTypes.WIREMILL_RECIPES)
//         .recipeModifiers([GTRecipeModifiers.OC_PERFECT])
//         .appearanceBlock(() => new Block.getBlock("kubejs:dark_steel_casing"))
//         .pattern(definition => FactoryBlockPattern.start()
//             .aisle('BBB', 'CCC', 'CCC')
//             .aisle('BBB', 'CGC', 'CCC')
//             .aisle('BBB', 'CKC', 'CCC')
//             .where('K', Predicates.controller(Predicates.blocks(definition.get())))
//             .where('B', Predicates.blocks('gtceu:nonconducting_casing'))
//             .where('G', Predicates.blocks('gtceu:titanium_gearbox'))
//             .where('C', Predicates.blocks('kubejs:dark_steel_casing')
//                 .or(Predicates.abilities(PartAbility.INPUT_ENERGY).setMaxGlobalLimited(1).setPreviewCount(1))
//                 .or(Predicates.abilities(PartAbility.IMPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
//                 .or(Predicates.abilities(PartAbility.EXPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
//                 .or(Predicates.abilities(PartAbility.MUFFLER).setExactLimit(1))
//                 .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1))
//             )
//             // .where(' ', Predicates.any())
//             .build()
//         )
//         .workableCasingModel('kubejs:block/custom_casings/dark_steel_casing/dark_steel_casing', 'gtceu:block/multiblock/gcym/large_wiremill')
// })


// **** ev_perfect_arc_furnace **** //
GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('ev_perfect_arc_furnace', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType(GTRecipeTypes.ARC_FURNACE_RECIPES)
        .recipeModifiers([GTRecipeModifiers.OC_PERFECT])
        .appearanceBlock(() => new Block.getBlock("kubejs:medium_temperature_smelting_casing"))
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('BBB', 'CCC', 'CCC')
            .aisle('BBB', 'CGC', 'CCC')
            .aisle('BBB', 'CKC', 'CCC')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('B', Predicates.blocks('gtceu:nonconducting_casing'))
            .where('G', Predicates.blocks('gtceu:molybdenum_disilicide_coil_block'))
            .where('C', Predicates.blocks('kubejs:medium_temperature_smelting_casing')
                .or(Predicates.abilities(PartAbility.INPUT_ENERGY).setMaxGlobalLimited(1).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.IMPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.EXPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.MUFFLER).setExactLimit(1))
                .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1))
            )
            .build()
        )
        .workableCasingModel('kubejs:block/custom_casings/medium_temperature_smelting_casing/medium_temperature_smelting_casing', 'gtceu:block/multiblock/gcym/large_arc_smelter')
})


// **** ev_perfect_electrolyzer **** //
GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('ev_perfect_electrolyzer', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType(GTRecipeTypes.ELECTROLYZER_RECIPES)
        .recipeModifiers([GTRecipeModifiers.OC_PERFECT])
        .appearanceBlock(() => new Block.getBlock("kubejs:electrolytic_casing"))
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('BBB', 'CCC', 'CCC')
            .aisle('BBB', 'CGC', 'CCC')
            .aisle('BBB', 'CKC', 'CCC')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('B', Predicates.blocks('gtceu:nonconducting_casing'))
            .where('G', Predicates.blocks('gtceu:laminated_glass'))
            .where('C', Predicates.blocks('kubejs:electrolytic_casing')
                .or(Predicates.abilities(PartAbility.INPUT_ENERGY).setMaxGlobalLimited(1).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.IMPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.EXPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.MUFFLER).setExactLimit(1))
                .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1))
            )
            .build()
        )
        .workableCasingModel('kubejs:block/custom_casings/electrolytic_casing/electrolytic_casing', 'gtceu:block/multiblock/gcym/large_electrolyzer')
})


//#endregion

// ********************************* // // ********************************* //
// ***** SINGLE BLOCK MACHINES ***** // // ***** SINGLE BLOCK MACHINES ***** //
// ********************************* // // ********************************* //
//#region SINGLE BLOCKS

// TODO - move me!
// **** firebrick_mixer **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('firebrick_mixer')
        .category('firebrick_mixer')
        .setEUIO('in')
        .setMaxIOSize(3, 1, 0, 0)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.BATH);
});

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('firebrick_mixer', 'steam')
        .hasHighPressure(false)
        .definition((hp, builder) => (
            builder
                .recipeType("firebrick_mixer")
                .workableSteamHullModel(hp, 'gtceu:block/machines/mixer')
        ))
});


// **** card_assembler **** //
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('card_assembler')
        .category('card_assembler')
        .setEUIO('in')
        .setMaxIOSize(9, 9, 1, 0)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.ASSEMBLER);
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('card_assembler', 'simple')
        .tiers(GTValues.LV, GTValues.MV, GTValues.HV, GTValues.EV, GTValues.IV, GTValues.LuV, GTValues.ZPM, GTValues.UV)
        .definition((tier, builder) =>
            builder
                .langValue(GTValues.VLVH[tier] + " Card Assembler")
                .recipeType('card_assembler')
                .workableTieredHullModel('gtceu:block/machines/assembler')
        )
})


//#endregion

// **************************** // // **************************** //
// ***** PRIMITIVE MULTIS ***** // // ***** PRIMITIVE MULTIS ***** //
// **************************** // // **************************** //
//#region PRIMITIVE MULTIS

// bronze_bulk_smelter
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('bronze_bulk_smelter')
        .category('bronze_bulk_smelter')
        .setMaxIOSize(6, 6, 0, 0)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.FURNACE);
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('bronze_bulk_smelter', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('bronze_bulk_smelter')
        .appearanceBlock(() => new Block.getBlock("minecraft:terracotta"))
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('BBB', 'CCC', 'CCC')
            .aisle('BBB', 'C C', 'C C')
            .aisle('BBB', 'CKC', 'CCC')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('B', Predicates.blocks('minecraft:smooth_stone'))
            .where('C', Predicates.blocks('minecraft:terracotta')
                .or(Predicates.blocks(PartAbility.IMPORT_ITEMS.getBlocks(GTValues.ULV).toArray()).setMaxGlobalLimited(2).setPreviewCount(2))
                .or(Predicates.blocks(PartAbility.EXPORT_ITEMS.getBlocks(GTValues.ULV).toArray()).setMaxGlobalLimited(2).setPreviewCount(1))
                // .or(Predicates.abilities(PartAbility.IMPORT_ITEMS).setMaxGlobalLimited(2).setPreviewCount(1))
                // .or(Predicates.abilities(PartAbility.EXPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
            )
            .where(' ', Predicates.any())
            .build()
        )
        .workableCasingModel('minecraft:block/terracotta',
            'kubejs:block/custom_casings/primitive_smelting_bricks');
});


// primitive_farm
GTCEuStartupEvents.registry('gtceu:recipe_type', event => {
    event.create('primitive_farm')
        .category('primitive_farm')
        .setMaxIOSize(3, 4, 1, 0)
        .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT)
        .setSound(GTSoundEntries.BATH);
})

GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('primitive_farm', 'multiblock')
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType('primitive_farm')
        .appearanceBlock(() => new Block.getBlock("minecraft:stone_bricks"))
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('BBBBB', 'CGGGC', 'CGGGC', 'CCCCC')
            .aisle('BWFWB', 'G   G', 'G   G', 'CGGGC')
            .aisle('BBKBB', 'CGGGC', 'CGGGC', 'CCCCC')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('C', Predicates.blocks('minecraft:bricks'))
            .where('G', Predicates.blocks('minecraft:glass')
                .or(Predicates.blocks('minecraft:bricks'))
            )
            .where('F', Predicates.blocks('minecraft:farmland'))
            .where('W', Predicates.fluids('minecraft:water'))
            .where('B', Predicates.blocks('minecraft:stone_bricks')
                .or(Predicates.abilities(PartAbility.IMPORT_ITEMS).setMaxGlobalLimited(4).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.EXPORT_ITEMS).setMaxGlobalLimited(4).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.IMPORT_FLUIDS).setMaxGlobalLimited(1).setPreviewCount(1))
            )
            .where(' ', Predicates.any())
            .build()
        )
        .workableCasingModel('minecraft:block/stone_bricks',
            'kubejs:block/custom_casings/primitive_smelting_bricks');
});


//#endregion

// ***************************** // // ***************************** //
// ***** STEAM BULK MULTIS ***** // // ***** STEAM BULK MULTIS ***** //
// ***************************** // // ***************************** //
//#region STEAM BULK MULTIS

// steam_alloy_smelter (bulk)
GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('steam_alloy_smelter', 'multiblock')
        .machine(holder => new $SteamMulti(holder, 1))
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType(GTRecipeTypes.ALLOY_SMELTER_RECIPES)
        .recipeModifiers([
            (machine, recipe) => $SteamMulti.recipeModifier(machine, recipe)
        ])
        .appearanceBlock(GTBlocks.CASING_BRONZE_BRICKS)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('RRRRR', '#####', '#####', '     ')
            .aisle('RRRRR', '#PGP#', '#PGP#', '#####')
            .aisle('RRRRR', '##C##', '#####', '     ')
            .where('C', Predicates.controller(Predicates.blocks(definition.get())))
            .where('#', Predicates.blocks('gtceu:steam_machine_casing')
                .or(Predicates.abilities(PartAbility.STEAM_IMPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.STEAM).setMaxGlobalLimited(1).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.STEAM_EXPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
            )
            .where('R', Predicates.blocks('gtceu:bronze_firebox_casing'))
            .where('G', Predicates.blocks('gtceu:bronze_gearbox'))
            .where('P', Predicates.blocks('gtceu:bronze_pipe_casing'))
            .where(' ', Predicates.any())
            .build())
        .workableCasingModel("gtceu:block/casings/solid/machine_casing_bronze_plated_bricks", "gtceu:block/machines/alloy_smelter")
})


// steam_wiremill (bulk)
GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('steam_wiremill', 'multiblock')
        .machine(holder => new $SteamMulti(holder, 1))
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType(GTRecipeTypes.WIREMILL_RECIPES)
        .recipeModifiers([
            (machine, recipe) => $SteamMulti.recipeModifier(machine, recipe)
        ])
        .appearanceBlock(GTBlocks.CASING_STEEL_SOLID)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle(' RRR ', ' ### ', '     ')
            .aisle('RRRRR', '#GGG#', ' ### ')
            .aisle('RRRRR', '#GGG#', ' ### ')
            .aisle('RRRRR', '#GGG#', ' ### ')
            .aisle(' RRR ', ' #C# ', '     ')
            .where('C', Predicates.controller(Predicates.blocks(definition.get())))
            .where('#', Predicates.blocks('gtceu:solid_machine_casing')
                .or(Predicates.abilities(PartAbility.IMPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.STEAM).setMaxGlobalLimited(1).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.EXPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
            )
            .where('R', Predicates.blocks('gtceu:steel_firebox_casing'))
            .where('G', Predicates.blocks('gtceu:steel_gearbox'))
            .where(' ', Predicates.any())
            .build())
        .workableCasingModel("gtceu:block/casings/solid/machine_casing_solid_steel", "gtceu:block/machines/wiremill")
})


// steam_compressor (bulk)
GTCEuStartupEvents.registry('gtceu:machine', event => {
    event.create('steam_compressor', 'multiblock')
        .machine(holder => new $SteamMulti(holder, 1))
        .rotationState(RotationState.NON_Y_AXIS)
        .recipeType(GTRecipeTypes.COMPRESSOR_RECIPES)
        .recipeModifiers([
            (machine, recipe) => $SteamMulti.recipeModifier(machine, recipe)
        ])
        .appearanceBlock(GTBlocks.CASING_BRONZE_BRICKS)
        .pattern(definition => FactoryBlockPattern.start()
            .aisle('BBB', 'CCC', 'CCC', 'CCC', 'CCC')
            .aisle('BBB', 'CAC', 'C C', 'CPC', 'CCC')
            .aisle('BBB', 'CKC', 'CCC', 'CCC', 'CCC')
            .where('K', Predicates.controller(Predicates.blocks(definition.get())))
            .where('C', Predicates.blocks('gtceu:steam_machine_casing')
                .or(Predicates.abilities(PartAbility.STEAM_IMPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.STEAM).setMaxGlobalLimited(1).setPreviewCount(1))
                .or(Predicates.abilities(PartAbility.STEAM_EXPORT_ITEMS).setMaxGlobalLimited(1).setPreviewCount(1))
            )
            .where('B', Predicates.blocks('gtceu:bronze_firebox_casing'))
            .where('A', Predicates.blocks('minecraft:anvil'))
            .where('P', Predicates.blocks('minecraft:piston'))
            .where(' ', Predicates.any())
            .build())
        .shapeInfo(controller => MultiblockShapeInfo.builder()
            .aisle('BBB', 'CKC', 'CCC', 'CCC', 'CCC')
            .aisle('BBB', 'CAC', 'O I', 'CPC', 'CCC')
            .aisle('BBB', 'CCC', 'CSC', 'CCC', 'CCC')
            .where('K', controller, Direction.NORTH)
            .where('C', Block.getBlock('gtceu:steam_machine_casing'))
            .where('B', GTBlocks.FIREBOX_BRONZE.get())
            .where('A', Block.getBlock("minecraft:anvil"))
        ["where(char,net.minecraft.world.level.block.state.BlockState)"](
            'P', Block.getBlock('minecraft:piston').defaultBlockState()
                .setValue(BlockProperties.FACING, Direction.DOWN)
        )
            .where(' ', Block.getBlock("minecraft:air"))
            .where('I', GTMachines.STEAM_IMPORT_BUS, Direction.EAST)
            .where('O', GTMachines.STEAM_EXPORT_BUS, Direction.WEST)
            .where('S', GTMachines.STEAM_HATCH, Direction.SOUTH)
            .build())
        .workableCasingModel("gtceu:block/casings/solid/machine_casing_bronze_plated_bricks", "gtceu:block/machines/compressor")
})


//#endregion

// fin //